diff options
255 files changed, 4900 insertions, 1405 deletions
diff --git a/apct-tests/perftests/core/AndroidManifest.xml b/apct-tests/perftests/core/AndroidManifest.xml index f27e8c82a303..48899410c07c 100644 --- a/apct-tests/perftests/core/AndroidManifest.xml +++ b/apct-tests/perftests/core/AndroidManifest.xml @@ -2,6 +2,9 @@ <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.android.perftests.core"> + <uses-permission + android:name="android.permission.GET_ACCOUNTS" /> + <application> <uses-library android:name="android.test.runner" /> <activity android:name="android.perftests.utils.StubActivity" /> diff --git a/apct-tests/perftests/core/src/android/accounts/AccountManagerPerfTest.java b/apct-tests/perftests/core/src/android/accounts/AccountManagerPerfTest.java new file mode 100644 index 000000000000..b9411fa463d5 --- /dev/null +++ b/apct-tests/perftests/core/src/android/accounts/AccountManagerPerfTest.java @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.accounts; + +import static junit.framework.Assert.fail; + +import android.Manifest; +import android.content.Context; +import android.content.pm.PackageManager; +import android.perftests.utils.BenchmarkState; +import android.perftests.utils.PerfStatusReporter; +import android.support.test.InstrumentationRegistry; +import android.support.test.filters.LargeTest; +import android.support.test.runner.AndroidJUnit4; +import android.util.Log; + +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; + +@RunWith(AndroidJUnit4.class) +@LargeTest +public class AccountManagerPerfTest { + + @Rule + public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter(); + + @Test + public void testGetAccounts() { + BenchmarkState state = mPerfStatusReporter.getBenchmarkState(); + final Context context = InstrumentationRegistry.getTargetContext(); + if (context.checkSelfPermission(Manifest.permission.GET_ACCOUNTS) + != PackageManager.PERMISSION_GRANTED) { + fail("Missing required GET_ACCOUNTS permission"); + } + AccountManager accountManager = AccountManager.get(context); + while (state.keepRunning()) { + accountManager.getAccounts(); + } + } +} diff --git a/api/current.txt b/api/current.txt index 96fbd31af65b..665726dfc1da 100644 --- a/api/current.txt +++ b/api/current.txt @@ -6328,6 +6328,7 @@ package android.app.admin { method public java.lang.CharSequence getDeviceOwnerLockScreenInfo(); method public java.util.List<byte[]> getInstalledCaCerts(android.content.ComponentName); method public int getKeyguardDisabledFeatures(android.content.ComponentName); + method public int getLockTaskFeatures(android.content.ComponentName); method public java.lang.String[] getLockTaskPackages(android.content.ComponentName); method public java.lang.CharSequence getLongSupportMessage(android.content.ComponentName); method public int getMaximumFailedPasswordsForWipe(android.content.ComponentName); @@ -6414,6 +6415,7 @@ package android.app.admin { method public void setGlobalSetting(android.content.ComponentName, java.lang.String, java.lang.String); method public boolean setKeyguardDisabled(android.content.ComponentName, boolean); method public void setKeyguardDisabledFeatures(android.content.ComponentName, int); + method public void setLockTaskFeatures(android.content.ComponentName, int); method public void setLockTaskPackages(android.content.ComponentName, java.lang.String[]) throws java.lang.SecurityException; method public void setLongSupportMessage(android.content.ComponentName, java.lang.CharSequence); method public void setMasterVolumeMuted(android.content.ComponentName, boolean); @@ -6530,6 +6532,13 @@ package android.app.admin { field public static final int KEYGUARD_DISABLE_TRUST_AGENTS = 16; // 0x10 field public static final int KEYGUARD_DISABLE_UNREDACTED_NOTIFICATIONS = 8; // 0x8 field public static final int KEYGUARD_DISABLE_WIDGETS_ALL = 1; // 0x1 + field public static final int LOCK_TASK_FEATURE_GLOBAL_ACTIONS = 16; // 0x10 + field public static final int LOCK_TASK_FEATURE_HOME = 4; // 0x4 + field public static final int LOCK_TASK_FEATURE_KEYGUARD = 32; // 0x20 + field public static final int LOCK_TASK_FEATURE_NONE = 0; // 0x0 + field public static final int LOCK_TASK_FEATURE_NOTIFICATIONS = 2; // 0x2 + field public static final int LOCK_TASK_FEATURE_RECENTS = 8; // 0x8 + field public static final int LOCK_TASK_FEATURE_SYSTEM_INFO = 1; // 0x1 field public static final java.lang.String MIME_TYPE_PROVISIONING_NFC = "application/com.android.managedprovisioning"; field public static final int PASSWORD_QUALITY_ALPHABETIC = 262144; // 0x40000 field public static final int PASSWORD_QUALITY_ALPHANUMERIC = 327680; // 0x50000 diff --git a/api/system-current.txt b/api/system-current.txt index 4f2c2ba7c2b6..f7fb102e5817 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -6550,6 +6550,7 @@ package android.app.admin { method public java.lang.CharSequence getDeviceOwnerOrganizationName(); method public java.util.List<byte[]> getInstalledCaCerts(android.content.ComponentName); method public int getKeyguardDisabledFeatures(android.content.ComponentName); + method public int getLockTaskFeatures(android.content.ComponentName); method public java.lang.String[] getLockTaskPackages(android.content.ComponentName); method public java.lang.CharSequence getLongSupportMessage(android.content.ComponentName); method public int getMaximumFailedPasswordsForWipe(android.content.ComponentName); @@ -6649,6 +6650,7 @@ package android.app.admin { method public void setGlobalSetting(android.content.ComponentName, java.lang.String, java.lang.String); method public boolean setKeyguardDisabled(android.content.ComponentName, boolean); method public void setKeyguardDisabledFeatures(android.content.ComponentName, int); + method public void setLockTaskFeatures(android.content.ComponentName, int); method public void setLockTaskPackages(android.content.ComponentName, java.lang.String[]) throws java.lang.SecurityException; method public void setLongSupportMessage(android.content.ComponentName, java.lang.CharSequence); method public void setMasterVolumeMuted(android.content.ComponentName, boolean); @@ -6776,6 +6778,13 @@ package android.app.admin { field public static final int KEYGUARD_DISABLE_TRUST_AGENTS = 16; // 0x10 field public static final int KEYGUARD_DISABLE_UNREDACTED_NOTIFICATIONS = 8; // 0x8 field public static final int KEYGUARD_DISABLE_WIDGETS_ALL = 1; // 0x1 + field public static final int LOCK_TASK_FEATURE_GLOBAL_ACTIONS = 16; // 0x10 + field public static final int LOCK_TASK_FEATURE_HOME = 4; // 0x4 + field public static final int LOCK_TASK_FEATURE_KEYGUARD = 32; // 0x20 + field public static final int LOCK_TASK_FEATURE_NONE = 0; // 0x0 + field public static final int LOCK_TASK_FEATURE_NOTIFICATIONS = 2; // 0x2 + field public static final int LOCK_TASK_FEATURE_RECENTS = 8; // 0x8 + field public static final int LOCK_TASK_FEATURE_SYSTEM_INFO = 1; // 0x1 field public static final java.lang.String MIME_TYPE_PROVISIONING_NFC = "application/com.android.managedprovisioning"; field public static final int PASSWORD_QUALITY_ALPHABETIC = 262144; // 0x40000 field public static final int PASSWORD_QUALITY_ALPHANUMERIC = 327680; // 0x50000 diff --git a/api/test-current.txt b/api/test-current.txt index dd0e9995b1ab..3a5165de8dd7 100644 --- a/api/test-current.txt +++ b/api/test-current.txt @@ -6393,6 +6393,7 @@ package android.app.admin { method public long getLastBugReportRequestTime(); method public long getLastNetworkLogRetrievalTime(); method public long getLastSecurityLogRetrievalTime(); + method public int getLockTaskFeatures(android.content.ComponentName); method public java.lang.String[] getLockTaskPackages(android.content.ComponentName); method public java.lang.CharSequence getLongSupportMessage(android.content.ComponentName); method public int getMaximumFailedPasswordsForWipe(android.content.ComponentName); @@ -6482,6 +6483,7 @@ package android.app.admin { method public void setGlobalSetting(android.content.ComponentName, java.lang.String, java.lang.String); method public boolean setKeyguardDisabled(android.content.ComponentName, boolean); method public void setKeyguardDisabledFeatures(android.content.ComponentName, int); + method public void setLockTaskFeatures(android.content.ComponentName, int); method public void setLockTaskPackages(android.content.ComponentName, java.lang.String[]) throws java.lang.SecurityException; method public void setLongSupportMessage(android.content.ComponentName, java.lang.CharSequence); method public void setMasterVolumeMuted(android.content.ComponentName, boolean); @@ -6601,6 +6603,13 @@ package android.app.admin { field public static final int KEYGUARD_DISABLE_TRUST_AGENTS = 16; // 0x10 field public static final int KEYGUARD_DISABLE_UNREDACTED_NOTIFICATIONS = 8; // 0x8 field public static final int KEYGUARD_DISABLE_WIDGETS_ALL = 1; // 0x1 + field public static final int LOCK_TASK_FEATURE_GLOBAL_ACTIONS = 16; // 0x10 + field public static final int LOCK_TASK_FEATURE_HOME = 4; // 0x4 + field public static final int LOCK_TASK_FEATURE_KEYGUARD = 32; // 0x20 + field public static final int LOCK_TASK_FEATURE_NONE = 0; // 0x0 + field public static final int LOCK_TASK_FEATURE_NOTIFICATIONS = 2; // 0x2 + field public static final int LOCK_TASK_FEATURE_RECENTS = 8; // 0x8 + field public static final int LOCK_TASK_FEATURE_SYSTEM_INFO = 1; // 0x1 field public static final java.lang.String MIME_TYPE_PROVISIONING_NFC = "application/com.android.managedprovisioning"; field public static final int PASSWORD_QUALITY_ALPHABETIC = 262144; // 0x40000 field public static final int PASSWORD_QUALITY_ALPHANUMERIC = 327680; // 0x50000 @@ -32047,12 +32056,10 @@ package android.os { public static final class StrictMode.ViolationInfo implements android.os.Parcelable { ctor public StrictMode.ViolationInfo(); ctor public StrictMode.ViolationInfo(java.lang.Throwable, int); - ctor public deprecated StrictMode.ViolationInfo(java.lang.String, java.lang.Throwable, int); ctor public StrictMode.ViolationInfo(android.os.Parcel); ctor public StrictMode.ViolationInfo(android.os.Parcel, boolean); method public int describeContents(); method public void dump(android.util.Printer, java.lang.String); - method public java.lang.String getMessagePrefix(); method public java.lang.String getStackTrace(); method public java.lang.String getViolationDetails(); method public void writeToParcel(android.os.Parcel, int); diff --git a/cmds/statsd/src/StatsLogProcessor.cpp b/cmds/statsd/src/StatsLogProcessor.cpp index 68f48a4f4c37..56d4e4d940c2 100644 --- a/cmds/statsd/src/StatsLogProcessor.cpp +++ b/cmds/statsd/src/StatsLogProcessor.cpp @@ -35,7 +35,7 @@ namespace statsd { StatsLogProcessor::StatsLogProcessor(const sp<UidMap>& uidMap, const std::function<void(const vector<uint8_t>&)>& pushLog) - : m_dropbox_writer("all-logs"), mUidMap(uidMap), mPushLog(pushLog) { + : mUidMap(uidMap), mPushLog(pushLog) { } StatsLogProcessor::~StatsLogProcessor() { @@ -43,12 +43,6 @@ StatsLogProcessor::~StatsLogProcessor() { // TODO: what if statsd service restarts? How do we know what logs are already processed before? void StatsLogProcessor::OnLogEvent(const LogEvent& msg) { - // TODO: Use EventMetric to filter the events we want to log. - /* TODO: Convert this when we have the generic protobuf writing library in. - EventMetricData eventMetricData = parse(msg); - m_dropbox_writer.addEventMetricData(eventMetricData); - */ - // pass the event to metrics managers. for (auto& pair : mMetricsManagers) { pair.second->onLogEvent(msg); diff --git a/cmds/statsd/src/StatsLogProcessor.h b/cmds/statsd/src/StatsLogProcessor.h index 08090c11f724..9cd74caf095e 100644 --- a/cmds/statsd/src/StatsLogProcessor.h +++ b/cmds/statsd/src/StatsLogProcessor.h @@ -20,7 +20,6 @@ #include "logd/LogReader.h" #include "metrics/MetricsManager.h" #include "packages/UidMap.h" -#include "storage/DropboxWriter.h" #include "frameworks/base/cmds/statsd/src/statsd_config.pb.h" @@ -49,9 +48,6 @@ public: void flush(); private: - // TODO: use EventMetrics to log the events. - DropboxWriter m_dropbox_writer; - std::unordered_map<ConfigKey, std::unique_ptr<MetricsManager>> mMetricsManagers; sp<UidMap> mUidMap; // Reference to the UidMap to lookup app name and version for each uid. @@ -75,7 +71,7 @@ private: size_t mBufferSize = 0; /* Check if the buffer size exceeds the max buffer size when the new entry is added, and flush - the logs to dropbox if true. */ + the logs to callback clients if true. */ void flushIfNecessary(const EventMetricData& eventMetricData); /* Append event metric data to StatsLogReport. */ diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java index 8bc2073c3cda..8d9dc1fab4ff 100644 --- a/core/java/android/app/ActivityManager.java +++ b/core/java/android/app/ActivityManager.java @@ -848,9 +848,8 @@ public class ActivityManager { /** * Returns true if this is a low-RAM device. Exactly whether a device is low-RAM * is ultimately up to the device configuration, but currently it generally means - * something in the class of a 512MB device with about a 800x480 or less screen. - * This is mostly intended to be used by apps to determine whether they should turn - * off certain features that require more RAM. + * something with 1GB or less of RAM. This is mostly intended to be used by apps + * to determine whether they should turn off certain features that require more RAM. */ public boolean isLowRamDevice() { return isLowRamDeviceStatic(); @@ -1900,7 +1899,7 @@ public class ActivityManager { public List<RunningTaskInfo> getRunningTasks(int maxNum) throws SecurityException { try { - return getService().getTasks(maxNum, 0); + return getService().getTasks(maxNum); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } diff --git a/core/java/android/app/IActivityManager.aidl b/core/java/android/app/IActivityManager.aidl index 117854a60499..86b8402338e9 100644 --- a/core/java/android/app/IActivityManager.aidl +++ b/core/java/android/app/IActivityManager.aidl @@ -115,7 +115,9 @@ interface IActivityManager { in PersistableBundle persistentState, in CharSequence description); String getCallingPackage(in IBinder token); ComponentName getCallingActivity(in IBinder token); - List<ActivityManager.RunningTaskInfo> getTasks(int maxNum, int flags); + List<ActivityManager.RunningTaskInfo> getTasks(int maxNum); + List<ActivityManager.RunningTaskInfo> getFilteredTasks(int maxNum, int ignoreActivityType, + int ignoreWindowingMode); void moveTaskToFront(int task, int flags, in Bundle options); void moveTaskBackwards(int task); int getTaskForActivity(in IBinder token, in boolean onlyRoot); @@ -652,7 +654,10 @@ interface IActivityManager { /** * Add a bare uid to the background restrictions whitelist. Only the system uid may call this. */ - void backgroundWhitelistUid(int uid); + void backgroundWhitelistUid(int uid); + + // Start of P transactions + void updateLockTaskFeatures(int userId, int flags); // WARNING: when these transactions are updated, check if they are any callers on the native // side. If so, make sure they are using the correct transaction ids and arguments. diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java index fee7d6c8ba2b..8226e0fb4e71 100644 --- a/core/java/android/app/Notification.java +++ b/core/java/android/app/Notification.java @@ -858,7 +858,7 @@ public class Notification implements Parcelable * * @hide */ - static public IBinder whitelistToken; + private IBinder mWhitelistToken; /** * Must be set by a process to start associating tokens with Notification objects @@ -1876,12 +1876,12 @@ public class Notification implements Parcelable { int version = parcel.readInt(); - whitelistToken = parcel.readStrongBinder(); - if (whitelistToken == null) { - whitelistToken = processWhitelistToken; + mWhitelistToken = parcel.readStrongBinder(); + if (mWhitelistToken == null) { + mWhitelistToken = processWhitelistToken; } // Propagate this token to all pending intents that are unmarshalled from the parcel. - parcel.setClassCookie(PendingIntent.class, whitelistToken); + parcel.setClassCookie(PendingIntent.class, mWhitelistToken); when = parcel.readLong(); creationTime = parcel.readLong(); @@ -1989,7 +1989,7 @@ public class Notification implements Parcelable * @hide */ public void cloneInto(Notification that, boolean heavy) { - that.whitelistToken = this.whitelistToken; + that.mWhitelistToken = this.mWhitelistToken; that.when = this.when; that.creationTime = this.creationTime; that.mSmallIcon = this.mSmallIcon; @@ -2219,7 +2219,7 @@ public class Notification implements Parcelable private void writeToParcelImpl(Parcel parcel, int flags) { parcel.writeInt(1); - parcel.writeStrongBinder(whitelistToken); + parcel.writeStrongBinder(mWhitelistToken); parcel.writeLong(when); parcel.writeLong(creationTime); if (mSmallIcon == null && icon != 0) { @@ -4981,6 +4981,8 @@ public class Notification implements Parcelable mN.flags |= FLAG_SHOW_LIGHTS; } + mN.allPendingIntents = null; + return mN; } diff --git a/core/java/android/app/PendingIntent.java b/core/java/android/app/PendingIntent.java index baeabc39e3fb..8b76cc7c966b 100644 --- a/core/java/android/app/PendingIntent.java +++ b/core/java/android/app/PendingIntent.java @@ -1129,8 +1129,13 @@ public final class PendingIntent implements Parcelable { */ public static void writePendingIntentOrNullToParcel(@Nullable PendingIntent sender, @NonNull Parcel out) { - out.writeStrongBinder(sender != null ? sender.mTarget.asBinder() - : null); + out.writeStrongBinder(sender != null ? sender.mTarget.asBinder() : null); + if (sender != null) { + OnMarshaledListener listener = sOnMarshaledListener.get(); + if (listener != null) { + listener.onMarshaled(sender, out, 0 /* flags */); + } + } } /** diff --git a/core/java/android/app/WindowConfiguration.java b/core/java/android/app/WindowConfiguration.java index 251863cae205..de27b4fd97f0 100644 --- a/core/java/android/app/WindowConfiguration.java +++ b/core/java/android/app/WindowConfiguration.java @@ -102,7 +102,7 @@ public class WindowConfiguration implements Parcelable, Comparable<WindowConfigu public static final int ACTIVITY_TYPE_STANDARD = 1; /** Home/Launcher activity type. */ public static final int ACTIVITY_TYPE_HOME = 2; - /** Recents/Overview activity type. */ + /** Recents/Overview activity type. There is only one activity with this type in the system. */ public static final int ACTIVITY_TYPE_RECENTS = 3; /** Assistant activity type. */ public static final int ACTIVITY_TYPE_ASSISTANT = 4; diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java index ab8edee724f2..772c6d60856f 100644 --- a/core/java/android/app/admin/DevicePolicyManager.java +++ b/core/java/android/app/admin/DevicePolicyManager.java @@ -1542,6 +1542,92 @@ public class DevicePolicyManager { public @interface ProvisioningPreCondition {} /** + * Disable all configurable SystemUI features during LockTask mode. This includes, + * <ul> + * <li>system info area in the status bar (connectivity icons, clock, etc.) + * <li>notifications (including alerts, icons, and the notification shade) + * <li>Home button + * <li>Recents button and UI + * <li>global actions menu (i.e. power button menu) + * <li>keyguard + * </ul> + * + * This is the default configuration for LockTask. + * + * @see #setLockTaskFeatures(ComponentName, int) + */ + public static final int LOCK_TASK_FEATURE_NONE = 0; + + /** + * Enable the system info area in the status bar during LockTask mode. The system info area + * usually occupies the right side of the status bar (although this can differ across OEMs). It + * includes all system information indicators, such as date and time, connectivity, battery, + * vibration mode, etc. + * + * @see #setLockTaskFeatures(ComponentName, int) + */ + public static final int LOCK_TASK_FEATURE_SYSTEM_INFO = 1; + + /** + * Enable notifications during LockTask mode. This includes notification icons on the status + * bar, heads-up notifications, and the expandable notification shade. Note that the Quick + * Settings panel will still be disabled. + * + * @see #setLockTaskFeatures(ComponentName, int) + */ + public static final int LOCK_TASK_FEATURE_NOTIFICATIONS = 1 << 1; + + /** + * Enable the Home button during LockTask mode. Note that if a custom launcher is used, it has + * to be registered as the default launcher with + * {@link #addPersistentPreferredActivity(ComponentName, IntentFilter, ComponentName)}, and its + * package needs to be whitelisted for LockTask with + * {@link #setLockTaskPackages(ComponentName, String[])}. + * + * @see #setLockTaskFeatures(ComponentName, int) + */ + public static final int LOCK_TASK_FEATURE_HOME = 1 << 2; + + /** + * Enable the Recents button and the Recents screen during LockTask mode. + * + * @see #setLockTaskFeatures(ComponentName, int) + */ + public static final int LOCK_TASK_FEATURE_RECENTS = 1 << 3; + + /** + * Enable the global actions dialog during LockTask mode. This is the dialog that shows up when + * the user long-presses the power button, for example. Note that the user may not be able to + * power off the device if this flag is not set. + * + * @see #setLockTaskFeatures(ComponentName, int) + */ + public static final int LOCK_TASK_FEATURE_GLOBAL_ACTIONS = 1 << 4; + + /** + * Enable the keyguard during LockTask mode. Note that if the keyguard is already disabled with + * {@link #setKeyguardDisabled(ComponentName, boolean)}, setting this flag will have no effect. + * If this flag is not set, the keyguard will not be shown even if the user has a lock screen + * credential. + * + * @see #setLockTaskFeatures(ComponentName, int) + */ + public static final int LOCK_TASK_FEATURE_KEYGUARD = 1 << 5; + + /** + * Flags supplied to {@link #setLockTaskFeatures(ComponentName, int)}. + * + * @hide + */ + @Retention(RetentionPolicy.SOURCE) + @IntDef(flag = true, + value = {LOCK_TASK_FEATURE_NONE, LOCK_TASK_FEATURE_SYSTEM_INFO, + LOCK_TASK_FEATURE_NOTIFICATIONS, LOCK_TASK_FEATURE_HOME, + LOCK_TASK_FEATURE_RECENTS, LOCK_TASK_FEATURE_GLOBAL_ACTIONS, + LOCK_TASK_FEATURE_KEYGUARD}) + public @interface LockTaskFeature {} + + /** * Service action: Action for a service that device owner and profile owner can optionally * own. If a device owner or a profile owner has such a service, the system tries to keep * a bound connection to it, in order to keep their process always running. @@ -6484,6 +6570,61 @@ public class DevicePolicyManager { } /** + * Sets which system features to enable for LockTask mode. + * <p> + * Feature flags set through this method will only take effect for the duration when the device + * is in LockTask mode. If this method is not called, none of the features listed here will be + * enabled. + * <p> + * This function can only be called by the device owner or by a profile owner of a user/profile + * that is affiliated with the device owner user. See {@link #setAffiliationIds}. Any features + * set via this method will be cleared if the user becomes unaffiliated. + * + * @param admin Which {@link DeviceAdminReceiver} this request is associated with. + * @param flags Bitfield of feature flags: + * {@link #LOCK_TASK_FEATURE_NONE} (default), + * {@link #LOCK_TASK_FEATURE_SYSTEM_INFO}, + * {@link #LOCK_TASK_FEATURE_NOTIFICATIONS}, + * {@link #LOCK_TASK_FEATURE_HOME}, + * {@link #LOCK_TASK_FEATURE_RECENTS}, + * {@link #LOCK_TASK_FEATURE_GLOBAL_ACTIONS}, + * {@link #LOCK_TASK_FEATURE_KEYGUARD} + * @throws SecurityException if {@code admin} is not the device owner, or the profile owner of + * an affiliated user or profile. + */ + public void setLockTaskFeatures(@NonNull ComponentName admin, @LockTaskFeature int flags) { + throwIfParentInstance("setLockTaskFeatures"); + if (mService != null) { + try { + mService.setLockTaskFeatures(admin, flags); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + } + + /** + * Gets which system features are enabled for LockTask mode. + * + * @param admin Which {@link DeviceAdminReceiver} this request is associated with. + * @return bitfield of flags. See {@link #setLockTaskFeatures(ComponentName, int)} for a list. + * @throws SecurityException if {@code admin} is not the device owner, or the profile owner of + * an affiliated user or profile. + * @see #setLockTaskFeatures(ComponentName, int) + */ + public @LockTaskFeature int getLockTaskFeatures(@NonNull ComponentName admin) { + throwIfParentInstance("getLockTaskFeatures"); + if (mService != null) { + try { + return mService.getLockTaskFeatures(admin); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + return 0; + } + + /** * Called by device owners to update {@link android.provider.Settings.Global} settings. * Validation that the value of the setting is in the correct form for the setting type should * be performed by the caller. @@ -6901,6 +7042,12 @@ public class DevicePolicyManager { * Called by device owner to disable the status bar. Disabling the status bar blocks * notifications, quick settings and other screen overlays that allow escaping from a single use * device. + * <p> + * <strong>Note:</strong> This method has no effect for LockTask mode. The behavior of the + * status bar in LockTask mode can be configured with + * {@link #setLockTaskFeatures(ComponentName, int)}. Calls to this method when the device is in + * LockTask mode will be registered, but will only take effect when the device leaves LockTask + * mode. * * @param admin Which {@link DeviceAdminReceiver} this request is associated with. * @param disabled {@code true} disables the status bar, {@code false} reenables it. diff --git a/core/java/android/app/admin/IDevicePolicyManager.aidl b/core/java/android/app/admin/IDevicePolicyManager.aidl index e77c18636594..be0b9205bcdd 100644 --- a/core/java/android/app/admin/IDevicePolicyManager.aidl +++ b/core/java/android/app/admin/IDevicePolicyManager.aidl @@ -226,6 +226,9 @@ interface IDevicePolicyManager { String[] getLockTaskPackages(in ComponentName who); boolean isLockTaskPermitted(in String pkg); + void setLockTaskFeatures(in ComponentName who, int flags); + int getLockTaskFeatures(in ComponentName who); + void setGlobalSetting(in ComponentName who, in String setting, in String value); void setSecureSetting(in ComponentName who, in String setting, in String value); diff --git a/core/java/android/hardware/location/ContextHubClient.java b/core/java/android/hardware/location/ContextHubClient.java new file mode 100644 index 000000000000..b7e353a4860c --- /dev/null +++ b/core/java/android/hardware/location/ContextHubClient.java @@ -0,0 +1,95 @@ +/* + * Copyright 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package android.hardware.location; + +import android.annotation.RequiresPermission; +import android.os.Handler; + +import java.io.Closeable; + +/** + * A class describing a client of the Context Hub Service. + * + * Clients can send messages to nanoapps at a Context Hub through this object. + * + * @hide + */ +public class ContextHubClient implements Closeable { + /* + * The ContextHubClient interface associated with this client. + */ + // TODO: Implement this interface and associate with ContextHubClient object + // private final IContextHubClient mClientInterface; + + /* + * The listening callback associated with this client. + */ + private ContextHubClientCallback mCallback; + + /* + * The Context Hub that this client is attached to. + */ + private ContextHubInfo mAttachedHub; + + /* + * The handler to invoke mCallback. + */ + private Handler mCallbackHandler; + + ContextHubClient(ContextHubClientCallback callback, Handler handler, ContextHubInfo hubInfo) { + mCallback = callback; + mCallbackHandler = handler; + mAttachedHub = hubInfo; + } + + /** + * Returns the hub that this client is attached to. + * + * @return the ContextHubInfo of the attached hub + */ + public ContextHubInfo getAttachedHub() { + return mAttachedHub; + } + + /** + * Closes the connection for this client and the Context Hub Service. + * + * When this function is invoked, the messaging associated with this client is invalidated. + * All futures messages targeted for this client are dropped at the service. + */ + public void close() { + throw new UnsupportedOperationException("TODO: Implement this"); + } + + /** + * Sends a message to a nanoapp through the Context Hub Service. + * + * This function returns TRANSACTION_SUCCESS if the message has reached the HAL, but + * does not guarantee delivery of the message to the target nanoapp. + * + * @param message the message object to send + * + * @return the result of sending the message defined as in ContextHubTransaction.Result + * + * @see NanoAppMessage + * @see ContextHubTransaction.Result + */ + @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) + @ContextHubTransaction.Result + public int sendMessageToNanoApp(NanoAppMessage message) { + throw new UnsupportedOperationException("TODO: Implement this"); + } +} diff --git a/core/java/android/hardware/location/ContextHubClientCallback.java b/core/java/android/hardware/location/ContextHubClientCallback.java new file mode 100644 index 000000000000..ab19d547025d --- /dev/null +++ b/core/java/android/hardware/location/ContextHubClientCallback.java @@ -0,0 +1,85 @@ +/* + * Copyright 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package android.hardware.location; + +/** + * A class for {@link android.hardware.location.ContextHubClient ContextHubClient} to + * receive messages and life-cycle events from nanoapps in the Context Hub at which the client is + * attached to. + * + * This callback is registered through the + * {@link android.hardware.location.ContextHubManager#createClient() creation} of + * {@link android.hardware.location.ContextHubClient ContextHubClient}. Callbacks are + * invoked in the following ways: + * 1) Messages from nanoapps delivered through onMessageFromNanoApp may either be broadcasted + * or targeted to a specific client. + * 2) Nanoapp or Context Hub events (the remaining callbacks) are broadcasted to all clients, and + * the client can choose to ignore the event by filtering through the parameters. + * + * @hide + */ +public class ContextHubClientCallback { + /** + * Callback invoked when receiving a message from a nanoapp. + * + * The message contents of this callback may either be broadcasted or targeted to the + * client receiving the invocation. + * + * @param message the message sent by the nanoapp + */ + public void onMessageFromNanoApp(NanoAppMessage message) {} + + /** + * Callback invoked when the attached Context Hub has reset. + */ + public void onHubReset() {} + + /** + * Callback invoked when a nanoapp aborts at the attached Context Hub. + * + * @param nanoAppId the ID of the nanoapp that had aborted + * @param abortCode the reason for nanoapp's abort, specific to each nanoapp + */ + public void onNanoAppAborted(long nanoAppId, int abortCode) {} + + /** + * Callback invoked when a nanoapp is loaded at the attached Context Hub. + * + * @param nanoAppId the ID of the nanoapp that had been loaded + */ + public void onNanoAppLoaded(long nanoAppId) {} + + /** + * Callback invoked when a nanoapp is unloaded from the attached Context Hub. + * + * @param nanoAppId the ID of the nanoapp that had been unloaded + */ + public void onNanoAppUnloaded(long nanoAppId) {} + + /** + * Callback invoked when a nanoapp is enabled at the attached Context Hub. + * + * @param nanoAppId the ID of the nanoapp that had been enabled + */ + public void onNanoAppEnabled(long nanoAppId) {} + + /** + * Callback invoked when a nanoapp is disabled at the attached Context Hub. + * + * @param nanoAppId the ID of the nanoapp that had been disabled + */ + public void onNanoAppDisabled(long nanoAppId) {} +} diff --git a/core/java/android/hardware/location/ContextHubManager.java b/core/java/android/hardware/location/ContextHubManager.java index 60500463d82e..7cbb436c84ee 100644 --- a/core/java/android/hardware/location/ContextHubManager.java +++ b/core/java/android/hardware/location/ContextHubManager.java @@ -15,6 +15,7 @@ */ package android.hardware.location; +import android.annotation.Nullable; import android.annotation.RequiresPermission; import android.annotation.SuppressLint; import android.annotation.SystemApi; @@ -27,6 +28,8 @@ import android.os.ServiceManager; import android.os.ServiceManager.ServiceNotFoundException; import android.util.Log; +import java.util.List; + /** * A class that exposes the Context hubs on a device to applications. * @@ -38,7 +41,6 @@ import android.util.Log; @SystemApi @SystemService(Context.CONTEXTHUB_SERVICE) public final class ContextHubManager { - private static final String TAG = "ContextHubManager"; private final Looper mMainLooper; @@ -256,6 +258,100 @@ public final class ContextHubManager { } /** + * Returns the list of context hubs in the system. + * + * @return the list of context hub informations + * + * @see ContextHubInfo + * + * @hide + */ + @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) + public List<ContextHubInfo> getContextHubs() { + throw new UnsupportedOperationException("TODO: Implement this"); + } + + /** + * Loads a nanoapp at the specified Context Hub. + * + * After the nanoapp binary is successfully loaded at the specified hub, the nanoapp will be in + * the enabled state. + * + * @param hubInfo the hub to load the nanoapp on + * @param appBinary The app binary to load + * + * @return the ContextHubTransaction of the request + * + * @see NanoAppBinary + * + * @hide + */ + @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) + public ContextHubTransaction<Void> loadNanoApp( + ContextHubInfo hubInfo, NanoAppBinary appBinary) { + throw new UnsupportedOperationException("TODO: Implement this"); + } + + /** + * Unloads a nanoapp at the specified Context Hub. + * + * @param hubInfo the hub to unload the nanoapp from + * @param nanoAppId the app to unload + * + * @return the ContextHubTransaction of the request + * + * @hide + */ + @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) + public ContextHubTransaction<Void> unloadNanoApp(ContextHubInfo hubInfo, long nanoAppId) { + throw new UnsupportedOperationException("TODO: Implement this"); + } + + /** + * Enables a nanoapp at the specified Context Hub. + * + * @param hubInfo the hub to enable the nanoapp on + * @param nanoAppId the app to enable + * + * @return the ContextHubTransaction of the request + * + * @hide + */ + @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) + public ContextHubTransaction<Void> enableNanoApp(ContextHubInfo hubInfo, long nanoAppId) { + throw new UnsupportedOperationException("TODO: Implement this"); + } + + /** + * Disables a nanoapp at the specified Context Hub. + * + * @param hubInfo the hub to disable the nanoapp on + * @param nanoAppId the app to disable + * + * @return the ContextHubTransaction of the request + * + * @hide + */ + @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) + public ContextHubTransaction<Void> disableNanoApp(ContextHubInfo hubInfo, long nanoAppId) { + throw new UnsupportedOperationException("TODO: Implement this"); + } + + /** + * Requests a query for nanoapps loaded at the specified Context Hub. + * + * @param hubInfo the hub to query a list of nanoapps from + * + * @return the ContextHubTransaction of the request + * + * @hide + */ + @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) + public ContextHubTransaction<List<NanoAppState>> queryNanoApps(ContextHubInfo hubInfo) { + throw new UnsupportedOperationException("TODO: Implement this"); + } + + /** * Set a callback to receive messages from the context hub * * @param callback Callback object @@ -307,6 +403,29 @@ public final class ContextHubManager { } /** + * Creates and registers a client and its callback with the Context Hub Service. + * + * A client is registered with the Context Hub Service for a specified Context Hub. When the + * registration succeeds, the client can send messages to nanoapps through the returned + * {@link ContextHubClient} object, and receive notifications through the provided callback. + * + * @param callback the notification callback to register + * @param hubInfo the hub to attach this client to + * @param handler the handler to invoke the callback, if null uses the current thread Looper + * + * @return the registered client object + * + * @see ContextHubClientCallback + * + * @hide + */ + public ContextHubClient createClient( + ContextHubClientCallback callback, ContextHubInfo hubInfo, @Nullable Handler handler) { + throw new UnsupportedOperationException( + "TODO: Implement this, and throw an exception on error"); + } + + /** * Unregister a callback for receive messages from the context hub. * * @see Callback diff --git a/core/java/android/hardware/location/ContextHubTransaction.java b/core/java/android/hardware/location/ContextHubTransaction.java new file mode 100644 index 000000000000..4877d38b37e0 --- /dev/null +++ b/core/java/android/hardware/location/ContextHubTransaction.java @@ -0,0 +1,229 @@ +/* + * Copyright 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package android.hardware.location; + +import android.annotation.IntDef; +import android.os.Handler; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.util.concurrent.TimeUnit; + +/** + * A class describing a request sent to the Context Hub Service. + * + * This object is generated as a result of an asynchronous request sent to the Context Hub + * through the ContextHubManager APIs. The caller can either retrieve the result + * synchronously through a blocking call ({@link #waitForResponse(long, TimeUnit)}) or + * asynchronously through a user-defined callback + * ({@link #onComplete(ContextHubTransaction.Callback<T>, Handler)}). + * + * A transaction can be invalidated if the caller of the transaction is no longer active + * and the reference to this object is lost, or if timeout period has passed in + * {@link #waitForResponse(long, TimeUnit)}. + * + * @param <T> the type of the contents in the transaction response + * + * @hide + */ +public class ContextHubTransaction<T> { + /** + * Constants describing the type of a transaction through the Context Hub Service. + */ + @Retention(RetentionPolicy.SOURCE) + @IntDef({ + TYPE_LOAD_NANOAPP, + TYPE_UNLOAD_NANOAPP, + TYPE_ENABLE_NANOAPP, + TYPE_DISABLE_NANOAPP, + TYPE_QUERY_NANOAPPS}) + public @interface Type {} + public static final int TYPE_LOAD_NANOAPP = 0; + public static final int TYPE_UNLOAD_NANOAPP = 1; + public static final int TYPE_ENABLE_NANOAPP = 2; + public static final int TYPE_DISABLE_NANOAPP = 3; + public static final int TYPE_QUERY_NANOAPPS = 4; + + /** + * Constants describing the result of a transaction or request through the Context Hub Service. + */ + @Retention(RetentionPolicy.SOURCE) + @IntDef({ + TRANSACTION_SUCCESS, + TRANSACTION_FAILED_UNKNOWN, + TRANSACTION_FAILED_BAD_PARAMS, + TRANSACTION_FAILED_UNINITIALIZED, + TRANSACTION_FAILED_PENDING, + TRANSACTION_FAILED_AT_HUB, + TRANSACTION_FAILED_TIMEOUT}) + public @interface Result {} + public static final int TRANSACTION_SUCCESS = 0; + /** + * Generic failure mode. + */ + public static final int TRANSACTION_FAILED_UNKNOWN = 1; + /** + * Failure mode when the request parameters were not valid. + */ + public static final int TRANSACTION_FAILED_BAD_PARAMS = 2; + /** + * Failure mode when the Context Hub is not initialized. + */ + public static final int TRANSACTION_FAILED_UNINITIALIZED = 3; + /** + * Failure mode when there are too many transactions pending. + */ + public static final int TRANSACTION_FAILED_PENDING = 4; + /** + * Failure mode when the request went through, but failed asynchronously at the hub. + */ + public static final int TRANSACTION_FAILED_AT_HUB = 5; + /** + * Failure mode when the transaction has timed out. + */ + public static final int TRANSACTION_FAILED_TIMEOUT = 6; + + /** + * A class describing the response for a ContextHubTransaction. + * + * @param <R> the type of the contents in the response + */ + public static class Response<R> { + /* + * The result of the transaction. + */ + @ContextHubTransaction.Result + private int mResult; + + /* + * The contents of the response from the Context Hub. + */ + private R mContents; + + Response(@ContextHubTransaction.Result int result, R contents) { + mResult = result; + mContents = contents; + } + + @ContextHubTransaction.Result + public int getResult() { + return mResult; + } + + public R getContents() { + return mContents; + } + } + + /** + * An interface describing the callback to be invoked when a transaction completes. + * + * @param <C> the type of the contents in the transaction response + */ + @FunctionalInterface + public interface Callback<C> { + /** + * The callback to invoke when the transaction completes. + * + * @param transaction the transaction that this callback was attached to. + * @param response the response of the transaction. + */ + void onComplete( + ContextHubTransaction<C> transaction, ContextHubTransaction.Response<C> response); + } + + /* + * The unique identifier representing the transaction. + */ + private int mTransactionId; + + /* + * The type of the transaction. + */ + @Type + private int mTransactionType; + + /* + * The response of the transaction. + */ + private ContextHubTransaction.Response<T> mResponse; + + /* + * The handler to invoke the aynsc response supplied by onComplete. + */ + private Handler mHandler = null; + + /* + * The callback to invoke when the transaction completes. + */ + private ContextHubTransaction.Callback<T> mCallback = null; + + ContextHubTransaction(int id, @Type int type) { + mTransactionId = id; + mTransactionType = type; + } + + /** + * @return the type of the transaction + */ + @Type + public int getType() { + return mTransactionType; + } + + /** + * Waits to receive the asynchronous transaction result. + * + * This function blocks until the Context Hub Service has received a response + * for the transaction represented by this object by the Context Hub, or a + * specified timeout period has elapsed. + * + * If the specified timeout has passed, the transaction represented by this object + * is invalidated by the Context Hub Service (resulting in a timeout failure in the + * response). + * + * @param timeout the timeout duration + * @param unit the unit of the timeout + * + * @return the transaction response + */ + public ContextHubTransaction.Response<T> waitForResponse(long timeout, TimeUnit unit) { + throw new UnsupportedOperationException("TODO: Implement this"); + } + + /** + * Sets a callback to be invoked when the transaction completes. + * + * This function provides an asynchronous approach to retrieve the result of the + * transaction. When the transaction response has been provided by the Context Hub, + * the given callback will be posted by the provided handler. + * + * If the transaction has already completed at the time of invocation, the callback + * will be immediately posted by the handler. If the transaction has been invalidated, + * the callback will never be invoked. + * + * @param callback the callback to be invoked upon completion + * @param handler the handler to post the callback + */ + public void onComplete(ContextHubTransaction.Callback<T> callback, Handler handler) { + throw new UnsupportedOperationException("TODO: Implement this"); + } + + private void setResponse(ContextHubTransaction.Response<T> response) { + mResponse = response; + throw new UnsupportedOperationException("TODO: Unblock waitForResponse"); + } +} diff --git a/core/java/android/hardware/location/NanoAppBinary.aidl b/core/java/android/hardware/location/NanoAppBinary.aidl new file mode 100644 index 000000000000..ff50c93e1e44 --- /dev/null +++ b/core/java/android/hardware/location/NanoAppBinary.aidl @@ -0,0 +1,22 @@ +/* + * Copyright 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.hardware.location; + +/** + * @hide + */ +parcelable NanoAppBinary; diff --git a/core/java/android/hardware/location/NanoAppBinary.java b/core/java/android/hardware/location/NanoAppBinary.java new file mode 100644 index 000000000000..545422773aed --- /dev/null +++ b/core/java/android/hardware/location/NanoAppBinary.java @@ -0,0 +1,198 @@ +/* + * Copyright 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package android.hardware.location; + +import android.os.Parcel; +import android.os.Parcelable; +import android.util.Log; + +import java.nio.BufferUnderflowException; +import java.nio.ByteBuffer; +import java.nio.ByteOrder; + +/** + * @hide + */ +public final class NanoAppBinary implements Parcelable { + private static final String TAG = "NanoAppBinary"; + + /* + * The contents of the app binary. + */ + private byte[] mNanoAppBinary; + + /* + * Contents of the nanoapp binary header. + * + * Only valid if mHasValidHeader is true. + * See nano_app_binary_t in context_hub.h for details. + */ + private int mHeaderVersion; + private int mMagic; + private long mNanoAppId; + private int mNanoAppVersion; + private int mFlags; + private long mHwHubType; + private byte mTargetChreApiMajorVersion; + private byte mTargetChreApiMinorVersion; + + private boolean mHasValidHeader = false; + + /* + * The header version used to parse the binary in parseBinaryHeader(). + */ + private static final int EXPECTED_HEADER_VERSION = 1; + + /* + * The magic value expected in the header. + */ + private static final int EXPECTED_MAGIC_VALUE = + (((int) 'N' << 0) | ((int) 'A' << 8) | ((int) 'N' << 16) | ((int) 'O' << 24)); + + /* + * Byte order established in context_hub.h + */ + private static final ByteOrder HEADER_ORDER = ByteOrder.LITTLE_ENDIAN; + + public NanoAppBinary(byte[] appBinary) { + mNanoAppBinary = appBinary; + parseBinaryHeader(); + } + + /* + * Parses the binary header and populates its field using mNanoAppBinary. + */ + private void parseBinaryHeader() { + ByteBuffer buf = ByteBuffer.wrap(mNanoAppBinary).order(HEADER_ORDER); + + mHasValidHeader = false; + try { + mHeaderVersion = buf.getInt(); + if (mHeaderVersion != EXPECTED_HEADER_VERSION) { + Log.e(TAG, "Unexpected header version " + mHeaderVersion + " while parsing header" + + " (expected " + EXPECTED_HEADER_VERSION + ")"); + return; + } + + mMagic = buf.getInt(); + mNanoAppId = buf.getLong(); + mNanoAppVersion = buf.getInt(); + mFlags = buf.getInt(); + mHwHubType = buf.getLong(); + mTargetChreApiMajorVersion = buf.get(); + mTargetChreApiMinorVersion = buf.get(); + } catch (BufferUnderflowException e) { + Log.e(TAG, "Not enough contents in nanoapp header"); + return; + } + + if (mMagic != EXPECTED_MAGIC_VALUE) { + Log.e(TAG, "Unexpected magic value " + String.format("0x%08X", mMagic) + + "while parsing header (expected " + + String.format("0x%08X", EXPECTED_MAGIC_VALUE) + ")"); + } else { + mHasValidHeader = true; + } + } + + /** + * @return the app binary byte array + */ + public byte[] getNanoAppBinary() { + return mNanoAppBinary; + } + + /** + * @return {@code true} if the header is valid, {@code false} otherwise + */ + public boolean hasValidHeader() { + return mHasValidHeader; + } + + /** + * @return the header version + */ + public int getHeaderVersion() { + return mHeaderVersion; + } + + /** + * @return the app ID parsed from the nanoapp header + */ + public long getNanoAppId() { + return mNanoAppId; + } + + /** + * @return the app version parsed from the nanoapp header + */ + public int getNanoAppVersion() { + return mNanoAppVersion; + } + + /** + * @return the compile target hub type parsed from the nanoapp header + */ + public long getHwHubType() { + return mHwHubType; + } + + /** + * @return the target CHRE API major version parsed from the nanoapp header + */ + public byte getTargetChreApiMajorVersion() { + return mTargetChreApiMajorVersion; + } + + /** + * @return the target CHRE API minor version parsed from the nanoapp header + */ + public byte getTargetChreApiMinorVersion() { + return mTargetChreApiMinorVersion; + } + + private NanoAppBinary(Parcel in) { + int binaryLength = in.readInt(); + mNanoAppBinary = new byte[binaryLength]; + in.readByteArray(mNanoAppBinary); + + parseBinaryHeader(); + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel out, int flags) { + out.writeInt(mNanoAppBinary.length); + out.writeByteArray(mNanoAppBinary); + } + + public static final Creator<NanoAppBinary> CREATOR = + new Creator<NanoAppBinary>() { + @Override + public NanoAppBinary createFromParcel(Parcel in) { + return new NanoAppBinary(in); + } + + @Override + public NanoAppBinary[] newArray(int size) { + return new NanoAppBinary[size]; + } + }; +} diff --git a/core/java/android/hardware/location/NanoAppMessage.aidl b/core/java/android/hardware/location/NanoAppMessage.aidl new file mode 100644 index 000000000000..f1f4ff69b7af --- /dev/null +++ b/core/java/android/hardware/location/NanoAppMessage.aidl @@ -0,0 +1,22 @@ +/* + * Copyright 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.hardware.location; + +/** + * @hide + */ +parcelable NanoAppMessage; diff --git a/core/java/android/hardware/location/NanoAppMessage.java b/core/java/android/hardware/location/NanoAppMessage.java new file mode 100644 index 000000000000..202867490fb9 --- /dev/null +++ b/core/java/android/hardware/location/NanoAppMessage.java @@ -0,0 +1,143 @@ +/* + * Copyright 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package android.hardware.location; + +import android.os.Parcel; +import android.os.Parcelable; + +/** + * A class describing messages send to or from nanoapps through the Context Hub Service. + * + * The basis of the class is in the IContextHub.hal ContextHubMsg definition. + * + * @hide + */ +public final class NanoAppMessage implements Parcelable { + private long mNanoAppId; + private int mMessageType; + private byte[] mMessageBody; + private boolean mIsBroadcasted; + + private NanoAppMessage( + long nanoAppId, int messageType, byte[] messageBody, boolean broadcasted) { + mNanoAppId = nanoAppId; + mMessageType = messageType; + mMessageBody = messageBody; + mIsBroadcasted = broadcasted; + } + + /** + * Creates a NanoAppMessage object to send to a nanoapp. + * + * This factory method can be used to generate a NanoAppMessage object to be used in + * the ContextHubClient.sendMessageToNanoApp API. + * + * @param targetNanoAppId the ID of the nanoapp to send the message to + * @param messageType the nanoapp-dependent message type + * @param messageBody the byte array message contents + * + * @return the NanoAppMessage object + */ + public static NanoAppMessage createMessageToNanoApp( + long targetNanoAppId, int messageType, byte[] messageBody) { + return new NanoAppMessage( + targetNanoAppId, messageType, messageBody, false /* broadcasted */); + } + + /** + * Creates a NanoAppMessage object sent from a nanoapp. + * + * This factory method is intended only to be used by the Context Hub Service when delivering + * messages from a nanoapp to clients. + * + * @param sourceNanoAppId the ID of the nanoapp that the message was sent from + * @param messageType the nanoapp-dependent message type + * @param messageBody the byte array message contents + * @param broadcasted {@code true} if the message was broadcasted, {@code false} otherwise + * + * @return the NanoAppMessage object + */ + public static NanoAppMessage createMessageFromNanoApp( + long sourceNanoAppId, int messageType, byte[] messageBody, boolean broadcasted) { + return new NanoAppMessage(sourceNanoAppId, messageType, messageBody, broadcasted); + } + + /** + * @return the ID of the source or destination nanoapp + */ + public long getNanoAppId() { + return mNanoAppId; + } + + /** + * @return the type of the message that is nanoapp-dependent + */ + public int getMessageType() { + return mMessageType; + } + + /** + * @return the byte array contents of the message + */ + public byte[] getMessageBody() { + return mMessageBody; + } + + /** + * @return {@code true} if the message is broadcasted, {@code false} otherwise + */ + public boolean isBroadcastMessage() { + return mIsBroadcasted; + } + + private NanoAppMessage(Parcel in) { + mNanoAppId = in.readLong(); + mIsBroadcasted = (in.readInt() == 1); + mMessageType = in.readInt(); + + int msgSize = in.readInt(); + mMessageBody = new byte[msgSize]; + in.readByteArray(mMessageBody); + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel out, int flags) { + out.writeLong(mNanoAppId); + out.writeInt(mIsBroadcasted ? 1 : 0); + out.writeInt(mMessageType); + + out.writeInt(mMessageBody.length); + out.writeByteArray(mMessageBody); + } + + public static final Creator<NanoAppMessage> CREATOR = + new Creator<NanoAppMessage>() { + @Override + public NanoAppMessage createFromParcel(Parcel in) { + return new NanoAppMessage(in); + } + + @Override + public NanoAppMessage[] newArray(int size) { + return new NanoAppMessage[size]; + } + }; +} diff --git a/core/java/android/hardware/location/NanoAppState.aidl b/core/java/android/hardware/location/NanoAppState.aidl new file mode 100644 index 000000000000..f80f4356ba55 --- /dev/null +++ b/core/java/android/hardware/location/NanoAppState.aidl @@ -0,0 +1,22 @@ +/* + * Copyright 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.hardware.location; + +/** + * @hide + */ +parcelable NanoAppState; diff --git a/core/java/android/hardware/location/NanoAppState.java b/core/java/android/hardware/location/NanoAppState.java new file mode 100644 index 000000000000..644031b034d5 --- /dev/null +++ b/core/java/android/hardware/location/NanoAppState.java @@ -0,0 +1,88 @@ +/* + * Copyright 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package android.hardware.location; + +import android.os.Parcel; +import android.os.Parcelable; + +/** + * A class describing the nanoapp state information resulting from a query to a Context Hub. + * + * @hide + */ +public final class NanoAppState implements Parcelable { + private long mNanoAppId; + private int mNanoAppVersion; + private boolean mIsEnabled; + + public NanoAppState(long nanoAppId, int appVersion, boolean enabled) { + mNanoAppId = nanoAppId; + mNanoAppVersion = appVersion; + mIsEnabled = enabled; + } + + /** + * @return the NanoAppInfo for this app + */ + public long getNanoAppId() { + return mNanoAppId; + } + + /** + * @return the app version + */ + public long getNanoAppVersion() { + return mNanoAppVersion; + } + + /** + * @return {@code true} if the app is enabled at the Context Hub, {@code false} otherwise + */ + public boolean isEnabled() { + return mIsEnabled; + } + + private NanoAppState(Parcel in) { + mNanoAppId = in.readLong(); + mNanoAppVersion = in.readInt(); + mIsEnabled = (in.readInt() == 1); + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel out, int flags) { + out.writeLong(mNanoAppId); + out.writeInt(mNanoAppVersion); + out.writeInt(mIsEnabled ? 1 : 0); + } + + public static final Creator<NanoAppState> CREATOR = + new Creator<NanoAppState>() { + @Override + public NanoAppState createFromParcel(Parcel in) { + return new NanoAppState(in); + } + + @Override + public NanoAppState[] newArray(int size) { + return new NanoAppState[size]; + } + }; +} diff --git a/core/java/android/os/Binder.java b/core/java/android/os/Binder.java index 66e1651997b4..ceeda042f9ad 100644 --- a/core/java/android/os/Binder.java +++ b/core/java/android/os/Binder.java @@ -27,6 +27,7 @@ import com.android.internal.util.FunctionalUtils.ThrowingRunnable; import com.android.internal.util.FunctionalUtils.ThrowingSupplier; import libcore.io.IoUtils; +import libcore.util.NativeAllocationRegistry; import java.io.FileDescriptor; import java.io.FileOutputStream; @@ -90,6 +91,20 @@ public class Binder implements IBinder { */ private static volatile TransactionTracker sTransactionTracker = null; + /** + * Guestimate of native memory associated with a Binder. + */ + private static final int NATIVE_ALLOCATION_SIZE = 500; + + private static native long getNativeFinalizer(); + + // Use a Holder to allow static initialization of Binder in the boot image, and + // possibly to avoid some initialization ordering issues. + private static class NoImagePreloadHolder { + public static final NativeAllocationRegistry sRegistry = new NativeAllocationRegistry( + Binder.class.getClassLoader(), getNativeFinalizer(), NATIVE_ALLOCATION_SIZE); + } + // Transaction tracking code. /** @@ -188,8 +203,11 @@ public class Binder implements IBinder { } } - /* mObject is used by native code, do not remove or rename */ - private long mObject; + /** + * Raw native pointer to JavaBBinderHolder object. Owned by this Java object. Not null. + */ + private final long mObject; + private IInterface mOwner; private String mDescriptor; @@ -360,7 +378,8 @@ public class Binder implements IBinder { * Default constructor initializes the object. */ public Binder() { - init(); + mObject = getNativeBBinderHolder(); + NoImagePreloadHolder.sRegistry.registerNativeAllocation(this, mObject); if (FIND_POTENTIAL_LEAKS) { final Class<? extends Binder> klass = getClass(); @@ -643,14 +662,6 @@ public class Binder implements IBinder { return true; } - protected void finalize() throws Throwable { - try { - destroyBinder(); - } finally { - super.finalize(); - } - } - static void checkParcel(IBinder obj, int code, Parcel parcel, String msg) { if (CHECK_PARCEL_SIZE && parcel.dataSize() >= 800*1024) { // Trying to send > 800k, this is way too much @@ -674,8 +685,8 @@ public class Binder implements IBinder { } } - private native final void init(); - private native final void destroyBinder(); + private static native long getNativeBBinderHolder(); + private static native long getFinalizer(); // Entry point from android_util_Binder.cpp's onTransact private boolean execTransact(int code, long dataObj, long replyObj, @@ -736,11 +747,25 @@ public class Binder implements IBinder { */ final class BinderProxy implements IBinder { // See android_util_Binder.cpp for the native half of this. - // TODO: Consider using NativeAllocationRegistry instead of finalization. // Assume the process-wide default value when created volatile boolean mWarnOnBlocking = Binder.sWarnOnBlocking; + /** + * Guestimate of native memory associated with a BinderProxy. + * This includes the underlying IBinder, associated DeathRecipientList, and KeyedVector + * that points back to us. We guess high since it includes a GlobalRef, which + * may be in short supply. + */ + private static final int NATIVE_ALLOCATION_SIZE = 1000; + + // Use a Holder to allow static initialization of BinderProxy in the boot image, and + // to avoid some initialization ordering issues. + private static class NoImagePreloadHolder { + public static final NativeAllocationRegistry sRegistry = new NativeAllocationRegistry( + BinderProxy.class.getClassLoader(), getNativeFinalizer(), NATIVE_ALLOCATION_SIZE); + } + public native boolean pingBinder(); public native boolean isBinderAlive(); @@ -776,6 +801,7 @@ final class BinderProxy implements IBinder { } } + private static native long getNativeFinalizer(); public native String getInterfaceDescriptor() throws RemoteException; public native boolean transactNative(int code, Parcel data, Parcel reply, int flags) throws RemoteException; @@ -830,21 +856,12 @@ final class BinderProxy implements IBinder { } } - BinderProxy() { + BinderProxy(long nativeData) { + mNativeData = nativeData; + NoImagePreloadHolder.sRegistry.registerNativeAllocation(this, mNativeData); mSelf = new WeakReference(this); } - @Override - protected void finalize() throws Throwable { - try { - destroy(); - } finally { - super.finalize(); - } - } - - private native final void destroy(); - private static final void sendDeathNotice(DeathRecipient recipient) { if (false) Log.v("JavaBinder", "sendDeathNotice to " + recipient); try { @@ -864,11 +881,9 @@ final class BinderProxy implements IBinder { // TODO: Consider making the extra native-to-java call to compute this on the fly. final private WeakReference mSelf; - // Native pointer to the wrapped native IBinder object. Counted as strong reference. - private long mObject; - - // Native pointer to native DeathRecipientList. Counted as strong reference. - // Basically owned by the JavaProxy object. Reference counted only because DeathRecipients - // hold a weak reference that can be temporarily promoted. - private long mOrgue; + /** + * C++ pointer to BinderProxyNativeData. That consists of strong pointers to the + * native IBinder object, and a DeathRecipientList. + */ + private final long mNativeData; } diff --git a/core/java/android/os/IServiceManager.java b/core/java/android/os/IServiceManager.java index 87c65ecc540b..2176a785e0a2 100644 --- a/core/java/android/os/IServiceManager.java +++ b/core/java/android/os/IServiceManager.java @@ -45,13 +45,13 @@ public interface IServiceManager extends IInterface * Place a new @a service called @a name into the service * manager. */ - void addService(String name, IBinder service, boolean allowIsolated, int dumpPriority) - throws RemoteException; + void addService(String name, IBinder service, boolean allowIsolated, int dumpFlags) + throws RemoteException; /** * Return a list of all currently running services. */ - String[] listServices(int dumpPriority) throws RemoteException; + String[] listServices(int dumpFlags) throws RemoteException; /** * Assign a permission controller to the service manager. After set, this @@ -72,9 +72,13 @@ public interface IServiceManager extends IInterface /* * Must update values in IServiceManager.h */ - int DUMP_PRIORITY_CRITICAL = 1 << 0; - int DUMP_PRIORITY_HIGH = 1 << 1; - int DUMP_PRIORITY_NORMAL = 1 << 2; - int DUMP_PRIORITY_ALL = DUMP_PRIORITY_CRITICAL | DUMP_PRIORITY_HIGH - | DUMP_PRIORITY_NORMAL; + /* Allows services to dump sections according to priorities. */ + int DUMP_FLAG_PRIORITY_CRITICAL = 1 << 0; + int DUMP_FLAG_PRIORITY_HIGH = 1 << 1; + int DUMP_FLAG_PRIORITY_NORMAL = 1 << 2; + int DUMP_FLAG_PRIORITY_ALL = DUMP_FLAG_PRIORITY_CRITICAL | DUMP_FLAG_PRIORITY_HIGH + | DUMP_FLAG_PRIORITY_NORMAL; + /* Allows services to dump sections in protobuf format. */ + int DUMP_FLAG_PROTO = 1 << 3; + } diff --git a/core/java/android/os/Parcel.java b/core/java/android/os/Parcel.java index 857e8a60098d..c2cf396716b8 100644 --- a/core/java/android/os/Parcel.java +++ b/core/java/android/os/Parcel.java @@ -561,6 +561,22 @@ public final class Parcel { mClassCookies = from.mClassCookies; } + /** @hide */ + public Map<Class, Object> copyClassCookies() { + return new ArrayMap<>(mClassCookies); + } + + /** @hide */ + public void putClassCookies(Map<Class, Object> cookies) { + if (cookies == null) { + return; + } + if (mClassCookies == null) { + mClassCookies = new ArrayMap<>(); + } + mClassCookies.putAll(cookies); + } + /** * Report whether the parcel contains any marshalled file descriptors. */ diff --git a/core/java/android/os/ServiceManager.java b/core/java/android/os/ServiceManager.java index f41848fad74a..42ec315c10e0 100644 --- a/core/java/android/os/ServiceManager.java +++ b/core/java/android/os/ServiceManager.java @@ -83,7 +83,7 @@ public final class ServiceManager { * @param service the service object */ public static void addService(String name, IBinder service) { - addService(name, service, false, IServiceManager.DUMP_PRIORITY_NORMAL); + addService(name, service, false, IServiceManager.DUMP_FLAG_PRIORITY_NORMAL); } /** @@ -96,7 +96,7 @@ public final class ServiceManager { * to access this service */ public static void addService(String name, IBinder service, boolean allowIsolated) { - addService(name, service, allowIsolated, IServiceManager.DUMP_PRIORITY_NORMAL); + addService(name, service, allowIsolated, IServiceManager.DUMP_FLAG_PRIORITY_NORMAL); } /** @@ -143,7 +143,7 @@ public final class ServiceManager { */ public static String[] listServices() { try { - return getIServiceManager().listServices(IServiceManager.DUMP_PRIORITY_ALL); + return getIServiceManager().listServices(IServiceManager.DUMP_FLAG_PRIORITY_ALL); } catch (RemoteException e) { Log.e(TAG, "error in listServices", e); return null; diff --git a/core/java/android/os/StrictMode.java b/core/java/android/os/StrictMode.java index 15468351102b..ee3e5bc9a001 100644 --- a/core/java/android/os/StrictMode.java +++ b/core/java/android/os/StrictMode.java @@ -1648,7 +1648,7 @@ public final class StrictMode { private static class AndroidCloseGuardReporter implements CloseGuard.Reporter { public void report(String message, Throwable allocationSite) { - onVmPolicyViolation(message, allocationSite); + onVmPolicyViolation(allocationSite); } } @@ -1687,7 +1687,7 @@ public final class StrictMode { long instances = instanceCounts[i]; if (instances > limit) { Throwable tr = new InstanceCountViolation(klass, instances, limit); - onVmPolicyViolation(tr.getMessage(), tr); + onVmPolicyViolation(tr); } } } @@ -1811,22 +1811,24 @@ public final class StrictMode { /** @hide */ public static void onSqliteObjectLeaked(String message, Throwable originStack) { - onVmPolicyViolation(message, originStack); + Throwable t = new Throwable(message); + t.setStackTrace(originStack.getStackTrace()); + onVmPolicyViolation(t); } /** @hide */ public static void onWebViewMethodCalledOnWrongThread(Throwable originStack) { - onVmPolicyViolation(null, originStack); + onVmPolicyViolation(originStack); } /** @hide */ public static void onIntentReceiverLeaked(Throwable originStack) { - onVmPolicyViolation(null, originStack); + onVmPolicyViolation(originStack); } /** @hide */ public static void onServiceConnectionLeaked(Throwable originStack) { - onVmPolicyViolation(null, originStack); + onVmPolicyViolation(originStack); } /** @hide */ @@ -1835,7 +1837,7 @@ public final class StrictMode { if ((sVmPolicy.mask & PENALTY_DEATH_ON_FILE_URI_EXPOSURE) != 0) { throw new FileUriExposedException(message); } else { - onVmPolicyViolation(null, new Throwable(message)); + onVmPolicyViolation(new Throwable(message)); } } @@ -1847,7 +1849,7 @@ public final class StrictMode { + location + " without permission grant flags; did you forget" + " FLAG_GRANT_READ_URI_PERMISSION?"; - onVmPolicyViolation(null, new Throwable(message)); + onVmPolicyViolation(new Throwable(message)); } /** @hide */ @@ -1877,10 +1879,9 @@ public final class StrictMode { } catch (UnknownHostException ignored) { } } - + msg += HexDump.dumpHexString(firstPacket).trim() + " "; final boolean forceDeath = (sVmPolicy.mask & PENALTY_DEATH_ON_CLEARTEXT_NETWORK) != 0; - onVmPolicyViolation( - HexDump.dumpHexString(firstPacket).trim(), new Throwable(msg), forceDeath); + onVmPolicyViolation(new Throwable(msg), forceDeath); } /** @hide */ @@ -1890,24 +1891,23 @@ public final class StrictMode { /** @hide */ public static void onUntaggedSocket() { - onVmPolicyViolation(null, new Throwable(UNTAGGED_SOCKET_VIOLATION_MESSAGE)); + onVmPolicyViolation(new Throwable(UNTAGGED_SOCKET_VIOLATION_MESSAGE)); } // Map from VM violation fingerprint to uptime millis. private static final HashMap<Integer, Long> sLastVmViolationTime = new HashMap<Integer, Long>(); /** @hide */ - public static void onVmPolicyViolation(String message, Throwable originStack) { - onVmPolicyViolation(message, originStack, false); + public static void onVmPolicyViolation(Throwable originStack) { + onVmPolicyViolation(originStack, false); } /** @hide */ - public static void onVmPolicyViolation( - String message, Throwable originStack, boolean forceDeath) { + public static void onVmPolicyViolation(Throwable originStack, boolean forceDeath) { final boolean penaltyDropbox = (sVmPolicy.mask & PENALTY_DROPBOX) != 0; final boolean penaltyDeath = ((sVmPolicy.mask & PENALTY_DEATH) != 0) || forceDeath; final boolean penaltyLog = (sVmPolicy.mask & PENALTY_LOG) != 0; - final ViolationInfo info = new ViolationInfo(message, originStack, sVmPolicy.mask); + final ViolationInfo info = new ViolationInfo(originStack, sVmPolicy.mask); // Erase stuff not relevant for process-wide violations info.numAnimationsRunning = 0; @@ -2225,7 +2225,7 @@ public final class StrictMode { // StrictMode not enabled. return; } - ((AndroidBlockGuardPolicy) policy).onUnbufferedIO(); + policy.onUnbufferedIO(); } /** @hide */ @@ -2235,7 +2235,7 @@ public final class StrictMode { // StrictMode not enabled. return; } - ((AndroidBlockGuardPolicy) policy).onReadFromDisk(); + policy.onReadFromDisk(); } /** @hide */ @@ -2245,7 +2245,7 @@ public final class StrictMode { // StrictMode not enabled. return; } - ((AndroidBlockGuardPolicy) policy).onWriteToDisk(); + policy.onWriteToDisk(); } @GuardedBy("StrictMode.class") @@ -2324,7 +2324,7 @@ public final class StrictMode { long instances = VMDebug.countInstancesOfClass(klass, false); if (instances > limit) { Throwable tr = new InstanceCountViolation(klass, instances, limit); - onVmPolicyViolation(tr.getMessage(), tr); + onVmPolicyViolation(tr); } } @@ -2336,9 +2336,6 @@ public final class StrictMode { */ @TestApi public static final class ViolationInfo implements Parcelable { - /** Some VM violations provide additional information outside the throwable. */ - @Nullable private final String mMessagePrefix; - /** Stack and violation details. */ @Nullable private final Throwable mThrowable; @@ -2382,24 +2379,12 @@ public final class StrictMode { /** Create an uninitialized instance of ViolationInfo */ public ViolationInfo() { - mMessagePrefix = null; mThrowable = null; policy = 0; } - /** Create an instance of ViolationInfo. */ + /** Create an instance of ViolationInfo initialized from an exception. */ public ViolationInfo(Throwable tr, int policy) { - this(null, tr, policy); - } - - /** - * Create an instance of ViolationInfo initialized from an exception with a message prefix. - * - * @deprecated prefixes belong in the Throwable. - */ - @Deprecated - public ViolationInfo(String messagePrefix, Throwable tr, int policy) { - this.mMessagePrefix = messagePrefix; this.mThrowable = tr; violationUptimeMillis = SystemClock.uptimeMillis(); this.policy = policy; @@ -2462,17 +2447,7 @@ public final class StrictMode { } /** - * A handful of VM violations provide extra information that should be presented before - * {@link #getViolationDetails()}. - * - * @hide - */ - @TestApi - public String getMessagePrefix() { - return mMessagePrefix != null ? mMessagePrefix : ""; - } - - /** If this violation has a useful stack trace. + * If this violation has a useful stack trace. * * @hide */ @@ -2552,7 +2527,6 @@ public final class StrictMode { * should be removed. */ public ViolationInfo(Parcel in, boolean unsetGatheringBit) { - mMessagePrefix = in.readString(); mThrowable = (Throwable) in.readSerializable(); int binderStackSize = in.readInt(); for (int i = 0; i < binderStackSize; i++) { @@ -2576,7 +2550,6 @@ public final class StrictMode { /** Save a ViolationInfo instance to a parcel. */ @Override public void writeToParcel(Parcel dest, int flags) { - dest.writeString(mMessagePrefix); dest.writeSerializable(mThrowable); dest.writeInt(mBinderStack.size()); for (Throwable t : mBinderStack) { diff --git a/core/java/android/service/autofill/SaveInfo.java b/core/java/android/service/autofill/SaveInfo.java index fde2416f053e..9a1dcbb2785f 100644 --- a/core/java/android/service/autofill/SaveInfo.java +++ b/core/java/android/service/autofill/SaveInfo.java @@ -535,14 +535,15 @@ public final class SaveInfo implements Parcelable { * 16 digits, or 15 digits starting with 108: * * <pre class="prettyprint"> - * import android.service.autofill.Validators; + * import static android.service.autofill.Validators.and; + * import static android.service.autofill.Validators.or; * * Validator validator = * and( * new LuhnChecksumValidator(ccNumberId), * or( - * new RegexValidator(ccNumberId, Pattern.compile(""^\\d{16}$")), - * new RegexValidator(ccNumberId, Pattern.compile(""^108\\d{12}$")) + * new RegexValidator(ccNumberId, Pattern.compile("^\\d{16}$")), + * new RegexValidator(ccNumberId, Pattern.compile("^108\\d{12}$")) * ) * ); * </pre> @@ -562,14 +563,14 @@ public final class SaveInfo implements Parcelable { * 4 digits on each field: * * <pre class="prettyprint"> - * import android.service.autofill.Validators; + * import static android.service.autofill.Validators.and; * * Validator validator = * and( - * new RegexValidator(ccNumberId1, Pattern.compile(""^\\d{4}$")), - * new RegexValidator(ccNumberId2, Pattern.compile(""^\\d{4}$")), - * new RegexValidator(ccNumberId3, Pattern.compile(""^\\d{4}$")), - * new RegexValidator(ccNumberId4, Pattern.compile(""^\\d{4}$")) + * new RegexValidator(ccNumberId1, Pattern.compile("^\\d{4}$")), + * new RegexValidator(ccNumberId2, Pattern.compile("^\\d{4}$")), + * new RegexValidator(ccNumberId3, Pattern.compile("^\\d{4}$")), + * new RegexValidator(ccNumberId4, Pattern.compile("^\\d{4}$")) * ); * </pre> * diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java index ff027a947d07..6f8315ae51bf 100644 --- a/core/java/android/view/SurfaceControl.java +++ b/core/java/android/view/SurfaceControl.java @@ -16,27 +16,22 @@ package android.view; -import static android.view.WindowManager.LayoutParams.INVALID_WINDOW_TYPE; - import android.annotation.Size; import android.graphics.Bitmap; import android.graphics.GraphicBuffer; -import android.graphics.Point; -import android.graphics.PointF; +import android.graphics.PixelFormat; import android.graphics.Rect; import android.graphics.Region; -import android.os.Binder; -import android.os.Debug; import android.os.IBinder; +import android.os.Process; +import android.os.UserHandle; import android.util.Log; import android.view.Surface.OutOfResourcesException; - import dalvik.system.CloseGuard; +import libcore.util.NativeAllocationRegistry; import java.io.Closeable; -import libcore.util.NativeAllocationRegistry; - /** * SurfaceControl * @hide @@ -60,6 +55,8 @@ public class SurfaceControl { private static native void nativeScreenshot(IBinder displayToken, Surface consumer, Rect sourceCrop, int width, int height, int minLayer, int maxLayer, boolean allLayers, boolean useIdentityTransform); + private static native void nativeCaptureLayers(IBinder layerHandleToken, Surface consumer, + int rotation); private static native long nativeCreateTransaction(); private static native long nativeGetNativeTransactionFinalizer(); @@ -186,7 +183,7 @@ public class SurfaceControl { /** * Surface creation flag: Indicates that the surface must be considered opaque, - * even if its pixel format is set to translucent. This can be useful if an + * even if its pixel format contains an alpha channel. This can be useful if an * application needs full RGBA 8888 support for instance but will * still draw every pixel opaque. * <p> @@ -307,6 +304,203 @@ public class SurfaceControl { public static final int WINDOW_TYPE_DONT_SCREENSHOT = 441731; /** + * Builder class for {@link SurfaceControl} objects. + */ + public static class Builder { + private SurfaceSession mSession; + private int mFlags = HIDDEN; + private int mWidth; + private int mHeight; + private int mFormat = PixelFormat.OPAQUE; + private String mName; + private SurfaceControl mParent; + private int mWindowType; + private int mOwnerUid; + + /** + * Begin building a SurfaceControl with a given {@link SurfaceSession}. + * + * @param session The {@link SurfaceSession} with which to eventually construct the surface. + */ + public Builder(SurfaceSession session) { + mSession = session; + } + + /** + * Construct a new {@link SurfaceControl} with the set parameters. + */ + public SurfaceControl build() { + if (mWidth <= 0 || mHeight <= 0) { + throw new IllegalArgumentException( + "width and height must be set"); + } + return new SurfaceControl(mSession, mName, mWidth, mHeight, mFormat, + mFlags, mParent, mWindowType, mOwnerUid); + } + + /** + * Set a debugging-name for the SurfaceControl. + * + * @param name A name to identify the Surface in debugging. + */ + public Builder setName(String name) { + mName = name; + return this; + } + + /** + * Set the initial size of the controlled surface's buffers in pixels. + * + * @param width The buffer width in pixels. + * @param height The buffer height in pixels. + */ + public Builder setSize(int width, int height) { + if (width <= 0 || height <= 0) { + throw new IllegalArgumentException( + "width and height must be positive"); + } + mWidth = width; + mHeight = height; + return this; + } + + /** + * Set the pixel format of the controlled surface's buffers, using constants from + * {@link android.graphics.PixelFormat}. + */ + public Builder setFormat(@PixelFormat.Format int format) { + mFormat = format; + return this; + } + + /** + * Specify if the app requires a hardware-protected path to + * an external display sync. If protected content is enabled, but + * such a path is not available, then the controlled Surface will + * not be displayed. + * + * @param protectedContent Whether to require a protected sink. + */ + public Builder setProtected(boolean protectedContent) { + if (protectedContent) { + mFlags |= PROTECTED_APP; + } else { + mFlags &= ~PROTECTED_APP; + } + return this; + } + + /** + * Specify whether the Surface contains secure content. If true, the system + * will prevent the surfaces content from being copied by another process. In + * particular screenshots and VNC servers will be disabled. This is however + * not a complete prevention of readback as {@link #setProtected}. + */ + public Builder setSecure(boolean secure) { + if (secure) { + mFlags |= SECURE; + } else { + mFlags &= ~SECURE; + } + return this; + } + + /** + * Indicates whether the surface must be considered opaque, + * even if its pixel format is set to translucent. This can be useful if an + * application needs full RGBA 8888 support for instance but will + * still draw every pixel opaque. + * <p> + * This flag only determines whether opacity will be sampled from the alpha channel. + * Plane-alpha from calls to setAlpha() can still result in blended composition + * regardless of the opaque setting. + * + * Combined effects are (assuming a buffer format with an alpha channel): + * <ul> + * <li>OPAQUE + alpha(1.0) == opaque composition + * <li>OPAQUE + alpha(0.x) == blended composition + * <li>OPAQUE + alpha(0.0) == no composition + * <li>!OPAQUE + alpha(1.0) == blended composition + * <li>!OPAQUE + alpha(0.x) == blended composition + * <li>!OPAQUE + alpha(0.0) == no composition + * </ul> + * If the underlying buffer lacks an alpha channel, it is as if setOpaque(true) + * were set automatically. + * @param opaque Whether the Surface is OPAQUE. + */ + public Builder setOpaque(boolean opaque) { + if (opaque) { + mFlags |= OPAQUE; + } else { + mFlags &= ~OPAQUE; + } + return this; + } + + /** + * Set a parent surface for our new SurfaceControl. + * + * Child surfaces are constrained to the onscreen region of their parent. + * Furthermore they stack relatively in Z order, and inherit the transformation + * of the parent. + * + * @param parent The parent control. + */ + public Builder setParent(SurfaceControl parent) { + mParent = parent; + return this; + } + + /** + * Set surface metadata. + * + * Currently these are window-types as per {@link WindowManager.LayoutParams} and + * owner UIDs. Child surfaces inherit their parents + * metadata so only the WindowManager needs to set this on root Surfaces. + * + * @param windowType A window-type + * @param ownerUid UID of the window owner. + */ + public Builder setMetadata(int windowType, int ownerUid) { + if (UserHandle.getAppId(Process.myUid()) != Process.SYSTEM_UID) { + throw new UnsupportedOperationException( + "It only makes sense to set Surface metadata from the WindowManager"); + } + mWindowType = windowType; + mOwnerUid = ownerUid; + return this; + } + + /** + * Indicate whether a 'ColorLayer' is to be constructed. + * + * Color layers will not have an associated BufferQueue and will instead always render a + * solid color (that is, solid before plane alpha). Currently that color is black. + * + * @param isColorLayer Whether to create a color layer. + */ + public Builder setColorLayer(boolean isColorLayer) { + if (isColorLayer) { + mFlags |= FX_SURFACE_DIM; + } else { + mFlags &= ~FX_SURFACE_DIM; + } + return this; + } + + /** + * Set 'Surface creation flags' such as {@link HIDDEN}, {@link SECURE}. + * + * TODO: Finish conversion to individual builder methods? + * @param flags The combined flags + */ + public Builder setFlags(int flags) { + mFlags = flags; + return this; + } + } + + /** * Create a surface with a name. * <p> * The surface creation flags specify what kind of surface to create and @@ -331,19 +525,7 @@ public class SurfaceControl { * * @throws throws OutOfResourcesException If the SurfaceControl cannot be created. */ - public SurfaceControl(SurfaceSession session, - String name, int w, int h, int format, int flags, int windowType, int ownerUid) - throws OutOfResourcesException { - this(session, name, w, h, format, flags, null, windowType, ownerUid); - } - - public SurfaceControl(SurfaceSession session, - String name, int w, int h, int format, int flags) - throws OutOfResourcesException { - this(session, name, w, h, format, flags, null, INVALID_WINDOW_TYPE, Binder.getCallingUid()); - } - - public SurfaceControl(SurfaceSession session, String name, int w, int h, int format, int flags, + private SurfaceControl(SurfaceSession session, String name, int w, int h, int format, int flags, SurfaceControl parent, int windowType, int ownerUid) throws OutOfResourcesException { if (session == null) { @@ -533,7 +715,7 @@ public class SurfaceControl { } } - public void setRelativeLayer(IBinder relativeTo, int zorder) { + public void setRelativeLayer(SurfaceControl relativeTo, int zorder) { checkNotReleased(); synchronized(SurfaceControl.class) { sGlobalTransaction.setRelativeLayer(this, relativeTo, zorder); @@ -970,6 +1152,20 @@ public class SurfaceControl { minLayer, maxLayer, allLayers, useIdentityTransform); } + /** + * Captures a layer and its children into the provided {@link Surface}. + * + * @param layerHandleToken The root layer to capture. + * @param consumer The {@link Surface} to capture the layer into. + * @param rotation Apply a custom clockwise rotation to the screenshot, i.e. + * Surface.ROTATION_0,90,180,270. Surfaceflinger will always capture in its + * native portrait orientation by default, so this is useful for returning + * captures that are independent of device orientation. + */ + public static void captureLayers(IBinder layerHandleToken, Surface consumer, int rotation) { + nativeCaptureLayers(layerHandleToken, consumer, rotation); + } + public static class Transaction implements Closeable { public static final NativeAllocationRegistry sRegistry = new NativeAllocationRegistry( Transaction.class.getClassLoader(), @@ -1035,9 +1231,9 @@ public class SurfaceControl { return this; } - public Transaction setRelativeLayer(SurfaceControl sc, IBinder relativeTo, int z) { + public Transaction setRelativeLayer(SurfaceControl sc, SurfaceControl relativeTo, int z) { nativeSetRelativeLayer(mNativeObject, sc.mNativeObject, - relativeTo, z); + relativeTo.getHandle(), z); return this; } diff --git a/core/java/android/view/SurfaceView.java b/core/java/android/view/SurfaceView.java index 462dad3fad7a..4eab496effda 100644 --- a/core/java/android/view/SurfaceView.java +++ b/core/java/android/view/SurfaceView.java @@ -532,10 +532,15 @@ public class SurfaceView extends View implements ViewRootImpl.WindowStoppedCallb mDeferredDestroySurfaceControl = mSurfaceControl; updateOpaqueFlag(); - mSurfaceControl = new SurfaceControlWithBackground(mSurfaceSession, - "SurfaceView - " + viewRoot.getTitle().toString(), - mSurfaceWidth, mSurfaceHeight, mFormat, - mSurfaceFlags); + final String name = "SurfaceView - " + viewRoot.getTitle().toString(); + + mSurfaceControl = new SurfaceControlWithBackground( + name, + (mSurfaceFlags & SurfaceControl.OPAQUE) != 0, + new SurfaceControl.Builder(mSurfaceSession) + .setSize(mSurfaceWidth, mSurfaceHeight) + .setFormat(mFormat) + .setFlags(mSurfaceFlags)); } else if (mSurfaceControl == null) { return; } @@ -1098,13 +1103,15 @@ public class SurfaceView extends View implements ViewRootImpl.WindowStoppedCallb private boolean mOpaque = true; public boolean mVisible = false; - public SurfaceControlWithBackground(SurfaceSession s, - String name, int w, int h, int format, int flags) + public SurfaceControlWithBackground(String name, boolean opaque, SurfaceControl.Builder b) throws Exception { - super(s, name, w, h, format, flags); - mBackgroundControl = new SurfaceControl(s, "Background for - " + name, w, h, - PixelFormat.OPAQUE, flags | SurfaceControl.FX_SURFACE_DIM); - mOpaque = (flags & SurfaceControl.OPAQUE) != 0; + super(b.setName(name).build()); + + mBackgroundControl = b.setName("Background for -" + name) + .setFormat(OPAQUE) + .setColorLayer(true) + .build(); + mOpaque = opaque; } @Override diff --git a/core/java/android/webkit/MimeTypeMap.java b/core/java/android/webkit/MimeTypeMap.java index 39874e82ec03..386169528e89 100644 --- a/core/java/android/webkit/MimeTypeMap.java +++ b/core/java/android/webkit/MimeTypeMap.java @@ -37,7 +37,7 @@ public class MimeTypeMap { } /** - * Returns the file extension or an empty string iff there is no + * Returns the file extension or an empty string if there is no * extension. This method is a convenience method for obtaining the * extension of a url and has undefined results for other Strings. * @param url @@ -76,7 +76,7 @@ public class MimeTypeMap { /** * Return {@code true} if the given MIME type has an entry in the map. * @param mimeType A MIME type (i.e. text/plain) - * @return {@code true} iff there is a mimeType entry in the map. + * @return {@code true} if there is a mimeType entry in the map. */ public boolean hasMimeType(String mimeType) { return MimeUtils.hasMimeType(mimeType); @@ -85,7 +85,7 @@ public class MimeTypeMap { /** * Return the MIME type for the given extension. * @param extension A file extension without the leading '.' - * @return The MIME type for the given extension or {@code null} iff there is none. + * @return The MIME type for the given extension or {@code null} if there is none. */ @Nullable public String getMimeTypeFromExtension(String extension) { @@ -100,7 +100,7 @@ public class MimeTypeMap { /** * Return {@code true} if the given extension has a registered MIME type. * @param extension A file extension without the leading '.' - * @return {@code true} iff there is an extension entry in the map. + * @return {@code true} if there is an extension entry in the map. */ public boolean hasExtension(String extension) { return MimeUtils.hasExtension(extension); @@ -111,7 +111,7 @@ public class MimeTypeMap { * MIME types map to multiple extensions. This call will return the most * common extension for the given MIME type. * @param mimeType A MIME type (i.e. text/plain) - * @return The extension for the given MIME type or {@code null} iff there is none. + * @return The extension for the given MIME type or {@code null} if there is none. */ @Nullable public String getExtensionFromMimeType(String mimeType) { diff --git a/core/java/android/webkit/URLUtil.java b/core/java/android/webkit/URLUtil.java index c2f121a13b91..84c000a379df 100644 --- a/core/java/android/webkit/URLUtil.java +++ b/core/java/android/webkit/URLUtil.java @@ -137,7 +137,7 @@ public final class URLUtil { } /** - * @return {@code true} iff the url is correctly URL encoded + * @return {@code true} if the url is correctly URL encoded */ static boolean verifyURLEncoding(String url) { int count = url.length(); @@ -171,14 +171,14 @@ public final class URLUtil { } /** - * @return {@code true} iff the url is an asset file. + * @return {@code true} if the url is an asset file. */ public static boolean isAssetUrl(String url) { return (null != url) && url.startsWith(ASSET_BASE); } /** - * @return {@code true} iff the url is a resource file. + * @return {@code true} if the url is a resource file. * @hide */ public static boolean isResourceUrl(String url) { @@ -186,7 +186,7 @@ public final class URLUtil { } /** - * @return {@code true} iff the url is a proxy url to allow cookieless network + * @return {@code true} if the url is a proxy url to allow cookieless network * requests from a file url. * @deprecated Cookieless proxy is no longer supported. */ @@ -196,7 +196,7 @@ public final class URLUtil { } /** - * @return {@code true} iff the url is a local file. + * @return {@code true} if the url is a local file. */ public static boolean isFileUrl(String url) { return (null != url) && (url.startsWith(FILE_BASE) && @@ -205,28 +205,28 @@ public final class URLUtil { } /** - * @return {@code true} iff the url is an about: url. + * @return {@code true} if the url is an about: url. */ public static boolean isAboutUrl(String url) { return (null != url) && url.startsWith("about:"); } /** - * @return {@code true} iff the url is a data: url. + * @return {@code true} if the url is a data: url. */ public static boolean isDataUrl(String url) { return (null != url) && url.startsWith("data:"); } /** - * @return {@code true} iff the url is a javascript: url. + * @return {@code true} if the url is a javascript: url. */ public static boolean isJavaScriptUrl(String url) { return (null != url) && url.startsWith("javascript:"); } /** - * @return {@code true} iff the url is an http: url. + * @return {@code true} if the url is an http: url. */ public static boolean isHttpUrl(String url) { return (null != url) && @@ -235,7 +235,7 @@ public final class URLUtil { } /** - * @return {@code true} iff the url is an https: url. + * @return {@code true} if the url is an https: url. */ public static boolean isHttpsUrl(String url) { return (null != url) && @@ -244,7 +244,7 @@ public final class URLUtil { } /** - * @return {@code true} iff the url is a network url. + * @return {@code true} if the url is a network url. */ public static boolean isNetworkUrl(String url) { if (url == null || url.length() == 0) { @@ -254,14 +254,14 @@ public final class URLUtil { } /** - * @return {@code true} iff the url is a content: url. + * @return {@code true} if the url is a content: url. */ public static boolean isContentUrl(String url) { return (null != url) && url.startsWith(CONTENT_BASE); } /** - * @return {@code true} iff the url is valid. + * @return {@code true} if the url is valid. */ public static boolean isValidUrl(String url) { if (url == null || url.length() == 0) { diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java index dfc81b2bcb5a..259bf60a3059 100644 --- a/core/java/android/webkit/WebView.java +++ b/core/java/android/webkit/WebView.java @@ -1103,7 +1103,7 @@ public class WebView extends AbsoluteLayout /** * Gets whether this WebView has a back history item. * - * @return {@code true} iff this WebView has a back history item + * @return {@code true} if this WebView has a back history item */ public boolean canGoBack() { checkThread(); @@ -1121,7 +1121,7 @@ public class WebView extends AbsoluteLayout /** * Gets whether this WebView has a forward history item. * - * @return {@code true} iff this WebView has a forward history item + * @return {@code true} if this WebView has a forward history item */ public boolean canGoForward() { checkThread(); diff --git a/core/java/android/webkit/WebViewFactory.java b/core/java/android/webkit/WebViewFactory.java index 48e427fd53b5..797bdfb705cb 100644 --- a/core/java/android/webkit/WebViewFactory.java +++ b/core/java/android/webkit/WebViewFactory.java @@ -137,7 +137,7 @@ public final class WebViewFactory { } /** - * Load the native library for the given package name iff that package + * Load the native library for the given package name if that package * name is the same as the one providing the webview. */ public static int loadWebViewNativeLibraryFromPackage(String packageName, diff --git a/core/java/android/webkit/WebViewLibraryLoader.java b/core/java/android/webkit/WebViewLibraryLoader.java index 175f35f41ebf..341c69fd2eba 100644 --- a/core/java/android/webkit/WebViewLibraryLoader.java +++ b/core/java/android/webkit/WebViewLibraryLoader.java @@ -16,6 +16,8 @@ package android.webkit; +import android.annotation.NonNull; +import android.annotation.Nullable; import android.app.ActivityManagerInternal; import android.content.pm.ApplicationInfo; import android.content.pm.PackageInfo; @@ -26,6 +28,7 @@ import android.os.SystemProperties; import android.text.TextUtils; import android.util.Log; +import com.android.internal.annotations.VisibleForTesting; import com.android.server.LocalServices; import dalvik.system.VMRuntime; @@ -36,7 +39,11 @@ import java.util.Arrays; import java.util.zip.ZipEntry; import java.util.zip.ZipFile; -class WebViewLibraryLoader { +/** + * @hide + */ +@VisibleForTesting +public class WebViewLibraryLoader { private static final String LOGTAG = WebViewLibraryLoader.class.getSimpleName(); private static final String CHROMIUM_WEBVIEW_NATIVE_RELRO_32 = @@ -94,7 +101,7 @@ class WebViewLibraryLoader { /** * Create a single relro file by invoking an isolated process that to do the actual work. */ - static void createRelroFile(final boolean is64Bit, String nativeLibraryPath) { + static void createRelroFile(final boolean is64Bit, @NonNull WebViewNativeLibrary nativeLib) { final String abi = is64Bit ? Build.SUPPORTED_64_BIT_ABIS[0] : Build.SUPPORTED_32_BIT_ABIS[0]; @@ -112,12 +119,12 @@ class WebViewLibraryLoader { }; try { - if (nativeLibraryPath == null) { + if (nativeLib == null || nativeLib.path == null) { throw new IllegalArgumentException( "Native library paths to the WebView RelRo process must not be null!"); } int pid = LocalServices.getService(ActivityManagerInternal.class).startIsolatedProcess( - RelroFileCreator.class.getName(), new String[] { nativeLibraryPath }, + RelroFileCreator.class.getName(), new String[] { nativeLib.path }, "WebViewLoader-" + abi, abi, Process.SHARED_RELRO_UID, crashHandler); if (pid <= 0) throw new Exception("Failed to start the relro file creator process"); } catch (Throwable t) { @@ -127,25 +134,48 @@ class WebViewLibraryLoader { } } + /** + * Perform preparations needed to allow loading WebView from an application. This method should + * be called whenever we change WebView provider. + * @return the number of relro processes started. + */ static int prepareNativeLibraries(PackageInfo webviewPackageInfo) throws WebViewFactory.MissingWebViewPackageException { - String[] nativeLibs = updateWebViewZygoteVmSize(webviewPackageInfo); + WebViewNativeLibrary nativeLib32bit = + getWebViewNativeLibrary(webviewPackageInfo, false /* is64bit */); + WebViewNativeLibrary nativeLib64bit = + getWebViewNativeLibrary(webviewPackageInfo, true /* is64bit */); + updateWebViewZygoteVmSize(nativeLib32bit, nativeLib64bit); + + return createRelros(nativeLib32bit, nativeLib64bit); + } + + /** + * @return the number of relro processes started. + */ + private static int createRelros(@Nullable WebViewNativeLibrary nativeLib32bit, + @Nullable WebViewNativeLibrary nativeLib64bit) { if (DEBUG) Log.v(LOGTAG, "creating relro files"); int numRelros = 0; - // We must always trigger createRelRo regardless of the value of nativeLibraryPaths. Any - // unexpected values will be handled there to ensure that we trigger notifying any process - // waiting on relro creation. if (Build.SUPPORTED_32_BIT_ABIS.length > 0) { - if (DEBUG) Log.v(LOGTAG, "Create 32 bit relro"); - createRelroFile(false /* is64Bit */, nativeLibs[0]); - numRelros++; + if (nativeLib32bit == null) { + Log.e(LOGTAG, "No 32-bit WebView library path, skipping relro creation."); + } else { + if (DEBUG) Log.v(LOGTAG, "Create 32 bit relro"); + createRelroFile(false /* is64Bit */, nativeLib32bit); + numRelros++; + } } if (Build.SUPPORTED_64_BIT_ABIS.length > 0) { - if (DEBUG) Log.v(LOGTAG, "Create 64 bit relro"); - createRelroFile(true /* is64Bit */, nativeLibs[1]); - numRelros++; + if (nativeLib64bit == null) { + Log.e(LOGTAG, "No 64-bit WebView library path, skipping relro creation."); + } else { + if (DEBUG) Log.v(LOGTAG, "Create 64 bit relro"); + createRelroFile(true /* is64Bit */, nativeLib64bit); + numRelros++; + } } return numRelros; } @@ -154,53 +184,28 @@ class WebViewLibraryLoader { * * @return the native WebView libraries in the new WebView APK. */ - private static String[] updateWebViewZygoteVmSize(PackageInfo packageInfo) + private static void updateWebViewZygoteVmSize( + @Nullable WebViewNativeLibrary nativeLib32bit, + @Nullable WebViewNativeLibrary nativeLib64bit) throws WebViewFactory.MissingWebViewPackageException { // Find the native libraries of the new WebView package, to change the size of the // memory region in the Zygote reserved for the library. - String[] nativeLibs = getWebViewNativeLibraryPaths(packageInfo); - if (nativeLibs != null) { - long newVmSize = 0L; - - for (String path : nativeLibs) { - if (path == null || TextUtils.isEmpty(path)) continue; - if (DEBUG) Log.d(LOGTAG, "Checking file size of " + path); - File f = new File(path); - if (f.exists()) { - newVmSize = Math.max(newVmSize, f.length()); - continue; - } - if (path.contains("!/")) { - String[] split = TextUtils.split(path, "!/"); - if (split.length == 2) { - try (ZipFile z = new ZipFile(split[0])) { - ZipEntry e = z.getEntry(split[1]); - if (e != null && e.getMethod() == ZipEntry.STORED) { - newVmSize = Math.max(newVmSize, e.getSize()); - continue; - } - } - catch (IOException e) { - Log.e(LOGTAG, "error reading APK file " + split[0] + ", ", e); - } - } - } - Log.e(LOGTAG, "error sizing load for " + path); - } + long newVmSize = 0L; - if (DEBUG) { - Log.v(LOGTAG, "Based on library size, need " + newVmSize - + " bytes of address space."); - } - // The required memory can be larger than the file on disk (due to .bss), and an - // upgraded version of the library will likely be larger, so always attempt to - // reserve twice as much as we think to allow for the library to grow during this - // boot cycle. - newVmSize = Math.max(2 * newVmSize, CHROMIUM_WEBVIEW_DEFAULT_VMSIZE_BYTES); - Log.d(LOGTAG, "Setting new address space to " + newVmSize); - setWebViewZygoteVmSize(newVmSize); + if (nativeLib32bit != null) newVmSize = Math.max(newVmSize, nativeLib32bit.size); + if (nativeLib64bit != null) newVmSize = Math.max(newVmSize, nativeLib64bit.size); + + if (DEBUG) { + Log.v(LOGTAG, "Based on library size, need " + newVmSize + + " bytes of address space."); } - return nativeLibs; + // The required memory can be larger than the file on disk (due to .bss), and an + // upgraded version of the library will likely be larger, so always attempt to + // reserve twice as much as we think to allow for the library to grow during this + // boot cycle. + newVmSize = Math.max(2 * newVmSize, CHROMIUM_WEBVIEW_DEFAULT_VMSIZE_BYTES); + Log.d(LOGTAG, "Setting new address space to " + newVmSize); + setWebViewZygoteVmSize(newVmSize); } /** @@ -250,64 +255,78 @@ class WebViewLibraryLoader { /** * Fetch WebView's native library paths from {@param packageInfo}. + * @hide */ - static String[] getWebViewNativeLibraryPaths(PackageInfo packageInfo) - throws WebViewFactory.MissingWebViewPackageException { + @Nullable + @VisibleForTesting + public static WebViewNativeLibrary getWebViewNativeLibrary(PackageInfo packageInfo, + boolean is64bit) throws WebViewFactory.MissingWebViewPackageException { ApplicationInfo ai = packageInfo.applicationInfo; final String nativeLibFileName = WebViewFactory.getWebViewLibrary(ai); - String path32; - String path64; - boolean primaryArchIs64bit = VMRuntime.is64BitAbi(ai.primaryCpuAbi); - if (!TextUtils.isEmpty(ai.secondaryCpuAbi)) { - // Multi-arch case. - if (primaryArchIs64bit) { - // Primary arch: 64-bit, secondary: 32-bit. - path64 = ai.nativeLibraryDir; - path32 = ai.secondaryNativeLibraryDir; - } else { - // Primary arch: 32-bit, secondary: 64-bit. - path64 = ai.secondaryNativeLibraryDir; - path32 = ai.nativeLibraryDir; - } - } else if (primaryArchIs64bit) { - // Single-arch 64-bit. - path64 = ai.nativeLibraryDir; - path32 = ""; - } else { - // Single-arch 32-bit. - path32 = ai.nativeLibraryDir; - path64 = ""; + String dir = getWebViewNativeLibraryDirectory(ai, is64bit /* 64bit */); + + WebViewNativeLibrary lib = findNativeLibrary(ai, nativeLibFileName, + is64bit ? Build.SUPPORTED_64_BIT_ABIS : Build.SUPPORTED_32_BIT_ABIS, dir); + + if (DEBUG) { + Log.v(LOGTAG, String.format("Native %d-bit lib: %s", is64bit ? 64 : 32, lib.path)); } + return lib; + } - // Form the full paths to the extracted native libraries. - // If libraries were not extracted, try load from APK paths instead. - if (!TextUtils.isEmpty(path32)) { - path32 += "/" + nativeLibFileName; - File f = new File(path32); - if (!f.exists()) { - path32 = getLoadFromApkPath(ai.sourceDir, - Build.SUPPORTED_32_BIT_ABIS, - nativeLibFileName); - } + /** + * @return the directory of the native WebView library with bitness {@param is64bit}. + * @hide + */ + @VisibleForTesting + public static String getWebViewNativeLibraryDirectory(ApplicationInfo ai, boolean is64bit) { + // Primary arch has the same bitness as the library we are looking for. + if (is64bit == VMRuntime.is64BitAbi(ai.primaryCpuAbi)) return ai.nativeLibraryDir; + + // Secondary arch has the same bitness as the library we are looking for. + if (!TextUtils.isEmpty(ai.secondaryCpuAbi)) { + return ai.secondaryNativeLibraryDir; } - if (!TextUtils.isEmpty(path64)) { - path64 += "/" + nativeLibFileName; - File f = new File(path64); - if (!f.exists()) { - path64 = getLoadFromApkPath(ai.sourceDir, - Build.SUPPORTED_64_BIT_ABIS, - nativeLibFileName); - } + + return ""; + } + + /** + * @return an object describing a native WebView library given the directory path of that + * library, or null if the library couldn't be found. + */ + @Nullable + private static WebViewNativeLibrary findNativeLibrary(ApplicationInfo ai, + String nativeLibFileName, String[] abiList, String libDirectory) + throws WebViewFactory.MissingWebViewPackageException { + if (TextUtils.isEmpty(libDirectory)) return null; + String libPath = libDirectory + "/" + nativeLibFileName; + File f = new File(libPath); + if (f.exists()) { + return new WebViewNativeLibrary(libPath, f.length()); + } else { + return getLoadFromApkPath(ai.sourceDir, abiList, nativeLibFileName); } + } - if (DEBUG) Log.v(LOGTAG, "Native 32-bit lib: " + path32 + ", 64-bit lib: " + path64); - return new String[] { path32, path64 }; + /** + * @hide + */ + @VisibleForTesting + public static class WebViewNativeLibrary { + public final String path; + public final long size; + + WebViewNativeLibrary(String path, long size) { + this.path = path; + this.size = size; + } } - private static String getLoadFromApkPath(String apkPath, - String[] abiList, - String nativeLibFileName) + private static WebViewNativeLibrary getLoadFromApkPath(String apkPath, + String[] abiList, + String nativeLibFileName) throws WebViewFactory.MissingWebViewPackageException { // Search the APK for a native library conforming to a listed ABI. try (ZipFile z = new ZipFile(apkPath)) { @@ -316,13 +335,13 @@ class WebViewLibraryLoader { ZipEntry e = z.getEntry(entry); if (e != null && e.getMethod() == ZipEntry.STORED) { // Return a path formatted for dlopen() load from APK. - return apkPath + "!/" + entry; + return new WebViewNativeLibrary(apkPath + "!/" + entry, e.getSize()); } } } catch (IOException e) { throw new WebViewFactory.MissingWebViewPackageException(e); } - return ""; + return null; } /** diff --git a/core/java/android/widget/RemoteViews.java b/core/java/android/widget/RemoteViews.java index 631f3882104b..e330916130dd 100644 --- a/core/java/android/widget/RemoteViews.java +++ b/core/java/android/widget/RemoteViews.java @@ -81,6 +81,7 @@ import java.lang.invoke.MethodType; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.HashMap; +import java.util.Map; import java.util.Stack; import java.util.concurrent.Executor; @@ -185,6 +186,9 @@ public class RemoteViews implements Parcelable, Filter { */ private boolean mIsWidgetCollectionChild = false; + /** Class cookies of the Parcel this instance was read from. */ + private final Map<Class, Object> mClassCookies; + private static final OnClickHandler DEFAULT_ON_CLICK_HANDLER = new OnClickHandler(); private static final ArrayMap<MethodKey, MethodArgs> sMethods = new ArrayMap<>(); @@ -1505,10 +1509,10 @@ public class RemoteViews implements Parcelable, Filter { } ViewGroupActionAdd(Parcel parcel, BitmapCache bitmapCache, ApplicationInfo info, - int depth) { + int depth, Map<Class, Object> classCookies) { viewId = parcel.readInt(); mIndex = parcel.readInt(); - mNestedViews = new RemoteViews(parcel, bitmapCache, info, depth); + mNestedViews = new RemoteViews(parcel, bitmapCache, info, depth, classCookies); } public void writeToParcel(Parcel dest, int flags) { @@ -2120,6 +2124,7 @@ public class RemoteViews implements Parcelable, Filter { mApplication = application; mLayoutId = layoutId; mBitmapCache = new BitmapCache(); + mClassCookies = null; } private boolean hasLandscapeAndPortraitLayouts() { @@ -2149,6 +2154,9 @@ public class RemoteViews implements Parcelable, Filter { mBitmapCache = new BitmapCache(); configureRemoteViewsAsChild(landscape); configureRemoteViewsAsChild(portrait); + + mClassCookies = (portrait.mClassCookies != null) + ? portrait.mClassCookies : landscape.mClassCookies; } /** @@ -2161,15 +2169,16 @@ public class RemoteViews implements Parcelable, Filter { mLayoutId = src.mLayoutId; mIsWidgetCollectionChild = src.mIsWidgetCollectionChild; mReapplyDisallowed = src.mReapplyDisallowed; + mClassCookies = src.mClassCookies; if (src.hasLandscapeAndPortraitLayouts()) { mLandscape = new RemoteViews(src.mLandscape); mPortrait = new RemoteViews(src.mPortrait); - } if (src.mActions != null) { Parcel p = Parcel.obtain(); + p.putClassCookies(mClassCookies); src.writeActionsToParcel(p); p.setDataPosition(0); // Since src is already in memory, we do not care about stack overflow as it has @@ -2189,10 +2198,11 @@ public class RemoteViews implements Parcelable, Filter { * @param parcel */ public RemoteViews(Parcel parcel) { - this(parcel, null, null, 0); + this(parcel, null, null, 0, null); } - private RemoteViews(Parcel parcel, BitmapCache bitmapCache, ApplicationInfo info, int depth) { + private RemoteViews(Parcel parcel, BitmapCache bitmapCache, ApplicationInfo info, int depth, + Map<Class, Object> classCookies) { if (depth > MAX_NESTED_VIEWS && (UserHandle.getAppId(Binder.getCallingUid()) != Process.SYSTEM_UID)) { throw new IllegalArgumentException("Too many nested views."); @@ -2204,8 +2214,11 @@ public class RemoteViews implements Parcelable, Filter { // We only store a bitmap cache in the root of the RemoteViews. if (bitmapCache == null) { mBitmapCache = new BitmapCache(parcel); + // Store the class cookies such that they are available when we clone this RemoteView. + mClassCookies = parcel.copyClassCookies(); } else { setBitmapCache(bitmapCache); + mClassCookies = classCookies; setNotRoot(); } @@ -2218,8 +2231,9 @@ public class RemoteViews implements Parcelable, Filter { readActionsFromParcel(parcel, depth); } else { // MODE_HAS_LANDSCAPE_AND_PORTRAIT - mLandscape = new RemoteViews(parcel, mBitmapCache, info, depth); - mPortrait = new RemoteViews(parcel, mBitmapCache, mLandscape.mApplication, depth); + mLandscape = new RemoteViews(parcel, mBitmapCache, info, depth, mClassCookies); + mPortrait = new RemoteViews(parcel, mBitmapCache, mLandscape.mApplication, depth, + mClassCookies); mApplication = mPortrait.mApplication; mLayoutId = mPortrait.getLayoutId(); } @@ -2246,7 +2260,8 @@ public class RemoteViews implements Parcelable, Filter { case REFLECTION_ACTION_TAG: return new ReflectionAction(parcel); case VIEW_GROUP_ACTION_ADD_TAG: - return new ViewGroupActionAdd(parcel, mBitmapCache, mApplication, depth); + return new ViewGroupActionAdd(parcel, mBitmapCache, mApplication, depth, + mClassCookies); case VIEW_GROUP_ACTION_REMOVE_TAG: return new ViewGroupActionRemove(parcel); case VIEW_CONTENT_NAVIGATION_TAG: diff --git a/core/jni/android/graphics/Paint.cpp b/core/jni/android/graphics/Paint.cpp index fd62a19f310f..e8e3f57c718b 100644 --- a/core/jni/android/graphics/Paint.cpp +++ b/core/jni/android/graphics/Paint.cpp @@ -112,8 +112,8 @@ namespace PaintGlue { float measured = 0; std::unique_ptr<float[]> advancesArray(new float[count]); - MinikinUtils::measureText(&paint, bidiFlags, typeface, text, 0, count, count, - advancesArray.get()); + MinikinUtils::measureText(&paint, static_cast<minikin::Bidi>(bidiFlags), typeface, text, + 0, count, count, advancesArray.get()); for (int i = 0; i < count; i++) { // traverse in the given direction @@ -203,8 +203,9 @@ namespace PaintGlue { if (advances) { advancesArray.reset(new jfloat[count]); } - const float advance = MinikinUtils::measureText(paint, bidiFlags, typeface, text, - start, count, contextCount, advancesArray.get()); + const float advance = MinikinUtils::measureText(paint, + static_cast<minikin::Bidi>(bidiFlags), typeface, text, start, count, contextCount, + advancesArray.get()); if (advances) { env->SetFloatArrayRegion(advances, advancesIndex, count, advancesArray.get()); } @@ -239,7 +240,7 @@ namespace PaintGlue { static jint doTextRunCursor(JNIEnv *env, Paint* paint, const Typeface* typeface, const jchar *text, jint start, jint count, jint dir, jint offset, jint opt) { minikin::GraphemeBreak::MoveOpt moveOpt = minikin::GraphemeBreak::MoveOpt(opt); - int bidiFlags = dir == 1 ? minikin::kBidi_Force_RTL : minikin::kBidi_Force_LTR; + minikin::Bidi bidiFlags = dir == 1 ? minikin::Bidi::FORCE_RTL : minikin::Bidi::FORCE_LTR; std::unique_ptr<float[]> advancesArray(new float[count]); MinikinUtils::measureText(paint, bidiFlags, typeface, text, start, count, start + count, advancesArray.get()); @@ -305,7 +306,7 @@ namespace PaintGlue { static void getTextPath(JNIEnv* env, Paint* paint, const Typeface* typeface, const jchar* text, jint count, jint bidiFlags, jfloat x, jfloat y, SkPath* path) { minikin::Layout layout = MinikinUtils::doLayout( - paint, bidiFlags, typeface, text, 0, count, count); + paint, static_cast<minikin::Bidi>(bidiFlags), typeface, text, 0, count, count); size_t nGlyphs = layout.nGlyphs(); uint16_t* glyphs = new uint16_t[nGlyphs]; SkPoint* pos = new SkPoint[nGlyphs]; @@ -346,8 +347,8 @@ namespace PaintGlue { SkRect r; SkIRect ir; - minikin::Layout layout = MinikinUtils::doLayout( - &paint, bidiFlags, typeface, text, 0, count, count); + minikin::Layout layout = MinikinUtils::doLayout(&paint, + static_cast<minikin::Bidi>(bidiFlags), typeface, text, 0, count, count); minikin::MinikinRect rect; layout.getBounds(&rect); r.fLeft = rect.mLeft; @@ -461,8 +462,9 @@ namespace PaintGlue { nChars++; prevCp = cp; } - minikin::Layout layout = MinikinUtils::doLayout( - paint, bidiFlags, typeface, str.get(), 0, str.size(), str.size()); + minikin::Layout layout = MinikinUtils::doLayout(paint, + static_cast<minikin::Bidi>(bidiFlags), typeface, str.get(), 0, str.size(), + str.size()); size_t nGlyphs = countNonSpaceGlyphs(layout); if (nGlyphs != 1 && nChars > 1) { // multiple-character input, and was not a ligature @@ -481,8 +483,8 @@ namespace PaintGlue { // since ZZ is reserved for unknown or invalid territory. // U+1F1FF (REGIONAL INDICATOR SYMBOL LETTER Z) is \uD83C\uDDFF in UTF16. static const jchar ZZ_FLAG_STR[] = { 0xD83C, 0xDDFF, 0xD83C, 0xDDFF }; - minikin::Layout zzLayout = MinikinUtils::doLayout( - paint, bidiFlags, typeface, ZZ_FLAG_STR, 0, 4, 4); + minikin::Layout zzLayout = MinikinUtils::doLayout(paint, + static_cast<minikin::Bidi>(bidiFlags), typeface, ZZ_FLAG_STR, 0, 4, 4); if (zzLayout.nGlyphs() != 1 || layoutContainsNotdef(zzLayout)) { // The font collection doesn't have a glyph for unknown flag. Just return true. return true; @@ -494,7 +496,7 @@ namespace PaintGlue { static jfloat doRunAdvance(const Paint* paint, const Typeface* typeface, const jchar buf[], jint start, jint count, jint bufSize, jboolean isRtl, jint offset) { - int bidiFlags = isRtl ? minikin::kBidi_Force_RTL : minikin::kBidi_Force_LTR; + minikin::Bidi bidiFlags = isRtl ? minikin::Bidi::FORCE_RTL : minikin::Bidi::FORCE_LTR; if (offset == start + count) { return MinikinUtils::measureText(paint, bidiFlags, typeface, buf, start, count, bufSize, nullptr); @@ -519,7 +521,7 @@ namespace PaintGlue { static jint doOffsetForAdvance(const Paint* paint, const Typeface* typeface, const jchar buf[], jint start, jint count, jint bufSize, jboolean isRtl, jfloat advance) { - int bidiFlags = isRtl ? minikin::kBidi_Force_RTL : minikin::kBidi_Force_LTR; + minikin::Bidi bidiFlags = isRtl ? minikin::Bidi::FORCE_RTL : minikin::Bidi::FORCE_LTR; std::unique_ptr<float[]> advancesArray(new float[count]); MinikinUtils::measureText(paint, bidiFlags, typeface, buf, start, count, bufSize, advancesArray.get()); diff --git a/core/jni/android_graphics_Canvas.cpp b/core/jni/android_graphics_Canvas.cpp index fba0721d9119..f08b89c8c988 100644 --- a/core/jni/android_graphics_Canvas.cpp +++ b/core/jni/android_graphics_Canvas.cpp @@ -480,7 +480,7 @@ static void drawTextChars(JNIEnv* env, jobject, jlong canvasHandle, jcharArray t const Typeface* typeface = paint->getAndroidTypeface(); jchar* jchars = env->GetCharArrayElements(text, NULL); get_canvas(canvasHandle)->drawText(jchars + index, 0, count, count, x, y, - bidiFlags, *paint, typeface); + static_cast<minikin::Bidi>(bidiFlags), *paint, typeface); env->ReleaseCharArrayElements(text, jchars, JNI_ABORT); } @@ -492,7 +492,7 @@ static void drawTextString(JNIEnv* env, jobject, jlong canvasHandle, jstring tex const int count = end - start; const jchar* jchars = env->GetStringChars(text, NULL); get_canvas(canvasHandle)->drawText(jchars + start, 0, count, count, x, y, - bidiFlags, *paint, typeface); + static_cast<minikin::Bidi>(bidiFlags), *paint, typeface); env->ReleaseStringChars(text, jchars); } @@ -502,7 +502,7 @@ static void drawTextRunChars(JNIEnv* env, jobject, jlong canvasHandle, jcharArra Paint* paint = reinterpret_cast<Paint*>(paintHandle); const Typeface* typeface = paint->getAndroidTypeface(); - const int bidiFlags = isRtl ? minikin::kBidi_Force_RTL : minikin::kBidi_Force_LTR; + const minikin::Bidi bidiFlags = isRtl ? minikin::Bidi::FORCE_RTL : minikin::Bidi::FORCE_LTR; jchar* jchars = env->GetCharArrayElements(text, NULL); get_canvas(canvasHandle)->drawText(jchars + contextIndex, index - contextIndex, count, contextCount, x, y, bidiFlags, *paint, typeface); @@ -515,7 +515,7 @@ static void drawTextRunString(JNIEnv* env, jobject obj, jlong canvasHandle, jstr Paint* paint = reinterpret_cast<Paint*>(paintHandle); const Typeface* typeface = paint->getAndroidTypeface(); - int bidiFlags = isRtl ? minikin::kBidi_Force_RTL : minikin::kBidi_Force_LTR; + const minikin::Bidi bidiFlags = isRtl ? minikin::Bidi::FORCE_RTL : minikin::Bidi::FORCE_LTR; jint count = end - start; jint contextCount = contextEnd - contextStart; const jchar* jchars = env->GetStringChars(text, NULL); @@ -533,8 +533,8 @@ static void drawTextOnPathChars(JNIEnv* env, jobject, jlong canvasHandle, jcharA jchar* jchars = env->GetCharArrayElements(text, NULL); - get_canvas(canvasHandle)->drawTextOnPath(jchars + index, count, bidiFlags, *path, - hOffset, vOffset, *paint, typeface); + get_canvas(canvasHandle)->drawTextOnPath(jchars + index, count, + static_cast<minikin::Bidi>(bidiFlags), *path, hOffset, vOffset, *paint, typeface); env->ReleaseCharArrayElements(text, jchars, 0); } @@ -549,8 +549,8 @@ static void drawTextOnPathString(JNIEnv* env, jobject, jlong canvasHandle, jstri const jchar* jchars = env->GetStringChars(text, NULL); int count = env->GetStringLength(text); - get_canvas(canvasHandle)->drawTextOnPath(jchars, count, bidiFlags, *path, - hOffset, vOffset, *paint, typeface); + get_canvas(canvasHandle)->drawTextOnPath(jchars, count, static_cast<minikin::Bidi>(bidiFlags), + *path, hOffset, vOffset, *paint, typeface); env->ReleaseStringChars(text, jchars); } diff --git a/core/jni/android_util_Binder.cpp b/core/jni/android_util_Binder.cpp index 6362bc7187fc..1b543f604a68 100644 --- a/core/jni/android_util_Binder.cpp +++ b/core/jni/android_util_Binder.cpp @@ -109,9 +109,8 @@ static struct binderproxy_offsets_t jmethodID mSendDeathNotice; // Object state. - jfieldID mObject; - jfieldID mSelf; - jfieldID mOrgue; + jfieldID mNativeData; // Field holds native pointer to BinderProxyNativeData. + jfieldID mSelf; // Field holds Java pointer to WeakReference to BinderProxy. } gBinderProxyOffsets; @@ -365,7 +364,7 @@ private: // ---------------------------------------------------------------------------- -class JavaBBinderHolder : public RefBase +class JavaBBinderHolder { public: sp<JavaBBinder> get(JNIEnv* env, jobject obj) @@ -523,7 +522,7 @@ protected: private: JavaVM* const mVM; jobject mObject; // Initial strong ref to Java-side DeathRecipient. Cleared on binderDied(). - jweak mObjectWeak; // weak ref to the same Java-side DeathRecipient after binderDied(). + jweak mObjectWeak; // Weak ref to the same Java-side DeathRecipient after binderDied(). wp<DeathRecipientList> mList; }; @@ -595,6 +594,25 @@ static void proxy_cleanup(const void* id, void* obj, void* cleanupCookie) env->DeleteGlobalRef((jobject)obj); } +// We aggregate native pointer fields for BinderProxy in a single object to allow +// management with a single NativeAllocationRegistry, and to reduce the number of JNI +// Java field accesses. This costs us some extra indirections here. +struct BinderProxyNativeData { + // The native IBinder proxied by this BinderProxy. + const sp<IBinder> mObject; + + // Death recipients for mObject. Reference counted only because DeathRecipients + // hold a weak reference that can be temporarily promoted. + const sp<DeathRecipientList> mOrgue; // Death recipients for mObject. + + BinderProxyNativeData(const sp<IBinder> &obj, DeathRecipientList *drl) + : mObject(obj), mOrgue(drl) {}; +}; + +BinderProxyNativeData* getBPNativeData(JNIEnv* env, jobject obj) { + return (BinderProxyNativeData *) env->GetLongField(obj, gBinderProxyOffsets.mNativeData); +} + static Mutex gProxyLock; jobject javaObjectForIBinder(JNIEnv* env, const sp<IBinder>& val) @@ -626,25 +644,22 @@ jobject javaObjectForIBinder(JNIEnv* env, const sp<IBinder>& val) env->DeleteGlobalRef(object); } - object = env->NewObject(gBinderProxyOffsets.mClass, gBinderProxyOffsets.mConstructor); + DeathRecipientList* drl = new DeathRecipientList; + BinderProxyNativeData* nativeData = new BinderProxyNativeData(val, drl); + object = env->NewObject(gBinderProxyOffsets.mClass, gBinderProxyOffsets.mConstructor, + (jlong)nativeData); if (object != NULL) { LOGDEATH("objectForBinder %p: created new proxy %p !\n", val.get(), object); - // The proxy holds a reference to the native object. - env->SetLongField(object, gBinderProxyOffsets.mObject, (jlong)val.get()); - val->incStrong((void*)javaObjectForIBinder); // The native object needs to hold a weak reference back to the // proxy, so we can retrieve the same proxy if it is still active. + // A JNI WeakGlobalRef would not currently work here, since it may be cleared + // after the Java object has been condemned, and can thus yield a stale reference. jobject refObject = env->NewGlobalRef( env->GetObjectField(object, gBinderProxyOffsets.mSelf)); val->attachObject(&gBinderProxyOffsets, refObject, jnienv_to_javavm(env), proxy_cleanup); - // Also remember the death recipients registered on this proxy - sp<DeathRecipientList> drl = new DeathRecipientList; - drl->incStrong((void*)javaObjectForIBinder); - env->SetLongField(object, gBinderProxyOffsets.mOrgue, reinterpret_cast<jlong>(drl.get())); - // Note that a new object reference has been created. android_atomic_inc(&gNumProxyRefs); incRefsCreated(env); @@ -660,12 +675,11 @@ sp<IBinder> ibinderForJavaObject(JNIEnv* env, jobject obj) if (env->IsInstanceOf(obj, gBinderOffsets.mClass)) { JavaBBinderHolder* jbh = (JavaBBinderHolder*) env->GetLongField(obj, gBinderOffsets.mObject); - return jbh != NULL ? jbh->get(env, obj) : NULL; + return jbh->get(env, obj); } if (env->IsInstanceOf(obj, gBinderProxyOffsets.mClass)) { - return (IBinder*) - env->GetLongField(obj, gBinderProxyOffsets.mObject); + return getBPNativeData(env, obj)->mObject; } ALOGW("ibinderForJavaObject: %p is not a Binder object", obj); @@ -858,35 +872,21 @@ static void android_os_Binder_flushPendingCommands(JNIEnv* env, jobject clazz) IPCThreadState::self()->flushCommands(); } -static void android_os_Binder_init(JNIEnv* env, jobject obj) +static jlong android_os_Binder_getNativeBBinderHolder(JNIEnv* env, jobject clazz) { JavaBBinderHolder* jbh = new JavaBBinderHolder(); - if (jbh == NULL) { - jniThrowException(env, "java/lang/OutOfMemoryError", NULL); - return; - } - ALOGV("Java Binder %p: acquiring first ref on holder %p", obj, jbh); - jbh->incStrong((void*)android_os_Binder_init); - env->SetLongField(obj, gBinderOffsets.mObject, (jlong)jbh); + return (jlong) jbh; } -static void android_os_Binder_destroyBinder(JNIEnv* env, jobject obj) +static void Binder_destroy(void* rawJbh) { - JavaBBinderHolder* jbh = (JavaBBinderHolder*) - env->GetLongField(obj, gBinderOffsets.mObject); - if (jbh != NULL) { - env->SetLongField(obj, gBinderOffsets.mObject, 0); - ALOGV("Java Binder %p: removing ref on holder %p", obj, jbh); - jbh->decStrong((void*)android_os_Binder_init); - } else { - // Encountering an uninitialized binder is harmless. All it means is that - // the Binder was only partially initialized when its finalizer ran and called - // destroyBinder(). The Binder could be partially initialized for several reasons. - // For example, a Binder subclass constructor might have thrown an exception before - // it could delegate to its superclass's constructor. Consequently init() would - // not have been called and the holder pointer would remain NULL. - ALOGV("Java Binder %p: ignoring uninitialized binder", obj); - } + JavaBBinderHolder* jbh = (JavaBBinderHolder*) rawJbh; + ALOGV("Java Binder: deleting holder %p", jbh); + delete jbh; +} + +JNIEXPORT jlong JNICALL android_os_Binder_getNativeFinalizer(JNIEnv*, jclass) { + return (jlong) Binder_destroy; } static void android_os_Binder_blockUntilThreadAvailable(JNIEnv* env, jobject clazz) @@ -905,8 +905,8 @@ static const JNINativeMethod gBinderMethods[] = { { "setThreadStrictModePolicy", "(I)V", (void*)android_os_Binder_setThreadStrictModePolicy }, { "getThreadStrictModePolicy", "()I", (void*)android_os_Binder_getThreadStrictModePolicy }, { "flushPendingCommands", "()V", (void*)android_os_Binder_flushPendingCommands }, - { "init", "()V", (void*)android_os_Binder_init }, - { "destroyBinder", "()V", (void*)android_os_Binder_destroyBinder }, + { "getNativeBBinderHolder", "()J", (void*)android_os_Binder_getNativeBBinderHolder }, + { "getNativeFinalizer", "()J", (void*)android_os_Binder_getNativeFinalizer }, { "blockUntilThreadAvailable", "()V", (void*)android_os_Binder_blockUntilThreadAvailable } }; @@ -1064,8 +1064,7 @@ static int int_register_android_os_BinderInternal(JNIEnv* env) static jboolean android_os_BinderProxy_pingBinder(JNIEnv* env, jobject obj) { - IBinder* target = (IBinder*) - env->GetLongField(obj, gBinderProxyOffsets.mObject); + IBinder* target = getBPNativeData(env, obj)->mObject.get(); if (target == NULL) { return JNI_FALSE; } @@ -1075,7 +1074,7 @@ static jboolean android_os_BinderProxy_pingBinder(JNIEnv* env, jobject obj) static jstring android_os_BinderProxy_getInterfaceDescriptor(JNIEnv* env, jobject obj) { - IBinder* target = (IBinder*) env->GetLongField(obj, gBinderProxyOffsets.mObject); + IBinder* target = getBPNativeData(env, obj)->mObject.get(); if (target != NULL) { const String16& desc = target->getInterfaceDescriptor(); return env->NewString(reinterpret_cast<const jchar*>(desc.string()), @@ -1088,8 +1087,7 @@ static jstring android_os_BinderProxy_getInterfaceDescriptor(JNIEnv* env, jobjec static jboolean android_os_BinderProxy_isBinderAlive(JNIEnv* env, jobject obj) { - IBinder* target = (IBinder*) - env->GetLongField(obj, gBinderProxyOffsets.mObject); + IBinder* target = getBPNativeData(env, obj)->mObject.get(); if (target == NULL) { return JNI_FALSE; } @@ -1211,8 +1209,7 @@ static jboolean android_os_BinderProxy_transact(JNIEnv* env, jobject obj, return JNI_FALSE; } - IBinder* target = (IBinder*) - env->GetLongField(obj, gBinderProxyOffsets.mObject); + IBinder* target = getBPNativeData(env, obj)->mObject.get(); if (target == NULL) { jniThrowException(env, "java/lang/IllegalStateException", "Binder has been finalized!"); return JNI_FALSE; @@ -1262,8 +1259,8 @@ static void android_os_BinderProxy_linkToDeath(JNIEnv* env, jobject obj, return; } - IBinder* target = (IBinder*) - env->GetLongField(obj, gBinderProxyOffsets.mObject); + BinderProxyNativeData *nd = getBPNativeData(env, obj); + IBinder* target = nd->mObject.get(); if (target == NULL) { ALOGW("Binder has been finalized when calling linkToDeath() with recip=%p)\n", recipient); assert(false); @@ -1272,8 +1269,7 @@ static void android_os_BinderProxy_linkToDeath(JNIEnv* env, jobject obj, LOGDEATH("linkToDeath: binder=%p recipient=%p\n", target, recipient); if (!target->localBinder()) { - DeathRecipientList* list = (DeathRecipientList*) - env->GetLongField(obj, gBinderProxyOffsets.mOrgue); + DeathRecipientList* list = nd->mOrgue.get(); sp<JavaDeathRecipient> jdr = new JavaDeathRecipient(env, recipient, list); status_t err = target->linkToDeath(jdr, NULL, flags); if (err != NO_ERROR) { @@ -1294,8 +1290,8 @@ static jboolean android_os_BinderProxy_unlinkToDeath(JNIEnv* env, jobject obj, return res; } - IBinder* target = (IBinder*) - env->GetLongField(obj, gBinderProxyOffsets.mObject); + BinderProxyNativeData* nd = getBPNativeData(env, obj); + IBinder* target = nd->mObject.get(); if (target == NULL) { ALOGW("Binder has been finalized when calling linkToDeath() with recip=%p)\n", recipient); return JNI_FALSE; @@ -1307,8 +1303,7 @@ static jboolean android_os_BinderProxy_unlinkToDeath(JNIEnv* env, jobject obj, status_t err = NAME_NOT_FOUND; // If we find the matching recipient, proceed to unlink using that - DeathRecipientList* list = (DeathRecipientList*) - env->GetLongField(obj, gBinderProxyOffsets.mOrgue); + DeathRecipientList* list = nd->mOrgue.get(); sp<JavaDeathRecipient> origJDR = list->find(recipient); LOGDEATH(" unlink found list %p and JDR %p", list, origJDR.get()); if (origJDR != NULL) { @@ -1334,27 +1329,22 @@ static jboolean android_os_BinderProxy_unlinkToDeath(JNIEnv* env, jobject obj, return res; } -static void android_os_BinderProxy_destroy(JNIEnv* env, jobject obj) +static void BinderProxy_destroy(void* rawNativeData) { // Don't race with construction/initialization AutoMutex _l(gProxyLock); - IBinder* b = (IBinder*) - env->GetLongField(obj, gBinderProxyOffsets.mObject); - DeathRecipientList* drl = (DeathRecipientList*) - env->GetLongField(obj, gBinderProxyOffsets.mOrgue); - - LOGDEATH("Destroying BinderProxy %p: binder=%p drl=%p\n", obj, b, drl); - if (b != nullptr) { - env->SetLongField(obj, gBinderProxyOffsets.mObject, 0); - env->SetLongField(obj, gBinderProxyOffsets.mOrgue, 0); - drl->decStrong((void*)javaObjectForIBinder); - b->decStrong((void*)javaObjectForIBinder); - } - + BinderProxyNativeData * nativeData = (BinderProxyNativeData *) rawNativeData; + LOGDEATH("Destroying BinderProxy: binder=%p drl=%p\n", + nativeData->mObject.get(), nativeData->mOrgue.get()); + delete (BinderProxyNativeData *) rawNativeData; IPCThreadState::self()->flushCommands(); } +JNIEXPORT jlong JNICALL android_os_BinderProxy_getNativeFinalizer(JNIEnv*, jclass) { + return (jlong) BinderProxy_destroy; +} + // ---------------------------------------------------------------------------- static const JNINativeMethod gBinderProxyMethods[] = { @@ -1365,7 +1355,7 @@ static const JNINativeMethod gBinderProxyMethods[] = { {"transactNative", "(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z", (void*)android_os_BinderProxy_transact}, {"linkToDeath", "(Landroid/os/IBinder$DeathRecipient;I)V", (void*)android_os_BinderProxy_linkToDeath}, {"unlinkToDeath", "(Landroid/os/IBinder$DeathRecipient;I)Z", (void*)android_os_BinderProxy_unlinkToDeath}, - {"destroy", "()V", (void*)android_os_BinderProxy_destroy}, + {"getNativeFinalizer", "()J", (void*)android_os_BinderProxy_getNativeFinalizer}, }; const char* const kBinderProxyPathName = "android/os/BinderProxy"; @@ -1377,14 +1367,13 @@ static int int_register_android_os_BinderProxy(JNIEnv* env) clazz = FindClassOrDie(env, kBinderProxyPathName); gBinderProxyOffsets.mClass = MakeGlobalRefOrDie(env, clazz); - gBinderProxyOffsets.mConstructor = GetMethodIDOrDie(env, clazz, "<init>", "()V"); + gBinderProxyOffsets.mConstructor = GetMethodIDOrDie(env, clazz, "<init>", "(J)V"); gBinderProxyOffsets.mSendDeathNotice = GetStaticMethodIDOrDie(env, clazz, "sendDeathNotice", "(Landroid/os/IBinder$DeathRecipient;)V"); - gBinderProxyOffsets.mObject = GetFieldIDOrDie(env, clazz, "mObject", "J"); + gBinderProxyOffsets.mNativeData = GetFieldIDOrDie(env, clazz, "mNativeData", "J"); gBinderProxyOffsets.mSelf = GetFieldIDOrDie(env, clazz, "mSelf", "Ljava/lang/ref/WeakReference;"); - gBinderProxyOffsets.mOrgue = GetFieldIDOrDie(env, clazz, "mOrgue", "J"); clazz = FindClassOrDie(env, "java/lang/Class"); gClassOffsets.mGetName = GetMethodIDOrDie(env, clazz, "getName", "()Ljava/lang/String;"); diff --git a/core/jni/android_view_SurfaceControl.cpp b/core/jni/android_view_SurfaceControl.cpp index 8ae9ada2dcb9..cfeba833a5a3 100644 --- a/core/jni/android_view_SurfaceControl.cpp +++ b/core/jni/android_view_SurfaceControl.cpp @@ -290,6 +290,22 @@ static void nativeScreenshot(JNIEnv* env, jclass clazz, jobject displayTokenObj, } } +static void nativeCaptureLayers(JNIEnv* env, jclass clazz, jobject layerHandleToken, + jobject surfaceObj, int rotation) { + + sp<IBinder> layerHandle = ibinderForJavaObject(env, layerHandleToken); + if (layerHandle == NULL) { + return; + } + + sp<Surface> consumer = android_view_Surface_getSurface(env, surfaceObj); + if (consumer == NULL) { + return; + } + + ScreenshotClient::captureLayers(layerHandle, consumer->getIGraphicBufferProducer(), rotation); +} + static void nativeApplyTransaction(JNIEnv* env, jclass clazz, jlong transactionObj, jboolean sync) { auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj); transaction->apply(sync); @@ -949,6 +965,8 @@ static const JNINativeMethod sSurfaceControlMethods[] = { {"nativeScreenshotToBuffer", "(Landroid/os/IBinder;Landroid/graphics/Rect;IIIIZZI)Landroid/graphics/GraphicBuffer;", (void*)nativeScreenshotToBuffer }, + {"nativeCaptureLayers", "(Landroid/os/IBinder;Landroid/view/Surface;I)V", + (void*)nativeCaptureLayers }, }; int register_android_view_SurfaceControl(JNIEnv* env) diff --git a/core/proto/android/os/incident.proto b/core/proto/android/os/incident.proto index f716ffee53af..50e811d79845 100644 --- a/core/proto/android/os/incident.proto +++ b/core/proto/android/os/incident.proto @@ -20,24 +20,24 @@ option java_outer_classname = "IncidentProtoMetadata"; import "frameworks/base/libs/incident/proto/android/privacy.proto"; import "frameworks/base/libs/incident/proto/android/section.proto"; +import "frameworks/base/core/proto/android/providers/settings.proto"; +import "frameworks/base/core/proto/android/os/incidentheader.proto"; +import "frameworks/base/core/proto/android/os/kernelwake.proto"; +import "frameworks/base/core/proto/android/os/pagetypeinfo.proto"; +import "frameworks/base/core/proto/android/os/procrank.proto"; +import "frameworks/base/core/proto/android/server/activitymanagerservice.proto"; +import "frameworks/base/core/proto/android/server/alarmmanagerservice.proto"; +import "frameworks/base/core/proto/android/server/fingerprint.proto"; import "frameworks/base/core/proto/android/server/powermanagerservice.proto"; import "frameworks/base/core/proto/android/service/appwidget.proto"; import "frameworks/base/core/proto/android/service/battery.proto"; import "frameworks/base/core/proto/android/service/batterystats.proto"; -import "frameworks/base/core/proto/android/service/fingerprint.proto"; import "frameworks/base/core/proto/android/service/diskstats.proto"; import "frameworks/base/core/proto/android/service/netstats.proto"; import "frameworks/base/core/proto/android/service/notification.proto"; import "frameworks/base/core/proto/android/service/package.proto"; import "frameworks/base/core/proto/android/service/print.proto"; import "frameworks/base/core/proto/android/service/procstats.proto"; -import "frameworks/base/core/proto/android/server/activitymanagerservice.proto"; -import "frameworks/base/core/proto/android/server/alarmmanagerservice.proto"; -import "frameworks/base/core/proto/android/providers/settings.proto"; -import "frameworks/base/core/proto/android/os/incidentheader.proto"; -import "frameworks/base/core/proto/android/os/kernelwake.proto"; -import "frameworks/base/core/proto/android/os/pagetypeinfo.proto"; -import "frameworks/base/core/proto/android/os/procrank.proto"; package android.os; @@ -69,7 +69,7 @@ message IncidentProto { // System Services - optional android.service.fingerprint.FingerprintServiceDumpProto fingerprint = 3000 [ + optional com.android.server.fingerprint.FingerprintServiceDumpProto fingerprint = 3000 [ (section).type = SECTION_DUMPSYS, (section).args = "fingerprint --proto --incident" ]; diff --git a/core/proto/android/service/fingerprint.proto b/core/proto/android/server/fingerprint.proto index 0826ad5cb31e..ec4ffe0ae4e1 100644 --- a/core/proto/android/service/fingerprint.proto +++ b/core/proto/android/server/fingerprint.proto @@ -15,7 +15,7 @@ */ syntax = "proto2"; -package android.service.fingerprint; +package com.android.server.fingerprint; option java_multiple_files = true; option java_outer_classname = "FingerprintServiceProto"; @@ -33,14 +33,15 @@ message FingerprintUserStatsProto { optional int32 num_fingerprints = 2; // Normal fingerprint authentications (e.g. lockscreen). - optional FingerprintActionStatsProto normal = 3; + optional PerformanceStatsProto normal = 3; // Crypto authentications (e.g. to unlock password storage, make secure // purchases, etc). - optional FingerprintActionStatsProto crypto = 4; + optional PerformanceStatsProto crypto = 4; } -message FingerprintActionStatsProto { +// A com.android.server.fingerprint.FingerpintService.PerformanceStats object. +message PerformanceStatsProto { // Number of accepted fingerprints. optional int32 accept = 1; @@ -55,5 +56,5 @@ message FingerprintActionStatsProto { optional int32 lockout = 4; // Total number of permanent lockouts. - optional int32 lockout_permanent = 5; + optional int32 permanent_lockout = 5; } diff --git a/core/proto/android/server/powermanagerservice.proto b/core/proto/android/server/powermanagerservice.proto index 70a285d4bbb2..d442acfd91be 100644 --- a/core/proto/android/server/powermanagerservice.proto +++ b/core/proto/android/server/powermanagerservice.proto @@ -30,6 +30,7 @@ import "frameworks/base/core/proto/android/server/wirelesschargerdetector.proto" import "frameworks/base/core/proto/android/view/display.proto"; message PowerManagerServiceDumpProto { + // A com.android.server.power.PowerManagerService.Constants object. message ConstantsProto { optional bool is_no_cached_wake_locks = 1; } @@ -49,7 +50,8 @@ message PowerManagerServiceDumpProto { optional bool is_screen_dim = 2; optional bool is_screen_dream = 3; } - message UidProto { + // A com.android.server.power.PowerManagerService.UidState object. + message UidStateProto { optional int32 uid = 1; optional string uid_string = 2; optional bool is_active = 3; @@ -154,7 +156,7 @@ message PowerManagerServiceDumpProto { // Some uids have actually changed while mUidsChanging was true. optional bool are_uids_changed = 45; // List of UIDs and their states - repeated UidProto uids = 46; + repeated UidStateProto uid_states = 46; optional .android.os.LooperProto looper = 47; // List of all wake locks acquired by applications. repeated WakeLockProto wake_locks = 48; @@ -163,11 +165,13 @@ message PowerManagerServiceDumpProto { optional WirelessChargerDetectorProto wireless_charger_detector = 50; } +// A com.android.server.power.PowerManagerService.SuspendBlockerImpl object. message SuspendBlockerProto { optional string name = 1; optional int32 reference_count = 2; } +// A com.android.server.power.PowerManagerService.WakeLock object. message WakeLockProto { message WakeLockFlagsProto { // Turn the screen on when the wake lock is acquired. diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml index a365c15300e1..dddd52bd1ef2 100644 --- a/core/res/res/values-ar/strings.xml +++ b/core/res/res/values-ar/strings.xml @@ -1726,7 +1726,6 @@ <string name="managed_profile_label_badge_2" msgid="5048136430082124036">"العمل الثاني <xliff:g id="LABEL">%1$s</xliff:g>"</string> <string name="managed_profile_label_badge_3" msgid="2808305070321719040">"العمل الثالث <xliff:g id="LABEL">%1$s</xliff:g>"</string> <string name="lock_to_app_toast" msgid="6820571533009838261">"لإزالة تثبيت هذه الشاشة، يمكنك لمس زرّي \"رجوع\" و\"نظرة عامة\" مع الاستمرار"</string> - <string name="lock_to_app_toast_locked" msgid="7849470948648628704">"لا يمكن إزالة تثبيت هذا التطبيق"</string> <string name="lock_to_app_start" msgid="6643342070839862795">"تم تثبيت الشاشة"</string> <string name="lock_to_app_exit" msgid="8598219838213787430">"تم إلغاء تثبيت الشاشة"</string> <string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"المطالبة برقم التعريف الشخصي قبل إزالة التثبيت"</string> @@ -1922,14 +1921,10 @@ <string name="etws_primary_default_message_test" msgid="2709597093560037455">"اختبار رسائل الطوارئ"</string> <string name="notification_reply_button_accessibility" msgid="3621714652387814344">"الرد"</string> <string name="etws_primary_default_message_others" msgid="6293148756130398971"></string> - <!-- no translation found for mmcc_authentication_reject (5767701075994754356) --> - <skip /> - <!-- no translation found for mmcc_imsi_unknown_in_hlr (5316658473301462825) --> - <skip /> - <!-- no translation found for mmcc_illegal_ms (807334478177362062) --> - <skip /> - <!-- no translation found for mmcc_illegal_me (1950705155760872972) --> - <skip /> + <string name="mmcc_authentication_reject" msgid="5767701075994754356">"غير مسموح باستخدام SIM للصوت"</string> + <string name="mmcc_imsi_unknown_in_hlr" msgid="5316658473301462825">"لم يتم توفير SIM للصوت"</string> + <string name="mmcc_illegal_ms" msgid="807334478177362062">"غير مسموح باستخدام SIM للصوت"</string> + <string name="mmcc_illegal_me" msgid="1950705155760872972">"غير مسموح باستخدام الهاتف للصوت"</string> <string name="popup_window_default_title" msgid="4874318849712115433">"نافذة منبثقة"</string> <string name="slice_more_content" msgid="8504342889413274608">"+ <xliff:g id="NUMBER">%1$d</xliff:g>"</string> <string name="shortcut_restored_on_lower_version" msgid="5270675146351613828">"يتطلب هذا الاختصار أحدث تطبيق"</string> diff --git a/core/res/res/values-b+sr+Latn/strings.xml b/core/res/res/values-b+sr+Latn/strings.xml index 0b82ffba4dff..7a907191ff52 100644 --- a/core/res/res/values-b+sr+Latn/strings.xml +++ b/core/res/res/values-b+sr+Latn/strings.xml @@ -278,8 +278,8 @@ <string name="permgroupdesc_storage" msgid="637758554581589203">"pristupa slikama, medijima i datotekama na uređaju"</string> <string name="permgrouprequest_storage" msgid="7429669910547860218">"Dozvolite <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> da pristupa slikama, medijskim datotekama i datotekama na uređaju"</string> <string name="permgrouplab_microphone" msgid="171539900250043464">"Mikrofon"</string> - <string name="permgroupdesc_microphone" msgid="4988812113943554584">"snima audio"</string> - <string name="permgrouprequest_microphone" msgid="8065941268709600606">"Dozvolite da <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> snima audio snimke"</string> + <string name="permgroupdesc_microphone" msgid="4988812113943554584">"snima zvuk"</string> + <string name="permgrouprequest_microphone" msgid="8065941268709600606">"Dozvolite da <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> snima zvuk"</string> <string name="permgrouplab_camera" msgid="4820372495894586615">"Kamera"</string> <string name="permgroupdesc_camera" msgid="3250611594678347720">"snima slike i video"</string> <string name="permgrouprequest_camera" msgid="810824326507258410">"Dozvolite da <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> snima slike i video snimke"</string> @@ -1651,7 +1651,6 @@ <string name="managed_profile_label_badge_2" msgid="5048136430082124036">"2. poslovni <xliff:g id="LABEL">%1$s</xliff:g>"</string> <string name="managed_profile_label_badge_3" msgid="2808305070321719040">"3. poslovni imejl <xliff:g id="LABEL">%1$s</xliff:g>"</string> <string name="lock_to_app_toast" msgid="6820571533009838261">"Da biste otkačili ovaj ekran, dodirnite i zadržite dugmad Nazad i Pregled"</string> - <string name="lock_to_app_toast_locked" msgid="7849470948648628704">"Ova aplikacija ne može da se otkači"</string> <string name="lock_to_app_start" msgid="6643342070839862795">"Ekran je zakačen"</string> <string name="lock_to_app_exit" msgid="8598219838213787430">"Ekran je otkačen"</string> <string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"Traži PIN pre otkačinjanja"</string> @@ -1817,14 +1816,10 @@ <string name="etws_primary_default_message_test" msgid="2709597093560037455">"Testiranje poruka u hitnim slučajevima"</string> <string name="notification_reply_button_accessibility" msgid="3621714652387814344">"Odgovori"</string> <string name="etws_primary_default_message_others" msgid="6293148756130398971"></string> - <!-- no translation found for mmcc_authentication_reject (5767701075994754356) --> - <skip /> - <!-- no translation found for mmcc_imsi_unknown_in_hlr (5316658473301462825) --> - <skip /> - <!-- no translation found for mmcc_illegal_ms (807334478177362062) --> - <skip /> - <!-- no translation found for mmcc_illegal_me (1950705155760872972) --> - <skip /> + <string name="mmcc_authentication_reject" msgid="5767701075994754356">"SIM kartica nije prilagođena za glasovne usluge"</string> + <string name="mmcc_imsi_unknown_in_hlr" msgid="5316658473301462825">"SIM kartica nije podešena za glasovne usluge"</string> + <string name="mmcc_illegal_ms" msgid="807334478177362062">"SIM kartica nije prilagođena za glasovne usluge"</string> + <string name="mmcc_illegal_me" msgid="1950705155760872972">"Telefon nije prilagođen za glasovne usluge"</string> <string name="popup_window_default_title" msgid="4874318849712115433">"Iskačući prozor"</string> <string name="slice_more_content" msgid="8504342889413274608">"i još <xliff:g id="NUMBER">%1$d</xliff:g>"</string> <string name="shortcut_restored_on_lower_version" msgid="5270675146351613828">"Ova prečica zahteva najnoviju aplikaciju"</string> diff --git a/core/res/res/values-bn/strings.xml b/core/res/res/values-bn/strings.xml index f5744ed9ab25..8e1b5b421356 100644 --- a/core/res/res/values-bn/strings.xml +++ b/core/res/res/values-bn/strings.xml @@ -1626,7 +1626,6 @@ <string name="managed_profile_label_badge_2" msgid="5048136430082124036">"দ্বিতীয় কার্যক্ষেত্র <xliff:g id="LABEL">%1$s</xliff:g>"</string> <string name="managed_profile_label_badge_3" msgid="2808305070321719040">"তৃতীয় কার্যক্ষেত্র <xliff:g id="LABEL">%1$s</xliff:g>"</string> <string name="lock_to_app_toast" msgid="6820571533009838261">"এই স্ক্রিনটিকে আনপিন করতে ফিরে যাওয়া এবং এক নজরে বোতামদুটি ট্যাপ করে ধরে রাখুন"</string> - <string name="lock_to_app_toast_locked" msgid="7849470948648628704">"এই অ্যাপটি আনপিন করা যাবে না"</string> <string name="lock_to_app_start" msgid="6643342070839862795">"স্ক্রিন পিন করা হয়েছে"</string> <string name="lock_to_app_exit" msgid="8598219838213787430">"পিন না করা স্ক্রীন"</string> <string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"আনপিন করার আগে পিন চান"</string> @@ -1782,14 +1781,10 @@ <string name="etws_primary_default_message_test" msgid="2709597093560037455">"বিপদকালীন বার্তাগুলির পরীক্ষা"</string> <string name="notification_reply_button_accessibility" msgid="3621714652387814344">"উত্তর দিন"</string> <string name="etws_primary_default_message_others" msgid="6293148756130398971"></string> - <!-- no translation found for mmcc_authentication_reject (5767701075994754356) --> - <skip /> - <!-- no translation found for mmcc_imsi_unknown_in_hlr (5316658473301462825) --> - <skip /> - <!-- no translation found for mmcc_illegal_ms (807334478177362062) --> - <skip /> - <!-- no translation found for mmcc_illegal_me (1950705155760872972) --> - <skip /> + <string name="mmcc_authentication_reject" msgid="5767701075994754356">"এই সিম দিয়ে ভয়েস কল করা যাবে না"</string> + <string name="mmcc_imsi_unknown_in_hlr" msgid="5316658473301462825">"সিমটি ভয়েস কলের জন্য প্রস্তুত নয়"</string> + <string name="mmcc_illegal_ms" msgid="807334478177362062">"এই সিম দিয়ে ভয়েস কল করা যাবে না"</string> + <string name="mmcc_illegal_me" msgid="1950705155760872972">"এই ফোন দিয়ে ভয়েস কল করা যাবে না"</string> <string name="popup_window_default_title" msgid="4874318849712115433">"পপ-আপ উইন্ডো"</string> <string name="slice_more_content" msgid="8504342889413274608">"+ <xliff:g id="NUMBER">%1$d</xliff:g>টি"</string> <string name="shortcut_restored_on_lower_version" msgid="5270675146351613828">"এই শর্টকাটটির জন্য লেটেস্ট অ্যাপ প্রয়োজন"</string> diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml index 2e0724d8b3bd..bb793a57de9c 100644 --- a/core/res/res/values-ca/strings.xml +++ b/core/res/res/values-ca/strings.xml @@ -275,7 +275,7 @@ <string name="permgroupdesc_storage" msgid="637758554581589203">"accedir a fotos, contingut multimèdia i fitxers del dispositiu"</string> <string name="permgrouprequest_storage" msgid="7429669910547860218">"Permet que <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> accedeixi a les fotos, al contingut multimèdia i als fitxers del dispositiu"</string> <string name="permgrouplab_microphone" msgid="171539900250043464">"Micròfon"</string> - <string name="permgroupdesc_microphone" msgid="4988812113943554584">"enregistrar àudio"</string> + <string name="permgroupdesc_microphone" msgid="4988812113943554584">"gravar àudio"</string> <string name="permgrouprequest_microphone" msgid="8065941268709600606">"Permet que <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> enregistri àudio"</string> <string name="permgrouplab_camera" msgid="4820372495894586615">"Càmera"</string> <string name="permgroupdesc_camera" msgid="3250611594678347720">"fer fotos i vídeos"</string> @@ -394,12 +394,12 @@ <string name="permdesc_accessCoarseLocation" product="default" msgid="7788009094906196995">"Aquesta aplicació pot obtenir la teva ubicació a partir de fonts de xarxa, com ara torres de telefonia mòbil i xarxes Wi-Fi. Aquests serveis d\'ubicació han d\'estar activats i disponibles al telèfon perquè l\'aplicació els pugui utilitzar."</string> <string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"canviar la configuració d\'àudio"</string> <string name="permdesc_modifyAudioSettings" msgid="3522565366806248517">"Permet que l\'aplicació modifiqui la configuració d\'àudio general, com ara el volum i l\'altaveu de sortida que es fa servir."</string> - <string name="permlab_recordAudio" msgid="3876049771427466323">"enregistrar àudio"</string> - <string name="permdesc_recordAudio" msgid="4245930455135321433">"Aquesta aplicació pot enregistrar àudio amb el micròfon en qualsevol moment."</string> + <string name="permlab_recordAudio" msgid="3876049771427466323">"gravar àudio"</string> + <string name="permdesc_recordAudio" msgid="4245930455135321433">"Aquesta aplicació pot gravar àudio amb el micròfon en qualsevol moment."</string> <string name="permlab_sim_communication" msgid="2935852302216852065">"enviar ordres a la SIM"</string> <string name="permdesc_sim_communication" msgid="5725159654279639498">"Permet que l\'aplicació enviï ordres a la SIM. Això és molt perillós."</string> <string name="permlab_camera" msgid="3616391919559751192">"fer fotos i vídeos"</string> - <string name="permdesc_camera" msgid="5392231870049240670">"Aquesta aplicació pot fer fotos i enregistrar vídeos amb la càmera en qualsevol moment."</string> + <string name="permdesc_camera" msgid="5392231870049240670">"Aquesta aplicació pot fer fotos i gravar vídeos amb la càmera en qualsevol moment."</string> <string name="permlab_vibrate" msgid="7696427026057705834">"controlar la vibració"</string> <string name="permdesc_vibrate" msgid="6284989245902300945">"Permet que l\'aplicació controli el vibrador."</string> <string name="permlab_callPhone" msgid="3925836347681847954">"trucar directament a números de telèfon"</string> @@ -450,7 +450,7 @@ <string name="permdesc_changeWifiMulticastState" product="tablet" msgid="7969774021256336548">"Permet que l\'aplicació rebi paquets enviats a tots els dispositius d\'una xarxa Wi-Fi mitjançant les adreces multidifusió, no només a la teva tauleta. Fa servir més energia que el mode que no és multidifusió."</string> <string name="permdesc_changeWifiMulticastState" product="tv" msgid="9031975661145014160">"Permet que l\'aplicació rebi paquets enviats a tots els dispositius d\'una xarxa Wi-Fi mitjançant les adreces de multidifusió, no només al televisor. Fa servir més energia que el mode que no és de multidifusió."</string> <string name="permdesc_changeWifiMulticastState" product="default" msgid="6851949706025349926">"Permet que l\'aplicació rebi paquets enviats a tots els dispositius d\'una xarxa Wi-Fi mitjançant les adreces multidifusió, no només al teu telèfon. Fa servir més energia que el mode que no és multidifusió."</string> - <string name="permlab_bluetoothAdmin" msgid="6006967373935926659">"accés a la configuració de Bluetooth"</string> + <string name="permlab_bluetoothAdmin" msgid="6006967373935926659">"accés a la configuració del Bluetooth"</string> <string name="permdesc_bluetoothAdmin" product="tablet" msgid="6921177471748882137">"Permet que l\'aplicació configuri la tauleta Bluetooth local i que detecti dispositius remots i s\'hi vinculi."</string> <string name="permdesc_bluetoothAdmin" product="tv" msgid="3373125682645601429">"Permet que l\'aplicació configuri el televisor Bluetooth local, cerqui dispositius remots i s\'hi vinculi."</string> <string name="permdesc_bluetoothAdmin" product="default" msgid="8931682159331542137">"Permet que l\'aplicació configuri el telèfon Bluetooth local i que detecti dispositius remots i s\'hi vinculi."</string> @@ -461,9 +461,9 @@ <string name="permdesc_changeWimaxState" product="tv" msgid="6022307083934827718">"Permet que l\'aplicació connecti el televisor a xarxes WiMAX, o bé que el desconnecti."</string> <string name="permdesc_changeWimaxState" product="default" msgid="697025043004923798">"Permet que l\'aplicació connecti i desconnecti el telèfon de les xarxes WiMAX."</string> <string name="permlab_bluetooth" msgid="6127769336339276828">"vincula amb dispositius Bluetooth"</string> - <string name="permdesc_bluetooth" product="tablet" msgid="3480722181852438628">"Permet que l\'aplicació visualitzi la configuració de Bluetooth de la tauleta i que estableixi i accepti connexions amb dispositius sincronitzats."</string> - <string name="permdesc_bluetooth" product="tv" msgid="3974124940101104206">"Permet que l\'aplicació consulti la configuració de Bluetooth del televisor i estableixi i accepti connexions amb dispositius vinculats ."</string> - <string name="permdesc_bluetooth" product="default" msgid="3207106324452312739">"Permet que una aplicació visualitzi la configuració de Bluetooth del telèfon i que estableixi i accepti connexions amb els dispositius sincronitzats."</string> + <string name="permdesc_bluetooth" product="tablet" msgid="3480722181852438628">"Permet que l\'aplicació visualitzi la configuració del Bluetooth de la tauleta i que estableixi i accepti connexions amb dispositius sincronitzats."</string> + <string name="permdesc_bluetooth" product="tv" msgid="3974124940101104206">"Permet que l\'aplicació consulti la configuració del Bluetooth del televisor i estableixi i accepti connexions amb dispositius vinculats ."</string> + <string name="permdesc_bluetooth" product="default" msgid="3207106324452312739">"Permet que una aplicació visualitzi la configuració del Bluetooth del telèfon i que estableixi i accepti connexions amb els dispositius sincronitzats."</string> <string name="permlab_nfc" msgid="4423351274757876953">"controlar Comunicació de camp proper (NFC)"</string> <string name="permdesc_nfc" msgid="7120611819401789907">"Permet que l\'aplicació es comuniqui amb les etiquetes, les targetes i els lectors de Comunicació de camp proper (NFC)."</string> <string name="permlab_disableKeyguard" msgid="3598496301486439258">"desactivació del bloqueig de pantalla"</string> @@ -1078,14 +1078,14 @@ <string name="sendText" msgid="5209874571959469142">"Tria una acció per al text"</string> <string name="volume_ringtone" msgid="6885421406845734650">"Volum del timbre"</string> <string name="volume_music" msgid="5421651157138628171">"Volum de multimèdia"</string> - <string name="volume_music_hint_playing_through_bluetooth" msgid="9165984379394601533">"S\'està reproduint a través de Bluetooth"</string> + <string name="volume_music_hint_playing_through_bluetooth" msgid="9165984379394601533">"S\'està reproduint per Bluetooth"</string> <string name="volume_music_hint_silent_ringtone_selected" msgid="8310739960973156272">"S\'ha establert el so de silenci"</string> <string name="volume_call" msgid="3941680041282788711">"Volum en trucada"</string> - <string name="volume_bluetooth_call" msgid="2002891926351151534">"Volum en trucada Bluetooth"</string> + <string name="volume_bluetooth_call" msgid="2002891926351151534">"Volum en trucada per Bluetooth"</string> <string name="volume_alarm" msgid="1985191616042689100">"Volum de l\'alarma"</string> <string name="volume_notification" msgid="2422265656744276715">"Volum de notificacions"</string> <string name="volume_unknown" msgid="1400219669770445902">"Volum"</string> - <string name="volume_icon_description_bluetooth" msgid="6538894177255964340">"Volum de Bluetooth"</string> + <string name="volume_icon_description_bluetooth" msgid="6538894177255964340">"Volum del Bluetooth"</string> <string name="volume_icon_description_ringer" msgid="3326003847006162496">"Volum del so"</string> <string name="volume_icon_description_incall" msgid="8890073218154543397">"Volum de trucada"</string> <string name="volume_icon_description_media" msgid="4217311719665194215">"Volum de multimèdia"</string> @@ -1626,7 +1626,6 @@ <string name="managed_profile_label_badge_2" msgid="5048136430082124036">"2n <xliff:g id="LABEL">%1$s</xliff:g> de la feina"</string> <string name="managed_profile_label_badge_3" msgid="2808305070321719040">"3r <xliff:g id="LABEL">%1$s</xliff:g> de la feina"</string> <string name="lock_to_app_toast" msgid="6820571533009838261">"Toca i mantén premuts els botons Enrere i Aplicacions recents per deixar de fixar aquesta pantalla"</string> - <string name="lock_to_app_toast_locked" msgid="7849470948648628704">"No es pot deixar de fixar aquesta aplicació"</string> <string name="lock_to_app_start" msgid="6643342070839862795">"Pantalla fixada"</string> <string name="lock_to_app_exit" msgid="8598219838213787430">"Fixació de la pantalla anul·lada"</string> <string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"Sol·licita el codi PIN per deixar de fixar"</string> @@ -1782,14 +1781,10 @@ <string name="etws_primary_default_message_test" msgid="2709597093560037455">"Prova de missatges d\'emergència"</string> <string name="notification_reply_button_accessibility" msgid="3621714652387814344">"Respon"</string> <string name="etws_primary_default_message_others" msgid="6293148756130398971"></string> - <!-- no translation found for mmcc_authentication_reject (5767701075994754356) --> - <skip /> - <!-- no translation found for mmcc_imsi_unknown_in_hlr (5316658473301462825) --> - <skip /> - <!-- no translation found for mmcc_illegal_ms (807334478177362062) --> - <skip /> - <!-- no translation found for mmcc_illegal_me (1950705155760872972) --> - <skip /> + <string name="mmcc_authentication_reject" msgid="5767701075994754356">"La SIM no és compatible per a la veu"</string> + <string name="mmcc_imsi_unknown_in_hlr" msgid="5316658473301462825">"La SIM no està proporcionada per a la veu"</string> + <string name="mmcc_illegal_ms" msgid="807334478177362062">"La SIM no és compatible per a la veu"</string> + <string name="mmcc_illegal_me" msgid="1950705155760872972">"El telèfon no és compatible per a la veu"</string> <string name="popup_window_default_title" msgid="4874318849712115433">"Finestra emergent"</string> <string name="slice_more_content" msgid="8504342889413274608">"<xliff:g id="NUMBER">%1$d</xliff:g> més"</string> <string name="shortcut_restored_on_lower_version" msgid="5270675146351613828">"Per fer servir aquesta drecera has de tenir l\'última versió de l\'aplicació"</string> diff --git a/core/res/res/values-en-rXC/strings.xml b/core/res/res/values-en-rXC/strings.xml index 336b35d44258..a131af5caf04 100644 --- a/core/res/res/values-en-rXC/strings.xml +++ b/core/res/res/values-en-rXC/strings.xml @@ -979,16 +979,11 @@ <string name="inputMethod" msgid="1653630062304567879">"Input method"</string> <string name="editTextMenuTitle" msgid="4909135564941815494">"Text actions"</string> <string name="email" msgid="4560673117055050403">"Email"</string> - <!-- no translation found for dial (1253998302767701559) --> - <skip /> - <!-- no translation found for map (6521159124535543457) --> - <skip /> - <!-- no translation found for browse (1245903488306147205) --> - <skip /> - <!-- no translation found for sms (4560537514610063430) --> - <skip /> - <!-- no translation found for add_contact (7867066569670597203) --> - <skip /> + <string name="dial" msgid="1253998302767701559">"Call"</string> + <string name="map" msgid="6521159124535543457">"Locate"</string> + <string name="browse" msgid="1245903488306147205">"Open"</string> + <string name="sms" msgid="4560537514610063430">"Message"</string> + <string name="add_contact" msgid="7867066569670597203">"Add"</string> <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Storage space running out"</string> <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Some system functions may not work"</string> <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"Not enough storage for the system. Make sure you have 250MB of free space and restart."</string> @@ -998,7 +993,6 @@ <string name="cancel" msgid="6442560571259935130">"Cancel"</string> <string name="yes" msgid="5362982303337969312">"OK"</string> <string name="no" msgid="5141531044935541497">"Cancel"</string> - <string name="close" msgid="2318214661230355730">"CLOSE"</string> <string name="dialog_alert_title" msgid="2049658708609043103">"Attention"</string> <string name="loading" msgid="7933681260296021180">"Loading…"</string> <string name="capital_on" msgid="1544682755514494298">"ON"</string> @@ -1055,8 +1049,6 @@ <string name="screen_compat_mode_scale" msgid="3202955667675944499">"Scale"</string> <string name="screen_compat_mode_show" msgid="4013878876486655892">"Always show"</string> <string name="screen_compat_mode_hint" msgid="1064524084543304459">"Re-enable this in System settings > Apps > Downloaded."</string> - <string name="top_app_killed_title" msgid="6814231368167994497">"App isn\'t responding"</string> - <string name="top_app_killed_message" msgid="3487519022191609844">"<xliff:g id="APP_NAME">%1$s</xliff:g> may be using too much memory."</string> <string name="unsupported_display_size_message" msgid="6545327290756295232">"<xliff:g id="APP_NAME">%1$s</xliff:g> does not support the current Display size setting and may behave unexpectedly."</string> <string name="unsupported_display_size_show" msgid="7969129195360353041">"Always show"</string> <string name="smv_application" msgid="3307209192155442829">"The app <xliff:g id="APPLICATION">%1$s</xliff:g> (process <xliff:g id="PROCESS">%2$s</xliff:g>) has violated its self-enforced StrictMode policy."</string> @@ -1634,7 +1626,6 @@ <string name="managed_profile_label_badge_2" msgid="5048136430082124036">"2nd Work <xliff:g id="LABEL">%1$s</xliff:g>"</string> <string name="managed_profile_label_badge_3" msgid="2808305070321719040">"3rd Work <xliff:g id="LABEL">%1$s</xliff:g>"</string> <string name="lock_to_app_toast" msgid="6820571533009838261">"To unpin this screen, touch & hold Back and Overview buttons"</string> - <string name="lock_to_app_toast_locked" msgid="7849470948648628704">"This app can\'t be unpinned"</string> <string name="lock_to_app_start" msgid="6643342070839862795">"Screen pinned"</string> <string name="lock_to_app_exit" msgid="8598219838213787430">"Screen unpinned"</string> <string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"Ask for PIN before unpinning"</string> @@ -1790,18 +1781,14 @@ <string name="etws_primary_default_message_test" msgid="2709597093560037455">"Emergency messages test"</string> <string name="notification_reply_button_accessibility" msgid="3621714652387814344">"Reply"</string> <string name="etws_primary_default_message_others" msgid="6293148756130398971"></string> - <string name="mmcc_authentication_reject" msgid="7729819349669603406">"SIM not allowed"</string> - <string name="mmcc_imsi_unknown_in_hlr" msgid="6321202257374418726">"SIM not provisioned"</string> - <string name="mmcc_illegal_ms" msgid="2769452751852211112">"SIM not allowed"</string> - <string name="mmcc_illegal_me" msgid="4438696681169345015">"Phone not allowed"</string> + <string name="mmcc_authentication_reject" msgid="5767701075994754356">"SIM not allowed for voice"</string> + <string name="mmcc_imsi_unknown_in_hlr" msgid="5316658473301462825">"SIM not provisioned for voice"</string> + <string name="mmcc_illegal_ms" msgid="807334478177362062">"SIM not allowed for voice"</string> + <string name="mmcc_illegal_me" msgid="1950705155760872972">"Phone not allowed for voice"</string> <string name="popup_window_default_title" msgid="4874318849712115433">"Popup Window"</string> <string name="slice_more_content" msgid="8504342889413274608">"+ <xliff:g id="NUMBER">%1$d</xliff:g>"</string> - <!-- no translation found for shortcut_restored_on_lower_version (5270675146351613828) --> - <skip /> - <!-- no translation found for shortcut_restore_not_supported (5028808567940014190) --> - <skip /> - <!-- no translation found for shortcut_restore_signature_mismatch (2406209324521327518) --> - <skip /> - <!-- no translation found for shortcut_restore_unknown_issue (8703738064603262597) --> - <skip /> + <string name="shortcut_restored_on_lower_version" msgid="5270675146351613828">"This shortcut requires latest app"</string> + <string name="shortcut_restore_not_supported" msgid="5028808567940014190">"Couldn’t restore shortcut because app doesn’t support backup and restore"</string> + <string name="shortcut_restore_signature_mismatch" msgid="2406209324521327518">"Couldn’t restore shortcut because of app signature mismatch"</string> + <string name="shortcut_restore_unknown_issue" msgid="8703738064603262597">"Couldn’t restore shortcut"</string> </resources> diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml index a9e848825449..dd26fe0a49e6 100644 --- a/core/res/res/values-es/strings.xml +++ b/core/res/res/values-es/strings.xml @@ -1626,7 +1626,6 @@ <string name="managed_profile_label_badge_2" msgid="5048136430082124036">"<xliff:g id="LABEL">%1$s</xliff:g> de trabajo 2"</string> <string name="managed_profile_label_badge_3" msgid="2808305070321719040">"<xliff:g id="LABEL">%1$s</xliff:g> de trabajo 3"</string> <string name="lock_to_app_toast" msgid="6820571533009838261">"Mantén pulsado el botón Atrás y el de aplicaciones recientes para dejar de fijar esta pantalla"</string> - <string name="lock_to_app_toast_locked" msgid="7849470948648628704">"Esta aplicación no se puede dejar de fijar"</string> <string name="lock_to_app_start" msgid="6643342070839862795">"Pantalla fijada"</string> <string name="lock_to_app_exit" msgid="8598219838213787430">"La pantalla ya no está fija"</string> <string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"Solicitar PIN para desactivar"</string> @@ -1782,14 +1781,10 @@ <string name="etws_primary_default_message_test" msgid="2709597093560037455">"Prueba de mensajes de emergencia"</string> <string name="notification_reply_button_accessibility" msgid="3621714652387814344">"Responder"</string> <string name="etws_primary_default_message_others" msgid="6293148756130398971"></string> - <!-- no translation found for mmcc_authentication_reject (5767701075994754356) --> - <skip /> - <!-- no translation found for mmcc_imsi_unknown_in_hlr (5316658473301462825) --> - <skip /> - <!-- no translation found for mmcc_illegal_ms (807334478177362062) --> - <skip /> - <!-- no translation found for mmcc_illegal_me (1950705155760872972) --> - <skip /> + <string name="mmcc_authentication_reject" msgid="5767701075994754356">"SIM no permitida para voz"</string> + <string name="mmcc_imsi_unknown_in_hlr" msgid="5316658473301462825">"SIM no proporcionada para voz"</string> + <string name="mmcc_illegal_ms" msgid="807334478177362062">"SIM no permitida para voz"</string> + <string name="mmcc_illegal_me" msgid="1950705155760872972">"Teléfono no permitido para voz"</string> <string name="popup_window_default_title" msgid="4874318849712115433">"Ventana emergente"</string> <string name="slice_more_content" msgid="8504342889413274608">"<xliff:g id="NUMBER">%1$d</xliff:g> más"</string> <string name="shortcut_restored_on_lower_version" msgid="5270675146351613828">"Para usar este acceso directo, necesitas la última versión de la aplicación"</string> diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml index 0ba0733d72bc..11a882069908 100644 --- a/core/res/res/values-hi/strings.xml +++ b/core/res/res/values-hi/strings.xml @@ -1626,7 +1626,6 @@ <string name="managed_profile_label_badge_2" msgid="5048136430082124036">"दूसरा कार्य <xliff:g id="LABEL">%1$s</xliff:g>"</string> <string name="managed_profile_label_badge_3" msgid="2808305070321719040">"तीसरा कार्य <xliff:g id="LABEL">%1$s</xliff:g>"</string> <string name="lock_to_app_toast" msgid="6820571533009838261">"इस स्क्रीन को अनपिन करने के लिए, \'वापस जाएं\' और \'खास जानकारी\' के बटन को दबाकर रखें"</string> - <string name="lock_to_app_toast_locked" msgid="7849470948648628704">"इस ऐप्लिकेशन को अनपिन नहीं किया जा सकता"</string> <string name="lock_to_app_start" msgid="6643342070839862795">"स्क्रीन पिन की गई"</string> <string name="lock_to_app_exit" msgid="8598219838213787430">"स्क्रीन अनपिन की गई"</string> <string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"अनपिन करने से पहले पिन के लिए पूछें"</string> @@ -1782,14 +1781,10 @@ <string name="etws_primary_default_message_test" msgid="2709597093560037455">"आपातकालीन संदेश परीक्षण"</string> <string name="notification_reply_button_accessibility" msgid="3621714652387814344">"जवाब दें"</string> <string name="etws_primary_default_message_others" msgid="6293148756130398971"></string> - <!-- no translation found for mmcc_authentication_reject (5767701075994754356) --> - <skip /> - <!-- no translation found for mmcc_imsi_unknown_in_hlr (5316658473301462825) --> - <skip /> - <!-- no translation found for mmcc_illegal_ms (807334478177362062) --> - <skip /> - <!-- no translation found for mmcc_illegal_me (1950705155760872972) --> - <skip /> + <string name="mmcc_authentication_reject" msgid="5767701075994754356">"सिम से कॉल करने की इजाज़त नहीं है"</string> + <string name="mmcc_imsi_unknown_in_hlr" msgid="5316658473301462825">"सिम से कॉल करने की इजाज़त नहीं है"</string> + <string name="mmcc_illegal_ms" msgid="807334478177362062">"सिम से कॉल करने की इजाज़त नहीं है"</string> + <string name="mmcc_illegal_me" msgid="1950705155760872972">"फ़ोन से कॉल करने की इजाज़त नहीं है"</string> <string name="popup_window_default_title" msgid="4874318849712115433">"पॉपअप विंडो"</string> <string name="slice_more_content" msgid="8504342889413274608">"+ <xliff:g id="NUMBER">%1$d</xliff:g>"</string> <string name="shortcut_restored_on_lower_version" msgid="5270675146351613828">"इस शॉर्टकट वाला ऐप चलाने के लिए इसका नया वर्शन डाउनलोड करें"</string> diff --git a/core/res/res/values-hy/strings.xml b/core/res/res/values-hy/strings.xml index c950c40325f3..99ff527a14c8 100644 --- a/core/res/res/values-hy/strings.xml +++ b/core/res/res/values-hy/strings.xml @@ -1626,7 +1626,6 @@ <string name="managed_profile_label_badge_2" msgid="5048136430082124036">"2-րդ աշխատանք <xliff:g id="LABEL">%1$s</xliff:g>"</string> <string name="managed_profile_label_badge_3" msgid="2808305070321719040">"3-րդ աշխատանք <xliff:g id="LABEL">%1$s</xliff:g>"</string> <string name="lock_to_app_toast" msgid="6820571533009838261">"Այս էկրանն ապամրացնելու համար հպեք և պահեք Հետ և Համատեսք կոճակները"</string> - <string name="lock_to_app_toast_locked" msgid="7849470948648628704">"Հնարավոր չէ ապամրացնել այս հավելվածը"</string> <string name="lock_to_app_start" msgid="6643342070839862795">"Էկրանն ամրացված է"</string> <string name="lock_to_app_exit" msgid="8598219838213787430">"Էկրանն ապամրացված է"</string> <string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"Ապաամրացնելուց առաջ հարցնել PIN-կոդը"</string> @@ -1782,14 +1781,10 @@ <string name="etws_primary_default_message_test" msgid="2709597093560037455">"Արտակարգ իրավիճակների հաղորդագրությունների թեստ"</string> <string name="notification_reply_button_accessibility" msgid="3621714652387814344">"Պատասխանել"</string> <string name="etws_primary_default_message_others" msgid="6293148756130398971"></string> - <!-- no translation found for mmcc_authentication_reject (5767701075994754356) --> - <skip /> - <!-- no translation found for mmcc_imsi_unknown_in_hlr (5316658473301462825) --> - <skip /> - <!-- no translation found for mmcc_illegal_ms (807334478177362062) --> - <skip /> - <!-- no translation found for mmcc_illegal_me (1950705155760872972) --> - <skip /> + <string name="mmcc_authentication_reject" msgid="5767701075994754356">"Այս SIM քարտով չեք կարող զանգել"</string> + <string name="mmcc_imsi_unknown_in_hlr" msgid="5316658473301462825">"Այս SIM քարտը նախապատրաստված չէ զանգելու համար"</string> + <string name="mmcc_illegal_ms" msgid="807334478177362062">"Այս SIM քարտով չեք կարող զանգել"</string> + <string name="mmcc_illegal_me" msgid="1950705155760872972">"Այս հեռախոսով չեք կարող զանգել"</string> <string name="popup_window_default_title" msgid="4874318849712115433">"Հայտնվող պատուհան"</string> <string name="slice_more_content" msgid="8504342889413274608">"+ <xliff:g id="NUMBER">%1$d</xliff:g>"</string> <string name="shortcut_restored_on_lower_version" msgid="5270675146351613828">"Այս դյուրանցման համար անհրաժեշտ է հավելվածի վերջին տարբերակը"</string> diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml index fe515d3bed52..cb7500429edd 100644 --- a/core/res/res/values-in/strings.xml +++ b/core/res/res/values-in/strings.xml @@ -317,7 +317,7 @@ <string name="permlab_receiveMms" msgid="1821317344668257098">"terima pesan teks (MMS)"</string> <string name="permdesc_receiveMms" msgid="533019437263212260">"Memungkinkan aplikasi menerima dan memproses pesan MMS. Ini artinya aplikasi dapat memantau atau menghapus pesan yang dikirim ke perangkat Anda tanpa menunjukkannya kepada Anda."</string> <string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"membaca pesan siaran seluler"</string> - <string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"Mengizinkan aplikasi membaca pesan siaran seluler yang diterima perangkat Anda. Lansiran siaran seluler dikirimkan di beberapa lokasi untuk memperingatkan Anda tentang situasi darurat. Aplikasi berbahaya dapat mengganggu kinerja atau operasi perangkat Anda saat siaran seluler darurat diterima."</string> + <string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"Mengizinkan aplikasi membaca pesan siaran seluler yang diterima perangkat Anda. Notifikasi siaran seluler dikirimkan di beberapa lokasi untuk memperingatkan Anda tentang situasi darurat. Aplikasi berbahaya dapat mengganggu kinerja atau operasi perangkat Anda saat siaran seluler darurat diterima."</string> <string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"baca umpan langganan"</string> <string name="permdesc_subscribedFeedsRead" msgid="5557058907906144505">"Mengizinkan apl mendapatkan detail tentang umpan yang saat ini sedang disinkronkan."</string> <string name="permlab_sendSms" msgid="7544599214260982981">"mengirim dan melihat pesan SMS"</string> @@ -1384,7 +1384,7 @@ <string name="storage_usb_drive_label" msgid="4501418548927759953">"Drive USB <xliff:g id="MANUFACTURER">%s</xliff:g>"</string> <string name="storage_usb" msgid="3017954059538517278">"Penyimpanan USB"</string> <string name="extract_edit_menu_button" msgid="8940478730496610137">"Edit"</string> - <string name="data_usage_warning_title" msgid="3620440638180218181">"Lansiran penggunaan data"</string> + <string name="data_usage_warning_title" msgid="3620440638180218181">"Notifikasi penggunaan data"</string> <string name="data_usage_warning_body" msgid="6660692274311972007">"Ketuk untuk lihat penggunaan & setelan."</string> <string name="data_usage_3g_limit_title" msgid="4361523876818447683">"Batas data 2G-3G terlampaui"</string> <string name="data_usage_4g_limit_title" msgid="4609566827219442376">"Batas data 4G terlampaui"</string> @@ -1626,7 +1626,6 @@ <string name="managed_profile_label_badge_2" msgid="5048136430082124036">"Upaya ke-2 <xliff:g id="LABEL">%1$s</xliff:g>"</string> <string name="managed_profile_label_badge_3" msgid="2808305070321719040">"Upaya ke-3 <xliff:g id="LABEL">%1$s</xliff:g>"</string> <string name="lock_to_app_toast" msgid="6820571533009838261">"Untuk melepas pin layar ini, sentuh & tahan tombol Kembali dan Ringkasan"</string> - <string name="lock_to_app_toast_locked" msgid="7849470948648628704">"Tidak dapat melepas pin aplikasi ini"</string> <string name="lock_to_app_start" msgid="6643342070839862795">"Layar disematkan"</string> <string name="lock_to_app_exit" msgid="8598219838213787430">"Layar dicopot sematannya"</string> <string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"Meminta PIN sebelum melepas sematan"</string> @@ -1782,14 +1781,10 @@ <string name="etws_primary_default_message_test" msgid="2709597093560037455">"Tes pesan darurat"</string> <string name="notification_reply_button_accessibility" msgid="3621714652387814344">"Balas"</string> <string name="etws_primary_default_message_others" msgid="6293148756130398971"></string> - <!-- no translation found for mmcc_authentication_reject (5767701075994754356) --> - <skip /> - <!-- no translation found for mmcc_imsi_unknown_in_hlr (5316658473301462825) --> - <skip /> - <!-- no translation found for mmcc_illegal_ms (807334478177362062) --> - <skip /> - <!-- no translation found for mmcc_illegal_me (1950705155760872972) --> - <skip /> + <string name="mmcc_authentication_reject" msgid="5767701075994754356">"SIM tidak diizinkan untuk suara"</string> + <string name="mmcc_imsi_unknown_in_hlr" msgid="5316658473301462825">"SIM tidak disediakan untuk suara"</string> + <string name="mmcc_illegal_ms" msgid="807334478177362062">"SIM tidak diizinkan untuk suara"</string> + <string name="mmcc_illegal_me" msgid="1950705155760872972">"Ponsel tidak diizinkan untuk suara"</string> <string name="popup_window_default_title" msgid="4874318849712115433">"Jendela Pop-up"</string> <string name="slice_more_content" msgid="8504342889413274608">"+ <xliff:g id="NUMBER">%1$d</xliff:g>"</string> <string name="shortcut_restored_on_lower_version" msgid="5270675146351613828">"Pintasan ini memerlukan aplikasi terbaru"</string> diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml index 5545c4324204..0f146babfefb 100644 --- a/core/res/res/values-iw/strings.xml +++ b/core/res/res/values-iw/strings.xml @@ -1345,7 +1345,7 @@ <string name="vpn_lockdown_disconnected" msgid="735805531187559719">"אין חיבור ל-VPN שפועל כל הזמן"</string> <string name="vpn_lockdown_error" msgid="6009249814034708175">"שגיאת VPN שמופעל תמיד"</string> <string name="vpn_lockdown_config" msgid="8151951501116759194">"רוצה לשנות את הגדרות הרשת או הגדרות ה-VPN?"</string> - <string name="upload_file" msgid="2897957172366730416">"בחר קובץ"</string> + <string name="upload_file" msgid="2897957172366730416">"בחירת קובץ"</string> <string name="no_file_chosen" msgid="6363648562170759465">"לא נבחר קובץ"</string> <string name="reset" msgid="2448168080964209908">"איפוס"</string> <string name="submit" msgid="1602335572089911941">"שלח"</string> @@ -1676,7 +1676,6 @@ <string name="managed_profile_label_badge_2" msgid="5048136430082124036">"<xliff:g id="LABEL">%1$s</xliff:g> שני בעבודה"</string> <string name="managed_profile_label_badge_3" msgid="2808305070321719040">"<xliff:g id="LABEL">%1$s</xliff:g> שלישי בעבודה"</string> <string name="lock_to_app_toast" msgid="6820571533009838261">"כדי לבטל את ההצמדה של מסך זה, גע בלחצנים \'הקודם\' ו\'סקירה\' והחזק אותם"</string> - <string name="lock_to_app_toast_locked" msgid="7849470948648628704">"לא ניתן לבטל את ההצמדה של האפליקציה הזו"</string> <string name="lock_to_app_start" msgid="6643342070839862795">"המסך מוצמד"</string> <string name="lock_to_app_exit" msgid="8598219838213787430">"הצמדת המסך בוטלה"</string> <string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"בקש קוד גישה לפני ביטול הצמדה"</string> @@ -1852,14 +1851,10 @@ <string name="etws_primary_default_message_test" msgid="2709597093560037455">"בדיקה של הודעות חירום"</string> <string name="notification_reply_button_accessibility" msgid="3621714652387814344">"השב"</string> <string name="etws_primary_default_message_others" msgid="6293148756130398971"></string> - <!-- no translation found for mmcc_authentication_reject (5767701075994754356) --> - <skip /> - <!-- no translation found for mmcc_imsi_unknown_in_hlr (5316658473301462825) --> - <skip /> - <!-- no translation found for mmcc_illegal_ms (807334478177362062) --> - <skip /> - <!-- no translation found for mmcc_illegal_me (1950705155760872972) --> - <skip /> + <string name="mmcc_authentication_reject" msgid="5767701075994754356">"כרטיס ה-SIM לא מורשה לזיהוי קולי"</string> + <string name="mmcc_imsi_unknown_in_hlr" msgid="5316658473301462825">"ניהול התצורה של כרטיס ה-SIM לא מתאים לזיהוי קולי"</string> + <string name="mmcc_illegal_ms" msgid="807334478177362062">"כרטיס ה-SIM לא מורשה לזיהוי קולי"</string> + <string name="mmcc_illegal_me" msgid="1950705155760872972">"הטלפון לא מורשה לזיהוי קולי"</string> <string name="popup_window_default_title" msgid="4874318849712115433">"חלון קופץ"</string> <string name="slice_more_content" msgid="8504342889413274608">"+ <xliff:g id="NUMBER">%1$d</xliff:g>"</string> <string name="shortcut_restored_on_lower_version" msgid="5270675146351613828">"קיצור דרך זה דורש את האפליקציה העדכנית ביותר"</string> diff --git a/core/res/res/values-ne/strings.xml b/core/res/res/values-ne/strings.xml index 830023713091..7de97b39cdb0 100644 --- a/core/res/res/values-ne/strings.xml +++ b/core/res/res/values-ne/strings.xml @@ -1632,7 +1632,6 @@ <string name="managed_profile_label_badge_2" msgid="5048136430082124036">"कार्यालयको दोस्रो <xliff:g id="LABEL">%1$s</xliff:g>"</string> <string name="managed_profile_label_badge_3" msgid="2808305070321719040">"कार्यालयको तेस्रो <xliff:g id="LABEL">%1$s</xliff:g>"</string> <string name="lock_to_app_toast" msgid="6820571533009838261">"यस स्क्रिनलाई अनपनि गर्न पछाडि जाने र परिदृश्य बटनहरूलाई छोएर थिची राख्नुहोस्"</string> - <string name="lock_to_app_toast_locked" msgid="7849470948648628704">"यस अनुप्रयोगलाई अनपिन गर्न मिल्दैन"</string> <string name="lock_to_app_start" msgid="6643342070839862795">"स्क्रिन पिन गरियो"</string> <string name="lock_to_app_exit" msgid="8598219838213787430">"स्क्रिन अनपिन गरियो"</string> <string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"पिन निकाल्नुअघि PIN सोध्नुहोस्"</string> @@ -1788,14 +1787,10 @@ <string name="etws_primary_default_message_test" msgid="2709597093560037455">"आपतकालीन सन्देशहरूको परीक्षण"</string> <string name="notification_reply_button_accessibility" msgid="3621714652387814344">"जवाफ दिनुहोस्"</string> <string name="etws_primary_default_message_others" msgid="6293148756130398971"></string> - <!-- no translation found for mmcc_authentication_reject (5767701075994754356) --> - <skip /> - <!-- no translation found for mmcc_imsi_unknown_in_hlr (5316658473301462825) --> - <skip /> - <!-- no translation found for mmcc_illegal_ms (807334478177362062) --> - <skip /> - <!-- no translation found for mmcc_illegal_me (1950705155760872972) --> - <skip /> + <string name="mmcc_authentication_reject" msgid="5767701075994754356">"SIM मार्फत भ्वाइस कल गर्न मिल्दैन"</string> + <string name="mmcc_imsi_unknown_in_hlr" msgid="5316658473301462825">"SIM मार्फत भ्वाइस कल गर्ने प्रावधान छैन"</string> + <string name="mmcc_illegal_ms" msgid="807334478177362062">"SIM मार्फत भ्वाइस कल गर्न मिल्दैन"</string> + <string name="mmcc_illegal_me" msgid="1950705155760872972">"फोनमार्फत भ्वाइस कल गर्न मिल्दैन"</string> <string name="popup_window_default_title" msgid="4874318849712115433">"पपअप विन्डो"</string> <string name="slice_more_content" msgid="8504342889413274608">"+ <xliff:g id="NUMBER">%1$d</xliff:g>"</string> <string name="shortcut_restored_on_lower_version" msgid="5270675146351613828">"यो सर्टकटलाई पछिल्लो अनुप्रयोग आवश्यक हुन्छ"</string> diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml index 44215c3720c7..f99d531b8deb 100644 --- a/core/res/res/values-nl/strings.xml +++ b/core/res/res/values-nl/strings.xml @@ -211,9 +211,9 @@ <string name="global_action_lock" msgid="2844945191792119712">"Schermvergrendeling"</string> <string name="global_action_power_off" msgid="4471879440839879722">"Uitschakelen"</string> <string name="global_action_emergency" msgid="7112311161137421166">"Noodgeval"</string> - <string name="global_action_bug_report" msgid="7934010578922304799">"Foutenrapport"</string> - <string name="bugreport_title" msgid="2667494803742548533">"Foutenrapport genereren"</string> - <string name="bugreport_message" msgid="398447048750350456">"Hiermee worden gegevens over de huidige status van je apparaat verzameld en als e-mail verzonden. Wanneer u een foutenrapport start, duurt het even voordat het kan worden verzonden. Even geduld alstublieft."</string> + <string name="global_action_bug_report" msgid="7934010578922304799">"Bugrapport"</string> + <string name="bugreport_title" msgid="2667494803742548533">"Bugrapport genereren"</string> + <string name="bugreport_message" msgid="398447048750350456">"Hiermee worden gegevens over de huidige status van je apparaat verzameld en als e-mail verzonden. Wanneer u een bugrapport start, duurt het even voordat het kan worden verzonden. Even geduld alstublieft."</string> <string name="bugreport_option_interactive_title" msgid="8635056131768862479">"Interactief rapport"</string> <string name="bugreport_option_interactive_summary" msgid="229299488536107968">"Gebruik deze optie in de meeste situaties. Hiermee kun je de voortgang van het rapport bijhouden, meer gegevens over het probleem opgeven en screenshots maken. Mogelijk worden bepaalde minder vaak gebruikte gedeelten weggelaten (waarvoor het lang zou duren om een rapport te genereren)."</string> <string name="bugreport_option_full_title" msgid="6354382025840076439">"Volledig rapport"</string> @@ -1626,7 +1626,6 @@ <string name="managed_profile_label_badge_2" msgid="5048136430082124036">"2e <xliff:g id="LABEL">%1$s</xliff:g>, werk"</string> <string name="managed_profile_label_badge_3" msgid="2808305070321719040">"3e <xliff:g id="LABEL">%1$s</xliff:g>, werk"</string> <string name="lock_to_app_toast" msgid="6820571533009838261">"Tik op Terug en Overzicht en houd deze knoppen vast om dit scherm los te maken"</string> - <string name="lock_to_app_toast_locked" msgid="7849470948648628704">"Deze app kan niet worden losgemaakt"</string> <string name="lock_to_app_start" msgid="6643342070839862795">"Scherm vastgezet"</string> <string name="lock_to_app_exit" msgid="8598219838213787430">"Scherm losgemaakt"</string> <string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"Vraag pin voor losmaken"</string> @@ -1782,14 +1781,10 @@ <string name="etws_primary_default_message_test" msgid="2709597093560037455">"Test voor noodberichten"</string> <string name="notification_reply_button_accessibility" msgid="3621714652387814344">"Beantwoorden"</string> <string name="etws_primary_default_message_others" msgid="6293148756130398971"></string> - <!-- no translation found for mmcc_authentication_reject (5767701075994754356) --> - <skip /> - <!-- no translation found for mmcc_imsi_unknown_in_hlr (5316658473301462825) --> - <skip /> - <!-- no translation found for mmcc_illegal_ms (807334478177362062) --> - <skip /> - <!-- no translation found for mmcc_illegal_me (1950705155760872972) --> - <skip /> + <string name="mmcc_authentication_reject" msgid="5767701075994754356">"Simkaart niet toegestaan voor spraak"</string> + <string name="mmcc_imsi_unknown_in_hlr" msgid="5316658473301462825">"Sim niet geregistreerd voor spraak"</string> + <string name="mmcc_illegal_ms" msgid="807334478177362062">"Simkaart niet toegestaan voor spraak"</string> + <string name="mmcc_illegal_me" msgid="1950705155760872972">"Telefoon niet toegestaan voor spraak"</string> <string name="popup_window_default_title" msgid="4874318849712115433">"Pop-upvenster"</string> <string name="slice_more_content" msgid="8504342889413274608">"+ <xliff:g id="NUMBER">%1$d</xliff:g>"</string> <string name="shortcut_restored_on_lower_version" msgid="5270675146351613828">"Voor deze snelkoppeling is de nieuwste app vereist"</string> diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml index afa28dd21fea..af5cfeca6004 100644 --- a/core/res/res/values-pt-rPT/strings.xml +++ b/core/res/res/values-pt-rPT/strings.xml @@ -166,17 +166,17 @@ <item quantity="other">Autoridades de certificação instaladas</item> </plurals> <string name="ssl_ca_cert_noti_by_unknown" msgid="4475437862189850602">"Por um terceiro desconhecido"</string> - <string name="ssl_ca_cert_noti_by_administrator" msgid="3541729986326153557">"Pelo administrador do seu perfil de trabalho"</string> + <string name="ssl_ca_cert_noti_by_administrator" msgid="3541729986326153557">"Pelo gestor do seu perfil de trabalho"</string> <string name="ssl_ca_cert_noti_managed" msgid="4030263497686867141">"Por <xliff:g id="MANAGING_DOMAIN">%s</xliff:g>"</string> <string name="work_profile_deleted" msgid="5005572078641980632">"Perfil de trabalho eliminado"</string> <string name="work_profile_deleted_description" msgid="1100529432509639864">"Perfil de trabalho eliminado devido a aplicação de administração em falta"</string> - <string name="work_profile_deleted_details" msgid="6307630639269092360">"A aplicação de administração do perfil de trabalho está em falta ou danificada. Consequentemente, o seu perfil de trabalho e os dados relacionados foram eliminados. Contacte o administrador para obter assistência."</string> + <string name="work_profile_deleted_details" msgid="6307630639269092360">"A aplicação de administração do perfil de trabalho está em falta ou danificada. Consequentemente, o seu perfil de trabalho e os dados relacionados foram eliminados. Contacte o gestor para obter assistência."</string> <string name="work_profile_deleted_description_dpm_wipe" msgid="8823792115612348820">"O seu perfil de trabalho já não está disponível neste dispositivo"</string> <string name="work_profile_deleted_reason_maximum_password_failure" msgid="8986903510053359694">"Demasiadas tentativas de introdução da palavra-passe"</string> <string name="network_logging_notification_title" msgid="6399790108123704477">"O dispositivo é gerido"</string> <string name="network_logging_notification_text" msgid="7930089249949354026">"A sua entidade gere este dispositivo e pode monitorizar o tráfego de rede. Toque para obter mais detalhes."</string> <string name="factory_reset_warning" msgid="5423253125642394387">"O seu dispositivo será apagado"</string> - <string name="factory_reset_message" msgid="7972496262232832457">"Não é possível utilizar a aplicação de administração. O seu dispositivo será agora apagado.\n\nSe tiver questões, contacte o administrador da entidade."</string> + <string name="factory_reset_message" msgid="7972496262232832457">"Não é possível utilizar a aplicação de administração. O seu dispositivo será agora apagado.\n\nSe tiver questões, contacte o gestor da entidade."</string> <string name="me" msgid="6545696007631404292">"Eu"</string> <string name="power_dialog" product="tablet" msgid="8545351420865202853">"Opções do tablet"</string> <string name="power_dialog" product="tv" msgid="6153888706430556356">"Opções de TV"</string> @@ -1199,7 +1199,7 @@ <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"A criar relatório de erro…"</string> <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Pretende partilhar o relatório de erro?"</string> <string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"A partilhar relatório de erro…"</string> - <string name="share_remote_bugreport_notification_message_finished" msgid="6029609949340992866">"O seu administrador solicitou um relatório de erro para ajudar na resolução de problemas deste dispositivo. As aplicações e os dados podem ser partilhados."</string> + <string name="share_remote_bugreport_notification_message_finished" msgid="6029609949340992866">"O seu gestor solicitou um relatório de erro para ajudar na resolução de problemas deste dispositivo. As aplicações e os dados podem ser partilhados."</string> <string name="share_remote_bugreport_action" msgid="6249476773913384948">"PARTILHAR"</string> <string name="decline_remote_bugreport_action" msgid="6230987241608770062">"RECUSAR"</string> <string name="select_input_method" msgid="8547250819326693584">"Alterar teclado"</string> @@ -1310,7 +1310,7 @@ <string name="tethered_notification_title" msgid="3146694234398202601">"Ligação ponto a ponto ou hotspot activos"</string> <string name="tethered_notification_message" msgid="2113628520792055377">"Toque para configurar."</string> <string name="disable_tether_notification_title" msgid="7526977944111313195">"A ligação (à Internet) via telemóvel está desativada."</string> - <string name="disable_tether_notification_message" msgid="2913366428516852495">"Contacte o administrador para obter detalhes."</string> + <string name="disable_tether_notification_message" msgid="2913366428516852495">"Contacte o gestor para obter detalhes."</string> <string name="back_button_label" msgid="2300470004503343439">"Anterior"</string> <string name="next_button_label" msgid="1080555104677992408">"Seguinte"</string> <string name="skip_button_label" msgid="1275362299471631819">"Ignorar"</string> @@ -1505,7 +1505,7 @@ <string name="user_logging_out_message" msgid="8939524935808875155">"A terminar a sessão de <xliff:g id="NAME">%1$s</xliff:g>…"</string> <string name="owner_name" msgid="2716755460376028154">"Proprietário"</string> <string name="error_message_title" msgid="4510373083082500195">"Erro"</string> - <string name="error_message_change_not_allowed" msgid="1238035947357923497">"O administrador não permite esta alteração"</string> + <string name="error_message_change_not_allowed" msgid="1238035947357923497">"O gestor não permite esta alteração"</string> <string name="app_not_found" msgid="3429141853498927379">"Não foram encontradas aplicações para executar esta ação"</string> <string name="revoke" msgid="5404479185228271586">"Revogar"</string> <string name="mediasize_iso_a0" msgid="1994474252931294172">"ISO A0"</string> @@ -1597,7 +1597,7 @@ <string name="reason_service_unavailable" msgid="7824008732243903268">"Serviço de impressão não ativado"</string> <string name="print_service_installed_title" msgid="2246317169444081628">"Serviço <xliff:g id="NAME">%s</xliff:g> instalado"</string> <string name="print_service_installed_message" msgid="5897362931070459152">"Toque para ativar"</string> - <string name="restr_pin_enter_admin_pin" msgid="8641662909467236832">"Introduzir o PIN do administrador"</string> + <string name="restr_pin_enter_admin_pin" msgid="8641662909467236832">"Introduzir o PIN do gestor"</string> <string name="restr_pin_enter_pin" msgid="3395953421368476103">"Introduzir PIN"</string> <string name="restr_pin_incorrect" msgid="8571512003955077924">"Incorreto"</string> <string name="restr_pin_enter_old_pin" msgid="1462206225512910757">"PIN Atual"</string> @@ -1626,15 +1626,14 @@ <string name="managed_profile_label_badge_2" msgid="5048136430082124036">"2.º <xliff:g id="LABEL">%1$s</xliff:g> de trabalho"</string> <string name="managed_profile_label_badge_3" msgid="2808305070321719040">"3.º <xliff:g id="LABEL">%1$s</xliff:g> de trabalho"</string> <string name="lock_to_app_toast" msgid="6820571533009838261">"Para soltar este ecrã, toque sem soltar nos botões Anterior e Vista geral"</string> - <string name="lock_to_app_toast_locked" msgid="7849470948648628704">"Não é possível soltar esta aplicação"</string> <string name="lock_to_app_start" msgid="6643342070839862795">"Ecrã fixo"</string> <string name="lock_to_app_exit" msgid="8598219838213787430">"Ecrã solto"</string> <string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"Pedir PIN antes de soltar"</string> <string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"Pedir sequência de desbloqueio antes de soltar"</string> <string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Pedir palavra-passe antes de soltar"</string> - <string name="package_installed_device_owner" msgid="6875717669960212648">"Instalado pelo seu administrador"</string> - <string name="package_updated_device_owner" msgid="1847154566357862089">"Atualizado pelo seu administrador"</string> - <string name="package_deleted_device_owner" msgid="2307122077550236438">"Eliminado pelo seu administrador"</string> + <string name="package_installed_device_owner" msgid="6875717669960212648">"Instalado pelo seu gestor"</string> + <string name="package_updated_device_owner" msgid="1847154566357862089">"Atualizado pelo seu gestor"</string> + <string name="package_deleted_device_owner" msgid="2307122077550236438">"Eliminado pelo seu gestor"</string> <string name="battery_saver_description" msgid="1960431123816253034">"Para ajudar a melhorar a autonomia da bateria, a poupança de bateria reduz o desempenho do seu dispositivo e limita a vibração, os serviços de localização e a maioria dos dados em segundo plano. O email, as mensagens e outras aplicações que dependem da sincronização não podem ser atualizados exceto se os abrir.\n\nA poupança de bateria desliga-se automaticamente quando o dispositivo está a carregar."</string> <string name="data_saver_description" msgid="6015391409098303235">"Para ajudar a reduzir a utilização de dados, a Poupança de dados impede que algumas aplicações enviem ou recebam dados em segundo plano. Uma determinada aplicação que esteja a utilizar atualmente pode aceder aos dados, mas é possível que o faça com menos frequência. Isto pode significar, por exemplo, que as imagens não são apresentadas até que toque nas mesmas."</string> <string name="data_saver_enable_title" msgid="4674073932722787417">"Ativar a Poupança de dados?"</string> @@ -1782,14 +1781,10 @@ <string name="etws_primary_default_message_test" msgid="2709597093560037455">"Teste de mensagens de emergência"</string> <string name="notification_reply_button_accessibility" msgid="3621714652387814344">"Responder"</string> <string name="etws_primary_default_message_others" msgid="6293148756130398971"></string> - <!-- no translation found for mmcc_authentication_reject (5767701075994754356) --> - <skip /> - <!-- no translation found for mmcc_imsi_unknown_in_hlr (5316658473301462825) --> - <skip /> - <!-- no translation found for mmcc_illegal_ms (807334478177362062) --> - <skip /> - <!-- no translation found for mmcc_illegal_me (1950705155760872972) --> - <skip /> + <string name="mmcc_authentication_reject" msgid="5767701075994754356">"SIM não permitido para voz"</string> + <string name="mmcc_imsi_unknown_in_hlr" msgid="5316658473301462825">"SIM não aprovisionado para voz"</string> + <string name="mmcc_illegal_ms" msgid="807334478177362062">"SIM não permitido para voz"</string> + <string name="mmcc_illegal_me" msgid="1950705155760872972">"Telemóvel não permitido para voz"</string> <string name="popup_window_default_title" msgid="4874318849712115433">"Janela pop-up"</string> <string name="slice_more_content" msgid="8504342889413274608">"+ <xliff:g id="NUMBER">%1$d</xliff:g>"</string> <string name="shortcut_restored_on_lower_version" msgid="5270675146351613828">"Este atalho requer a aplicação mais recente."</string> diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml index 2dd1d1a3a58f..b6de548af434 100644 --- a/core/res/res/values-sr/strings.xml +++ b/core/res/res/values-sr/strings.xml @@ -278,8 +278,8 @@ <string name="permgroupdesc_storage" msgid="637758554581589203">"приступа сликама, медијима и датотекама на уређају"</string> <string name="permgrouprequest_storage" msgid="7429669910547860218">"Дозволите <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> да приступа сликама, медијским датотекама и датотекама на уређају"</string> <string name="permgrouplab_microphone" msgid="171539900250043464">"Микрофон"</string> - <string name="permgroupdesc_microphone" msgid="4988812113943554584">"снима аудио"</string> - <string name="permgrouprequest_microphone" msgid="8065941268709600606">"Дозволите да <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> снима аудио снимке"</string> + <string name="permgroupdesc_microphone" msgid="4988812113943554584">"снима звук"</string> + <string name="permgrouprequest_microphone" msgid="8065941268709600606">"Дозволите да <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> снима звук"</string> <string name="permgrouplab_camera" msgid="4820372495894586615">"Камера"</string> <string name="permgroupdesc_camera" msgid="3250611594678347720">"снима слике и видео"</string> <string name="permgrouprequest_camera" msgid="810824326507258410">"Дозволите да <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> снима слике и видео снимке"</string> @@ -1651,7 +1651,6 @@ <string name="managed_profile_label_badge_2" msgid="5048136430082124036">"2. пословни <xliff:g id="LABEL">%1$s</xliff:g>"</string> <string name="managed_profile_label_badge_3" msgid="2808305070321719040">"3. пословни имејл <xliff:g id="LABEL">%1$s</xliff:g>"</string> <string name="lock_to_app_toast" msgid="6820571533009838261">"Да бисте откачили овај екран, додирните и задржите дугмад Назад и Преглед"</string> - <string name="lock_to_app_toast_locked" msgid="7849470948648628704">"Ова апликација не може да се откачи"</string> <string name="lock_to_app_start" msgid="6643342070839862795">"Екран је закачен"</string> <string name="lock_to_app_exit" msgid="8598219838213787430">"Екран је откачен"</string> <string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"Тражи PIN пре откачињања"</string> @@ -1817,14 +1816,10 @@ <string name="etws_primary_default_message_test" msgid="2709597093560037455">"Тестирање порука у хитним случајевима"</string> <string name="notification_reply_button_accessibility" msgid="3621714652387814344">"Одговори"</string> <string name="etws_primary_default_message_others" msgid="6293148756130398971"></string> - <!-- no translation found for mmcc_authentication_reject (5767701075994754356) --> - <skip /> - <!-- no translation found for mmcc_imsi_unknown_in_hlr (5316658473301462825) --> - <skip /> - <!-- no translation found for mmcc_illegal_ms (807334478177362062) --> - <skip /> - <!-- no translation found for mmcc_illegal_me (1950705155760872972) --> - <skip /> + <string name="mmcc_authentication_reject" msgid="5767701075994754356">"SIM картица није прилагођена за гласовне услуге"</string> + <string name="mmcc_imsi_unknown_in_hlr" msgid="5316658473301462825">"SIM картица није подешена за гласовне услуге"</string> + <string name="mmcc_illegal_ms" msgid="807334478177362062">"SIM картица није прилагођена за гласовне услуге"</string> + <string name="mmcc_illegal_me" msgid="1950705155760872972">"Телефон није прилагођен за гласовне услуге"</string> <string name="popup_window_default_title" msgid="4874318849712115433">"Искачући прозор"</string> <string name="slice_more_content" msgid="8504342889413274608">"и још <xliff:g id="NUMBER">%1$d</xliff:g>"</string> <string name="shortcut_restored_on_lower_version" msgid="5270675146351613828">"Ова пречица захтева најновију апликацију"</string> diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml index 2460e6550927..8b778508035b 100644 --- a/core/res/res/values-tr/strings.xml +++ b/core/res/res/values-tr/strings.xml @@ -1626,7 +1626,6 @@ <string name="managed_profile_label_badge_2" msgid="5048136430082124036">"İş için 2. <xliff:g id="LABEL">%1$s</xliff:g>"</string> <string name="managed_profile_label_badge_3" msgid="2808305070321719040">"İş için 3. <xliff:g id="LABEL">%1$s</xliff:g>"</string> <string name="lock_to_app_toast" msgid="6820571533009838261">"Bu ekranın sabitlemesini kaldırmak için Geri\'ye ve Genel Bakış\'a dokunup basılı tutun"</string> - <string name="lock_to_app_toast_locked" msgid="7849470948648628704">"Bu uygulamanın sabitlemesi kaldırılamaz"</string> <string name="lock_to_app_start" msgid="6643342070839862795">"Ekran sabitlendi"</string> <string name="lock_to_app_exit" msgid="8598219838213787430">"Ekran sabitlemesi kaldırıldı"</string> <string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"Sabitlemeyi kaldırmadan önce PIN\'i sor"</string> @@ -1782,14 +1781,10 @@ <string name="etws_primary_default_message_test" msgid="2709597093560037455">"Acil durum mesajları testi"</string> <string name="notification_reply_button_accessibility" msgid="3621714652387814344">"Yanıtla"</string> <string name="etws_primary_default_message_others" msgid="6293148756130398971"></string> - <!-- no translation found for mmcc_authentication_reject (5767701075994754356) --> - <skip /> - <!-- no translation found for mmcc_imsi_unknown_in_hlr (5316658473301462825) --> - <skip /> - <!-- no translation found for mmcc_illegal_ms (807334478177362062) --> - <skip /> - <!-- no translation found for mmcc_illegal_me (1950705155760872972) --> - <skip /> + <string name="mmcc_authentication_reject" msgid="5767701075994754356">"Ses için SIM\'e izin verilmiyor"</string> + <string name="mmcc_imsi_unknown_in_hlr" msgid="5316658473301462825">"Ses için SIM\'in temel hazırlığı yapılmadı"</string> + <string name="mmcc_illegal_ms" msgid="807334478177362062">"Ses için SIM\'e izin verilmiyor"</string> + <string name="mmcc_illegal_me" msgid="1950705155760872972">"Ses için telefona izin verilmiyor"</string> <string name="popup_window_default_title" msgid="4874318849712115433">"Pop-up Pencere"</string> <string name="slice_more_content" msgid="8504342889413274608">"+ <xliff:g id="NUMBER">%1$d</xliff:g>"</string> <string name="shortcut_restored_on_lower_version" msgid="5270675146351613828">"Bu kısayol, en son uygulamayı gerektiriyor"</string> diff --git a/core/res/res/values-uz/strings.xml b/core/res/res/values-uz/strings.xml index a99fc0f37eb8..af5e0bd33dac 100644 --- a/core/res/res/values-uz/strings.xml +++ b/core/res/res/values-uz/strings.xml @@ -980,7 +980,7 @@ <string name="editTextMenuTitle" msgid="4909135564941815494">"Matn yozish"</string> <string name="email" msgid="4560673117055050403">"E-pochta"</string> <string name="dial" msgid="1253998302767701559">"Chaqiruv"</string> - <string name="map" msgid="6521159124535543457">"Joylashuvni aniqlash"</string> + <string name="map" msgid="6521159124535543457">"Xaritadan topish"</string> <string name="browse" msgid="1245903488306147205">"Ochish"</string> <string name="sms" msgid="4560537514610063430">"Xabar"</string> <string name="add_contact" msgid="7867066569670597203">"Qo‘shish"</string> @@ -1626,7 +1626,6 @@ <string name="managed_profile_label_badge_2" msgid="5048136430082124036">"2-ishxona <xliff:g id="LABEL">%1$s</xliff:g>"</string> <string name="managed_profile_label_badge_3" msgid="2808305070321719040">"3-ishxona <xliff:g id="LABEL">%1$s</xliff:g>"</string> <string name="lock_to_app_toast" msgid="6820571533009838261">"Bu ekrandan chiqish uchun Orqaga va Menyu tugmalarini bosib turing"</string> - <string name="lock_to_app_toast_locked" msgid="7849470948648628704">"Bu ilovani olib tashlab bo‘lmaydi"</string> <string name="lock_to_app_start" msgid="6643342070839862795">"Ekran qadab qo‘yildi"</string> <string name="lock_to_app_exit" msgid="8598219838213787430">"Ekran bo‘shatildi"</string> <string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"Yechishda PIN-kod so‘ralsin"</string> @@ -1782,14 +1781,10 @@ <string name="etws_primary_default_message_test" msgid="2709597093560037455">"Favqulodda holatlar uchun sinov xabarlari"</string> <string name="notification_reply_button_accessibility" msgid="3621714652387814344">"Javob berish"</string> <string name="etws_primary_default_message_others" msgid="6293148756130398971"></string> - <!-- no translation found for mmcc_authentication_reject (5767701075994754356) --> - <skip /> - <!-- no translation found for mmcc_imsi_unknown_in_hlr (5316658473301462825) --> - <skip /> - <!-- no translation found for mmcc_illegal_ms (807334478177362062) --> - <skip /> - <!-- no translation found for mmcc_illegal_me (1950705155760872972) --> - <skip /> + <string name="mmcc_authentication_reject" msgid="5767701075994754356">"Ovoz uchun SIM karta ishlatish taqiqlangan"</string> + <string name="mmcc_imsi_unknown_in_hlr" msgid="5316658473301462825">"Ovoz uchun SIM karta taqdim etilmagan"</string> + <string name="mmcc_illegal_ms" msgid="807334478177362062">"Ovoz uchun SIM karta ishlatish taqiqlangan"</string> + <string name="mmcc_illegal_me" msgid="1950705155760872972">"Ovoz uchun telefon taqiqlangan"</string> <string name="popup_window_default_title" msgid="4874318849712115433">"Qalqib chiquvchi oyna"</string> <string name="slice_more_content" msgid="8504342889413274608">"+ <xliff:g id="NUMBER">%1$d</xliff:g>"</string> <string name="shortcut_restored_on_lower_version" msgid="5270675146351613828">"Bu yorliq uchun eng oxirgi versiyadagi ilova zarur"</string> diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml index 376139486fc5..c2814d72ebe0 100644 --- a/core/res/res/values/config.xml +++ b/core/res/res/values/config.xml @@ -2085,6 +2085,9 @@ <!-- Maximum number of supported users --> <integer name="config_multiuserMaximumUsers">1</integer> + <!-- Maximum number of users we allow to be running at a time --> + <integer name="config_multiuserMaxRunningUsers">3</integer> + <!-- Whether UI for multi user should be shown --> <bool name="config_enableMultiUserUI">false</bool> @@ -2368,6 +2371,10 @@ property. If this is false, then the following recents config flags are ignored. --> <bool name="config_hasRecents">true</bool> + <!-- Component name for the activity that will be presenting the Recents UI, which will receive + special permissions for API related to fetching and presenting recent tasks. --> + <string name="config_recentsComponentName" translatable="false">com.android.systemui/.recents.RecentsActivity</string> + <!-- The minimum number of visible recent tasks to be presented to the user through the SystemUI. Can be -1 if there is no minimum limit. --> <integer name="config_minNumVisibleRecentTasks_grid">-1</integer> diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml index f8a147d1e9f2..f301644f8f89 100644 --- a/core/res/res/values/symbols.xml +++ b/core/res/res/values/symbols.xml @@ -311,6 +311,7 @@ <java-symbol type="bool" name="config_enableMultiUserUI"/> <java-symbol type="bool" name="config_disableUsbPermissionDialogs"/> <java-symbol type="bool" name="config_hasRecents" /> + <java-symbol type="string" name="config_recentsComponentName" /> <java-symbol type="integer" name="config_minNumVisibleRecentTasks_lowRam" /> <java-symbol type="integer" name="config_maxNumVisibleRecentTasks_lowRam" /> <java-symbol type="integer" name="config_minNumVisibleRecentTasks_grid" /> @@ -444,6 +445,7 @@ <java-symbol type="integer" name="config_soundEffectVolumeDb" /> <java-symbol type="integer" name="config_lockSoundVolumeDb" /> <java-symbol type="integer" name="config_multiuserMaximumUsers" /> + <java-symbol type="integer" name="config_multiuserMaxRunningUsers" /> <java-symbol type="integer" name="config_safe_media_volume_index" /> <java-symbol type="integer" name="config_mobile_mtu" /> <java-symbol type="array" name="config_mobile_tcp_buffers" /> diff --git a/core/tests/coretests/src/android/app/NotificationTest.java b/core/tests/coretests/src/android/app/NotificationTest.java index 5457713112fe..bec862ab7d2f 100644 --- a/core/tests/coretests/src/android/app/NotificationTest.java +++ b/core/tests/coretests/src/android/app/NotificationTest.java @@ -22,10 +22,13 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import android.content.Context; +import android.content.Intent; import android.media.session.MediaSession; +import android.os.Parcel; import android.support.test.InstrumentationRegistry; import android.support.test.filters.SmallTest; import android.support.test.runner.AndroidJUnit4; +import android.widget.RemoteViews; import org.junit.Before; import org.junit.Test; @@ -138,6 +141,44 @@ public class NotificationTest { assertFalse(n.hasCompletedProgress()); } + @Test + public void allPendingIntents_recollectedAfterReusingBuilder() { + PendingIntent intent1 = PendingIntent.getActivity(mContext, 0, new Intent("test1"), 0); + PendingIntent intent2 = PendingIntent.getActivity(mContext, 0, new Intent("test2"), 0); + + Notification.Builder builder = new Notification.Builder(mContext, "channel"); + builder.setContentIntent(intent1); + + Parcel p = Parcel.obtain(); + + Notification n1 = builder.build(); + n1.writeToParcel(p, 0); + + builder.setContentIntent(intent2); + Notification n2 = builder.build(); + n2.writeToParcel(p, 0); + + assertTrue(n2.allPendingIntents.contains(intent2)); + } + + @Test + public void allPendingIntents_containsCustomRemoteViews() { + PendingIntent intent = PendingIntent.getActivity(mContext, 0, new Intent("test"), 0); + + RemoteViews contentView = new RemoteViews(mContext.getPackageName(), 0 /* layoutId */); + contentView.setOnClickPendingIntent(1 /* id */, intent); + + Notification.Builder builder = new Notification.Builder(mContext, "channel"); + builder.setCustomContentView(contentView); + + Parcel p = Parcel.obtain(); + + Notification n = builder.build(); + n.writeToParcel(p, 0); + + assertTrue(n.allPendingIntents.contains(intent)); + } + private Notification.Builder getMediaNotification() { MediaSession session = new MediaSession(mContext, "test"); return new Notification.Builder(mContext, "color") diff --git a/core/tests/coretests/src/android/widget/RemoteViewsTest.java b/core/tests/coretests/src/android/widget/RemoteViewsTest.java index ddf9876d3dae..70cf097f42a3 100644 --- a/core/tests/coretests/src/android/widget/RemoteViewsTest.java +++ b/core/tests/coretests/src/android/widget/RemoteViewsTest.java @@ -27,6 +27,7 @@ import android.graphics.Bitmap; import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.Drawable; import android.os.AsyncTask; +import android.os.Binder; import android.os.Parcel; import android.support.test.InstrumentationRegistry; import android.support.test.filters.SmallTest; @@ -376,13 +377,24 @@ public class RemoteViewsTest { parcelAndRecreate(views); } - private void parcelAndRecreate(RemoteViews views) { + private RemoteViews parcelAndRecreate(RemoteViews views) { + return parcelAndRecreateWithPendingIntentCookie(views, null); + } + + private RemoteViews parcelAndRecreateWithPendingIntentCookie(RemoteViews views, Object cookie) { Parcel p = Parcel.obtain(); - views.writeToParcel(p, 0); - p.setDataPosition(0); + try { + views.writeToParcel(p, 0); + p.setDataPosition(0); + + if (cookie != null) { + p.setClassCookie(PendingIntent.class, cookie); + } - RemoteViews.CREATOR.createFromParcel(p); - p.recycle(); + return RemoteViews.CREATOR.createFromParcel(p); + } finally { + p.recycle(); + } } @Test @@ -399,4 +411,37 @@ public class RemoteViewsTest { throw new Exception(t); } } + + @Test + public void copy_keepsPendingIntentWhitelistToken() throws Exception { + Binder whitelistToken = new Binder(); + + RemoteViews views = new RemoteViews(mPackage, R.layout.remote_views_test); + PendingIntent pi = PendingIntent.getBroadcast(mContext, 0, + new Intent("test"), PendingIntent.FLAG_ONE_SHOT); + views.setOnClickPendingIntent(1, pi); + RemoteViews withCookie = parcelAndRecreateWithPendingIntentCookie(views, whitelistToken); + + RemoteViews cloned = new RemoteViews(withCookie); + + PendingIntent found = extractAnyPendingIntent(cloned); + assertEquals(whitelistToken, found.getWhitelistToken()); + } + + private PendingIntent extractAnyPendingIntent(RemoteViews cloned) { + PendingIntent[] found = new PendingIntent[1]; + Parcel p = Parcel.obtain(); + try { + PendingIntent.setOnMarshaledListener((intent, parcel, flags) -> { + if (parcel == p) { + found[0] = intent; + } + }); + cloned.writeToParcel(p, 0); + } finally { + p.recycle(); + PendingIntent.setOnMarshaledListener(null); + } + return found[0]; + } } diff --git a/core/tests/webkit/Android.mk b/core/tests/webkit/Android.mk new file mode 100644 index 000000000000..cd0c3d25a68b --- /dev/null +++ b/core/tests/webkit/Android.mk @@ -0,0 +1,44 @@ +# Copyright (C) 2017 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +LOCAL_PATH:= $(call my-dir) +include $(CLEAR_VARS) + +# We only want this apk build for tests. +LOCAL_MODULE_TAGS := tests + +LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS) + + +# Include all test java files. +LOCAL_SRC_FILES := \ + $(call all-java-files-under, unit_tests_src) + +LOCAL_JAVA_LIBRARIES := android.test.runner + +LOCAL_STATIC_JAVA_LIBRARIES := \ + android-support-test + +LOCAL_PACKAGE_NAME := WebViewLoadingTests +LOCAL_CERTIFICATE := platform + +LOCAL_COMPATIBILITY_SUITE := device-tests + +LOCAL_REQUIRED_MODULES := \ + WebViewLoadingOnDiskTestApk \ + WebViewLoadingFromApkTestApk + +include $(BUILD_PACKAGE) + +include $(call all-makefiles-under,$(LOCAL_PATH)) diff --git a/core/tests/webkit/AndroidManifest.xml b/core/tests/webkit/AndroidManifest.xml new file mode 100644 index 000000000000..42accdf66891 --- /dev/null +++ b/core/tests/webkit/AndroidManifest.xml @@ -0,0 +1,30 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2017 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + package="com.android.webkit.tests" + android:sharedUserId="android.uid.system"> + + <application> + <uses-library android:name="android.test.runner" /> + </application> + + <instrumentation + android:name="android.support.test.runner.AndroidJUnitRunner" + android:targetPackage="com.android.webkit.tests" + android:label="Frameworks WebView Loader Tests" /> + +</manifest> diff --git a/core/tests/webkit/AndroidTest.xml b/core/tests/webkit/AndroidTest.xml new file mode 100644 index 000000000000..78cfa462beeb --- /dev/null +++ b/core/tests/webkit/AndroidTest.xml @@ -0,0 +1,29 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2017 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<configuration description="Runs Frameworks WebView Loading Tests."> + <target_preparer class="com.android.tradefed.targetprep.TestAppInstallSetup"> + <option name="test-file-name" value="WebViewLoadingTests.apk" /> + <option name="test-file-name" value="WebViewLoadingOnDiskTestApk.apk" /> + <option name="test-file-name" value="WebViewLoadingFromApkTestApk.apk" /> + <option name="cleanup-apks" value="true" /> + <option name="alt-dir" value="out" /> + </target_preparer> + + <test class="com.android.tradefed.testtype.AndroidJUnitTest" > + <option name="package" value="com.android.webkit.tests" /> + <option name="runner" value="android.support.test.runner.AndroidJUnitRunner" /> + </test> +</configuration> diff --git a/core/tests/webkit/apk_with_native_libs/Android.mk b/core/tests/webkit/apk_with_native_libs/Android.mk new file mode 100644 index 000000000000..7c6c36e0a6a2 --- /dev/null +++ b/core/tests/webkit/apk_with_native_libs/Android.mk @@ -0,0 +1,66 @@ +# Copyright (C) 2017 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +LOCAL_PATH := $(call my-dir) +MY_PATH := $(LOCAL_PATH) + +# Set shared variables +MY_MODULE_TAGS := optional +MY_JNI_SHARED_LIBRARIES := libwebviewtest_jni +MY_MODULE_PATH := $(TARGET_OUT_DATA_APPS) +MY_SRC_FILES := $(call all-java-files-under, src) +MY_SDK_VERSION := system_current +MY_PROGUARD_ENABLED := disabled +MY_MULTILIB := both + +# Recurse down the file tree. +include $(call all-subdir-makefiles) + + + +# Builds an apk containing native libraries that will be unzipped on the device. +include $(CLEAR_VARS) + +LOCAL_PATH := $(MY_PATH) +LOCAL_PACKAGE_NAME := WebViewLoadingOnDiskTestApk +LOCAL_MANIFEST_FILE := ondisk/AndroidManifest.xml + +LOCAL_MODULE_TAGS := $(MY_MODULE_TAGS) +LOCAL_JNI_SHARED_LIBRARIES := $(MY_JNI_SHARED_LIBRARIES) +LOCAL_MODULE_PATH := $(MY_MODULE_PATH) +LOCAL_SRC_FILES := $(MY_SRC_FILES) +LOCAL_SDK_VERSION := $(MY_SDK_VERSION) +LOCAL_PROGUARD_ENABLED := $(MY_PROGUARD_ENABLED) +LOCAL_MULTILIB := $(MY_MULTILIB) + +include $(BUILD_PACKAGE) + + +# Builds an apk containing uncompressed native libraries that have to be +# accessed through the APK itself on the device. +include $(CLEAR_VARS) + +LOCAL_PATH := $(MY_PATH) +LOCAL_PACKAGE_NAME := WebViewLoadingFromApkTestApk +LOCAL_MANIFEST_FILE := inapk/AndroidManifest.xml + +LOCAL_MODULE_TAGS := $(MY_MODULE_TAGS) +LOCAL_JNI_SHARED_LIBRARIES := $(MY_JNI_SHARED_LIBRARIES) +LOCAL_MODULE_PATH := $(MY_MODULE_PATH) +LOCAL_SRC_FILES := $(MY_SRC_FILES) +LOCAL_SDK_VERSION := $(MY_SDK_VERSION) +LOCAL_PROGUARD_ENABLED := $(MY_PROGUARD_ENABLED) +LOCAL_MULTILIB := $(MY_MULTILIB) + +include $(BUILD_PACKAGE) diff --git a/core/tests/webkit/apk_with_native_libs/inapk/AndroidManifest.xml b/core/tests/webkit/apk_with_native_libs/inapk/AndroidManifest.xml new file mode 100644 index 000000000000..868b2388d135 --- /dev/null +++ b/core/tests/webkit/apk_with_native_libs/inapk/AndroidManifest.xml @@ -0,0 +1,29 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + --> + +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + package="com.android.webviewloading_test_from_apk" + android:versionCode="1" + android:versionName="0.0.0.1"> + + <application android:label="WebView Loading Test APK" + android:multiArch="true" + android:extractNativeLibs="false"> + <meta-data android:name="com.android.webview.WebViewLibrary" + android:value="libwebviewtest_jni.so" /> + </application> +</manifest> diff --git a/core/tests/webkit/apk_with_native_libs/jni/Android.mk b/core/tests/webkit/apk_with_native_libs/jni/Android.mk new file mode 100644 index 000000000000..fd5b5eb50c5f --- /dev/null +++ b/core/tests/webkit/apk_with_native_libs/jni/Android.mk @@ -0,0 +1,32 @@ +# +# Copyright (C) 2017 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +LOCAL_PATH:= $(call my-dir) +include $(CLEAR_VARS) + +LOCAL_MODULE := libwebviewtest_jni + +LOCAL_MODULE_TAGS := optional + +LOCAL_SRC_FILES := WebViewTestJniOnLoad.cpp + +LOCAL_C_INCLUDES := $(JNI_H_INCLUDE) + +LOCAL_SDK_VERSION := current + +LOCAL_MULTILIB := both + +include $(BUILD_SHARED_LIBRARY) diff --git a/core/tests/webkit/apk_with_native_libs/jni/WebViewTestJniOnLoad.cpp b/core/tests/webkit/apk_with_native_libs/jni/WebViewTestJniOnLoad.cpp new file mode 100644 index 000000000000..9b0502fc286d --- /dev/null +++ b/core/tests/webkit/apk_with_native_libs/jni/WebViewTestJniOnLoad.cpp @@ -0,0 +1,21 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <jni.h> + +jint JNI_OnLoad(JavaVM *vm, void *reserved) { + return JNI_VERSION_1_4; +} diff --git a/core/tests/webkit/apk_with_native_libs/ondisk/AndroidManifest.xml b/core/tests/webkit/apk_with_native_libs/ondisk/AndroidManifest.xml new file mode 100644 index 000000000000..ffffeb8e1630 --- /dev/null +++ b/core/tests/webkit/apk_with_native_libs/ondisk/AndroidManifest.xml @@ -0,0 +1,28 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + --> + +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + package="com.android.webviewloading_test_on_disk" + android:versionCode="1" + android:versionName="0.0.0.1"> + + <application android:label="WebView Loading Test APK" + android:multiArch="true"> + <meta-data android:name="com.android.webview.WebViewLibrary" + android:value="libwebviewtest_jni.so" /> + </application> +</manifest> diff --git a/core/tests/webkit/apk_with_native_libs/src/com/google/android/xts/webview_list/WebViewLoadingTestClass.java b/core/tests/webkit/apk_with_native_libs/src/com/google/android/xts/webview_list/WebViewLoadingTestClass.java new file mode 100644 index 000000000000..0efa4b4ac694 --- /dev/null +++ b/core/tests/webkit/apk_with_native_libs/src/com/google/android/xts/webview_list/WebViewLoadingTestClass.java @@ -0,0 +1,24 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +package com.android.webview.chromium; + +/** + * An empty class for testing purposes. + */ +public class WebViewLoadingTestClass { +} diff --git a/core/tests/webkit/unit_tests_src/com/android/webkit/WebViewLibraryLoaderTest.java b/core/tests/webkit/unit_tests_src/com/android/webkit/WebViewLibraryLoaderTest.java new file mode 100644 index 000000000000..e2f2d37a4d68 --- /dev/null +++ b/core/tests/webkit/unit_tests_src/com/android/webkit/WebViewLibraryLoaderTest.java @@ -0,0 +1,329 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.webkit; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +import android.content.pm.ApplicationInfo; +import android.content.pm.PackageInfo; +import android.content.pm.PackageManager; +import android.os.Build; +import android.os.Bundle; +import android.util.Log; + +import android.support.test.filters.MediumTest; +import android.support.test.filters.SmallTest; +import android.support.test.runner.AndroidJUnit4; +import android.support.test.InstrumentationRegistry; + +import java.io.File; +import java.io.IOException; +import java.util.zip.ZipEntry; +import java.util.zip.ZipFile; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; + +/** + * Unit tests for {@link WebViewLibraryLoader}. + * Use the following command to run these tests: + * make WebViewLoadingTests \ + * && adb install -r -d \ + * ${ANDROID_PRODUCT_OUT}/data/app/WebViewLoadingTests/WebViewLoadingTests.apk \ + * && adb shell am instrument -e class 'android.webkit.WebViewLibraryLoaderTest' -w \ + * 'com.android.webkit.tests/android.support.test.runner.AndroidJUnitRunner' + */ +@RunWith(AndroidJUnit4.class) +public final class WebViewLibraryLoaderTest { + private static final String WEBVIEW_LIBS_ON_DISK_TEST_APK = + "com.android.webviewloading_test_on_disk"; + private static final String WEBVIEW_LIBS_IN_APK_TEST_APK = + "com.android.webviewloading_test_from_apk"; + private static final String WEBVIEW_LOADING_TEST_NATIVE_LIB = "libwebviewtest_jni.so"; + + private PackageInfo webviewOnDiskPackageInfo; + private PackageInfo webviewFromApkPackageInfo; + + @Before public void setUp() throws PackageManager.NameNotFoundException { + PackageManager pm = InstrumentationRegistry.getContext().getPackageManager(); + webviewOnDiskPackageInfo = + pm.getPackageInfo(WEBVIEW_LIBS_ON_DISK_TEST_APK, PackageManager.GET_META_DATA); + webviewFromApkPackageInfo = + pm.getPackageInfo(WEBVIEW_LIBS_IN_APK_TEST_APK, PackageManager.GET_META_DATA); + } + + private static boolean is64BitDevice() { + return Build.SUPPORTED_64_BIT_ABIS.length > 0; + } + + // We test the getWebViewNativeLibraryDirectory method here because it handled several different + // cases/combinations and it seems unnecessary to create one test-apk for each such combination + // and arch. + + /** + * Ensure we fetch the correct native library directories in the multi-arch case where + * the primary ABI is 64-bit. + */ + @SmallTest + @Test public void testGetWebViewLibDirMultiArchPrimary64bit() { + final String nativeLib = "nativeLib"; + final String secondaryNativeLib = "secondaryNativeLib"; + PackageInfo packageInfo = new PackageInfo(); + ApplicationInfo ai = new ApplicationInfoBuilder(). + // See VMRuntime.ABI_TO_INSTRUCTION_SET_MAP + setPrimaryCpuAbi("arm64-v8a"). + setNativeLibraryDir(nativeLib). + setSecondaryCpuAbi("armeabi"). + setSecondaryNativeLibraryDir(secondaryNativeLib). + create(); + packageInfo.applicationInfo = ai; + String actual32Lib = + WebViewLibraryLoader.getWebViewNativeLibraryDirectory(ai, false /* is64bit */); + String actual64Lib = + WebViewLibraryLoader.getWebViewNativeLibraryDirectory(ai, true /* is64bit */); + assertEquals(nativeLib, actual64Lib); + assertEquals(secondaryNativeLib, actual32Lib); + } + + /** + * Ensure we fetch the correct native library directory in the 64-bit single-arch case. + */ + @SmallTest + @Test public void testGetWebViewLibDirSingleArch64bit() { + final String nativeLib = "nativeLib"; + PackageInfo packageInfo = new PackageInfo(); + ApplicationInfo ai = new ApplicationInfoBuilder(). + // See VMRuntime.ABI_TO_INSTRUCTION_SET_MAP + setPrimaryCpuAbi("arm64-v8a"). + setNativeLibraryDir(nativeLib). + create(); + packageInfo.applicationInfo = ai; + String actual64Lib = + WebViewLibraryLoader.getWebViewNativeLibraryDirectory(ai, true /* is64bit */); + assertEquals(nativeLib, actual64Lib); + } + + /** + * Ensure we fetch the correct native library directory in the 32-bit single-arch case. + */ + @SmallTest + @Test public void testGetWebViewLibDirSingleArch32bit() { + final String nativeLib = "nativeLib"; + PackageInfo packageInfo = new PackageInfo(); + ApplicationInfo ai = new ApplicationInfoBuilder(). + // See VMRuntime.ABI_TO_INSTRUCTION_SET_MAP + setPrimaryCpuAbi("armeabi-v7a"). + setNativeLibraryDir(nativeLib). + create(); + packageInfo.applicationInfo = ai; + String actual32Lib = + WebViewLibraryLoader.getWebViewNativeLibraryDirectory(ai, false /* is64bit */); + assertEquals(nativeLib, actual32Lib); + } + + /** + * Ensure we fetch the correct 32-bit library path from an APK with 32-bit and 64-bit + * libraries unzipped onto disk. + */ + @MediumTest + @Test public void testGetWebViewLibraryPathOnDisk32Bit() + throws WebViewFactory.MissingWebViewPackageException { + WebViewLibraryLoader.WebViewNativeLibrary actualNativeLib = + WebViewLibraryLoader.getWebViewNativeLibrary( + webviewOnDiskPackageInfo, false /* is64bit */); + String expectedLibaryDirectory = is64BitDevice() ? + webviewOnDiskPackageInfo.applicationInfo.secondaryNativeLibraryDir : + webviewOnDiskPackageInfo.applicationInfo.nativeLibraryDir; + String lib32Path = expectedLibaryDirectory + "/" + WEBVIEW_LOADING_TEST_NATIVE_LIB; + assertEquals("Fetched incorrect 32-bit path from WebView library.", + lib32Path, actualNativeLib.path); + } + + /** + * Ensure we fetch the correct 64-bit library path from an APK with 32-bit and 64-bit + * libraries unzipped onto disk. + */ + @MediumTest + @Test public void testGetWebViewLibraryPathOnDisk64Bit() + throws WebViewFactory.MissingWebViewPackageException { + // A 32-bit device will not unpack 64-bit libraries. + if (!is64BitDevice()) return; + + WebViewLibraryLoader.WebViewNativeLibrary actualNativeLib = + WebViewLibraryLoader.getWebViewNativeLibrary( + webviewOnDiskPackageInfo, true /* is64bit */); + String lib64Path = webviewOnDiskPackageInfo.applicationInfo.nativeLibraryDir + + "/" + WEBVIEW_LOADING_TEST_NATIVE_LIB; + assertEquals("Fetched incorrect 64-bit path from WebView library.", + lib64Path, actualNativeLib.path); + } + + /** + * Check the size of the 32-bit library fetched from an APK with both 32-bit and 64-bit + * libraries unzipped onto disk. + */ + @MediumTest + @Test public void testGetWebView32BitLibrarySizeOnDiskIsNonZero() + throws WebViewFactory.MissingWebViewPackageException { + WebViewLibraryLoader.WebViewNativeLibrary actual32BitNativeLib = + WebViewLibraryLoader.getWebViewNativeLibrary( + webviewOnDiskPackageInfo, false /* is64bit */); + assertTrue(actual32BitNativeLib.size > 0); + } + + /** + * Check the size of the 64-bit library fetched from an APK with both 32-bit and 64-bit + * libraries unzipped onto disk. + */ + @MediumTest + @Test public void testGetWebView64BitLibrarySizeOnDiskIsNonZero() + throws WebViewFactory.MissingWebViewPackageException { + // A 32-bit device will not unpack 64-bit libraries. + if (!is64BitDevice()) return; + WebViewLibraryLoader.WebViewNativeLibrary actual64BitNativeLib = + WebViewLibraryLoader.getWebViewNativeLibrary( + webviewOnDiskPackageInfo, true /* is64bit */); + assertTrue(actual64BitNativeLib.size > 0); + } + + /** + * Ensure we fetch the correct 32-bit library path from an APK with both 32-bit and 64-bit + * libraries stored uncompressed in the APK. + */ + @MediumTest + @Test public void testGetWebView32BitLibraryPathFromApk() + throws WebViewFactory.MissingWebViewPackageException, IOException { + WebViewLibraryLoader.WebViewNativeLibrary actualNativeLib = + WebViewLibraryLoader.getWebViewNativeLibrary( + webviewFromApkPackageInfo, false /* is64bit */); + // The device might have ignored the app's request to not extract native libs, so first + // check whether the library paths match those of extracted libraries. + String expectedLibaryDirectory = is64BitDevice() ? + webviewFromApkPackageInfo.applicationInfo.secondaryNativeLibraryDir : + webviewFromApkPackageInfo.applicationInfo.nativeLibraryDir; + String lib32Path = expectedLibaryDirectory + "/" + WEBVIEW_LOADING_TEST_NATIVE_LIB; + if (lib32Path.equals(actualNativeLib.path)) { + // If the libraries were extracted to disk, ensure that they're actually there. + assertTrue("The given WebView library doesn't exist.", + new File(actualNativeLib.path).exists()); + } else { // The libraries were not extracted to disk. + assertIsValidZipEntryPath(actualNativeLib.path, + webviewFromApkPackageInfo.applicationInfo.sourceDir); + } + } + + /** + * Ensure we fetch the correct 32-bit library path from an APK with both 32-bit and 64-bit + * libraries stored uncompressed in the APK. + */ + @MediumTest + @Test public void testGetWebView64BitLibraryPathFromApk() + throws WebViewFactory.MissingWebViewPackageException, IOException { + // A 32-bit device will not unpack 64-bit libraries. + if (!is64BitDevice()) return; + + WebViewLibraryLoader.WebViewNativeLibrary actualNativeLib = + WebViewLibraryLoader.getWebViewNativeLibrary( + webviewFromApkPackageInfo, true /* is64bit */); + assertIsValidZipEntryPath(actualNativeLib.path, + webviewFromApkPackageInfo.applicationInfo.sourceDir); + } + + private static void assertIsValidZipEntryPath(String path, String zipFilePath) + throws IOException { + assertTrue("The path to a zip entry must start with the path to the zip file itself." + + "Expected zip path: " + zipFilePath + ", actual zip entry: " + path, + path.startsWith(zipFilePath + "!/")); + String[] pathSplit = path.split("!/"); + assertEquals("A zip file path should have two parts, the zip path, and the zip entry path.", + 2, pathSplit.length); + ZipFile zipFile = new ZipFile(pathSplit[0]); + assertNotNull("Path doesn't point to a valid zip entry: " + path, + zipFile.getEntry(pathSplit[1])); + } + + + /** + * Check the size of the 32-bit library fetched from an APK with both 32-bit and 64-bit + * libraries stored uncompressed in the APK. + */ + @MediumTest + @Test public void testGetWebView32BitLibrarySizeFromApkIsNonZero() + throws WebViewFactory.MissingWebViewPackageException { + WebViewLibraryLoader.WebViewNativeLibrary actual32BitNativeLib = + WebViewLibraryLoader.getWebViewNativeLibrary( + webviewFromApkPackageInfo, false /* is64bit */); + assertTrue(actual32BitNativeLib.size > 0); + } + + /** + * Check the size of the 64-bit library fetched from an APK with both 32-bit and 64-bit + * libraries stored uncompressed in the APK. + */ + @MediumTest + @Test public void testGetWebView64BitLibrarySizeFromApkIsNonZero() + throws WebViewFactory.MissingWebViewPackageException { + // A 32-bit device will not unpack 64-bit libraries. + if (!is64BitDevice()) return; + + WebViewLibraryLoader.WebViewNativeLibrary actual64BitNativeLib = + WebViewLibraryLoader.getWebViewNativeLibrary( + webviewFromApkPackageInfo, true /* is64bit */); + assertTrue(actual64BitNativeLib.size > 0); + } + + private static class ApplicationInfoBuilder { + ApplicationInfo ai; + + public ApplicationInfoBuilder setPrimaryCpuAbi(String primaryCpuAbi) { + ai.primaryCpuAbi = primaryCpuAbi; + return this; + } + + public ApplicationInfoBuilder setSecondaryCpuAbi(String secondaryCpuAbi) { + ai.secondaryCpuAbi = secondaryCpuAbi; + return this; + } + + public ApplicationInfoBuilder setNativeLibraryDir(String nativeLibraryDir) { + ai.nativeLibraryDir = nativeLibraryDir; + return this; + } + + public ApplicationInfoBuilder setSecondaryNativeLibraryDir( + String secondaryNativeLibraryDir) { + ai.secondaryNativeLibraryDir = secondaryNativeLibraryDir; + return this; + } + + public ApplicationInfoBuilder setMetaData(Bundle metaData) { + ai.metaData = metaData; + return this; + } + + public ApplicationInfoBuilder() { + ai = new android.content.pm.ApplicationInfo(); + } + + public ApplicationInfo create() { + return ai; + } + } +} diff --git a/libs/hwui/hwui/Canvas.cpp b/libs/hwui/hwui/Canvas.cpp index a087035fd8e5..6f0579950e10 100644 --- a/libs/hwui/hwui/Canvas.cpp +++ b/libs/hwui/hwui/Canvas.cpp @@ -158,7 +158,8 @@ private: }; void Canvas::drawText(const uint16_t* text, int start, int count, int contextCount, - float x, float y, int bidiFlags, const Paint& origPaint, const Typeface* typeface) { + float x, float y, minikin::Bidi bidiFlags, const Paint& origPaint, + const Typeface* typeface) { // minikin may modify the original paint Paint paint(origPaint); @@ -206,8 +207,9 @@ private: const SkPath& path; }; -void Canvas::drawTextOnPath(const uint16_t* text, int count, int bidiFlags, const SkPath& path, - float hOffset, float vOffset, const Paint& paint, const Typeface* typeface) { +void Canvas::drawTextOnPath(const uint16_t* text, int count, minikin::Bidi bidiFlags, + const SkPath& path, float hOffset, float vOffset, const Paint& paint, + const Typeface* typeface) { Paint paintCopy(paint); minikin::Layout layout = MinikinUtils::doLayout( &paintCopy, bidiFlags, typeface, text, 0, count, count); diff --git a/libs/hwui/hwui/Canvas.h b/libs/hwui/hwui/Canvas.h index fbd89606fc9d..0a1bae7c99d9 100644 --- a/libs/hwui/hwui/Canvas.h +++ b/libs/hwui/hwui/Canvas.h @@ -33,6 +33,7 @@ class SkVertices; namespace minikin { class Layout; + enum class Bidi : uint8_t; } namespace android { @@ -255,10 +256,12 @@ public: * and delegating the final draw to virtual drawGlyphs method. */ void drawText(const uint16_t* text, int start, int count, int contextCount, - float x, float y, int bidiFlags, const Paint& origPaint, const Typeface* typeface); + float x, float y, minikin::Bidi bidiFlags, const Paint& origPaint, + const Typeface* typeface); - void drawTextOnPath(const uint16_t* text, int count, int bidiFlags, const SkPath& path, - float hOffset, float vOffset, const Paint& paint, const Typeface* typeface); + void drawTextOnPath(const uint16_t* text, int count, minikin::Bidi bidiFlags, + const SkPath& path, float hOffset, float vOffset, const Paint& paint, + const Typeface* typeface); protected: void drawTextDecorations(float x, float y, float length, const SkPaint& paint); diff --git a/libs/hwui/hwui/MinikinUtils.cpp b/libs/hwui/hwui/MinikinUtils.cpp index 7da7f3876a3d..814d2cf84b49 100644 --- a/libs/hwui/hwui/MinikinUtils.cpp +++ b/libs/hwui/hwui/MinikinUtils.cpp @@ -51,9 +51,8 @@ minikin::FontStyle MinikinUtils::prepareMinikinPaint(minikin::MinikinPaint* mini return minikinStyle; } -minikin::Layout MinikinUtils::doLayout(const Paint* paint, int bidiFlags, - const Typeface* typeface, const uint16_t* buf, size_t start, size_t count, - size_t bufSize) { +minikin::Layout MinikinUtils::doLayout(const Paint* paint, minikin::Bidi bidiFlags, + const Typeface* typeface, const uint16_t* buf, size_t start, size_t count, size_t bufSize) { minikin::MinikinPaint minikinPaint; minikin::FontStyle minikinStyle = prepareMinikinPaint(&minikinPaint, paint, typeface); minikin::Layout layout; @@ -62,8 +61,9 @@ minikin::Layout MinikinUtils::doLayout(const Paint* paint, int bidiFlags, return layout; } -float MinikinUtils::measureText(const Paint* paint, int bidiFlags, const Typeface* typeface, - const uint16_t* buf, size_t start, size_t count, size_t bufSize, float *advances) { +float MinikinUtils::measureText(const Paint* paint, minikin::Bidi bidiFlags, + const Typeface* typeface, const uint16_t* buf, size_t start, size_t count, size_t bufSize, + float *advances) { minikin::MinikinPaint minikinPaint; minikin::FontStyle minikinStyle = prepareMinikinPaint(&minikinPaint, paint, typeface); const Typeface* resolvedTypeface = Typeface::resolveDefault(typeface); diff --git a/libs/hwui/hwui/MinikinUtils.h b/libs/hwui/hwui/MinikinUtils.h index bfd816fd3b58..2e8aa58682a2 100644 --- a/libs/hwui/hwui/MinikinUtils.h +++ b/libs/hwui/hwui/MinikinUtils.h @@ -37,11 +37,11 @@ public: ANDROID_API static minikin::FontStyle prepareMinikinPaint(minikin::MinikinPaint* minikinPaint, const Paint* paint, const Typeface* typeface); - ANDROID_API static minikin::Layout doLayout(const Paint* paint, int bidiFlags, + ANDROID_API static minikin::Layout doLayout(const Paint* paint, minikin::Bidi bidiFlags, const Typeface* typeface, const uint16_t* buf, size_t start, size_t count, size_t bufSize); - ANDROID_API static float measureText(const Paint* paint, int bidiFlags, + ANDROID_API static float measureText(const Paint* paint, minikin::Bidi bidiFlags, const Typeface* typeface, const uint16_t* buf, size_t start, size_t count, size_t bufSize, float *advances); diff --git a/libs/hwui/tests/common/TestUtils.cpp b/libs/hwui/tests/common/TestUtils.cpp index 64ec58d0adab..e6137763cbe7 100644 --- a/libs/hwui/tests/common/TestUtils.cpp +++ b/libs/hwui/tests/common/TestUtils.cpp @@ -19,6 +19,7 @@ #include "hwui/Paint.h" #include "DeferredLayerUpdater.h" +#include <minikin/Layout.h> #include <renderthread/EglManager.h> #include <renderthread/OpenGLPipeline.h> #include <pipeline/skia/SkiaOpenGLPipeline.h> @@ -121,13 +122,15 @@ void TestUtils::layoutTextUnscaled(const SkPaint& paint, const char* text, void TestUtils::drawUtf8ToCanvas(Canvas* canvas, const char* text, const SkPaint& paint, float x, float y) { auto utf16 = asciiToUtf16(text); - canvas->drawText(utf16.get(), 0, strlen(text), strlen(text), x, y, 0, paint, nullptr); + canvas->drawText(utf16.get(), 0, strlen(text), strlen(text), x, y, minikin::Bidi::LTR, paint, + nullptr); } void TestUtils::drawUtf8ToCanvas(Canvas* canvas, const char* text, const SkPaint& paint, const SkPath& path) { auto utf16 = asciiToUtf16(text); - canvas->drawTextOnPath(utf16.get(), strlen(text), 0, path, 0, 0, paint, nullptr); + canvas->drawTextOnPath(utf16.get(), strlen(text), minikin::Bidi::LTR, path, 0, 0, paint, + nullptr); } void TestUtils::TestTask::run() { diff --git a/libs/hwui/tests/common/scenes/GlyphStressAnimation.cpp b/libs/hwui/tests/common/scenes/GlyphStressAnimation.cpp index 5b685bb2f3f7..21d8d75fbf18 100644 --- a/libs/hwui/tests/common/scenes/GlyphStressAnimation.cpp +++ b/libs/hwui/tests/common/scenes/GlyphStressAnimation.cpp @@ -57,7 +57,7 @@ public: for (int i = 0; i < 5; i++) { paint.setTextSize(10 + (frameNr % 20) + i * 20); canvas->drawText(text.get(), 0, textLength, textLength, - 0, 100 * (i + 2), minikin::kBidi_Force_LTR, paint, nullptr); + 0, 100 * (i + 2), minikin::Bidi::FORCE_LTR, paint, nullptr); } container->setStagingDisplayList(canvas->finishRecording()); diff --git a/libs/hwui/tests/common/scenes/SaveLayer2Animation.cpp b/libs/hwui/tests/common/scenes/SaveLayer2Animation.cpp index ad0b1f15abff..d678af9bd3e4 100644 --- a/libs/hwui/tests/common/scenes/SaveLayer2Animation.cpp +++ b/libs/hwui/tests/common/scenes/SaveLayer2Animation.cpp @@ -55,7 +55,7 @@ public: std::string offscreen = "offscreen line " + stri; std::unique_ptr<uint16_t[]> offtext = TestUtils::asciiToUtf16(offscreen.c_str()); canvas.drawText(offtext.get(), 0, offscreen.length(), offscreen.length(), - bounds.fLeft, top + padding, minikin::kBidi_Force_LTR, mBluePaint, nullptr); + bounds.fLeft, top + padding, minikin::Bidi::FORCE_LTR, mBluePaint, nullptr); canvas.restore(); canvas.drawRect(bounds.fLeft, top + padding, bounds.fRight, @@ -63,7 +63,7 @@ public: std::string onscreen = "onscreen line " + stri; std::unique_ptr<uint16_t[]> ontext = TestUtils::asciiToUtf16(onscreen.c_str()); canvas.drawText(ontext.get(), 0, onscreen.length(), onscreen.length(), bounds.fLeft, - top + smallRectHeight - padding, minikin::kBidi_Force_LTR, mGreenPaint, + top + smallRectHeight - padding, minikin::Bidi::FORCE_LTR, mGreenPaint, nullptr); } } diff --git a/libs/hwui/tests/unit/RecordingCanvasTests.cpp b/libs/hwui/tests/unit/RecordingCanvasTests.cpp index c4e419591a4d..dab1f894b681 100644 --- a/libs/hwui/tests/unit/RecordingCanvasTests.cpp +++ b/libs/hwui/tests/unit/RecordingCanvasTests.cpp @@ -806,7 +806,7 @@ OPENGL_PIPELINE_TEST(RecordingCanvas, drawText) { paint.setTextSize(20); paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding); std::unique_ptr<uint16_t[]> dst = TestUtils::asciiToUtf16("HELLO"); - canvas.drawText(dst.get(), 0, 5, 5, 25, 25, minikin::kBidi_Force_LTR, paint, NULL); + canvas.drawText(dst.get(), 0, 5, 5, 25, 25, minikin::Bidi::FORCE_LTR, paint, NULL); }); int count = 0; @@ -830,7 +830,7 @@ OPENGL_PIPELINE_TEST(RecordingCanvas, drawTextInHighContrast) { paint.setTextSize(20); paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding); std::unique_ptr<uint16_t[]> dst = TestUtils::asciiToUtf16("HELLO"); - canvas.drawText(dst.get(), 0, 5, 5, 25, 25, minikin::kBidi_Force_LTR, paint, NULL); + canvas.drawText(dst.get(), 0, 5, 5, 25, 25, minikin::Bidi::FORCE_LTR, paint, NULL); }); Properties::enableHighContrastText = false; diff --git a/packages/BackupRestoreConfirmation/res/values-hy/strings.xml b/packages/BackupRestoreConfirmation/res/values-hy/strings.xml index 285c15d49a05..ca9834e30f08 100644 --- a/packages/BackupRestoreConfirmation/res/values-hy/strings.xml +++ b/packages/BackupRestoreConfirmation/res/values-hy/strings.xml @@ -32,7 +32,7 @@ <string name="backup_enc_password_required" msgid="7889652203371654149">"Քանի որ ձեր սարքը գաղտնագրված է, դուք պետք է գաղտնագրեք նաև ձեր պահուստը: Խնդրում ենք ստորև սահմանել գաղտնաբառը՝"</string> <string name="restore_enc_password_text" msgid="6140898525580710823">"Եթե վերականգնվող տվյալները գաղտնագրված են, խնդրում ենք մուտքագրել գաղտնաբառը ստորև`"</string> <string name="toast_backup_started" msgid="550354281452756121">"Պահուստավորումը սկսվում է..."</string> - <string name="toast_backup_ended" msgid="3818080769548726424">"Պահուստավորումն ավարտվեց"</string> + <string name="toast_backup_ended" msgid="3818080769548726424">"Պահուստավորումն ավարտված է"</string> <string name="toast_restore_started" msgid="7881679218971277385">"Վերականգնումը մեկնարկեց..."</string> <string name="toast_restore_ended" msgid="1764041639199696132">"Վերականգնումն ավարտվեց"</string> <string name="toast_timeout" msgid="5276598587087626877">"Գործողության ժամանակը սպառվեց"</string> diff --git a/packages/SettingsLib/res/values-af/strings.xml b/packages/SettingsLib/res/values-af/strings.xml index a7a7ea9ac842..145060bfb30c 100644 --- a/packages/SettingsLib/res/values-af/strings.xml +++ b/packages/SettingsLib/res/values-af/strings.xml @@ -209,6 +209,8 @@ <string name="bluetooth_select_a2dp_codec_ldac_playback_quality" msgid="3619694372407843405">"Bluetooth-oudio-LDAC-kodek: Speelgehalte"</string> <string name="bluetooth_select_a2dp_codec_ldac_playback_quality_dialog_title" msgid="3181967377574368400">"Kies Bluetooth-oudio-LDAC-kodek:\nSpeelgehalte"</string> <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"Stroming: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string> + <string name="dns_tls" msgid="6773814174391131955">"DNS oor TLS"</string> + <string name="dns_tls_summary" msgid="3692494150251071380">"Indien dit geaktiveer is, probeer DNS oor TLS op poort 853."</string> <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Wys opsies vir draadlose skermsertifisering"</string> <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Verhoog Wi-Fi-aantekeningvlak, wys per SSID RSSI in Wi‑Fi-kieser"</string> <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"Wanneer dit geaktiveer is, sal Wi-Fi die dataverbinding aggressiewer na mobiel oordra wanneer die Wi-Fi-sein swak is"</string> diff --git a/packages/SettingsLib/res/values-am/strings.xml b/packages/SettingsLib/res/values-am/strings.xml index bff8fe205aeb..0abf21b828f8 100644 --- a/packages/SettingsLib/res/values-am/strings.xml +++ b/packages/SettingsLib/res/values-am/strings.xml @@ -209,6 +209,8 @@ <string name="bluetooth_select_a2dp_codec_ldac_playback_quality" msgid="3619694372407843405">"የብሉቱዝ ኦዲዮ LDAC ኮዴክ ይምረጡ፦ የመልሶ ማጫወት ጥራት"</string> <string name="bluetooth_select_a2dp_codec_ldac_playback_quality_dialog_title" msgid="3181967377574368400">"የብሉቱዝ ኦዲዮ LDAC ኮዴክ ይምረጡ፦\nየመልሶ ማጫወት ጥራት"</string> <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"ዥረት፦ <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string> + <string name="dns_tls" msgid="6773814174391131955">"DNS በTLS ላይ"</string> + <string name="dns_tls_summary" msgid="3692494150251071380">"ከነቃ በወደብ 853 ላይ DNS በTLS ላይ ይሞክሩት።"</string> <string name="wifi_display_certification_summary" msgid="1155182309166746973">"የገመድ አልባ ማሳያ እውቅና ማረጋገጫ አማራጮችን አሳይ"</string> <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"የWi‑Fi ምዝግብ ማስታወሻ አያያዝ ደረጃ ጨምር፣ በWi‑Fi መምረጫ ውስጥ በአንድ SSID RSSI አሳይ"</string> <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"ሲነቃ የWi‑Fi ምልክት ዝቅተኛ ሲሆን Wi‑Fi የውሂብ ግንኙነት ለሞባይል ማስረከብ ላይ ይበልጥ አስገዳጅ ይሆናል"</string> diff --git a/packages/SettingsLib/res/values-ar/strings.xml b/packages/SettingsLib/res/values-ar/strings.xml index 457a6dd484ac..2dc8dc9bf22d 100644 --- a/packages/SettingsLib/res/values-ar/strings.xml +++ b/packages/SettingsLib/res/values-ar/strings.xml @@ -209,6 +209,8 @@ <string name="bluetooth_select_a2dp_codec_ldac_playback_quality" msgid="3619694372407843405">"برنامج ترميز LDAC لصوت البلوتوث: جودة التشغيل"</string> <string name="bluetooth_select_a2dp_codec_ldac_playback_quality_dialog_title" msgid="3181967377574368400">"اختيار برنامج ترميز LDAC لصوت البلوتوث:\nجودة التشغيل"</string> <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"البث: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string> + <string name="dns_tls" msgid="6773814174391131955">"نظام أسماء النطاقات عبر طبقة النقل الآمنة"</string> + <string name="dns_tls_summary" msgid="3692494150251071380">"عند تمكينه، يمكن استخدام نظام أسماء النطاقات عبر طبقة النقل الآمنة على المنفذ 853."</string> <string name="wifi_display_certification_summary" msgid="1155182309166746973">"عرض خيارات شهادة عرض شاشة لاسلكي"</string> <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"زيادة مستوى تسجيل Wi-Fi، وعرض لكل SSID RSSI في منتقي Wi-Fi"</string> <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"عند تمكينه، سيكون Wi-Fi أكثر حدة في تسليم اتصال البيانات إلى الجوّال، وذلك عندما تكون إشارة WiFi منخفضة"</string> diff --git a/packages/SettingsLib/res/values-az/strings.xml b/packages/SettingsLib/res/values-az/strings.xml index 8b453ab09863..0ae902519b12 100644 --- a/packages/SettingsLib/res/values-az/strings.xml +++ b/packages/SettingsLib/res/values-az/strings.xml @@ -209,6 +209,8 @@ <string name="bluetooth_select_a2dp_codec_ldac_playback_quality" msgid="3619694372407843405">"Bluetooth Audio LDAC Kodeki:Oxutma Keyfiyyəti"</string> <string name="bluetooth_select_a2dp_codec_ldac_playback_quality_dialog_title" msgid="3181967377574368400">"Bluetooth Audio LDAC Kodek:\nOxutma Keyfiyyəti Seçin"</string> <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"Canlı yayım: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string> + <string name="dns_tls" msgid="6773814174391131955">"TLS ilə DNS"</string> + <string name="dns_tls_summary" msgid="3692494150251071380">"Aktiv edilərsə, 853 nömrəli portda TLS ilə DNS-i sınayın."</string> <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Simsiz displey sertifikatlaşması üçün seçimləri göstərir"</string> <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Wi‑Fi giriş səviyyəsini qaldırın, Wi‑Fi seçəndə hər SSID RSSI üzrə göstərin"</string> <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"Aktiv edildikdə, Wi-Fi siqnalı zəif olan zaman, data bağlantısını mobilə ötürərəkən Wi-Fi daha aqressiv olacaq"</string> diff --git a/packages/SettingsLib/res/values-b+sr+Latn/strings.xml b/packages/SettingsLib/res/values-b+sr+Latn/strings.xml index ba0de57b804f..ef4e48eee064 100644 --- a/packages/SettingsLib/res/values-b+sr+Latn/strings.xml +++ b/packages/SettingsLib/res/values-b+sr+Latn/strings.xml @@ -209,6 +209,8 @@ <string name="bluetooth_select_a2dp_codec_ldac_playback_quality" msgid="3619694372407843405">"Bluetooth audio kodek LDAC: kvalitet reprodukcije"</string> <string name="bluetooth_select_a2dp_codec_ldac_playback_quality_dialog_title" msgid="3181967377574368400">"Izaberite Bluetooth audio kodek LDAC:\nkvalitet reprodukcije"</string> <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"Strimovanje: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string> + <string name="dns_tls" msgid="6773814174391131955">"DNS preko TLS-a"</string> + <string name="dns_tls_summary" msgid="3692494150251071380">"Ako je omogućeno, probajte DNS preko TLS-a na portu 853."</string> <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Prikaz opcija za sertifikaciju bežičnog ekrana"</string> <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Povećava nivo evidentiranja za Wi‑Fi. Prikaz po SSID RSSI-u u biraču Wi‑Fi mreže"</string> <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"Kad se omogući, Wi‑Fi će biti agresivniji pri prebacivanju mreže za prenos podataka na mobilnu ako je Wi‑Fi signal slab"</string> diff --git a/packages/SettingsLib/res/values-be/strings.xml b/packages/SettingsLib/res/values-be/strings.xml index 49a18b6ff531..e855f9b141ad 100644 --- a/packages/SettingsLib/res/values-be/strings.xml +++ b/packages/SettingsLib/res/values-be/strings.xml @@ -209,6 +209,8 @@ <string name="bluetooth_select_a2dp_codec_ldac_playback_quality" msgid="3619694372407843405">"Аўдыякодэк Bluetooth LDAC: якасць прайгравання"</string> <string name="bluetooth_select_a2dp_codec_ldac_playback_quality_dialog_title" msgid="3181967377574368400">"Выбраць аўдыякодэк Bluetooth LDAC:\nякасць прайгравання"</string> <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"Перадача плынню: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string> + <string name="dns_tls" msgid="6773814174391131955">"DNS праз TLS"</string> + <string name="dns_tls_summary" msgid="3692494150251071380">"Калі магчыма, паспрабаваць DNS праз TLS на порце 853."</string> <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Паказаць опцыі сертыфікацыі бесправаднога дысплея"</string> <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Падвыс. узровень дэтал-цыі журнала Wi‑Fi у залежн. ад SSID RSSI у Wi‑Fi Picker"</string> <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"Калі гэта функцыя ўключана, Wi-Fi будзе больш інтэнсіўна імкнуцца перайсці на падключ. маб. перад. даных пры слабым сігнале Wi‑Fi"</string> diff --git a/packages/SettingsLib/res/values-bg/strings.xml b/packages/SettingsLib/res/values-bg/strings.xml index 8fbef191edf1..d8b650af2dc6 100644 --- a/packages/SettingsLib/res/values-bg/strings.xml +++ b/packages/SettingsLib/res/values-bg/strings.xml @@ -209,6 +209,8 @@ <string name="bluetooth_select_a2dp_codec_ldac_playback_quality" msgid="3619694372407843405">"Кодек за звука през Bluetooth с технологията LDAC: Качество на възпроизвеждане"</string> <string name="bluetooth_select_a2dp_codec_ldac_playback_quality_dialog_title" msgid="3181967377574368400">"Изберете кодек за звука през Bluetooth с технологията LDAC:\nКачество на възпроизвеждане"</string> <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"Поточно предаване: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string> + <string name="dns_tls" msgid="6773814174391131955">"DNS през TLS"</string> + <string name="dns_tls_summary" msgid="3692494150251071380">"Ако опцията е активирана, изпробвайте DNS през TLS на порт 853."</string> <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Показване на опциите за сертифициране на безжичния дисплей"</string> <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"По-подробно регистр. на Wi‑Fi – данни за RSSI на SSID в инстр. за избор на Wi‑Fi"</string> <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"При активиране предаването на връзката за данни от Wi-Fi към мобилната мрежа ще е по-агресивно, когато сигналът за Wi-Fi е слаб"</string> diff --git a/packages/SettingsLib/res/values-bn/strings.xml b/packages/SettingsLib/res/values-bn/strings.xml index ec48835fc72e..24a90847cdbc 100644 --- a/packages/SettingsLib/res/values-bn/strings.xml +++ b/packages/SettingsLib/res/values-bn/strings.xml @@ -209,6 +209,8 @@ <string name="bluetooth_select_a2dp_codec_ldac_playback_quality" msgid="3619694372407843405">"ব্লুটুথ অডিও LDAC কোডেক: প্লেব্যাক গুণমান"</string> <string name="bluetooth_select_a2dp_codec_ldac_playback_quality_dialog_title" msgid="3181967377574368400">"ব্লুটুথ অডিও LDAC কোডেক বেছে নিন:\nপ্লেব্যাক গুণমান"</string> <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"স্ট্রিমিং: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string> + <string name="dns_tls" msgid="6773814174391131955">"TLS এ ডিএনএস"</string> + <string name="dns_tls_summary" msgid="3692494150251071380">"যদি সক্ষম করা থাকে তাহলে পোর্ট ৮৫৩ তে TLS এ ডিএনএস এর চেষ্টা করুন।"</string> <string name="wifi_display_certification_summary" msgid="1155182309166746973">"ওয়্যারলেস প্রদর্শন সার্টিফিকেশন জন্য বিকল্পগুলি দেখান"</string> <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"ওয়াই-ফাই লগিং স্তর বাড়ান, ওয়াই-ফাই চয়নকারীতে SSID RSSI অনুযায়ী দেখান"</string> <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"সক্ষম করা থাকলে, ওয়াই ফাই সিগন্যালের মান খারাপ হলে ডেটা সংযোগ মোবাইলের কাছে হস্তান্তর করার জন্য ওয়াই ফাই আরো বেশি তৎপর হবে।"</string> diff --git a/packages/SettingsLib/res/values-bs/strings.xml b/packages/SettingsLib/res/values-bs/strings.xml index a331286e8781..ca610f7e4ee2 100644 --- a/packages/SettingsLib/res/values-bs/strings.xml +++ b/packages/SettingsLib/res/values-bs/strings.xml @@ -209,6 +209,8 @@ <string name="bluetooth_select_a2dp_codec_ldac_playback_quality" msgid="3619694372407843405">"Bluetooth Audio LDAC kodek: Kvalitet reprodukcije"</string> <string name="bluetooth_select_a2dp_codec_ldac_playback_quality_dialog_title" msgid="3181967377574368400">"Odaberite Bluetooth Audio LDAC kodek:\nKvalitet reprodukcije"</string> <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"Prijenos: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string> + <string name="dns_tls" msgid="6773814174391131955">"DNS preko TLS-a"</string> + <string name="dns_tls_summary" msgid="3692494150251071380">"Ako je opcija omogućena, pokušaj DNS preko TLS-a na priključku 853."</string> <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Pokaži opcije za certifikaciju Bežičnog prikaza"</string> <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Povećajte nivo Wi-Fi zapisivanja, pokazati po SSID RSSI Wi-Fi Picker"</string> <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"Kada je omogućeno, Wi-Fi veza će u slučaju slabog signala agresivnije predavati vezu za prijenos podataka na mobilnu vezu"</string> diff --git a/packages/SettingsLib/res/values-ca/strings.xml b/packages/SettingsLib/res/values-ca/strings.xml index 145f61ca61a2..0ee111a97839 100644 --- a/packages/SettingsLib/res/values-ca/strings.xml +++ b/packages/SettingsLib/res/values-ca/strings.xml @@ -209,6 +209,8 @@ <string name="bluetooth_select_a2dp_codec_ldac_playback_quality" msgid="3619694372407843405">"Còdec LDAC d\'àudio per Bluetooth: qualitat de reproducció"</string> <string name="bluetooth_select_a2dp_codec_ldac_playback_quality_dialog_title" msgid="3181967377574368400">"Selecciona el còdec LDAC d\'àudio per Bluetooth:\nQualitat de reproducció"</string> <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"S\'està reproduint en temps real: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string> + <string name="dns_tls" msgid="6773814174391131955">"DNS per TLS"</string> + <string name="dns_tls_summary" msgid="3692494150251071380">"Si s\'ha activat, prova d\'utilitzar DNS per TLS al port 853."</string> <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Mostra les opcions de certificació de pantalla sense fil"</string> <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Augmenta nivell de registre Wi‑Fi i mostra\'l per SSID RSSI al Selector de Wi‑Fi"</string> <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"Quan s\'activa, la Wi-Fi és més agressiva en transferir la connexió de dades al mòbil quan el senyal de la Wi-Fi sigui dèbil"</string> @@ -234,8 +236,8 @@ <string name="verify_apps_over_usb_title" msgid="4177086489869041953">"Verifica aplicacions per USB"</string> <string name="verify_apps_over_usb_summary" msgid="9164096969924529200">"Comprova les aplicacions instal·lades mitjançant ADB/ADT per detectar possibles comportaments perillosos"</string> <string name="bluetooth_show_devices_without_names_summary" msgid="2351196058115755520">"Es mostraran els dispositius Bluetooth sense el nom (només l\'adreça MAC)"</string> - <string name="bluetooth_disable_absolute_volume_summary" msgid="6031284410786545957">"Desactiva la funció de volum absolut de Bluetooth en cas que es produeixin problemes de volum amb dispositius remots, com ara un volum massa alt o una manca de control."</string> - <string name="bluetooth_enable_inband_ringing_summary" msgid="2787866074741784975">"Permet que els sons de trucada del telèfon es reprodueixin en auriculars amb Bluetooth"</string> + <string name="bluetooth_disable_absolute_volume_summary" msgid="6031284410786545957">"Desactiva la funció de volum absolut del Bluetooth en cas que es produeixin problemes de volum amb dispositius remots, com ara un volum massa alt o una manca de control."</string> + <string name="bluetooth_enable_inband_ringing_summary" msgid="2787866074741784975">"Permet que els sons de trucada del telèfon es reprodueixin en auriculars Bluetooth"</string> <string name="enable_terminal_title" msgid="95572094356054120">"Terminal local"</string> <string name="enable_terminal_summary" msgid="67667852659359206">"Activa l\'aplicació de terminal que ofereix accés al shell local"</string> <string name="hdcp_checking_title" msgid="8605478913544273282">"Comprovació HDCP"</string> diff --git a/packages/SettingsLib/res/values-cs/strings.xml b/packages/SettingsLib/res/values-cs/strings.xml index 994afaefa934..60bbbf3c77f8 100644 --- a/packages/SettingsLib/res/values-cs/strings.xml +++ b/packages/SettingsLib/res/values-cs/strings.xml @@ -209,6 +209,8 @@ <string name="bluetooth_select_a2dp_codec_ldac_playback_quality" msgid="3619694372407843405">"Kodek Bluetooth Audio LDAC: Kvalita přehrávání"</string> <string name="bluetooth_select_a2dp_codec_ldac_playback_quality_dialog_title" msgid="3181967377574368400">"Vyberte kodek Bluetooth Audio LDAC:\nKvalita přehrávání"</string> <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"Streamování: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string> + <string name="dns_tls" msgid="6773814174391131955">"DNS přes TLS"</string> + <string name="dns_tls_summary" msgid="3692494150251071380">"Pokud tuto možnost aktivujete, zařízení se bude připojovat k serverům DNS pomocí protokolu TLS na portu 853."</string> <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Zobrazit možnosti certifikace bezdrátového displeje"</string> <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Zvýšit úroveň protokolování Wi‑Fi zobrazenou v SSID a RSSI při výběru sítě Wi‑Fi."</string> <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"Pokud je tato možnost zapnuta, bude síť Wi-Fi při předávání datového připojení mobilní síti při slabém signálu Wi-Fi agresivnější."</string> diff --git a/packages/SettingsLib/res/values-da/strings.xml b/packages/SettingsLib/res/values-da/strings.xml index e916853ae57d..089c43c2f857 100644 --- a/packages/SettingsLib/res/values-da/strings.xml +++ b/packages/SettingsLib/res/values-da/strings.xml @@ -209,6 +209,8 @@ <string name="bluetooth_select_a2dp_codec_ldac_playback_quality" msgid="3619694372407843405">"LDAC-codec for Bluetooth-lyd: Afspilningskvalitet"</string> <string name="bluetooth_select_a2dp_codec_ldac_playback_quality_dialog_title" msgid="3181967377574368400">"Vælg LDAC-codec for Bluetooth-lyd:\nAfspilningskvalitet"</string> <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"Streamer: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string> + <string name="dns_tls" msgid="6773814174391131955">"DNS via TLS"</string> + <string name="dns_tls_summary" msgid="3692494150251071380">"Prøv DNS via TLS (hvis muligheden er aktiveret) på port 853."</string> <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Vis valgmuligheder for certificering af trådløs skærm"</string> <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Øg mængden af Wi‑Fi-logføring. Vis opdelt efter SSID RSSI i Wi‑Fi-vælgeren"</string> <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"Når dette er aktiveret, gennemtvinges en overdragelse af dataforbindelsen fra Wi-Fi til mobilnetværk, når Wi-Fi-signalet er svagt"</string> diff --git a/packages/SettingsLib/res/values-de/strings.xml b/packages/SettingsLib/res/values-de/strings.xml index 1ec4fee36e7a..2635e6670095 100644 --- a/packages/SettingsLib/res/values-de/strings.xml +++ b/packages/SettingsLib/res/values-de/strings.xml @@ -209,6 +209,8 @@ <string name="bluetooth_select_a2dp_codec_ldac_playback_quality" msgid="3619694372407843405">"Bluetooth-Audio-LDAC-Codec: Wiedergabequalität"</string> <string name="bluetooth_select_a2dp_codec_ldac_playback_quality_dialog_title" msgid="3181967377574368400">"Bluetooth-Audio-LDAC-Codec auswählen:\nWiedergabequalität"</string> <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"Streaming: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string> + <string name="dns_tls" msgid="6773814174391131955">"DNS-over-TLS"</string> + <string name="dns_tls_summary" msgid="3692494150251071380">"Wenn diese Option aktiviert ist, versuche für Port 853 DNS-over-TLS anzuwenden."</string> <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Optionen zur Zertifizierung für kabellose Übertragung anzeigen"</string> <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Level für WLAN-Protokollierung erhöhen, in WiFi Picker pro SSID-RSSI anzeigen"</string> <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"Wenn diese Option aktiviert ist, ist das WLAN bei schwachem Signal bei der Übergabe der Datenverbindung an den Mobilfunk aggressiver"</string> diff --git a/packages/SettingsLib/res/values-el/strings.xml b/packages/SettingsLib/res/values-el/strings.xml index 2548a5d32fa1..b6b1bdeddef1 100644 --- a/packages/SettingsLib/res/values-el/strings.xml +++ b/packages/SettingsLib/res/values-el/strings.xml @@ -209,6 +209,8 @@ <string name="bluetooth_select_a2dp_codec_ldac_playback_quality" msgid="3619694372407843405">"Κωδικοποιητής LDAC ήχου Bluetooth: Ποιότητα αναπαραγωγής"</string> <string name="bluetooth_select_a2dp_codec_ldac_playback_quality_dialog_title" msgid="3181967377574368400">"Επιλογή κωδικοποιητή LDAC ήχου Bluetooth:\nΠοιότητα αναπαραγωγής"</string> <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"Ροή: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string> + <string name="dns_tls" msgid="6773814174391131955">"DNS μέσω TLS"</string> + <string name="dns_tls_summary" msgid="3692494150251071380">"Εάν ενεργοποιηθεί, γίνεται προσπάθεια DNS μέσω TLS στη θύρα 853."</string> <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Εμφάνιση επιλογών για πιστοποίηση ασύρματης οθόνης"</string> <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Αύξηση επιπέδου καταγ. Wi-Fi, εμφάνιση ανά SSID RSSI στο εργαλείο επιλογής Wi-Fi"</string> <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"Όταν είναι ενεργό, το Wi-Fi θα μεταβιβάζει πιο επιθετικά τη σύνδ.δεδομένων σε δίκτυο κινητής τηλ., όταν το σήμα Wi-Fi είναι χαμηλό"</string> diff --git a/packages/SettingsLib/res/values-en-rAU/strings.xml b/packages/SettingsLib/res/values-en-rAU/strings.xml index 9e24004f518d..e85242a87736 100644 --- a/packages/SettingsLib/res/values-en-rAU/strings.xml +++ b/packages/SettingsLib/res/values-en-rAU/strings.xml @@ -209,6 +209,8 @@ <string name="bluetooth_select_a2dp_codec_ldac_playback_quality" msgid="3619694372407843405">"Bluetooth Audio LDAC Codec: Playback Quality"</string> <string name="bluetooth_select_a2dp_codec_ldac_playback_quality_dialog_title" msgid="3181967377574368400">"Select Bluetooth Audio LDAC Codec:\nPlayback Quality"</string> <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"Streaming: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string> + <string name="dns_tls" msgid="6773814174391131955">"DNS over TLS"</string> + <string name="dns_tls_summary" msgid="3692494150251071380">"If enabled, attempt DNS over TLS on port 853."</string> <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Show options for wireless display certification"</string> <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Increase Wi‑Fi logging level, show per SSID RSSI in Wi‑Fi Picker"</string> <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"When enabled, Wi‑Fi will be more aggressive in handing over the data connection to mobile, when Wi‑Fi signal is low"</string> diff --git a/packages/SettingsLib/res/values-en-rCA/strings.xml b/packages/SettingsLib/res/values-en-rCA/strings.xml index 9e24004f518d..e85242a87736 100644 --- a/packages/SettingsLib/res/values-en-rCA/strings.xml +++ b/packages/SettingsLib/res/values-en-rCA/strings.xml @@ -209,6 +209,8 @@ <string name="bluetooth_select_a2dp_codec_ldac_playback_quality" msgid="3619694372407843405">"Bluetooth Audio LDAC Codec: Playback Quality"</string> <string name="bluetooth_select_a2dp_codec_ldac_playback_quality_dialog_title" msgid="3181967377574368400">"Select Bluetooth Audio LDAC Codec:\nPlayback Quality"</string> <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"Streaming: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string> + <string name="dns_tls" msgid="6773814174391131955">"DNS over TLS"</string> + <string name="dns_tls_summary" msgid="3692494150251071380">"If enabled, attempt DNS over TLS on port 853."</string> <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Show options for wireless display certification"</string> <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Increase Wi‑Fi logging level, show per SSID RSSI in Wi‑Fi Picker"</string> <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"When enabled, Wi‑Fi will be more aggressive in handing over the data connection to mobile, when Wi‑Fi signal is low"</string> diff --git a/packages/SettingsLib/res/values-en-rGB/strings.xml b/packages/SettingsLib/res/values-en-rGB/strings.xml index 9e24004f518d..e85242a87736 100644 --- a/packages/SettingsLib/res/values-en-rGB/strings.xml +++ b/packages/SettingsLib/res/values-en-rGB/strings.xml @@ -209,6 +209,8 @@ <string name="bluetooth_select_a2dp_codec_ldac_playback_quality" msgid="3619694372407843405">"Bluetooth Audio LDAC Codec: Playback Quality"</string> <string name="bluetooth_select_a2dp_codec_ldac_playback_quality_dialog_title" msgid="3181967377574368400">"Select Bluetooth Audio LDAC Codec:\nPlayback Quality"</string> <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"Streaming: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string> + <string name="dns_tls" msgid="6773814174391131955">"DNS over TLS"</string> + <string name="dns_tls_summary" msgid="3692494150251071380">"If enabled, attempt DNS over TLS on port 853."</string> <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Show options for wireless display certification"</string> <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Increase Wi‑Fi logging level, show per SSID RSSI in Wi‑Fi Picker"</string> <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"When enabled, Wi‑Fi will be more aggressive in handing over the data connection to mobile, when Wi‑Fi signal is low"</string> diff --git a/packages/SettingsLib/res/values-en-rIN/strings.xml b/packages/SettingsLib/res/values-en-rIN/strings.xml index 9e24004f518d..e85242a87736 100644 --- a/packages/SettingsLib/res/values-en-rIN/strings.xml +++ b/packages/SettingsLib/res/values-en-rIN/strings.xml @@ -209,6 +209,8 @@ <string name="bluetooth_select_a2dp_codec_ldac_playback_quality" msgid="3619694372407843405">"Bluetooth Audio LDAC Codec: Playback Quality"</string> <string name="bluetooth_select_a2dp_codec_ldac_playback_quality_dialog_title" msgid="3181967377574368400">"Select Bluetooth Audio LDAC Codec:\nPlayback Quality"</string> <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"Streaming: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string> + <string name="dns_tls" msgid="6773814174391131955">"DNS over TLS"</string> + <string name="dns_tls_summary" msgid="3692494150251071380">"If enabled, attempt DNS over TLS on port 853."</string> <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Show options for wireless display certification"</string> <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Increase Wi‑Fi logging level, show per SSID RSSI in Wi‑Fi Picker"</string> <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"When enabled, Wi‑Fi will be more aggressive in handing over the data connection to mobile, when Wi‑Fi signal is low"</string> diff --git a/packages/SettingsLib/res/values-en-rXC/strings.xml b/packages/SettingsLib/res/values-en-rXC/strings.xml index 77c0e4fc5dbe..a3430fc8e98e 100644 --- a/packages/SettingsLib/res/values-en-rXC/strings.xml +++ b/packages/SettingsLib/res/values-en-rXC/strings.xml @@ -209,6 +209,8 @@ <string name="bluetooth_select_a2dp_codec_ldac_playback_quality" msgid="3619694372407843405">"Bluetooth Audio LDAC Codec: Playback Quality"</string> <string name="bluetooth_select_a2dp_codec_ldac_playback_quality_dialog_title" msgid="3181967377574368400">"Select Bluetooth Audio LDAC Codec:\nPlayback Quality"</string> <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"Streaming: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string> + <string name="dns_tls" msgid="6773814174391131955">"DNS over TLS"</string> + <string name="dns_tls_summary" msgid="3692494150251071380">"If enabled, attempt DNS over TLS on port 853."</string> <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Show options for wireless display certification"</string> <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Increase Wi‑Fi logging level, show per SSID RSSI in Wi‑Fi Picker"</string> <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"When enabled, Wi‑Fi will be more aggressive in handing over the data connection to mobile, when Wi‑Fi signal is low"</string> diff --git a/packages/SettingsLib/res/values-es-rUS/strings.xml b/packages/SettingsLib/res/values-es-rUS/strings.xml index ff26eefeb11f..ea62383fe9a5 100644 --- a/packages/SettingsLib/res/values-es-rUS/strings.xml +++ b/packages/SettingsLib/res/values-es-rUS/strings.xml @@ -163,7 +163,7 @@ <string name="choose_profile" msgid="6921016979430278661">"Elegir perfil"</string> <string name="category_personal" msgid="1299663247844969448">"Personal"</string> <string name="category_work" msgid="8699184680584175622">"Trabajo"</string> - <string name="development_settings_title" msgid="215179176067683667">"Opciones del programador"</string> + <string name="development_settings_title" msgid="215179176067683667">"Opciones para programadores"</string> <string name="development_settings_enable" msgid="542530994778109538">"Activar opciones para programador"</string> <string name="development_settings_summary" msgid="1815795401632854041">"Establecer opciones para desarrollar aplicaciones"</string> <string name="development_settings_not_available" msgid="4308569041701535607">"Las opciones de programador no están disponibles para este usuario."</string> @@ -209,6 +209,8 @@ <string name="bluetooth_select_a2dp_codec_ldac_playback_quality" msgid="3619694372407843405">"Códec del audio Bluetooth LDAC: calidad de reproducción"</string> <string name="bluetooth_select_a2dp_codec_ldac_playback_quality_dialog_title" msgid="3181967377574368400">"Seleccionar códec del audio Bluetooth LDAC:\nCalidad de reproducción"</string> <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"Transmitiendo: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string> + <string name="dns_tls" msgid="6773814174391131955">"DNS mediante TLS"</string> + <string name="dns_tls_summary" msgid="3692494150251071380">"Si esta opción está habilitada, prueba DNS mediante TLS en el puerto 853."</string> <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Mostrar opciones de certificación de pantalla inalámbrica"</string> <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Aumentar nivel de registro Wi-Fi; mostrar por SSID RSSI en el selector de Wi-Fi"</string> <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"Si habilitas esta opción, se priorizará el cambio de Wi-Fi a datos móviles cuando la señal de Wi-Fi sea débil"</string> diff --git a/packages/SettingsLib/res/values-es/strings.xml b/packages/SettingsLib/res/values-es/strings.xml index 20bab132306b..8474c4941e10 100644 --- a/packages/SettingsLib/res/values-es/strings.xml +++ b/packages/SettingsLib/res/values-es/strings.xml @@ -209,6 +209,8 @@ <string name="bluetooth_select_a2dp_codec_ldac_playback_quality" msgid="3619694372407843405">"Selecciona el códec LDAC por Bluetooth: calidad de reproducción"</string> <string name="bluetooth_select_a2dp_codec_ldac_playback_quality_dialog_title" msgid="3181967377574368400">"Selecciona el códec LDAC de audio por Bluetooth:\nCalidad de reproducción"</string> <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"Streaming: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string> + <string name="dns_tls" msgid="6773814174391131955">"DNS a través de TLS"</string> + <string name="dns_tls_summary" msgid="3692494150251071380">"Si esta opción está inhabilitada, prueba DNS a través de TLS en el puerto 853."</string> <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Mostrar opciones para la certificación de la pantalla inalámbrica"</string> <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Aumentar el nivel de registro de Wi-Fi, mostrar por SSID RSSI en el selector Wi-Fi"</string> <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"Si se activa esta opción, la conexión Wi-Fi será más agresiva al pasar la conexión a datos móviles (si la señal Wi-Fi es débil)"</string> diff --git a/packages/SettingsLib/res/values-et/strings.xml b/packages/SettingsLib/res/values-et/strings.xml index a0341fb103f8..efbbac1b7ea6 100644 --- a/packages/SettingsLib/res/values-et/strings.xml +++ b/packages/SettingsLib/res/values-et/strings.xml @@ -209,6 +209,8 @@ <string name="bluetooth_select_a2dp_codec_ldac_playback_quality" msgid="3619694372407843405">"Bluetoothi LDAC-helikodek: taasesituskvaliteet"</string> <string name="bluetooth_select_a2dp_codec_ldac_playback_quality_dialog_title" msgid="3181967377574368400">"Valige Bluetoothi LDAC-helikodek:\ntaasesituskvaliteet"</string> <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"Voogesitus: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string> + <string name="dns_tls" msgid="6773814174391131955">"DNS TLS-i kaudu"</string> + <string name="dns_tls_summary" msgid="3692494150251071380">"Kui on lubatud, katsetatakse DNS-i TLS-i kaudu (port 853)."</string> <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Juhtmeta ekraaniühenduse sertifitseerimisvalikute kuvamine"</string> <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Suurenda WiFi logimistaset, kuva WiFi valijas SSID RSSI järgi"</string> <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"Kui seade on lubatud, asendatakse nõrga signaaliga WiFi-ühendus agressiivsemalt mobiilse andmesideühendusega"</string> diff --git a/packages/SettingsLib/res/values-eu/strings.xml b/packages/SettingsLib/res/values-eu/strings.xml index e8d9a5e1c211..bd2f94e3aaf9 100644 --- a/packages/SettingsLib/res/values-eu/strings.xml +++ b/packages/SettingsLib/res/values-eu/strings.xml @@ -209,6 +209,8 @@ <string name="bluetooth_select_a2dp_codec_ldac_playback_quality" msgid="3619694372407843405">"Bluetooth audioaren LDAC kodeka: erreprodukzioaren kalitatea"</string> <string name="bluetooth_select_a2dp_codec_ldac_playback_quality_dialog_title" msgid="3181967377574368400">"Hautatu Bluetooth audioaren LDAC kodeka:\nerreprodukzioaren kalitatea"</string> <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"Igortzean: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string> + <string name="dns_tls" msgid="6773814174391131955">"TLS bidezko DNSa"</string> + <string name="dns_tls_summary" msgid="3692494150251071380">"Gaituz gero, erabili TLS bidezko DNSa 853 atakan."</string> <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Erakutsi hari gabeko bistaratze-egiaztapenaren aukerak"</string> <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Erakutsi datu gehiago Wi-Fi sareetan saioa hasterakoan. Erakutsi sarearen identifikatzailea eta seinalearen indarra Wi‑Fi sareen hautagailuan."</string> <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"Aukera hori gaituz gero, gailua nahitaez aldatuko da datu mugikorren konexiora Wi-Fi seinalea ahultzen dela nabaritutakoan"</string> diff --git a/packages/SettingsLib/res/values-fa/strings.xml b/packages/SettingsLib/res/values-fa/strings.xml index 326192d4a771..bc287bcd7c87 100644 --- a/packages/SettingsLib/res/values-fa/strings.xml +++ b/packages/SettingsLib/res/values-fa/strings.xml @@ -209,6 +209,8 @@ <string name="bluetooth_select_a2dp_codec_ldac_playback_quality" msgid="3619694372407843405">"کدک LDAC صوتی بلوتوث: کیفیت پخش"</string> <string name="bluetooth_select_a2dp_codec_ldac_playback_quality_dialog_title" msgid="3181967377574368400">"انتخاب کدک LDAC صوتی بلوتوث:\nکیفیت پخش"</string> <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"پخش جریانی: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string> + <string name="dns_tls" msgid="6773814174391131955">"DNS ازطریق امنیت لایه انتقال"</string> + <string name="dns_tls_summary" msgid="3692494150251071380">"درصورت فعال بودن، DNS ازطریق امنیت لایه انتقال در درگاه ۸۵۳ انجام شود."</string> <string name="wifi_display_certification_summary" msgid="1155182309166746973">"نمایش گزینهها برای گواهینامه نمایش بیسیم"</string> <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"افزایش سطح گزارشگیری Wi‑Fi، نمایش به ازای SSID RSSI در انتخابکننده Wi‑Fi"</string> <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"زمانیکه فعال است، درشرایطی که سیگنال Wi-Fi ضعیف باشد، Wi‑Fi برای واگذاری اتصال داده به دستگاه همراه قویتر عمل خواهد کرد."</string> diff --git a/packages/SettingsLib/res/values-fi/strings.xml b/packages/SettingsLib/res/values-fi/strings.xml index 63210869507e..6742acafbadc 100644 --- a/packages/SettingsLib/res/values-fi/strings.xml +++ b/packages/SettingsLib/res/values-fi/strings.xml @@ -209,6 +209,8 @@ <string name="bluetooth_select_a2dp_codec_ldac_playback_quality" msgid="3619694372407843405">"Bluetooth-äänen LDAC-koodekki: Toiston laatu"</string> <string name="bluetooth_select_a2dp_codec_ldac_playback_quality_dialog_title" msgid="3181967377574368400">"Valitse Bluetooth-äänen LDAC-koodekki:\nToiston laatu"</string> <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"Striimaus: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string> + <string name="dns_tls" msgid="6773814174391131955">"DNS ennen TLS:ää"</string> + <string name="dns_tls_summary" msgid="3692494150251071380">"Jos tämä on käytössä, yritä käyttää DNS:ää mieluummin kuin TLS:ää portin 853 kautta."</string> <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Näytä langattoman näytön sertifiointiin liittyvät asetukset"</string> <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Lisää Wi‑Fin lokikirjaustasoa, näytä SSID RSSI -kohtaisesti Wi‑Fi-valitsimessa."</string> <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"Kun asetus on käytössä, datayhteys siirtyy helpommin Wi-Fistä matkapuhelinverkkoon, jos Wi-Fi-signaali on heikko."</string> diff --git a/packages/SettingsLib/res/values-fr-rCA/strings.xml b/packages/SettingsLib/res/values-fr-rCA/strings.xml index 00c02ce3dfbf..bb5d2d8e3380 100644 --- a/packages/SettingsLib/res/values-fr-rCA/strings.xml +++ b/packages/SettingsLib/res/values-fr-rCA/strings.xml @@ -209,6 +209,8 @@ <string name="bluetooth_select_a2dp_codec_ldac_playback_quality" msgid="3619694372407843405">"Codec audio Bluetooth LDAC : qualité de lecture"</string> <string name="bluetooth_select_a2dp_codec_ldac_playback_quality_dialog_title" msgid="3181967377574368400">"Sélectionner le codec audio Bluetooth LDAC :\nQualité de lecture"</string> <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"Diffusion : <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string> + <string name="dns_tls" msgid="6773814174391131955">"DNS par TLS"</string> + <string name="dns_tls_summary" msgid="3692494150251071380">"Si cette option est activée, essayez le DNS par TLS sur le port 853."</string> <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Afficher les options pour la certification d\'affichage sans fil"</string> <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Détailler davantage les données Wi-Fi, afficher par SSID RSSI dans sélect. Wi-Fi"</string> <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"Si cette option est activée, le passage du Wi-Fi aux données cellulaires est forcé lorsque le signal Wi-Fi est faible"</string> diff --git a/packages/SettingsLib/res/values-fr/strings.xml b/packages/SettingsLib/res/values-fr/strings.xml index a5625e4e9e8e..9238c21d25da 100644 --- a/packages/SettingsLib/res/values-fr/strings.xml +++ b/packages/SettingsLib/res/values-fr/strings.xml @@ -209,6 +209,8 @@ <string name="bluetooth_select_a2dp_codec_ldac_playback_quality" msgid="3619694372407843405">"Codec audio Bluetooth LDAC : qualité de lecture"</string> <string name="bluetooth_select_a2dp_codec_ldac_playback_quality_dialog_title" msgid="3181967377574368400">"Sélectionner le codec audio Bluetooth LDAC :\nQualité de lecture"</string> <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"Diffusion : <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string> + <string name="dns_tls" msgid="6773814174391131955">"DNS sur TLS"</string> + <string name="dns_tls_summary" msgid="3692494150251071380">"Si l\'option est activée, essayez le protocole DNS sur TLS sur le port 853."</string> <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Afficher les options de la certification de l\'affichage sans fil"</string> <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Détailler plus infos Wi-Fi, afficher par RSSI de SSID dans outil sélection Wi-Fi"</string> <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"Si cette option est activée, le passage du Wi-Fi aux données mobiles est forcé en cas de signal Wi-Fi faible."</string> diff --git a/packages/SettingsLib/res/values-gl/strings.xml b/packages/SettingsLib/res/values-gl/strings.xml index e1ea694db64e..29b1e2b22ed0 100644 --- a/packages/SettingsLib/res/values-gl/strings.xml +++ b/packages/SettingsLib/res/values-gl/strings.xml @@ -209,6 +209,8 @@ <string name="bluetooth_select_a2dp_codec_ldac_playback_quality" msgid="3619694372407843405">"Códec LDAC de audio por Bluetooth: calidade de reprodución"</string> <string name="bluetooth_select_a2dp_codec_ldac_playback_quality_dialog_title" msgid="3181967377574368400">"Seleccionar códec LDAC de audio por Bluetooth:\ncalidade de reprodución"</string> <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"Reprodución en tempo real: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string> + <string name="dns_tls" msgid="6773814174391131955">"DNS a través de TLS"</string> + <string name="dns_tls_summary" msgid="3692494150251071380">"Se se activa esta opción, téntase utilizar o método DNS a través de TLS no porto 853."</string> <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Mostra opcións para o certificado de visualización sen fíos"</string> <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Aumentar o nivel de rexistro da wifi, mostrar por SSID RSSI no selector de wifi"</string> <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"Cando estea activada esta función, a wifi será máis agresiva ao transferir a conexión de datos ao móbil cando o sinal wifi sexa feble"</string> diff --git a/packages/SettingsLib/res/values-gu/strings.xml b/packages/SettingsLib/res/values-gu/strings.xml index 0e8dd47fdc7b..cbaa414ebddc 100644 --- a/packages/SettingsLib/res/values-gu/strings.xml +++ b/packages/SettingsLib/res/values-gu/strings.xml @@ -209,6 +209,8 @@ <string name="bluetooth_select_a2dp_codec_ldac_playback_quality" msgid="3619694372407843405">"બ્લૂટૂથ ઑડિઓ LDAC કોડેક: પ્લેબૅક ગુણવત્તા"</string> <string name="bluetooth_select_a2dp_codec_ldac_playback_quality_dialog_title" msgid="3181967377574368400">"બ્લૂટૂથ ઑડિઓ LDAC કોડેક પસંદ કરો:\nપ્લેબૅક ગુણવત્તા"</string> <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"સ્ટ્રીમિંગ: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string> + <string name="dns_tls" msgid="6773814174391131955">"DNS ઓવર TLS"</string> + <string name="dns_tls_summary" msgid="3692494150251071380">"જો ચાલુ કરવામાં આવે, તો પોર્ટ 853 પરથી DNS ઓવર TLSનો પ્રયાસ કરો."</string> <string name="wifi_display_certification_summary" msgid="1155182309166746973">"વાયરલેસ ડિસ્પ્લે પ્રમાણપત્ર માટેના વિકલ્પો બતાવો"</string> <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"વાઇ-ફાઇ લોગિંગ સ્તર વધારો, વાઇ-ફાઇ પીકરમાં SSID RSSI દીઠ બતાવો"</string> <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"જ્યારે સક્ષમ કરેલ હોય, ત્યારે વાઇ-ફાઇ સિગ્નલ નબળું હોવા પર, વાઇ-ફાઇ વધુ ઝડપથી ડેટા કનેક્શનને મોબાઇલ પર મોકલશે"</string> diff --git a/packages/SettingsLib/res/values-hi/strings.xml b/packages/SettingsLib/res/values-hi/strings.xml index 28bc68aa556b..5d25d2096abe 100644 --- a/packages/SettingsLib/res/values-hi/strings.xml +++ b/packages/SettingsLib/res/values-hi/strings.xml @@ -209,6 +209,10 @@ <string name="bluetooth_select_a2dp_codec_ldac_playback_quality" msgid="3619694372407843405">"ब्लूटूथ ऑडियो LDAC कोडेक: प्लेबैक क्वालिटी"</string> <string name="bluetooth_select_a2dp_codec_ldac_playback_quality_dialog_title" msgid="3181967377574368400">"ब्लूटूथ ऑडियो LDAC कोडेक चुनें:\nप्लेबैक क्वालिटी"</string> <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"चलाया जा रहा है: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string> + <!-- no translation found for dns_tls (6773814174391131955) --> + <skip /> + <!-- no translation found for dns_tls_summary (3692494150251071380) --> + <skip /> <string name="wifi_display_certification_summary" msgid="1155182309166746973">"वायरलेस दिखाई देने के लिए प्रमाणन विकल्प दिखाएं"</string> <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"वाई-फ़ाई प्रवेश स्तर बढ़ाएं, वाई-फ़ाई पिकर में प्रति SSID RSSI दिखाएं"</string> <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"इसके सक्षम होने पर, जब वाई-फ़ाई संकेत कमज़ोर हों तो वाई-फ़ाई, डेटा कनेक्शन को मोबाइल पर ज़्यादा तेज़ी से भेजेगा"</string> diff --git a/packages/SettingsLib/res/values-hr/strings.xml b/packages/SettingsLib/res/values-hr/strings.xml index b5c543944029..c134970f005a 100644 --- a/packages/SettingsLib/res/values-hr/strings.xml +++ b/packages/SettingsLib/res/values-hr/strings.xml @@ -209,6 +209,8 @@ <string name="bluetooth_select_a2dp_codec_ldac_playback_quality" msgid="3619694372407843405">"Kodek za Bluetooth Audio LDAC: kvaliteta reprodukcije"</string> <string name="bluetooth_select_a2dp_codec_ldac_playback_quality_dialog_title" msgid="3181967377574368400">"Odaberi kodek za Bluetooth Audio LDAC:\nkvaliteta reprodukcije"</string> <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"Strujanje: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string> + <string name="dns_tls" msgid="6773814174391131955">"DNS putem TLS-a"</string> + <string name="dns_tls_summary" msgid="3692494150251071380">"Ako je omogućeno, pokušava se upotrijebiti DNS putem TLS-a na priključku 853."</string> <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Prikaži opcije za certifikaciju bežičnog prikaza"</string> <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Povećana razina prijave na Wi‑Fi, prikaz po SSID RSSI-ju u Biraču Wi‑Fi-ja"</string> <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"Ako je omogućeno, Wi-Fi će aktivno prebacivati podatkovnu vezu mobilnoj mreži kada je Wi-Fi signal slab."</string> diff --git a/packages/SettingsLib/res/values-hu/strings.xml b/packages/SettingsLib/res/values-hu/strings.xml index 47d6c987bab7..da206cb793f0 100644 --- a/packages/SettingsLib/res/values-hu/strings.xml +++ b/packages/SettingsLib/res/values-hu/strings.xml @@ -209,6 +209,8 @@ <string name="bluetooth_select_a2dp_codec_ldac_playback_quality" msgid="3619694372407843405">"Bluetooth LDAC hangkodek: lejátszási minőség"</string> <string name="bluetooth_select_a2dp_codec_ldac_playback_quality_dialog_title" msgid="3181967377574368400">"Bluetooth LDAC hangkodek kiválasztása:\nlejátszási minőség"</string> <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"Streamelés: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string> + <string name="dns_tls" msgid="6773814174391131955">"TLS-en keresztüli DNS"</string> + <string name="dns_tls_summary" msgid="3692494150251071380">"TLS-en keresztüli DNS megkísérlése a 853-as porton, ha engedélyezve van."</string> <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Vezeték nélküli kijelző tanúsítványával kapcsolatos lehetőségek megjelenítése"</string> <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Wi‑Fi-naplózási szint növelése, RSSI/SSID megjelenítése a Wi‑Fi-választóban"</string> <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"Ha engedélyezi, a Wi-Fi agresszívebben fogja átadni az adatkapcsolatot a mobilhálózatnak gyenge Wi-Fi-jel esetén"</string> diff --git a/packages/SettingsLib/res/values-hy/strings.xml b/packages/SettingsLib/res/values-hy/strings.xml index 6f11cd852737..2365058bb8db 100644 --- a/packages/SettingsLib/res/values-hy/strings.xml +++ b/packages/SettingsLib/res/values-hy/strings.xml @@ -209,6 +209,8 @@ <string name="bluetooth_select_a2dp_codec_ldac_playback_quality" msgid="3619694372407843405">"Bluetooth աուդիո LDAC կոդեկ՝ նվագարկման որակ"</string> <string name="bluetooth_select_a2dp_codec_ldac_playback_quality_dialog_title" msgid="3181967377574368400">"Ընտրեք Bluetooth աուդիո LDAC կոդեկը՝\nնվագարկման որակ"</string> <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"Հեռարձակում՝ <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string> + <string name="dns_tls" msgid="6773814174391131955">"DNS TLS-ի միջոցով"</string> + <string name="dns_tls_summary" msgid="3692494150251071380">"Միացնելու դեպքում փորձել DNS-ը TLS-ի միջոցով միացք 853-ում:"</string> <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Ցույց տալ անլար էկրանի հավաստագրման ընտրանքները"</string> <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Բարձրացնել մակարդակը, Wi‑Fi ընտրիչում ամեն մի SSID-ի համար ցույց տալ RSSI"</string> <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"Եթե այս գործառույթը միացված է, Wi-Fi-ի թույլ ազդանշանի դեպքում Wi‑Fi ինտերնետից բջջային ինտերնետի անցումը ավելի կտրուկ կկատարվի"</string> diff --git a/packages/SettingsLib/res/values-in/strings.xml b/packages/SettingsLib/res/values-in/strings.xml index b4a58bbf7129..7e2848fe7092 100644 --- a/packages/SettingsLib/res/values-in/strings.xml +++ b/packages/SettingsLib/res/values-in/strings.xml @@ -209,6 +209,8 @@ <string name="bluetooth_select_a2dp_codec_ldac_playback_quality" msgid="3619694372407843405">"Codec LDAC Audio Bluetooth: Kualitas Pemutaran"</string> <string name="bluetooth_select_a2dp_codec_ldac_playback_quality_dialog_title" msgid="3181967377574368400">"Pilih Codec LDAC Audio Bluetooth:\nKualitas Pemutaran"</string> <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"Streaming: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string> + <string name="dns_tls" msgid="6773814174391131955">"DNS melalui TLS"</string> + <string name="dns_tls_summary" msgid="3692494150251071380">"Jika diaktifkan, coba DNS melalui TLS pada port 853."</string> <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Tampilkan opsi untuk sertifikasi layar nirkabel"</string> <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Tingkatkan level pencatatan log Wi-Fi, tampilkan per SSID RSSI di Pemilih Wi‑Fi"</string> <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"Jika diaktifkan, Wi-Fi akan menjadi lebih agresif dalam mengalihkan sambungan data ke seluler saat sinyal Wi-Fi lemah"</string> @@ -277,7 +279,7 @@ <string name="debug_layout_summary" msgid="2001775315258637682">"Tampilkan batas klip, margin, dll."</string> <string name="force_rtl_layout_all_locales" msgid="2259906643093138978">"Paksa arah tata letak RTL"</string> <string name="force_rtl_layout_all_locales_summary" msgid="9192797796616132534">"Paksa arah tata letak layar RTL untuk semua lokal"</string> - <string name="force_hw_ui" msgid="6426383462520888732">"Paksa perenderan GPU"</string> + <string name="force_hw_ui" msgid="6426383462520888732">"Paksa rendering GPU"</string> <string name="force_hw_ui_summary" msgid="5535991166074861515">"Paksa penggunaan GPU untuk gambar 2d"</string> <string name="force_msaa" msgid="7920323238677284387">"Paksa 4x MSAA"</string> <string name="force_msaa_summary" msgid="9123553203895817537">"Aktifkan 4x MSAA dalam aplikasi OpenGL ES 2.0"</string> diff --git a/packages/SettingsLib/res/values-is/strings.xml b/packages/SettingsLib/res/values-is/strings.xml index 29b1b5d10e06..5f4d401eddc2 100644 --- a/packages/SettingsLib/res/values-is/strings.xml +++ b/packages/SettingsLib/res/values-is/strings.xml @@ -209,6 +209,8 @@ <string name="bluetooth_select_a2dp_codec_ldac_playback_quality" msgid="3619694372407843405">"Bluetooth LDAC-hljóðkóðari: gæði spilunar"</string> <string name="bluetooth_select_a2dp_codec_ldac_playback_quality_dialog_title" msgid="3181967377574368400">"Velja Bluetooth LDAC-hljóðkóðara:\ngæði spilunar"</string> <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"Streymi: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string> + <string name="dns_tls" msgid="6773814174391131955">"DNS yfir TLS"</string> + <string name="dns_tls_summary" msgid="3692494150251071380">"Ef kveikt er á þessu, reyna DNS yfir TLS á gátt 853."</string> <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Sýna valkosti fyrir vottun þráðlausra skjáa"</string> <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Auka skráningarstig Wi-Fi, sýna RSSI fyrir hvert SSID í Wi-Fi vali"</string> <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"Þegar þetta er virkt mun Wi-Fi skipta hraðar yfir í farsímagagnatengingu þegar Wi-Fi-tenging er léleg"</string> diff --git a/packages/SettingsLib/res/values-it/strings.xml b/packages/SettingsLib/res/values-it/strings.xml index 46004c314f02..439fea198fe4 100644 --- a/packages/SettingsLib/res/values-it/strings.xml +++ b/packages/SettingsLib/res/values-it/strings.xml @@ -209,6 +209,8 @@ <string name="bluetooth_select_a2dp_codec_ldac_playback_quality" msgid="3619694372407843405">"Codec LDAC audio Bluetooth: qualità di riproduzione"</string> <string name="bluetooth_select_a2dp_codec_ldac_playback_quality_dialog_title" msgid="3181967377574368400">"Seleziona il codec LDAC audio Bluetooth:\nQualità di riproduzione"</string> <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"Streaming: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string> + <string name="dns_tls" msgid="6773814174391131955">"DNS tramite TLS"</string> + <string name="dns_tls_summary" msgid="3692494150251071380">"Se l\'opzione è attiva, prova DNS tramite TLS sulla porta 853."</string> <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Mostra opzioni per la certificazione display wireless"</string> <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Aumenta il livello di registrazione Wi-Fi, mostrando il SSID RSSI nel selettore Wi-Fi"</string> <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"Con questa impostazione attivata, il Wi-Fi è più aggressivo nel passare la connessione dati al cellulare, con segnale Wi-Fi basso"</string> diff --git a/packages/SettingsLib/res/values-iw/strings.xml b/packages/SettingsLib/res/values-iw/strings.xml index 24f4684f34f5..435abbb908da 100644 --- a/packages/SettingsLib/res/values-iw/strings.xml +++ b/packages/SettingsLib/res/values-iw/strings.xml @@ -209,6 +209,8 @@ <string name="bluetooth_select_a2dp_codec_ldac_playback_quality" msgid="3619694372407843405">"Codec אודיו LDAC ל-Bluetooth: איכות נגינה"</string> <string name="bluetooth_select_a2dp_codec_ldac_playback_quality_dialog_title" msgid="3181967377574368400">"בחירת Codec אודיו LDAC ל-Bluetooth:\nאיכות נגינה"</string> <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"סטרימינג: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string> + <string name="dns_tls" msgid="6773814174391131955">"DNS באמצעות TLS (אבטחת שכבת התעבורה)"</string> + <string name="dns_tls_summary" msgid="3692494150251071380">"אם האפשרות מופעלת, יש לנסות DNS באמצעות TLS (אבטחת שכבת התעבורה) ביציאה 853."</string> <string name="wifi_display_certification_summary" msgid="1155182309166746973">"הצג אפשרויות עבור אישור של תצוגת WiFi"</string> <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"העלה את רמת הרישום של Wi‑Fi ביומן, הצג לכל SSID RSSI ב-Wi‑Fi Picker"</string> <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"כשאפשרות זו מופעלת, Wi-Fi יתנהג בצורה אגרסיבית יותר בעת העברת חיבור הנתונים לרשת הסלולרית כשאות ה-Wi-Fi חלש."</string> diff --git a/packages/SettingsLib/res/values-ja/strings.xml b/packages/SettingsLib/res/values-ja/strings.xml index bb3f5a930fab..308e97d81f7c 100644 --- a/packages/SettingsLib/res/values-ja/strings.xml +++ b/packages/SettingsLib/res/values-ja/strings.xml @@ -209,6 +209,8 @@ <string name="bluetooth_select_a2dp_codec_ldac_playback_quality" msgid="3619694372407843405">"Bluetooth オーディオ LDAC コーデック: 再生音質"</string> <string name="bluetooth_select_a2dp_codec_ldac_playback_quality_dialog_title" msgid="3181967377574368400">"Bluetooth オーディオ LDAC コーデックを選択:\n再生音質"</string> <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"ストリーミング: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string> + <string name="dns_tls" msgid="6773814174391131955">"DNS over TLS"</string> + <string name="dns_tls_summary" msgid="3692494150251071380">"この設定を有効にした場合、ポート 853 で DNS over TLS を試行します。"</string> <string name="wifi_display_certification_summary" msgid="1155182309166746973">"ワイヤレスディスプレイ認証のオプションを表示"</string> <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Wi-Fiログレベルを上げて、Wi-Fi選択ツールでSSID RSSIごとに表示します"</string> <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"ON にすると、Wi-Fi の電波強度が弱い場合は強制的にモバイルデータ接続に切り替わるようになります"</string> diff --git a/packages/SettingsLib/res/values-ka/strings.xml b/packages/SettingsLib/res/values-ka/strings.xml index 228026131460..9318a7f62769 100644 --- a/packages/SettingsLib/res/values-ka/strings.xml +++ b/packages/SettingsLib/res/values-ka/strings.xml @@ -209,6 +209,8 @@ <string name="bluetooth_select_a2dp_codec_ldac_playback_quality" msgid="3619694372407843405">"Bluetooth აუდიოს LDAC კოდეკის დაკვრის ხარისხი"</string> <string name="bluetooth_select_a2dp_codec_ldac_playback_quality_dialog_title" msgid="3181967377574368400">"აირჩიეთ Bluetooth აუდიოს LDAC კოდეკის\nდაკვრის ხარისხი"</string> <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"სტრიმინგი: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string> + <string name="dns_tls" msgid="6773814174391131955">"DNS-ის TLS-ის მეშვეობით გადაცემა"</string> + <string name="dns_tls_summary" msgid="3692494150251071380">"ჩართვის შემთხვევაში, ცადეთ DNS-ის TLS-ის მეშვეობით გადაცემა პორტზე 853."</string> <string name="wifi_display_certification_summary" msgid="1155182309166746973">"უსადენო ეკრანის სერტიფიცირების ვარიანტების ჩვენება"</string> <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Wi‑Fi-ს აღრიცხვის დონის გაზრდა, Wi‑Fi ამომრჩეველში ყოველ SSID RSSI-ზე ჩვენება"</string> <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"ჩართვის შემთხვევაში, Wi‑Fi უფრო აქტიურად შეეცდება მობილურ ინტერნეტზე გადართვას, როცა Wi‑Fi სიგნალი სუსტია"</string> diff --git a/packages/SettingsLib/res/values-kk/strings.xml b/packages/SettingsLib/res/values-kk/strings.xml index 03bd3cd0cdb6..223a32842ff7 100644 --- a/packages/SettingsLib/res/values-kk/strings.xml +++ b/packages/SettingsLib/res/values-kk/strings.xml @@ -209,6 +209,8 @@ <string name="bluetooth_select_a2dp_codec_ldac_playback_quality" msgid="3619694372407843405">"Bluetooth LDAC аудиокодегі: ойнату сапасы"</string> <string name="bluetooth_select_a2dp_codec_ldac_playback_quality_dialog_title" msgid="3181967377574368400">"Bluetooth LDAC аудиокодегін таңдау:\nойнату сапасы"</string> <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"Трансляция: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string> + <string name="dns_tls" msgid="6773814174391131955">"TLS бойынша DNS"</string> + <string name="dns_tls_summary" msgid="3692494150251071380">"Қосулы болса, 853 портында DNS жүйесін TLS протоколы арқылы қосып көріңіз."</string> <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Сымсыз дисплей растау опцияларын көрсету"</string> <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Wi‑Fi жур. тір. дең. арт., Wi‑Fi желісін таңдағышта әр SSID RSSI бойынша көрсету"</string> <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"Wi‑Fi сигналы әлсіз болғанда, деректер байланысы мәжбүрлі түрде мобильдік желіге ауысады"</string> diff --git a/packages/SettingsLib/res/values-km/strings.xml b/packages/SettingsLib/res/values-km/strings.xml index 6414141dfbcc..873d15ae4668 100644 --- a/packages/SettingsLib/res/values-km/strings.xml +++ b/packages/SettingsLib/res/values-km/strings.xml @@ -209,6 +209,8 @@ <string name="bluetooth_select_a2dp_codec_ldac_playback_quality" msgid="3619694372407843405">"កូឌិកប្រភេទ LDAC នៃសំឡេងប៊្លូធូស៖ គុណភាពចាក់សំឡេង"</string> <string name="bluetooth_select_a2dp_codec_ldac_playback_quality_dialog_title" msgid="3181967377574368400">"ជ្រើសរើសកូឌិកប្រភេទ LDAC នៃសំឡេងប៊្លូធូស៖\nគុណភាពចាក់សំឡេង"</string> <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"កំពុងចាក់៖ <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string> + <string name="dns_tls" msgid="6773814174391131955">"DNS តាមរយៈ TLS"</string> + <string name="dns_tls_summary" msgid="3692494150251071380">"ប្រសិនបើបើក វានឹងព្យាយាមប្រើ DNS តាមរៈ TLS នៅលើរន្ធ 853។"</string> <string name="wifi_display_certification_summary" msgid="1155182309166746973">"បង្ហាញជម្រើសសម្រាប់វិញ្ញាបនបត្របង្ហាញឥតខ្សែ"</string> <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"បង្កើនកម្រិតកំណត់ហេតុវ៉ាយហ្វាយបង្ហាញក្នុង SSID RSSI ក្នុងកម្មវិធីជ្រើសវ៉ាយហ្វាយ"</string> <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"នៅពេលដែលបើក នោះ Wi‑Fi នឹងផ្តល់ការតភ្ជាប់ទិន្នន័យយ៉ាងគំហុកទៅបណ្តាញទូរសព្ទចល័ត នៅពេលរលកសញ្ញា Wi‑Fi ចុះខ្សោយ។"</string> diff --git a/packages/SettingsLib/res/values-kn/strings.xml b/packages/SettingsLib/res/values-kn/strings.xml index d108dd6210d6..8d9a7e150f87 100644 --- a/packages/SettingsLib/res/values-kn/strings.xml +++ b/packages/SettingsLib/res/values-kn/strings.xml @@ -209,6 +209,8 @@ <string name="bluetooth_select_a2dp_codec_ldac_playback_quality" msgid="3619694372407843405">"ಬ್ಲೂಟೂತ್ ಆಡಿಯೊ LDAC ಕೋಡೆಕ್: ಪ್ಲೇಬ್ಯಾಕ್ ಗುಣಮಟ್ಟ"</string> <string name="bluetooth_select_a2dp_codec_ldac_playback_quality_dialog_title" msgid="3181967377574368400">"ಬ್ಲೂಟೂತ್ ಆಡಿಯೊ LDAC ಕೋಡೆಕ್:\nಪ್ಲೇಬ್ಯಾಕ್ ಗುಣಮಟ್ಟ ಆಯ್ಕೆ ಮಾಡಿ"</string> <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"ಸ್ಟ್ರೀಮಿಂಗ್: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string> + <string name="dns_tls" msgid="6773814174391131955">"TLS ಮೇಲೆ DNS"</string> + <string name="dns_tls_summary" msgid="3692494150251071380">"ಸಕ್ರಿಯಗೊಂಡರೆ, ಪೋರ್ಟ್ 853 ನಲ್ಲಿ TLS ಮೇಲೆ DNS ಅನ್ನು ಪ್ರಯತ್ನಿಸಿ."</string> <string name="wifi_display_certification_summary" msgid="1155182309166746973">"ವೈರ್ಲೆಸ್ ಪ್ರದರ್ಶನ ಪ್ರಮಾಣೀಕರಣಕ್ಕಾಗಿ ಆಯ್ಕೆಗಳನ್ನು ತೋರಿಸು"</string> <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Wi‑Fi ಲಾಗಿಂಗ್ ಮಟ್ಟನ್ನು ಹೆಚ್ಚಿಸಿ, Wi‑Fi ಆಯ್ಕೆಯಲ್ಲಿ ಪ್ರತಿಯೊಂದು SSID RSSI ತೋರಿಸಿ"</string> <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"ಇದು ಸಕ್ರಿಯಗೊಂಡರೆ, ವೈ-ಫೈ ಸಿಗ್ನಲ್ ದುರ್ಬಲವಾಗಿದ್ದಾಗ, ಮೊಬೈಲ್ಗೆ ಡೇಟಾ ಸಂಪರ್ಕವನ್ನು ಹಸ್ತಾಂತರಿಸುವಲ್ಲಿ ವೈ-ಫೈ ಹೆಚ್ಚು ಆಕ್ರಮಣಕಾರಿಯಾಗಿರುತ್ತದೆ"</string> diff --git a/packages/SettingsLib/res/values-ko/strings.xml b/packages/SettingsLib/res/values-ko/strings.xml index ec03fb143825..4e3bc3368aed 100644 --- a/packages/SettingsLib/res/values-ko/strings.xml +++ b/packages/SettingsLib/res/values-ko/strings.xml @@ -209,6 +209,8 @@ <string name="bluetooth_select_a2dp_codec_ldac_playback_quality" msgid="3619694372407843405">"블루투스 오디오 LDAC 코덱: 재생 품질"</string> <string name="bluetooth_select_a2dp_codec_ldac_playback_quality_dialog_title" msgid="3181967377574368400">"블루투스 오디오 LDAC 코덱 선택:\n재생 품질"</string> <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"스트리밍: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string> + <string name="dns_tls" msgid="6773814174391131955">"TLS를 통한 DNS"</string> + <string name="dns_tls_summary" msgid="3692494150251071380">"사용 설정한 경우, 포트 853에서 TLS를 통해 DNS를 시도합니다."</string> <string name="wifi_display_certification_summary" msgid="1155182309166746973">"무선 디스플레이 인증서 옵션 표시"</string> <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Wi‑Fi 로깅 수준을 높이고, Wi‑Fi 선택도구에서 SSID RSSI당 값을 표시합니다."</string> <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"사용 설정하면 Wi-Fi 신호가 약할 때 데이터 연결을 Wi-Fi에서 모바일 네트워크로 더욱 적극적으로 핸드오버합니다."</string> diff --git a/packages/SettingsLib/res/values-ky/strings.xml b/packages/SettingsLib/res/values-ky/strings.xml index 883811d4cec9..09edefeaffc8 100644 --- a/packages/SettingsLib/res/values-ky/strings.xml +++ b/packages/SettingsLib/res/values-ky/strings.xml @@ -209,6 +209,8 @@ <string name="bluetooth_select_a2dp_codec_ldac_playback_quality" msgid="3619694372407843405">"Bluetooth аудио LDAC кодеги: Ойнотуу сапаты"</string> <string name="bluetooth_select_a2dp_codec_ldac_playback_quality_dialog_title" msgid="3181967377574368400">"Bluetooth аудио LDAC кодегин тандаңыз:\nОйнотуу сапаты"</string> <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"Трансляция: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string> + <string name="dns_tls" msgid="6773814174391131955">"TLS аркылуу DNS"</string> + <string name="dns_tls_summary" msgid="3692494150251071380">"Эгер иштетилсе, DNS сервери TLS аркылуу 853-оюкчага аракет кылсын."</string> <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Зымсыз дисплейди сертификатто мүмкүнчүлүктөрүн көргөзүү"</string> <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Wi-Fi Кармагычта Wi‑Fi протокол деңгээлин жогорулатуу жана ар бир SSID RSSI үчүн көрсөтүү."</string> <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"Иштетилсе, Wi-Fi байланышы үзүл-кесил болуп жатканда, Wi-Fi тармагы туташууну мобилдик Интернетке өжөрлүк менен өткөрүп берет"</string> diff --git a/packages/SettingsLib/res/values-lo/strings.xml b/packages/SettingsLib/res/values-lo/strings.xml index 464b490225f9..f1c92b07be09 100644 --- a/packages/SettingsLib/res/values-lo/strings.xml +++ b/packages/SettingsLib/res/values-lo/strings.xml @@ -209,6 +209,8 @@ <string name="bluetooth_select_a2dp_codec_ldac_playback_quality" msgid="3619694372407843405">"Bluetooth Audio LDAC Codec: Playback Quality"</string> <string name="bluetooth_select_a2dp_codec_ldac_playback_quality_dialog_title" msgid="3181967377574368400">"Select Bluetooth Audio LDAC Codec:\nPlayback Quality"</string> <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"Streaming: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string> + <string name="dns_tls" msgid="6773814174391131955">"DNS ຜ່ານ TLS"</string> + <string name="dns_tls_summary" msgid="3692494150251071380">"ຫາກເປີດໃຊ້, ລະບົບຈະພະຍາຍາມໃຊ້ DNS ຜ່ານ TLS ຢູ່ຜອດ 853."</string> <string name="wifi_display_certification_summary" msgid="1155182309166746973">"ສະແດງໂຕເລືອກສຳລັບການສະແດງການຮັບຮອງລະບົບໄຮ້ສາຍ"</string> <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"ເພີ່ມລະດັບການເກັບປະຫວັດ Wi‑Fi, ສະແດງຕໍ່ SSID RSSI ໃນ Wi‑Fi Picker"</string> <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"ເມື່ອເປີດໃຊ້ແລ້ວ, Wi-Fi ຈະສົ່ງຜ່ານການເຊື່ອມຕໍ່ຂໍ້ມູນໄປຫາເຄືອຂ່າຍມືຖືເມື່ອສັນຍານ Wi-Fi ອ່ອນ"</string> diff --git a/packages/SettingsLib/res/values-lt/strings.xml b/packages/SettingsLib/res/values-lt/strings.xml index fd3bc1840941..f888504ee945 100644 --- a/packages/SettingsLib/res/values-lt/strings.xml +++ b/packages/SettingsLib/res/values-lt/strings.xml @@ -209,6 +209,8 @@ <string name="bluetooth_select_a2dp_codec_ldac_playback_quality" msgid="3619694372407843405">"„Bluetooth“ garso LDAC kodekas: atkūrimo kokybė"</string> <string name="bluetooth_select_a2dp_codec_ldac_playback_quality_dialog_title" msgid="3181967377574368400">"Pasirinkite „Bluetooth“ garso LDAC kodeką:\natkūrimo kokybė"</string> <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"Srautinis perdavimas: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string> + <string name="dns_tls" msgid="6773814174391131955">"DNS naudojant TLS"</string> + <string name="dns_tls_summary" msgid="3692494150251071380">"Jei parinktis įgalinta, bandykite pateikti DNS užklausą naudojant TLS 853 prievadu."</string> <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Rodyti belaidžio rodymo sertifikavimo parinktis"</string> <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Padidinti „Wi‑Fi“ įrašymo į žurnalą lygį, rodyti SSID RSSI „Wi-Fi“ rinkiklyje"</string> <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"Jei ši parinktis įgalinta, „Wi‑Fi“ agresyviau perduos duomenų ryšiu į mobiliojo ryšio tinklą, kai „Wi‑Fi“ signalas silpnas"</string> diff --git a/packages/SettingsLib/res/values-lv/strings.xml b/packages/SettingsLib/res/values-lv/strings.xml index a6d308aa6d50..dbe13b5a375f 100644 --- a/packages/SettingsLib/res/values-lv/strings.xml +++ b/packages/SettingsLib/res/values-lv/strings.xml @@ -209,6 +209,8 @@ <string name="bluetooth_select_a2dp_codec_ldac_playback_quality" msgid="3619694372407843405">"Bluetooth audio LDAC kodeks: atskaņošanas kvalitāte"</string> <string name="bluetooth_select_a2dp_codec_ldac_playback_quality_dialog_title" msgid="3181967377574368400">"Atlasīt Bluetooth audio LDAC kodeku:\natskaņošanas kvalitāte"</string> <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"Straumēšana: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string> + <string name="dns_tls" msgid="6773814174391131955">"DNS, izmantojot TLS"</string> + <string name="dns_tls_summary" msgid="3692494150251071380">"Ja opcija ir iespējota, tiek mēģināts pieprasīt DNS, izmantojot TLS portā 853."</string> <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Rādīt bezvadu attēlošanas sertifikācijas iespējas"</string> <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Palieliniet Wi‑Fi reģistrēšanas līmeni; rādīt katram SSID RSSI Wi‑Fi atlasītājā."</string> <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"Ja opcija ir iespējota un Wi‑Fi signāls ir vājš, datu savienojuma pāreja no Wi-Fi uz mobilo tīklu tiks veikta agresīvāk."</string> diff --git a/packages/SettingsLib/res/values-mk/strings.xml b/packages/SettingsLib/res/values-mk/strings.xml index 8882cb75b1c2..0ebb44dc89ae 100644 --- a/packages/SettingsLib/res/values-mk/strings.xml +++ b/packages/SettingsLib/res/values-mk/strings.xml @@ -209,6 +209,8 @@ <string name="bluetooth_select_a2dp_codec_ldac_playback_quality" msgid="3619694372407843405">"Кодек за LDAC-аудио преку Bluetooth: квалитет на репродукција"</string> <string name="bluetooth_select_a2dp_codec_ldac_playback_quality_dialog_title" msgid="3181967377574368400">"Изберете кодек за LDAC-аудио преку Bluetooth:\nКвалитет на репродукција"</string> <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"Емитување: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string> + <string name="dns_tls" msgid="6773814174391131955">"DNS преку TLS"</string> + <string name="dns_tls_summary" msgid="3692494150251071380">"Ако е овозможено, обидете се со DNS преку TLS на портата 853."</string> <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Покажи ги опциите за безжичен приказ на сертификат"</string> <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Зголеми Wi‑Fi ниво на пријавување, прикажи по SSID RSSI во Wi‑Fi бирач"</string> <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"Кога е овозможено, Wi-Fi ќе биде поагресивна при предавање на интернет-врската на мобилната мрежа при слаб сигнал на Wi-Fi"</string> diff --git a/packages/SettingsLib/res/values-ml/strings.xml b/packages/SettingsLib/res/values-ml/strings.xml index 8f711b35139c..a2a10f273092 100644 --- a/packages/SettingsLib/res/values-ml/strings.xml +++ b/packages/SettingsLib/res/values-ml/strings.xml @@ -209,6 +209,8 @@ <string name="bluetooth_select_a2dp_codec_ldac_playback_quality" msgid="3619694372407843405">"Bluetooth ഓഡിയോ LDAC കോഡെക്: പ്ലേബാക്ക് നിലവാരം"</string> <string name="bluetooth_select_a2dp_codec_ldac_playback_quality_dialog_title" msgid="3181967377574368400">"Bluetooth ഓഡിയോ LDAC കോഡെക് തിരഞ്ഞെടുക്കുക:\nപ്ലേബാക്ക് നിലവാരം"</string> <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"സ്ട്രീമിംഗ്: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string> + <string name="dns_tls" msgid="6773814174391131955">"TLS വഴിയുള്ള DNS"</string> + <string name="dns_tls_summary" msgid="3692494150251071380">"പ്രവർത്തനക്ഷമമാക്കിയിട്ടുണ്ടെങ്കിൽ, പോർട്ട് 853-ലെ TLS വഴി DNS-ന് ശ്രമിക്കുക."</string> <string name="wifi_display_certification_summary" msgid="1155182309166746973">"വയർലെസ് ഡിസ്പ്ലേ സർട്ടിഫിക്കേഷനായി ഓപ്ഷനുകൾ ദൃശ്യമാക്കുക"</string> <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"വൈഫൈ പിക്കറിൽ ഓരോ SSID RSSI പ്രകാരം കാണിക്കാൻ വൈഫൈ ലോഗിംഗ് നില വർദ്ധിപ്പിക്കുക"</string> <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"പ്രവർത്തനക്ഷമമായിരിക്കുമ്പോൾ, വൈഫൈ സിഗ്നൽ കുറവായിരിക്കുന്ന സമയത്ത് മൊബൈലിലേക്ക് ഡാറ്റ കണക്ഷൻ വഴി കൈമാറുന്നതിൽ വൈഫൈ കൂടുതൽ സക്രിയമായിരിക്കും"</string> diff --git a/packages/SettingsLib/res/values-mn/strings.xml b/packages/SettingsLib/res/values-mn/strings.xml index 2e1f5e6a791a..0990ecf09234 100644 --- a/packages/SettingsLib/res/values-mn/strings.xml +++ b/packages/SettingsLib/res/values-mn/strings.xml @@ -209,6 +209,8 @@ <string name="bluetooth_select_a2dp_codec_ldac_playback_quality" msgid="3619694372407843405">"Bluetooth Аудио LDAC Кодлогч: Тоглуулагчийн чанар"</string> <string name="bluetooth_select_a2dp_codec_ldac_playback_quality_dialog_title" msgid="3181967377574368400">"Bluetooth Аудио LDAC Кодлогч сонгох:\nТоглуулагчийн чанар"</string> <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"Дамжуулж байна: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string> + <string name="dns_tls" msgid="6773814174391131955">"TLS дээрх DNS"</string> + <string name="dns_tls_summary" msgid="3692494150251071380">"Идэвхжүүлсэн тохиолдолд TLS-р DNS-г 853-р портод оролдоно уу."</string> <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Утасгүй дэлгэцийн сертификатын сонголтыг харуулах"</string> <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Wi‑Fi лог-н түвшинг нэмэгдүүлэх, Wi‑Fi Сонгогч дээрх SSID-д ногдох RSSI-г харуулах"</string> <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"Идэвхжүүлсэн үед Wi‑Fi холболт сул байх үед дата холболтыг мобайлд шилжүүлэхэд илүү идэвхтэй байх болно"</string> diff --git a/packages/SettingsLib/res/values-mr/strings.xml b/packages/SettingsLib/res/values-mr/strings.xml index 63e2e87be097..42ee5817e341 100644 --- a/packages/SettingsLib/res/values-mr/strings.xml +++ b/packages/SettingsLib/res/values-mr/strings.xml @@ -209,6 +209,8 @@ <string name="bluetooth_select_a2dp_codec_ldac_playback_quality" msgid="3619694372407843405">"ब्लूटूथ ऑडिओ LDAC कोडेक: प्लेबॅक गुणवत्ता"</string> <string name="bluetooth_select_a2dp_codec_ldac_playback_quality_dialog_title" msgid="3181967377574368400">"ब्लूटूथ ऑडिओ LDAC कोडेक निवडा:\nप्लेबॅक गुणवत्ता"</string> <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"स्ट्रीमिंग: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string> + <string name="dns_tls" msgid="6773814174391131955">"DNS ओव्हर TLS"</string> + <string name="dns_tls_summary" msgid="3692494150251071380">"सुरू केल्यास, पोर्ट 853 वर DNS ओव्हर TLS करण्याचा प्रयत्न करा."</string> <string name="wifi_display_certification_summary" msgid="1155182309166746973">"वायरलेस डिस्प्ले प्रमाणिकरणाचे पर्याय दाखवा"</string> <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"वाय-फाय लॉगिंग स्तर वाढवा, वाय-फाय सिलेक्टरमध्ये प्रति SSID RSSI दर्शवा"</string> <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"सक्षम केले असताना, वाय-फाय सिग्नल कमी असताना, मोबाइलकडे डेटा कनेक्शन सोपवण्यासाठी वाय-फाय अधिक अॅग्रेसिव्ह असेल."</string> diff --git a/packages/SettingsLib/res/values-ms/strings.xml b/packages/SettingsLib/res/values-ms/strings.xml index 9d81cea3d471..857093ad2d67 100644 --- a/packages/SettingsLib/res/values-ms/strings.xml +++ b/packages/SettingsLib/res/values-ms/strings.xml @@ -209,6 +209,8 @@ <string name="bluetooth_select_a2dp_codec_ldac_playback_quality" msgid="3619694372407843405">"Codec LDAC Audio Bluetooth: Kualiti Main Balik"</string> <string name="bluetooth_select_a2dp_codec_ldac_playback_quality_dialog_title" msgid="3181967377574368400">"Pilih Codec LDAC Audio Bluetooth:\nKualiti Main Balik"</string> <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"Penstriman: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string> + <string name="dns_tls" msgid="6773814174391131955">"DNS di atas TLS"</string> + <string name="dns_tls_summary" msgid="3692494150251071380">"Jika di dayakan, cuba DNS di atas TLS pada port 853."</string> <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Tunjukkan pilihan untuk pensijilan paparan wayarles"</string> <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Tingkatkan tahap pengelogan Wi-Fi, tunjuk setiap SSID RSSI dalam Pemilih Wi-Fi"</string> <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"Apabila didayakan, Wi-Fi akan menjadi lebih agresif dalam menyerahkan sambungan data ke mudah alih, apabila isyarat Wi-Fi rendah"</string> diff --git a/packages/SettingsLib/res/values-my/strings.xml b/packages/SettingsLib/res/values-my/strings.xml index aa241a92696c..7d166b403f3f 100644 --- a/packages/SettingsLib/res/values-my/strings.xml +++ b/packages/SettingsLib/res/values-my/strings.xml @@ -209,6 +209,8 @@ <string name="bluetooth_select_a2dp_codec_ldac_playback_quality" msgid="3619694372407843405">"ဘလူးတုသ်အသံ LDAC ကိုးဒက်ခ်− နားထောင်ရန် အရည်အသွေး"</string> <string name="bluetooth_select_a2dp_codec_ldac_playback_quality_dialog_title" msgid="3181967377574368400">"ဘလူးတုသ်အသံ LDAC ကိုးဒက်ခ်ကို ရွေးပါ−\nနားထောင်ရန် အရည်အသွေး"</string> <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"တိုက်ရိုက်လွှင့်နေသည်− <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string> + <string name="dns_tls" msgid="6773814174391131955">"DNS over TLS"</string> + <string name="dns_tls_summary" msgid="3692494150251071380">"ဖွင့်ထားပါက DNS over TLS ကို ပို့တ် ၈၅၃ တွင် စမ်းကြည့်ပါ။"</string> <string name="wifi_display_certification_summary" msgid="1155182309166746973">"ကြိုးမဲ့ အခင်းအကျင်း အသိအမှတ်ပြုလက်မှတ်အတွက် ရွေးချယ်စရာများပြရန်"</string> <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Wi‑Fi မှတ်တမ်းတင်ခြင်း နှုန်းအားမြင့်ကာ၊ Wi‑Fi ရွေးရာတွင် SSID RSSI ဖြင့်ပြပါ"</string> <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"ဖွင့်ထားပါက Wi‑Fi လွှင့်အား နည်းချိန်တွင် Wi‑Fi မှ မိုဘိုင်းသို့ ဒေတာချိတ်ဆက်မှုကို လွှဲပြောင်းရာ၌ ပိုမိုထိရောက်ပါသည်"</string> diff --git a/packages/SettingsLib/res/values-nb/strings.xml b/packages/SettingsLib/res/values-nb/strings.xml index daf0051d41de..f88df542cb2d 100644 --- a/packages/SettingsLib/res/values-nb/strings.xml +++ b/packages/SettingsLib/res/values-nb/strings.xml @@ -209,6 +209,8 @@ <string name="bluetooth_select_a2dp_codec_ldac_playback_quality" msgid="3619694372407843405">"LDAC-kodek for Bluetooth-lyd: Avspillingskvalitet"</string> <string name="bluetooth_select_a2dp_codec_ldac_playback_quality_dialog_title" msgid="3181967377574368400">"Velg LDAC-kodek for Bluetooth-lyd:\nAvspillingskvalitet"</string> <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"Strømming: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string> + <string name="dns_tls" msgid="6773814174391131955">"DNS over TLS"</string> + <string name="dns_tls_summary" msgid="3692494150251071380">"Hvis det er slått på, forsøk DNS over TLS på port 853."</string> <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Vis alternativer for sertifisering av trådløs skjerm"</string> <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Øk Wi-Fi-loggenivå – vis per SSID RSSI i Wi-Fi-velgeren"</string> <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"Hvis dette slås på, overfører Wi-Fi-nettverket datatilkoblingen til mobil mer aggressivt når Wi-Fi-signalet er svakt"</string> diff --git a/packages/SettingsLib/res/values-ne/strings.xml b/packages/SettingsLib/res/values-ne/strings.xml index 105c44207a0a..a3875a6a2026 100644 --- a/packages/SettingsLib/res/values-ne/strings.xml +++ b/packages/SettingsLib/res/values-ne/strings.xml @@ -209,6 +209,8 @@ <string name="bluetooth_select_a2dp_codec_ldac_playback_quality" msgid="3619694372407843405">"ब्लुटुथ अडियो LDAC कोडेक: प्लेब्याक गुणस्तर"</string> <string name="bluetooth_select_a2dp_codec_ldac_playback_quality_dialog_title" msgid="3181967377574368400">"ब्लुटुथ अडियो LDAC कोडेक चयन गर्नुहोस्:\nप्लेब्याक गुणस्तर"</string> <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"स्ट्रिमिङ: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string> + <string name="dns_tls" msgid="6773814174391131955">"TLS मा DNS को प्रयोग"</string> + <string name="dns_tls_summary" msgid="3692494150251071380">"सक्षम पारिएको खण्डमा पोर्ट ८५३ मा TLS मा DNS प्रयोग गर्ने अनुरोध गर्नुहोस्।"</string> <string name="wifi_display_certification_summary" msgid="1155182309166746973">"ताररहित प्रदर्शन प्रमाणीकरणका लागि विकल्पहरू देखाउनुहोस्"</string> <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Wi-Fi लग स्तर बढाउनुहोस्, Wi-Fi चयनकर्तामा प्रति SSID RSSI देखाइन्छ"</string> <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"सक्षम गरिएको अवस्थामा, Wi-Fi सिग्नल न्यून हुँदा, Wi-Fi ले बढी आक्रामक ढंगले मोबाइलमा डेटा जडान हस्तान्तरण गर्नेछ"</string> diff --git a/packages/SettingsLib/res/values-nl/strings.xml b/packages/SettingsLib/res/values-nl/strings.xml index d8ae320e264b..4d0d7fe8d932 100644 --- a/packages/SettingsLib/res/values-nl/strings.xml +++ b/packages/SettingsLib/res/values-nl/strings.xml @@ -173,8 +173,8 @@ <string name="enable_adb" msgid="7982306934419797485">"USB-foutopsporing"</string> <string name="enable_adb_summary" msgid="4881186971746056635">"Foutopsporingsmodus bij USB-verbinding"</string> <string name="clear_adb_keys" msgid="4038889221503122743">"Autorisatie USB-foutopsporing intrekken"</string> - <string name="bugreport_in_power" msgid="7923901846375587241">"Snelle link naar foutenrapport"</string> - <string name="bugreport_in_power_summary" msgid="1778455732762984579">"Een knop in het voedingsmenu weergeven om een foutenrapport te maken"</string> + <string name="bugreport_in_power" msgid="7923901846375587241">"Snelle link naar bugrapport"</string> + <string name="bugreport_in_power_summary" msgid="1778455732762984579">"Een knop in het voedingsmenu weergeven om een bugrapport te maken"</string> <string name="keep_screen_on" msgid="1146389631208760344">"Stand-by"</string> <string name="keep_screen_on_summary" msgid="2173114350754293009">"Scherm gaat nooit uit tijdens het opladen"</string> <string name="bt_hci_snoop_log" msgid="3340699311158865670">"Snoop-logbestand voor Bluetooth-HCI inschakelen"</string> @@ -209,6 +209,8 @@ <string name="bluetooth_select_a2dp_codec_ldac_playback_quality" msgid="3619694372407843405">"LDAC-codec voor Bluetooth-audio: afspeelkwaliteit"</string> <string name="bluetooth_select_a2dp_codec_ldac_playback_quality_dialog_title" msgid="3181967377574368400">"LDAC-codec voor Bluetooth-audio selecteren:\nafspeelkwaliteit"</string> <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"Streaming: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string> + <string name="dns_tls" msgid="6773814174391131955">"DNS via TLS"</string> + <string name="dns_tls_summary" msgid="3692494150251071380">"Als deze optie is ingeschakeld, wordt geprobeerd om DNS via TLS uit te voeren via poort 853."</string> <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Opties weergeven voor certificering van draadloze weergave"</string> <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Logniveau voor wifi verhogen, weergeven per SSID RSSI in wifi-kiezer"</string> <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"Indien ingeschakeld, is wifi agressiever bij het overgeven van de gegevensverbinding aan mobiel wanneer het wifi-signaal zwak is"</string> diff --git a/packages/SettingsLib/res/values-pa/strings.xml b/packages/SettingsLib/res/values-pa/strings.xml index b54d296325ce..56e361f20e08 100644 --- a/packages/SettingsLib/res/values-pa/strings.xml +++ b/packages/SettingsLib/res/values-pa/strings.xml @@ -209,6 +209,8 @@ <string name="bluetooth_select_a2dp_codec_ldac_playback_quality" msgid="3619694372407843405">"ਬਲੂਟੁੱਥ ਔਡੀਓ LDAC ਕੋਡੇਕ: ਪਲੇਬੈਕ ਗੁਣਵੱਤਾ"</string> <string name="bluetooth_select_a2dp_codec_ldac_playback_quality_dialog_title" msgid="3181967377574368400">"ਬਲੂਟੁੱਥ ਔਡੀਓ LDAC ਕੋਡੇਕ ਚੁਣੋ:\nਪਲੇਬੈਕ ਗੁਣਵੱਤਾ"</string> <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"ਸਟ੍ਰੀਮਿੰਗ: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string> + <string name="dns_tls" msgid="6773814174391131955">"TLS \'ਤੇ DNS"</string> + <string name="dns_tls_summary" msgid="3692494150251071380">"ਚਾਲੂ ਕੀਤੇ ਜਾਣ \'ਤੇ, ਪੋਰਟ 853 \'ਤੇ TLS \'ਤੇ DNS ਵਰਤਣ ਦੀ ਬੇਨਤੀ ਕਰੋ।"</string> <string name="wifi_display_certification_summary" msgid="1155182309166746973">"ਵਾਇਰਲੈੱਸ ਡਿਸਪਲੇ ਪ੍ਰਮਾਣੀਕਰਨ ਲਈ ਚੋਣਾਂ ਪ੍ਰਦਰਸ਼ਿਤ ਕਰੋ"</string> <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"ਵਾਈ‑ਫਾਈ ਲੌਗਿੰਗ ਪੱਧਰ ਵਧਾਓ, ਵਾਈ‑ਫਾਈ Picker ਵਿੱਚ ਪ੍ਰਤੀ SSID RSSI ਦਿਖਾਓ"</string> <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"ਜਦੋਂ ਯੋਗ ਬਣਾਇਆ ਹੋਵੇ, ਤਾਂ ਵਾਈ‑ਫਾਈ ਸਿਗਨਲ ਘੱਟ ਹੋਣ \'ਤੇ ਵਾਈ‑ਫਾਈ ਡਾਟਾ ਕਨੈਕਸ਼ਨ ਮੋਬਾਈਲ ਨੂੰ ਹੈਂਡ ਓਵਰ ਕਰਨ ਵਿੱਚ ਵੱਧ ਆਕਰਮਣਸ਼ੀਲ ਹੋਵੇਗਾ।"</string> diff --git a/packages/SettingsLib/res/values-pl/strings.xml b/packages/SettingsLib/res/values-pl/strings.xml index 481027977d8e..51c8505bf144 100644 --- a/packages/SettingsLib/res/values-pl/strings.xml +++ b/packages/SettingsLib/res/values-pl/strings.xml @@ -209,6 +209,8 @@ <string name="bluetooth_select_a2dp_codec_ldac_playback_quality" msgid="3619694372407843405">"Kodek dźwięku Bluetooth LDAC: jakość odtwarzania"</string> <string name="bluetooth_select_a2dp_codec_ldac_playback_quality_dialog_title" msgid="3181967377574368400">"Wybierz kodek dźwięku Bluetooth LDAC:\njakość odtwarzania"</string> <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"Strumieniowe przesyłanie danych: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string> + <string name="dns_tls" msgid="6773814174391131955">"DNS przez TLS"</string> + <string name="dns_tls_summary" msgid="3692494150251071380">"Po włączeniu wypróbuj komunikację DNS przez TLS przez port 853."</string> <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Pokaż opcje certyfikacji wyświetlacza bezprzewodowego"</string> <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Zwiększ poziom rejestrowania Wi‑Fi, pokazuj według RSSI SSID w selektorze Wi‑Fi"</string> <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"Po włączeniu połączenie danych będzie bardziej agresywnie przełączać się z Wi-Fi na sieć komórkową przy słabym sygnale Wi-Fi"</string> diff --git a/packages/SettingsLib/res/values-pt-rBR/strings.xml b/packages/SettingsLib/res/values-pt-rBR/strings.xml index 7a080a27ef47..6b2a5ca04b0a 100644 --- a/packages/SettingsLib/res/values-pt-rBR/strings.xml +++ b/packages/SettingsLib/res/values-pt-rBR/strings.xml @@ -209,6 +209,8 @@ <string name="bluetooth_select_a2dp_codec_ldac_playback_quality" msgid="3619694372407843405">"Codec de áudio Bluetooth LDAC: qualidade de reprodução"</string> <string name="bluetooth_select_a2dp_codec_ldac_playback_quality_dialog_title" msgid="3181967377574368400">"Selecionar codec de áudio Bluetooth LDAC:\nqualidade de reprodução"</string> <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"Streaming: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string> + <string name="dns_tls" msgid="6773814174391131955">"DNS por TLS"</string> + <string name="dns_tls_summary" msgid="3692494150251071380">"Se essa opção estiver ativada, tente o DNS por TLS na porta 853."</string> <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Mostrar opções de certificação de Display sem fio"</string> <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Aumentar o nível de registro do Wi-Fi; mostrar conforme o RSSI de SSID na Seleção de Wi-Fi"</string> <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"Quando ativada, o Wi-Fi será mais agressivo em passar a conexão de dados para móvel, quando o sinal de Wi-Fi estiver fraco"</string> diff --git a/packages/SettingsLib/res/values-pt-rPT/strings.xml b/packages/SettingsLib/res/values-pt-rPT/strings.xml index 9229e13e9d34..1a6f0c678001 100644 --- a/packages/SettingsLib/res/values-pt-rPT/strings.xml +++ b/packages/SettingsLib/res/values-pt-rPT/strings.xml @@ -209,6 +209,8 @@ <string name="bluetooth_select_a2dp_codec_ldac_playback_quality" msgid="3619694372407843405">"Codec LDAC de áudio Bluetooth: qualidade de reprodução"</string> <string name="bluetooth_select_a2dp_codec_ldac_playback_quality_dialog_title" msgid="3181967377574368400">"Selecionar codec LDAC de áudio Bluetooth:\nQualidade de reprodução"</string> <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"Transmissão em fluxo contínuo: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string> + <string name="dns_tls" msgid="6773814174391131955">"DNS através de TLS"</string> + <string name="dns_tls_summary" msgid="3692494150251071380">"Se a opção estiver ativada, tente efetuar DNS através de TLS na porta 853."</string> <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Mostrar opções da certificação de display sem fios"</string> <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Aumentar o nível de reg. de Wi-Fi, mostrar por RSSI de SSID no Selec. de Wi-Fi"</string> <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"Se estiver ativado, o Wi-Fi será mais agressivo ao transmitir a lig. de dados para a rede móvel quando o sinal Wi-Fi estiver fraco"</string> @@ -357,9 +359,9 @@ <string name="battery_info_status_discharging" msgid="310932812698268588">"Não está a carregar"</string> <string name="battery_info_status_not_charging" msgid="8523453668342598579">"Ligada à corrente, não é possível carregar neste momento"</string> <string name="battery_info_status_full" msgid="2824614753861462808">"Completo"</string> - <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Controlado pelo administrador"</string> - <string name="enabled_by_admin" msgid="5302986023578399263">"Ativada pelo administrador"</string> - <string name="disabled_by_admin" msgid="8505398946020816620">"Desativada pelo administrador"</string> + <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Controlado pelo gestor"</string> + <string name="enabled_by_admin" msgid="5302986023578399263">"Ativada pelo gestor"</string> + <string name="disabled_by_admin" msgid="8505398946020816620">"Desativada pelo gestor"</string> <string name="disabled" msgid="9206776641295849915">"Desativada"</string> <string name="external_source_trusted" msgid="2707996266575928037">"Autorizada"</string> <string name="external_source_untrusted" msgid="2677442511837596726">"Não autorizada"</string> diff --git a/packages/SettingsLib/res/values-pt/strings.xml b/packages/SettingsLib/res/values-pt/strings.xml index 7a080a27ef47..6b2a5ca04b0a 100644 --- a/packages/SettingsLib/res/values-pt/strings.xml +++ b/packages/SettingsLib/res/values-pt/strings.xml @@ -209,6 +209,8 @@ <string name="bluetooth_select_a2dp_codec_ldac_playback_quality" msgid="3619694372407843405">"Codec de áudio Bluetooth LDAC: qualidade de reprodução"</string> <string name="bluetooth_select_a2dp_codec_ldac_playback_quality_dialog_title" msgid="3181967377574368400">"Selecionar codec de áudio Bluetooth LDAC:\nqualidade de reprodução"</string> <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"Streaming: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string> + <string name="dns_tls" msgid="6773814174391131955">"DNS por TLS"</string> + <string name="dns_tls_summary" msgid="3692494150251071380">"Se essa opção estiver ativada, tente o DNS por TLS na porta 853."</string> <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Mostrar opções de certificação de Display sem fio"</string> <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Aumentar o nível de registro do Wi-Fi; mostrar conforme o RSSI de SSID na Seleção de Wi-Fi"</string> <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"Quando ativada, o Wi-Fi será mais agressivo em passar a conexão de dados para móvel, quando o sinal de Wi-Fi estiver fraco"</string> diff --git a/packages/SettingsLib/res/values-ro/strings.xml b/packages/SettingsLib/res/values-ro/strings.xml index df34d5832874..7be64e41f302 100644 --- a/packages/SettingsLib/res/values-ro/strings.xml +++ b/packages/SettingsLib/res/values-ro/strings.xml @@ -209,6 +209,8 @@ <string name="bluetooth_select_a2dp_codec_ldac_playback_quality" msgid="3619694372407843405">"Codecul LDAC audio pentru Bluetooth: calitatea redării"</string> <string name="bluetooth_select_a2dp_codec_ldac_playback_quality_dialog_title" msgid="3181967377574368400">"Selectați codecul LDAC audio pentru Bluetooth:\ncalitatea redării"</string> <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"Transmitere în flux: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string> + <string name="dns_tls" msgid="6773814174391131955">"DNS prin TLS"</string> + <string name="dns_tls_summary" msgid="3692494150251071380">"Dacă opțiunea este activată, încercați DNS prin TLS pe portul 853."</string> <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Afișați opțiunile pentru certificarea Ecran wireless"</string> <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Măriți niv. de înr. prin Wi‑Fi, afișați în fcț. de SSID RSSI în Selectorul Wi‑Fi"</string> <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"Când este activată, Wi-Fi va fi mai agresivă la predarea conexiunii de date către rețeaua mobilă când semnalul Wi-Fi este slab"</string> diff --git a/packages/SettingsLib/res/values-ru/strings.xml b/packages/SettingsLib/res/values-ru/strings.xml index 3752cb37d585..725665dcc09b 100644 --- a/packages/SettingsLib/res/values-ru/strings.xml +++ b/packages/SettingsLib/res/values-ru/strings.xml @@ -209,6 +209,8 @@ <string name="bluetooth_select_a2dp_codec_ldac_playback_quality" msgid="3619694372407843405">"Аудиокодек LDAC для Bluetooth: качество воспроизведения"</string> <string name="bluetooth_select_a2dp_codec_ldac_playback_quality_dialog_title" msgid="3181967377574368400">"Аудиокодек LDAC для Bluetooth:\nкачество воспроизведения"</string> <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"Потоковая передача: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string> + <string name="dns_tls" msgid="6773814174391131955">"DNS по TLS"</string> + <string name="dns_tls_summary" msgid="3692494150251071380">"Если функция включена, соединение с DNS будет выполняться по TLS через порт 853."</string> <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Показывать параметры сертификации беспроводных мониторов"</string> <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"При выборе Wi‑Fi указывать в журнале RSSI для каждого SSID"</string> <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"Принудительно переключаться на мобильную сеть, если сигнал Wi-Fi слабый"</string> diff --git a/packages/SettingsLib/res/values-si/strings.xml b/packages/SettingsLib/res/values-si/strings.xml index 36fd95266d42..db01eea5c7a5 100644 --- a/packages/SettingsLib/res/values-si/strings.xml +++ b/packages/SettingsLib/res/values-si/strings.xml @@ -209,6 +209,8 @@ <string name="bluetooth_select_a2dp_codec_ldac_playback_quality" msgid="3619694372407843405">"බ්ලූටූත් ශ්රව්ය LDAC පසුධාවන ගුණත්වය"</string> <string name="bluetooth_select_a2dp_codec_ldac_playback_quality_dialog_title" msgid="3181967377574368400">"බ්ලූටූත් ශ්රව්ය LDAC කොඩෙක් තෝරන්න:\nපසුධාවන ගුණත්වය"</string> <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"ප්රවාහ කරමින්: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string> + <string name="dns_tls" msgid="6773814174391131955">"TLS හරහා DNS"</string> + <string name="dns_tls_summary" msgid="3692494150251071380">"සබල නම්, 853 තොට මත TLS හරහා DNS උත්සාහ කරන්න."</string> <string name="wifi_display_certification_summary" msgid="1155182309166746973">"නොරැහැන් සංදර්ශක සහතිකය සඳහා විකල්ප පෙන්වන්න"</string> <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Wi‑Fi ලොග් මට්ටම වැඩි කරන්න, Wi‑Fi තෝරනයෙහි SSID RSSI අනුව පෙන්වන්න"</string> <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"සබල විට Wi‑Fi සිග්නලය අඩු විට Wi‑Fi දත්ත සම්බන්ධතාවය ජංගම වෙත භාර දීමට වඩා ආක්රමණික වේ"</string> diff --git a/packages/SettingsLib/res/values-sk/strings.xml b/packages/SettingsLib/res/values-sk/strings.xml index 2eea457d3b34..fc7e1c3154a2 100644 --- a/packages/SettingsLib/res/values-sk/strings.xml +++ b/packages/SettingsLib/res/values-sk/strings.xml @@ -209,6 +209,8 @@ <string name="bluetooth_select_a2dp_codec_ldac_playback_quality" msgid="3619694372407843405">"Kodek LDAC Bluetooth Audio: Kvalita prehrávania"</string> <string name="bluetooth_select_a2dp_codec_ldac_playback_quality_dialog_title" msgid="3181967377574368400">"Vybrať kodek LDAC Bluetooth Audio:\nKvalita prehrávania"</string> <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"Streamovanie: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string> + <string name="dns_tls" msgid="6773814174391131955">"DNS cez TLS"</string> + <string name="dns_tls_summary" msgid="3692494150251071380">"Ak túto možnosť aktivujete, zariadenie sa bude pripájať k serverom DNS pomocou protokolu TLS na porte 853."</string> <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Zobraziť možnosti certifikácie bezdrôtového zobrazenia"</string> <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Zvýšiť úroveň denníkov Wi‑Fi, zobrazovať podľa SSID RSSI pri výbere siete Wi‑Fi"</string> <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"Keď túto možnosť zapnete, Wi‑Fi bude agresívnejšie odovzdávať dátové pripojenie na mobilnú sieť vtedy, keď bude slabý signál Wi‑Fi"</string> diff --git a/packages/SettingsLib/res/values-sl/strings.xml b/packages/SettingsLib/res/values-sl/strings.xml index e7e621207920..07475d39e058 100644 --- a/packages/SettingsLib/res/values-sl/strings.xml +++ b/packages/SettingsLib/res/values-sl/strings.xml @@ -209,6 +209,8 @@ <string name="bluetooth_select_a2dp_codec_ldac_playback_quality" msgid="3619694372407843405">"Zvočni kodek LDAC za Bluetooth: kakovost predvajanja"</string> <string name="bluetooth_select_a2dp_codec_ldac_playback_quality_dialog_title" msgid="3181967377574368400">"Izberi zvočni kodek LDAC za Bluetooth:\nKakovost predvajanja"</string> <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"Pretočno predvajanje: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string> + <string name="dns_tls" msgid="6773814174391131955">"DNS s šifriranjem TLS"</string> + <string name="dns_tls_summary" msgid="3692494150251071380">"Če je ta možnost omogočena, poskusi vzpostaviti povezavo DNS s šifriranjem TLS na vratih 853."</string> <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Pokaži možnosti za potrdilo brezžičnega zaslona"</string> <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Povečaj raven zapis. dnev. za Wi-Fi; v izbir. Wi‑Fi-ja pokaži glede na SSID RSSI"</string> <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"Če je ta možnost omogočena, Wi-Fi odločneje preda podatkovno povezavo mobilnemu omrežju, ko je signal Wi-Fi šibek."</string> diff --git a/packages/SettingsLib/res/values-sq/strings.xml b/packages/SettingsLib/res/values-sq/strings.xml index f557d815eab6..4fcfc5ce12bf 100644 --- a/packages/SettingsLib/res/values-sq/strings.xml +++ b/packages/SettingsLib/res/values-sq/strings.xml @@ -209,6 +209,8 @@ <string name="bluetooth_select_a2dp_codec_ldac_playback_quality" msgid="3619694372407843405">"Kodeku LDAC i audios së Bluetooth-it: Cilësia e luajtjes"</string> <string name="bluetooth_select_a2dp_codec_ldac_playback_quality_dialog_title" msgid="3181967377574368400">"Zgjidh kodekun LDAC të audios së Bluetooth-it:\nCilësia e luajtjes"</string> <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"Transmetimi: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string> + <string name="dns_tls" msgid="6773814174391131955">"DNS nëpërmjet protokollit TLS"</string> + <string name="dns_tls_summary" msgid="3692494150251071380">"Nëse është aktivizuar, provo DNS-në nëpërmjet protokollit TLS në portën 853."</string> <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Shfaq opsionet për certifikimin e ekranit valor"</string> <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Rrit nivelin regjistrues të Wi‑Fi duke shfaqur SSID RSSI-në te Zgjedhësi i Wi‑Fi"</string> <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"Kur ky funksion aktivizohet, Wi‑Fi bëhet më agresiv në kalimin e lidhjes së të dhënave te rrjeti celular, në rastet kur sinjali Wi‑Fi është i dobët"</string> diff --git a/packages/SettingsLib/res/values-sr/strings.xml b/packages/SettingsLib/res/values-sr/strings.xml index 1c0fb24dec82..e591aa1f6784 100644 --- a/packages/SettingsLib/res/values-sr/strings.xml +++ b/packages/SettingsLib/res/values-sr/strings.xml @@ -209,6 +209,8 @@ <string name="bluetooth_select_a2dp_codec_ldac_playback_quality" msgid="3619694372407843405">"Bluetooth аудио кодек LDAC: квалитет репродукције"</string> <string name="bluetooth_select_a2dp_codec_ldac_playback_quality_dialog_title" msgid="3181967377574368400">"Изаберите Bluetooth аудио кодек LDAC:\nквалитет репродукције"</string> <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"Стримовање: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string> + <string name="dns_tls" msgid="6773814174391131955">"DNS преко TLS-а"</string> + <string name="dns_tls_summary" msgid="3692494150251071380">"Ако је омогућено, пробајte DNS преко TLS-а на порту 853."</string> <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Приказ опција за сертификацију бежичног екрана"</string> <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Повећава ниво евидентирања за Wi‑Fi. Приказ по SSID RSSI-у у бирачу Wi‑Fi мреже"</string> <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"Кад се омогући, Wi‑Fi ће бити агресивнији при пребацивању мреже за пренос података на мобилну ако је Wi‑Fi сигнал слаб"</string> diff --git a/packages/SettingsLib/res/values-sv/strings.xml b/packages/SettingsLib/res/values-sv/strings.xml index c233bec4e77c..cb86b5b4e74d 100644 --- a/packages/SettingsLib/res/values-sv/strings.xml +++ b/packages/SettingsLib/res/values-sv/strings.xml @@ -209,6 +209,8 @@ <string name="bluetooth_select_a2dp_codec_ldac_playback_quality" msgid="3619694372407843405">"Bluetooth-ljud via LDAC-kodek: uppspelningskvalitet"</string> <string name="bluetooth_select_a2dp_codec_ldac_playback_quality_dialog_title" msgid="3181967377574368400">"Välj Bluetooth-ljud via LDAC-kodek:\nuppspelningskvalitet"</string> <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"Streaming: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string> + <string name="dns_tls" msgid="6773814174391131955">"DNS via TLS"</string> + <string name="dns_tls_summary" msgid="3692494150251071380">"Om inställningen är aktiverad görs försök att använda DNS via TLS på port 853."</string> <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Visa certifieringsalternativ för Wi-Fi-skärmdelning"</string> <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Öka loggningsnivån för Wi-Fi, visa per SSID RSSI i Wi‑Fi Picker"</string> <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"När funktionen har aktiverats kommer dataanslutningen lämnas över från Wi-Fi till mobilen på ett aggressivare sätt när Wi-Fi-signalen är svag"</string> diff --git a/packages/SettingsLib/res/values-sw/strings.xml b/packages/SettingsLib/res/values-sw/strings.xml index 700153b257d6..756254b98c1c 100644 --- a/packages/SettingsLib/res/values-sw/strings.xml +++ b/packages/SettingsLib/res/values-sw/strings.xml @@ -209,6 +209,8 @@ <string name="bluetooth_select_a2dp_codec_ldac_playback_quality" msgid="3619694372407843405">"Kodeki ya LDAC ya Sauti ya Bluetooth: Ubora wa Kucheza"</string> <string name="bluetooth_select_a2dp_codec_ldac_playback_quality_dialog_title" msgid="3181967377574368400">"Chagua Kodeki ya LDAC ya Sauti ya Bluetooth:\nUbora wa Kucheza"</string> <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"Kutiririsha: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string> + <string name="dns_tls" msgid="6773814174391131955">"DNS kupitia TLS"</string> + <string name="dns_tls_summary" msgid="3692494150251071380">"Ukiwasha mipangilio hii, jaribu kutumia DNS kupitia TLS kwenye mlango wa 853."</string> <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Onyesha chaguo za cheti cha kuonyesha pasiwaya"</string> <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Ongeza hatua ya uwekaji kumbukumbu ya Wi-Fi, onyesha kwa kila SSID RSSI kwenye Kichukuzi cha Wi-Fi"</string> <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"Ikiwashwa, Wi-Fi itakabidhi kwa hima muunganisho wa data kwa mtandao wa simu, wakati mtandao wa Wi-Fi si thabiti"</string> diff --git a/packages/SettingsLib/res/values-ta/strings.xml b/packages/SettingsLib/res/values-ta/strings.xml index 5ea41c42402f..e31e3e0a4377 100644 --- a/packages/SettingsLib/res/values-ta/strings.xml +++ b/packages/SettingsLib/res/values-ta/strings.xml @@ -209,6 +209,8 @@ <string name="bluetooth_select_a2dp_codec_ldac_playback_quality" msgid="3619694372407843405">"புளூடூத் ஆடியோ LDAC கோடெக்: வீடியோவின் தரம்"</string> <string name="bluetooth_select_a2dp_codec_ldac_playback_quality_dialog_title" msgid="3181967377574368400">"புளூடூத் ஆடியோ LDAC கோடெக்கைத் தேர்ந்தெடுக்கவும்:\nவீடியோவின் தரம்"</string> <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"ஸ்ட்ரீமிங்: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string> + <string name="dns_tls" msgid="6773814174391131955">"TLS வழியாக DNS"</string> + <string name="dns_tls_summary" msgid="3692494150251071380">"இயக்கப்பட்டிருந்தால், போர்ட் 853 இல் TLS வழியாக DNSஐ முயலவும்."</string> <string name="wifi_display_certification_summary" msgid="1155182309166746973">"வயர்லெஸ் காட்சி சான்றுக்கான விருப்பங்களைக் காட்டு"</string> <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Wifi நுழைவு அளவை அதிகரித்து, வைஃபை தேர்வியில் ஒவ்வொன்றிற்கும் SSID RSSI ஐ காட்டுக"</string> <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"இயக்கப்பட்டதும், வைஃபை சிக்னல் குறையும் போது, வைஃபை முழுமையாக ஒத்துழைக்காமல் இருந்தால் மொபைல் தரவிற்கு மாறும்"</string> diff --git a/packages/SettingsLib/res/values-te/strings.xml b/packages/SettingsLib/res/values-te/strings.xml index 7daa89e45d57..0c28ef218b8d 100644 --- a/packages/SettingsLib/res/values-te/strings.xml +++ b/packages/SettingsLib/res/values-te/strings.xml @@ -209,6 +209,8 @@ <string name="bluetooth_select_a2dp_codec_ldac_playback_quality" msgid="3619694372407843405">"బ్లూటూత్ ఆడియో LDAC కోడెక్: ప్లేబ్యాక్ నాణ్యత"</string> <string name="bluetooth_select_a2dp_codec_ldac_playback_quality_dialog_title" msgid="3181967377574368400">"బ్లూటూత్ ఆడియో LDAC కోడెక్ని ఎంచుకోండి:\nప్లేబ్యాక్ నాణ్యత"</string> <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"ప్రసారం చేస్తోంది: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string> + <string name="dns_tls" msgid="6773814174391131955">"TLSపై DNS"</string> + <string name="dns_tls_summary" msgid="3692494150251071380">"ప్రారంభించబడితే, పోర్ట్ 853లో TLSపై DNSని ప్రయత్నించండి."</string> <string name="wifi_display_certification_summary" msgid="1155182309166746973">"వైర్లెస్ ప్రదర్శన సర్టిఫికెట్ కోసం ఎంపికలను చూపు"</string> <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Wi‑Fi ఎంపికలో SSID RSSI ప్రకారం చూపబడే Wi‑Fi లాగింగ్ స్థాయిని పెంచండి"</string> <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"ప్రారంభించబడినప్పుడు, Wi‑Fi సిగ్నల్ బలహీనంగా ఉంటే డేటా కనెక్షన్ను మొబైల్కి మార్చేలా Wi‑Fi చురుగ్గా వ్యవహరిస్తుంది"</string> diff --git a/packages/SettingsLib/res/values-th/strings.xml b/packages/SettingsLib/res/values-th/strings.xml index 37fba9907189..5ff39b6bcf97 100644 --- a/packages/SettingsLib/res/values-th/strings.xml +++ b/packages/SettingsLib/res/values-th/strings.xml @@ -209,6 +209,8 @@ <string name="bluetooth_select_a2dp_codec_ldac_playback_quality" msgid="3619694372407843405">"ตัวแปลงรหัสเสียงบลูทูธที่ใช้ LDAC: คุณภาพการเล่น"</string> <string name="bluetooth_select_a2dp_codec_ldac_playback_quality_dialog_title" msgid="3181967377574368400">"เลือกตัวแปลงรหัสเสียงบลูทูธที่ใช้ LDAC:\nคุณภาพการเล่น"</string> <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"สตรีมมิง: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string> + <string name="dns_tls" msgid="6773814174391131955">"DNS ผ่าน TLS"</string> + <string name="dns_tls_summary" msgid="3692494150251071380">"หากเปิดใช้แล้ว ให้ลองใช้ DNS ผ่าน TLS บนพอร์ต 853"</string> <string name="wifi_display_certification_summary" msgid="1155182309166746973">"แสดงตัวเลือกสำหรับการรับรองการแสดงผล แบบไร้สาย"</string> <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"เพิ่มระดับการบันทึก Wi‑Fi แสดงต่อ SSID RSSI ในตัวเลือก Wi‑Fi"</string> <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"เมื่อเปิดใช้แล้ว Wi-Fi จะส่งผ่านการเชื่อมต่อข้อมูลไปยังเครือข่ายมือถือเมื่อสัญญาณ Wi-Fi อ่อน"</string> diff --git a/packages/SettingsLib/res/values-tl/strings.xml b/packages/SettingsLib/res/values-tl/strings.xml index 25227a3bb11f..6021d793d01c 100644 --- a/packages/SettingsLib/res/values-tl/strings.xml +++ b/packages/SettingsLib/res/values-tl/strings.xml @@ -209,6 +209,8 @@ <string name="bluetooth_select_a2dp_codec_ldac_playback_quality" msgid="3619694372407843405">"Audio LDAC Codec ng Bluetooth: Kalidad ng Pag-playback"</string> <string name="bluetooth_select_a2dp_codec_ldac_playback_quality_dialog_title" msgid="3181967377574368400">"Piliin ang Audio LDAC Codec ng Bluetooth:\nKalidad ng Pag-playback"</string> <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"Streaming: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string> + <string name="dns_tls" msgid="6773814174391131955">"DNS sa pamamagitan ng TLS"</string> + <string name="dns_tls_summary" msgid="3692494150251071380">"Kung naka-enable, subukan ang DNS sa pamamagitan ng TLS sa port 853."</string> <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Ipakita ang mga opsyon para sa certification ng wireless display"</string> <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Pataasin ang antas ng Wi‑Fi logging, ipakita sa bawat SSID RSSI sa Wi‑Fi Picker"</string> <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"Kapag na-enable, magiging mas agresibo ang Wi‑Fi sa paglipat sa koneksyon ng mobile data kapag mahina ang signal ng Wi‑Fi"</string> diff --git a/packages/SettingsLib/res/values-tr/strings.xml b/packages/SettingsLib/res/values-tr/strings.xml index 893d8b33a629..367f84bac05a 100644 --- a/packages/SettingsLib/res/values-tr/strings.xml +++ b/packages/SettingsLib/res/values-tr/strings.xml @@ -209,6 +209,8 @@ <string name="bluetooth_select_a2dp_codec_ldac_playback_quality" msgid="3619694372407843405">"Bluetooth Ses LDAC Codec\'i: Oynatma Kalitesi"</string> <string name="bluetooth_select_a2dp_codec_ldac_playback_quality_dialog_title" msgid="3181967377574368400">"Bluetooth Ses LDAC Codec\'ini Seçin:\nOynatma Kalitesi"</string> <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"Akış: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string> + <string name="dns_tls" msgid="6773814174391131955">"TLS üzerinden DNS"</string> + <string name="dns_tls_summary" msgid="3692494150251071380">"Etkinleştirildiyse, 853 numaralı bağlantı noktasında TLS üzerinden DNS\'yi deneyin."</string> <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Kablosuz ekran sertifikası seçeneklerini göster"</string> <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Kablosuz günlük kaydı seviyesini artır. Kablosuz Seçici\'de her bir SSID RSSI için göster."</string> <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"Etkinleştirildiğinde, kablosuz ağ sinyali zayıfken veri bağlantısının mobil ağa geçirilmesinde daha agresif olunur"</string> diff --git a/packages/SettingsLib/res/values-uk/strings.xml b/packages/SettingsLib/res/values-uk/strings.xml index f3ed643c8039..2693002ab0a5 100644 --- a/packages/SettingsLib/res/values-uk/strings.xml +++ b/packages/SettingsLib/res/values-uk/strings.xml @@ -209,6 +209,8 @@ <string name="bluetooth_select_a2dp_codec_ldac_playback_quality" msgid="3619694372407843405">"Кодек для аудіо Bluetooth LDAC: якість відтворення"</string> <string name="bluetooth_select_a2dp_codec_ldac_playback_quality_dialog_title" msgid="3181967377574368400">"Вибрати кодек для аудіо Bluetooth LDAC:\nякість відтворення"</string> <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"Трансляція: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string> + <string name="dns_tls" msgid="6773814174391131955">"DNS через протокол TLS"</string> + <string name="dns_tls_summary" msgid="3692494150251071380">"Якщо ввімкнено, спробуйте DNS через протокол TLS у порту 853."</string> <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Показати параметри сертифікації бездротового екрана"</string> <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Показувати в журналі RSSI для кожного SSID під час вибору Wi-Fi"</string> <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"Примусово перемикатися на мобільну мережу, коли сигнал Wi-Fi слабкий"</string> diff --git a/packages/SettingsLib/res/values-ur/strings.xml b/packages/SettingsLib/res/values-ur/strings.xml index 550280dfefac..782bb6fc4230 100644 --- a/packages/SettingsLib/res/values-ur/strings.xml +++ b/packages/SettingsLib/res/values-ur/strings.xml @@ -209,6 +209,8 @@ <string name="bluetooth_select_a2dp_codec_ldac_playback_quality" msgid="3619694372407843405">"بلوٹوتھ آڈیو LDAC کوڈیک: پلے بیک کا معیار"</string> <string name="bluetooth_select_a2dp_codec_ldac_playback_quality_dialog_title" msgid="3181967377574368400">"بلوٹوتھ آڈیو LDAC کوڈیک منتخب کریں:\nپلے بیک کا معیار"</string> <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"سلسلہ بندی: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string> + <string name="dns_tls" msgid="6773814174391131955">"TLS پر DNS"</string> + <string name="dns_tls_summary" msgid="3692494150251071380">"فعال ہونے پر پورٹ 853 پر TLS پر DNS استعمال کرنے کی کوشش کریں۔"</string> <string name="wifi_display_certification_summary" msgid="1155182309166746973">"وائرلیس ڈسپلے سرٹیفیکیشن کیلئے اختیارات دکھائیں"</string> <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Wi‑Fi لاگنگ لیول میں اضافہ کریں، Wi‑Fi منتخب کنندہ میں فی SSID RSSI دکھائیں"</string> <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"فعال کئے جانے پر، جب Wi‑Fi سگنل کمزور ہوگا، تو Wi‑Fi موبائل پر ڈیٹا کنکشن بھیجنے کیلئے مزید جارحانہ کارروائی کرے گا"</string> diff --git a/packages/SettingsLib/res/values-uz/strings.xml b/packages/SettingsLib/res/values-uz/strings.xml index 055613b91a50..95e4455e2d1d 100644 --- a/packages/SettingsLib/res/values-uz/strings.xml +++ b/packages/SettingsLib/res/values-uz/strings.xml @@ -209,6 +209,8 @@ <string name="bluetooth_select_a2dp_codec_ldac_playback_quality" msgid="3619694372407843405">"LDAC audiokodeki bilan ijro etish sifati (Bluetooth orqali)"</string> <string name="bluetooth_select_a2dp_codec_ldac_playback_quality_dialog_title" msgid="3181967377574368400">"LDAC audiokodeki:\nijro sifati"</string> <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"Translatsiya: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string> + <string name="dns_tls" msgid="6773814174391131955">"TLS orqali DNS"</string> + <string name="dns_tls_summary" msgid="3692494150251071380">"Yoqilgan bo‘lsa, TLS orqali DNS serverini 853-port yordamida sozlab ko‘ring"</string> <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Simsiz monitorlarni sertifikatlash parametrini ko‘rsatish"</string> <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Wi-Fi ulanishini tanlashda har bir SSID uchun jurnalda ko‘rsatilsin"</string> <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"Agar ushbu funksiya yoqilsa, Wi-Fi signali past bo‘lganda internetga ulanish majburiy ravishda mobil internetga o‘tkaziladi"</string> diff --git a/packages/SettingsLib/res/values-vi/strings.xml b/packages/SettingsLib/res/values-vi/strings.xml index bc5df8f84d15..8beb8199b345 100644 --- a/packages/SettingsLib/res/values-vi/strings.xml +++ b/packages/SettingsLib/res/values-vi/strings.xml @@ -209,6 +209,8 @@ <string name="bluetooth_select_a2dp_codec_ldac_playback_quality" msgid="3619694372407843405">"Codec LDAC âm thanh Bluetooth: Chất lượng phát lại"</string> <string name="bluetooth_select_a2dp_codec_ldac_playback_quality_dialog_title" msgid="3181967377574368400">"Chọn Codec LDAC âm thanh Bluetooth:\nChất lượng phát lại"</string> <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"Truyền trực tuyến: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string> + <string name="dns_tls" msgid="6773814174391131955">"DNS qua TLS"</string> + <string name="dns_tls_summary" msgid="3692494150251071380">"Nếu được bật, hãy thử DNS qua TLS trên cổng 853."</string> <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Hiển thị tùy chọn chứng nhận hiển thị không dây"</string> <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Tăng mức ghi nhật ký Wi‑Fi, hiển thị mỗi SSID RSSI trong bộ chọn Wi‑Fi"</string> <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"Khi được bật, Wi‑Fi sẽ tích cực hơn trong việc chuyển vùng kết nối dữ liệu sang mạng di động khi tín hiệu Wi‑Fi yếu"</string> diff --git a/packages/SettingsLib/res/values-zh-rCN/arrays.xml b/packages/SettingsLib/res/values-zh-rCN/arrays.xml index 3a80e7b6262f..dc24afdd9952 100644 --- a/packages/SettingsLib/res/values-zh-rCN/arrays.xml +++ b/packages/SettingsLib/res/values-zh-rCN/arrays.xml @@ -24,7 +24,7 @@ <item msgid="1922181315419294640"></item> <item msgid="8934131797783724664">"正在扫描..."</item> <item msgid="8513729475867537913">"正在连接..."</item> - <item msgid="515055375277271756">"正在进行身份验证..."</item> + <item msgid="515055375277271756">"正在验证身份…"</item> <item msgid="1943354004029184381">"正在获取IP地址..."</item> <item msgid="4221763391123233270">"已连接"</item> <item msgid="624838831631122137">"已暂停"</item> diff --git a/packages/SettingsLib/res/values-zh-rCN/strings.xml b/packages/SettingsLib/res/values-zh-rCN/strings.xml index 4bbc9764506b..094bb906a3c0 100644 --- a/packages/SettingsLib/res/values-zh-rCN/strings.xml +++ b/packages/SettingsLib/res/values-zh-rCN/strings.xml @@ -209,6 +209,8 @@ <string name="bluetooth_select_a2dp_codec_ldac_playback_quality" msgid="3619694372407843405">"蓝牙音频 LDAC 编解码器:播放质量"</string> <string name="bluetooth_select_a2dp_codec_ldac_playback_quality_dialog_title" msgid="3181967377574368400">"选择蓝牙音频 LDAC 编解码器:\n播放质量"</string> <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"正在流式传输:<xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string> + <string name="dns_tls" msgid="6773814174391131955">"通过传输层安全协议 (TLS) 执行 DNS"</string> + <string name="dns_tls_summary" msgid="3692494150251071380">"如果启用,即可在端口 853 上尝试“通过传输层安全协议 (TLS) 执行 DNS”。"</string> <string name="wifi_display_certification_summary" msgid="1155182309166746973">"显示无线显示认证选项"</string> <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"提升WLAN日志记录级别(在WLAN选择器中显示每个SSID的RSSI)"</string> <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"开启此设置后,系统会在 WLAN 信号较弱时,主动将网络模式从 WLAN 网络切换到移动数据网络"</string> diff --git a/packages/SettingsLib/res/values-zh-rHK/strings.xml b/packages/SettingsLib/res/values-zh-rHK/strings.xml index e70b63bb7dc5..c489850aa977 100644 --- a/packages/SettingsLib/res/values-zh-rHK/strings.xml +++ b/packages/SettingsLib/res/values-zh-rHK/strings.xml @@ -209,6 +209,8 @@ <string name="bluetooth_select_a2dp_codec_ldac_playback_quality" msgid="3619694372407843405">"藍牙音訊 LDAC 編解碼器:播放品質"</string> <string name="bluetooth_select_a2dp_codec_ldac_playback_quality_dialog_title" msgid="3181967377574368400">"選擇藍牙音訊 LDAC 編解碼器:\n播放品質"</string> <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"正在串流:<xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string> + <string name="dns_tls" msgid="6773814174391131955">"透過傳輸層安全性 (TLS) 執行網域名稱系統 (DNS)"</string> + <string name="dns_tls_summary" msgid="3692494150251071380">"如果啟用這個選項,即可在連接埠 853 上嘗試「透過傳輸層安全性 (TLS) 執行網域名稱系統 (DNS)」。"</string> <string name="wifi_display_certification_summary" msgid="1155182309166746973">"顯示無線螢幕分享認證的選項"</string> <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"讓 Wi‑Fi 記錄功能升級,在 Wi‑Fi 選擇器中依每個 SSID RSSI 顯示 Wi‑Fi 詳細紀錄"</string> <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"啟用後,Wi-Fi 連線會在訊號不穩定的情況下更積極轉換成流動數據連線"</string> diff --git a/packages/SettingsLib/res/values-zh-rTW/strings.xml b/packages/SettingsLib/res/values-zh-rTW/strings.xml index 38ec6c7d91b7..25543886e1b2 100644 --- a/packages/SettingsLib/res/values-zh-rTW/strings.xml +++ b/packages/SettingsLib/res/values-zh-rTW/strings.xml @@ -209,6 +209,8 @@ <string name="bluetooth_select_a2dp_codec_ldac_playback_quality" msgid="3619694372407843405">"藍牙音訊 LDAC 轉碼器:播放品質"</string> <string name="bluetooth_select_a2dp_codec_ldac_playback_quality_dialog_title" msgid="3181967377574368400">"選取藍牙音訊 LDAC 轉碼器:\n播放品質"</string> <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"串流中:<xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string> + <string name="dns_tls" msgid="6773814174391131955">"透過傳輸層安全標準 (TLS) 執行 DNS"</string> + <string name="dns_tls_summary" msgid="3692494150251071380">"如果啟用這個選項,即可在通訊埠 853 上嘗試透過傳輸層安全標準 (TLS) 執行 DNS。"</string> <string name="wifi_display_certification_summary" msgid="1155182309166746973">"顯示無線螢幕分享認證的選項"</string> <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"讓 Wi‑Fi 記錄功能升級,在 Wi‑Fi 選擇器中依每個 SSID RSSI 顯示 Wi‑Fi 詳細紀錄"</string> <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"啟用時,Wi-Fi 連線在訊號不穩的情況下會更積極轉換成行動數據連線"</string> diff --git a/packages/SettingsLib/res/values-zu/strings.xml b/packages/SettingsLib/res/values-zu/strings.xml index 1c15d54a6ab5..928eac51f167 100644 --- a/packages/SettingsLib/res/values-zu/strings.xml +++ b/packages/SettingsLib/res/values-zu/strings.xml @@ -209,6 +209,8 @@ <string name="bluetooth_select_a2dp_codec_ldac_playback_quality" msgid="3619694372407843405">"I-Bluetooth Audio LDAC Codec: Ikhwalithi yokudlala"</string> <string name="bluetooth_select_a2dp_codec_ldac_playback_quality_dialog_title" msgid="3181967377574368400">"Khetha i-Bluetooth Audio LDAC Codec:\nIkhwalithi yokudlala"</string> <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"Ukusakaza: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string> + <string name="dns_tls" msgid="6773814174391131955">"I-DNS nge-TLS"</string> + <string name="dns_tls_summary" msgid="3692494150251071380">"Uma inikwe amandla, zama i-DNS nge-TLS embobeni 853."</string> <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Bonisa izinketho zokunikeza isitifiketi ukubukeka okungenantambo"</string> <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"khuphula izinga lokungena le-Wi-Fi, bonisa nge-SSID RSSI engayodwana kusikhethi se-Wi-Fi"</string> <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"Uma inikwe amandla, i-Wi-Fi izoba namandla kakhulu ekudluliseleni ukuxhumeka kwedatha kuselula, uma isignali ye-Wi-Fi iphansi"</string> diff --git a/packages/SettingsLib/src/com/android/settingslib/drawer/TileUtils.java b/packages/SettingsLib/src/com/android/settingslib/drawer/TileUtils.java index 35ba6ae975d8..038dcf8469cf 100644 --- a/packages/SettingsLib/src/com/android/settingslib/drawer/TileUtils.java +++ b/packages/SettingsLib/src/com/android/settingslib/drawer/TileUtils.java @@ -65,7 +65,7 @@ public class TileUtils { * * <p>A summary my be defined by meta-data named {@link #META_DATA_PREFERENCE_SUMMARY} */ - private static final String EXTRA_SETTINGS_ACTION = + public static final String EXTRA_SETTINGS_ACTION = "com.android.settings.action.EXTRA_SETTINGS"; /** diff --git a/packages/SystemUI/res-keyguard/values-ar/strings.xml b/packages/SystemUI/res-keyguard/values-ar/strings.xml index e9d4c37a8143..04ce7524bda8 100644 --- a/packages/SystemUI/res-keyguard/values-ar/strings.xml +++ b/packages/SystemUI/res-keyguard/values-ar/strings.xml @@ -29,8 +29,7 @@ <string name="keyguard_password_enter_password_code" msgid="595980919238127672">"اكتب كلمة المرور لإلغاء التأمين"</string> <string name="keyguard_password_enter_pin_password_code" msgid="7504123374204446086">"اكتب رمز رقم التعريف الشخصي لإلغاء التأمين"</string> <string name="keyguard_password_wrong_pin_code" msgid="6535018036285012028">"رمز رقم التعريف الشخصي غير صحيح."</string> - <!-- no translation found for keyguard_sim_error_message_short (592109500618448312) --> - <skip /> + <string name="keyguard_sim_error_message_short" msgid="592109500618448312">"بطاقة غير صالحة."</string> <string name="keyguard_charged" msgid="2222329688813033109">"تم الشحن"</string> <string name="keyguard_plugged_in" msgid="89308975354638682">"جارٍ الشحن"</string> <string name="keyguard_plugged_in_charging_fast" msgid="8869226755413795173">"الشحن سريعًا"</string> diff --git a/packages/SystemUI/res-keyguard/values-b+sr+Latn/strings.xml b/packages/SystemUI/res-keyguard/values-b+sr+Latn/strings.xml index 8af89c321542..e24001ce56fa 100644 --- a/packages/SystemUI/res-keyguard/values-b+sr+Latn/strings.xml +++ b/packages/SystemUI/res-keyguard/values-b+sr+Latn/strings.xml @@ -29,8 +29,7 @@ <string name="keyguard_password_enter_password_code" msgid="595980919238127672">"Unesite lozinku da biste otključali"</string> <string name="keyguard_password_enter_pin_password_code" msgid="7504123374204446086">"Unesite PIN za otključavanje"</string> <string name="keyguard_password_wrong_pin_code" msgid="6535018036285012028">"PIN kôd je netačan."</string> - <!-- no translation found for keyguard_sim_error_message_short (592109500618448312) --> - <skip /> + <string name="keyguard_sim_error_message_short" msgid="592109500618448312">"Nevažeća kartica."</string> <string name="keyguard_charged" msgid="2222329688813033109">"Napunjena je"</string> <string name="keyguard_plugged_in" msgid="89308975354638682">"Puni se"</string> <string name="keyguard_plugged_in_charging_fast" msgid="8869226755413795173">"Brzo se puni"</string> diff --git a/packages/SystemUI/res-keyguard/values-bn/strings.xml b/packages/SystemUI/res-keyguard/values-bn/strings.xml index 917effbe4fe4..22e67b8dc363 100644 --- a/packages/SystemUI/res-keyguard/values-bn/strings.xml +++ b/packages/SystemUI/res-keyguard/values-bn/strings.xml @@ -29,8 +29,7 @@ <string name="keyguard_password_enter_password_code" msgid="595980919238127672">"আনলক করতে পাসওয়ার্ড লিখুন"</string> <string name="keyguard_password_enter_pin_password_code" msgid="7504123374204446086">"আনলক করতে পিন লিখুন"</string> <string name="keyguard_password_wrong_pin_code" msgid="6535018036285012028">"ভুল পিন কোড দেওয়া হয়েছে।"</string> - <!-- no translation found for keyguard_sim_error_message_short (592109500618448312) --> - <skip /> + <string name="keyguard_sim_error_message_short" msgid="592109500618448312">"ভুল কার্ড।"</string> <string name="keyguard_charged" msgid="2222329688813033109">"চার্জ হয়েছে"</string> <string name="keyguard_plugged_in" msgid="89308975354638682">"চার্জ হচ্ছে"</string> <string name="keyguard_plugged_in_charging_fast" msgid="8869226755413795173">"দ্রুত চার্জ হচ্ছে"</string> diff --git a/packages/SystemUI/res-keyguard/values-ca/strings.xml b/packages/SystemUI/res-keyguard/values-ca/strings.xml index 9f219ef060b1..9aa8229d4a7b 100644 --- a/packages/SystemUI/res-keyguard/values-ca/strings.xml +++ b/packages/SystemUI/res-keyguard/values-ca/strings.xml @@ -29,8 +29,7 @@ <string name="keyguard_password_enter_password_code" msgid="595980919238127672">"Escriu la contrasenya per desbloquejar"</string> <string name="keyguard_password_enter_pin_password_code" msgid="7504123374204446086">"Escriu el PIN per desbloquejar"</string> <string name="keyguard_password_wrong_pin_code" msgid="6535018036285012028">"El codi PIN no és correcte."</string> - <!-- no translation found for keyguard_sim_error_message_short (592109500618448312) --> - <skip /> + <string name="keyguard_sim_error_message_short" msgid="592109500618448312">"La targeta no és vàlida."</string> <string name="keyguard_charged" msgid="2222329688813033109">"Bateria carregada"</string> <string name="keyguard_plugged_in" msgid="89308975354638682">"S\'està carregant"</string> <string name="keyguard_plugged_in_charging_fast" msgid="8869226755413795173">"S\'està carregant ràpidament"</string> diff --git a/packages/SystemUI/res-keyguard/values-en-rXC/strings.xml b/packages/SystemUI/res-keyguard/values-en-rXC/strings.xml index 57a15feecc2e..dede14205ae7 100644 --- a/packages/SystemUI/res-keyguard/values-en-rXC/strings.xml +++ b/packages/SystemUI/res-keyguard/values-en-rXC/strings.xml @@ -29,6 +29,7 @@ <string name="keyguard_password_enter_password_code" msgid="595980919238127672">"Type password to unlock"</string> <string name="keyguard_password_enter_pin_password_code" msgid="7504123374204446086">"Type PIN to unlock"</string> <string name="keyguard_password_wrong_pin_code" msgid="6535018036285012028">"Incorrect PIN code."</string> + <string name="keyguard_sim_error_message_short" msgid="592109500618448312">"Invalid Card."</string> <string name="keyguard_charged" msgid="2222329688813033109">"Charged"</string> <string name="keyguard_plugged_in" msgid="89308975354638682">"Charging"</string> <string name="keyguard_plugged_in_charging_fast" msgid="8869226755413795173">"Charging rapidly"</string> diff --git a/packages/SystemUI/res-keyguard/values-es/strings.xml b/packages/SystemUI/res-keyguard/values-es/strings.xml index 523eb4c4e987..ac99a84a0b83 100644 --- a/packages/SystemUI/res-keyguard/values-es/strings.xml +++ b/packages/SystemUI/res-keyguard/values-es/strings.xml @@ -29,8 +29,7 @@ <string name="keyguard_password_enter_password_code" msgid="595980919238127672">"Escribe la contraseña para desbloquear"</string> <string name="keyguard_password_enter_pin_password_code" msgid="7504123374204446086">"Escribe el código PIN para desbloquear"</string> <string name="keyguard_password_wrong_pin_code" msgid="6535018036285012028">"El código PIN es incorrecto."</string> - <!-- no translation found for keyguard_sim_error_message_short (592109500618448312) --> - <skip /> + <string name="keyguard_sim_error_message_short" msgid="592109500618448312">"Tarjeta no válida."</string> <string name="keyguard_charged" msgid="2222329688813033109">"Cargada"</string> <string name="keyguard_plugged_in" msgid="89308975354638682">"Cargando"</string> <string name="keyguard_plugged_in_charging_fast" msgid="8869226755413795173">"Cargando rápidamente"</string> diff --git a/packages/SystemUI/res-keyguard/values-hi/strings.xml b/packages/SystemUI/res-keyguard/values-hi/strings.xml index 08f31dadff6e..62ed06429b18 100644 --- a/packages/SystemUI/res-keyguard/values-hi/strings.xml +++ b/packages/SystemUI/res-keyguard/values-hi/strings.xml @@ -29,8 +29,7 @@ <string name="keyguard_password_enter_password_code" msgid="595980919238127672">"अनलॉक करने के लिए पासवर्ड लिखें"</string> <string name="keyguard_password_enter_pin_password_code" msgid="7504123374204446086">"अनलॉक करने के लिए पिन लिखें"</string> <string name="keyguard_password_wrong_pin_code" msgid="6535018036285012028">"गलत पिन कोड."</string> - <!-- no translation found for keyguard_sim_error_message_short (592109500618448312) --> - <skip /> + <string name="keyguard_sim_error_message_short" msgid="592109500618448312">"गलत कार्ड."</string> <string name="keyguard_charged" msgid="2222329688813033109">"चार्ज हो गई है"</string> <string name="keyguard_plugged_in" msgid="89308975354638682">"चार्ज हो रही है"</string> <string name="keyguard_plugged_in_charging_fast" msgid="8869226755413795173">"तेज़ी से चार्ज हो रही है"</string> diff --git a/packages/SystemUI/res-keyguard/values-hy/strings.xml b/packages/SystemUI/res-keyguard/values-hy/strings.xml index 8118d079c470..7914b5f792a5 100644 --- a/packages/SystemUI/res-keyguard/values-hy/strings.xml +++ b/packages/SystemUI/res-keyguard/values-hy/strings.xml @@ -29,8 +29,7 @@ <string name="keyguard_password_enter_password_code" msgid="595980919238127672">"Ապակողպելու համար մուտքագրեք գաղտնաբառը"</string> <string name="keyguard_password_enter_pin_password_code" msgid="7504123374204446086">"Ապակողպելու համար մուտքագրեք PIN կոդը"</string> <string name="keyguard_password_wrong_pin_code" msgid="6535018036285012028">"PIN կոդը սխալ է։"</string> - <!-- no translation found for keyguard_sim_error_message_short (592109500618448312) --> - <skip /> + <string name="keyguard_sim_error_message_short" msgid="592109500618448312">"Սխալ քարտ"</string> <string name="keyguard_charged" msgid="2222329688813033109">"Լիցքավորված է"</string> <string name="keyguard_plugged_in" msgid="89308975354638682">"Լիցքավորում"</string> <string name="keyguard_plugged_in_charging_fast" msgid="8869226755413795173">"Արագ լիցքավորում"</string> diff --git a/packages/SystemUI/res-keyguard/values-in/strings.xml b/packages/SystemUI/res-keyguard/values-in/strings.xml index fbbb4be5478d..e417a3f44918 100644 --- a/packages/SystemUI/res-keyguard/values-in/strings.xml +++ b/packages/SystemUI/res-keyguard/values-in/strings.xml @@ -29,8 +29,7 @@ <string name="keyguard_password_enter_password_code" msgid="595980919238127672">"Ketik sandi untuk membuka kunci"</string> <string name="keyguard_password_enter_pin_password_code" msgid="7504123374204446086">"Ketik PIN untuk membuka kunci"</string> <string name="keyguard_password_wrong_pin_code" msgid="6535018036285012028">"Kode PIN salah."</string> - <!-- no translation found for keyguard_sim_error_message_short (592109500618448312) --> - <skip /> + <string name="keyguard_sim_error_message_short" msgid="592109500618448312">"Kartu Tidak Valid"</string> <string name="keyguard_charged" msgid="2222329688813033109">"Terisi"</string> <string name="keyguard_plugged_in" msgid="89308975354638682">"Mengisi daya"</string> <string name="keyguard_plugged_in_charging_fast" msgid="8869226755413795173">"Mengisi daya dengan cepat"</string> diff --git a/packages/SystemUI/res-keyguard/values-iw/strings.xml b/packages/SystemUI/res-keyguard/values-iw/strings.xml index 8b4e7907cc59..cb61b7dffb8a 100644 --- a/packages/SystemUI/res-keyguard/values-iw/strings.xml +++ b/packages/SystemUI/res-keyguard/values-iw/strings.xml @@ -29,8 +29,7 @@ <string name="keyguard_password_enter_password_code" msgid="595980919238127672">"הזן סיסמה לביטול הנעילה"</string> <string name="keyguard_password_enter_pin_password_code" msgid="7504123374204446086">"הזן את קוד הגישה לביטול הנעילה"</string> <string name="keyguard_password_wrong_pin_code" msgid="6535018036285012028">"קוד הגישה שגוי"</string> - <!-- no translation found for keyguard_sim_error_message_short (592109500618448312) --> - <skip /> + <string name="keyguard_sim_error_message_short" msgid="592109500618448312">"כרטיס לא חוקי."</string> <string name="keyguard_charged" msgid="2222329688813033109">"הסוללה טעונה"</string> <string name="keyguard_plugged_in" msgid="89308975354638682">"הסוללה נטענת"</string> <string name="keyguard_plugged_in_charging_fast" msgid="8869226755413795173">"הסוללה נטענת מהר"</string> diff --git a/packages/SystemUI/res-keyguard/values-ne/strings.xml b/packages/SystemUI/res-keyguard/values-ne/strings.xml index 32e46f88245e..d5ac1d84212f 100644 --- a/packages/SystemUI/res-keyguard/values-ne/strings.xml +++ b/packages/SystemUI/res-keyguard/values-ne/strings.xml @@ -29,8 +29,7 @@ <string name="keyguard_password_enter_password_code" msgid="595980919238127672">"अनलक गर्न पासवर्ड टाइप गर्नुहोस्"</string> <string name="keyguard_password_enter_pin_password_code" msgid="7504123374204446086">"अनलक गर्न PIN कोड टाइप गर्नुहोस्"</string> <string name="keyguard_password_wrong_pin_code" msgid="6535018036285012028">"PIN कोड गलत छ।"</string> - <!-- no translation found for keyguard_sim_error_message_short (592109500618448312) --> - <skip /> + <string name="keyguard_sim_error_message_short" msgid="592109500618448312">"अमान्य कार्ड।"</string> <string name="keyguard_charged" msgid="2222329688813033109">"चार्ज भयो"</string> <string name="keyguard_plugged_in" msgid="89308975354638682">"चार्ज हुँदै"</string> <string name="keyguard_plugged_in_charging_fast" msgid="8869226755413795173">"छिटो चार्ज हुँदै"</string> diff --git a/packages/SystemUI/res-keyguard/values-nl/strings.xml b/packages/SystemUI/res-keyguard/values-nl/strings.xml index 411ee6e4d7f6..6a1f3c92cd1a 100644 --- a/packages/SystemUI/res-keyguard/values-nl/strings.xml +++ b/packages/SystemUI/res-keyguard/values-nl/strings.xml @@ -29,8 +29,7 @@ <string name="keyguard_password_enter_password_code" msgid="595980919238127672">"Typ het wachtwoord om te ontgrendelen"</string> <string name="keyguard_password_enter_pin_password_code" msgid="7504123374204446086">"Typ pincode om te ontgrendelen"</string> <string name="keyguard_password_wrong_pin_code" msgid="6535018036285012028">"Onjuiste pincode."</string> - <!-- no translation found for keyguard_sim_error_message_short (592109500618448312) --> - <skip /> + <string name="keyguard_sim_error_message_short" msgid="592109500618448312">"Ongeldige kaart."</string> <string name="keyguard_charged" msgid="2222329688813033109">"Opgeladen"</string> <string name="keyguard_plugged_in" msgid="89308975354638682">"Opladen"</string> <string name="keyguard_plugged_in_charging_fast" msgid="8869226755413795173">"Snel opladen"</string> diff --git a/packages/SystemUI/res-keyguard/values-pt-rPT/strings.xml b/packages/SystemUI/res-keyguard/values-pt-rPT/strings.xml index bd0bdaa2da2e..4f6fcb956f0a 100644 --- a/packages/SystemUI/res-keyguard/values-pt-rPT/strings.xml +++ b/packages/SystemUI/res-keyguard/values-pt-rPT/strings.xml @@ -29,8 +29,7 @@ <string name="keyguard_password_enter_password_code" msgid="595980919238127672">"Introduza a palavra-passe para desbloquear"</string> <string name="keyguard_password_enter_pin_password_code" msgid="7504123374204446086">"Introduza o PIN para desbloquear"</string> <string name="keyguard_password_wrong_pin_code" msgid="6535018036285012028">"Código PIN incorreto."</string> - <!-- no translation found for keyguard_sim_error_message_short (592109500618448312) --> - <skip /> + <string name="keyguard_sim_error_message_short" msgid="592109500618448312">"Cartão inválido."</string> <string name="keyguard_charged" msgid="2222329688813033109">"Carregada"</string> <string name="keyguard_plugged_in" msgid="89308975354638682">"A carregar…"</string> <string name="keyguard_plugged_in_charging_fast" msgid="8869226755413795173">"A carregar rapidamente…"</string> @@ -121,7 +120,7 @@ <string name="kg_prompt_reason_switch_profiles_pattern" msgid="3398054847288438444">"É necessário um padrão quando muda de perfil"</string> <string name="kg_prompt_reason_switch_profiles_pin" msgid="7426368139226961699">"É necessário um PIN quando muda de perfil"</string> <string name="kg_prompt_reason_switch_profiles_password" msgid="8383831046318421845">"É necessária uma palavra-passe quando muda de perfil"</string> - <string name="kg_prompt_reason_device_admin" msgid="3452168247888906179">"Dispositivo bloqueado pelo administrador"</string> + <string name="kg_prompt_reason_device_admin" msgid="3452168247888906179">"Dispositivo bloqueado pelo gestor"</string> <string name="kg_prompt_reason_user_request" msgid="8236951765212462286">"O dispositivo foi bloqueado manualmente"</string> <plurals name="kg_prompt_reason_time_pattern" formatted="false" msgid="71299470072448533"> <item quantity="one">O dispositivo não é desbloqueado há <xliff:g id="NUMBER_0">%d</xliff:g> hora. Confirme o padrão.</item> diff --git a/packages/SystemUI/res-keyguard/values-sr/strings.xml b/packages/SystemUI/res-keyguard/values-sr/strings.xml index 6c40bd03f254..9d06e008f7c5 100644 --- a/packages/SystemUI/res-keyguard/values-sr/strings.xml +++ b/packages/SystemUI/res-keyguard/values-sr/strings.xml @@ -29,8 +29,7 @@ <string name="keyguard_password_enter_password_code" msgid="595980919238127672">"Унесите лозинку да бисте откључали"</string> <string name="keyguard_password_enter_pin_password_code" msgid="7504123374204446086">"Унесите PIN за откључавање"</string> <string name="keyguard_password_wrong_pin_code" msgid="6535018036285012028">"PIN кôд је нетачан."</string> - <!-- no translation found for keyguard_sim_error_message_short (592109500618448312) --> - <skip /> + <string name="keyguard_sim_error_message_short" msgid="592109500618448312">"Неважећа картица."</string> <string name="keyguard_charged" msgid="2222329688813033109">"Напуњена је"</string> <string name="keyguard_plugged_in" msgid="89308975354638682">"Пуни се"</string> <string name="keyguard_plugged_in_charging_fast" msgid="8869226755413795173">"Брзо се пуни"</string> diff --git a/packages/SystemUI/res-keyguard/values-tr/strings.xml b/packages/SystemUI/res-keyguard/values-tr/strings.xml index 5f526c3ad513..b80e4db816ce 100644 --- a/packages/SystemUI/res-keyguard/values-tr/strings.xml +++ b/packages/SystemUI/res-keyguard/values-tr/strings.xml @@ -29,8 +29,7 @@ <string name="keyguard_password_enter_password_code" msgid="595980919238127672">"Kilidi açmak için şifreyi yazın"</string> <string name="keyguard_password_enter_pin_password_code" msgid="7504123374204446086">"Kilidi açmak için PIN kodunu yazın"</string> <string name="keyguard_password_wrong_pin_code" msgid="6535018036285012028">"Yanlış PIN kodu."</string> - <!-- no translation found for keyguard_sim_error_message_short (592109500618448312) --> - <skip /> + <string name="keyguard_sim_error_message_short" msgid="592109500618448312">"Geçersiz Kart."</string> <string name="keyguard_charged" msgid="2222329688813033109">"Ödeme alındı"</string> <string name="keyguard_plugged_in" msgid="89308975354638682">"Şarj oluyor"</string> <string name="keyguard_plugged_in_charging_fast" msgid="8869226755413795173">"Hızlı şarj oluyor"</string> diff --git a/packages/SystemUI/res-keyguard/values-uz/strings.xml b/packages/SystemUI/res-keyguard/values-uz/strings.xml index 88bd095604df..699ad6002760 100644 --- a/packages/SystemUI/res-keyguard/values-uz/strings.xml +++ b/packages/SystemUI/res-keyguard/values-uz/strings.xml @@ -29,8 +29,7 @@ <string name="keyguard_password_enter_password_code" msgid="595980919238127672">"Qulfni ochish uchun parolni kiriting"</string> <string name="keyguard_password_enter_pin_password_code" msgid="7504123374204446086">"Qulfni ochish uchun PIN kodni kiriting"</string> <string name="keyguard_password_wrong_pin_code" msgid="6535018036285012028">"PIN kodi xato."</string> - <!-- no translation found for keyguard_sim_error_message_short (592109500618448312) --> - <skip /> + <string name="keyguard_sim_error_message_short" msgid="592109500618448312">"SIM karta yaroqsiz."</string> <string name="keyguard_charged" msgid="2222329688813033109">"Batareya quvvati to‘ldi"</string> <string name="keyguard_plugged_in" msgid="89308975354638682">"Quvvatlash"</string> <string name="keyguard_plugged_in_charging_fast" msgid="8869226755413795173">"Tezkor quvvat olmoqda"</string> diff --git a/packages/SystemUI/res/values-ar/strings.xml b/packages/SystemUI/res/values-ar/strings.xml index bff8d86cacee..b5ac31a07c37 100644 --- a/packages/SystemUI/res/values-ar/strings.xml +++ b/packages/SystemUI/res/values-ar/strings.xml @@ -169,7 +169,7 @@ <string name="accessibility_battery_level_charging" msgid="1147587904439319646">"جارٍ شحن البطارية، <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> بالمائة."</string> <string name="accessibility_settings_button" msgid="799583911231893380">"إعدادات النظام."</string> <string name="accessibility_notifications_button" msgid="4498000369779421892">"الإشعارات."</string> - <string name="accessibility_overflow_action" msgid="5681882033274783311">"الاطلاع على جميع الإشعارات"</string> + <string name="accessibility_overflow_action" msgid="5681882033274783311">"الاطّلاع على جميع الإشعارات"</string> <string name="accessibility_remove_notification" msgid="3603099514902182350">"محو الإشعار."</string> <string name="accessibility_gps_enabled" msgid="3511469499240123019">"تم تمكين GPS."</string> <string name="accessibility_gps_acquiring" msgid="8959333351058967158">"الحصول على GPS."</string> @@ -477,7 +477,7 @@ <string name="keyguard_indication_trust_managed" msgid="8319646760022357585">"<xliff:g id="TRUST_AGENT">%1$s</xliff:g> قيد التشغيل"</string> <string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"سيظل الجهاز مقفلاً إلى أن يتم إلغاء قفله يدويًا"</string> <string name="hidden_notifications_title" msgid="7139628534207443290">"الحصول على الإشعارات بشكل أسرع"</string> - <string name="hidden_notifications_text" msgid="2326409389088668981">"الاطلاع عليها قبل إلغاء القفل"</string> + <string name="hidden_notifications_text" msgid="2326409389088668981">"الاطّلاع عليها قبل إلغاء القفل"</string> <string name="hidden_notifications_cancel" msgid="3690709735122344913">"لا، شكرًا"</string> <string name="hidden_notifications_setup" msgid="41079514801976810">"إعداد"</string> <string name="zen_mode_and_condition" msgid="4462471036429759903">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string> diff --git a/packages/SystemUI/res/values-ca/strings.xml b/packages/SystemUI/res/values-ca/strings.xml index eea0e636f5c9..28b0ffe6b789 100644 --- a/packages/SystemUI/res/values-ca/strings.xml +++ b/packages/SystemUI/res/values-ca/strings.xml @@ -404,7 +404,7 @@ <string name="battery_saver_notification_title" msgid="237918726750955859">"Estalvi de bateria activat"</string> <string name="battery_saver_notification_text" msgid="820318788126672692">"Redueix el rendiment i l\'ús de les dades en segon pla."</string> <string name="battery_saver_notification_action_text" msgid="109158658238110382">"Desactiva l\'estalvi de bateria"</string> - <string name="media_projection_dialog_text" msgid="3071431025448218928">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> començarà a enregistrar tot el que es mostri a la pantalla."</string> + <string name="media_projection_dialog_text" msgid="3071431025448218928">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> començarà a gravar tot el que es mostri a la pantalla."</string> <string name="media_projection_remember_text" msgid="3103510882172746752">"No ho tornis a mostrar"</string> <string name="clear_all_notifications_text" msgid="814192889771462828">"Esborra-ho tot"</string> <string name="media_projection_action_text" msgid="8470872969457985954">"Comença ara"</string> diff --git a/packages/SystemUI/res/values-en-rXC/strings.xml b/packages/SystemUI/res/values-en-rXC/strings.xml index 39af7ec7550a..e1326de67a03 100644 --- a/packages/SystemUI/res/values-en-rXC/strings.xml +++ b/packages/SystemUI/res/values-en-rXC/strings.xml @@ -180,7 +180,6 @@ <string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"All recent applications dismissed."</string> <string name="accessibility_recents_item_open_app_info" msgid="5107479759905883540">"Open <xliff:g id="APP">%s</xliff:g> application info."</string> <string name="accessibility_recents_item_launched" msgid="7616039892382525203">"Starting <xliff:g id="APP">%s</xliff:g>."</string> - <string name="accessibility_recents_task_header" msgid="1437183540924535457">"<xliff:g id="APP">%1$s</xliff:g> <xliff:g id="ACTIVITY_LABEL">%2$s</xliff:g>"</string> <string name="accessibility_notification_dismissed" msgid="854211387186306927">"Notification dismissed."</string> <string name="accessibility_desc_notification_shade" msgid="4690274844447504208">"Notification shade."</string> <string name="accessibility_desc_quick_settings" msgid="6186378411582437046">"Quick settings."</string> @@ -343,8 +342,6 @@ <string name="recents_accessibility_split_screen_top" msgid="9056056469282256287">"Split screen to the top"</string> <string name="recents_accessibility_split_screen_left" msgid="8987144699630620019">"Split screen to the left"</string> <string name="recents_accessibility_split_screen_right" msgid="275069779299592867">"Split screen to the right"</string> - <string-array name="recents_blacklist_array"> - </string-array> <string name="expanded_header_battery_charged" msgid="5945855970267657951">"Charged"</string> <string name="expanded_header_battery_charging" msgid="205623198487189724">"Charging"</string> <string name="expanded_header_battery_charging_with_time" msgid="457559884275395376">"<xliff:g id="CHARGING_TIME">%s</xliff:g> until full"</string> diff --git a/packages/SystemUI/res/values-ne/strings.xml b/packages/SystemUI/res/values-ne/strings.xml index 8afef76795ad..b2bf111c1bfc 100644 --- a/packages/SystemUI/res/values-ne/strings.xml +++ b/packages/SystemUI/res/values-ne/strings.xml @@ -69,7 +69,7 @@ <string name="compat_mode_off" msgid="4434467572461327898">"स्क्रिन भर्न तन्काउनुहोस्"</string> <string name="screenshot_saving_ticker" msgid="7403652894056693515">"स्क्रिनसट बचत गर्दै…"</string> <string name="screenshot_saving_title" msgid="8242282144535555697">"स्क्रिनसट बचत गर्दै…"</string> - <string name="screenshot_saving_text" msgid="2419718443411738818">"स्क्रिनसट बचत हुँदै छ।"</string> + <string name="screenshot_saving_text" msgid="2419718443411738818">"स्क्रिनसट बचत हुँदैछ।"</string> <string name="screenshot_saved_title" msgid="6461865960961414961">"स्क्रिनसट क्याप्चर गरियो।"</string> <string name="screenshot_saved_text" msgid="2685605830386712477">"आफ्नो स्क्रिनसट हेर्न ट्याप गर्नुहोस्।"</string> <string name="screenshot_failed_title" msgid="705781116746922771">"स्क्रिनसट क्याप्चर गर्न सकिएन।"</string> diff --git a/packages/SystemUI/res/values-pt-rPT/strings.xml b/packages/SystemUI/res/values-pt-rPT/strings.xml index 962dc49bf9f3..2bbc4704b247 100644 --- a/packages/SystemUI/res/values-pt-rPT/strings.xml +++ b/packages/SystemUI/res/values-pt-rPT/strings.xml @@ -436,12 +436,12 @@ <string name="disable_vpn" msgid="4435534311510272506">"Desativar a VPN"</string> <string name="disconnect_vpn" msgid="1324915059568548655">"Desligar VPN"</string> <string name="monitoring_button_view_policies" msgid="100913612638514424">"Ver Políticas"</string> - <string name="monitoring_description_named_management" msgid="5281789135578986303">"O dispositivo é gerido pela <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>.\n\nO administrador pode monitorizar e gerir definições, acesso empresarial, aplicações, dados associados ao dispositivo e informações de localização do dispositivo.\n\nContacte o administrador para obter mais informações."</string> - <string name="monitoring_description_management" msgid="4573721970278370790">"O dispositivo é gerido pela sua entidade.\n\nO administrador pode monitorizar e gerir definições, acesso empresarial, aplicações, dados associados ao dispositivo e informações de localização do dispositivo.\n\nContacte o administrador para obter mais informações."</string> + <string name="monitoring_description_named_management" msgid="5281789135578986303">"O dispositivo é gerido pela <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>.\n\nO gestor pode monitorizar e gerir definições, acesso empresarial, aplicações, dados associados ao dispositivo e informações de localização do dispositivo.\n\nContacte o gestor para obter mais informações."</string> + <string name="monitoring_description_management" msgid="4573721970278370790">"O dispositivo é gerido pela sua entidade.\n\nO gestor pode monitorizar e gerir definições, acesso empresarial, aplicações, dados associados ao dispositivo e informações de localização do dispositivo.\n\nContacte o gestor para obter mais informações."</string> <string name="monitoring_description_management_ca_certificate" msgid="5202023784131001751">"A sua entidade instalou uma autoridade de certificação neste dispositivo. O tráfego da sua rede segura pode ser monitorizado ou alterado."</string> <string name="monitoring_description_managed_profile_ca_certificate" msgid="4683248196789897964">"A sua entidade instalou uma autoridade de certificação no seu perfil de trabalho. O tráfego da sua rede segura pode ser monitorizado ou alterado."</string> <string name="monitoring_description_ca_certificate" msgid="7886985418413598352">"Está instalada uma autoridade de certificação neste dispositivo. O tráfego da sua rede segura pode ser monitorizado ou alterado."</string> - <string name="monitoring_description_management_network_logging" msgid="7184005419733060736">"O administrador ativou os registos de rede, que monitorizam o tráfego no seu dispositivo."</string> + <string name="monitoring_description_management_network_logging" msgid="7184005419733060736">"O gestor ativou os registos de rede, que monitorizam o tráfego no seu dispositivo."</string> <string name="monitoring_description_named_vpn" msgid="7403457334088909254">"Está ligado à rede <xliff:g id="VPN_APP">%1$s</xliff:g>, que pode monitorizar a sua atividade de rede, incluindo emails, aplicações e Sites."</string> <string name="monitoring_description_two_named_vpns" msgid="4198511413729213802">"Está ligado às redes <xliff:g id="VPN_APP_0">%1$s</xliff:g> e <xliff:g id="VPN_APP_1">%2$s</xliff:g>, que podem monitorizar a sua atividade de rede, incluindo emails, aplicações e Sites."</string> <string name="monitoring_description_managed_profile_named_vpn" msgid="1427905889862420559">"O seu perfil de trabalho está ligado à rede <xliff:g id="VPN_APP">%1$s</xliff:g>, que pode monitorizar a sua atividade de rede, incluindo emails, aplicações e Sites."</string> @@ -456,14 +456,14 @@ <string name="monitoring_description_vpn_settings" msgid="6434859242636063861">"Abrir as definições de VPN"</string> <string name="monitoring_description_ca_cert_settings_separator" msgid="4987350385906393626">" "</string> <string name="monitoring_description_ca_cert_settings" msgid="5489969458872997092">"Abrir credenciais fidedignas"</string> - <string name="monitoring_description_network_logging" msgid="7223505523384076027">"O seu administrador ativou os registos de rede, que monitorizam o tráfego no seu dispositivo.\n\nPara obter mais informações, contacte o administrador."</string> + <string name="monitoring_description_network_logging" msgid="7223505523384076027">"O seu gestor ativou os registos de rede, que monitorizam o tráfego no seu dispositivo.\n\nPara obter mais informações, contacte o gestor."</string> <string name="monitoring_description_vpn" msgid="4445150119515393526">"Concedeu autorização a uma aplicação para configurar uma ligação VPN.\n\nEsta aplicação pode monitorizar a atividade do dispositivo e da rede, incluindo emails, aplicações e Sites."</string> - <string name="monitoring_description_vpn_profile_owned" msgid="2958019119161161530">"O seu perfil de trabalho é gerido por <xliff:g id="ORGANIZATION">%1$s</xliff:g>.\n\nO seu administrador tem a capacidade de monitorizar a sua atividade da rede, incluindo emails, aplicações e Sites.\n\nPara obter mais informações, contacte o administrador.\n\nAlém disso, está ligado a uma VPN, que pode monitorizar a sua atividade da rede."</string> + <string name="monitoring_description_vpn_profile_owned" msgid="2958019119161161530">"O seu perfil de trabalho é gerido por <xliff:g id="ORGANIZATION">%1$s</xliff:g>.\n\nO seu gestor tem a capacidade de monitorizar a sua atividade da rede, incluindo emails, aplicações e Sites.\n\nPara obter mais informações, contacte o gestor.\n\nAlém disso, está ligado a uma VPN, que pode monitorizar a sua atividade da rede."</string> <string name="legacy_vpn_name" msgid="6604123105765737830">"VPN"</string> <string name="monitoring_description_app" msgid="1828472472674709532">"Está associado à aplicação <xliff:g id="APPLICATION">%1$s</xliff:g>, que pode monitorizar a sua atividade de rede, incluindo emails, aplicações e Sites."</string> <string name="monitoring_description_app_personal" msgid="484599052118316268">"Está ligado a <xliff:g id="APPLICATION">%1$s</xliff:g>, que pode monitorizar a atividade da rede pessoal, incluindo emails, aplicações e Sites."</string> <string name="branded_monitoring_description_app_personal" msgid="2669518213949202599">"Está ligado ao <xliff:g id="APPLICATION">%1$s</xliff:g>, que pode monitorizar a atividade da rede pessoal, incluindo emails, aplicações e Sites."</string> - <string name="monitoring_description_app_work" msgid="4612997849787922906">"O seu perfil de trabalho é gerido pela <xliff:g id="ORGANIZATION">%1$s</xliff:g>. O perfil está associado à aplicação <xliff:g id="APPLICATION">%2$s</xliff:g>, que pode monitorizar a atividade da rede de trabalho, incluindo emails, aplicações e Sites.\n\nContacte o administrador para obter mais informações."</string> + <string name="monitoring_description_app_work" msgid="4612997849787922906">"O seu perfil de trabalho é gerido pela <xliff:g id="ORGANIZATION">%1$s</xliff:g>. O perfil está associado à aplicação <xliff:g id="APPLICATION">%2$s</xliff:g>, que pode monitorizar a atividade da rede de trabalho, incluindo emails, aplicações e Sites.\n\nContacte o gestor para obter mais informações."</string> <string name="monitoring_description_app_personal_work" msgid="5664165460056859391">"O seu perfil de trabalho é gerido pela <xliff:g id="ORGANIZATION">%1$s</xliff:g>. O perfil está associado à aplicação <xliff:g id="APPLICATION_WORK">%2$s</xliff:g>, que pode monitorizar a atividade da rede de trabalho, incluindo emails, aplicações e Sites.\n\nTambém está associado à aplicação <xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g>, que pode monitorizar a atividade da rede pessoal."</string> <string name="keyguard_indication_trust_granted" msgid="4985003749105182372">"Desbloqueado para <xliff:g id="USER_NAME">%1$s</xliff:g>"</string> <string name="keyguard_indication_trust_managed" msgid="8319646760022357585">"<xliff:g id="TRUST_AGENT">%1$s</xliff:g> em execução"</string> diff --git a/packages/SystemUI/res/values-uz/strings.xml b/packages/SystemUI/res/values-uz/strings.xml index 7e4de6404952..8722fb19da8f 100644 --- a/packages/SystemUI/res/values-uz/strings.xml +++ b/packages/SystemUI/res/values-uz/strings.xml @@ -337,7 +337,7 @@ <string name="recents_launch_error_message" msgid="2969287838120550506">"“<xliff:g id="APP">%s</xliff:g>” ilovasini ishga tushirib bo‘lmadi."</string> <string name="recents_launch_disabled_message" msgid="1624523193008871793">"Xavfsiz rejimda <xliff:g id="APP">%s</xliff:g> ilovasi o‘chirib qo‘yildi."</string> <string name="recents_stack_action_button_label" msgid="6593727103310426253">"Hammasini tozalash"</string> - <string name="recents_drag_hint_message" msgid="2649739267073203985">"Ekranni bo‘lish xususiyatidan foydalanish uchun uchun bu yerga torting"</string> + <string name="recents_drag_hint_message" msgid="2649739267073203985">"Ekranni bo‘lish xususiyatidan foydalanish uchun bu yerga torting"</string> <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Gorizontal yo‘nalishda bo‘lish"</string> <string name="recents_multistack_add_stack_dialog_split_vertical" msgid="9075292233696180813">"Vertikal yo‘nalishda bo‘lish"</string> <string name="recents_multistack_add_stack_dialog_split_custom" msgid="4177837597513701943">"Boshqa usulda bo‘lish"</string> diff --git a/packages/SystemUI/src/com/android/systemui/ForegroundServiceControllerImpl.java b/packages/SystemUI/src/com/android/systemui/ForegroundServiceControllerImpl.java index c930d567254a..3714c4ea7e2c 100644 --- a/packages/SystemUI/src/com/android/systemui/ForegroundServiceControllerImpl.java +++ b/packages/SystemUI/src/com/android/systemui/ForegroundServiceControllerImpl.java @@ -34,6 +34,10 @@ import java.util.Arrays; */ public class ForegroundServiceControllerImpl implements ForegroundServiceController { + + // shelf life of foreground services before they go bad + public static final long FG_SERVICE_GRACE_MILLIS = 5000; + private static final String TAG = "FgServiceController"; private static final boolean DBG = false; @@ -72,7 +76,7 @@ public class ForegroundServiceControllerImpl if (isDungeonNotification(sbn)) { // if you remove the dungeon entirely, we take that to mean there are // no running services - userServices.setRunningServices(null); + userServices.setRunningServices(null, 0); return true; } else { // this is safe to call on any notification, not just FLAG_FOREGROUND_SERVICE @@ -94,7 +98,7 @@ public class ForegroundServiceControllerImpl final Bundle extras = sbn.getNotification().extras; if (extras != null) { final String[] svcs = extras.getStringArray(Notification.EXTRA_FOREGROUND_APPS); - userServices.setRunningServices(svcs); // null ok + userServices.setRunningServices(svcs, sbn.getNotification().when); } } else { userServices.removeNotification(sbn.getPackageName(), sbn.getKey()); @@ -118,9 +122,11 @@ public class ForegroundServiceControllerImpl */ private static class UserServices { private String[] mRunning = null; + private long mServiceStartTime = 0; private ArrayMap<String, ArraySet<String>> mNotifications = new ArrayMap<>(1); - public void setRunningServices(String[] pkgs) { + public void setRunningServices(String[] pkgs, long serviceStartTime) { mRunning = pkgs != null ? Arrays.copyOf(pkgs, pkgs.length) : null; + mServiceStartTime = serviceStartTime; } public void addNotification(String pkg, String key) { if (mNotifications.get(pkg) == null) { @@ -142,7 +148,9 @@ public class ForegroundServiceControllerImpl return found; } public boolean isDungeonNeeded() { - if (mRunning != null) { + if (mRunning != null + && System.currentTimeMillis() - mServiceStartTime >= FG_SERVICE_GRACE_MILLIS) { + for (String pkg : mRunning) { final ArraySet<String> set = mNotifications.get(pkg); if (set == null || set.size() == 0) { diff --git a/packages/SystemUI/src/com/android/systemui/pip/tv/PipManager.java b/packages/SystemUI/src/com/android/systemui/pip/tv/PipManager.java index 312b9908d202..c92562b4436f 100644 --- a/packages/SystemUI/src/com/android/systemui/pip/tv/PipManager.java +++ b/packages/SystemUI/src/com/android/systemui/pip/tv/PipManager.java @@ -599,8 +599,8 @@ public class PipManager implements BasePipManager { private boolean isSettingsShown() { List<RunningTaskInfo> runningTasks; try { - runningTasks = mActivityManager.getTasks(1, 0); - if (runningTasks == null || runningTasks.size() == 0) { + runningTasks = mActivityManager.getTasks(1); + if (runningTasks.isEmpty()) { return false; } } catch (RemoteException e) { diff --git a/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java b/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java index 87f24fdb6cdb..55ec5e7ed2ce 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java +++ b/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java @@ -200,25 +200,17 @@ public class SystemServicesProxy { */ public ActivityManager.RunningTaskInfo getRunningTask() { // Note: The set of running tasks from the system is ordered by recency - List<ActivityManager.RunningTaskInfo> tasks = mAm.getRunningTasks(10); - if (tasks == null || tasks.isEmpty()) { - return null; - } - - // Find the first task in a valid stack, we ignore everything from the Recents and PiP - // stacks - for (int i = 0; i < tasks.size(); i++) { - final ActivityManager.RunningTaskInfo task = tasks.get(i); - final WindowConfiguration winConfig = task.configuration.windowConfiguration; - if (winConfig.getActivityType() == ACTIVITY_TYPE_RECENTS) { - continue; - } - if (winConfig.getWindowingMode() == WINDOWING_MODE_PINNED) { - continue; + try { + List<ActivityManager.RunningTaskInfo> tasks = mIam.getFilteredTasks(1, + ACTIVITY_TYPE_RECENTS /* ignoreActivityType */, + WINDOWING_MODE_PINNED /* ignoreWindowingMode */); + if (tasks.isEmpty()) { + return null; } - return task; + return tasks.get(0); + } catch (RemoteException e) { + return null; } - return null; } /** diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsTransitionHelper.java b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsTransitionHelper.java index 25c2fc97eda4..7442904ec1c0 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsTransitionHelper.java +++ b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsTransitionHelper.java @@ -302,11 +302,6 @@ public class RecentsTransitionHelper { */ private List<AppTransitionAnimationSpec> composeAnimationSpecs(final Task task, final TaskStackView stackView, int windowingMode, int activityType, Rect windowRect) { - if (activityType == ACTIVITY_TYPE_RECENTS || activityType == ACTIVITY_TYPE_HOME - || windowingMode == WINDOWING_MODE_PINNED) { - return null; - } - // Calculate the offscreen task rect (for tasks that are not backed by views) TaskView taskView = stackView.getChildViewForTask(task); TaskStackLayoutAlgorithm stackLayout = stackView.getStackAlgorithm(); 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 9a7039a515a1..094129c5793b 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java @@ -448,10 +448,18 @@ public class NavigationBarView extends FrameLayout implements PluginListener<Nav // Always disable recents when alternate car mode UI is active. boolean disableRecent = mUseCarModeUi - || ((disabledFlags & View.STATUS_BAR_DISABLE_RECENT) != 0); - final boolean disableBack = ((disabledFlags & View.STATUS_BAR_DISABLE_BACK) != 0) + || ((disabledFlags & View.STATUS_BAR_DISABLE_RECENT) != 0); + + boolean disableBack = ((disabledFlags & View.STATUS_BAR_DISABLE_BACK) != 0) && ((mNavigationIconHints & StatusBarManager.NAVIGATION_HINT_BACK_ALT) == 0); + if ((disableRecent || disableBack) && inScreenPinning()) { + // Don't hide back and recents buttons when in screen pinning mode, as they are used for + // exiting. + disableBack = false; + disableRecent = false; + } + ViewGroup navButtons = (ViewGroup) getCurrentView().findViewById(R.id.nav_buttons); if (navButtons != null) { LayoutTransition lt = navButtons.getLayoutTransition(); @@ -461,20 +469,16 @@ public class NavigationBarView extends FrameLayout implements PluginListener<Nav } } } - if (inLockTask() && disableRecent && !disableHome) { - // Don't hide recents when in lock task, it is used for exiting. - // Unless home is hidden, then in DPM locked mode and no exit available. - disableRecent = false; - } getBackButton().setVisibility(disableBack ? View.INVISIBLE : View.VISIBLE); getHomeButton().setVisibility(disableHome ? View.INVISIBLE : View.VISIBLE); getRecentsButton().setVisibility(disableRecent ? View.INVISIBLE : View.VISIBLE); } - private boolean inLockTask() { + private boolean inScreenPinning() { try { - return ActivityManager.getService().isInLockTaskMode(); + return ActivityManager.getService().getLockTaskModeState() + == ActivityManager.LOCK_TASK_MODE_PINNED; } catch (RemoteException e) { return false; } diff --git a/packages/SystemUI/tests/src/com/android/systemui/ForegroundServiceControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/ForegroundServiceControllerTest.java index 1f5255a0e869..943020c7b28e 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/ForegroundServiceControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/ForegroundServiceControllerTest.java @@ -287,6 +287,7 @@ public class ForegroundServiceControllerTest extends SysuiTestCase { final Bundle extras = new Bundle(); if (pkgs != null) extras.putStringArray(Notification.EXTRA_FOREGROUND_APPS, pkgs); n.extras = extras; + n.when = System.currentTimeMillis() - 10000; // ten seconds ago final StatusBarNotification sbn = makeMockSBN(userid, "android", SystemMessageProto.SystemMessage.NOTE_FOREGROUND_SERVICES, null, n); diff --git a/proto/src/metrics_constants.proto b/proto/src/metrics_constants.proto index 5dd3620ee762..93aa5207a9ec 100644 --- a/proto/src/metrics_constants.proto +++ b/proto/src/metrics_constants.proto @@ -4704,6 +4704,11 @@ message MetricsEvent { // OS: P AUTOFILL_SAVE_EXPLICITLY_TRIGGERED = 1229; + // OPEN: Settings > Network & Internet > Mobile network > Wi-Fi calling + // CATEGORY: SETTINGS + // OS: P + WIFI_CALLING_FOR_SUB = 1230; + // Add new aosp constants above this line. // END OF AOSP CONSTANTS } diff --git a/services/core/java/com/android/server/BatteryService.java b/services/core/java/com/android/server/BatteryService.java index b824fab7a835..68546bd22221 100644 --- a/services/core/java/com/android/server/BatteryService.java +++ b/services/core/java/com/android/server/BatteryService.java @@ -253,39 +253,33 @@ public final class BatteryService extends SystemService { mHealthServiceWrapper.init(mHealthHalCallback, new HealthServiceWrapper.IServiceManagerSupplier() {}, new HealthServiceWrapper.IHealthSupplier() {}); - } catch (RemoteException | NoSuchElementException ex) { - Slog.w(TAG, "health: cannot register callback. " - + "BatteryService will be started with dummy values. Reason: " - + ex.getClass().getSimpleName() + ": " + ex.getMessage()); - update(new HealthInfo()); - return; + } catch (RemoteException ex) { + Slog.e(TAG, "health: cannot register callback. (RemoteException)"); + throw ex.rethrowFromSystemServer(); + } catch (NoSuchElementException ex) { + Slog.e(TAG, "health: cannot register callback. (no supported health HAL service)"); + throw ex; } // init register for new service notifications, and IServiceManager should return the // existing service in a near future. Wait for this.update() to instantiate // the initial mHealthInfo. - long timeWaited = 0; + long beforeWait = SystemClock.uptimeMillis(); synchronized (mLock) { - long beforeWait = SystemClock.uptimeMillis(); - while (mHealthInfo == null && - (timeWaited = SystemClock.uptimeMillis() - beforeWait) < HEALTH_HAL_WAIT_MS) { + while (mHealthInfo == null) { + Slog.i(TAG, "health: Waited " + (SystemClock.uptimeMillis() - beforeWait) + + "ms for callbacks. Waiting another " + HEALTH_HAL_WAIT_MS + " ms..."); try { - mLock.wait(HEALTH_HAL_WAIT_MS - timeWaited); + mLock.wait(HEALTH_HAL_WAIT_MS); } catch (InterruptedException ex) { - break; + Slog.i(TAG, "health: InterruptedException when waiting for update. " + + " Continuing..."); } } - if (mHealthInfo == null) { - Slog.w(TAG, "health: Waited " + timeWaited + "ms for callbacks but received " - + "nothing. BatteryService will be started with dummy values."); - update(new HealthInfo()); - return; - } } - if (DEBUG) { - Slog.d(TAG, "health: Waited " + timeWaited + "ms and received the update."); - } + Slog.i(TAG, "health: Waited " + (SystemClock.uptimeMillis() - beforeWait) + + "ms and received the update."); } private void updateBatteryWarningLevelLocked() { diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java index d819a33d9207..7e65d36024e3 100644 --- a/services/core/java/com/android/server/ConnectivityService.java +++ b/services/core/java/com/android/server/ConnectivityService.java @@ -143,6 +143,7 @@ import com.android.server.connectivity.tethering.TetheringDependencies; import com.android.server.net.BaseNetworkObserver; import com.android.server.net.LockdownVpnTracker; import com.android.server.net.NetworkPolicyManagerInternal; +import com.android.server.utils.PriorityDump; import com.google.android.collect.Lists; @@ -682,6 +683,28 @@ public class ConnectivityService extends IConnectivityManager.Stub } private LegacyTypeTracker mLegacyTypeTracker = new LegacyTypeTracker(); + /** + * Helper class which parses out priority arguments and dumps sections according to their + * priority. If priority arguments are omitted, function calls the legacy dump command. + */ + private final PriorityDump.PriorityDumper mPriorityDumper = new PriorityDump.PriorityDumper() { + @Override + public void dumpHigh(FileDescriptor fd, PrintWriter pw, String[] args, boolean asProto) { + doDump(fd, pw, new String[] {DIAG_ARG}, asProto); + doDump(fd, pw, new String[] {SHORT_ARG}, asProto); + } + + @Override + public void dumpNormal(FileDescriptor fd, PrintWriter pw, String[] args, boolean asProto) { + doDump(fd, pw, args, asProto); + } + + @Override + public void dump(FileDescriptor fd, PrintWriter pw, String[] args, boolean asProto) { + doDump(fd, pw, args, asProto); + } + }; + public ConnectivityService(Context context, INetworkManagementService netManager, INetworkStatsService statsService, INetworkPolicyManager policyManager) { this(context, netManager, statsService, policyManager, new IpConnectivityLog()); @@ -1862,8 +1885,13 @@ public class ConnectivityService extends IConnectivityManager.Stub @Override protected void dump(FileDescriptor fd, PrintWriter writer, String[] args) { + PriorityDump.dump(mPriorityDumper, fd, writer, args); + } + + private void doDump(FileDescriptor fd, PrintWriter writer, String[] args, boolean asProto) { final IndentingPrintWriter pw = new IndentingPrintWriter(writer, " "); if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return; + if (asProto) return; if (argsContain(args, DIAG_ARG)) { dumpNetworkDiagnostics(pw); diff --git a/services/core/java/com/android/server/InputMethodManagerService.java b/services/core/java/com/android/server/InputMethodManagerService.java index 9da375700a62..f007bcc829b1 100644 --- a/services/core/java/com/android/server/InputMethodManagerService.java +++ b/services/core/java/com/android/server/InputMethodManagerService.java @@ -1470,7 +1470,9 @@ public class InputMethodManagerService extends IInputMethodManager.Stub broadcastFilter.addAction(ACTION_SHOW_INPUT_METHOD_PICKER); mContext.registerReceiver(new ImmsBroadcastReceiver(), broadcastFilter); - buildInputMethodListLocked(true /* resetDefaultEnabledIme */); + final String defaultImiId = mSettings.getSelectedInputMethod(); + final boolean imeSelectedOnBoot = !TextUtils.isEmpty(defaultImiId); + buildInputMethodListLocked(!imeSelectedOnBoot /* resetDefaultEnabledIme */); resetDefaultImeLocked(mContext); updateFromSettingsLocked(true); InputMethodUtils.setNonSelectedSystemImesDisabledUntilUsed(mIPackageManager, diff --git a/services/core/java/com/android/server/am/ActivityDisplay.java b/services/core/java/com/android/server/am/ActivityDisplay.java index 29073cb68c04..c04ddf8ae6de 100644 --- a/services/core/java/com/android/server/am/ActivityDisplay.java +++ b/services/core/java/com/android/server/am/ActivityDisplay.java @@ -604,7 +604,7 @@ class ActivityDisplay extends ConfigurationContainer<ActivityStack> { public void writeToProto(ProtoOutputStream proto, long fieldId) { final long token = proto.start(fieldId); - super.writeToProto(proto, CONFIGURATION_CONTAINER); + super.writeToProto(proto, CONFIGURATION_CONTAINER, false /* trim */); proto.write(ID, mDisplayId); for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) { final ActivityStack stack = mStacks.get(stackNdx); diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index a513e140ba2b..f2e049325497 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -23,17 +23,20 @@ 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; +import static android.Manifest.permission.REMOVE_TASKS; import static android.Manifest.permission.START_TASKS_FROM_RECENTS; import static android.app.ActivityManager.DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT; import static android.app.ActivityManager.LOCK_TASK_MODE_NONE; import static android.app.ActivityManager.RESIZE_MODE_PRESERVE_WINDOW; import static android.app.ActivityManager.StackId.INVALID_STACK_ID; import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD; +import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED; import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM; import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN; import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN_OR_SPLIT_SCREEN_SECONDARY; import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED; import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY; +import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED; import static android.content.pm.PackageManager.FEATURE_ACTIVITIES_ON_SECONDARY_DISPLAYS; import static android.content.pm.PackageManager.FEATURE_FREEFORM_WINDOW_MANAGEMENT; import static android.content.pm.PackageManager.FEATURE_LEANBACK_ONLY; @@ -50,9 +53,10 @@ import static android.content.res.Configuration.UI_MODE_TYPE_TELEVISION; import static android.net.NetworkPolicyManager.isProcStateAllowedWhileIdleOrPowerSaveMode; import static android.net.NetworkPolicyManager.isProcStateAllowedWhileOnRestrictBackground; import static android.os.Build.VERSION_CODES.N; -import static android.os.IServiceManager.DUMP_PRIORITY_CRITICAL; -import static android.os.IServiceManager.DUMP_PRIORITY_HIGH; -import static android.os.IServiceManager.DUMP_PRIORITY_NORMAL; +import static android.os.IServiceManager.DUMP_FLAG_PRIORITY_CRITICAL; +import static android.os.IServiceManager.DUMP_FLAG_PRIORITY_HIGH; +import static android.os.IServiceManager.DUMP_FLAG_PRIORITY_NORMAL; +import static android.os.IServiceManager.DUMP_FLAG_PROTO; import static android.os.Process.BLUETOOTH_UID; import static android.os.Process.FIRST_APPLICATION_UID; import static android.os.Process.FIRST_ISOLATED_UID; @@ -227,6 +231,8 @@ import android.app.PictureInPictureParams; import android.app.ProfilerInfo; import android.app.RemoteAction; import android.app.WaitResult; +import android.app.WindowConfiguration.ActivityType; +import android.app.WindowConfiguration.WindowingMode; import android.app.admin.DevicePolicyManager; import android.app.assist.AssistContent; import android.app.assist.AssistStructure; @@ -668,7 +674,7 @@ public class ActivityManagerService extends IActivityManager.Stub /** * List of intents that were used to start the most recent tasks. */ - final RecentTasks mRecentTasks; + private final RecentTasks mRecentTasks; /** * For addAppTask: cached of the last activity component that was added. @@ -717,30 +723,36 @@ public class ActivityManagerService extends IActivityManager.Stub */ private final PriorityDump.PriorityDumper mPriorityDumper = new PriorityDump.PriorityDumper() { @Override - public void dumpCritical(FileDescriptor fd, PrintWriter pw, String[] args) { - doDump(fd, pw, new String[] {"activities"}); + public void dumpCritical(FileDescriptor fd, PrintWriter pw, String[] args, + boolean asProto) { + if (asProto) return; + doDump(fd, pw, new String[]{"activities"}, asProto); } @Override - public void dumpNormal(FileDescriptor fd, PrintWriter pw, String[] args) { - doDump(fd, pw, new String[] {"settings"}); - doDump(fd, pw, new String[] {"intents"}); - doDump(fd, pw, new String[] {"broadcasts"}); - doDump(fd, pw, new String[] {"providers"}); - doDump(fd, pw, new String[] {"permissions"}); - doDump(fd, pw, new String[] {"services"}); - doDump(fd, pw, new String[] {"recents"}); - doDump(fd, pw, new String[] {"lastanr"}); - doDump(fd, pw, new String[] {"starter"}); - if (mAssociations.size() > 0) { - doDump(fd, pw, new String[] {"associations"}); - } - doDump(fd, pw, new String[] {"processes"}); + public void dumpNormal(FileDescriptor fd, PrintWriter pw, String[] args, boolean asProto) { + if (asProto) { + doDump(fd, pw, new String[0], asProto); + } else { + doDump(fd, pw, new String[]{"settings"}, asProto); + doDump(fd, pw, new String[]{"intents"}, asProto); + doDump(fd, pw, new String[]{"broadcasts"}, asProto); + doDump(fd, pw, new String[]{"providers"}, asProto); + doDump(fd, pw, new String[]{"permissions"}, asProto); + doDump(fd, pw, new String[]{"services"}, asProto); + doDump(fd, pw, new String[]{"recents"}, asProto); + doDump(fd, pw, new String[]{"lastanr"}, asProto); + doDump(fd, pw, new String[]{"starter"}, asProto); + if (mAssociations.size() > 0) { + doDump(fd, pw, new String[]{"associations"}, asProto); + } + doDump(fd, pw, new String[]{"processes"}, asProto); + } } @Override - public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { - doDump(fd, pw, args); + public void dump(FileDescriptor fd, PrintWriter pw, String[] args, boolean asProto) { + doDump(fd, pw, args, asProto); } }; @@ -2033,7 +2045,9 @@ public class ActivityManagerService extends IActivityManager.Stub synchronized (ActivityManagerService.this) { for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { ProcessRecord r = mLruProcesses.get(i); - if (r.thread != null) { + // Don't dispatch to isolated processes as they can't access + // ConnectivityManager and don't have network privileges anyway. + if (r.thread != null && !r.isolated) { try { r.thread.setHttpProxy(host, port, exclList, pacFileUrl); } catch (RemoteException ex) { @@ -2486,15 +2500,15 @@ public class ActivityManagerService extends IActivityManager.Stub public void setSystemProcess() { try { ServiceManager.addService(Context.ACTIVITY_SERVICE, this, /* allowIsolated= */ true, - DUMP_PRIORITY_CRITICAL | DUMP_PRIORITY_NORMAL); + DUMP_FLAG_PRIORITY_CRITICAL | DUMP_FLAG_PRIORITY_NORMAL | DUMP_FLAG_PROTO); ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats); ServiceManager.addService("meminfo", new MemBinder(this), /* allowIsolated= */ false, - DUMP_PRIORITY_HIGH | DUMP_PRIORITY_NORMAL); + DUMP_FLAG_PRIORITY_HIGH | DUMP_FLAG_PRIORITY_NORMAL); ServiceManager.addService("gfxinfo", new GraphicsBinder(this)); ServiceManager.addService("dbinfo", new DbBinder(this)); if (MONITOR_CPU_USAGE) { ServiceManager.addService("cpuinfo", new CpuBinder(this), - /* allowIsolated= */ false, DUMP_PRIORITY_CRITICAL); + /* allowIsolated= */ false, DUMP_FLAG_PRIORITY_CRITICAL); } ServiceManager.addService("permission", new PermissionController(this)); ServiceManager.addService("processinfo", new ProcessInfoService(this)); @@ -2547,7 +2561,9 @@ public class ActivityManagerService extends IActivityManager.Stub private final PriorityDump.PriorityDumper mPriorityDumper = new PriorityDump.PriorityDumper() { @Override - public void dumpNormal(FileDescriptor fd, PrintWriter pw, String[] args) { + public void dumpNormal(FileDescriptor fd, PrintWriter pw, String[] args, + boolean asProto) { + if (asProto) return; mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, false, null); } }; @@ -2597,7 +2613,9 @@ public class ActivityManagerService extends IActivityManager.Stub private final PriorityDump.PriorityDumper mPriorityDumper = new PriorityDump.PriorityDumper() { @Override - public void dumpCritical(FileDescriptor fd, PrintWriter pw, String[] args) { + public void dumpCritical(FileDescriptor fd, PrintWriter pw, String[] args, + boolean asProto) { + if (asProto) return; if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext, "cpuinfo", pw)) return; synchronized (mActivityManagerService.mProcessCpuTracker) { @@ -2767,7 +2785,7 @@ public class ActivityManagerService extends IActivityManager.Stub mTaskChangeNotificationController = new TaskChangeNotificationController(this, mStackSupervisor, mHandler); mActivityStarter = new ActivityStarter(this); - mRecentTasks = new RecentTasks(this, mStackSupervisor); + mRecentTasks = createRecentTasks(); mStackSupervisor.setRecentTasks(mRecentTasks); mLockTaskController = new LockTaskController(mContext, mStackSupervisor, mHandler); @@ -2813,6 +2831,14 @@ public class ActivityManagerService extends IActivityManager.Stub return new ActivityStackSupervisor(this, mHandler.getLooper()); } + protected RecentTasks createRecentTasks() { + return new RecentTasks(this, mStackSupervisor); + } + + RecentTasks getRecentTasks() { + return mRecentTasks; + } + public void setSystemServiceManager(SystemServiceManager mgr) { mSystemServiceManager = mgr; } @@ -3148,6 +3174,7 @@ public class ActivityManagerService extends IActivityManager.Stub synchronized (this) { final ActivityStack stack = mStackSupervisor.getStack(stackId); if (stack == null) { + Slog.w(TAG, "setFocusedStack: No stack with id=" + stackId); return; } final ActivityRecord r = stack.topRunningActivityLocked(); @@ -3184,7 +3211,8 @@ public class ActivityManagerService extends IActivityManager.Stub /** Sets the task stack listener that gets callbacks when a task stack changes. */ @Override public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException { - enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "registerTaskStackListener()"); + enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, + "registerTaskStackListener()"); mTaskChangeNotificationController.registerTaskStackListener(listener); } @@ -3193,7 +3221,8 @@ public class ActivityManagerService extends IActivityManager.Stub */ @Override public void unregisterTaskStackListener(ITaskStackListener listener) throws RemoteException { - enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "unregisterTaskStackListener()"); + enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, + "unregisterTaskStackListener()"); mTaskChangeNotificationController.unregisterTaskStackListener(listener); } @@ -4871,12 +4900,9 @@ public class ActivityManagerService extends IActivityManager.Stub @Override public final int startActivityFromRecents(int taskId, Bundle bOptions) { - if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) { - String msg = "Permission Denial: startActivityFromRecents called without " + - START_TASKS_FROM_RECENTS; - Slog.w(TAG, msg); - throw new SecurityException(msg); - } + enforceCallerIsRecentsOrHasPermission(START_TASKS_FROM_RECENTS, + "startActivityFromRecents()"); + final long origId = Binder.clearCallingIdentity(); try { synchronized (this) { @@ -8328,9 +8354,6 @@ public class ActivityManagerService extends IActivityManager.Stub } } - /** - * This can be called with or without the global lock held. - */ int checkComponentPermission(String permission, int pid, int uid, int owningUid, boolean exported) { if (pid == MY_PID) { @@ -8405,6 +8428,15 @@ public class ActivityManagerService extends IActivityManager.Stub } /** + * This can be called with or without the global lock held. + */ + void enforceCallerIsRecentsOrHasPermission(String permission, String func) { + if (!mRecentTasks.isCallerRecents(Binder.getCallingUid())) { + enforceCallingPermission(permission, func); + } + } + + /** * Determine if UID is holding permissions required to access {@link Uri} in * the given {@link ProviderInfo}. Final permission checking is always done * in {@link ContentProvider}. @@ -9770,25 +9802,34 @@ public class ActivityManagerService extends IActivityManager.Stub } @Override - public List<RunningTaskInfo> getTasks(int maxNum, int flags) { + public List<RunningTaskInfo> getTasks(int maxNum) { + return getFilteredTasks(maxNum, ACTIVITY_TYPE_UNDEFINED, WINDOWING_MODE_UNDEFINED); + } + + @Override + public List<RunningTaskInfo> getFilteredTasks(int maxNum, @ActivityType int ignoreActivityType, + @WindowingMode int ignoreWindowingMode) { final int callingUid = Binder.getCallingUid(); - ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>(); + ArrayList<RunningTaskInfo> list = new ArrayList<>(); synchronized(this) { - if (DEBUG_ALL) Slog.v( - TAG, "getTasks: max=" + maxNum + ", flags=" + flags); + if (DEBUG_ALL) Slog.v(TAG, "getTasks: max=" + maxNum); final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(), callingUid); - - // TODO: Improve with MRU list from all ActivityStacks. - mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed); + mStackSupervisor.getRunningTasks(maxNum, list, ignoreActivityType, + ignoreWindowingMode, callingUid, allowed); } return list; } private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) { + if (mRecentTasks.isCallerRecents(callingUid)) { + // Always allow the recents component to get tasks + return true; + } + boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS, callingPid, callingUid) == PackageManager.PERMISSION_GRANTED; if (!allowed) { @@ -9836,8 +9877,7 @@ public class ActivityManagerService extends IActivityManager.Stub @Override public ActivityManager.TaskDescription getTaskDescription(int id) { synchronized (this) { - enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, - "getTaskDescription()"); + enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "getTaskDescription()"); final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(id, MATCH_TASK_IN_STACKS_OR_RECENT_TASKS); if (tr != null) { @@ -10031,7 +10071,8 @@ public class ActivityManagerService extends IActivityManager.Stub @Override public void cancelTaskWindowTransition(int taskId) { - enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "cancelTaskWindowTransition()"); + enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, + "cancelTaskWindowTransition()"); final long ident = Binder.clearCallingIdentity(); try { synchronized (this) { @@ -10050,7 +10091,8 @@ public class ActivityManagerService extends IActivityManager.Stub @Override public void cancelTaskThumbnailTransition(int taskId) { - enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "cancelTaskThumbnailTransition()"); + enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, + "cancelTaskThumbnailTransition()"); final long ident = Binder.clearCallingIdentity(); try { synchronized (this) { @@ -10069,7 +10111,7 @@ public class ActivityManagerService extends IActivityManager.Stub @Override public TaskSnapshot getTaskSnapshot(int taskId, boolean reducedResolution) { - enforceCallingPermission(READ_FRAME_BUFFER, "getTaskSnapshot()"); + enforceCallerIsRecentsOrHasPermission(READ_FRAME_BUFFER, "getTaskSnapshot()"); final long ident = Binder.clearCallingIdentity(); try { final TaskRecord task; @@ -10122,12 +10164,13 @@ public class ActivityManagerService extends IActivityManager.Stub @Override public void removeStack(int stackId) { - enforceCallingPermission(Manifest.permission.MANAGE_ACTIVITY_STACKS, "removeStack()"); + enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "removeStack()"); synchronized (this) { final long ident = Binder.clearCallingIdentity(); try { final ActivityStack stack = mStackSupervisor.getStack(stackId); if (stack == null) { + Slog.w(TAG, "removeStack: No stack with id=" + stackId); return; } if (!stack.isActivityTypeStandardOrUndefined()) { @@ -10147,7 +10190,8 @@ public class ActivityManagerService extends IActivityManager.Stub */ @Override public void removeStacksInWindowingModes(int[] windowingModes) { - enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "removeStacksInWindowingModes()"); + enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, + "removeStacksInWindowingModes()"); synchronized (this) { final long ident = Binder.clearCallingIdentity(); try { @@ -10160,7 +10204,8 @@ public class ActivityManagerService extends IActivityManager.Stub @Override public void removeStacksWithActivityTypes(int[] activityTypes) { - enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "removeStacksWithActivityTypes()"); + enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, + "removeStacksWithActivityTypes()"); synchronized (this) { final long ident = Binder.clearCallingIdentity(); try { @@ -10189,7 +10234,7 @@ public class ActivityManagerService extends IActivityManager.Stub @Override public boolean removeTask(int taskId) { - enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, "removeTask()"); + enforceCallerIsRecentsOrHasPermission(REMOVE_TASKS, "removeTask()"); synchronized (this) { final long ident = Binder.clearCallingIdentity(); try { @@ -10366,7 +10411,7 @@ public class ActivityManagerService extends IActivityManager.Stub @Override public void setTaskWindowingMode(int taskId, int windowingMode, boolean toTop) { - enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setTaskWindowingMode()"); + enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "setTaskWindowingMode()"); synchronized (this) { final long ident = Binder.clearCallingIdentity(); try { @@ -10402,7 +10447,7 @@ public class ActivityManagerService extends IActivityManager.Stub @Override public void moveTaskToStack(int taskId, int stackId, boolean toTop) { - enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToStack()"); + enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToStack()"); synchronized (this) { long ident = Binder.clearCallingIdentity(); try { @@ -10453,7 +10498,7 @@ public class ActivityManagerService extends IActivityManager.Stub @Override public boolean moveTaskToDockedStack(int taskId, int createMode, boolean toTop, boolean animate, Rect initialBounds) { - enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToDockedStack()"); + enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToDockedStack()"); synchronized (this) { long ident = Binder.clearCallingIdentity(); try { @@ -10492,12 +10537,16 @@ public class ActivityManagerService extends IActivityManager.Stub */ @Override public void dismissSplitScreenMode(boolean toTop) { - enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "dismissSplitScreenMode()"); + enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "dismissSplitScreenMode()"); final long ident = Binder.clearCallingIdentity(); try { synchronized (this) { final ActivityStack stack = mStackSupervisor.getDefaultDisplay().getSplitScreenPrimaryStack(); + if (stack == null) { + Slog.w(TAG, "dismissSplitScreenMode: primary split-screen stack not found."); + return; + } if (toTop) { mStackSupervisor.resizeStackLocked(stack, null /* destBounds */, null /* tempTaskBounds */, null /* tempTaskInsetBounds */, @@ -10520,14 +10569,14 @@ public class ActivityManagerService extends IActivityManager.Stub */ @Override public void dismissPip(boolean animate, int animationDuration) { - enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "dismissPip()"); + enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "dismissPip()"); final long ident = Binder.clearCallingIdentity(); try { synchronized (this) { final PinnedActivityStack stack = mStackSupervisor.getDefaultDisplay().getPinnedStack(); - if (stack == null) { + Slog.w(TAG, "dismissPip: pinned stack not found."); return; } if (stack.getWindowingMode() != WINDOWING_MODE_PINNED) { @@ -10557,7 +10606,8 @@ public class ActivityManagerService extends IActivityManager.Stub */ @Override public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) { - enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTopActivityToPinnedStack()"); + enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, + "moveTopActivityToPinnedStack()"); synchronized (this) { if (!mSupportsPictureInPicture) { throw new IllegalStateException("moveTopActivityToPinnedStack:" @@ -10576,13 +10626,14 @@ public class ActivityManagerService extends IActivityManager.Stub @Override public void resizeStack(int stackId, Rect destBounds, boolean allowResizeInDockedMode, boolean preserveWindows, boolean animate, int animationDuration) { - enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeStack()"); + enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "resizeStack()"); long ident = Binder.clearCallingIdentity(); try { synchronized (this) { if (animate) { final PinnedActivityStack stack = mStackSupervisor.getStack(stackId); if (stack == null) { + Slog.w(TAG, "resizeStack: stackId " + stackId + " not found."); return; } if (stack.getWindowingMode() != WINDOWING_MODE_PINNED) { @@ -10611,8 +10662,7 @@ public class ActivityManagerService extends IActivityManager.Stub public void resizeDockedStack(Rect dockedBounds, Rect tempDockedTaskBounds, Rect tempDockedTaskInsetBounds, Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds) { - enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, - "resizeDockedStack()"); + enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "resizeDockedStack()"); long ident = Binder.clearCallingIdentity(); try { synchronized (this) { @@ -10627,8 +10677,7 @@ public class ActivityManagerService extends IActivityManager.Stub @Override public void resizePinnedStack(Rect pinnedBounds, Rect tempPinnedTaskBounds) { - enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, - "resizePinnedStack()"); + enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "resizePinnedStack()"); final long ident = Binder.clearCallingIdentity(); try { synchronized (this) { @@ -10687,7 +10736,7 @@ public class ActivityManagerService extends IActivityManager.Stub @Override public List<StackInfo> getAllStackInfos() { - enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getAllStackInfos()"); + enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "getAllStackInfos()"); long ident = Binder.clearCallingIdentity(); try { synchronized (this) { @@ -10700,7 +10749,7 @@ public class ActivityManagerService extends IActivityManager.Stub @Override public StackInfo getStackInfo(int windowingMode, int activityType) { - enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()"); + enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()"); long ident = Binder.clearCallingIdentity(); try { synchronized (this) { @@ -10743,6 +10792,20 @@ public class ActivityManagerService extends IActivityManager.Stub } } + @Override + public void updateLockTaskFeatures(int userId, int flags) { + final int callingUid = Binder.getCallingUid(); + if (callingUid != 0 && callingUid != SYSTEM_UID) { + enforceCallingPermission(android.Manifest.permission.UPDATE_LOCK_TASK_PACKAGES, + "updateLockTaskFeatures()"); + } + synchronized (this) { + if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Allowing features " + userId + ":0x" + + Integer.toHexString(flags)); + mLockTaskController.updateLockTaskFeatures(userId, flags); + } + } + private void startLockTaskModeLocked(@Nullable TaskRecord task, boolean isAppPinning) { if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task); if (task == null || task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) { @@ -11861,8 +11924,7 @@ public class ActivityManagerService extends IActivityManager.Stub @Override public void appNotRespondingViaProvider(IBinder connection) { - enforceCallingPermission( - android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()"); + enforceCallingPermission(REMOVE_TASKS, "appNotRespondingViaProvider()"); final ContentProviderConnection conn = (ContentProviderConnection) connection; if (conn == null) { @@ -13896,6 +13958,9 @@ public class ActivityManagerService extends IActivityManager.Stub com.android.internal.R.string.config_appsNotReportingCrashes)); mUserController.mUserSwitchUiEnabled = !res.getBoolean( com.android.internal.R.bool.config_customUserSwitchUi); + mUserController.mMaxRunningUsers = res.getInteger( + com.android.internal.R.integer.config_multiuserMaxRunningUsers); + if ((globalConfig.uiMode & UI_MODE_TYPE_TELEVISION) == UI_MODE_TYPE_TELEVISION) { mFullscreenThumbnailScale = (float) res .getInteger(com.android.internal.R.integer.thumbnail_width_tv) / @@ -14810,7 +14875,7 @@ public class ActivityManagerService extends IActivityManager.Stub /** * Wrapper function to print out debug data filtered by specified arguments. */ - private void doDump(FileDescriptor fd, PrintWriter pw, String[] args) { + private void doDump(FileDescriptor fd, PrintWriter pw, String[] args, boolean useProto) { if (!DumpUtils.checkDumpAndUsageStatsPermission(mContext, TAG, pw)) return; boolean dumpAll = false; @@ -14819,7 +14884,6 @@ public class ActivityManagerService extends IActivityManager.Stub boolean dumpCheckinFormat = false; boolean dumpVisibleStacksOnly = false; boolean dumpFocusedStackOnly = false; - boolean useProto = false; String dumpPackage = null; int opti = 0; @@ -14853,8 +14917,6 @@ public class ActivityManagerService extends IActivityManager.Stub } else if ("-h".equals(opt)) { ActivityManagerShellCommand.dumpHelp(pw, true); return; - } else if ("--proto".equals(opt)) { - useProto = true; } else { pw.println("Unknown argument: " + opt + "; use -h for help"); } @@ -18125,8 +18187,7 @@ public class ActivityManagerService extends IActivityManager.Stub // ========================================================= @Override - public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, - int flags) { + public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, int flags) { enforceNotIsolatedCaller("getServices"); final int callingUid = Binder.getCallingUid(); @@ -20070,7 +20131,7 @@ public class ActivityManagerService extends IActivityManager.Stub @Override public StackInfo getFocusedStackInfo() throws RemoteException { - enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()"); + enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()"); long ident = Binder.clearCallingIdentity(); try { synchronized (this) { @@ -20110,7 +20171,8 @@ public class ActivityManagerService extends IActivityManager.Stub @Override // TODO: API should just be about changing windowing modes... public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) { - enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTasksToFullscreenStack()"); + enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, + "moveTasksToFullscreenStack()"); synchronized (this) { final long origId = Binder.clearCallingIdentity(); try { diff --git a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java index 4cf2794c3584..f9422656c7db 100644 --- a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java +++ b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java @@ -2305,7 +2305,7 @@ final class ActivityManagerShellCommand extends ShellCommand { int runWrite(PrintWriter pw) { mInternal.enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, "registerUidObserver()"); - mInternal.mRecentTasks.flush(); + mInternal.getRecentTasks().flush(); pw.println("All tasks persisted."); return 0; } diff --git a/services/core/java/com/android/server/am/ActivityRecord.java b/services/core/java/com/android/server/am/ActivityRecord.java index b47f81948edb..2f0b64918bf9 100644 --- a/services/core/java/com/android/server/am/ActivityRecord.java +++ b/services/core/java/com/android/server/am/ActivityRecord.java @@ -204,7 +204,6 @@ final class ActivityRecord extends ConfigurationContainer implements AppWindowCo private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY; private static final boolean SHOW_ACTIVITY_START_TIME = true; - private static final String RECENTS_PACKAGE_NAME = "com.android.systemui.recents"; private static final String ATTR_ID = "id"; private static final String TAG_INTENT = "intent"; @@ -1058,7 +1057,7 @@ final class ActivityRecord extends ConfigurationContainer implements AppWindowCo // We only allow home activities to be resizeable if they explicitly requested it. info.resizeMode = RESIZE_MODE_UNRESIZEABLE; } - } else if (realActivity.getClassName().contains(RECENTS_PACKAGE_NAME)) { + } else if (service.getRecentTasks().isRecentsComponent(realActivity, appInfo.uid)) { activityType = ACTIVITY_TYPE_RECENTS; } else if (options != null && options.getLaunchActivityType() == ACTIVITY_TYPE_ASSISTANT && canLaunchAssistActivity(launchedFromPackage)) { @@ -1562,17 +1561,7 @@ final class ActivityRecord extends ConfigurationContainer implements AppWindowCo return false; } - boolean isVisible = !behindFullscreenActivity || mLaunchTaskBehind; - - if (service.mSupportsLeanbackOnly && isVisible && isActivityTypeRecents()) { - // On devices that support leanback only (Android TV), Recents activity can only be - // visible if the home stack is the focused stack or we are in split-screen mode. - final ActivityDisplay display = getDisplay(); - boolean hasSplitScreenStack = display != null && display.hasSplitScreenPrimaryStack(); - isVisible = hasSplitScreenStack || mStackSupervisor.isFocusedStack(getStack()); - } - - return isVisible; + return !behindFullscreenActivity || mLaunchTaskBehind; } void makeVisibleIfNeeded(ActivityRecord starting) { @@ -2074,7 +2063,7 @@ final class ActivityRecord extends ConfigurationContainer implements AppWindowCo final File iconFile = new File(TaskPersister.getUserImagesDir(task.userId), iconFilename); final String iconFilePath = iconFile.getAbsolutePath(); - service.mRecentTasks.saveImage(icon, iconFilePath); + service.getRecentTasks().saveImage(icon, iconFilePath); _taskDescription.setIconFilename(iconFilePath); } taskDescription = _taskDescription; @@ -2821,7 +2810,7 @@ final class ActivityRecord extends ConfigurationContainer implements AppWindowCo public void writeToProto(ProtoOutputStream proto, long fieldId) { final long token = proto.start(fieldId); - super.writeToProto(proto, CONFIGURATION_CONTAINER); + super.writeToProto(proto, CONFIGURATION_CONTAINER, false /* trim */); writeIdentifierToProto(proto, IDENTIFIER); proto.write(STATE, state.toString()); proto.write(VISIBLE, visible); diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java index bafcce7bdefe..ba41bd4c3b6f 100644 --- a/services/core/java/com/android/server/am/ActivityStack.java +++ b/services/core/java/com/android/server/am/ActivityStack.java @@ -99,6 +99,8 @@ import android.app.ActivityOptions; import android.app.AppGlobals; import android.app.IActivityController; import android.app.ResultInfo; +import android.app.WindowConfiguration.ActivityType; +import android.app.WindowConfiguration.WindowingMode; import android.content.ComponentName; import android.content.Intent; import android.content.pm.ActivityInfo; @@ -4605,69 +4607,43 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai return didSomething; } - void getTasksLocked(List<RunningTaskInfo> list, int callingUid, boolean allowed) { + /** + * @return The set of running tasks through {@param tasksOut} that are available to the caller. + * If {@param ignoreActivityType} or {@param ignoreWindowingMode} are not undefined, + * then skip running tasks that match those types. + */ + void getRunningTasks(List<TaskRecord> tasksOut, @ActivityType int ignoreActivityType, + @WindowingMode int ignoreWindowingMode, int callingUid, boolean allowed) { boolean focusedStack = mStackSupervisor.getFocusedStack() == this; boolean topTask = true; 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; } - ActivityRecord r = null; - ActivityRecord top = null; - ActivityRecord tmp; - int numActivities = 0; - int numRunning = 0; - final ArrayList<ActivityRecord> activities = task.mActivities; if (!allowed && !task.isActivityTypeHome() && task.effectiveUid != callingUid) { + // Skip if the caller can't fetch this task continue; } - for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { - tmp = activities.get(activityNdx); - if (tmp.finishing) { - continue; - } - r = tmp; - - // Initialize state for next task if needed. - if (top == null || (top.state == ActivityState.INITIALIZING)) { - top = r; - numActivities = numRunning = 0; - } - - // Add 'r' into the current task. - numActivities++; - if (r.app != null && r.app.thread != null) { - numRunning++; - } - - if (DEBUG_ALL) Slog.v( - TAG, r.intent.getComponent().flattenToShortString() - + ": task=" + r.getTask()); + if (ignoreActivityType != ACTIVITY_TYPE_UNDEFINED + && task.getActivityType() == ignoreActivityType) { + // Skip ignored activity type + continue; + } + if (ignoreWindowingMode != WINDOWING_MODE_UNDEFINED + && task.getWindowingMode() == ignoreWindowingMode) { + // Skip ignored windowing mode + continue; } - - RunningTaskInfo ci = new RunningTaskInfo(); - ci.id = task.taskId; - ci.stackId = mStackId; - ci.baseActivity = r.intent.getComponent(); - ci.topActivity = top.intent.getComponent(); - ci.lastActiveTime = task.lastActiveTime; if (focusedStack && topTask) { - // Give the latest time to ensure foreground task can be sorted - // at the first, because lastActiveTime of creating task is 0. - ci.lastActiveTime = SystemClock.elapsedRealtime(); + // For the focused stack top task, update the last stack active time so that it can + // be used to determine the order of the tasks (it may not be set for newly created + // tasks) + task.lastActiveTime = SystemClock.elapsedRealtime(); topTask = false; } - - if (top.getTask() != null) { - ci.description = top.getTask().lastDescription; - } - ci.numActivities = numActivities; - ci.numRunning = numRunning; - ci.supportsSplitScreenMultiWindow = task.supportsSplitScreenWindowingMode(); - ci.resizeMode = task.mResizeMode; - ci.configuration.setTo(task.getConfiguration()); - list.add(ci); + tasksOut.add(task); } } @@ -5023,7 +4999,7 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai public void writeToProto(ProtoOutputStream proto, long fieldId) { final long token = proto.start(fieldId); - super.writeToProto(proto, CONFIGURATION_CONTAINER); + super.writeToProto(proto, CONFIGURATION_CONTAINER, false /* trim */); proto.write(ID, mStackId); for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) { final TaskRecord task = mTaskHistory.get(taskNdx); diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java index 14c0eeae36aa..6ec158efa1cd 100644 --- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java +++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java @@ -110,6 +110,8 @@ import android.app.AppOpsManager; import android.app.ProfilerInfo; import android.app.ResultInfo; import android.app.WaitResult; +import android.app.WindowConfiguration.ActivityType; +import android.app.WindowConfiguration.WindowingMode; import android.content.ComponentName; import android.content.Context; import android.content.Intent; @@ -279,8 +281,12 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D final ActivityManagerService mService; + /** The historial list of recent tasks including inactive tasks */ RecentTasks mRecentTasks; + /** Helper class to abstract out logic for fetching the set of currently running tasks */ + private RunningTasks mRunningTasks; + final ActivityStackSupervisorHandler mHandler; /** Short cut */ @@ -566,6 +572,7 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D public ActivityStackSupervisor(ActivityManagerService service, Looper looper) { mService = service; mHandler = new ActivityStackSupervisorHandler(looper); + mRunningTasks = createRunningTasks(); mActivityMetricsLogger = new ActivityMetricsLogger(this, mService.mContext); mKeyguardController = new KeyguardController(service, this); @@ -578,6 +585,11 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D mRecentTasks.registerCallback(this); } + @VisibleForTesting + RunningTasks createRunningTasks() { + return new RunningTasks(); + } + /** * At the time when the constructor runs, the power manager has not yet been * initialized. So we initialize our wakelocks afterwards. @@ -1152,43 +1164,12 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D return null; } - void getTasksLocked(int maxNum, List<RunningTaskInfo> list, int callingUid, boolean allowed) { - // Gather all of the running tasks for each stack into runningTaskLists. - ArrayList<ArrayList<RunningTaskInfo>> runningTaskLists = new ArrayList<>(); - final int numDisplays = mActivityDisplays.size(); - for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) { - final ActivityDisplay display = mActivityDisplays.valueAt(displayNdx); - for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) { - final ActivityStack stack = display.getChildAt(stackNdx); - ArrayList<RunningTaskInfo> stackTaskList = new ArrayList<>(); - runningTaskLists.add(stackTaskList); - stack.getTasksLocked(stackTaskList, callingUid, allowed); - } - } - - // The lists are already sorted from most recent to oldest. Just pull the most recent off - // each list and add it to list. Stop when all lists are empty or maxNum reached. - while (maxNum > 0) { - long mostRecentActiveTime = Long.MIN_VALUE; - ArrayList<RunningTaskInfo> selectedStackList = null; - final int numTaskLists = runningTaskLists.size(); - for (int stackNdx = 0; stackNdx < numTaskLists; ++stackNdx) { - ArrayList<RunningTaskInfo> stackTaskList = runningTaskLists.get(stackNdx); - if (!stackTaskList.isEmpty()) { - final long lastActiveTime = stackTaskList.get(0).lastActiveTime; - if (lastActiveTime > mostRecentActiveTime) { - mostRecentActiveTime = lastActiveTime; - selectedStackList = stackTaskList; - } - } - } - if (selectedStackList != null) { - list.add(selectedStackList.remove(0)); - --maxNum; - } else { - break; - } - } + @VisibleForTesting + void getRunningTasks(int maxNum, List<RunningTaskInfo> list, + @ActivityType int ignoreActivityType, @WindowingMode int ignoreWindowingMode, + int callingUid, boolean allowed) { + mRunningTasks.getTasks(maxNum, list, ignoreActivityType, ignoreWindowingMode, + mActivityDisplays, callingUid, allowed); } ActivityInfo resolveActivity(Intent intent, ResolveInfo rInfo, int startFlags, @@ -1584,7 +1565,10 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D return false; } if (options != null) { - if (options.getLaunchTaskId() != INVALID_STACK_ID) { + // If a launch task id is specified, then ensure that the caller is the recents + // component or has the START_TASKS_FROM_RECENTS permission + if (options.getLaunchTaskId() != INVALID_TASK_ID + && !mRecentTasks.isCallerRecents(callingUid)) { final int startInTaskPerm = mService.checkPermission(START_TASKS_FROM_RECENTS, callingPid, callingUid); if (startInTaskPerm == PERMISSION_DENIED) { @@ -3692,7 +3676,7 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D } public void writeToProto(ProtoOutputStream proto) { - super.writeToProto(proto, CONFIGURATION_CONTAINER); + super.writeToProto(proto, CONFIGURATION_CONTAINER, false /* trim */); for (int displayNdx = 0; displayNdx < mActivityDisplays.size(); ++displayNdx) { ActivityDisplay activityDisplay = mActivityDisplays.valueAt(displayNdx); activityDisplay.writeToProto(proto, DISPLAYS); diff --git a/services/core/java/com/android/server/am/AppTaskImpl.java b/services/core/java/com/android/server/am/AppTaskImpl.java index 38b3039f1856..17626ea166af 100644 --- a/services/core/java/com/android/server/am/AppTaskImpl.java +++ b/services/core/java/com/android/server/am/AppTaskImpl.java @@ -82,7 +82,7 @@ class AppTaskImpl extends IAppTask.Stub { if (tr == null) { throw new IllegalArgumentException("Unable to find task ID " + mTaskId); } - return RecentTasks.createRecentTaskInfo(tr); + return mService.getRecentTasks().createRecentTaskInfo(tr); } finally { Binder.restoreCallingIdentity(origId); } diff --git a/services/core/java/com/android/server/am/LockTaskController.java b/services/core/java/com/android/server/am/LockTaskController.java index 11daf3f9138b..4b2a08439f2d 100644 --- a/services/core/java/com/android/server/am/LockTaskController.java +++ b/services/core/java/com/android/server/am/LockTaskController.java @@ -19,17 +19,11 @@ package com.android.server.am; import static android.app.ActivityManager.LOCK_TASK_MODE_LOCKED; import static android.app.ActivityManager.LOCK_TASK_MODE_NONE; import static android.app.ActivityManager.LOCK_TASK_MODE_PINNED; -import static android.app.StatusBarManager.DISABLE_BACK; -import static android.app.StatusBarManager.DISABLE_HOME; -import static android.app.StatusBarManager.DISABLE_MASK; -import static android.app.StatusBarManager.DISABLE_NONE; -import static android.app.StatusBarManager.DISABLE_RECENT; import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED; import static android.content.Context.DEVICE_POLICY_SERVICE; import static android.content.Context.STATUS_BAR_SERVICE; import static android.os.UserHandle.USER_ALL; import static android.os.UserHandle.USER_CURRENT; -import static android.provider.Settings.Secure.LOCK_TO_APP_EXIT_LOCKED; import static android.view.Display.DEFAULT_DISPLAY; import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKTASK; @@ -46,7 +40,10 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.app.Activity; import android.app.ActivityManager; +import android.app.StatusBarManager; +import android.app.admin.DevicePolicyManager; import android.app.admin.IDevicePolicyManager; +import android.content.ComponentName; import android.content.Context; import android.os.Binder; import android.os.Debug; @@ -55,6 +52,7 @@ import android.os.IBinder; import android.os.RemoteException; import android.os.ServiceManager; import android.provider.Settings; +import android.util.Pair; import android.util.Slog; import android.util.SparseArray; @@ -84,13 +82,39 @@ public class LockTaskController { private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK; @VisibleForTesting - static final int STATUS_BAR_MASK_LOCKED = DISABLE_MASK - & (~DISABLE_BACK); + static final int STATUS_BAR_MASK_LOCKED = StatusBarManager.DISABLE_MASK + & (~StatusBarManager.DISABLE_EXPAND) + & (~StatusBarManager.DISABLE_NOTIFICATION_TICKER) + & (~StatusBarManager.DISABLE_SYSTEM_INFO) + & (~StatusBarManager.DISABLE_BACK); @VisibleForTesting - static final int STATUS_BAR_MASK_PINNED = DISABLE_MASK - & (~DISABLE_BACK) - & (~DISABLE_HOME) - & (~DISABLE_RECENT); + static final int STATUS_BAR_MASK_PINNED = StatusBarManager.DISABLE_MASK + & (~StatusBarManager.DISABLE_BACK) + & (~StatusBarManager.DISABLE_HOME) + & (~StatusBarManager.DISABLE_RECENT); + + private static final SparseArray<Pair<Integer, Integer>> STATUS_BAR_FLAG_MAP_LOCKED; + static { + STATUS_BAR_FLAG_MAP_LOCKED = new SparseArray<>(); + + STATUS_BAR_FLAG_MAP_LOCKED.append(DevicePolicyManager.LOCK_TASK_FEATURE_SYSTEM_INFO, + new Pair<>(StatusBarManager.DISABLE_CLOCK, StatusBarManager.DISABLE2_SYSTEM_ICONS)); + + STATUS_BAR_FLAG_MAP_LOCKED.append(DevicePolicyManager.LOCK_TASK_FEATURE_NOTIFICATIONS, + new Pair<>(StatusBarManager.DISABLE_NOTIFICATION_ICONS + | StatusBarManager.DISABLE_NOTIFICATION_ALERTS, + StatusBarManager.DISABLE2_NOTIFICATION_SHADE)); + + STATUS_BAR_FLAG_MAP_LOCKED.append(DevicePolicyManager.LOCK_TASK_FEATURE_HOME, + new Pair<>(StatusBarManager.DISABLE_HOME, StatusBarManager.DISABLE2_NONE)); + + STATUS_BAR_FLAG_MAP_LOCKED.append(DevicePolicyManager.LOCK_TASK_FEATURE_RECENTS, + new Pair<>(StatusBarManager.DISABLE_RECENT, StatusBarManager.DISABLE2_NONE)); + + STATUS_BAR_FLAG_MAP_LOCKED.append(DevicePolicyManager.LOCK_TASK_FEATURE_GLOBAL_ACTIONS, + new Pair<>(StatusBarManager.DISABLE_NONE, + StatusBarManager.DISABLE2_GLOBAL_ACTIONS)); + } /** Tag used for disabling of keyguard */ private static final String LOCK_TASK_TAG = "Lock-to-App"; @@ -131,6 +155,11 @@ public class LockTaskController { private final SparseArray<String[]> mLockTaskPackages = new SparseArray<>(); /** + * Features that are allowed by DPC to show during LockTask mode. + */ + private final SparseArray<Integer> mLockTaskFeatures = new SparseArray<>(); + + /** * Store the current lock task mode. Possible values: * {@link ActivityManager#LOCK_TASK_MODE_NONE}, {@link ActivityManager#LOCK_TASK_MODE_LOCKED}, * {@link ActivityManager#LOCK_TASK_MODE_PINNED} @@ -319,30 +348,17 @@ public class LockTaskController { private void performStopLockTask(int userId) { // When lock task ends, we enable the status bars. try { - if (getStatusBarService() != null) { - getStatusBarService().disable(DISABLE_NONE, mToken, - mContext.getPackageName()); + setStatusBarState(LOCK_TASK_MODE_NONE, userId); + setKeyguardState(LOCK_TASK_MODE_NONE, userId); + if (mLockTaskModeState == LOCK_TASK_MODE_PINNED) { + lockKeyguardIfNeeded(); } - mWindowManager.reenableKeyguard(mToken); if (getDevicePolicyManager() != null) { getDevicePolicyManager().notifyLockTaskModeChanged(false, null, userId); } if (mLockTaskModeState == LOCK_TASK_MODE_PINNED) { getLockTaskNotify().showPinningExitToast(); } - try { - boolean shouldLockKeyguard = Settings.Secure.getIntForUser( - mContext.getContentResolver(), - LOCK_TO_APP_EXIT_LOCKED, - USER_CURRENT) != 0; - if (mLockTaskModeState == LOCK_TASK_MODE_PINNED && shouldLockKeyguard) { - mWindowManager.lockNow(null); - mWindowManager.dismissKeyguard(null /* callback */); - getLockPatternUtils().requireCredentialEntry(USER_ALL); - } - } catch (Settings.SettingNotFoundException e) { - // No setting, don't lock. - } } catch (RemoteException ex) { throw new RuntimeException(ex); } finally { @@ -448,16 +464,8 @@ public class LockTaskController { getLockTaskNotify().showPinningStartToast(); } mLockTaskModeState = lockTaskModeState; - if (getStatusBarService() != null) { - int flags = 0; - if (mLockTaskModeState == LOCK_TASK_MODE_LOCKED) { - flags = STATUS_BAR_MASK_LOCKED; - } else if (mLockTaskModeState == LOCK_TASK_MODE_PINNED) { - flags = STATUS_BAR_MASK_PINNED; - } - getStatusBarService().disable(flags, mToken, mContext.getPackageName()); - } - mWindowManager.disableKeyguard(mToken, LOCK_TASK_TAG); + setStatusBarState(lockTaskModeState, userId); + setKeyguardState(lockTaskModeState, userId); if (getDevicePolicyManager() != null) { getDevicePolicyManager().notifyLockTaskModeChanged(true, packageName, userId); } @@ -536,6 +544,135 @@ public class LockTaskController { } /** + * Update the UI features that are enabled for LockTask mode. + * @param userId Which user these feature flags are associated with + * @param flags Bitfield of feature flags + * @see DevicePolicyManager#setLockTaskFeatures(ComponentName, int) + */ + void updateLockTaskFeatures(int userId, int flags) { + int oldFlags = getLockTaskFeaturesForUser(userId); + if (flags == oldFlags) { + return; + } + + mLockTaskFeatures.put(userId, flags); + TaskRecord lockedTask = getLockedTask(); + if (lockedTask != null && userId == lockedTask.userId) { + mHandler.post(() -> { + if (mLockTaskModeState == LOCK_TASK_MODE_LOCKED) { + setStatusBarState(mLockTaskModeState, userId); + setKeyguardState(mLockTaskModeState, userId); + } + }); + } + } + + /** + * Helper method for configuring the status bar disabled state. + * Should only be called on the handler thread to avoid race. + */ + private void setStatusBarState(int lockTaskModeState, int userId) { + IStatusBarService statusBar = getStatusBarService(); + if (statusBar == null) { + Slog.e(TAG, "Can't find StatusBarService"); + return; + } + + // Default state, when lockTaskModeState == LOCK_TASK_MODE_NONE + int flags1 = StatusBarManager.DISABLE_NONE; + int flags2 = StatusBarManager.DISABLE2_NONE; + + if (lockTaskModeState == LOCK_TASK_MODE_PINNED) { + flags1 = STATUS_BAR_MASK_PINNED; + + } else if (lockTaskModeState == LOCK_TASK_MODE_LOCKED) { + int lockTaskFeatures = getLockTaskFeaturesForUser(userId); + Pair<Integer, Integer> statusBarFlags = getStatusBarDisableFlags(lockTaskFeatures); + flags1 = statusBarFlags.first; + flags2 = statusBarFlags.second; + } + + try { + statusBar.disable(flags1, mToken, mContext.getPackageName()); + statusBar.disable2(flags2, mToken, mContext.getPackageName()); + } catch (RemoteException e) { + Slog.e(TAG, "Failed to set status bar flags", e); + } + } + + /** + * Helper method for configuring the keyguard disabled state. + * Should only be called on the handler thread to avoid race. + */ + private void setKeyguardState(int lockTaskModeState, int userId) { + if (lockTaskModeState == LOCK_TASK_MODE_NONE) { + mWindowManager.reenableKeyguard(mToken); + + } else if (lockTaskModeState == LOCK_TASK_MODE_LOCKED) { + int lockTaskFeatures = getLockTaskFeaturesForUser(userId); + if ((DevicePolicyManager.LOCK_TASK_FEATURE_KEYGUARD & lockTaskFeatures) == 0) { + mWindowManager.disableKeyguard(mToken, LOCK_TASK_TAG); + } else { + mWindowManager.reenableKeyguard(mToken); + } + + } else { // lockTaskModeState == LOCK_TASK_MODE_PINNED + mWindowManager.disableKeyguard(mToken, LOCK_TASK_TAG); + } + } + + /** + * Helper method for locking the device immediately. This may be necessary when the device + * leaves the pinned mode. + */ + private void lockKeyguardIfNeeded() { + try { + boolean shouldLockKeyguard = Settings.Secure.getIntForUser( + mContext.getContentResolver(), + Settings.Secure.LOCK_TO_APP_EXIT_LOCKED, + USER_CURRENT) != 0; + if (shouldLockKeyguard) { + mWindowManager.lockNow(null); + mWindowManager.dismissKeyguard(null /* callback */); + getLockPatternUtils().requireCredentialEntry(USER_ALL); + } + } catch (Settings.SettingNotFoundException e) { + // No setting, don't lock. + } + } + + /** + * Translates from LockTask feature flags to StatusBarManager disable and disable2 flags. + * @param lockTaskFlags Bitfield of flags as per + * {@link DevicePolicyManager#setLockTaskFeatures(ComponentName, int)} + * @return A {@link Pair} of {@link StatusBarManager#disable(int)} and + * {@link StatusBarManager#disable2(int)} flags + */ + @VisibleForTesting + Pair<Integer, Integer> getStatusBarDisableFlags(int lockTaskFlags) { + // Everything is disabled by default + int flags1 = StatusBarManager.DISABLE_MASK; + int flags2 = StatusBarManager.DISABLE2_MASK; + for (int i = STATUS_BAR_FLAG_MAP_LOCKED.size() - 1; i >= 0; i--) { + Pair<Integer, Integer> statusBarFlags = STATUS_BAR_FLAG_MAP_LOCKED.valueAt(i); + if ((STATUS_BAR_FLAG_MAP_LOCKED.keyAt(i) & lockTaskFlags) != 0) { + flags1 &= ~statusBarFlags.first; + flags2 &= ~statusBarFlags.second; + } + } + // Some flags are not used for LockTask purposes, so we mask them + flags1 &= STATUS_BAR_MASK_LOCKED; + return new Pair<>(flags1, flags2); + } + + /** + * Gets the cached value of LockTask feature flags for a specific user. + */ + private int getLockTaskFeaturesForUser(int userId) { + return mLockTaskFeatures.get(userId, DevicePolicyManager.LOCK_TASK_FEATURE_NONE); + } + + /** * @return the topmost locked task */ private TaskRecord getLockedTask() { diff --git a/services/core/java/com/android/server/am/RecentTasks.java b/services/core/java/com/android/server/am/RecentTasks.java index ed3f5033a046..0b9e0a23a4e8 100644 --- a/services/core/java/com/android/server/am/RecentTasks.java +++ b/services/core/java/com/android/server/am/RecentTasks.java @@ -37,8 +37,6 @@ import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NA import static com.android.server.am.ActivityStackSupervisor.REMOVE_FROM_RECENTS; import static com.android.server.am.TaskRecord.INVALID_TASK_ID; -import com.google.android.collect.Sets; - import android.app.ActivityManager; import android.app.AppGlobals; import android.content.ComponentName; @@ -58,15 +56,16 @@ import android.os.IBinder; import android.os.RemoteException; import android.os.SystemProperties; import android.os.UserHandle; +import android.text.TextUtils; import android.util.ArraySet; -import android.util.MutableBoolean; -import android.util.MutableInt; import android.util.Slog; import android.util.SparseArray; import android.util.SparseBooleanArray; import com.android.internal.annotations.VisibleForTesting; -import com.android.server.am.ActivityStack.ActivityState; +import com.android.server.am.TaskRecord.TaskActivitiesReport; + +import com.google.android.collect.Sets; import java.io.File; import java.io.PrintWriter; @@ -75,7 +74,6 @@ import java.util.Arrays; import java.util.Collections; import java.util.Comparator; import java.util.HashMap; -import java.util.HashSet; import java.util.Set; import java.util.concurrent.TimeUnit; @@ -126,6 +124,13 @@ class RecentTasks { private final UserController mUserController; /** + * Keeps track of the static recents package/component which is granted additional permissions + * to call recents-related APIs. + */ + private int mRecentsUid = -1; + private ComponentName mRecentsComponent = null; + + /** * Mapping of user id -> whether recent tasks have been loaded for that user. */ private final SparseBooleanArray mUsersWithRecentsLoaded = new SparseBooleanArray( @@ -154,6 +159,7 @@ class RecentTasks { private final HashMap<ComponentName, ActivityInfo> mTmpAvailActCache = new HashMap<>(); private final HashMap<String, ApplicationInfo> mTmpAvailAppCache = new HashMap<>(); private final SparseBooleanArray mTmpQuietProfileUserIds = new SparseBooleanArray(); + private final TaskActivitiesReport mTmpReport = new TaskActivitiesReport(); @VisibleForTesting RecentTasks(ActivityManagerService service, TaskPersister taskPersister, @@ -173,7 +179,7 @@ class RecentTasks { mTaskPersister = new TaskPersister(systemDir, stackSupervisor, service, this); mGlobalMaxNumTasks = ActivityManager.getMaxRecentTasksStatic(); mHasVisibleRecentTasks = res.getBoolean(com.android.internal.R.bool.config_hasRecents); - loadParametersFromResources(service.mContext.getResources()); + loadParametersFromResources(res); } @VisibleForTesting @@ -217,6 +223,47 @@ class RecentTasks { : -1; } + /** + * Loads the static recents component. This is called after the system is ready, but before + * any dependent services (like SystemUI) is started. + */ + void loadRecentsComponent(Resources res) { + final String rawRecentsComponent = res.getString( + com.android.internal.R.string.config_recentsComponentName); + if (TextUtils.isEmpty(rawRecentsComponent)) { + return; + } + + final ComponentName cn = ComponentName.unflattenFromString(rawRecentsComponent); + if (cn != null) { + try { + final ApplicationInfo appInfo = AppGlobals.getPackageManager() + .getApplicationInfo(cn.getPackageName(), 0, mService.mContext.getUserId()); + if (appInfo != null) { + mRecentsUid = appInfo.uid; + mRecentsComponent = cn; + } + } catch (RemoteException e) { + Slog.w(TAG, "Could not load application info for recents component: " + cn); + } + } + } + + /** + * @return whether the current caller has the same uid as the recents component. + */ + boolean isCallerRecents(int callingUid) { + return UserHandle.isSameApp(callingUid, mRecentsUid); + } + + /** + * @return whether the given component is the recents component and shares the same uid as the + * recents component. + */ + boolean isRecentsComponent(ComponentName cn, int uid) { + return cn.equals(mRecentsComponent) && UserHandle.isSameApp(uid, mRecentsUid); + } + void registerCallback(Callbacks callback) { mCallbacks.add(callback); } @@ -339,6 +386,7 @@ class RecentTasks { } void onSystemReadyLocked() { + loadRecentsComponent(mService.mContext.getResources()); mTasks.clear(); mTaskPersister.startPersisting(); } @@ -690,7 +738,7 @@ class RecentTasks { continue; } - ActivityManager.RecentTaskInfo rti = RecentTasks.createRecentTaskInfo(tr); + final ActivityManager.RecentTaskInfo rti = createRecentTaskInfo(tr); if (!getDetailedTasks) { rti.baseIntent.replaceExtras((Bundle)null); } @@ -1327,12 +1375,14 @@ class RecentTasks { void dump(PrintWriter pw, boolean dumpAll, String dumpPackage) { pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)"); + pw.println("mRecentsUid=" + mRecentsUid); + pw.println("mRecentsComponent=" + mRecentsComponent); if (mTasks.isEmpty()) { return; } - final MutableBoolean printedAnything = new MutableBoolean(false); - final MutableBoolean printedHeader = new MutableBoolean(false); + boolean printedAnything = false; + boolean printedHeader = false; final int size = mTasks.size(); for (int i = 0; i < size; i++) { final TaskRecord tr = mTasks.get(i); @@ -1341,10 +1391,10 @@ class RecentTasks { continue; } - if (!printedHeader.value) { + if (!printedHeader) { pw.println(" Recent tasks:"); - printedHeader.value = true; - printedAnything.value = true; + printedHeader = true; + printedAnything = true; } pw.print(" * Recent #"); pw.print(i); pw.print(": "); pw.println(tr); @@ -1353,7 +1403,7 @@ class RecentTasks { } } - if (!printedAnything.value) { + if (!printedAnything) { pw.println(" (nothing)"); } } @@ -1361,7 +1411,7 @@ class RecentTasks { /** * Creates a new RecentTaskInfo from a TaskRecord. */ - static ActivityManager.RecentTaskInfo createRecentTaskInfo(TaskRecord tr) { + ActivityManager.RecentTaskInfo createRecentTaskInfo(TaskRecord tr) { // Update the task description to reflect any changes in the task stack tr.updateTaskDescription(); @@ -1387,24 +1437,10 @@ class RecentTasks { rti.resizeMode = tr.mResizeMode; rti.configuration.setTo(tr.getConfiguration()); - ActivityRecord base = null; - ActivityRecord top = null; - ActivityRecord tmp; - - for (int i = tr.mActivities.size() - 1; i >= 0; --i) { - tmp = tr.mActivities.get(i); - if (tmp.finishing) { - continue; - } - base = tmp; - if (top == null || (top.state == ActivityState.INITIALIZING)) { - top = base; - } - rti.numActivities++; - } - - rti.baseActivity = (base != null) ? base.intent.getComponent() : null; - rti.topActivity = (top != null) ? top.intent.getComponent() : null; + tr.getNumRunningActivities(mTmpReport); + rti.numActivities = mTmpReport.numActivities; + rti.baseActivity = (mTmpReport.base != null) ? mTmpReport.base.intent.getComponent() : null; + rti.topActivity = (mTmpReport.top != null) ? mTmpReport.top.intent.getComponent() : null; return rti; } diff --git a/services/core/java/com/android/server/am/RunningTasks.java b/services/core/java/com/android/server/am/RunningTasks.java new file mode 100644 index 000000000000..400b03a986ed --- /dev/null +++ b/services/core/java/com/android/server/am/RunningTasks.java @@ -0,0 +1,102 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License + */ + +package com.android.server.am; + +import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM; +import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME; + +import android.app.ActivityManager.RunningTaskInfo; +import android.app.WindowConfiguration.ActivityType; +import android.app.WindowConfiguration.WindowingMode; +import android.util.SparseArray; + +import java.util.ArrayList; +import java.util.Comparator; +import java.util.Iterator; +import java.util.List; +import java.util.TreeSet; + +/** + * Class for resolving the set of running tasks in the system. + */ +class RunningTasks { + + // Comparator to sort by last active time (descending) + private static final Comparator<TaskRecord> LAST_ACTIVE_TIME_COMPARATOR = + (o1, o2) -> Long.signum(o2.lastActiveTime - o1.lastActiveTime); + + private final TaskRecord.TaskActivitiesReport mTmpReport = + new TaskRecord.TaskActivitiesReport(); + private final TreeSet<TaskRecord> mTmpSortedSet = new TreeSet<>(LAST_ACTIVE_TIME_COMPARATOR); + private final ArrayList<TaskRecord> mTmpStackTasks = new ArrayList<>(); + + void getTasks(int maxNum, List<RunningTaskInfo> list, @ActivityType int ignoreActivityType, + @WindowingMode int ignoreWindowingMode, SparseArray<ActivityDisplay> activityDisplays, + int callingUid, boolean allowed) { + // For each stack on each display, add the tasks into the sorted set and then pull the first + // {@param maxNum} from the set + + // Gather all of the tasks across all of the tasks, and add them to the sorted set + mTmpSortedSet.clear(); + mTmpStackTasks.clear(); + final int numDisplays = activityDisplays.size(); + for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) { + final ActivityDisplay display = activityDisplays.valueAt(displayNdx); + for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) { + final ActivityStack stack = display.getChildAt(stackNdx); + stack.getRunningTasks(mTmpStackTasks, ignoreActivityType, ignoreWindowingMode, + callingUid, allowed); + for (int i = mTmpStackTasks.size() - 1; i >= 0; i--) { + mTmpSortedSet.addAll(mTmpStackTasks); + } + } + } + + // Take the first {@param maxNum} tasks and create running task infos for them + final Iterator<TaskRecord> iter = mTmpSortedSet.iterator(); + while (iter.hasNext()) { + if (maxNum == 0) { + break; + } + + final TaskRecord task = iter.next(); + list.add(createRunningTaskInfo(task)); + maxNum--; + } + } + + /** + * Constructs a {@link RunningTaskInfo} from a given {@param task}. + */ + private RunningTaskInfo createRunningTaskInfo(TaskRecord task) { + task.getNumRunningActivities(mTmpReport); + + final RunningTaskInfo ci = new RunningTaskInfo(); + ci.id = task.taskId; + ci.stackId = task.getStackId(); + ci.baseActivity = mTmpReport.base.intent.getComponent(); + ci.topActivity = mTmpReport.top.intent.getComponent(); + ci.lastActiveTime = task.lastActiveTime; + ci.description = task.lastDescription; + ci.numActivities = mTmpReport.numActivities; + ci.numRunning = mTmpReport.numRunning; + ci.supportsSplitScreenMultiWindow = task.supportsSplitScreenWindowingMode(); + ci.resizeMode = task.mResizeMode; + ci.configuration.setTo(task.getConfiguration()); + return ci; + } +} diff --git a/services/core/java/com/android/server/am/TaskRecord.java b/services/core/java/com/android/server/am/TaskRecord.java index f04bdb3a81a8..1b5a1ce33cff 100644 --- a/services/core/java/com/android/server/am/TaskRecord.java +++ b/services/core/java/com/android/server/am/TaskRecord.java @@ -112,6 +112,7 @@ import android.util.proto.ProtoOutputStream; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.app.IVoiceInteractor; import com.android.internal.util.XmlUtils; +import com.android.server.am.ActivityStack.ActivityState; import com.android.server.wm.AppWindowContainerController; import com.android.server.wm.ConfigurationContainer; import com.android.server.wm.StackWindowController; @@ -1060,6 +1061,36 @@ class TaskRecord extends ConfigurationContainer implements TaskWindowContainerLi return null; } + /** + * Return the number of running activities, and the number of non-finishing/initializing + * activities in the provided {@param reportOut} respectively. + */ + void getNumRunningActivities(TaskActivitiesReport reportOut) { + reportOut.reset(); + for (int i = mActivities.size() - 1; i >= 0; --i) { + final ActivityRecord r = mActivities.get(i); + if (r.finishing) { + continue; + } + + reportOut.base = r; + + // Increment the total number of non-finishing activities + reportOut.numActivities++; + + if (reportOut.top == null || (reportOut.top.state == ActivityState.INITIALIZING)) { + reportOut.top = r; + // Reset the number of running activities until we hit the first non-initializing + // activity + reportOut.numRunning = 0; + } + if (r.app != null && r.app.thread != null) { + // Increment the number of actually running activities + reportOut.numRunning++; + } + } + } + boolean okToShowLocked() { // NOTE: If {@link TaskRecord#topRunningActivityLocked} return is not null then it is // okay to show the activity when locked. @@ -2205,7 +2236,7 @@ class TaskRecord extends ConfigurationContainer implements TaskWindowContainerLi public void writeToProto(ProtoOutputStream proto, long fieldId) { final long token = proto.start(fieldId); - super.writeToProto(proto, CONFIGURATION_CONTAINER); + super.writeToProto(proto, CONFIGURATION_CONTAINER, false /* trim */); proto.write(ID, taskId); for (int i = mActivities.size() - 1; i >= 0; i--) { ActivityRecord activity = mActivities.get(i); @@ -2231,4 +2262,19 @@ class TaskRecord extends ConfigurationContainer implements TaskWindowContainerLi proto.write(MIN_HEIGHT, mMinHeight); proto.end(token); } + + /** + * See {@link #getNumRunningActivities(TaskActivitiesReport)}. + */ + static class TaskActivitiesReport { + int numRunning; + int numActivities; + ActivityRecord top; + ActivityRecord base; + + void reset() { + numRunning = numActivities = 0; + top = base = null; + } + } } diff --git a/services/core/java/com/android/server/am/UserController.java b/services/core/java/com/android/server/am/UserController.java index a0c5cfaa7908..44f83b0e08fb 100644 --- a/services/core/java/com/android/server/am/UserController.java +++ b/services/core/java/com/android/server/am/UserController.java @@ -117,20 +117,6 @@ import java.util.concurrent.atomic.AtomicInteger; class UserController implements Handler.Callback { private static final String TAG = TAG_WITH_CLASS_NAME ? "UserController" : TAG_AM; - /** - * Maximum number of users we allow to be running at a time, including the system user and - * its profiles. - * Note changing this to 2 is not recommended, since that would mean, if the user uses - * work profile and then switch to a secondary user, then the work profile user would be killed, - * which should work fine, but aggressively killing the work profile user that has just been - * running could cause data loss. (Even without work profile, witching from secondary user A - * to secondary user B would cause similar issues on user B.) - * - * TODO: Consider adding or replacing with "MAX_RUNNING_*SECONDARY*_USERS", which is the max - * number of running *secondary, switchable* users. - */ - static final int MAX_RUNNING_USERS = 3; - // Amount of time we wait for observers to handle a user switch before // giving up on them and unfreezing the screen. static final int USER_SWITCH_TIMEOUT_MS = 3 * 1000; @@ -157,6 +143,17 @@ class UserController implements Handler.Callback { // when it never calls back. private static final int USER_SWITCH_CALLBACKS_TIMEOUT_MS = 5 * 1000; + /** + * Maximum number of users we allow to be running at a time, including system user. + * + * <p>This parameter only affects how many background users will be stopped when switching to a + * new user. It has no impact on {@link #startUser(int, boolean)} behavior. + * + * <p>Note: Current and system user (and their related profiles) are never stopped when + * switching users. Due to that, the actual number of running users can exceed mMaxRunningUsers + */ + int mMaxRunningUsers; + // Lock for internal state. private final Object mLock = new Object(); @@ -245,7 +242,7 @@ class UserController implements Handler.Callback { finishUserBoot(uss); startProfiles(); synchronized (mLock) { - stopRunningUsersLU(MAX_RUNNING_USERS); + stopRunningUsersLU(mMaxRunningUsers); } } @@ -813,7 +810,7 @@ class UserController implements Handler.Callback { } final int profilesToStartSize = profilesToStart.size(); int i = 0; - for (; i < profilesToStartSize && i < (MAX_RUNNING_USERS - 1); ++i) { + for (; i < profilesToStartSize && i < (mMaxRunningUsers - 1); ++i) { startUser(profilesToStart.get(i).id, /* foreground= */ false); } if (i < profilesToStartSize) { @@ -2020,7 +2017,7 @@ class UserController implements Handler.Callback { void loadUserRecents(int userId) { synchronized (mService) { - mService.mRecentTasks.loadUserRecentsLocked(userId); + mService.getRecentTasks().loadUserRecentsLocked(userId); } } diff --git a/services/core/java/com/android/server/display/ColorFade.java b/services/core/java/com/android/server/display/ColorFade.java index 2541050f406d..c2167eb8d1ad 100644 --- a/services/core/java/com/android/server/display/ColorFade.java +++ b/services/core/java/com/android/server/display/ColorFade.java @@ -585,9 +585,11 @@ final class ColorFade { } else { flags = SurfaceControl.OPAQUE | SurfaceControl.HIDDEN; } - mSurfaceControl = new SurfaceControl(mSurfaceSession, - "ColorFade", mDisplayWidth, mDisplayHeight, - PixelFormat.OPAQUE, flags); + mSurfaceControl = new SurfaceControl.Builder(mSurfaceSession) + .setName("ColorFade") + .setSize(mDisplayWidth, mDisplayHeight) + .setFlags(flags) + .build(); } catch (OutOfResourcesException ex) { Slog.e(TAG, "Unable to create surface.", ex); return false; diff --git a/services/core/java/com/android/server/fingerprint/FingerprintService.java b/services/core/java/com/android/server/fingerprint/FingerprintService.java index 1df9c861a666..d0d951b85b40 100644 --- a/services/core/java/com/android/server/fingerprint/FingerprintService.java +++ b/services/core/java/com/android/server/fingerprint/FingerprintService.java @@ -59,9 +59,6 @@ import android.os.SystemClock; import android.os.UserHandle; import android.os.UserManager; import android.security.KeyStore; -import android.service.fingerprint.FingerprintActionStatsProto; -import android.service.fingerprint.FingerprintServiceDumpProto; -import android.service.fingerprint.FingerprintUserStatsProto; import android.util.Slog; import android.util.SparseBooleanArray; import android.util.SparseIntArray; @@ -1374,11 +1371,11 @@ public class FingerprintService extends SystemService implements IHwBinder.Death final PerformanceStats normal = mPerformanceMap.get(userId); if (normal != null) { final long countsToken = proto.start(FingerprintUserStatsProto.NORMAL); - proto.write(FingerprintActionStatsProto.ACCEPT, normal.accept); - proto.write(FingerprintActionStatsProto.REJECT, normal.reject); - proto.write(FingerprintActionStatsProto.ACQUIRE, normal.acquire); - proto.write(FingerprintActionStatsProto.LOCKOUT, normal.lockout); - proto.write(FingerprintActionStatsProto.LOCKOUT_PERMANENT, normal.permanentLockout); + proto.write(PerformanceStatsProto.ACCEPT, normal.accept); + proto.write(PerformanceStatsProto.REJECT, normal.reject); + proto.write(PerformanceStatsProto.ACQUIRE, normal.acquire); + proto.write(PerformanceStatsProto.LOCKOUT, normal.lockout); + proto.write(PerformanceStatsProto.PERMANENT_LOCKOUT, normal.permanentLockout); proto.end(countsToken); } @@ -1387,11 +1384,11 @@ public class FingerprintService extends SystemService implements IHwBinder.Death final PerformanceStats crypto = mCryptoPerformanceMap.get(userId); if (crypto != null) { final long countsToken = proto.start(FingerprintUserStatsProto.CRYPTO); - proto.write(FingerprintActionStatsProto.ACCEPT, crypto.accept); - proto.write(FingerprintActionStatsProto.REJECT, crypto.reject); - proto.write(FingerprintActionStatsProto.ACQUIRE, crypto.acquire); - proto.write(FingerprintActionStatsProto.LOCKOUT, crypto.lockout); - proto.write(FingerprintActionStatsProto.LOCKOUT_PERMANENT, crypto.permanentLockout); + proto.write(PerformanceStatsProto.ACCEPT, crypto.accept); + proto.write(PerformanceStatsProto.REJECT, crypto.reject); + proto.write(PerformanceStatsProto.ACQUIRE, crypto.acquire); + proto.write(PerformanceStatsProto.LOCKOUT, crypto.lockout); + proto.write(PerformanceStatsProto.PERMANENT_LOCKOUT, crypto.permanentLockout); proto.end(countsToken); } diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index acec2cb0cc79..7be0cde4a94d 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -3719,19 +3719,16 @@ public class PackageManagerService extends IPackageManager.Stub * <p> * Currently, there are three cases in which this can occur: * <ol> - * <li>The calling application is a "special" process. The special - * processes are {@link Process#SYSTEM_UID}, {@link Process#SHELL_UID} - * and {@code 0}</li> + * <li>The calling application is a "special" process. Special processes + * are those with a UID < {@link Process#FIRST_APPLICATION_UID}.</li> * <li>The calling application has the permission - * {@link android.Manifest.permission#ACCESS_INSTANT_APPS}</li> + * {@link android.Manifest.permission#ACCESS_INSTANT_APPS}.</li> * <li>The calling application is the default launcher on the * system partition.</li> * </ol> */ private boolean canViewInstantApps(int callingUid, int userId) { - if (callingUid == Process.SYSTEM_UID - || callingUid == Process.SHELL_UID - || callingUid == Process.ROOT_UID) { + if (callingUid < Process.FIRST_APPLICATION_UID) { return true; } if (mContext.checkCallingOrSelfPermission( 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 abe4f5ed44ad..76805ce3a9ff 100644 --- a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java +++ b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java @@ -288,7 +288,18 @@ public class PermissionManagerService { final String[] packages = mContext.getPackageManager().getPackagesForUid(uid); if (packages != null && packages.length > 0) { - final PackageParser.Package pkg = mPackageManagerInt.getPackage(packages[0]); + PackageParser.Package pkg = null; + for (String packageName : packages) { + pkg = mPackageManagerInt.getPackage(packageName); + if (pkg != null) { + break; + } + } + if (pkg == null) { +Slog.e(TAG, "TODD: No package not found; UID: " + uid); +Slog.e(TAG, "TODD: Packages: " + Arrays.toString(packages)); + return PackageManager.PERMISSION_DENIED; + } if (pkg.mSharedUserId != null) { if (isCallerInstantApp) { return PackageManager.PERMISSION_DENIED; @@ -996,8 +1007,6 @@ public class PermissionManagerService { if (!privappPermissionsDisable && privilegedPermission && pkg.isPrivileged() && !platformPackage && platformPermission) { if (!hasPrivappWhitelistEntry(perm, pkg)) { - Slog.w(TAG, "Privileged permission " + perm + " for package " - + pkg.packageName + " - not in privapp-permissions whitelist"); // Only report violations for apps on system image if (!mSystemReady && !pkg.isUpdatedSystemApp()) { // it's only a reportable violation if the permission isn't explicitly denied @@ -1005,12 +1014,16 @@ public class PermissionManagerService { .getPrivAppDenyPermissions(pkg.packageName); final boolean permissionViolation = deniedPermissions == null || !deniedPermissions.contains(perm); - if (permissionViolation - && RoSystemProperties.CONTROL_PRIVAPP_PERMISSIONS_ENFORCE) { - if (mPrivappPermissionsViolations == null) { - mPrivappPermissionsViolations = new ArraySet<>(); + if (permissionViolation) { + Slog.w(TAG, "Privileged permission " + perm + " for package " + + pkg.packageName + " - not in privapp-permissions whitelist"); + + if (RoSystemProperties.CONTROL_PRIVAPP_PERMISSIONS_ENFORCE) { + if (mPrivappPermissionsViolations == null) { + mPrivappPermissionsViolations = new ArraySet<>(); + } + mPrivappPermissionsViolations.add(pkg.packageName + ": " + perm); } - mPrivappPermissionsViolations.add(pkg.packageName + ": " + perm); } else { return false; } diff --git a/services/core/java/com/android/server/power/PowerManagerService.java b/services/core/java/com/android/server/power/PowerManagerService.java index a95a539dd86a..2494bded1b86 100644 --- a/services/core/java/com/android/server/power/PowerManagerService.java +++ b/services/core/java/com/android/server/power/PowerManagerService.java @@ -3702,16 +3702,16 @@ public final class PowerManagerService extends SystemService for (int i = 0; i < mUidState.size(); i++) { final UidState state = mUidState.valueAt(i); - final long uIDToken = proto.start(PowerManagerServiceDumpProto.UIDS); + final long uIDToken = proto.start(PowerManagerServiceDumpProto.UID_STATES); final int uid = mUidState.keyAt(i); - proto.write(PowerManagerServiceDumpProto.UidProto.UID, uid); - proto.write(PowerManagerServiceDumpProto.UidProto.UID_STRING, UserHandle.formatUid(uid)); - proto.write(PowerManagerServiceDumpProto.UidProto.IS_ACTIVE, state.mActive); - proto.write(PowerManagerServiceDumpProto.UidProto.NUM_WAKE_LOCKS, state.mNumWakeLocks); + proto.write(PowerManagerServiceDumpProto.UidStateProto.UID, uid); + proto.write(PowerManagerServiceDumpProto.UidStateProto.UID_STRING, UserHandle.formatUid(uid)); + proto.write(PowerManagerServiceDumpProto.UidStateProto.IS_ACTIVE, state.mActive); + proto.write(PowerManagerServiceDumpProto.UidStateProto.NUM_WAKE_LOCKS, state.mNumWakeLocks); if (state.mProcState == ActivityManager.PROCESS_STATE_UNKNOWN) { - proto.write(PowerManagerServiceDumpProto.UidProto.IS_PROCESS_STATE_UNKNOWN, true); + proto.write(PowerManagerServiceDumpProto.UidStateProto.IS_PROCESS_STATE_UNKNOWN, true); } else { - proto.write(PowerManagerServiceDumpProto.UidProto.PROCESS_STATE, + proto.write(PowerManagerServiceDumpProto.UidStateProto.PROCESS_STATE, ActivityManager.processStateAmToProto(state.mProcState)); } proto.end(uIDToken); diff --git a/services/core/java/com/android/server/utils/PriorityDump.java b/services/core/java/com/android/server/utils/PriorityDump.java index 054f1564730e..fb92c2b8dd2f 100644 --- a/services/core/java/com/android/server/utils/PriorityDump.java +++ b/services/core/java/com/android/server/utils/PriorityDump.java @@ -16,12 +16,19 @@ package com.android.server.utils; +import android.annotation.IntDef; + import java.io.FileDescriptor; import java.io.PrintWriter; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Iterator; /** * Helper for {@link android.os.Binder#dump(java.io.FileDescriptor, String[])} that supports the - * {@link #PRIORITY_ARG} argument. + * {@link #PRIORITY_ARG} and {@link #PROTO_ARG} arguments. * <p> * Typical usage: * @@ -31,13 +38,25 @@ public class SpringfieldNuclearPowerPlant extends Binder { private final PriorityDump.PriorityDumper mPriorityDumper = new PriorityDump.PriorityDumper() { @Override - public void dumpCritical(FileDescriptor fd, PrintWriter pw, String[] args) { - pw.println("Donuts in the box: 1"); + public void dumpCritical(FileDescriptor fd, PrintWriter pw, String[] args, boolean asProto) { + if (asProto) { + ProtoOutputStream proto = new ProtoOutputStream(fd); + proto.write(SpringfieldProto.DONUTS, 1); + proto.flush(); + } else { + pw.println("Donuts in the box: 1"); + } } @Override public void dumpNormal(FileDescriptor fd, PrintWriter pw, String[] args) { - pw.println("Nuclear reactor status: DANGER - MELTDOWN IMMINENT"); + if (asProto) { + ProtoOutputStream proto = new ProtoOutputStream(fd); + proto.write(SpringfieldProto.REACTOR_STATUS, DANGER_MELTDOWN_IMMINENT); + proto.flush(); + } else { + pw.println("Nuclear reactor status: DANGER - MELTDOWN IMMINENT"); + } } }; @@ -65,6 +84,9 @@ public class SpringfieldNuclearPowerPlant extends Binder { $ adb shell dumpsys snpp --dump-priority NORMAL Nuclear reactor status: DANGER - MELTDOWN IMMINENT + $ adb shell dumpsys snpp --dump-priority CRITICAL --proto + //binary output + * </code></pre> * * @@ -85,95 +107,146 @@ public class SpringfieldNuclearPowerPlant extends Binder { public final class PriorityDump { public static final String PRIORITY_ARG = "--dump-priority"; + public static final String PROTO_ARG = "--proto"; private PriorityDump() { throw new UnsupportedOperationException(); } + /** Enum to switch through supported priority types */ + @Retention(RetentionPolicy.SOURCE) + @IntDef({PRIORITY_TYPE_INVALID, PRIORITY_TYPE_CRITICAL, PRIORITY_TYPE_HIGH, + PRIORITY_TYPE_NORMAL}) + private @interface PriorityType { } + private static final int PRIORITY_TYPE_INVALID = 0; + private static final int PRIORITY_TYPE_CRITICAL = 1; + private static final int PRIORITY_TYPE_HIGH = 2; + private static final int PRIORITY_TYPE_NORMAL = 3; + /** - * Parses {@code} and call the proper {@link PriorityDumper} method when the first argument is - * {@code --dump-priority}, stripping the priority and its type. + * Parses {@code args} matching {@code --dump-priority} and/or {@code --proto}. The matching + * arguments are stripped. + * <p> + * If priority args are passed as an argument, it will call the appropriate method and if proto + * args are passed then the {@code asProto} flag is set. * <p> * For example, if called as {@code --dump-priority HIGH arg1 arg2 arg3}, it will call - * <code>dumper.dumpHigh(fd, pw, {"arg1", "arg2", "arg3"}) </code> + * <code>dumper.dumpHigh(fd, pw, {"arg1", "arg2", "arg3"}, false) </code> * <p> * If the {@code --dump-priority} is not set, it calls - * {@link PriorityDumper#dump(FileDescriptor, PrintWriter, String[])} passing the whole + * {@link PriorityDumper#dump(FileDescriptor, PrintWriter, String[], boolean)} passing the whole * {@code args} instead. */ public static void dump(PriorityDumper dumper, FileDescriptor fd, PrintWriter pw, String[] args) { - if (args != null && args.length >= 2 && args[0].equals(PRIORITY_ARG)) { - final String priority = args[1]; - switch (priority) { - case "CRITICAL": { - dumper.dumpCritical(fd, pw, getStrippedArgs(args)); - return; - } - case "HIGH": { - dumper.dumpHigh(fd, pw, getStrippedArgs(args)); - return; - } - case "NORMAL": { - dumper.dumpNormal(fd, pw, getStrippedArgs(args)); - return; + boolean asProto = false; + @PriorityType int priority = PRIORITY_TYPE_INVALID; + + if (args == null) { + dumper.dump(fd, pw, args, asProto); + return; + } + + String[] strippedArgs = new String[args.length]; + int strippedCount = 0; + for (int argIndex = 0; argIndex < args.length; argIndex++) { + if (args[argIndex].equals(PROTO_ARG)) { + asProto = true; + } else if (args[argIndex].equals(PRIORITY_ARG)) { + if (argIndex + 1 < args.length) { + argIndex++; + priority = getPriorityType(args[argIndex]); } + } else { + strippedArgs[strippedCount++] = args[argIndex]; + } + } + + if (strippedCount < args.length) { + strippedArgs = Arrays.copyOf(strippedArgs, strippedCount); + } + + switch (priority) { + case PRIORITY_TYPE_CRITICAL: { + dumper.dumpCritical(fd, pw, strippedArgs, asProto); + return; + } + case PRIORITY_TYPE_HIGH: { + dumper.dumpHigh(fd, pw, strippedArgs, asProto); + return; + } + case PRIORITY_TYPE_NORMAL: { + dumper.dumpNormal(fd, pw, strippedArgs, asProto); + return; + } + default: { + dumper.dump(fd, pw, strippedArgs, asProto); + return; } } - dumper.dump(fd, pw, args); } /** - * Gets an array without the {@code --dump-priority PRIORITY} prefix. + * Converts priority argument type to enum. */ - private static String[] getStrippedArgs(String[] args) { - final String[] stripped = new String[args.length - 2]; - System.arraycopy(args, 2, stripped, 0, stripped.length); - return stripped; + private static @PriorityType int getPriorityType(String arg) { + switch (arg) { + case "CRITICAL": { + return PRIORITY_TYPE_CRITICAL; + } + case "HIGH": { + return PRIORITY_TYPE_HIGH; + } + case "NORMAL": { + return PRIORITY_TYPE_NORMAL; + } + } + return PRIORITY_TYPE_INVALID; } /** * Helper for {@link android.os.Binder#dump(java.io.FileDescriptor, String[])} that supports the - * {@link #PRIORITY_ARG} argument. + * {@link #PRIORITY_ARG} and {@link #PROTO_ARG} arguments. * * @hide */ - public static interface PriorityDumper { + public interface PriorityDumper { /** * Dumps only the critical section. */ @SuppressWarnings("unused") - default void dumpCritical(FileDescriptor fd, PrintWriter pw, String[] args) { + default void dumpCritical(FileDescriptor fd, PrintWriter pw, String[] args, + boolean asProto) { } /** * Dumps only the high-priority section. */ @SuppressWarnings("unused") - default void dumpHigh(FileDescriptor fd, PrintWriter pw, String[] args) { + default void dumpHigh(FileDescriptor fd, PrintWriter pw, String[] args, boolean asProto) { } /** * Dumps only the normal section. */ @SuppressWarnings("unused") - default void dumpNormal(FileDescriptor fd, PrintWriter pw, String[] args) { + default void dumpNormal(FileDescriptor fd, PrintWriter pw, String[] args, boolean asProto) { } /** * Dumps all sections. * <p> * This method is called when - * {@link PriorityDump#dump(PriorityDumper, FileDescriptor, PrintWriter, String[])} is - * called without priority arguments. By default, it calls the 3 {@code dumpTYPE} methods, - * so sub-classes just need to implement the priority types they support. + * {@link PriorityDump#dump(PriorityDumper, FileDescriptor, PrintWriter, String[], boolean)} + * is called without priority arguments. By default, it calls the 3 {@code dumpTYPE} + * methods, so sub-classes just need to implement the priority types they support. */ @SuppressWarnings("unused") - default void dump(FileDescriptor fd, PrintWriter pw, String[] args) { - dumpCritical(fd, pw, args); - dumpHigh(fd, pw, args); - dumpNormal(fd, pw, args); + default void dump(FileDescriptor fd, PrintWriter pw, String[] args, boolean asProto) { + dumpCritical(fd, pw, args, asProto); + dumpHigh(fd, pw, args, asProto); + dumpNormal(fd, pw, args, asProto); } } } diff --git a/services/core/java/com/android/server/wm/AccessibilityController.java b/services/core/java/com/android/server/wm/AccessibilityController.java index 6484a13d8c3e..de4fd7cd06b5 100644 --- a/services/core/java/com/android/server/wm/AccessibilityController.java +++ b/services/core/java/com/android/server/wm/AccessibilityController.java @@ -74,12 +74,12 @@ import java.util.Set; */ final class AccessibilityController { - private final WindowManagerService mWindowManagerService; + private final WindowManagerService mService; private static final float[] sTempFloats = new float[9]; public AccessibilityController(WindowManagerService service) { - mWindowManagerService = service; + mService = service; } private DisplayMagnifier mDisplayMagnifier; @@ -91,7 +91,7 @@ final class AccessibilityController { if (mDisplayMagnifier != null) { throw new IllegalStateException("Magnification callbacks already set!"); } - mDisplayMagnifier = new DisplayMagnifier(mWindowManagerService, callbacks); + mDisplayMagnifier = new DisplayMagnifier(mService, callbacks); } else { if (mDisplayMagnifier == null) { throw new IllegalStateException("Magnification callbacks already cleared!"); @@ -108,7 +108,7 @@ final class AccessibilityController { "Windows for accessibility callback already set!"); } mWindowsForAccessibilityObserver = new WindowsForAccessibilityObserver( - mWindowManagerService, callback); + mService, callback); } else { if (mWindowsForAccessibilityObserver == null) { throw new IllegalStateException( @@ -120,7 +120,7 @@ final class AccessibilityController { public void performComputeChangedWindowsNotLocked() { WindowsForAccessibilityObserver observer = null; - synchronized (mWindowManagerService) { + synchronized (mService) { observer = mWindowsForAccessibilityObserver; } if (observer != null) { @@ -188,7 +188,7 @@ final class AccessibilityController { // Not relevant for the display magnifier. WindowsForAccessibilityObserver observer = null; - synchronized (mWindowManagerService) { + synchronized (mService) { observer = mWindowsForAccessibilityObserver; } if (observer != null) { @@ -268,7 +268,7 @@ final class AccessibilityController { private final Region mTempRegion4 = new Region(); private final Context mContext; - private final WindowManagerService mWindowManagerService; + private final WindowManagerService mService; private final MagnifiedViewport mMagnifedViewport; private final Handler mHandler; @@ -281,9 +281,9 @@ final class AccessibilityController { public DisplayMagnifier(WindowManagerService windowManagerService, MagnificationCallbacks callbacks) { mContext = windowManagerService.mContext; - mWindowManagerService = windowManagerService; + mService = windowManagerService; mCallbacks = callbacks; - mHandler = new MyHandler(mWindowManagerService.mH.getLooper()); + mHandler = new MyHandler(mService.mH.getLooper()); mMagnifedViewport = new MagnifiedViewport(); mLongAnimationDuration = mContext.getResources().getInteger( com.android.internal.R.integer.config_longAnimTime); @@ -292,7 +292,7 @@ final class AccessibilityController { public void setMagnificationSpecLocked(MagnificationSpec spec) { mMagnifedViewport.updateMagnificationSpecLocked(spec); mMagnifedViewport.recomputeBoundsLocked(); - mWindowManagerService.scheduleAnimationLocked(); + mService.scheduleAnimationLocked(); } public void setForceShowMagnifiableBoundsLocked(boolean show) { @@ -330,7 +330,7 @@ final class AccessibilityController { Slog.i(LOG_TAG, "Layers changed."); } mMagnifedViewport.recomputeBoundsLocked(); - mWindowManagerService.scheduleAnimationLocked(); + mService.scheduleAnimationLocked(); } public void onRotationChangedLocked(DisplayContent displayContent) { @@ -421,7 +421,7 @@ final class AccessibilityController { public MagnificationSpec getMagnificationSpecForWindowLocked(WindowState windowState) { MagnificationSpec spec = mMagnifedViewport.getMagnificationSpecLocked(); if (spec != null && !spec.isNop()) { - if (!mWindowManagerService.mPolicy.canMagnifyWindow(windowState.mAttrs.type)) { + if (!mService.mPolicy.canMagnifyWindow(windowState.mAttrs.type)) { return null; } } @@ -565,7 +565,7 @@ final class AccessibilityController { portionOfWindowAlreadyAccountedFor.op(nonMagnifiedBounds, Region.Op.UNION); windowBounds.op(portionOfWindowAlreadyAccountedFor, Region.Op.DIFFERENCE); - if (mWindowManagerService.mPolicy.canMagnifyWindow(windowState.mAttrs.type)) { + if (mService.mPolicy.canMagnifyWindow(windowState.mAttrs.type)) { mMagnificationRegion.op(windowBounds, Region.Op.UNION); mMagnificationRegion.op(availableBounds, Region.Op.INTERSECT); } else { @@ -632,7 +632,7 @@ final class AccessibilityController { if (isMagnifyingLocked() || isForceShowingMagnifiableBoundsLocked()) { setMagnifiedRegionBorderShownLocked(false, false); final long delay = (long) (mLongAnimationDuration - * mWindowManagerService.getWindowAnimationScaleLocked()); + * mService.getWindowAnimationScaleLocked()); Message message = mHandler.obtainMessage( MyHandler.MESSAGE_SHOW_MAGNIFIED_REGION_BOUNDS_IF_NEEDED); mHandler.sendMessageDelayed(message, delay); @@ -675,7 +675,7 @@ final class AccessibilityController { } private void populateWindowsOnScreenLocked(SparseArray<WindowState> outWindows) { - final DisplayContent dc = mWindowManagerService.getDefaultDisplayContentLocked(); + final DisplayContent dc = mService.getDefaultDisplayContentLocked(); dc.forAllWindows((w) -> { if (w.isOnScreen() && w.isVisibleLw() && !w.mWinAnimator.mEnterAnimationPending) { @@ -705,23 +705,25 @@ final class AccessibilityController { SurfaceControl surfaceControl = null; try { mWindowManager.getDefaultDisplay().getRealSize(mTempPoint); - surfaceControl = new SurfaceControl(mWindowManagerService.mFxSession, - SURFACE_TITLE, mTempPoint.x, mTempPoint.y, PixelFormat.TRANSLUCENT, - SurfaceControl.HIDDEN); + surfaceControl = new SurfaceControl.Builder(mService.mFxSession) + .setName(SURFACE_TITLE) + .setSize(mTempPoint.x, mTempPoint.y) // not a typo + .setFormat(PixelFormat.TRANSLUCENT) + .build(); } catch (OutOfResourcesException oore) { /* ignore */ } mSurfaceControl = surfaceControl; mSurfaceControl.setLayerStack(mWindowManager.getDefaultDisplay() .getLayerStack()); - mSurfaceControl.setLayer(mWindowManagerService.mPolicy.getWindowLayerFromTypeLw( + mSurfaceControl.setLayer(mService.mPolicy.getWindowLayerFromTypeLw( TYPE_MAGNIFICATION_OVERLAY) * WindowManagerService.TYPE_LAYER_MULTIPLIER); mSurfaceControl.setPosition(0, 0); mSurface.copyFrom(mSurfaceControl); mAnimationController = new AnimationController(context, - mWindowManagerService.mH.getLooper()); + mService.mH.getLooper()); TypedValue typedValue = new TypedValue(); context.getTheme().resolveAttribute(R.attr.colorActivatedHighlight, @@ -736,7 +738,7 @@ final class AccessibilityController { } public void setShown(boolean shown, boolean animate) { - synchronized (mWindowManagerService.mWindowMap) { + synchronized (mService.mWindowMap) { if (mShown == shown) { return; } @@ -751,13 +753,13 @@ final class AccessibilityController { @SuppressWarnings("unused") // Called reflectively from an animator. public int getAlpha() { - synchronized (mWindowManagerService.mWindowMap) { + synchronized (mService.mWindowMap) { return mAlpha; } } public void setAlpha(int alpha) { - synchronized (mWindowManagerService.mWindowMap) { + synchronized (mService.mWindowMap) { if (mAlpha == alpha) { return; } @@ -770,7 +772,7 @@ final class AccessibilityController { } public void setBounds(Region bounds) { - synchronized (mWindowManagerService.mWindowMap) { + synchronized (mService.mWindowMap) { if (mBounds.equals(bounds)) { return; } @@ -783,7 +785,7 @@ final class AccessibilityController { } public void updateSize() { - synchronized (mWindowManagerService.mWindowMap) { + synchronized (mService.mWindowMap) { mWindowManager.getDefaultDisplay().getRealSize(mTempPoint); mSurfaceControl.setSize(mTempPoint.x, mTempPoint.y); invalidate(mDirtyRect); @@ -797,12 +799,12 @@ final class AccessibilityController { mDirtyRect.setEmpty(); } mInvalidated = true; - mWindowManagerService.scheduleAnimationLocked(); + mService.scheduleAnimationLocked(); } /** NOTE: This has to be called within a surface transaction. */ public void drawIfNeeded() { - synchronized (mWindowManagerService.mWindowMap) { + synchronized (mService.mWindowMap) { if (!mInvalidated) { return; } @@ -950,11 +952,11 @@ final class AccessibilityController { } break; case MESSAGE_SHOW_MAGNIFIED_REGION_BOUNDS_IF_NEEDED : { - synchronized (mWindowManagerService.mWindowMap) { + synchronized (mService.mWindowMap) { if (mMagnifedViewport.isMagnifyingLocked() || isForceShowingMagnifiableBoundsLocked()) { mMagnifedViewport.setMagnifiedRegionBorderShownLocked(true, true); - mWindowManagerService.scheduleAnimationLocked(); + mService.scheduleAnimationLocked(); } } } break; @@ -995,7 +997,7 @@ final class AccessibilityController { private final Context mContext; - private final WindowManagerService mWindowManagerService; + private final WindowManagerService mService; private final Handler mHandler; @@ -1006,9 +1008,9 @@ final class AccessibilityController { public WindowsForAccessibilityObserver(WindowManagerService windowManagerService, WindowsForAccessibilityCallback callback) { mContext = windowManagerService.mContext; - mWindowManagerService = windowManagerService; + mService = windowManagerService; mCallback = callback; - mHandler = new MyHandler(mWindowManagerService.mH.getLooper()); + mHandler = new MyHandler(mService.mH.getLooper()); mRecurringAccessibilityEventsIntervalMillis = ViewConfiguration .getSendRecurringAccessibilityEventsInterval(); computeChangedWindows(); @@ -1034,11 +1036,11 @@ final class AccessibilityController { boolean windowsChanged = false; List<WindowInfo> windows = new ArrayList<WindowInfo>(); - synchronized (mWindowManagerService.mWindowMap) { + synchronized (mService.mWindowMap) { // Do not send the windows if there is no current focus as // the window manager is still looking for where to put it. // We will do the work when we get a focus change callback. - if (mWindowManagerService.mCurrentFocus == null) { + if (mService.mCurrentFocus == null) { return; } @@ -1320,7 +1322,7 @@ final class AccessibilityController { } private void populateVisibleWindowsOnScreenLocked(SparseArray<WindowState> outWindows) { - final DisplayContent dc = mWindowManagerService.getDefaultDisplayContentLocked(); + final DisplayContent dc = mService.getDefaultDisplayContentLocked(); dc.forAllWindows((w) -> { if (w.isVisibleLw()) { outWindows.put(w.mLayer, w); diff --git a/services/core/java/com/android/server/wm/AppWindowToken.java b/services/core/java/com/android/server/wm/AppWindowToken.java index 5d034935e4fb..e873d32e7278 100644 --- a/services/core/java/com/android/server/wm/AppWindowToken.java +++ b/services/core/java/com/android/server/wm/AppWindowToken.java @@ -1621,10 +1621,10 @@ class AppWindowToken extends WindowToken implements WindowManagerService.AppFree @CallSuper @Override - public void writeToProto(ProtoOutputStream proto, long fieldId) { + public void writeToProto(ProtoOutputStream proto, long fieldId, boolean trim) { final long token = proto.start(fieldId); writeNameToProto(proto, NAME); - super.writeToProto(proto, WINDOW_TOKEN); + super.writeToProto(proto, WINDOW_TOKEN, trim); proto.end(token); } diff --git a/services/core/java/com/android/server/wm/BlackFrame.java b/services/core/java/com/android/server/wm/BlackFrame.java index d206554c1130..9729e50125b4 100644 --- a/services/core/java/com/android/server/wm/BlackFrame.java +++ b/services/core/java/com/android/server/wm/BlackFrame.java @@ -50,8 +50,11 @@ public class BlackFrame { int w = r-l; int h = b-t; - surface = new SurfaceControl(session, "BlackSurface", - w, h, OPAQUE, FX_SURFACE_DIM | SurfaceControl.HIDDEN); + surface = new SurfaceControl.Builder(session) + .setName("BlackSurface") + .setSize(w, h) + .setColorLayer(true) + .build(); surface.setAlpha(1); surface.setLayerStack(layerStack); diff --git a/services/core/java/com/android/server/wm/CircularDisplayMask.java b/services/core/java/com/android/server/wm/CircularDisplayMask.java index 85f468b59dc6..2d5d1b2f1da7 100644 --- a/services/core/java/com/android/server/wm/CircularDisplayMask.java +++ b/services/core/java/com/android/server/wm/CircularDisplayMask.java @@ -66,8 +66,11 @@ class CircularDisplayMask { SurfaceControl ctrl = null; try { - ctrl = new SurfaceControl(session, "CircularDisplayMask", mScreenSize.x, - mScreenSize.y, PixelFormat.TRANSLUCENT, SurfaceControl.HIDDEN); + ctrl = new SurfaceControl.Builder(session) + .setName("CircularDisplayMask") + .setSize(mScreenSize.x, mScreenSize.y) // not a typo + .setFormat(PixelFormat.TRANSLUCENT) + .build(); ctrl.setLayerStack(display.getLayerStack()); ctrl.setLayer(zOrder); diff --git a/services/core/java/com/android/server/wm/ConfigurationContainer.java b/services/core/java/com/android/server/wm/ConfigurationContainer.java index a4ab3ba33e18..cc948070f2fb 100644 --- a/services/core/java/com/android/server/wm/ConfigurationContainer.java +++ b/services/core/java/com/android/server/wm/ConfigurationContainer.java @@ -50,6 +50,9 @@ public abstract class ConfigurationContainer<E extends ConfigurationContainer> { /** Contains override configuration settings applied to this configuration container. */ private Configuration mOverrideConfiguration = new Configuration(); + /** True if mOverrideConfiguration is not empty */ + private boolean mHasOverrideConfiguration; + /** * Contains full configuration applied to this configuration container. Corresponds to full * parent's config with applied {@link #mOverrideConfiguration}. @@ -101,6 +104,9 @@ public abstract class ConfigurationContainer<E extends ConfigurationContainer> { * @see #mFullConfiguration */ public void onOverrideConfigurationChanged(Configuration overrideConfiguration) { + // Pre-compute this here, so we don't need to go through the entire Configuration when + // writing to proto (which has significant cost if we write a lot of empty configurations). + mHasOverrideConfiguration = !Configuration.EMPTY.equals(overrideConfiguration); mOverrideConfiguration.setTo(overrideConfiguration); // Update full configuration of this container and all its children. final ConfigurationContainer parent = getParent(); @@ -330,18 +336,23 @@ public abstract class ConfigurationContainer<E extends ConfigurationContainer> { * Write to a protocol buffer output stream. Protocol buffer message definition is at * {@link com.android.server.wm.proto.ConfigurationContainerProto}. * - * @param protoOutputStream Stream to write the ConfigurationContainer object to. - * @param fieldId Field Id of the ConfigurationContainer as defined in the parent - * message. + * @param proto Stream to write the ConfigurationContainer object to. + * @param fieldId Field Id of the ConfigurationContainer as defined in the parent + * message. + * @param trim If true, reduce amount of data written. * @hide */ @CallSuper - public void writeToProto(ProtoOutputStream protoOutputStream, long fieldId) { - final long token = protoOutputStream.start(fieldId); - mOverrideConfiguration.writeToProto(protoOutputStream, OVERRIDE_CONFIGURATION); - mFullConfiguration.writeToProto(protoOutputStream, FULL_CONFIGURATION); - mMergedOverrideConfiguration.writeToProto(protoOutputStream, MERGED_OVERRIDE_CONFIGURATION); - protoOutputStream.end(token); + public void writeToProto(ProtoOutputStream proto, long fieldId, boolean trim) { + final long token = proto.start(fieldId); + if (!trim || mHasOverrideConfiguration) { + mOverrideConfiguration.writeToProto(proto, OVERRIDE_CONFIGURATION); + } + if (!trim) { + mFullConfiguration.writeToProto(proto, FULL_CONFIGURATION); + mMergedOverrideConfiguration.writeToProto(proto, MERGED_OVERRIDE_CONFIGURATION); + } + proto.end(token); } /** diff --git a/services/core/java/com/android/server/wm/DimLayer.java b/services/core/java/com/android/server/wm/DimLayer.java index 48181d30337a..401547e6eebb 100644 --- a/services/core/java/com/android/server/wm/DimLayer.java +++ b/services/core/java/com/android/server/wm/DimLayer.java @@ -104,9 +104,11 @@ public class DimLayer { private void constructSurface(WindowManagerService service) { service.openSurfaceTransaction(); try { - mDimSurface = new SurfaceControl(service.mFxSession, mName, - 16, 16, PixelFormat.OPAQUE, - SurfaceControl.FX_SURFACE_DIM | SurfaceControl.HIDDEN); + mDimSurface = new SurfaceControl.Builder(service.mFxSession) + .setName(mName) + .setSize(16, 16) + .setColorLayer(true) + .build(); if (SHOW_TRANSACTIONS || SHOW_SURFACE_ALLOC) Slog.i(TAG, " DIM " + mDimSurface + ": CREATE"); diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java index 03fdc968d87b..4c6ab3f7cc4f 100644 --- a/services/core/java/com/android/server/wm/DisplayContent.java +++ b/services/core/java/com/android/server/wm/DisplayContent.java @@ -2137,27 +2137,27 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo @CallSuper @Override - public void writeToProto(ProtoOutputStream proto, long fieldId) { + public void writeToProto(ProtoOutputStream proto, long fieldId, boolean trim) { final long token = proto.start(fieldId); - super.writeToProto(proto, WINDOW_CONTAINER); + super.writeToProto(proto, WINDOW_CONTAINER, trim); proto.write(ID, mDisplayId); for (int stackNdx = mTaskStackContainers.getChildCount() - 1; stackNdx >= 0; --stackNdx) { final TaskStack stack = mTaskStackContainers.getChildAt(stackNdx); - stack.writeToProto(proto, STACKS); + stack.writeToProto(proto, STACKS, trim); } mDividerControllerLocked.writeToProto(proto, DOCKED_STACK_DIVIDER_CONTROLLER); mPinnedStackControllerLocked.writeToProto(proto, PINNED_STACK_CONTROLLER); for (int i = mAboveAppWindowsContainers.getChildCount() - 1; i >= 0; --i) { final WindowToken windowToken = mAboveAppWindowsContainers.getChildAt(i); - windowToken.writeToProto(proto, ABOVE_APP_WINDOWS); + windowToken.writeToProto(proto, ABOVE_APP_WINDOWS, trim); } for (int i = mBelowAppWindowsContainers.getChildCount() - 1; i >= 0; --i) { final WindowToken windowToken = mBelowAppWindowsContainers.getChildAt(i); - windowToken.writeToProto(proto, BELOW_APP_WINDOWS); + windowToken.writeToProto(proto, BELOW_APP_WINDOWS, trim); } for (int i = mImeWindowsContainers.getChildCount() - 1; i >= 0; --i) { final WindowToken windowToken = mImeWindowsContainers.getChildAt(i); - windowToken.writeToProto(proto, IME_WINDOWS); + windowToken.writeToProto(proto, IME_WINDOWS, trim); } proto.write(DPI, mBaseDisplayDensity); mDisplayInfo.writeToProto(proto, DISPLAY_INFO); diff --git a/services/core/java/com/android/server/wm/DragDropController.java b/services/core/java/com/android/server/wm/DragDropController.java index 36871b1d8c5b..a3c6167075d9 100644 --- a/services/core/java/com/android/server/wm/DragDropController.java +++ b/services/core/java/com/android/server/wm/DragDropController.java @@ -16,23 +16,20 @@ package com.android.server.wm; -import static android.graphics.PixelFormat.TRANSLUCENT; -import static android.view.SurfaceControl.HIDDEN; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_DRAG; import static com.android.server.wm.WindowManagerDebugConfig.SHOW_LIGHT_TRANSACTIONS; import static com.android.server.wm.WindowManagerDebugConfig.SHOW_TRANSACTIONS; import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM; import android.content.ClipData; +import android.graphics.PixelFormat; import android.os.Binder; -import android.os.Handler; import android.os.IBinder; import android.os.Message; import android.util.Slog; import android.view.Display; import android.view.IWindow; import android.view.Surface; -import android.view.Surface.OutOfResourcesException; import android.view.SurfaceControl; import android.view.SurfaceSession; import android.view.View; @@ -44,6 +41,11 @@ import com.android.server.wm.WindowManagerService.H; class DragDropController { private static final float DRAG_SHADOW_ALPHA_TRANSPARENT = .7071f; private static final long DRAG_TIMEOUT_MS = 5000; + DragState mDragState; + + boolean dragDropActiveLocked() { + return mDragState != null; + } IBinder prepareDrag(WindowManagerService service, SurfaceSession session, int callerPid, int callerUid, IWindow window, int flags, int width, int height, Surface outSurface) { @@ -56,49 +58,42 @@ class DragDropController { IBinder token = null; synchronized (service.mWindowMap) { - try { - if (service.mDragState == null) { - // TODO(multi-display): support other displays - final DisplayContent displayContent = - service.getDefaultDisplayContentLocked(); - final Display display = displayContent.getDisplay(); - - SurfaceControl surface = new SurfaceControl(session, "drag surface", - width, height, TRANSLUCENT, HIDDEN); - surface.setLayerStack(display.getLayerStack()); - float alpha = 1; - if ((flags & View.DRAG_FLAG_OPAQUE) == 0) { - alpha = DRAG_SHADOW_ALPHA_TRANSPARENT; - } - surface.setAlpha(alpha); - - if (SHOW_TRANSACTIONS) Slog.i(TAG_WM, " DRAG " - + surface + ": CREATE"); - outSurface.copyFrom(surface); - final IBinder winBinder = window.asBinder(); - token = new Binder(); - service.mDragState = - new DragState(service, token, surface, flags, winBinder); - service.mDragState.mPid = callerPid; - service.mDragState.mUid = callerUid; - service.mDragState.mOriginalAlpha = alpha; - token = service.mDragState.mToken = new Binder(); - - // 5 second timeout for this window to actually begin the drag - service.mH.removeMessages(H.DRAG_START_TIMEOUT, winBinder); - Message msg = service.mH.obtainMessage(H.DRAG_START_TIMEOUT, winBinder); - service.mH.sendMessageDelayed(msg, DRAG_TIMEOUT_MS); - } else { - Slog.w(TAG_WM, "Drag already in progress"); - } - } catch (OutOfResourcesException e) { - Slog.e(TAG_WM, "Can't allocate drag surface w=" + width + " h=" + height, - e); - if (service.mDragState != null) { - service.mDragState.reset(); - service.mDragState = null; - } + if (dragDropActiveLocked()) { + Slog.w(TAG_WM, "Drag already in progress"); + return null; + } + + // TODO(multi-display): support other displays + final DisplayContent displayContent = + service.getDefaultDisplayContentLocked(); + final Display display = displayContent.getDisplay(); + + final SurfaceControl surface = new SurfaceControl.Builder(session) + .setName("drag surface") + .setSize(width, height) + .setFormat(PixelFormat.TRANSLUCENT) + .build(); + surface.setLayerStack(display.getLayerStack()); + float alpha = 1; + if ((flags & View.DRAG_FLAG_OPAQUE) == 0) { + alpha = DRAG_SHADOW_ALPHA_TRANSPARENT; } + surface.setAlpha(alpha); + + if (SHOW_TRANSACTIONS) Slog.i(TAG_WM, " DRAG " + surface + ": CREATE"); + outSurface.copyFrom(surface); + final IBinder winBinder = window.asBinder(); + token = new Binder(); + mDragState = new DragState(service, token, surface, flags, winBinder); + mDragState.mPid = callerPid; + mDragState.mUid = callerUid; + mDragState.mOriginalAlpha = alpha; + token = mDragState.mToken = new Binder(); + + // 5 second timeout for this window to actually begin the drag + service.mH.removeMessages(H.DRAG_START_TIMEOUT, winBinder); + Message msg = service.mH.obtainMessage(H.DRAG_START_TIMEOUT, winBinder); + service.mH.sendMessageDelayed(msg, DRAG_TIMEOUT_MS); } return token; @@ -112,12 +107,12 @@ class DragDropController { } synchronized (service.mWindowMap) { - if (service.mDragState == null) { + if (mDragState == null) { Slog.w(TAG_WM, "No drag prepared"); throw new IllegalStateException("performDrag() without prepareDrag()"); } - if (dragToken != service.mDragState.mToken) { + if (dragToken != mDragState.mToken) { Slog.w(TAG_WM, "Performing mismatched drag"); throw new IllegalStateException("performDrag() does not match prepareDrag()"); } @@ -145,34 +140,34 @@ class DragDropController { return false; } Display display = displayContent.getDisplay(); - service.mDragState.register(display); + mDragState.register(display); if (!service.mInputManager.transferTouchFocus(callingWin.mInputChannel, - service.mDragState.getInputChannel())) { + mDragState.getInputChannel())) { Slog.e(TAG_WM, "Unable to transfer touch focus"); - service.mDragState.unregister(); - service.mDragState.reset(); - service.mDragState = null; + mDragState.unregister(); + mDragState.reset(); + mDragState = null; return false; } - service.mDragState.mDisplayContent = displayContent; - service.mDragState.mData = data; - service.mDragState.broadcastDragStartedLw(touchX, touchY); - service.mDragState.overridePointerIconLw(touchSource); + mDragState.mDisplayContent = displayContent; + mDragState.mData = data; + mDragState.broadcastDragStartedLw(touchX, touchY); + mDragState.overridePointerIconLw(touchSource); // remember the thumb offsets for later - service.mDragState.mThumbOffsetX = thumbCenterX; - service.mDragState.mThumbOffsetY = thumbCenterY; + mDragState.mThumbOffsetX = thumbCenterX; + mDragState.mThumbOffsetY = thumbCenterY; // Make the surface visible at the proper location - final SurfaceControl surfaceControl = service.mDragState.mSurfaceControl; + final SurfaceControl surfaceControl = mDragState.mSurfaceControl; if (SHOW_LIGHT_TRANSACTIONS) Slog.i( TAG_WM, ">>> OPEN TRANSACTION performDrag"); service.openSurfaceTransaction(); try { surfaceControl.setPosition(touchX - thumbCenterX, touchY - thumbCenterY); - surfaceControl.setLayer(service.mDragState.getDragLayerLw()); + surfaceControl.setLayer(mDragState.getDragLayerLw()); surfaceControl.setLayerStack(display.getLayerStack()); surfaceControl.show(); } finally { @@ -181,7 +176,7 @@ class DragDropController { TAG_WM, "<<< CLOSE TRANSACTION performDrag"); } - service.mDragState.notifyLocationLw(touchX, touchY); + mDragState.notifyLocationLw(touchX, touchY); } return true; // success! @@ -194,14 +189,14 @@ class DragDropController { } synchronized (service.mWindowMap) { - if (service.mDragState == null) { + if (mDragState == null) { // Most likely the drop recipient ANRed and we ended the drag // out from under it. Log the issue and move on. Slog.w(TAG_WM, "Drop result given but no drag in progress"); return; } - if (service.mDragState.mToken != token) { + if (mDragState.mToken != token) { // We're in a drag, but the wrong window has responded. Slog.w(TAG_WM, "Invalid drop-result claim by " + window); throw new IllegalStateException("reportDropResult() by non-recipient"); @@ -217,8 +212,8 @@ class DragDropController { return; // !!! TODO: throw here? } - service.mDragState.mDragResult = consumed; - service.mDragState.endDragLw(); + mDragState.mDragResult = consumed; + mDragState.endDragLw(); } } @@ -228,20 +223,20 @@ class DragDropController { } synchronized (service.mWindowMap) { - if (service.mDragState == null) { + if (mDragState == null) { Slog.w(TAG_WM, "cancelDragAndDrop() without prepareDrag()"); throw new IllegalStateException("cancelDragAndDrop() without prepareDrag()"); } - if (service.mDragState.mToken != dragToken) { + if (mDragState.mToken != dragToken) { Slog.w(TAG_WM, "cancelDragAndDrop() does not match prepareDrag()"); throw new IllegalStateException( "cancelDragAndDrop() does not match prepareDrag()"); } - service.mDragState.mDragResult = false; - service.mDragState.cancelDragLw(); + mDragState.mDragResult = false; + mDragState.cancelDragLw(); } } @@ -266,10 +261,10 @@ class DragDropController { } synchronized (service.mWindowMap) { // !!! TODO: ANR the app that has failed to start the drag in time - if (service.mDragState != null) { - service.mDragState.unregister(); - service.mDragState.reset(); - service.mDragState = null; + if (mDragState != null) { + mDragState.unregister(); + mDragState.reset(); + mDragState = null; } } break; @@ -282,9 +277,9 @@ class DragDropController { } synchronized (service.mWindowMap) { // !!! TODO: ANR the drag-receiving app - if (service.mDragState != null) { - service.mDragState.mDragResult = false; - service.mDragState.endDragLw(); + if (mDragState != null) { + mDragState.mDragResult = false; + mDragState.endDragLw(); } } break; diff --git a/services/core/java/com/android/server/wm/DragState.java b/services/core/java/com/android/server/wm/DragState.java index 4a75e010add5..11f22411d4c5 100644 --- a/services/core/java/com/android/server/wm/DragState.java +++ b/services/core/java/com/android/server/wm/DragState.java @@ -430,7 +430,7 @@ class DragState { // WindowManagerService, which will cause DragState#reset() while playing the // cancel animation. reset(); - mService.mDragState = null; + mService.mDragDropController.mDragState = null; return; } mAnimator = createCancelAnimationLocked(); @@ -447,7 +447,7 @@ class DragState { // free our resources and drop all the object references reset(); - mService.mDragState = null; + mService.mDragDropController.mDragState = null; } void notifyMoveLw(float x, float y) { @@ -658,7 +658,7 @@ class DragState { switch (msg.what) { case MSG_ANIMATION_END: synchronized (mService.mWindowMap) { - if (mService.mDragState != DragState.this) { + if (mService.mDragDropController.mDragState != DragState.this) { Slog.wtf(TAG_WM, "mDragState is updated unexpectedly while " + "playing animation"); return; diff --git a/services/core/java/com/android/server/wm/EmulatorDisplayOverlay.java b/services/core/java/com/android/server/wm/EmulatorDisplayOverlay.java index 19bd8e9d6f25..8bec8d7572a4 100644 --- a/services/core/java/com/android/server/wm/EmulatorDisplayOverlay.java +++ b/services/core/java/com/android/server/wm/EmulatorDisplayOverlay.java @@ -56,8 +56,11 @@ class EmulatorDisplayOverlay { SurfaceControl ctrl = null; try { - ctrl = new SurfaceControl(session, "EmulatorDisplayOverlay", mScreenSize.x, - mScreenSize.y, PixelFormat.TRANSLUCENT, SurfaceControl.HIDDEN); + ctrl = new SurfaceControl.Builder(session) + .setName("EmulatorDisplayOverlay") + .setSize(mScreenSize.x, mScreenSize.y) + .setFormat(PixelFormat.TRANSLUCENT) + .build(); ctrl.setLayerStack(display.getLayerStack()); ctrl.setLayer(zOrder); ctrl.setPosition(0, 0); diff --git a/services/core/java/com/android/server/wm/InputMonitor.java b/services/core/java/com/android/server/wm/InputMonitor.java index 238cb9f1dfea..cf1f1713a611 100644 --- a/services/core/java/com/android/server/wm/InputMonitor.java +++ b/services/core/java/com/android/server/wm/InputMonitor.java @@ -367,12 +367,13 @@ final class InputMonitor implements InputManagerService.WindowManagerCallbacks { // currently has touch focus. // If there's a drag in flight, provide a pseudo-window to catch drag input - final boolean inDrag = (mService.mDragState != null); + final boolean inDrag = mService.mDragDropController.dragDropActiveLocked(); if (inDrag) { if (DEBUG_DRAG) { Log.d(TAG_WM, "Inserting drag window"); } - final InputWindowHandle dragWindowHandle = mService.mDragState.getInputWindowHandle(); + final InputWindowHandle dragWindowHandle = + mService.mDragDropController.mDragState.getInputWindowHandle(); if (dragWindowHandle != null) { addInputWindowHandle(dragWindowHandle); } else { @@ -689,7 +690,7 @@ final class InputMonitor implements InputManagerService.WindowManagerCallbacks { // If there's a drag in progress and 'child' is a potential drop target, // make sure it's been told about the drag if (inDrag && isVisible && w.getDisplayContent().isDefaultDisplay) { - mService.mDragState.sendDragStartedIfNeededLw(w); + mService.mDragDropController.mDragState.sendDragStartedIfNeededLw(w); } addInputWindowHandle( diff --git a/services/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java index fd574709e623..a7104410f4d3 100644 --- a/services/core/java/com/android/server/wm/RootWindowContainer.java +++ b/services/core/java/com/android/server/wm/RootWindowContainer.java @@ -1081,19 +1081,21 @@ class RootWindowContainer extends WindowContainer<DisplayContent> { @CallSuper @Override - public void writeToProto(ProtoOutputStream proto, long fieldId) { + public void writeToProto(ProtoOutputStream proto, long fieldId, boolean trim) { final long token = proto.start(fieldId); - super.writeToProto(proto, WINDOW_CONTAINER); + super.writeToProto(proto, WINDOW_CONTAINER, trim); if (mService.mDisplayReady) { final int count = mChildren.size(); for (int i = 0; i < count; ++i) { final DisplayContent displayContent = mChildren.get(i); - displayContent.writeToProto(proto, DISPLAYS); + displayContent.writeToProto(proto, DISPLAYS, trim); } } - forAllWindows((w) -> { - w.writeIdentifierToProto(proto, WINDOWS); - }, true); + if (!trim) { + forAllWindows((w) -> { + w.writeIdentifierToProto(proto, WINDOWS); + }, true); + } proto.end(token); } diff --git a/services/core/java/com/android/server/wm/ScreenRotationAnimation.java b/services/core/java/com/android/server/wm/ScreenRotationAnimation.java index 8e99be83d918..c25b19ccc6ff 100644 --- a/services/core/java/com/android/server/wm/ScreenRotationAnimation.java +++ b/services/core/java/com/android/server/wm/ScreenRotationAnimation.java @@ -269,14 +269,11 @@ class ScreenRotationAnimation { try { try { - int flags = SurfaceControl.HIDDEN; - if (isSecure) { - flags |= SurfaceControl.SECURE; - } - - mSurfaceControl = new SurfaceControl(session, "ScreenshotSurface", - mWidth, mHeight, - PixelFormat.OPAQUE, flags); + mSurfaceControl = new SurfaceControl.Builder(session) + .setName("ScreenshotSurface") + .setSize(mWidth, mHeight) + .setSecure(isSecure) + .build(); // capture a screenshot into the surface we just created Surface sur = new Surface(); diff --git a/services/core/java/com/android/server/wm/StrictModeFlash.java b/services/core/java/com/android/server/wm/StrictModeFlash.java index d1547eb04c78..eb8ee69646d9 100644 --- a/services/core/java/com/android/server/wm/StrictModeFlash.java +++ b/services/core/java/com/android/server/wm/StrictModeFlash.java @@ -44,8 +44,11 @@ class StrictModeFlash { public StrictModeFlash(Display display, SurfaceSession session) { SurfaceControl ctrl = null; try { - ctrl = new SurfaceControl(session, "StrictModeFlash", - 1, 1, PixelFormat.TRANSLUCENT, SurfaceControl.HIDDEN); + ctrl = new SurfaceControl.Builder(session) + .setName("StrictModeFlash") + .setSize(1, 1) + .setFormat(PixelFormat.TRANSLUCENT) + .build(); ctrl.setLayerStack(display.getLayerStack()); ctrl.setLayer(WindowManagerService.TYPE_LAYER_MULTIPLIER * 101); // one more than Watermark? arbitrary. ctrl.setPosition(0, 0); diff --git a/services/core/java/com/android/server/wm/SurfaceControlWithBackground.java b/services/core/java/com/android/server/wm/SurfaceControlWithBackground.java index b0eaf1488f21..a5080d57af2a 100644 --- a/services/core/java/com/android/server/wm/SurfaceControlWithBackground.java +++ b/services/core/java/com/android/server/wm/SurfaceControlWithBackground.java @@ -66,10 +66,10 @@ class SurfaceControlWithBackground extends SurfaceControl { mWindowSurfaceController = other.mWindowSurfaceController; } - public SurfaceControlWithBackground(SurfaceSession s, String name, int w, int h, int format, - int flags, int windowType, int ownerUid, + public SurfaceControlWithBackground(String name, SurfaceControl.Builder b, + int windowType, int w, int h, WindowSurfaceController windowSurfaceController) throws OutOfResourcesException { - super(s, name, w, h, format, flags, windowType, ownerUid); + super(b.build()); // We should only show background behind app windows that are letterboxed in a task. if ((windowType != TYPE_BASE_APPLICATION && windowType != TYPE_APPLICATION_STARTING) @@ -80,9 +80,11 @@ class SurfaceControlWithBackground extends SurfaceControl { mLastWidth = w; mLastHeight = h; mWindowSurfaceController.getContainerRect(mTmpContainerRect); - mBackgroundControl = new SurfaceControl(s, "Background for - " + name, - mTmpContainerRect.width(), mTmpContainerRect.height(), PixelFormat.OPAQUE, - flags | SurfaceControl.FX_SURFACE_DIM); + mBackgroundControl = b.setName("Background for - " + name) + .setSize(mTmpContainerRect.width(), mTmpContainerRect.height()) + .setFormat(OPAQUE) + .setColorLayer(true) + .build(); } @Override diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java index 891d637a4efa..7620cb0dfdb9 100644 --- a/services/core/java/com/android/server/wm/Task.java +++ b/services/core/java/com/android/server/wm/Task.java @@ -725,13 +725,13 @@ class Task extends WindowContainer<AppWindowToken> implements DimLayer.DimLayerU @CallSuper @Override - public void writeToProto(ProtoOutputStream proto, long fieldId) { + public void writeToProto(ProtoOutputStream proto, long fieldId, boolean trim) { final long token = proto.start(fieldId); - super.writeToProto(proto, WINDOW_CONTAINER); + super.writeToProto(proto, WINDOW_CONTAINER, trim); proto.write(ID, mTaskId); for (int i = mChildren.size() - 1; i >= 0; i--) { final AppWindowToken appWindowToken = mChildren.get(i); - appWindowToken.writeToProto(proto, APP_WINDOW_TOKENS); + appWindowToken.writeToProto(proto, APP_WINDOW_TOKENS, trim); } proto.write(FILLS_PARENT, mFillsParent); mBounds.writeToProto(proto, BOUNDS); diff --git a/services/core/java/com/android/server/wm/TaskSnapshotSurface.java b/services/core/java/com/android/server/wm/TaskSnapshotSurface.java index 4698d72567c4..3ce090ace7b3 100644 --- a/services/core/java/com/android/server/wm/TaskSnapshotSurface.java +++ b/services/core/java/com/android/server/wm/TaskSnapshotSurface.java @@ -304,9 +304,11 @@ class TaskSnapshotSurface implements StartingSurface { final SurfaceSession session = new SurfaceSession(mSurface); // Keep a reference to it such that it doesn't get destroyed when finalized. - mChildSurfaceControl = new SurfaceControl(session, - mTitle + " - task-snapshot-surface", - buffer.getWidth(), buffer.getHeight(), buffer.getFormat(), HIDDEN); + mChildSurfaceControl = new SurfaceControl.Builder(session) + .setName(mTitle + " - task-snapshot-surface") + .setSize(buffer.getWidth(), buffer.getHeight()) + .setFormat(buffer.getFormat()) + .build(); Surface surface = new Surface(); surface.copyFrom(mChildSurfaceControl); diff --git a/services/core/java/com/android/server/wm/TaskStack.java b/services/core/java/com/android/server/wm/TaskStack.java index 33202749aca1..791accf8f347 100644 --- a/services/core/java/com/android/server/wm/TaskStack.java +++ b/services/core/java/com/android/server/wm/TaskStack.java @@ -1232,12 +1232,12 @@ public class TaskStack extends WindowContainer<Task> implements DimLayer.DimLaye @CallSuper @Override - public void writeToProto(ProtoOutputStream proto, long fieldId) { + public void writeToProto(ProtoOutputStream proto, long fieldId, boolean trim) { final long token = proto.start(fieldId); - super.writeToProto(proto, WINDOW_CONTAINER); + super.writeToProto(proto, WINDOW_CONTAINER, trim); proto.write(ID, mStackId); for (int taskNdx = mChildren.size() - 1; taskNdx >= 0; taskNdx--) { - mChildren.get(taskNdx).writeToProto(proto, TASKS); + mChildren.get(taskNdx).writeToProto(proto, TASKS, trim); } proto.write(FILLS_PARENT, mFillsParent); mBounds.writeToProto(proto, BOUNDS); diff --git a/services/core/java/com/android/server/wm/Watermark.java b/services/core/java/com/android/server/wm/Watermark.java index 171e575c1801..d97aaac4fea5 100644 --- a/services/core/java/com/android/server/wm/Watermark.java +++ b/services/core/java/com/android/server/wm/Watermark.java @@ -114,8 +114,11 @@ class Watermark { SurfaceControl ctrl = null; try { - ctrl = new SurfaceControl(session, "WatermarkSurface", - 1, 1, PixelFormat.TRANSLUCENT, SurfaceControl.HIDDEN); + ctrl = new SurfaceControl.Builder(session) + .setName("WatermarkSurface") + .setSize(1, 1) + .setFormat(PixelFormat.TRANSLUCENT) + .build(); ctrl.setLayerStack(mDisplay.getLayerStack()); ctrl.setLayer(WindowManagerService.TYPE_LAYER_MULTIPLIER*100); ctrl.setPosition(0, 0); diff --git a/services/core/java/com/android/server/wm/WindowContainer.java b/services/core/java/com/android/server/wm/WindowContainer.java index 563eb9cd1d88..8f4b897cd804 100644 --- a/services/core/java/com/android/server/wm/WindowContainer.java +++ b/services/core/java/com/android/server/wm/WindowContainer.java @@ -677,17 +677,18 @@ a * Returns whether this child is on top of the window hierarchy. * Write to a protocol buffer output stream. Protocol buffer message definition is at * {@link com.android.server.wm.proto.WindowContainerProto}. * - * @param protoOutputStream Stream to write the WindowContainer object to. - * @param fieldId Field Id of the WindowContainer as defined in the parent message. + * @param proto Stream to write the WindowContainer object to. + * @param fieldId Field Id of the WindowContainer as defined in the parent message. + * @param trim If true, reduce the amount of data written. * @hide */ @CallSuper @Override - public void writeToProto(ProtoOutputStream protoOutputStream, long fieldId) { - final long token = protoOutputStream.start(fieldId); - super.writeToProto(protoOutputStream, CONFIGURATION_CONTAINER); - protoOutputStream.write(ORIENTATION, mOrientation); - protoOutputStream.end(token); + public void writeToProto(ProtoOutputStream proto, long fieldId, boolean trim) { + final long token = proto.start(fieldId); + super.writeToProto(proto, CONFIGURATION_CONTAINER, trim); + proto.write(ORIENTATION, mOrientation); + proto.end(token); } private ForAllWindowsConsumerWrapper obtainConsumerWrapper(Consumer<WindowState> consumer) { diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index 70d06169ba9e..f31ea67c8edf 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -392,13 +392,14 @@ public class WindowManagerService extends IWindowManager.Stub private final PriorityDump.PriorityDumper mPriorityDumper = new PriorityDump.PriorityDumper() { @Override - public void dumpCritical(FileDescriptor fd, PrintWriter pw, String[] args) { - doDump(fd, pw, new String[] {"-a"}); + public void dumpCritical(FileDescriptor fd, PrintWriter pw, String[] args, + boolean asProto) { + doDump(fd, pw, new String[] {"-a"}, asProto); } @Override - public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { - doDump(fd, pw, args); + public void dump(FileDescriptor fd, PrintWriter pw, String[] args, boolean asProto) { + doDump(fd, pw, args, asProto); } }; @@ -751,7 +752,6 @@ public class WindowManagerService extends IWindowManager.Stub TaskPositioner mTaskPositioner; final DragDropController mDragDropController = new DragDropController(); - DragState mDragState = null; // For frozen screen animations. private int mExitAnimId, mEnterAnimId; @@ -788,7 +788,7 @@ public class WindowManagerService extends IWindowManager.Stub public void onInputEvent(InputEvent event, int displayId) { boolean handled = false; try { - if (mDragState == null) { + if (mDragDropController.mDragState == null) { // The drag has ended but the clean-up message has not been processed by // window manager. Drop events that occur after this until window manager // has a chance to clean-up the input handle. @@ -827,12 +827,12 @@ public class WindowManagerService extends IWindowManager.Stub + newX + "," + newY); mMuteInput = true; synchronized (mWindowMap) { - endDrag = mDragState.notifyDropLw(newX, newY); + endDrag = mDragDropController.mDragState.notifyDropLw(newX, newY); } } else { synchronized (mWindowMap) { // move the surface and tell the involved window(s) where we are - mDragState.notifyMoveLw(newX, newY); + mDragDropController.mDragState.notifyMoveLw(newX, newY); } } } break; @@ -842,7 +842,7 @@ public class WindowManagerService extends IWindowManager.Stub + newX + "," + newY); mMuteInput = true; synchronized (mWindowMap) { - endDrag = mDragState.notifyDropLw(newX, newY); + endDrag = mDragDropController.mDragState.notifyDropLw(newX, newY); } } break; @@ -859,7 +859,7 @@ public class WindowManagerService extends IWindowManager.Stub synchronized (mWindowMap) { // endDragLw will post back to looper to dispose the receiver // since we still need the receiver for the last finishInputEvent. - mDragState.endDragLw(); + mDragDropController.mDragState.endDragLw(); } mStylusButtonDownAtStart = false; mIsStartEvent = true; @@ -6430,9 +6430,16 @@ public class WindowManagerService extends IWindowManager.Stub } } - private void writeToProtoLocked(ProtoOutputStream proto) { + /** + * Write to a protocol buffer output stream. Protocol buffer message definition is at + * {@link com.android.server.wm.proto.WindowManagerServiceProto}. + * + * @param proto Stream to write the WindowContainer object to. + * @param trim If true, reduce the amount of data written. + */ + private void writeToProtoLocked(ProtoOutputStream proto, boolean trim) { mPolicy.writeToProto(proto, POLICY); - mRoot.writeToProto(proto, ROOT_WINDOW_CONTAINER); + mRoot.writeToProto(proto, ROOT_WINDOW_CONTAINER, trim); if (mCurrentFocus != null) { mCurrentFocus.writeIdentifierToProto(proto, FOCUSED_WINDOW); } @@ -6723,10 +6730,9 @@ public class WindowManagerService extends IWindowManager.Stub PriorityDump.dump(mPriorityDumper, fd, pw, args); } - private void doDump(FileDescriptor fd, PrintWriter pw, String[] args) { + private void doDump(FileDescriptor fd, PrintWriter pw, String[] args, boolean useProto) { if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return; boolean dumpAll = false; - boolean useProto = false; int opti = 0; while (opti < args.length) { @@ -6737,8 +6743,6 @@ public class WindowManagerService extends IWindowManager.Stub opti++; if ("-a".equals(opt)) { dumpAll = true; - } else if ("--proto".equals(opt)) { - useProto = true; } else if ("-h".equals(opt)) { pw.println("Window manager dump options:"); pw.println(" [-a] [-h] [cmd] ..."); @@ -6768,7 +6772,7 @@ public class WindowManagerService extends IWindowManager.Stub if (useProto) { final ProtoOutputStream proto = new ProtoOutputStream(fd); synchronized (mWindowMap) { - writeToProtoLocked(proto); + writeToProtoLocked(proto, false /* trim */); } proto.flush(); return; @@ -7166,7 +7170,7 @@ public class WindowManagerService extends IWindowManager.Stub } synchronized (mWindowMap) { - if (mDragState != null) { + if (mDragDropController.mDragState != null) { // Drag cursor overrides the app cursor. return; } diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java index e171528403d0..4370a7637e01 100644 --- a/services/core/java/com/android/server/wm/WindowState.java +++ b/services/core/java/com/android/server/wm/WindowState.java @@ -3120,9 +3120,9 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP @CallSuper @Override - public void writeToProto(ProtoOutputStream proto, long fieldId) { + public void writeToProto(ProtoOutputStream proto, long fieldId, boolean trim) { final long token = proto.start(fieldId); - super.writeToProto(proto, WINDOW_CONTAINER); + super.writeToProto(proto, WINDOW_CONTAINER, trim); writeIdentifierToProto(proto, IDENTIFIER); proto.write(DISPLAY_ID, getDisplayId()); proto.write(STACK_ID, getStackId()); @@ -3137,7 +3137,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP mWinAnimator.writeToProto(proto, ANIMATOR); proto.write(ANIMATING_EXIT, mAnimatingExit); for (int i = 0; i < mChildren.size(); i++) { - mChildren.get(i).writeToProto(proto, CHILD_WINDOWS); + mChildren.get(i).writeToProto(proto, CHILD_WINDOWS, trim); } proto.end(token); } diff --git a/services/core/java/com/android/server/wm/WindowSurfaceController.java b/services/core/java/com/android/server/wm/WindowSurfaceController.java index d56df55da306..edd650a42107 100644 --- a/services/core/java/com/android/server/wm/WindowSurfaceController.java +++ b/services/core/java/com/android/server/wm/WindowSurfaceController.java @@ -101,8 +101,14 @@ class WindowSurfaceController { mWindowSession = win.mSession; Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "new SurfaceControl"); + final SurfaceControl.Builder b = new SurfaceControl.Builder(s) + .setName(name) + .setSize(w, h) + .setFormat(format) + .setFlags(flags) + .setMetadata(windowType, ownerUid); mSurfaceControl = new SurfaceControlWithBackground( - s, name, w, h, format, flags, windowType, ownerUid, this); + name, b, windowType, w, h, this); Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER); if (mService.mRoot.mSurfaceTraceEnabled) { @@ -246,7 +252,7 @@ class WindowSurfaceController { if (mAnimator.mWin.usesRelativeZOrdering()) { mSurfaceControl.setRelativeLayer( mAnimator.mWin.getParentWindow() - .mWinAnimator.mSurfaceController.mSurfaceControl.getHandle(), + .mWinAnimator.mSurfaceController.mSurfaceControl, -1); } else { mSurfaceLayer = layer; diff --git a/services/core/java/com/android/server/wm/WindowSurfacePlacer.java b/services/core/java/com/android/server/wm/WindowSurfacePlacer.java index fa33fe8fa92a..d57fdd26d250 100644 --- a/services/core/java/com/android/server/wm/WindowSurfacePlacer.java +++ b/services/core/java/com/android/server/wm/WindowSurfacePlacer.java @@ -1,3 +1,18 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License + */ package com.android.server.wm; @@ -689,11 +704,14 @@ class WindowSurfacePlacer { // Create a new surface for the thumbnail WindowState window = appToken.findMainWindow(); - SurfaceControl surfaceControl = new SurfaceControl(mService.mFxSession, - "thumbnail anim", dirty.width(), dirty.height(), - PixelFormat.TRANSLUCENT, SurfaceControl.HIDDEN, - appToken.windowType, - window != null ? window.mOwnerUid : Binder.getCallingUid()); + final SurfaceControl surfaceControl = new SurfaceControl.Builder(mService.mFxSession) + .setName("thumbnail anim") + .setSize(dirty.width(), dirty.height()) + .setFormat(PixelFormat.TRANSLUCENT) + .setMetadata(appToken.windowType, + window != null ? window.mOwnerUid : Binder.getCallingUid()) + .build(); + surfaceControl.setLayerStack(display.getLayerStack()); if (SHOW_TRANSACTIONS) { Slog.i(TAG, " THUMBNAIL " + surfaceControl + ": CREATE"); diff --git a/services/core/java/com/android/server/wm/WindowToken.java b/services/core/java/com/android/server/wm/WindowToken.java index 943448eea2b0..62a2abbb15ec 100644 --- a/services/core/java/com/android/server/wm/WindowToken.java +++ b/services/core/java/com/android/server/wm/WindowToken.java @@ -267,13 +267,13 @@ class WindowToken extends WindowContainer<WindowState> { @CallSuper @Override - public void writeToProto(ProtoOutputStream proto, long fieldId) { + public void writeToProto(ProtoOutputStream proto, long fieldId, boolean trim) { final long token = proto.start(fieldId); - super.writeToProto(proto, WINDOW_CONTAINER); + super.writeToProto(proto, WINDOW_CONTAINER, trim); proto.write(HASH_CODE, System.identityHashCode(this)); for (int i = 0; i < mChildren.size(); i++) { final WindowState w = mChildren.get(i); - w.writeToProto(proto, WINDOWS); + w.writeToProto(proto, WINDOWS, trim); } proto.end(token); } diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java index 80f6a4b9f258..2d8a0ee02225 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java @@ -18,6 +18,7 @@ package com.android.server.devicepolicy; import static android.Manifest.permission.BIND_DEVICE_ADMIN; import static android.Manifest.permission.MANAGE_CA_CERTIFICATES; +import static android.app.ActivityManager.LOCK_TASK_MODE_NONE; import static android.app.admin.DevicePolicyManager.CODE_ACCOUNTS_NOT_EMPTY; import static android.app.admin.DevicePolicyManager.CODE_ADD_MANAGED_PROFILE_DISALLOWED; import static android.app.admin.DevicePolicyManager.CODE_CANNOT_ADD_MANAGED_PROFILE; @@ -225,6 +226,8 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { private static final String TAG_LOCK_TASK_COMPONENTS = "lock-task-component"; + private static final String TAG_LOCK_TASK_FEATURES = "lock-task-features"; + private static final String TAG_STATUS_BAR = "statusbar"; private static final String ATTR_DISABLED = "disabled"; @@ -507,6 +510,9 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { // This is the list of component allowed to start lock task mode. List<String> mLockTaskPackages = new ArrayList<>(); + // Bitfield of feature flags to be enabled during LockTask mode. + int mLockTaskFeatures = DevicePolicyManager.LOCK_TASK_FEATURE_NONE; + boolean mStatusBarDisabled = false; ComponentName mRestrictionsProvider; @@ -2628,6 +2634,12 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { out.endTag(null, TAG_LOCK_TASK_COMPONENTS); } + if (policy.mLockTaskFeatures != DevicePolicyManager.LOCK_TASK_FEATURE_NONE) { + out.startTag(null, TAG_LOCK_TASK_FEATURES); + out.attribute(null, ATTR_VALUE, Integer.toString(policy.mLockTaskFeatures)); + out.endTag(null, TAG_LOCK_TASK_FEATURES); + } + if (policy.mStatusBarDisabled) { out.startTag(null, TAG_STATUS_BAR); out.attribute(null, ATTR_DISABLED, Boolean.toString(policy.mStatusBarDisabled)); @@ -2868,6 +2880,9 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { policy.mAcceptedCaCertificates.add(parser.getAttributeValue(null, ATTR_NAME)); } else if (TAG_LOCK_TASK_COMPONENTS.equals(tag)) { policy.mLockTaskPackages.add(parser.getAttributeValue(null, "name")); + } else if (TAG_LOCK_TASK_FEATURES.equals(tag)) { + policy.mLockTaskFeatures = Integer.parseInt( + parser.getAttributeValue(null, ATTR_VALUE)); } else if (TAG_STATUS_BAR.equals(tag)) { policy.mStatusBarDisabled = Boolean.parseBoolean( parser.getAttributeValue(null, ATTR_DISABLED)); @@ -2936,6 +2951,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { validatePasswordOwnerLocked(policy); updateMaximumTimeToLockLocked(userHandle); updateLockTaskPackagesLocked(policy.mLockTaskPackages, userHandle); + updateLockTaskFeaturesLocked(policy.mLockTaskFeatures, userHandle); if (policy.mStatusBarDisabled) { setStatusBarDisabledInternal(policy.mStatusBarDisabled, userHandle); } @@ -2953,6 +2969,18 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } } + private void updateLockTaskFeaturesLocked(int flags, int userId) { + long ident = mInjector.binderClearCallingIdentity(); + try { + mInjector.getIActivityManager() + .updateLockTaskFeatures(userId, flags); + } catch (RemoteException e) { + // Not gonna happen. + } finally { + mInjector.binderRestoreCallingIdentity(ident); + } + } + private void updateDeviceOwnerLocked() { long ident = mInjector.binderClearCallingIdentity(); try { @@ -6939,6 +6967,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { policy.mUserProvisioningState = DevicePolicyManager.STATE_USER_UNMANAGED; policy.mAffiliationIds.clear(); policy.mLockTaskPackages.clear(); + policy.mLockTaskFeatures = DevicePolicyManager.LOCK_TASK_FEATURE_NONE; saveSettingsLocked(userId); try { @@ -8921,25 +8950,6 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { updateLockTaskPackagesLocked(packages, userHandle); } - private void maybeClearLockTaskPackagesLocked() { - final long ident = mInjector.binderClearCallingIdentity(); - try { - final List<UserInfo> userInfos = mUserManager.getUsers(/*excludeDying=*/ true); - for (int i = 0; i < userInfos.size(); i++) { - int userId = userInfos.get(i).id; - final List<String> lockTaskPackages = getUserData(userId).mLockTaskPackages; - if (!lockTaskPackages.isEmpty() && - !isUserAffiliatedWithDeviceLocked(userId)) { - Slog.d(LOG_TAG, - "User id " + userId + " not affiliated. Clearing lock task packages"); - setLockTaskPackagesLocked(userId, Collections.<String>emptyList()); - } - } - } finally { - mInjector.binderRestoreCallingIdentity(ident); - } - } - @Override public String[] getLockTaskPackages(ComponentName who) { Preconditions.checkNotNull(who, "ComponentName is null"); @@ -8966,12 +8976,82 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } @Override + public void setLockTaskFeatures(ComponentName who, int flags) { + Preconditions.checkNotNull(who, "ComponentName is null"); + final int userHandle = mInjector.userHandleGetCallingUserId(); + synchronized (this) { + getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER); + if (!isUserAffiliatedWithDeviceLocked(userHandle)) { + throw new SecurityException("Admin " + who + + " is neither the device owner or affiliated user's profile owner."); + } + setLockTaskFeaturesLocked(userHandle, flags); + } + } + + private void setLockTaskFeaturesLocked(int userHandle, int flags) { + DevicePolicyData policy = getUserData(userHandle); + policy.mLockTaskFeatures = flags; + saveSettingsLocked(userHandle); + updateLockTaskFeaturesLocked(flags, userHandle); + } + + @Override + public int getLockTaskFeatures(ComponentName who) { + Preconditions.checkNotNull(who, "ComponentName is null"); + final int userHandle = mInjector.userHandleGetCallingUserId(); + synchronized (this) { + getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER); + if (!isUserAffiliatedWithDeviceLocked(userHandle)) { + throw new SecurityException("Admin " + who + + " is neither the device owner or affiliated user's profile owner."); + } + return getUserData(userHandle).mLockTaskFeatures; + } + } + + private void maybeClearLockTaskPolicyLocked() { + final long ident = mInjector.binderClearCallingIdentity(); + try { + final List<UserInfo> userInfos = mUserManager.getUsers(/*excludeDying=*/ true); + for (int i = userInfos.size() - 1; i >= 0; i--) { + int userId = userInfos.get(i).id; + if (isUserAffiliatedWithDeviceLocked(userId)) { + continue; + } + + final List<String> lockTaskPackages = getUserData(userId).mLockTaskPackages; + if (!lockTaskPackages.isEmpty()) { + Slog.d(LOG_TAG, + "User id " + userId + " not affiliated. Clearing lock task packages"); + setLockTaskPackagesLocked(userId, Collections.<String>emptyList()); + } + final int lockTaskFeatures = getUserData(userId).mLockTaskFeatures; + if (lockTaskFeatures != DevicePolicyManager.LOCK_TASK_FEATURE_NONE){ + Slog.d(LOG_TAG, + "User id " + userId + " not affiliated. Clearing lock task features"); + setLockTaskFeaturesLocked(userId, DevicePolicyManager.LOCK_TASK_FEATURE_NONE); + } + } + } finally { + mInjector.binderRestoreCallingIdentity(ident); + } + } + + @Override public void notifyLockTaskModeChanged(boolean isEnabled, String pkg, int userHandle) { if (!isCallerWithSystemUid()) { throw new SecurityException("notifyLockTaskModeChanged can only be called by system"); } synchronized (this) { final DevicePolicyData policy = getUserData(userHandle); + + if (policy.mStatusBarDisabled) { + // Status bar is managed by LockTaskController during LockTask, so we cancel this + // policy when LockTask starts, and reapply it when LockTask ends + setStatusBarDisabledInternal(!isEnabled, userHandle); + } + Bundle adminExtras = new Bundle(); adminExtras.putString(DeviceAdminReceiver.EXTRA_LOCK_TASK_PACKAGE, pkg); for (ActiveAdmin admin : policy.mAdminList) { @@ -9182,8 +9262,17 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_DEVICE_OWNER); DevicePolicyData policy = getUserData(userId); if (policy.mStatusBarDisabled != disabled) { - if (!setStatusBarDisabledInternal(disabled, userId)) { - return false; + boolean isLockTaskMode = false; + try { + isLockTaskMode = mInjector.getIActivityManager().getLockTaskModeState() + != LOCK_TASK_MODE_NONE; + } catch (RemoteException e) { + Slog.e(LOG_TAG, "Failed to get LockTask mode"); + } + if (!isLockTaskMode) { + if (!setStatusBarDisabledInternal(disabled, userId)) { + return false; + } } policy.mStatusBarDisabled = disabled; saveSettingsLocked(userId); @@ -10283,7 +10372,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { // but as a result of that other users might become affiliated or un-affiliated. maybePauseDeviceWideLoggingLocked(); maybeResumeDeviceWideLoggingLocked(); - maybeClearLockTaskPackagesLocked(); + maybeClearLockTaskPolicyLocked(); } } diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java index b78fcddee119..de5d879a05af 100644 --- a/services/java/com/android/server/SystemServer.java +++ b/services/java/com/android/server/SystemServer.java @@ -125,7 +125,10 @@ import java.util.Timer; import java.util.concurrent.CountDownLatch; import java.util.concurrent.Future; -import static android.os.IServiceManager.DUMP_PRIORITY_CRITICAL; +import static android.os.IServiceManager.DUMP_FLAG_PRIORITY_CRITICAL; +import static android.os.IServiceManager.DUMP_FLAG_PRIORITY_HIGH; +import static android.os.IServiceManager.DUMP_FLAG_PRIORITY_NORMAL; +import static android.os.IServiceManager.DUMP_FLAG_PROTO; import static android.view.Display.DEFAULT_DISPLAY; public final class SystemServer { @@ -827,7 +830,7 @@ public final class SystemServer { mFactoryTestMode != FactoryTest.FACTORY_TEST_LOW_LEVEL, !mFirstBoot, mOnlyCore, new PhoneWindowManager()); ServiceManager.addService(Context.WINDOW_SERVICE, wm, /* allowIsolated= */ false, - DUMP_PRIORITY_CRITICAL); + DUMP_FLAG_PRIORITY_CRITICAL | DUMP_FLAG_PROTO); ServiceManager.addService(Context.INPUT_SERVICE, inputManager); traceEnd(); @@ -1138,7 +1141,9 @@ public final class SystemServer { try { connectivity = new ConnectivityService( context, networkManagement, networkStats, networkPolicy); - ServiceManager.addService(Context.CONNECTIVITY_SERVICE, connectivity); + ServiceManager.addService(Context.CONNECTIVITY_SERVICE, connectivity, + /* allowIsolated= */ false, + DUMP_FLAG_PRIORITY_HIGH | DUMP_FLAG_PRIORITY_NORMAL); networkStats.bindConnectivityManager(connectivity); networkPolicy.bindConnectivityManager(connectivity); } catch (Throwable e) { diff --git a/services/net/java/android/net/util/VersionedBroadcastListener.java b/services/net/java/android/net/util/VersionedBroadcastListener.java index 115aa464f4f1..107c40495f9e 100644 --- a/services/net/java/android/net/util/VersionedBroadcastListener.java +++ b/services/net/java/android/net/util/VersionedBroadcastListener.java @@ -61,10 +61,6 @@ public class VersionedBroadcastListener { mGenerationNumber = new AtomicInteger(0); } - public int generationNumber() { - return mGenerationNumber.get(); - } - public void startListening() { if (DBG) Log.d(mTag, "startListening"); if (mReceiver != null) return; diff --git a/services/tests/servicestests/src/com/android/server/am/ActivityTestsBase.java b/services/tests/servicestests/src/com/android/server/am/ActivityTestsBase.java index 3d5d87c1359a..198cc6ded558 100644 --- a/services/tests/servicestests/src/com/android/server/am/ActivityTestsBase.java +++ b/services/tests/servicestests/src/com/android/server/am/ActivityTestsBase.java @@ -78,7 +78,11 @@ public class ActivityTestsBase { } protected ActivityManagerService createActivityManagerService() { - final ActivityManagerService service = spy(new TestActivityManagerService(mContext)); + return setupActivityManagerService(new TestActivityManagerService(mContext)); + } + + protected ActivityManagerService setupActivityManagerService(ActivityManagerService service) { + service = spy(service); service.mWindowManager = prepareMockWindowManager(); return service; } diff --git a/services/tests/servicestests/src/com/android/server/am/LockTaskControllerTest.java b/services/tests/servicestests/src/com/android/server/am/LockTaskControllerTest.java index 4c1d3e9f0003..44a79ab3a6f3 100644 --- a/services/tests/servicestests/src/com/android/server/am/LockTaskControllerTest.java +++ b/services/tests/servicestests/src/com/android/server/am/LockTaskControllerTest.java @@ -19,6 +19,16 @@ package com.android.server.am; import static android.app.ActivityManager.LOCK_TASK_MODE_LOCKED; import static android.app.ActivityManager.LOCK_TASK_MODE_NONE; import static android.app.ActivityManager.LOCK_TASK_MODE_PINNED; +import static android.app.StatusBarManager.DISABLE2_MASK; +import static android.app.StatusBarManager.DISABLE2_NONE; +import static android.app.StatusBarManager.DISABLE2_NOTIFICATION_SHADE; +import static android.app.StatusBarManager.DISABLE_HOME; +import static android.app.StatusBarManager.DISABLE_NOTIFICATION_ALERTS; +import static android.app.StatusBarManager.DISABLE_NOTIFICATION_ICONS; +import static android.app.admin.DevicePolicyManager.LOCK_TASK_FEATURE_HOME; +import static android.app.admin.DevicePolicyManager.LOCK_TASK_FEATURE_KEYGUARD; +import static android.app.admin.DevicePolicyManager.LOCK_TASK_FEATURE_NONE; +import static android.app.admin.DevicePolicyManager.LOCK_TASK_FEATURE_NOTIFICATIONS; import static android.os.Process.SYSTEM_UID; import static com.android.server.am.LockTaskController.STATUS_BAR_MASK_LOCKED; @@ -29,6 +39,7 @@ import static org.mockito.ArgumentMatchers.*; import static org.mockito.Mockito.*; import android.app.StatusBarManager; +import android.app.admin.DevicePolicyManager; import android.app.admin.IDevicePolicyManager; import android.content.ComponentName; import android.content.Context; @@ -42,6 +53,7 @@ import android.platform.test.annotations.Presubmit; import android.provider.Settings; import android.support.test.InstrumentationRegistry; import android.support.test.filters.SmallTest; +import android.util.Pair; import com.android.internal.statusbar.IStatusBarService; import com.android.internal.widget.LockPatternUtils; @@ -139,7 +151,7 @@ public class LockTaskControllerTest { assertTrue(mLockTaskController.checkLockedTask(tr)); // THEN lock task mode should be started - verifyLockTaskStarted(STATUS_BAR_MASK_LOCKED); + verifyLockTaskStarted(STATUS_BAR_MASK_LOCKED, DISABLE2_MASK); } @Test @@ -159,7 +171,7 @@ public class LockTaskControllerTest { assertTrue(mLockTaskController.checkLockedTask(tr2)); // THEN lock task mode should be started - verifyLockTaskStarted(STATUS_BAR_MASK_LOCKED); + verifyLockTaskStarted(STATUS_BAR_MASK_LOCKED, DISABLE2_MASK); } @Test @@ -188,7 +200,7 @@ public class LockTaskControllerTest { assertTrue(mLockTaskController.checkLockedTask(tr)); // THEN lock task mode should be started - verifyLockTaskStarted(STATUS_BAR_MASK_PINNED); + verifyLockTaskStarted(STATUS_BAR_MASK_PINNED, DISABLE2_NONE); // THEN screen pinning toast should be shown verify(mLockTaskNotify).showPinningStartToast(); } @@ -291,6 +303,9 @@ public class LockTaskControllerTest { Settings.Secure.putInt(mContext.getContentResolver(), Settings.Secure.LOCK_TO_APP_EXIT_LOCKED, 1); + // reset invocation counter + reset(mStatusBarService); + // WHEN calling stopLockTask mLockTaskController.stopLockTaskMode(true, SYSTEM_UID); @@ -354,7 +369,7 @@ public class LockTaskControllerTest { assertEquals(LOCK_TASK_MODE_LOCKED, mLockTaskController.getLockTaskModeState()); assertTrue(mLockTaskController.checkLockedTask(tr1)); assertTrue(mLockTaskController.checkLockedTask(tr2)); - verifyLockTaskStarted(STATUS_BAR_MASK_LOCKED); + verifyLockTaskStarted(STATUS_BAR_MASK_LOCKED, DISABLE2_MASK); // WHEN removing one package from whitelist whitelist = new String[] {TEST_PACKAGE_NAME}; @@ -366,7 +381,7 @@ public class LockTaskControllerTest { // THEN the other task should remain locked assertEquals(LOCK_TASK_MODE_LOCKED, mLockTaskController.getLockTaskModeState()); assertTrue(mLockTaskController.checkLockedTask(tr1)); - verifyLockTaskStarted(STATUS_BAR_MASK_LOCKED); + verifyLockTaskStarted(STATUS_BAR_MASK_LOCKED, DISABLE2_MASK); // WHEN removing the last package from whitelist whitelist = new String[] {}; @@ -379,6 +394,131 @@ public class LockTaskControllerTest { verifyLockTaskStopped(times(1)); } + @Test + public void testUpdateLockTaskFeatures() throws Exception { + // GIVEN a locked task + TaskRecord tr = getTaskRecord(TaskRecord.LOCK_TASK_AUTH_WHITELISTED); + mLockTaskController.startLockTaskMode(tr, false, TEST_UID); + + // THEN lock task mode should be started with default status bar masks + verifyLockTaskStarted(STATUS_BAR_MASK_LOCKED, DISABLE2_MASK); + + // reset invocation counter + reset(mStatusBarService); + + // WHEN home button is enabled for lock task mode + mLockTaskController.updateLockTaskFeatures(TEST_USER_ID, LOCK_TASK_FEATURE_HOME); + + // THEN status bar should be updated to reflect this change + int expectedFlags = STATUS_BAR_MASK_LOCKED + & ~DISABLE_HOME; + int expectedFlags2 = DISABLE2_MASK; + verify(mStatusBarService).disable(eq(expectedFlags), any(IBinder.class), + eq(mContext.getPackageName())); + verify(mStatusBarService).disable2(eq(expectedFlags2), any(IBinder.class), + eq(mContext.getPackageName())); + + // reset invocation counter + reset(mStatusBarService); + + // WHEN notifications are enabled for lock task mode + mLockTaskController.updateLockTaskFeatures(TEST_USER_ID, LOCK_TASK_FEATURE_NOTIFICATIONS); + + // THEN status bar should be updated to reflect this change + expectedFlags = STATUS_BAR_MASK_LOCKED + & ~DISABLE_NOTIFICATION_ICONS + & ~DISABLE_NOTIFICATION_ALERTS; + expectedFlags2 = DISABLE2_MASK + & ~DISABLE2_NOTIFICATION_SHADE; + verify(mStatusBarService).disable(eq(expectedFlags), any(IBinder.class), + eq(mContext.getPackageName())); + verify(mStatusBarService).disable2(eq(expectedFlags2), any(IBinder.class), + eq(mContext.getPackageName())); + } + + @Test + public void testUpdateLockTaskFeatures_differentUser() throws Exception { + // GIVEN a locked task + TaskRecord tr = getTaskRecord(TaskRecord.LOCK_TASK_AUTH_WHITELISTED); + mLockTaskController.startLockTaskMode(tr, false, TEST_UID); + + // THEN lock task mode should be started with default status bar masks + verifyLockTaskStarted(STATUS_BAR_MASK_LOCKED, DISABLE2_MASK); + + // reset invocation counter + reset(mStatusBarService); + + // WHEN home button is enabled for lock task mode for another user + mLockTaskController.updateLockTaskFeatures(TEST_USER_ID + 1, LOCK_TASK_FEATURE_HOME); + + // THEN status bar shouldn't change + verify(mStatusBarService, never()).disable(anyInt(), any(IBinder.class), + eq(mContext.getPackageName())); + verify(mStatusBarService, never()).disable2(anyInt(), any(IBinder.class), + eq(mContext.getPackageName())); + } + + @Test + public void testUpdateLockTaskFeatures_keyguard() throws Exception { + // GIVEN a locked task + TaskRecord tr = getTaskRecord(TaskRecord.LOCK_TASK_AUTH_WHITELISTED); + mLockTaskController.startLockTaskMode(tr, false, TEST_UID); + + // THEN keyguard should be disabled + verify(mWindowManager).disableKeyguard(any(IBinder.class), anyString()); + + // WHEN keyguard is enabled for lock task mode + mLockTaskController.updateLockTaskFeatures(TEST_USER_ID, LOCK_TASK_FEATURE_KEYGUARD); + + // THEN keyguard should be enabled + verify(mWindowManager).reenableKeyguard(any(IBinder.class)); + + // WHEN keyguard is disabled again for lock task mode + mLockTaskController.updateLockTaskFeatures(TEST_USER_ID, LOCK_TASK_FEATURE_NONE); + + // THEN keyguard should be disabled + verify(mWindowManager, times(2)).disableKeyguard(any(IBinder.class), anyString()); + } + + @Test + public void testGetStatusBarDisableFlags() { + // Note that we don't enumerate all StatusBarManager flags, but only choose a subset to test + + // WHEN nothing is enabled + Pair<Integer, Integer> flags = mLockTaskController.getStatusBarDisableFlags( + LOCK_TASK_FEATURE_NONE); + // THEN unsupported feature flags should still be untouched + assertTrue((~STATUS_BAR_MASK_LOCKED & flags.first) == 0); + // THEN everything else should be disabled + assertTrue((StatusBarManager.DISABLE_CLOCK & flags.first) != 0); + assertTrue((StatusBarManager.DISABLE2_QUICK_SETTINGS & flags.second) != 0); + + // WHEN only home button is enabled + flags = mLockTaskController.getStatusBarDisableFlags( + LOCK_TASK_FEATURE_HOME); + // THEN unsupported feature flags should still be untouched + assertTrue((~STATUS_BAR_MASK_LOCKED & flags.first) == 0); + // THEN home button should indeed be enabled + assertTrue((StatusBarManager.DISABLE_HOME & flags.first) == 0); + // THEN other feature flags should remain disabled + assertTrue((StatusBarManager.DISABLE2_NOTIFICATION_SHADE & flags.second) != 0); + + // WHEN only global actions menu and notifications are enabled + flags = mLockTaskController.getStatusBarDisableFlags( + DevicePolicyManager.LOCK_TASK_FEATURE_GLOBAL_ACTIONS + | DevicePolicyManager.LOCK_TASK_FEATURE_NOTIFICATIONS); + // THEN unsupported feature flags should still be untouched + assertTrue((~STATUS_BAR_MASK_LOCKED & flags.first) == 0); + // THEN notifications should be enabled + assertTrue((StatusBarManager.DISABLE_NOTIFICATION_ICONS & flags.first) == 0); + assertTrue((StatusBarManager.DISABLE_NOTIFICATION_ALERTS & flags.first) == 0); + assertTrue((StatusBarManager.DISABLE2_NOTIFICATION_SHADE & flags.second) == 0); + // THEN global actions should be enabled + assertTrue((StatusBarManager.DISABLE2_GLOBAL_ACTIONS & flags.second) == 0); + // THEN quick settings should still be disabled + assertTrue((StatusBarManager.DISABLE2_QUICK_SETTINGS & flags.second) != 0); + } + private TaskRecord getTaskRecord(int lockTaskAuth) { return getTaskRecord(TEST_PACKAGE_NAME, lockTaskAuth); } @@ -411,12 +551,14 @@ public class LockTaskControllerTest { return tr; } - private void verifyLockTaskStarted(int statusBarMask) throws Exception { + private void verifyLockTaskStarted(int statusBarMask, int statusBarMask2) throws Exception { // THEN the keyguard should have been disabled verify(mWindowManager).disableKeyguard(any(IBinder.class), anyString()); // THEN the status bar should have been disabled verify(mStatusBarService).disable(eq(statusBarMask), any(IBinder.class), eq(mContext.getPackageName())); + verify(mStatusBarService).disable2(eq(statusBarMask2), any(IBinder.class), + eq(mContext.getPackageName())); // THEN the DO/PO should be informed about the operation verify(mDevicePolicyManager).notifyLockTaskModeChanged(true, TEST_PACKAGE_NAME, TEST_USER_ID); @@ -428,6 +570,8 @@ public class LockTaskControllerTest { // THEN the status bar should have been disabled verify(mStatusBarService, mode).disable(eq(StatusBarManager.DISABLE_NONE), any(IBinder.class), eq(mContext.getPackageName())); + verify(mStatusBarService, mode).disable2(eq(StatusBarManager.DISABLE2_NONE), + any(IBinder.class), eq(mContext.getPackageName())); // THEN the DO/PO should be informed about the operation verify(mDevicePolicyManager, mode).notifyLockTaskModeChanged(false, null, TEST_USER_ID); } diff --git a/services/tests/servicestests/src/com/android/server/am/RecentTasksTest.java b/services/tests/servicestests/src/com/android/server/am/RecentTasksTest.java index 939e989c5fe8..3c9b54215f80 100644 --- a/services/tests/servicestests/src/com/android/server/am/RecentTasksTest.java +++ b/services/tests/servicestests/src/com/android/server/am/RecentTasksTest.java @@ -16,44 +16,55 @@ package com.android.server.am; +import static android.app.ActivityManager.DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT; import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD; +import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED; import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN; +import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED; import static android.content.Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS; import static android.content.Intent.FLAG_ACTIVITY_NEW_DOCUMENT; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.eq; +import static org.junit.Assert.fail; +import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.when; +import static java.lang.Integer.MAX_VALUE; + +import android.app.ActivityManager.RecentTaskInfo; +import android.app.ActivityManager.RunningTaskInfo; import android.content.ComponentName; import android.content.Context; +import android.content.pm.PackageManager; +import android.content.pm.ParceledListSlice; import android.content.pm.UserInfo; -import android.os.Debug; +import android.graphics.Rect; +import android.os.Bundle; +import android.os.Looper; +import android.os.RemoteException; import android.os.SystemClock; import android.platform.test.annotations.Presubmit; import android.support.test.InstrumentationRegistry; import android.support.test.filters.MediumTest; import android.support.test.runner.AndroidJUnit4; import android.util.MutableLong; +import android.util.SparseArray; import android.util.SparseBooleanArray; import com.android.server.am.RecentTasks.Callbacks; -import org.junit.After; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; import java.io.File; import java.util.ArrayList; import java.util.Arrays; +import java.util.HashSet; import java.util.List; +import java.util.Set; /** * runtest --path frameworks/base/services/tests/servicestests/src/com/android/server/am/RecentTasksTest.java @@ -67,13 +78,17 @@ public class RecentTasksTest extends ActivityTestsBase { private static final int TEST_QUIET_USER_ID = 20; private static final UserInfo DEFAULT_USER_INFO = new UserInfo(); private static final UserInfo QUIET_USER_INFO = new UserInfo(); + private static final ComponentName MY_COMPONENT = new ComponentName( + RecentTasksTest.class.getPackage().getName(), RecentTasksTest.class.getName()); private static int LAST_TASK_ID = 1; + private static int INVALID_STACK_ID = 999; private Context mContext = InstrumentationRegistry.getContext(); private ActivityManagerService mService; private ActivityStack mStack; private TestTaskPersister mTaskPersister; private RecentTasks mRecentTasks; + private RunningTasks mRunningTasks; private static ArrayList<TaskRecord> mTasks = new ArrayList<>(); private static ArrayList<TaskRecord> mSameDocumentTasks = new ArrayList<>(); @@ -91,6 +106,14 @@ public class RecentTasksTest extends ActivityTestsBase { } @Override + Set<Integer> getProfileIds(int userId) { + Set<Integer> profileIds = new HashSet<>(); + profileIds.add(TEST_USER_0_ID); + profileIds.add(TEST_QUIET_USER_ID); + return profileIds; + } + + @Override UserInfo getUserInfo(int userId) { switch (userId) { case TEST_USER_0_ID: @@ -108,12 +131,12 @@ public class RecentTasksTest extends ActivityTestsBase { public void setUp() throws Exception { super.setUp(); - mService = createActivityManagerService(); - mStack = mService.mStackSupervisor.getDefaultDisplay().createStack( - WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */); mTaskPersister = new TestTaskPersister(mContext.getFilesDir()); - mRecentTasks = new RecentTasks(mService, mTaskPersister, new TestUserController(mService)); + mService = setupActivityManagerService(new MyTestActivityManagerService(mContext)); + mRecentTasks = mService.getRecentTasks(); mRecentTasks.loadParametersFromResources(mContext.getResources()); + mStack = mService.mStackSupervisor.getDefaultDisplay().createStack( + WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */); mCallbacksRecorder = new CallbacksRecorder(); mRecentTasks.registerCallback(mCallbacksRecorder); QUIET_USER_INFO.flags = UserInfo.FLAG_MANAGED_PROFILE | UserInfo.FLAG_QUIET_MODE; @@ -322,6 +345,103 @@ public class RecentTasksTest extends ActivityTestsBase { assertTrimmed(mTasks.get(0), mTasks.get(1)); } + @Test + public void testNotRecentsComponent_denyApiAccess() throws Exception { + doReturn(PackageManager.PERMISSION_DENIED).when(mService).checkPermission(anyString(), + anyInt(), anyInt()); + + // Expect the following methods to fail due to recents component not being set + ((TestRecentTasks) mRecentTasks).setIsCallerRecentsOverride( + TestRecentTasks.DENY_THROW_SECURITY_EXCEPTION); + testRecentTasksApis(false /* expectNoSecurityException */); + // Don't throw for the following tests + ((TestRecentTasks) mRecentTasks).setIsCallerRecentsOverride(TestRecentTasks.DENY); + testGetTasksApis(false /* expectNoSecurityException */); + } + + @Test + public void testRecentsComponent_allowApiAccessWithoutPermissions() throws Exception { + doReturn(PackageManager.PERMISSION_DENIED).when(mService).checkPermission(anyString(), + anyInt(), anyInt()); + + // Set the recents component and ensure that the following calls do not fail + ((TestRecentTasks) mRecentTasks).setIsCallerRecentsOverride(TestRecentTasks.GRANT); + testRecentTasksApis(true /* expectNoSecurityException */); + testGetTasksApis(true /* expectNoSecurityException */); + } + + private void testRecentTasksApis(boolean expectCallable) { + assertSecurityException(expectCallable, () -> mService.removeStack(INVALID_STACK_ID)); + assertSecurityException(expectCallable, + () -> mService.removeStacksInWindowingModes(new int[] {WINDOWING_MODE_UNDEFINED})); + assertSecurityException(expectCallable, + () -> mService.removeStacksWithActivityTypes(new int[] {ACTIVITY_TYPE_UNDEFINED})); + assertSecurityException(expectCallable, () -> mService.removeTask(0)); + assertSecurityException(expectCallable, + () -> mService.setTaskWindowingMode(0, WINDOWING_MODE_UNDEFINED, true)); + assertSecurityException(expectCallable, + () -> mService.moveTaskToStack(0, INVALID_STACK_ID, true)); + assertSecurityException(expectCallable, + () -> mService.moveTaskToDockedStack(0, DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT, true, + true, new Rect())); + assertSecurityException(expectCallable, () -> mService.dismissSplitScreenMode(true)); + assertSecurityException(expectCallable, () -> mService.dismissPip(true, 0)); + assertSecurityException(expectCallable, + () -> mService.moveTopActivityToPinnedStack(INVALID_STACK_ID, new Rect())); + assertSecurityException(expectCallable, + () -> mService.resizeStack(INVALID_STACK_ID, new Rect(), true, true, true, 0)); + assertSecurityException(expectCallable, + () -> mService.resizeDockedStack(new Rect(), new Rect(), new Rect(), new Rect(), + new Rect())); + assertSecurityException(expectCallable, + () -> mService.resizePinnedStack(new Rect(), new Rect())); + assertSecurityException(expectCallable, () -> mService.getAllStackInfos()); + assertSecurityException(expectCallable, + () -> mService.getStackInfo(WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_UNDEFINED)); + assertSecurityException(expectCallable, () -> { + try { + mService.getFocusedStackInfo(); + } catch (RemoteException e) { + // Ignore + } + }); + assertSecurityException(expectCallable, + () -> mService.moveTasksToFullscreenStack(INVALID_STACK_ID, true)); + assertSecurityException(expectCallable, + () -> mService.startActivityFromRecents(0, new Bundle())); + assertSecurityException(expectCallable, + () -> mService.getTaskSnapshot(0, true)); + assertSecurityException(expectCallable, () -> { + try { + mService.registerTaskStackListener(null); + } catch (RemoteException e) { + // Ignore + } + }); + assertSecurityException(expectCallable, () -> { + try { + mService.unregisterTaskStackListener(null); + } catch (RemoteException e) { + // Ignore + } + }); + assertSecurityException(expectCallable, () -> mService.getTaskDescription(0)); + assertSecurityException(expectCallable, () -> mService.cancelTaskWindowTransition(0)); + assertSecurityException(expectCallable, () -> mService.cancelTaskThumbnailTransition(0)); + } + + private void testGetTasksApis(boolean expectCallable) { + mService.getRecentTasks(MAX_VALUE, 0, TEST_USER_0_ID); + mService.getTasks(MAX_VALUE); + if (expectCallable) { + assertTrue(((TestRecentTasks) mRecentTasks).mLastAllowed); + assertTrue(((TestRunningTasks) mRunningTasks).mLastAllowed); + } else { + assertFalse(((TestRecentTasks) mRecentTasks).mLastAllowed); + assertFalse(((TestRunningTasks) mRunningTasks).mLastAllowed); + } + } + private ComponentName createComponent(String className) { return new ComponentName(mContext.getPackageName(), className); } @@ -367,6 +487,55 @@ public class RecentTasksTest extends ActivityTestsBase { } } + private void assertSecurityException(boolean expectCallable, Runnable runnable) { + boolean noSecurityException = true; + try { + runnable.run(); + } catch (SecurityException se) { + noSecurityException = false; + } catch (Exception e) { + // We only care about SecurityExceptions, fall through here + e.printStackTrace(); + } + if (noSecurityException != expectCallable) { + fail("Expected callable: " + expectCallable + " but got no security exception: " + + noSecurityException); + } + } + + private class MyTestActivityManagerService extends TestActivityManagerService { + MyTestActivityManagerService(Context context) { + super(context); + } + + @Override + protected ActivityStackSupervisor createStackSupervisor() { + return new MyTestActivityStackSupervisor(this, mHandlerThread.getLooper()); + } + + @Override + protected RecentTasks createRecentTasks() { + return new TestRecentTasks(this, mTaskPersister, new TestUserController(this)); + } + + @Override + public boolean isUserRunning(int userId, int flags) { + return true; + } + } + + private class MyTestActivityStackSupervisor extends TestActivityStackSupervisor { + public MyTestActivityStackSupervisor(ActivityManagerService service, Looper looper) { + super(service, looper); + } + + @Override + RunningTasks createRunningTasks() { + mRunningTasks = new TestRunningTasks(); + return mRunningTasks; + } + } + private static class CallbacksRecorder implements Callbacks { ArrayList<TaskRecord> added = new ArrayList<>(); ArrayList<TaskRecord> trimmed = new ArrayList<>(); @@ -417,4 +586,61 @@ public class RecentTasksTest extends ActivityTestsBase { return super.restoreTasksForUserLocked(userId, preaddedTasks); } } + + private static class TestRecentTasks extends RecentTasks { + static final int GRANT = 0; + static final int DENY = 1; + static final int DENY_THROW_SECURITY_EXCEPTION = 2; + + private boolean mOverrideIsCallerRecents; + private int mIsCallerRecentsPolicy; + boolean mLastAllowed; + + TestRecentTasks(ActivityManagerService service, TaskPersister taskPersister, + UserController userController) { + super(service, taskPersister, userController); + } + + @Override + boolean isCallerRecents(int callingUid) { + if (mOverrideIsCallerRecents) { + switch (mIsCallerRecentsPolicy) { + case GRANT: + return true; + case DENY: + return false; + case DENY_THROW_SECURITY_EXCEPTION: + throw new SecurityException(); + } + } + return super.isCallerRecents(callingUid); + } + + void setIsCallerRecentsOverride(int policy) { + mOverrideIsCallerRecents = true; + mIsCallerRecentsPolicy = policy; + } + + @Override + ParceledListSlice<RecentTaskInfo> getRecentTasks(int maxNum, int flags, + boolean getTasksAllowed, + boolean getDetailedTasks, int userId, int callingUid) { + mLastAllowed = getTasksAllowed; + return super.getRecentTasks(maxNum, flags, getTasksAllowed, getDetailedTasks, userId, + callingUid); + } + } + + private static class TestRunningTasks extends RunningTasks { + boolean mLastAllowed; + + @Override + void getTasks(int maxNum, List<RunningTaskInfo> list, int ignoreActivityType, + int ignoreWindowingMode, SparseArray<ActivityDisplay> activityDisplays, + int callingUid, boolean allowed) { + mLastAllowed = allowed; + super.getTasks(maxNum, list, ignoreActivityType, ignoreWindowingMode, activityDisplays, + callingUid, allowed); + } + } }
\ No newline at end of file diff --git a/services/tests/servicestests/src/com/android/server/am/RunningTasksTest.java b/services/tests/servicestests/src/com/android/server/am/RunningTasksTest.java new file mode 100644 index 000000000000..fc7562869490 --- /dev/null +++ b/services/tests/servicestests/src/com/android/server/am/RunningTasksTest.java @@ -0,0 +1,126 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.server.am; + +import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD; +import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED; +import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN; +import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED; +import static android.view.Display.DEFAULT_DISPLAY; + +import static com.android.server.am.ActivityDisplay.POSITION_BOTTOM; + +import static org.junit.Assert.assertTrue; + +import android.app.ActivityManager.RunningTaskInfo; +import android.content.ComponentName; +import android.content.Context; +import android.platform.test.annotations.Presubmit; +import android.support.test.InstrumentationRegistry; +import android.support.test.filters.MediumTest; +import android.support.test.runner.AndroidJUnit4; +import android.util.SparseArray; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; + +import java.util.ArrayList; + +/** + * runtest --path frameworks/base/services/tests/servicestests/src/com/android/server/am/RunningTasksTest.java + */ +@MediumTest +@Presubmit +@RunWith(AndroidJUnit4.class) +public class RunningTasksTest extends ActivityTestsBase { + + private Context mContext = InstrumentationRegistry.getContext(); + private ActivityManagerService mService; + + private RunningTasks mRunningTasks; + + @Before + @Override + public void setUp() throws Exception { + super.setUp(); + + mService = createActivityManagerService(); + mRunningTasks = new RunningTasks(); + } + + @Test + public void testCollectTasksByLastActiveTime() throws Exception { + // Create a number of stacks with tasks (of incrementing active time) + final ActivityStackSupervisor supervisor = mService.mStackSupervisor; + final SparseArray<ActivityDisplay> displays = new SparseArray<>(); + final ActivityDisplay display = new ActivityDisplay(supervisor, DEFAULT_DISPLAY); + displays.put(DEFAULT_DISPLAY, display); + + final int numStacks = 2; + for (int stackIndex = 0; stackIndex < numStacks; stackIndex++) { + final ActivityStack stack = new TestActivityStack(display, stackIndex, supervisor, + WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true); + display.addChild(stack, POSITION_BOTTOM); + } + + final int numTasks = 10; + int activeTime = 0; + for (int i = 0; i < numTasks; i++) { + createTask(display.getChildAt(i % numStacks), ".Task" + i, i, activeTime++); + } + + // Ensure that the latest tasks were returned in order of decreasing last active time, + // collected from all tasks across all the stacks + final int numFetchTasks = 5; + ArrayList<RunningTaskInfo> tasks = new ArrayList<>(); + mRunningTasks.getTasks(5, tasks, ACTIVITY_TYPE_UNDEFINED, WINDOWING_MODE_UNDEFINED, + displays, -1 /* callingUid */, true /* allowed */); + assertTrue(tasks.size() == numFetchTasks); + for (int i = 0; i < numFetchTasks; i++) { + assertTrue(tasks.get(i).id == (numTasks - i - 1)); + } + + // Ensure that requesting more than the total number of tasks only returns the subset + // and does not crash + tasks.clear(); + mRunningTasks.getTasks(100, tasks, ACTIVITY_TYPE_UNDEFINED, WINDOWING_MODE_UNDEFINED, + displays, -1 /* callingUid */, true /* allowed */); + assertTrue(tasks.size() == numTasks); + for (int i = 0; i < numTasks; i++) { + assertTrue(tasks.get(i).id == (numTasks - i - 1)); + } + } + + /** + * Create a task with a single activity in it, with the given last active time. + */ + private TaskRecord createTask(ActivityStack stack, String className, int taskId, + int lastActiveTime) { + final TaskRecord task = new TaskBuilder(mService.mStackSupervisor) + .setComponent(new ComponentName(mContext.getPackageName(), className)) + .setTaskId(taskId) + .setStack(stack) + .build(); + task.lastActiveTime = lastActiveTime; + final ActivityRecord activity = new ActivityBuilder(mService) + .setTask(task) + .setComponent(new ComponentName(mContext.getPackageName(), ".TaskActivity")) + .build(); + return task; + } +}
\ No newline at end of file diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java index e1e9cf5bc013..9d23fe9691b1 100644 --- a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java +++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java @@ -3340,13 +3340,15 @@ public class DevicePolicyManagerTest extends DpmTestBase { MoreAsserts.assertEmpty(targetUsers); } - public void testLockTaskPackagesAllowedForAffiliatedUsers() throws Exception { + public void testLockTaskPolicyAllowedForAffiliatedUsers() throws Exception { // Setup a device owner. mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID; setupDeviceOwner(); - // Lock task packages are updated when loading user data. - verify(getServices().iactivityManager) - .updateLockTaskPackages(eq(UserHandle.USER_SYSTEM), eq(new String[0])); + // Lock task policy is updated when loading user data. + verify(getServices().iactivityManager).updateLockTaskPackages( + UserHandle.USER_SYSTEM, new String[0]); + verify(getServices().iactivityManager).updateLockTaskFeatures( + UserHandle.USER_SYSTEM, DevicePolicyManager.LOCK_TASK_FEATURE_NONE); // Set up a managed profile managed by different package (package name shouldn't matter) final int MANAGED_PROFILE_USER_ID = 15; @@ -3354,8 +3356,10 @@ public class DevicePolicyManagerTest extends DpmTestBase { final ComponentName adminDifferentPackage = new ComponentName("another.package", "whatever.class"); addManagedProfile(adminDifferentPackage, MANAGED_PROFILE_ADMIN_UID, admin2); - verify(getServices().iactivityManager) - .updateLockTaskPackages(eq(MANAGED_PROFILE_USER_ID), eq(new String[0])); + verify(getServices().iactivityManager).updateLockTaskPackages( + MANAGED_PROFILE_USER_ID, new String[0]); + verify(getServices().iactivityManager).updateLockTaskFeatures( + MANAGED_PROFILE_USER_ID, DevicePolicyManager.LOCK_TASK_FEATURE_NONE); // The DO can still set lock task packages mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID; @@ -3364,8 +3368,14 @@ public class DevicePolicyManagerTest extends DpmTestBase { MoreAsserts.assertEquals(doPackages, dpm.getLockTaskPackages(admin1)); assertTrue(dpm.isLockTaskPermitted("doPackage1")); assertFalse(dpm.isLockTaskPermitted("anotherPackage")); - verify(getServices().iactivityManager) - .updateLockTaskPackages(eq(UserHandle.USER_SYSTEM), eq(doPackages)); + verify(getServices().iactivityManager).updateLockTaskPackages( + UserHandle.USER_SYSTEM, doPackages); + // And the DO can still set lock task features + final int doFlags = DevicePolicyManager.LOCK_TASK_FEATURE_NOTIFICATIONS + | DevicePolicyManager.LOCK_TASK_FEATURE_RECENTS; + dpm.setLockTaskFeatures(admin1, doFlags); + verify(getServices().iactivityManager).updateLockTaskFeatures( + UserHandle.USER_SYSTEM, doFlags); // Managed profile is unaffiliated - shouldn't be able to setLockTaskPackages. mContext.binder.callingUid = MANAGED_PROFILE_ADMIN_UID; @@ -3375,6 +3385,11 @@ public class DevicePolicyManagerTest extends DpmTestBase { assertExpectException(SecurityException.class, /* messageRegex =*/ null, () -> dpm.getLockTaskPackages(adminDifferentPackage)); assertFalse(dpm.isLockTaskPermitted("doPackage1")); + // And it shouldn't be able to setLockTaskFeatures. + final int poFlags = DevicePolicyManager.LOCK_TASK_FEATURE_NOTIFICATIONS + | DevicePolicyManager.LOCK_TASK_FEATURE_RECENTS; + assertExpectException(SecurityException.class, /* messageRegex =*/ null, + () -> dpm.setLockTaskFeatures(adminDifferentPackage, poFlags)); // Setting same affiliation ids final Set<String> userAffiliationIds = Collections.singleton("some-affiliation-id"); @@ -3389,15 +3404,21 @@ public class DevicePolicyManagerTest extends DpmTestBase { MoreAsserts.assertEquals(poPackages, dpm.getLockTaskPackages(adminDifferentPackage)); assertTrue(dpm.isLockTaskPermitted("poPackage1")); assertFalse(dpm.isLockTaskPermitted("doPackage2")); - verify(getServices().iactivityManager) - .updateLockTaskPackages(eq(MANAGED_PROFILE_USER_ID), eq(poPackages)); + verify(getServices().iactivityManager).updateLockTaskPackages( + MANAGED_PROFILE_USER_ID, poPackages); + // And it can set lock task features. + dpm.setLockTaskFeatures(adminDifferentPackage, poFlags); + verify(getServices().iactivityManager).updateLockTaskFeatures( + MANAGED_PROFILE_USER_ID, poFlags); // Unaffiliate the profile, lock task mode no longer available on the profile. dpm.setAffiliationIds(adminDifferentPackage, Collections.emptySet()); assertFalse(dpm.isLockTaskPermitted("poPackage1")); // Lock task packages cleared when loading user data and when the user becomes unaffiliated. - verify(getServices().iactivityManager, times(2)) - .updateLockTaskPackages(eq(MANAGED_PROFILE_USER_ID), eq(new String[0])); + verify(getServices().iactivityManager, times(2)).updateLockTaskPackages( + MANAGED_PROFILE_USER_ID, new String[0]); + verify(getServices().iactivityManager, times(2)).updateLockTaskFeatures( + MANAGED_PROFILE_USER_ID, DevicePolicyManager.LOCK_TASK_FEATURE_NONE); mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID; assertTrue(dpm.isLockTaskPermitted("doPackage1")); diff --git a/services/tests/servicestests/src/com/android/server/utils/PriorityDumpTest.java b/services/tests/servicestests/src/com/android/server/utils/PriorityDumpTest.java index 8a312f64a846..da45d81c6a08 100644 --- a/services/tests/servicestests/src/com/android/server/utils/PriorityDumpTest.java +++ b/services/tests/servicestests/src/com/android/server/utils/PriorityDumpTest.java @@ -19,6 +19,7 @@ package com.android.server.utils; import static com.android.server.utils.PriorityDump.dump; import static org.junit.Assert.assertSame; +import static org.junit.Assert.assertArrayEquals; import static org.mockito.Matchers.eq; import static org.mockito.Matchers.same; import static org.mockito.Mockito.verify; @@ -59,13 +60,13 @@ public class PriorityDumpTest { @Test public void testNullArgs() { dump(mDumper, mFd, mPw, null); - verify(mDumper).dump(same(mFd), same(mPw), eq(null)); + verify(mDumper).dump(same(mFd), same(mPw), eq(null), /* asProto= */ eq(false)); } @Test public void testNoArgs() { dump(mDumper, mFd, mPw, EMPTY_ARGS); - verify(mDumper).dump(same(mFd), same(mPw), same(EMPTY_ARGS)); + verify(mDumper).dump(same(mFd), same(mPw), eq(EMPTY_ARGS), /* asProto= */ eq(false)); } @Test @@ -74,7 +75,7 @@ public class PriorityDumpTest { "--dumb_priority" }; dump(mDumper, mFd, mPw, args); - verify(mDumper).dump(same(mFd), same(mPw), same(args)); + verify(mDumper).dump(same(mFd), same(mPw), eq(args), /* asProto= */ eq(false)); } @Test @@ -83,7 +84,7 @@ public class PriorityDumpTest { "--dump-priority" }; dump(mDumper, mFd, mPw, args); - verify(mDumper).dump(same(mFd), same(mPw), same(args)); + verify(mDumper).dump(same(mFd), same(mPw), eq(EMPTY_ARGS), /* asProto= */ eq(false)); } @Test @@ -92,7 +93,7 @@ public class PriorityDumpTest { "--dump-priority", "SUPER_HIGH" }; dump(mDumper, mFd, mPw, args); - verify(mDumper).dump(same(mFd), same(mPw), same(args)); + verify(mDumper).dump(same(mFd), same(mPw), eq(EMPTY_ARGS), /* asProto= */ eq(false)); } @Test @@ -101,7 +102,9 @@ public class PriorityDumpTest { "--dump-priority", "SUPER_HIGH", "--high", "--five" }; dump(mDumper, mFd, mPw, args); - verify(mDumper).dump(same(mFd), same(mPw), same(args)); + verify(mDumper).dump(same(mFd), same(mPw), eq(new String[] { + "--high", "--five" + }), /* asProto= */ eq(false)); } @Test @@ -117,13 +120,13 @@ public class PriorityDumpTest { assertSame(mFd, fakeDumper.criticalFd); assertSame(mPw, fakeDumper.criticalPw); - assertSame(args, fakeDumper.criticalArgs); + assertArrayEquals(args, fakeDumper.criticalArgs); assertSame(mFd, fakeDumper.highFd); assertSame(mPw, fakeDumper.highPw); - assertSame(args, fakeDumper.highArgs); + assertArrayEquals(args, fakeDumper.highArgs); assertSame(mFd, fakeDumper.normalFd); assertSame(mPw, fakeDumper.normalPw); - assertSame(args, fakeDumper.normalArgs); + assertArrayEquals(args, fakeDumper.normalArgs); } @Test @@ -131,7 +134,8 @@ public class PriorityDumpTest { dump(mDumper, mFd, mPw, new String[] { "--dump-priority", "CRITICAL" }); - verify(mDumper).dumpCritical(same(mFd), same(mPw), eq(EMPTY_ARGS)); + verify(mDumper).dumpCritical(same(mFd), same(mPw), eq(EMPTY_ARGS), + /* asProto= */ eq(false)); } @Test @@ -141,7 +145,27 @@ public class PriorityDumpTest { }); verify(mDumper).dumpCritical(same(mFd), same(mPw), eq(new String[] { "--high", "--five" - })); + }), /* asProto= */ eq(false)); + } + + @Test + public void testCriticalExtraArgsInMiddle() { + dump(mDumper, mFd, mPw, new String[] { + "--high", "--dump-priority", "CRITICAL", "--five" + }); + verify(mDumper).dumpCritical(same(mFd), same(mPw), eq(new String[] { + "--high", "--five" + }), /* asProto= */ eq(false)); + } + + @Test + public void testCriticalExtraArgsAtEnd() { + dump(mDumper, mFd, mPw, new String[] { + "--high", "--five", "--dump-priority", "CRITICAL" + }); + verify(mDumper).dumpCritical(same(mFd), same(mPw), eq(new String[] { + "--high", "--five" + }), /* asProto= */ eq(false)); } @Test @@ -149,7 +173,7 @@ public class PriorityDumpTest { dump(mDumper, mFd, mPw, new String[] { "--dump-priority", "HIGH" }); - verify(mDumper).dumpHigh(same(mFd), same(mPw), eq(EMPTY_ARGS)); + verify(mDumper).dumpHigh(same(mFd), same(mPw), eq(EMPTY_ARGS), /* asProto= */ eq(false)); } @Test @@ -159,7 +183,7 @@ public class PriorityDumpTest { }); verify(mDumper).dumpHigh(same(mFd), same(mPw), eq(new String[] { "--high", "--five" - })); + }), /* asProto= */ eq(false)); } @Test @@ -167,17 +191,58 @@ public class PriorityDumpTest { dump(mDumper, mFd, mPw, new String[] { "--dump-priority", "NORMAL" }); - verify(mDumper).dumpNormal(same(mFd), same(mPw), eq(EMPTY_ARGS)); + verify(mDumper).dumpNormal(same(mFd), same(mPw), eq(EMPTY_ARGS), /* asProto= */ eq(false)); } @Test public void testNormalExtraArgs() { - dump(mDumper, mFd, mPw, new String[] { + dump(mDumper, mFd, mPw, new String[]{ "--dump-priority", "NORMAL", "--high", "--five" }); - verify(mDumper).dumpNormal(same(mFd), same(mPw), eq(new String[] { + verify(mDumper).dumpNormal(same(mFd), same(mPw), eq(new String[]{ "--high", "--five" - })); + }), /* asProto= */ eq(false)); + } + + @Test + public void testProtoArgs() { + dump(mDumper, mFd, mPw, new String[]{"--proto"}); + verify(mDumper).dump(same(mFd), same(mPw), eq(EMPTY_ARGS), /* asProto= */ eq(true)); + } + + @Test + public void testProtoArgsWithPriorityArgs() { + dump(mDumper, mFd, mPw, new String[]{"--proto", "--dump-priority", "NORMAL", "--five"}); + verify(mDumper).dumpNormal(same(mFd), same(mPw), + eq(new String[]{"--five"}), /* asProto= */ eq(true)); + } + + @Test + public void testProtoArgsWithPriorityArgsReverseOrder() { + dump(mDumper, mFd, mPw, new String[]{"--dump-priority", "NORMAL", "--proto", "--five"}); + verify(mDumper).dumpNormal(same(mFd), same(mPw), + eq(new String[]{"--five"}), /* asProto= */ eq(true)); + } + + @Test + public void testProtoArgsInMiddle() { + dump(mDumper, mFd, mPw, new String[]{"--unknown", "--proto", "--five"}); + verify(mDumper).dump(same(mFd), same(mPw), + eq(new String[]{"--unknown", "--five"}), /* asProto= */ eq(true)); + } + + @Test + public void testProtoArgsAtEnd() { + dump(mDumper, mFd, mPw, new String[]{"args", "-left", "--behind", "--proto"}); + verify(mDumper).dump(same(mFd), same(mPw), + eq(new String[]{"args", "-left", "--behind"}), /* asProto= */ eq(true)); + } + + @Test + public void testProtoArgsWithInvalidPriorityType() { + dump(mDumper, mFd, mPw, new String[]{"--dump-priority", "HIGH?", "--proto"}); + verify(mDumper).dump(same(mFd), same(mPw), + eq(EMPTY_ARGS), /* asProto= */ eq(true)); } private final class FakeDumper implements PriorityDumper { @@ -187,21 +252,22 @@ public class PriorityDumpTest { PrintWriter criticalPw, highPw, normalPw; @Override - public void dumpCritical(FileDescriptor fd, PrintWriter pw, String[] args) { + public void dumpCritical(FileDescriptor fd, PrintWriter pw, String[] args, + boolean asProto) { criticalFd = fd; criticalPw = pw; criticalArgs = args; } @Override - public void dumpHigh(FileDescriptor fd, PrintWriter pw, String[] args) { + public void dumpHigh(FileDescriptor fd, PrintWriter pw, String[] args, boolean asProto) { highFd = fd; highPw = pw; highArgs = args; } @Override - public void dumpNormal(FileDescriptor fd, PrintWriter pw, String[] args) { + public void dumpNormal(FileDescriptor fd, PrintWriter pw, String[] args, boolean asProto) { normalFd = fd; normalPw = pw; normalArgs = args; diff --git a/tools/aapt2/compile/InlineXmlFormatParser.cpp b/tools/aapt2/compile/InlineXmlFormatParser.cpp index a17926067a0b..99b4c31884bb 100644 --- a/tools/aapt2/compile/InlineXmlFormatParser.cpp +++ b/tools/aapt2/compile/InlineXmlFormatParser.cpp @@ -118,10 +118,11 @@ bool InlineXmlFormatParser::Consume(IAaptContext* context, xml::XmlResource* doc size_t name_suffix_counter = 0; for (const InlineDeclaration& decl : visitor.GetInlineDeclarations()) { - auto new_doc = util::make_unique<xml::XmlResource>(); - new_doc->file.config = doc->file.config; - new_doc->file.source = doc->file.source.WithLine(decl.el->line_number); - new_doc->file.name = doc->file.name; + // Create a new XmlResource with the same ResourceFile as the base XmlResource. + auto new_doc = util::make_unique<xml::XmlResource>(doc->file); + + // Attach the line number. + new_doc->file.source.line = decl.el->line_number; // Modify the new entry name. We need to suffix the entry with a number to // avoid local collisions, then mangle it with the empty package, such that it won't show up diff --git a/tools/aapt2/compile/InlineXmlFormatParser_test.cpp b/tools/aapt2/compile/InlineXmlFormatParser_test.cpp index de7739ada407..d6d734d395b5 100644 --- a/tools/aapt2/compile/InlineXmlFormatParser_test.cpp +++ b/tools/aapt2/compile/InlineXmlFormatParser_test.cpp @@ -54,6 +54,7 @@ TEST(InlineXmlFormatParserTest, ExtractOneXmlResource) { </View1>)"); doc->file.name = test::ParseNameOrDie("layout/main"); + doc->file.type = ResourceFile::Type::kProtoXml; InlineXmlFormatParser parser; ASSERT_TRUE(parser.Consume(context.get(), doc.get())); @@ -81,6 +82,9 @@ TEST(InlineXmlFormatParserTest, ExtractOneXmlResource) { // Make sure the generated reference is correct. EXPECT_THAT(extracted_doc->file.name, Eq(name_ref)); + // Make sure the ResourceFile::Type is the same. + EXPECT_THAT(extracted_doc->file.type, Eq(ResourceFile::Type::kProtoXml)); + // Verify the structure of the extracted XML. el = extracted_doc->root.get(); ASSERT_THAT(el, NotNull()); |