Ensure munmap matches mmap
am: aa394dd42c
Change-Id: I80dbf9a859693cbd90aa472b04ae58d4d081d735
diff --git a/Android.mk b/Android.mk
index 18d9c69..99e0c46 100644
--- a/Android.mk
+++ b/Android.mk
@@ -90,6 +90,7 @@
core/java/android/app/IWallpaperManager.aidl \
core/java/android/app/IWallpaperManagerCallback.aidl \
core/java/android/app/admin/IDevicePolicyManager.aidl \
+ core/java/android/app/trust/IStrongAuthTracker.aidl \
core/java/android/app/trust/ITrustManager.aidl \
core/java/android/app/trust/ITrustListener.aidl \
core/java/android/app/backup/IBackupManager.aidl \
@@ -159,6 +160,7 @@
core/java/android/hardware/fingerprint/IFingerprintDaemon.aidl \
core/java/android/hardware/fingerprint/IFingerprintDaemonCallback.aidl \
core/java/android/hardware/fingerprint/IFingerprintService.aidl \
+ core/java/android/hardware/fingerprint/IFingerprintServiceLockoutResetCallback.aidl \
core/java/android/hardware/fingerprint/IFingerprintServiceReceiver.aidl \
core/java/android/hardware/hdmi/IHdmiControlCallback.aidl \
core/java/android/hardware/hdmi/IHdmiControlService.aidl \
@@ -171,7 +173,9 @@
core/java/android/hardware/hdmi/IHdmiVendorCommandListener.aidl \
core/java/android/hardware/input/IInputManager.aidl \
core/java/android/hardware/input/IInputDevicesChangedListener.aidl \
+ core/java/android/hardware/input/ITabletModeChangedListener.aidl \
core/java/android/hardware/location/IActivityRecognitionHardware.aidl \
+ core/java/android/hardware/location/IActivityRecognitionHardwareClient.aidl \
core/java/android/hardware/location/IActivityRecognitionHardwareSink.aidl \
core/java/android/hardware/location/IActivityRecognitionHardwareWatcher.aidl \
core/java/android/hardware/location/IFusedLocationHardware.aidl \
@@ -344,6 +348,7 @@
media/java/android/media/IRingtonePlayer.aidl \
media/java/android/media/IVolumeController.aidl \
media/java/android/media/audiopolicy/IAudioPolicyCallback.aidl \
+ media/java/android/media/midi/IBluetoothMidiService.aidl \
media/java/android/media/midi/IMidiDeviceListener.aidl \
media/java/android/media/midi/IMidiDeviceOpenCallback.aidl \
media/java/android/media/midi/IMidiDeviceServer.aidl \
diff --git a/cmds/bootanimation/BootAnimation.cpp b/cmds/bootanimation/BootAnimation.cpp
index fba462b..8f361ce 100644
--- a/cmds/bootanimation/BootAnimation.cpp
+++ b/cmds/bootanimation/BootAnimation.cpp
@@ -556,15 +556,10 @@
mZip->endIteration(cookie);
- // clear screen
glShadeModel(GL_FLAT);
glDisable(GL_DITHER);
glDisable(GL_SCISSOR_TEST);
glDisable(GL_BLEND);
- glClearColor(0,0,0,1);
- glClear(GL_COLOR_BUFFER_BIT);
-
- eglSwapBuffers(mDisplay, mSurface);
glBindTexture(GL_TEXTURE_2D, 0);
glEnable(GL_TEXTURE_2D);
diff --git a/cmds/svc/src/com/android/commands/svc/NfcCommand.java b/cmds/svc/src/com/android/commands/svc/NfcCommand.java
new file mode 100644
index 0000000..e0f09ee
--- /dev/null
+++ b/cmds/svc/src/com/android/commands/svc/NfcCommand.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.commands.svc;
+
+import android.content.Context;
+import android.content.pm.IPackageManager;
+import android.content.pm.PackageManager;
+import android.nfc.INfcAdapter;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+
+public class NfcCommand extends Svc.Command {
+
+ public NfcCommand() {
+ super("nfc");
+ }
+
+ @Override
+ public String shortHelp() {
+ return "Control NFC functions";
+ }
+
+ @Override
+ public String longHelp() {
+ return shortHelp() + "\n"
+ + "\n"
+ + "usage: svc nfc [enable|disable]\n"
+ + " Turn NFC on or off.\n\n";
+ }
+
+ @Override
+ public void run(String[] args) {
+ boolean validCommand = false;
+ if (args.length >= 2) {
+ boolean flag = false;
+ if ("enable".equals(args[1])) {
+ flag = true;
+ validCommand = true;
+ } else if ("disable".equals(args[1])) {
+ flag = false;
+ validCommand = true;
+ }
+ if (validCommand) {
+ IPackageManager pm = IPackageManager.Stub.asInterface(
+ ServiceManager.getService("package"));
+ try {
+ if (pm.hasSystemFeature(PackageManager.FEATURE_NFC)) {
+ INfcAdapter nfc = INfcAdapter.Stub
+ .asInterface(ServiceManager.getService(Context.NFC_SERVICE));
+ try {
+ if (flag) {
+ nfc.enable();
+ } else
+ nfc.disable(true);
+ } catch (RemoteException e) {
+ System.err.println("NFC operation failed: " + e);
+ }
+ } else {
+ System.err.println("NFC feature not supported.");
+ }
+ } catch (RemoteException e) {
+ System.err.println("RemoteException while calling PackageManager, is the "
+ + "system running?");
+ }
+ return;
+ }
+ }
+ System.err.println(longHelp());
+ }
+
+}
diff --git a/cmds/svc/src/com/android/commands/svc/Svc.java b/cmds/svc/src/com/android/commands/svc/Svc.java
index 0fbba11..2cccd1a 100644
--- a/cmds/svc/src/com/android/commands/svc/Svc.java
+++ b/cmds/svc/src/com/android/commands/svc/Svc.java
@@ -95,6 +95,7 @@
new PowerCommand(),
new DataCommand(),
new WifiCommand(),
- new UsbCommand()
+ new UsbCommand(),
+ new NfcCommand(),
};
}
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index 2cb3f39..ecd0050 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -689,6 +689,8 @@
private static final String SAVED_DIALOGS_TAG = "android:savedDialogs";
private static final String SAVED_DIALOG_KEY_PREFIX = "android:dialog_";
private static final String SAVED_DIALOG_ARGS_KEY_PREFIX = "android:dialog_args_";
+ private static final String HAS_CURENT_PERMISSIONS_REQUEST_KEY =
+ "android:hasCurrentPermissionsRequest";
private static final String REQUEST_PERMISSIONS_WHO_PREFIX = "@android:requestPermissions:";
@@ -797,6 +799,8 @@
SharedElementCallback mEnterTransitionListener = SharedElementCallback.NULL_CALLBACK;
SharedElementCallback mExitTransitionListener = SharedElementCallback.NULL_CALLBACK;
+ private boolean mHasCurrentPermissionsRequest;
+
/** Return the intent that started this activity. */
public Intent getIntent() {
return mIntent;
@@ -1298,6 +1302,7 @@
onSaveInstanceState(outState);
saveManagedDialogs(outState);
mActivityTransitionState.saveState(outState);
+ storeHasCurrentPermissionRequest(outState);
if (DEBUG_LIFECYCLE) Slog.v(TAG, "onSaveInstanceState " + this + ": " + outState);
}
@@ -1313,6 +1318,7 @@
final void performSaveInstanceState(Bundle outState, PersistableBundle outPersistentState) {
onSaveInstanceState(outState, outPersistentState);
saveManagedDialogs(outState);
+ storeHasCurrentPermissionRequest(outState);
if (DEBUG_LIFECYCLE) Slog.v(TAG, "onSaveInstanceState " + this + ": " + outState +
", " + outPersistentState);
}
@@ -3811,8 +3817,15 @@
* @see #shouldShowRequestPermissionRationale(String)
*/
public final void requestPermissions(@NonNull String[] permissions, int requestCode) {
+ if (mHasCurrentPermissionsRequest) {
+ Log.w(TAG, "Can reqeust only one set of permissions at a time");
+ // Dispatch the callback with empty arrays which means a cancellation.
+ onRequestPermissionsResult(requestCode, new String[0], new int[0]);
+ return;
+ }
Intent intent = getPackageManager().buildRequestPermissionsIntent(permissions);
startActivityForResult(REQUEST_PERMISSIONS_WHO_PREFIX, intent, requestCode, null);
+ mHasCurrentPermissionsRequest = true;
}
/**
@@ -6234,12 +6247,14 @@
}
final void performCreate(Bundle icicle) {
+ restoreHasCurrentPermissionRequest(icicle);
onCreate(icicle);
mActivityTransitionState.readState(icicle);
performCreateCommon();
}
final void performCreate(Bundle icicle, PersistableBundle persistentState) {
+ restoreHasCurrentPermissionRequest(icicle);
onCreate(icicle, persistentState);
mActivityTransitionState.readState(icicle);
performCreateCommon();
@@ -6418,6 +6433,19 @@
return mResumed;
}
+ private void storeHasCurrentPermissionRequest(Bundle bundle) {
+ if (bundle != null && mHasCurrentPermissionsRequest) {
+ bundle.putBoolean(HAS_CURENT_PERMISSIONS_REQUEST_KEY, true);
+ }
+ }
+
+ private void restoreHasCurrentPermissionRequest(Bundle bundle) {
+ if (bundle != null) {
+ mHasCurrentPermissionsRequest = bundle.getBoolean(
+ HAS_CURENT_PERMISSIONS_REQUEST_KEY, false);
+ }
+ }
+
void dispatchActivityResult(String who, int requestCode,
int resultCode, Intent data) {
if (false) Log.v(
@@ -6545,6 +6573,7 @@
}
private void dispatchRequestPermissionsResult(int requestCode, Intent data) {
+ mHasCurrentPermissionsRequest = false;
// If the package installer crashed we may have not data - best effort.
String[] permissions = (data != null) ? data.getStringArrayExtra(
PackageManager.EXTRA_REQUEST_PERMISSIONS_NAMES) : new String[0];
diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java
index 0adce5d..7cae745 100644
--- a/core/java/android/app/ApplicationPackageManager.java
+++ b/core/java/android/app/ApplicationPackageManager.java
@@ -1619,7 +1619,8 @@
// System apps and apps demanding internal storage can't be moved
// anywhere else
if (app.isSystemApp()
- || app.installLocation == PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY) {
+ || app.installLocation == PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY
+ || app.installLocation == PackageInfo.INSTALL_LOCATION_UNSPECIFIED) {
return false;
}
diff --git a/core/java/android/app/Fragment.java b/core/java/android/app/Fragment.java
index 82206ea..29e8dd4 100644
--- a/core/java/android/app/Fragment.java
+++ b/core/java/android/app/Fragment.java
@@ -2401,7 +2401,7 @@
mLoaderManager = mHost.getLoaderManager(mWho, mLoadersStarted, false);
}
if (mLoaderManager != null) {
- if (mRetaining) {
+ if (mHost.getRetainLoaders()) {
mLoaderManager.doRetain();
} else {
mLoaderManager.doStop();
diff --git a/core/java/android/app/FragmentHostCallback.java b/core/java/android/app/FragmentHostCallback.java
index 7b01307..13517e6 100644
--- a/core/java/android/app/FragmentHostCallback.java
+++ b/core/java/android/app/FragmentHostCallback.java
@@ -42,9 +42,14 @@
private final Handler mHandler;
final int mWindowAnimations;
final FragmentManagerImpl mFragmentManager = new FragmentManagerImpl();
+ /** The loader managers for individual fragments [i.e. Fragment#getLoaderManager()] */
private ArrayMap<String, LoaderManager> mAllLoaderManagers;
+ /** Whether or not fragment loaders should retain their state */
+ private boolean mRetainLoaders;
+ /** The loader manger for the fragment host [i.e. Activity#getLoaderManager()] */
private LoaderManagerImpl mLoaderManager;
private boolean mCheckedForLoaderManager;
+ /** Whether or not the fragment host loader manager was started */
private boolean mLoadersStarted;
public FragmentHostCallback(Context context, Handler handler, int windowAnimations) {
@@ -166,6 +171,10 @@
return true;
}
+ boolean getRetainLoaders() {
+ return mRetainLoaders;
+ }
+
Activity getActivity() {
return mActivity;
}
@@ -217,6 +226,8 @@
}
void doLoaderStop(boolean retain) {
+ mRetainLoaders = retain;
+
if (mLoaderManager == null) {
return;
}
diff --git a/core/java/android/app/FragmentManager.java b/core/java/android/app/FragmentManager.java
index 132ffef..696ccdb 100644
--- a/core/java/android/app/FragmentManager.java
+++ b/core/java/android/app/FragmentManager.java
@@ -2210,6 +2210,7 @@
// This fragment was retained from a previous instance; get it
// going now.
fragment.mInLayout = true;
+ fragment.mHost = mHost;
// If this fragment is newly instantiated (either right now, or
// from last saved state), then give it the attributes to
// initialize itself.
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index f3f2428..6a4f6a1 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -3963,13 +3963,18 @@
return this;
}
+ /** @hide */
+ public static final int MIN_ASHMEM_BITMAP_SIZE = 128 * (1 << 10);
+
/**
* @hide
*/
@Override
public void purgeResources() {
super.purgeResources();
- if (mPicture != null && mPicture.isMutable()) {
+ if (mPicture != null &&
+ mPicture.isMutable() &&
+ mPicture.getAllocationByteCount() >= MIN_ASHMEM_BITMAP_SIZE) {
mPicture = mPicture.createAshmemBitmap();
}
if (mBigLargeIcon != null) {
diff --git a/core/java/android/app/StatusBarManager.java b/core/java/android/app/StatusBarManager.java
index 31d1ab7..5e8ad68 100644
--- a/core/java/android/app/StatusBarManager.java
+++ b/core/java/android/app/StatusBarManager.java
@@ -90,6 +90,9 @@
public static final int WINDOW_STATE_HIDING = 1;
public static final int WINDOW_STATE_HIDDEN = 2;
+ public static final int CAMERA_LAUNCH_SOURCE_WIGGLE = 0;
+ public static final int CAMERA_LAUNCH_SOURCE_POWER_DOUBLE_TAP = 1;
+
private Context mContext;
private IStatusBarService mService;
private IBinder mToken = new Binder();
diff --git a/core/java/android/app/backup/BackupManager.java b/core/java/android/app/backup/BackupManager.java
index 8b79305..ca7ba85 100644
--- a/core/java/android/app/backup/BackupManager.java
+++ b/core/java/android/app/backup/BackupManager.java
@@ -59,6 +59,68 @@
public class BackupManager {
private static final String TAG = "BackupManager";
+ // BackupObserver status codes
+ /**
+ * Indicates that backup succeeded.
+ *
+ * @hide
+ */
+ public static final int SUCCESS = 0;
+
+ /**
+ * Indicates that backup is either not enabled at all or
+ * backup for the package was rejected by backup service
+ * or backup transport,
+ *
+ * @hide
+ */
+ public static final int ERROR_BACKUP_NOT_ALLOWED = -2001;
+
+ /**
+ * The requested app is not installed on the device.
+ *
+ * @hide
+ */
+ public static final int ERROR_PACKAGE_NOT_FOUND = -2002;
+
+ /**
+ * The transport for some reason was not in a good state and
+ * aborted the entire backup request. This is a transient
+ * failure and should not be retried immediately.
+ *
+ * @hide
+ */
+ public static final int ERROR_TRANSPORT_ABORTED = BackupTransport.TRANSPORT_ERROR;
+
+ /**
+ * Returned when the transport was unable to process the
+ * backup request for a given package, for example if the
+ * transport hit a transient network failure. The remaining
+ * packages provided to {@link #requestBackup(String[], BackupObserver)}
+ * will still be attempted.
+ *
+ * @hide
+ */
+ public static final int ERROR_TRANSPORT_PACKAGE_REJECTED =
+ BackupTransport.TRANSPORT_PACKAGE_REJECTED;
+
+ /**
+ * Returned when the transport reject the attempt to backup because
+ * backup data size exceeded current quota limit for this package.
+ *
+ * @hide
+ */
+ public static final int ERROR_TRANSPORT_QUOTA_EXCEEDED =
+ BackupTransport.TRANSPORT_QUOTA_EXCEEDED;
+
+ /**
+ * The {@link BackupAgent} for the requested package failed for some reason
+ * and didn't provide appropriate backup data.
+ *
+ * @hide
+ */
+ public static final int ERROR_AGENT_FAILURE = BackupTransport.AGENT_ERROR;
+
private Context mContext;
private static IBackupManager sService;
diff --git a/core/java/android/app/backup/BackupTransport.java b/core/java/android/app/backup/BackupTransport.java
index 954ccef..9141b02 100644
--- a/core/java/android/app/backup/BackupTransport.java
+++ b/core/java/android/app/backup/BackupTransport.java
@@ -49,6 +49,8 @@
public static final int TRANSPORT_PACKAGE_REJECTED = -1002;
public static final int AGENT_ERROR = -1003;
public static final int AGENT_UNKNOWN = -1004;
+ /** @hide */
+ public static final int TRANSPORT_QUOTA_EXCEEDED = -1005;
IBackupTransport mBinderImpl = new TransportImpl();
diff --git a/core/java/android/app/trust/IStrongAuthTracker.aidl b/core/java/android/app/trust/IStrongAuthTracker.aidl
new file mode 100644
index 0000000..36c71bf
--- /dev/null
+++ b/core/java/android/app/trust/IStrongAuthTracker.aidl
@@ -0,0 +1,26 @@
+/*
+**
+** Copyright 2015, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+package android.app.trust;
+
+/**
+ * Private API to be notified about strong auth changes
+ *
+ * {@hide}
+ */
+oneway interface IStrongAuthTracker {
+ void onStrongAuthRequiredChanged(int strongAuthRequired, int userId);
+}
\ No newline at end of file
diff --git a/core/java/android/app/trust/ITrustManager.aidl b/core/java/android/app/trust/ITrustManager.aidl
index 32951d9..2dea545 100644
--- a/core/java/android/app/trust/ITrustManager.aidl
+++ b/core/java/android/app/trust/ITrustManager.aidl
@@ -26,11 +26,9 @@
interface ITrustManager {
void reportUnlockAttempt(boolean successful, int userId);
void reportEnabledTrustAgentsChanged(int userId);
- void reportRequireCredentialEntry(int userId);
void registerTrustListener(in ITrustListener trustListener);
void unregisterTrustListener(in ITrustListener trustListener);
void reportKeyguardShowingChanged();
boolean isDeviceLocked(int userId);
boolean isDeviceSecure(int userId);
- boolean hasUserAuthenticatedSinceBoot(int userId);
}
diff --git a/core/java/android/app/trust/TrustManager.java b/core/java/android/app/trust/TrustManager.java
index 8cab565..aff69f0 100644
--- a/core/java/android/app/trust/TrustManager.java
+++ b/core/java/android/app/trust/TrustManager.java
@@ -16,13 +16,19 @@
package android.app.trust;
+import android.annotation.IntDef;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import android.os.Message;
import android.os.RemoteException;
+import android.os.UserHandle;
import android.util.ArrayMap;
import android.util.Log;
+import android.util.SparseIntArray;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
/**
* See {@link com.android.server.trust.TrustManagerService}
@@ -73,21 +79,6 @@
}
/**
- * Reports that trust is disabled until credentials have been entered for user {@param userId}.
- *
- * Requires the {@link android.Manifest.permission#ACCESS_KEYGUARD_SECURE_STORAGE} permission.
- *
- * @param userId either an explicit user id or {@link android.os.UserHandle#USER_ALL}
- */
- public void reportRequireCredentialEntry(int userId) {
- try {
- mService.reportRequireCredentialEntry(userId);
- } catch (RemoteException e) {
- onError(e);
- }
- }
-
- /**
* Reports that the visibility of the keyguard has changed.
*
* Requires the {@link android.Manifest.permission#ACCESS_KEYGUARD_SECURE_STORAGE} permission.
@@ -147,23 +138,6 @@
}
}
- /**
- * Checks whether the specified user has been authenticated since the last boot.
- *
- * @param userId the user id of the user to check for
- * @return true if the user has authenticated since boot, false otherwise
- *
- * Requires the {@link android.Manifest.permission#ACCESS_KEYGUARD_SECURE_STORAGE} permission.
- */
- public boolean hasUserAuthenticatedSinceBoot(int userId) {
- try {
- return mService.hasUserAuthenticatedSinceBoot(userId);
- } catch (RemoteException e) {
- onError(e);
- return false;
- }
- }
-
private void onError(Exception e) {
Log.e(TAG, "Error while calling TrustManagerService", e);
}
diff --git a/core/java/android/app/usage/UsageStats.java b/core/java/android/app/usage/UsageStats.java
index 0fce4e2..a88aa3125 100644
--- a/core/java/android/app/usage/UsageStats.java
+++ b/core/java/android/app/usage/UsageStats.java
@@ -165,14 +165,18 @@
mPackageName + "' with UsageStats for package '" + right.mPackageName + "'.");
}
- if (right.mEndTimeStamp > mEndTimeStamp) {
+ if (right.mBeginTimeStamp > mBeginTimeStamp) {
+ // The incoming UsageStat begins after this one, so use its last time used fields
+ // as the source of truth.
+ // We use the mBeginTimeStamp due to a bug where UsageStats files can overlap with
+ // regards to their mEndTimeStamp.
mLastEvent = right.mLastEvent;
- mEndTimeStamp = right.mEndTimeStamp;
mLastTimeUsed = right.mLastTimeUsed;
mBeginIdleTime = right.mBeginIdleTime;
mLastTimeSystemUsed = right.mLastTimeSystemUsed;
}
mBeginTimeStamp = Math.min(mBeginTimeStamp, right.mBeginTimeStamp);
+ mEndTimeStamp = Math.max(mEndTimeStamp, right.mEndTimeStamp);
mTotalTimeInForeground += right.mTotalTimeInForeground;
mLaunchCount += right.mLaunchCount;
}
diff --git a/core/java/android/app/usage/UsageStatsManagerInternal.java b/core/java/android/app/usage/UsageStatsManagerInternal.java
index 948ea1e..498ff81 100644
--- a/core/java/android/app/usage/UsageStatsManagerInternal.java
+++ b/core/java/android/app/usage/UsageStatsManagerInternal.java
@@ -71,10 +71,11 @@
* Could be hours, could be days, who knows?
*
* @param packageName
+ * @param uidForAppId The uid of the app, which will be used for its app id
* @param userId
* @return
*/
- public abstract boolean isAppIdle(String packageName, int userId);
+ public abstract boolean isAppIdle(String packageName, int uidForAppId, int userId);
/**
* Returns all of the uids for a given user where all packages associating with that uid
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index 4c7dd10..758b6ff 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -643,20 +643,18 @@
/**
* Open a private file associated with this Context's application package
- * for writing. Creates the file if it doesn't already exist.
- *
- * <p>No permissions are required to invoke this method, since it uses internal
- * storage.
+ * for writing. Creates the file if it doesn't already exist.
+ * <p>
+ * No additional permissions are required for the calling app to read or
+ * write the returned file.
*
* @param name The name of the file to open; can not contain path
- * separators.
- * @param mode Operating mode. Use 0 or {@link #MODE_PRIVATE} for the
- * default operation, {@link #MODE_APPEND} to append to an existing file,
- * {@link #MODE_WORLD_READABLE} and {@link #MODE_WORLD_WRITEABLE} to control
- * permissions.
- *
+ * separators.
+ * @param mode Operating mode. Use 0 or {@link #MODE_PRIVATE} for the
+ * default operation, {@link #MODE_APPEND} to append to an
+ * existing file, {@link #MODE_WORLD_READABLE} and
+ * {@link #MODE_WORLD_WRITEABLE} to control permissions.
* @return The resulting {@link FileOutputStream}.
- *
* @see #MODE_APPEND
* @see #MODE_PRIVATE
* @see #MODE_WORLD_READABLE
@@ -689,6 +687,9 @@
/**
* Returns the absolute path on the filesystem where a file created with
* {@link #openFileOutput} is stored.
+ * <p>
+ * The returned path may change over time if the calling app is moved to an
+ * adopted storage device, so only relative paths should be persisted.
*
* @param name The name of the file for which you would like to get
* its path.
@@ -702,14 +703,16 @@
public abstract File getFileStreamPath(String name);
/**
- * Returns the absolute path to the directory on the filesystem where
- * files created with {@link #openFileOutput} are stored.
- *
- * <p>No permissions are required to read or write to the returned path, since this
- * path is internal storage.
+ * Returns the absolute path to the directory on the filesystem where files
+ * created with {@link #openFileOutput} are stored.
+ * <p>
+ * The returned path may change over time if the calling app is moved to an
+ * adopted storage device, so only relative paths should be persisted.
+ * <p>
+ * No additional permissions are required for the calling app to read or
+ * write files under the returned path.
*
* @return The path of the directory holding application files.
- *
* @see #openFileOutput
* @see #getFileStreamPath
* @see #getDir
@@ -718,17 +721,19 @@
/**
* Returns the absolute path to the directory on the filesystem similar to
- * {@link #getFilesDir()}. The difference is that files placed under this
- * directory will be excluded from automatic backup to remote storage. See
+ * {@link #getFilesDir()}. The difference is that files placed under this
+ * directory will be excluded from automatic backup to remote storage. See
* {@link android.app.backup.BackupAgent BackupAgent} for a full discussion
* of the automatic backup mechanism in Android.
+ * <p>
+ * The returned path may change over time if the calling app is moved to an
+ * adopted storage device, so only relative paths should be persisted.
+ * <p>
+ * No additional permissions are required for the calling app to read or
+ * write files under the returned path.
*
- * <p>No permissions are required to read or write to the returned path, since this
- * path is internal storage.
- *
- * @return The path of the directory holding application files that will not be
- * automatically backed up to remote storage.
- *
+ * @return The path of the directory holding application files that will not
+ * be automatically backed up to remote storage.
* @see #openFileOutput
* @see #getFileStreamPath
* @see #getDir
@@ -737,200 +742,256 @@
public abstract File getNoBackupFilesDir();
/**
- * Returns the absolute path to the directory on the primary external filesystem
- * (that is somewhere on {@link android.os.Environment#getExternalStorageDirectory()
- * Environment.getExternalStorageDirectory()}) where the application can
- * place persistent files it owns. These files are internal to the
- * applications, and not typically visible to the user as media.
- *
- * <p>This is like {@link #getFilesDir()} in that these
- * files will be deleted when the application is uninstalled, however there
- * are some important differences:
- *
+ * Returns the absolute path to the directory on the primary shared/external
+ * storage device where the application can place persistent files it owns.
+ * These files are internal to the applications, and not typically visible
+ * to the user as media.
+ * <p>
+ * This is like {@link #getFilesDir()} in that these files will be deleted
+ * when the application is uninstalled, however there are some important
+ * differences:
* <ul>
- * <li>External files are not always available: they will disappear if the
- * user mounts the external storage on a computer or removes it. See the
- * APIs on {@link android.os.Environment} for information in the storage state.
- * <li>There is no security enforced with these files. For example, any application
- * holding {@link android.Manifest.permission#WRITE_EXTERNAL_STORAGE} can write to
+ * <li>Shared storage may not always be available, since removable media can
+ * be ejected by the user. Media state can be checked using
+ * {@link Environment#getExternalStorageState(File)}.
+ * <li>There is no security enforced with these files. For example, any
+ * application holding
+ * {@link android.Manifest.permission#WRITE_EXTERNAL_STORAGE} can write to
* these files.
* </ul>
- *
- * <p>Starting in {@link android.os.Build.VERSION_CODES#KITKAT}, no permissions
+ * <p>
+ * If a shared storage device is emulated (as determined by
+ * {@link Environment#isExternalStorageEmulated(File)}), it's contents are
+ * backed by a private user data partition, which means there is little
+ * benefit to storing data here instead of the private directories returned
+ * by {@link #getFilesDir()}, etc.
+ * <p>
+ * Starting in {@link android.os.Build.VERSION_CODES#KITKAT}, no permissions
* are required to read or write to the returned path; it's always
- * accessible to the calling app. This only applies to paths generated for
- * package name of the calling application. To access paths belonging
- * to other packages, {@link android.Manifest.permission#WRITE_EXTERNAL_STORAGE}
- * and/or {@link android.Manifest.permission#READ_EXTERNAL_STORAGE} are required.
- *
- * <p>On devices with multiple users (as described by {@link UserManager}),
- * each user has their own isolated external storage. Applications only
- * have access to the external storage for the user they're running as.</p>
- *
- * <p>Here is an example of typical code to manipulate a file in
- * an application's private storage:</p>
- *
+ * accessible to the calling app. This only applies to paths generated for
+ * package name of the calling application. To access paths belonging to
+ * other packages,
+ * {@link android.Manifest.permission#WRITE_EXTERNAL_STORAGE} and/or
+ * {@link android.Manifest.permission#READ_EXTERNAL_STORAGE} are required.
+ * <p>
+ * On devices with multiple users (as described by {@link UserManager}),
+ * each user has their own isolated shared storage. Applications only have
+ * access to the shared storage for the user they're running as.
+ * <p>
+ * The returned path may change over time if different shared storage media
+ * is inserted, so only relative paths should be persisted.
+ * <p>
+ * Here is an example of typical code to manipulate a file in an
+ * application's shared storage:
+ * </p>
* {@sample development/samples/ApiDemos/src/com/example/android/apis/content/ExternalStorage.java
* private_file}
- *
- * <p>If you supply a non-null <var>type</var> to this function, the returned
- * file will be a path to a sub-directory of the given type. Though these files
- * are not automatically scanned by the media scanner, you can explicitly
- * add them to the media database with
- * {@link android.media.MediaScannerConnection#scanFile(Context, String[], String[],
- * android.media.MediaScannerConnection.OnScanCompletedListener)
- * MediaScannerConnection.scanFile}.
- * Note that this is not the same as
+ * <p>
+ * If you supply a non-null <var>type</var> to this function, the returned
+ * file will be a path to a sub-directory of the given type. Though these
+ * files are not automatically scanned by the media scanner, you can
+ * explicitly add them to the media database with
+ * {@link android.media.MediaScannerConnection#scanFile(Context, String[], String[], android.media.MediaScannerConnection.OnScanCompletedListener)
+ * MediaScannerConnection.scanFile}. Note that this is not the same as
* {@link android.os.Environment#getExternalStoragePublicDirectory
* Environment.getExternalStoragePublicDirectory()}, which provides
- * directories of media shared by all applications. The
- * directories returned here are
- * owned by the application, and their contents will be removed when the
- * application is uninstalled. Unlike
+ * directories of media shared by all applications. The directories returned
+ * here are owned by the application, and their contents will be removed
+ * when the application is uninstalled. Unlike
* {@link android.os.Environment#getExternalStoragePublicDirectory
- * Environment.getExternalStoragePublicDirectory()}, the directory
- * returned here will be automatically created for you.
- *
- * <p>Here is an example of typical code to manipulate a picture in
- * an application's private storage and add it to the media database:</p>
- *
+ * Environment.getExternalStoragePublicDirectory()}, the directory returned
+ * here will be automatically created for you.
+ * <p>
+ * Here is an example of typical code to manipulate a picture in an
+ * application's shared storage and add it to the media database:
+ * </p>
* {@sample development/samples/ApiDemos/src/com/example/android/apis/content/ExternalStorage.java
* private_picture}
*
- * @param type The type of files directory to return. May be null for
- * the root of the files directory or one of
- * the following Environment constants for a subdirectory:
- * {@link android.os.Environment#DIRECTORY_MUSIC},
- * {@link android.os.Environment#DIRECTORY_PODCASTS},
- * {@link android.os.Environment#DIRECTORY_RINGTONES},
- * {@link android.os.Environment#DIRECTORY_ALARMS},
- * {@link android.os.Environment#DIRECTORY_NOTIFICATIONS},
- * {@link android.os.Environment#DIRECTORY_PICTURES}, or
- * {@link android.os.Environment#DIRECTORY_MOVIES}.
- *
- * @return The path of the directory holding application files
- * on external storage. Returns null if external storage is not currently
- * mounted so it could not ensure the path exists; you will need to call
- * this method again when it is available.
- *
+ * @param type The type of files directory to return. May be {@code null}
+ * for the root of the files directory or one of the following
+ * constants for a subdirectory:
+ * {@link android.os.Environment#DIRECTORY_MUSIC},
+ * {@link android.os.Environment#DIRECTORY_PODCASTS},
+ * {@link android.os.Environment#DIRECTORY_RINGTONES},
+ * {@link android.os.Environment#DIRECTORY_ALARMS},
+ * {@link android.os.Environment#DIRECTORY_NOTIFICATIONS},
+ * {@link android.os.Environment#DIRECTORY_PICTURES}, or
+ * {@link android.os.Environment#DIRECTORY_MOVIES}.
+ * @return the absolute path to application-specific directory. May return
+ * {@code null} if shared storage is not currently available.
* @see #getFilesDir
- * @see android.os.Environment#getExternalStoragePublicDirectory
+ * @see #getExternalFilesDirs(String)
+ * @see Environment#getExternalStorageState(File)
+ * @see Environment#isExternalStorageEmulated(File)
+ * @see Environment#isExternalStorageRemovable(File)
*/
@Nullable
public abstract File getExternalFilesDir(@Nullable String type);
/**
* Returns absolute paths to application-specific directories on all
- * external storage devices where the application can place persistent files
- * it owns. These files are internal to the application, and not typically
- * visible to the user as media.
+ * shared/external storage devices where the application can place
+ * persistent files it owns. These files are internal to the application,
+ * and not typically visible to the user as media.
* <p>
- * This is like {@link #getFilesDir()} in that these files will be deleted when
- * the application is uninstalled, however there are some important differences:
+ * This is like {@link #getFilesDir()} in that these files will be deleted
+ * when the application is uninstalled, however there are some important
+ * differences:
* <ul>
- * <li>External files are not always available: they will disappear if the
- * user mounts the external storage on a computer or removes it.
- * <li>There is no security enforced with these files.
+ * <li>Shared storage may not always be available, since removable media can
+ * be ejected by the user. Media state can be checked using
+ * {@link Environment#getExternalStorageState(File)}.
+ * <li>There is no security enforced with these files. For example, any
+ * application holding
+ * {@link android.Manifest.permission#WRITE_EXTERNAL_STORAGE} can write to
+ * these files.
* </ul>
* <p>
- * External storage devices returned here are considered a permanent part of
- * the device, including both emulated external storage and physical media
- * slots, such as SD cards in a battery compartment. The returned paths do
- * not include transient devices, such as USB flash drives.
+ * If a shared storage device is emulated (as determined by
+ * {@link Environment#isExternalStorageEmulated(File)}), it's contents are
+ * backed by a private user data partition, which means there is little
+ * benefit to storing data here instead of the private directories returned
+ * by {@link #getFilesDir()}, etc.
* <p>
- * An application may store data on any or all of the returned devices. For
+ * Shared storage devices returned here are considered a stable part of the
+ * device, including physical media slots under a protective cover. The
+ * returned paths do not include transient devices, such as USB flash drives
+ * connected to handheld devices.
+ * <p>
+ * An application may store data on any or all of the returned devices. For
* example, an app may choose to store large files on the device with the
* most available space, as measured by {@link StatFs}.
* <p>
- * No permissions are required to read or write to the returned paths; they
- * are always accessible to the calling app. Write access outside of these
- * paths on secondary external storage devices is not available.
+ * No additional permissions are required for the calling app to read or
+ * write files under the returned path. Write access outside of these paths
+ * on secondary external storage devices is not available.
* <p>
- * The first path returned is the same as {@link #getExternalFilesDir(String)}.
- * Returned paths may be {@code null} if a storage device is unavailable.
+ * The returned path may change over time if different shared storage media
+ * is inserted, so only relative paths should be persisted.
*
+ * @param type The type of files directory to return. May be {@code null}
+ * for the root of the files directory or one of the following
+ * constants for a subdirectory:
+ * {@link android.os.Environment#DIRECTORY_MUSIC},
+ * {@link android.os.Environment#DIRECTORY_PODCASTS},
+ * {@link android.os.Environment#DIRECTORY_RINGTONES},
+ * {@link android.os.Environment#DIRECTORY_ALARMS},
+ * {@link android.os.Environment#DIRECTORY_NOTIFICATIONS},
+ * {@link android.os.Environment#DIRECTORY_PICTURES}, or
+ * {@link android.os.Environment#DIRECTORY_MOVIES}.
+ * @return the absolute paths to application-specific directories. Some
+ * individual paths may be {@code null} if that shared storage is
+ * not currently available. The first path returned is the same as
+ * {@link #getExternalFilesDir(String)}.
* @see #getExternalFilesDir(String)
* @see Environment#getExternalStorageState(File)
+ * @see Environment#isExternalStorageEmulated(File)
+ * @see Environment#isExternalStorageRemovable(File)
*/
public abstract File[] getExternalFilesDirs(String type);
/**
- * Return the primary external storage directory where this application's OBB
- * files (if there are any) can be found. Note if the application does not have
- * any OBB files, this directory may not exist.
+ * Return the primary shared/external storage directory where this
+ * application's OBB files (if there are any) can be found. Note if the
+ * application does not have any OBB files, this directory may not exist.
* <p>
- * This is like {@link #getFilesDir()} in that these files will be deleted when
- * the application is uninstalled, however there are some important differences:
+ * This is like {@link #getFilesDir()} in that these files will be deleted
+ * when the application is uninstalled, however there are some important
+ * differences:
* <ul>
- * <li>External files are not always available: they will disappear if the
- * user mounts the external storage on a computer or removes it.
- * <li>There is no security enforced with these files. For example, any application
- * holding {@link android.Manifest.permission#WRITE_EXTERNAL_STORAGE} can write to
+ * <li>Shared storage may not always be available, since removable media can
+ * be ejected by the user. Media state can be checked using
+ * {@link Environment#getExternalStorageState(File)}.
+ * <li>There is no security enforced with these files. For example, any
+ * application holding
+ * {@link android.Manifest.permission#WRITE_EXTERNAL_STORAGE} can write to
* these files.
* </ul>
* <p>
* Starting in {@link android.os.Build.VERSION_CODES#KITKAT}, no permissions
* are required to read or write to the returned path; it's always
- * accessible to the calling app. This only applies to paths generated for
- * package name of the calling application. To access paths belonging
- * to other packages, {@link android.Manifest.permission#WRITE_EXTERNAL_STORAGE}
- * and/or {@link android.Manifest.permission#READ_EXTERNAL_STORAGE} are required.
+ * accessible to the calling app. This only applies to paths generated for
+ * package name of the calling application. To access paths belonging to
+ * other packages,
+ * {@link android.Manifest.permission#WRITE_EXTERNAL_STORAGE} and/or
+ * {@link android.Manifest.permission#READ_EXTERNAL_STORAGE} are required.
* <p>
* On devices with multiple users (as described by {@link UserManager}),
* multiple users may share the same OBB storage location. Applications
* should ensure that multiple instances running under different users don't
* interfere with each other.
+ *
+ * @return the absolute path to application-specific directory. May return
+ * {@code null} if shared storage is not currently available.
+ * @see #getObbDirs()
+ * @see Environment#getExternalStorageState(File)
+ * @see Environment#isExternalStorageEmulated(File)
+ * @see Environment#isExternalStorageRemovable(File)
*/
public abstract File getObbDir();
/**
* Returns absolute paths to application-specific directories on all
- * external storage devices where the application's OBB files (if there are
- * any) can be found. Note if the application does not have any OBB files,
- * these directories may not exist.
+ * shared/external storage devices where the application's OBB files (if
+ * there are any) can be found. Note if the application does not have any
+ * OBB files, these directories may not exist.
* <p>
- * This is like {@link #getFilesDir()} in that these files will be deleted when
- * the application is uninstalled, however there are some important differences:
+ * This is like {@link #getFilesDir()} in that these files will be deleted
+ * when the application is uninstalled, however there are some important
+ * differences:
* <ul>
- * <li>External files are not always available: they will disappear if the
- * user mounts the external storage on a computer or removes it.
- * <li>There is no security enforced with these files.
+ * <li>Shared storage may not always be available, since removable media can
+ * be ejected by the user. Media state can be checked using
+ * {@link Environment#getExternalStorageState(File)}.
+ * <li>There is no security enforced with these files. For example, any
+ * application holding
+ * {@link android.Manifest.permission#WRITE_EXTERNAL_STORAGE} can write to
+ * these files.
* </ul>
* <p>
- * External storage devices returned here are considered a permanent part of
- * the device, including both emulated external storage and physical media
- * slots, such as SD cards in a battery compartment. The returned paths do
- * not include transient devices, such as USB flash drives.
+ * Shared storage devices returned here are considered a stable part of the
+ * device, including physical media slots under a protective cover. The
+ * returned paths do not include transient devices, such as USB flash drives
+ * connected to handheld devices.
* <p>
- * An application may store data on any or all of the returned devices. For
+ * An application may store data on any or all of the returned devices. For
* example, an app may choose to store large files on the device with the
* most available space, as measured by {@link StatFs}.
* <p>
- * No permissions are required to read or write to the returned paths; they
- * are always accessible to the calling app. Write access outside of these
- * paths on secondary external storage devices is not available.
- * <p>
- * The first path returned is the same as {@link #getObbDir()}.
- * Returned paths may be {@code null} if a storage device is unavailable.
+ * No additional permissions are required for the calling app to read or
+ * write files under the returned path. Write access outside of these paths
+ * on secondary external storage devices is not available.
*
+ * @return the absolute paths to application-specific directories. Some
+ * individual paths may be {@code null} if that shared storage is
+ * not currently available. The first path returned is the same as
+ * {@link #getObbDir()}
* @see #getObbDir()
* @see Environment#getExternalStorageState(File)
+ * @see Environment#isExternalStorageEmulated(File)
+ * @see Environment#isExternalStorageRemovable(File)
*/
public abstract File[] getObbDirs();
/**
- * Returns the absolute path to the application specific cache directory
- * on the filesystem. These files will be ones that get deleted first when the
- * device runs low on storage.
- * There is no guarantee when these files will be deleted.
- *
+ * Returns the absolute path to the application specific cache directory on
+ * the filesystem. These files will be ones that get deleted first when the
+ * device runs low on storage. There is no guarantee when these files will
+ * be deleted.
+ * <p>
* <strong>Note: you should not <em>rely</em> on the system deleting these
* files for you; you should always have a reasonable maximum, such as 1 MB,
* for the amount of space you consume with cache files, and prune those
* files when exceeding that space.</strong>
+ * <p>
+ * The returned path may change over time if the calling app is moved to an
+ * adopted storage device, so only relative paths should be persisted.
+ * <p>
+ * Apps require no extra permissions to read or write to the returned path,
+ * since this path lives in their private storage.
*
* @return The path of the directory holding application cache files.
- *
* @see #openFileOutput
* @see #getFileStreamPath
* @see #getDir
@@ -946,6 +1007,9 @@
* This location is optimal for storing compiled or optimized code generated
* by your application at runtime.
* <p>
+ * The returned path may change over time if the calling app is moved to an
+ * adopted storage device, so only relative paths should be persisted.
+ * <p>
* Apps require no extra permissions to read or write to the returned path,
* since this path lives in their private storage.
*
@@ -954,120 +1018,161 @@
public abstract File getCodeCacheDir();
/**
- * Returns the absolute path to the directory on the primary external filesystem
- * (that is somewhere on {@link android.os.Environment#getExternalStorageDirectory()
- * Environment.getExternalStorageDirectory()} where the application can
- * place cache files it owns. These files are internal to the application, and
- * not typically visible to the user as media.
- *
- * <p>This is like {@link #getCacheDir()} in that these
- * files will be deleted when the application is uninstalled, however there
- * are some important differences:
- *
+ * Returns absolute path to application-specific directory on the primary
+ * shared/external storage device where the application can place cache
+ * files it owns. These files are internal to the application, and not
+ * typically visible to the user as media.
+ * <p>
+ * This is like {@link #getCacheDir()} in that these files will be deleted
+ * when the application is uninstalled, however there are some important
+ * differences:
* <ul>
- * <li>The platform does not always monitor the space available in external
- * storage, and thus may not automatically delete these files. Currently
- * the only time files here will be deleted by the platform is when running
- * on {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR1} or later and
- * {@link android.os.Environment#isExternalStorageEmulated()
- * Environment.isExternalStorageEmulated()} returns true. Note that you should
- * be managing the maximum space you will use for these anyway, just like
- * with {@link #getCacheDir()}.
- * <li>External files are not always available: they will disappear if the
- * user mounts the external storage on a computer or removes it. See the
- * APIs on {@link android.os.Environment} for information in the storage state.
- * <li>There is no security enforced with these files. For example, any application
- * holding {@link android.Manifest.permission#WRITE_EXTERNAL_STORAGE} can write to
+ * <li>The platform does not always monitor the space available in shared
+ * storage, and thus may not automatically delete these files. Apps should
+ * always manage the maximum space used in this location. Currently the only
+ * time files here will be deleted by the platform is when running on
+ * {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR1} or later and
+ * {@link Environment#isExternalStorageEmulated(File)} returns true.
+ * <li>Shared storage may not always be available, since removable media can
+ * be ejected by the user. Media state can be checked using
+ * {@link Environment#getExternalStorageState(File)}.
+ * <li>There is no security enforced with these files. For example, any
+ * application holding
+ * {@link android.Manifest.permission#WRITE_EXTERNAL_STORAGE} can write to
* these files.
* </ul>
- *
- * <p>Starting in {@link android.os.Build.VERSION_CODES#KITKAT}, no permissions
+ * <p>
+ * If a shared storage device is emulated (as determined by
+ * {@link Environment#isExternalStorageEmulated(File)}), it's contents are
+ * backed by a private user data partition, which means there is little
+ * benefit to storing data here instead of the private directory returned by
+ * {@link #getCacheDir()}.
+ * <p>
+ * Starting in {@link android.os.Build.VERSION_CODES#KITKAT}, no permissions
* are required to read or write to the returned path; it's always
- * accessible to the calling app. This only applies to paths generated for
- * package name of the calling application. To access paths belonging
- * to other packages, {@link android.Manifest.permission#WRITE_EXTERNAL_STORAGE}
- * and/or {@link android.Manifest.permission#READ_EXTERNAL_STORAGE} are required.
+ * accessible to the calling app. This only applies to paths generated for
+ * package name of the calling application. To access paths belonging to
+ * other packages,
+ * {@link android.Manifest.permission#WRITE_EXTERNAL_STORAGE} and/or
+ * {@link android.Manifest.permission#READ_EXTERNAL_STORAGE} are required.
+ * <p>
+ * On devices with multiple users (as described by {@link UserManager}),
+ * each user has their own isolated shared storage. Applications only have
+ * access to the shared storage for the user they're running as.
+ * <p>
+ * The returned path may change over time if different shared storage media
+ * is inserted, so only relative paths should be persisted.
*
- * <p>On devices with multiple users (as described by {@link UserManager}),
- * each user has their own isolated external storage. Applications only
- * have access to the external storage for the user they're running as.</p>
- *
- * @return The path of the directory holding application cache files
- * on external storage. Returns null if external storage is not currently
- * mounted so it could not ensure the path exists; you will need to call
- * this method again when it is available.
- *
+ * @return the absolute path to application-specific directory. May return
+ * {@code null} if shared storage is not currently available.
* @see #getCacheDir
+ * @see #getExternalCacheDirs()
+ * @see Environment#getExternalStorageState(File)
+ * @see Environment#isExternalStorageEmulated(File)
+ * @see Environment#isExternalStorageRemovable(File)
*/
@Nullable
public abstract File getExternalCacheDir();
/**
* Returns absolute paths to application-specific directories on all
- * external storage devices where the application can place cache files it
- * owns. These files are internal to the application, and not typically
- * visible to the user as media.
+ * shared/external storage devices where the application can place cache
+ * files it owns. These files are internal to the application, and not
+ * typically visible to the user as media.
* <p>
- * This is like {@link #getCacheDir()} in that these files will be deleted when
- * the application is uninstalled, however there are some important differences:
+ * This is like {@link #getCacheDir()} in that these files will be deleted
+ * when the application is uninstalled, however there are some important
+ * differences:
* <ul>
- * <li>External files are not always available: they will disappear if the
- * user mounts the external storage on a computer or removes it.
- * <li>There is no security enforced with these files.
+ * <li>The platform does not always monitor the space available in shared
+ * storage, and thus may not automatically delete these files. Apps should
+ * always manage the maximum space used in this location. Currently the only
+ * time files here will be deleted by the platform is when running on
+ * {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR1} or later and
+ * {@link Environment#isExternalStorageEmulated(File)} returns true.
+ * <li>Shared storage may not always be available, since removable media can
+ * be ejected by the user. Media state can be checked using
+ * {@link Environment#getExternalStorageState(File)}.
+ * <li>There is no security enforced with these files. For example, any
+ * application holding
+ * {@link android.Manifest.permission#WRITE_EXTERNAL_STORAGE} can write to
+ * these files.
* </ul>
* <p>
- * External storage devices returned here are considered a permanent part of
- * the device, including both emulated external storage and physical media
- * slots, such as SD cards in a battery compartment. The returned paths do
- * not include transient devices, such as USB flash drives.
+ * If a shared storage device is emulated (as determined by
+ * {@link Environment#isExternalStorageEmulated(File)}), it's contents are
+ * backed by a private user data partition, which means there is little
+ * benefit to storing data here instead of the private directory returned by
+ * {@link #getCacheDir()}.
* <p>
- * An application may store data on any or all of the returned devices. For
+ * Shared storage devices returned here are considered a stable part of the
+ * device, including physical media slots under a protective cover. The
+ * returned paths do not include transient devices, such as USB flash drives
+ * connected to handheld devices.
+ * <p>
+ * An application may store data on any or all of the returned devices. For
* example, an app may choose to store large files on the device with the
* most available space, as measured by {@link StatFs}.
* <p>
- * No permissions are required to read or write to the returned paths; they
- * are always accessible to the calling app. Write access outside of these
- * paths on secondary external storage devices is not available.
+ * No additional permissions are required for the calling app to read or
+ * write files under the returned path. Write access outside of these paths
+ * on secondary external storage devices is not available.
* <p>
- * The first path returned is the same as {@link #getExternalCacheDir()}.
- * Returned paths may be {@code null} if a storage device is unavailable.
+ * The returned paths may change over time if different shared storage media
+ * is inserted, so only relative paths should be persisted.
*
+ * @return the absolute paths to application-specific directories. Some
+ * individual paths may be {@code null} if that shared storage is
+ * not currently available. The first path returned is the same as
+ * {@link #getExternalCacheDir()}.
* @see #getExternalCacheDir()
* @see Environment#getExternalStorageState(File)
+ * @see Environment#isExternalStorageEmulated(File)
+ * @see Environment#isExternalStorageRemovable(File)
*/
public abstract File[] getExternalCacheDirs();
/**
* Returns absolute paths to application-specific directories on all
- * external storage devices where the application can place media files.
- * These files are scanned and made available to other apps through
+ * shared/external storage devices where the application can place media
+ * files. These files are scanned and made available to other apps through
* {@link MediaStore}.
* <p>
* This is like {@link #getExternalFilesDirs} in that these files will be
* deleted when the application is uninstalled, however there are some
* important differences:
* <ul>
- * <li>External files are not always available: they will disappear if the
- * user mounts the external storage on a computer or removes it.
- * <li>There is no security enforced with these files.
+ * <li>Shared storage may not always be available, since removable media can
+ * be ejected by the user. Media state can be checked using
+ * {@link Environment#getExternalStorageState(File)}.
+ * <li>There is no security enforced with these files. For example, any
+ * application holding
+ * {@link android.Manifest.permission#WRITE_EXTERNAL_STORAGE} can write to
+ * these files.
* </ul>
* <p>
- * External storage devices returned here are considered a permanent part of
- * the device, including both emulated external storage and physical media
- * slots, such as SD cards in a battery compartment. The returned paths do
- * not include transient devices, such as USB flash drives.
+ * Shared storage devices returned here are considered a stable part of the
+ * device, including physical media slots under a protective cover. The
+ * returned paths do not include transient devices, such as USB flash drives
+ * connected to handheld devices.
* <p>
* An application may store data on any or all of the returned devices. For
* example, an app may choose to store large files on the device with the
* most available space, as measured by {@link StatFs}.
* <p>
- * No permissions are required to read or write to the returned paths; they
- * are always accessible to the calling app. Write access outside of these
- * paths on secondary external storage devices is not available.
+ * No additional permissions are required for the calling app to read or
+ * write files under the returned path. Write access outside of these paths
+ * on secondary external storage devices is not available.
* <p>
- * Returned paths may be {@code null} if a storage device is unavailable.
+ * The returned paths may change over time if different shared storage media
+ * is inserted, so only relative paths should be persisted.
*
+ * @return the absolute paths to application-specific directories. Some
+ * individual paths may be {@code null} if that shared storage is
+ * not currently available.
* @see Environment#getExternalStorageState(File)
+ * @see Environment#isExternalStorageEmulated(File)
+ * @see Environment#isExternalStorageRemovable(File)
*/
public abstract File[] getExternalMediaDirs();
@@ -1090,6 +1195,12 @@
* created through a File object will only be accessible by your own
* application; you can only set the mode of the entire directory, not
* of individual files.
+ * <p>
+ * The returned path may change over time if the calling app is moved to an
+ * adopted storage device, so only relative paths should be persisted.
+ * <p>
+ * Apps require no extra permissions to read or write to the returned path,
+ * since this path lives in their private storage.
*
* @param name Name of the directory to retrieve. This is a directory
* that is created as part of your application data.
@@ -1173,6 +1284,9 @@
/**
* Returns the absolute path on the filesystem where a database created with
* {@link #openOrCreateDatabase} is stored.
+ * <p>
+ * The returned path may change over time if the calling app is moved to an
+ * adopted storage device, so only relative paths should be persisted.
*
* @param name The name of the database for which you would like to get
* its path.
diff --git a/core/java/android/content/pm/ActivityInfo.java b/core/java/android/content/pm/ActivityInfo.java
index 43cc63b..e798eb8 100644
--- a/core/java/android/content/pm/ActivityInfo.java
+++ b/core/java/android/content/pm/ActivityInfo.java
@@ -33,12 +33,16 @@
*/
public class ActivityInfo extends ComponentInfo
implements Parcelable {
+
+ // NOTE: When adding new data members be sure to update the copy-constructor, Parcel
+ // constructor, and writeToParcel.
+
/**
* A style resource identifier (in the package's resources) of this
* activity's theme. From the "theme" attribute or, if not set, 0.
*/
public int theme;
-
+
/**
* Constant corresponding to <code>standard</code> in
* the {@link android.R.attr#launchMode} attribute.
@@ -705,6 +709,7 @@
super(orig);
theme = orig.theme;
launchMode = orig.launchMode;
+ documentLaunchMode = orig.documentLaunchMode;
permission = orig.permission;
taskAffinity = orig.taskAffinity;
targetActivity = orig.targetActivity;
@@ -780,6 +785,7 @@
super.writeToParcel(dest, parcelableFlags);
dest.writeInt(theme);
dest.writeInt(launchMode);
+ dest.writeInt(documentLaunchMode);
dest.writeString(permission);
dest.writeString(taskAffinity);
dest.writeString(targetActivity);
@@ -809,6 +815,7 @@
super(source);
theme = source.readInt();
launchMode = source.readInt();
+ documentLaunchMode = source.readInt();
permission = source.readString();
taskAffinity = source.readString();
targetActivity = source.readString();
diff --git a/core/java/android/content/pm/IPackageManager.aidl b/core/java/android/content/pm/IPackageManager.aidl
index a5e9faf..fec2c44 100644
--- a/core/java/android/content/pm/IPackageManager.aidl
+++ b/core/java/android/content/pm/IPackageManager.aidl
@@ -63,7 +63,9 @@
boolean isPackageAvailable(String packageName, int userId);
PackageInfo getPackageInfo(String packageName, int flags, int userId);
int getPackageUid(String packageName, int userId);
+ int getPackageUidEtc(String packageName, int flags, int userId);
int[] getPackageGids(String packageName, int userId);
+ int[] getPackageGidsEtc(String packageName, int flags, int userId);
String[] currentToCanonicalPackageNames(in String[] names);
String[] canonicalToCurrentPackageNames(in String[] names);
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index ed7a2a3..99bd390 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -894,6 +894,7 @@
}
pkg.volumeUuid = volumeUuid;
+ pkg.applicationInfo.volumeUuid = volumeUuid;
pkg.baseCodePath = apkPath;
pkg.mSignatures = null;
@@ -4520,6 +4521,17 @@
return applicationInfo.isUpdatedSystemApp();
}
+ /**
+ * @hide
+ */
+ public boolean canHaveOatDir() {
+ // The following app types CANNOT have oat directory
+ // - non-updated system apps
+ // - forward-locked apps or apps installed in ASEC containers
+ return (!isSystemApp() || isUpdatedSystemApp())
+ && !isForwardLocked() && !applicationInfo.isExternalAsec();
+ }
+
public String toString() {
return "Package{"
+ Integer.toHexString(System.identityHashCode(this))
diff --git a/core/java/android/hardware/ICameraServiceProxy.aidl b/core/java/android/hardware/ICameraServiceProxy.aidl
index 0bb24bc..0e654d5 100644
--- a/core/java/android/hardware/ICameraServiceProxy.aidl
+++ b/core/java/android/hardware/ICameraServiceProxy.aidl
@@ -19,6 +19,8 @@
/**
* Binder interface for the camera service proxy running in system_server.
*
+ * Keep in sync with frameworks/av/include/camera/ICameraServiceProxy.h
+ *
* @hide
*/
interface ICameraServiceProxy
@@ -27,4 +29,9 @@
* Ping the service proxy to update the valid users for the camera service.
*/
oneway void pingForUserUpdate();
+
+ /**
+ * Update the status of a camera device
+ */
+ oneway void notifyCameraState(String cameraId, int newCameraState);
}
diff --git a/core/java/android/hardware/SystemSensorManager.java b/core/java/android/hardware/SystemSensorManager.java
index 30cdfd3..2fe8fb6 100644
--- a/core/java/android/hardware/SystemSensorManager.java
+++ b/core/java/android/hardware/SystemSensorManager.java
@@ -78,14 +78,14 @@
sSensorModuleInitialized = true;
nativeClassInit();
}
- }
- // initialize the sensor list
- for (int index = 0;;++index) {
- Sensor sensor = new Sensor();
- if (!nativeGetSensorAtIndex(mNativeInstance, sensor, index)) break;
- mFullSensorsList.add(sensor);
- mHandleToSensor.append(sensor.getHandle(), sensor);
+ // initialize the sensor list
+ for (int index = 0;;++index) {
+ Sensor sensor = new Sensor();
+ if (!nativeGetSensorAtIndex(mNativeInstance, sensor, index)) break;
+ mFullSensorsList.add(sensor);
+ mHandleToSensor.append(sensor.getHandle(), sensor);
+ }
}
}
diff --git a/core/java/android/hardware/camera2/CameraCaptureSession.java b/core/java/android/hardware/camera2/CameraCaptureSession.java
index 46ffe36..766868d 100644
--- a/core/java/android/hardware/camera2/CameraCaptureSession.java
+++ b/core/java/android/hardware/camera2/CameraCaptureSession.java
@@ -138,6 +138,48 @@
*/
public abstract void prepare(@NonNull Surface surface) throws CameraAccessException;
+ /**
+ * <p>Pre-allocate at most maxCount buffers for an output Surface.</p>
+ *
+ * <p>Like the {@link #prepare(Surface)} method, this method can be used to allocate output
+ * buffers for a given Surface. However, while the {@link #prepare(Surface)} method allocates
+ * the maximum possible buffer count, this method allocates at most maxCount buffers.</p>
+ *
+ * <p>If maxCount is greater than the possible maximum count (which is the sum of the buffer
+ * count requested by the creator of the Surface and the count requested by the camera device),
+ * only the possible maximum count is allocated, in which case the function acts exactly like
+ * {@link #prepare(Surface)}.</p>
+ *
+ * <p>The restrictions on when this method can be called are the same as for
+ * {@link #prepare(Surface)}.</p>
+ *
+ * <p>Repeated calls to this method are allowed, and a mix of {@link #prepare(Surface)} and
+ * this method is also allowed. Note that after the first call to {@link #prepare(Surface)},
+ * subsequent calls to either prepare method are effectively no-ops. In addition, this method
+ * is not additive in terms of buffer count. This means calling it twice with maxCount = 2
+ * will only allocate 2 buffers, not 4 (assuming the possible maximum is at least 2); to
+ * allocate two buffers on the first call and two on the second, the application needs to call
+ * prepare with prepare(surface, 2) and prepare(surface, 4).</p>
+ *
+ * @param maxCount the buffer count to try to allocate. If this is greater than the possible
+ * maximum for this output, the possible maximum is allocated instead. If
+ * maxCount buffers are already allocated, then prepare will do nothing.
+ * @param surface the output Surface for which buffers should be pre-allocated.
+ *
+ * @throws CameraAccessException if the camera device is no longer connected or has
+ * encountered a fatal error.
+ * @throws IllegalStateException if this session is no longer active, either because the
+ * session was explicitly closed, a new session has been created
+ * or the camera device has been closed.
+ * @throws IllegalArgumentException if the Surface is invalid, not part of this Session,
+ * or has already been used as a target of a CaptureRequest in
+ * this session or immediately prior sessions without an
+ * intervening tearDown call.
+ *
+ * @hide
+ */
+ public abstract void prepare(int maxCount, @NonNull Surface surface)
+ throws CameraAccessException;
/**
* <p>Free all buffers allocated for an output Surface.</p>
diff --git a/core/java/android/hardware/camera2/ICameraDeviceUser.aidl b/core/java/android/hardware/camera2/ICameraDeviceUser.aidl
index 7cb3673..c9c9abc 100644
--- a/core/java/android/hardware/camera2/ICameraDeviceUser.aidl
+++ b/core/java/android/hardware/camera2/ICameraDeviceUser.aidl
@@ -102,4 +102,6 @@
int prepare(int streamId);
int tearDown(int streamId);
+
+ int prepare2(int maxCount, int streamId);
}
diff --git a/core/java/android/hardware/camera2/impl/CameraCaptureSessionImpl.java b/core/java/android/hardware/camera2/impl/CameraCaptureSessionImpl.java
index d325c77..5573896 100644
--- a/core/java/android/hardware/camera2/impl/CameraCaptureSessionImpl.java
+++ b/core/java/android/hardware/camera2/impl/CameraCaptureSessionImpl.java
@@ -146,6 +146,11 @@
}
@Override
+ public void prepare(int maxCount, Surface surface) throws CameraAccessException {
+ mDeviceImpl.prepare(maxCount, surface);
+ }
+
+ @Override
public void tearDown(Surface surface) throws CameraAccessException {
mDeviceImpl.tearDown(surface);
}
diff --git a/core/java/android/hardware/camera2/impl/CameraConstrainedHighSpeedCaptureSessionImpl.java b/core/java/android/hardware/camera2/impl/CameraConstrainedHighSpeedCaptureSessionImpl.java
index a920e2b..8cd1da5 100644
--- a/core/java/android/hardware/camera2/impl/CameraConstrainedHighSpeedCaptureSessionImpl.java
+++ b/core/java/android/hardware/camera2/impl/CameraConstrainedHighSpeedCaptureSessionImpl.java
@@ -169,6 +169,11 @@
}
@Override
+ public void prepare(int maxCount, Surface surface) throws CameraAccessException {
+ mSessionImpl.prepare(maxCount, surface);
+ }
+
+ @Override
public void tearDown(Surface surface) throws CameraAccessException {
mSessionImpl.tearDown(surface);
}
diff --git a/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java b/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java
index 91d623e..6e02df1 100644
--- a/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java
+++ b/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java
@@ -679,6 +679,33 @@
}
}
+ public void prepare(int maxCount, Surface surface) throws CameraAccessException {
+ if (surface == null) throw new IllegalArgumentException("Surface is null");
+ if (maxCount <= 0) throw new IllegalArgumentException("Invalid maxCount given: " +
+ maxCount);
+
+ synchronized(mInterfaceLock) {
+ int streamId = -1;
+ for (int i = 0; i < mConfiguredOutputs.size(); i++) {
+ if (surface == mConfiguredOutputs.valueAt(i).getSurface()) {
+ streamId = mConfiguredOutputs.keyAt(i);
+ break;
+ }
+ }
+ if (streamId == -1) {
+ throw new IllegalArgumentException("Surface is not part of this session");
+ }
+ try {
+ mRemoteDevice.prepare2(maxCount, streamId);
+ } catch (CameraRuntimeException e) {
+ throw e.asChecked();
+ } catch (RemoteException e) {
+ // impossible
+ return;
+ }
+ }
+ }
+
public void tearDown(Surface surface) throws CameraAccessException {
if (surface == null) throw new IllegalArgumentException("Surface is null");
diff --git a/core/java/android/hardware/camera2/legacy/CameraDeviceUserShim.java b/core/java/android/hardware/camera2/legacy/CameraDeviceUserShim.java
index e20eaa7..6b8e113 100644
--- a/core/java/android/hardware/camera2/legacy/CameraDeviceUserShim.java
+++ b/core/java/android/hardware/camera2/legacy/CameraDeviceUserShim.java
@@ -636,6 +636,11 @@
return CameraBinderDecorator.NO_ERROR;
}
+ public int prepare2(int maxCount, int streamId) {
+ // We don't support this in LEGACY mode.
+ return prepare(streamId);
+ }
+
public int tearDown(int streamId) {
if (DEBUG) {
Log.d(TAG, "tearDown called.");
diff --git a/core/java/android/hardware/camera2/params/OutputConfiguration.java b/core/java/android/hardware/camera2/params/OutputConfiguration.java
index 7aa9787..a04cdce 100644
--- a/core/java/android/hardware/camera2/params/OutputConfiguration.java
+++ b/core/java/android/hardware/camera2/params/OutputConfiguration.java
@@ -19,7 +19,9 @@
import android.hardware.camera2.CameraDevice;
import android.hardware.camera2.utils.HashCodeHelpers;
+import android.hardware.camera2.utils.SurfaceUtils;
import android.util.Log;
+import android.util.Size;
import android.view.Surface;
import android.os.Parcel;
import android.os.Parcelable;
@@ -66,9 +68,7 @@
*
*/
public OutputConfiguration(Surface surface) {
- checkNotNull(surface, "Surface must not be null");
- mSurface = surface;
- mRotation = ROTATION_0;
+ this(surface, ROTATION_0);
}
/**
@@ -94,6 +94,9 @@
checkArgumentInRange(rotation, ROTATION_0, ROTATION_270, "Rotation constant");
mSurface = surface;
mRotation = rotation;
+ mConfiguredSize = SurfaceUtils.getSurfaceSize(surface);
+ mConfiguredFormat = SurfaceUtils.getSurfaceFormat(surface);
+ mConfiguredDataspace = SurfaceUtils.getSurfaceDataspace(surface);
}
/**
@@ -106,6 +109,9 @@
checkArgumentInRange(rotation, ROTATION_0, ROTATION_270, "Rotation constant");
mSurface = surface;
mRotation = rotation;
+ mConfiguredSize = SurfaceUtils.getSurfaceSize(mSurface);
+ mConfiguredFormat = SurfaceUtils.getSurfaceFormat(mSurface);
+ mConfiguredDataspace = SurfaceUtils.getSurfaceDataspace(mSurface);
}
/**
@@ -163,8 +169,9 @@
/**
* Check if this {@link OutputConfiguration} is equal to another {@link OutputConfiguration}.
*
- * <p>Two output configurations are only equal if and only if the underlying surface and
- * all other configuration parameters are equal. </p>
+ * <p>Two output configurations are only equal if and only if the underlying surfaces, surface
+ * properties (width, height, format, dataspace) when the output configurations are created,
+ * and all other configuration parameters are equal. </p>
*
* @return {@code true} if the objects were equal, {@code false} otherwise
*/
@@ -176,7 +183,11 @@
return true;
} else if (obj instanceof OutputConfiguration) {
final OutputConfiguration other = (OutputConfiguration) obj;
- return (mSurface == other.mSurface && mRotation == other.mRotation);
+ return mSurface == other.mSurface &&
+ mRotation == other.mRotation &&
+ mConfiguredSize.equals(other.mConfiguredSize) &&
+ mConfiguredFormat == other.mConfiguredFormat &&
+ mConfiguredDataspace == other.mConfiguredDataspace;
}
return false;
}
@@ -192,4 +203,9 @@
private static final String TAG = "OutputConfiguration";
private final Surface mSurface;
private final int mRotation;
+
+ // The size, format, and dataspace of the surface when OutputConfiguration is created.
+ private final Size mConfiguredSize;
+ private final int mConfiguredFormat;
+ private final int mConfiguredDataspace;
}
diff --git a/core/java/android/hardware/display/DisplayManagerGlobal.java b/core/java/android/hardware/display/DisplayManagerGlobal.java
index 21ba7bd..121a187 100644
--- a/core/java/android/hardware/display/DisplayManagerGlobal.java
+++ b/core/java/android/hardware/display/DisplayManagerGlobal.java
@@ -359,6 +359,14 @@
}
}
+ public void requestColorTransform(int displayId, int colorTransformId) {
+ try {
+ mDm.requestColorTransform(displayId, colorTransformId);
+ } catch (RemoteException ex) {
+ Log.e(TAG, "Failed to request color transform.", ex);
+ }
+ }
+
public VirtualDisplay createVirtualDisplay(Context context, MediaProjection projection,
String name, int width, int height, int densityDpi, Surface surface, int flags,
VirtualDisplay.Callback callback, Handler handler) {
diff --git a/core/java/android/hardware/display/IDisplayManager.aidl b/core/java/android/hardware/display/IDisplayManager.aidl
index 4486dd4..8a1abf1 100644
--- a/core/java/android/hardware/display/IDisplayManager.aidl
+++ b/core/java/android/hardware/display/IDisplayManager.aidl
@@ -59,6 +59,9 @@
// No permissions required.
WifiDisplayStatus getWifiDisplayStatus();
+ // Requires CONFIGURE_DISPLAY_COLOR_TRANSFORM
+ void requestColorTransform(int displayId, int colorTransformId);
+
// Requires CAPTURE_VIDEO_OUTPUT, CAPTURE_SECURE_VIDEO_OUTPUT, or an appropriate
// MediaProjection token for certain combinations of flags.
int createVirtualDisplay(in IVirtualDisplayCallback callback,
diff --git a/core/java/android/hardware/fingerprint/FingerprintManager.java b/core/java/android/hardware/fingerprint/FingerprintManager.java
index 6e29989..62396a3 100644
--- a/core/java/android/hardware/fingerprint/FingerprintManager.java
+++ b/core/java/android/hardware/fingerprint/FingerprintManager.java
@@ -27,6 +27,7 @@
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
+import android.os.PowerManager;
import android.os.RemoteException;
import android.os.UserHandle;
import android.security.keystore.AndroidKeyStoreProvider;
@@ -257,6 +258,7 @@
public static class AuthenticationResult {
private Fingerprint mFingerprint;
private CryptoObject mCryptoObject;
+ private int mUserId;
/**
* Authentication result
@@ -265,9 +267,10 @@
* @param fingerprint the recognized fingerprint data, if allowed.
* @hide
*/
- public AuthenticationResult(CryptoObject crypto, Fingerprint fingerprint) {
+ public AuthenticationResult(CryptoObject crypto, Fingerprint fingerprint, int userId) {
mCryptoObject = crypto;
mFingerprint = fingerprint;
+ mUserId = userId;
}
/**
@@ -284,6 +287,12 @@
* @hide
*/
public Fingerprint getFingerprint() { return mFingerprint; }
+
+ /**
+ * Obtain the userId for which this fingerprint was authenticated.
+ * @hide
+ */
+ public int getUserId() { return mUserId; }
};
/**
@@ -392,6 +401,18 @@
};
/**
+ * @hide
+ */
+ public static abstract class LockoutResetCallback {
+
+ /**
+ * Called when lockout period expired and clients are allowed to listen for fingerprint
+ * again.
+ */
+ public void onLockoutReset() { }
+ };
+
+ /**
* Request authentication of a crypto object. This call warms up the fingerprint hardware
* and starts scanning for a fingerprint. It terminates when
* {@link AuthenticationCallback#onAuthenticationError(int, CharSequence)} or
@@ -668,6 +689,60 @@
return 0;
}
+ /**
+ * Reset the lockout timer when asked to do so by keyguard.
+ *
+ * @param token an opaque token returned by password confirmation.
+ *
+ * @hide
+ */
+ public void resetTimeout(byte[] token) {
+ if (mService != null) {
+ try {
+ mService.resetTimeout(token);
+ } catch (RemoteException e) {
+ Log.v(TAG, "Remote exception in resetTimeout(): ", e);
+ }
+ } else {
+ Log.w(TAG, "resetTimeout(): Service not connected!");
+ }
+ }
+
+ /**
+ * @hide
+ */
+ public void addLockoutResetCallback(final LockoutResetCallback callback) {
+ if (mService != null) {
+ try {
+ final PowerManager powerManager = mContext.getSystemService(PowerManager.class);
+ mService.addLockoutResetCallback(
+ new IFingerprintServiceLockoutResetCallback.Stub() {
+
+ @Override
+ public void onLockoutReset(long deviceId) throws RemoteException {
+ final PowerManager.WakeLock wakeLock = powerManager.newWakeLock(
+ PowerManager.PARTIAL_WAKE_LOCK, "lockoutResetCallback");
+ wakeLock.acquire();
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ try {
+ callback.onLockoutReset();
+ } finally {
+ wakeLock.release();
+ }
+ }
+ });
+ }
+ });
+ } catch (RemoteException e) {
+ Log.v(TAG, "Remote exception in addLockoutResetCallback(): ", e);
+ }
+ } else {
+ Log.w(TAG, "addLockoutResetCallback(): Service not connected!");
+ }
+ }
+
private class MyHandler extends Handler {
private MyHandler(Context context) {
super(context.getMainLooper());
@@ -677,6 +752,7 @@
super(looper);
}
+ @Override
public void handleMessage(android.os.Message msg) {
switch(msg.what) {
case MSG_ENROLL_RESULT:
@@ -686,7 +762,7 @@
sendAcquiredResult((Long) msg.obj /* deviceId */, msg.arg1 /* acquire info */);
break;
case MSG_AUTHENTICATION_SUCCEEDED:
- sendAuthenticatedSucceeded((Fingerprint) msg.obj);
+ sendAuthenticatedSucceeded((Fingerprint) msg.obj, msg.arg1 /* userId */);
break;
case MSG_AUTHENTICATION_FAILED:
sendAuthenticatedFailed();
@@ -707,7 +783,7 @@
if (fingerId != reqFingerId) {
Log.w(TAG, "Finger id didn't match: " + fingerId + " != " + reqFingerId);
}
- if (fingerId != reqFingerId) {
+ if (groupId != reqGroupId) {
Log.w(TAG, "Group id didn't match: " + groupId + " != " + reqGroupId);
}
mRemovalCallback.onRemovalSucceeded(mRemovalFingerprint);
@@ -731,9 +807,10 @@
}
}
- private void sendAuthenticatedSucceeded(Fingerprint fp) {
+ private void sendAuthenticatedSucceeded(Fingerprint fp, int userId) {
if (mAuthenticationCallback != null) {
- final AuthenticationResult result = new AuthenticationResult(mCryptoObject, fp);
+ final AuthenticationResult result =
+ new AuthenticationResult(mCryptoObject, fp, userId);
mAuthenticationCallback.onAuthenticationSucceeded(result);
}
}
@@ -873,8 +950,8 @@
}
@Override // binder call
- public void onAuthenticationSucceeded(long deviceId, Fingerprint fp) {
- mHandler.obtainMessage(MSG_AUTHENTICATION_SUCCEEDED, fp).sendToTarget();
+ public void onAuthenticationSucceeded(long deviceId, Fingerprint fp, int userId) {
+ mHandler.obtainMessage(MSG_AUTHENTICATION_SUCCEEDED, userId, 0, fp).sendToTarget();
}
@Override // binder call
diff --git a/core/java/android/hardware/fingerprint/IFingerprintService.aidl b/core/java/android/hardware/fingerprint/IFingerprintService.aidl
index 5e233b8..690a751 100644
--- a/core/java/android/hardware/fingerprint/IFingerprintService.aidl
+++ b/core/java/android/hardware/fingerprint/IFingerprintService.aidl
@@ -17,6 +17,7 @@
import android.os.Bundle;
import android.hardware.fingerprint.IFingerprintServiceReceiver;
+import android.hardware.fingerprint.IFingerprintServiceLockoutResetCallback;
import android.hardware.fingerprint.Fingerprint;
import java.util.List;
@@ -68,4 +69,10 @@
// Gets the authenticator ID for fingerprint
long getAuthenticatorId(String opPackageName);
+
+ // Reset the timeout when user authenticates with strong auth (e.g. PIN, pattern or password)
+ void resetTimeout(in byte [] cryptoToken);
+
+ // Add a callback which gets notified when the fingerprint lockout period expired.
+ void addLockoutResetCallback(IFingerprintServiceLockoutResetCallback callback);
}
diff --git a/core/java/android/hardware/fingerprint/IFingerprintServiceLockoutResetCallback.aidl b/core/java/android/hardware/fingerprint/IFingerprintServiceLockoutResetCallback.aidl
new file mode 100644
index 0000000..e027a2b3
--- /dev/null
+++ b/core/java/android/hardware/fingerprint/IFingerprintServiceLockoutResetCallback.aidl
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.hardware.fingerprint;
+
+import android.hardware.fingerprint.Fingerprint;
+import android.os.Bundle;
+import android.os.UserHandle;
+
+/**
+ * Callback when lockout period expired and clients are allowed to authenticate again.
+ * @hide
+ */
+interface IFingerprintServiceLockoutResetCallback {
+
+ /** Method is synchronous so wakelock is held when this is called from a WAKEUP alarm. */
+ void onLockoutReset(long deviceId);
+}
diff --git a/core/java/android/hardware/fingerprint/IFingerprintServiceReceiver.aidl b/core/java/android/hardware/fingerprint/IFingerprintServiceReceiver.aidl
index 57a429f..b024b29 100644
--- a/core/java/android/hardware/fingerprint/IFingerprintServiceReceiver.aidl
+++ b/core/java/android/hardware/fingerprint/IFingerprintServiceReceiver.aidl
@@ -26,7 +26,7 @@
oneway interface IFingerprintServiceReceiver {
void onEnrollResult(long deviceId, int fingerId, int groupId, int remaining);
void onAcquired(long deviceId, int acquiredInfo);
- void onAuthenticationSucceeded(long deviceId, in Fingerprint fp);
+ void onAuthenticationSucceeded(long deviceId, in Fingerprint fp, int userId);
void onAuthenticationFailed(long deviceId);
void onError(long deviceId, int error);
void onRemoved(long deviceId, int fingerId, int groupId);
diff --git a/core/java/android/hardware/input/IInputManager.aidl b/core/java/android/hardware/input/IInputManager.aidl
index 465d142..3601b39 100644
--- a/core/java/android/hardware/input/IInputManager.aidl
+++ b/core/java/android/hardware/input/IInputManager.aidl
@@ -19,6 +19,7 @@
import android.hardware.input.InputDeviceIdentifier;
import android.hardware.input.KeyboardLayout;
import android.hardware.input.IInputDevicesChangedListener;
+import android.hardware.input.ITabletModeChangedListener;
import android.hardware.input.TouchCalibration;
import android.os.IBinder;
import android.view.InputDevice;
@@ -60,6 +61,11 @@
// Registers an input devices changed listener.
void registerInputDevicesChangedListener(IInputDevicesChangedListener listener);
+ // Queries whether the device is currently in tablet mode
+ int isInTabletMode();
+ // Registers a tablet mode change listener
+ void registerTabletModeChangedListener(ITabletModeChangedListener listener);
+
// Input device vibrator control.
void vibrate(int deviceId, in long[] pattern, int repeat, IBinder token);
void cancelVibrate(int deviceId, IBinder token);
diff --git a/core/java/android/hardware/input/ITabletModeChangedListener.aidl b/core/java/android/hardware/input/ITabletModeChangedListener.aidl
new file mode 100644
index 0000000..a8559a7
--- /dev/null
+++ b/core/java/android/hardware/input/ITabletModeChangedListener.aidl
@@ -0,0 +1,23 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.input;
+
+/** @hide */
+interface ITabletModeChangedListener {
+ /* Called when the device enters or exits tablet mode. */
+ oneway void onTabletModeChanged(long whenNanos, boolean inTabletMode);
+}
diff --git a/core/java/android/hardware/input/InputManager.java b/core/java/android/hardware/input/InputManager.java
index 444f020..618864f 100644
--- a/core/java/android/hardware/input/InputManager.java
+++ b/core/java/android/hardware/input/InputManager.java
@@ -16,8 +16,10 @@
package android.hardware.input;
+import com.android.internal.os.SomeArgs;
import com.android.internal.util.ArrayUtils;
+import android.annotation.IntDef;
import android.annotation.SdkConstant;
import android.annotation.SdkConstant.SdkConstantType;
import android.content.Context;
@@ -29,6 +31,7 @@
import android.os.Message;
import android.os.RemoteException;
import android.os.ServiceManager;
+import android.os.SystemClock;
import android.os.Vibrator;
import android.provider.Settings;
import android.provider.Settings.SettingNotFoundException;
@@ -37,7 +40,10 @@
import android.view.InputDevice;
import android.view.InputEvent;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
+import java.util.List;
/**
* Provides information about input devices and available key layouts.
@@ -67,6 +73,11 @@
private final ArrayList<InputDeviceListenerDelegate> mInputDeviceListeners =
new ArrayList<InputDeviceListenerDelegate>();
+ // Guarded by mTabletModeLock
+ private final Object mTabletModeLock = new Object();
+ private TabletModeChangedListener mTabletModeChangedListener;
+ private List<OnTabletModeChangedListenerDelegate> mOnTabletModeChangedListeners;
+
/**
* Broadcast Action: Query available keyboard layouts.
* <p>
@@ -171,6 +182,31 @@
*/
public static final int INJECT_INPUT_EVENT_MODE_WAIT_FOR_FINISH = 2; // see InputDispatcher.h
+ /** @hide */
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef({SWITCH_STATE_UNKNOWN, SWITCH_STATE_OFF, SWITCH_STATE_ON})
+ public @interface SwitchState {}
+
+ /**
+ * Switch State: Unknown.
+ *
+ * The system has yet to report a valid value for the switch.
+ * @hide
+ */
+ public static final int SWITCH_STATE_UNKNOWN = -1;
+
+ /**
+ * Switch State: Off.
+ * @hide
+ */
+ public static final int SWITCH_STATE_OFF = 0;
+
+ /**
+ * Switch State: On.
+ * @hide
+ */
+ public static final int SWITCH_STATE_ON = 1;
+
private InputManager(IInputManager im) {
mIm = im;
}
@@ -331,6 +367,89 @@
}
/**
+ * Queries whether the device is in tablet mode.
+ *
+ * @return The tablet switch state which is one of {@link #SWITCH_STATE_UNKNOWN},
+ * {@link #SWITCH_STATE_OFF} or {@link #SWITCH_STATE_ON}.
+ * @hide
+ */
+ @SwitchState
+ public int isInTabletMode() {
+ try {
+ return mIm.isInTabletMode();
+ } catch (RemoteException ex) {
+ Log.w(TAG, "Could not get tablet mode state", ex);
+ return SWITCH_STATE_UNKNOWN;
+ }
+ }
+
+ /**
+ * Register a tablet mode changed listener.
+ *
+ * @param listener The listener to register.
+ * @param handler The handler on which the listener should be invoked, or null
+ * if the listener should be invoked on the calling thread's looper.
+ * @hide
+ */
+ public void registerOnTabletModeChangedListener(
+ OnTabletModeChangedListener listener, Handler handler) {
+ if (listener == null) {
+ throw new IllegalArgumentException("listener must not be null");
+ }
+ synchronized (mTabletModeLock) {
+ if (mOnTabletModeChangedListeners == null) {
+ initializeTabletModeListenerLocked();
+ }
+ int idx = findOnTabletModeChangedListenerLocked(listener);
+ if (idx < 0) {
+ OnTabletModeChangedListenerDelegate d =
+ new OnTabletModeChangedListenerDelegate(listener, handler);
+ mOnTabletModeChangedListeners.add(d);
+ }
+ }
+ }
+
+ /**
+ * Unregister a tablet mode changed listener.
+ *
+ * @param listener The listener to unregister.
+ * @hide
+ */
+ public void unregisterOnTabletModeChangedListener(OnTabletModeChangedListener listener) {
+ if (listener == null) {
+ throw new IllegalArgumentException("listener must not be null");
+ }
+ synchronized (mTabletModeLock) {
+ int idx = findOnTabletModeChangedListenerLocked(listener);
+ if (idx >= 0) {
+ OnTabletModeChangedListenerDelegate d = mOnTabletModeChangedListeners.remove(idx);
+ d.removeCallbacksAndMessages(null);
+ }
+ }
+ }
+
+ private void initializeTabletModeListenerLocked() {
+ final TabletModeChangedListener listener = new TabletModeChangedListener();
+ try {
+ mIm.registerTabletModeChangedListener(listener);
+ } catch (RemoteException ex) {
+ throw new RuntimeException("Could not register tablet mode changed listener", ex);
+ }
+ mTabletModeChangedListener = listener;
+ mOnTabletModeChangedListeners = new ArrayList<>();
+ }
+
+ private int findOnTabletModeChangedListenerLocked(OnTabletModeChangedListener listener) {
+ final int N = mOnTabletModeChangedListeners.size();
+ for (int i = 0; i < N; i++) {
+ if (mOnTabletModeChangedListeners.get(i).mListener == listener) {
+ return i;
+ }
+ }
+ return -1;
+ }
+
+ /**
* Gets information about all supported keyboard layouts.
* <p>
* The input manager consults the built-in keyboard layouts as well
@@ -769,6 +888,22 @@
return false;
}
+
+ private void onTabletModeChanged(long whenNanos, boolean inTabletMode) {
+ if (DEBUG) {
+ Log.d(TAG, "Received tablet mode changed: "
+ + "whenNanos=" + whenNanos + ", inTabletMode=" + inTabletMode);
+ }
+ synchronized (mTabletModeLock) {
+ final int N = mOnTabletModeChangedListeners.size();
+ for (int i = 0; i < N; i++) {
+ OnTabletModeChangedListenerDelegate listener =
+ mOnTabletModeChangedListeners.get(i);
+ listener.sendTabletModeChanged(whenNanos, inTabletMode);
+ }
+ }
+ }
+
/**
* Gets a vibrator service associated with an input device, assuming it has one.
* @return The vibrator, never null.
@@ -838,6 +973,57 @@
}
}
+ /** @hide */
+ public interface OnTabletModeChangedListener {
+ /**
+ * Called whenever the device goes into or comes out of tablet mode.
+ *
+ * @param whenNanos The time at which the device transitioned into or
+ * out of tablet mode. This is given in nanoseconds in the
+ * {@link SystemClock#uptimeMillis} time base.
+ */
+ void onTabletModeChanged(long whenNanos, boolean inTabletMode);
+ }
+
+ private final class TabletModeChangedListener extends ITabletModeChangedListener.Stub {
+ @Override
+ public void onTabletModeChanged(long whenNanos, boolean inTabletMode) {
+ InputManager.this.onTabletModeChanged(whenNanos, inTabletMode);
+ }
+ }
+
+ private static final class OnTabletModeChangedListenerDelegate extends Handler {
+ private static final int MSG_TABLET_MODE_CHANGED = 0;
+
+ public final OnTabletModeChangedListener mListener;
+
+ public OnTabletModeChangedListenerDelegate(
+ OnTabletModeChangedListener listener, Handler handler) {
+ super(handler != null ? handler.getLooper() : Looper.myLooper());
+ mListener = listener;
+ }
+
+ public void sendTabletModeChanged(long whenNanos, boolean inTabletMode) {
+ SomeArgs args = SomeArgs.obtain();
+ args.argi1 = (int) (whenNanos & 0xFFFFFFFF);
+ args.argi2 = (int) (whenNanos >> 32);
+ args.arg1 = (Boolean) inTabletMode;
+ obtainMessage(MSG_TABLET_MODE_CHANGED, args).sendToTarget();
+ }
+
+ @Override
+ public void handleMessage(Message msg) {
+ switch (msg.what) {
+ case MSG_TABLET_MODE_CHANGED:
+ SomeArgs args = (SomeArgs) msg.obj;
+ long whenNanos = (args.argi1 & 0xFFFFFFFFl) | ((long) args.argi2 << 32);
+ boolean inTabletMode = (boolean) args.arg1;
+ mListener.onTabletModeChanged(whenNanos, inTabletMode);
+ break;
+ }
+ }
+ }
+
private final class InputDeviceVibrator extends Vibrator {
private final int mDeviceId;
private final Binder mToken;
diff --git a/core/java/android/hardware/location/ActivityRecognitionHardware.java b/core/java/android/hardware/location/ActivityRecognitionHardware.java
index 5d3953a..8acd1ff 100644
--- a/core/java/android/hardware/location/ActivityRecognitionHardware.java
+++ b/core/java/android/hardware/location/ActivityRecognitionHardware.java
@@ -30,20 +30,34 @@
* @hide
*/
public class ActivityRecognitionHardware extends IActivityRecognitionHardware.Stub {
- private static final String TAG = "ActivityRecognitionHardware";
+ private static final String TAG = "ActivityRecognitionHW";
+ private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
private static final String HARDWARE_PERMISSION = Manifest.permission.LOCATION_HARDWARE;
+ private static final String ENFORCE_HW_PERMISSION_MESSAGE = "Permission '"
+ + HARDWARE_PERMISSION + "' not granted to access ActivityRecognitionHardware";
+
private static final int INVALID_ACTIVITY_TYPE = -1;
private static final int NATIVE_SUCCESS_RESULT = 0;
+ private static final int EVENT_TYPE_DISABLED = 0;
+ private static final int EVENT_TYPE_ENABLED = 1;
- private static ActivityRecognitionHardware sSingletonInstance = null;
+ /**
+ * Contains the number of supported Event Types.
+ *
+ * NOTE: increment this counter every time a new EVENT_TYPE_ is added to
+ * com.android.location.provider.ActivityRecognitionProvider
+ */
+ private static final int EVENT_TYPE_COUNT = 3;
+
+ private static ActivityRecognitionHardware sSingletonInstance;
private static final Object sSingletonInstanceLock = new Object();
private final Context mContext;
+ private final int mSupportedActivitiesCount;
private final String[] mSupportedActivities;
-
- private final RemoteCallbackList<IActivityRecognitionHardwareSink> mSinks =
- new RemoteCallbackList<IActivityRecognitionHardwareSink>();
+ private final int[][] mSupportedActivitiesEnabledEvents;
+ private final SinkList mSinks = new SinkList();
private static class Event {
public int activity;
@@ -56,6 +70,8 @@
mContext = context;
mSupportedActivities = fetchSupportedActivities();
+ mSupportedActivitiesCount = mSupportedActivities.length;
+ mSupportedActivitiesEnabledEvents = new int[mSupportedActivitiesCount][EVENT_TYPE_COUNT];
}
public static ActivityRecognitionHardware getInstance(Context context) {
@@ -107,7 +123,11 @@
}
int result = nativeEnableActivityEvent(activityType, eventType, reportLatencyNs);
- return result == NATIVE_SUCCESS_RESULT;
+ if (result == NATIVE_SUCCESS_RESULT) {
+ mSupportedActivitiesEnabledEvents[activityType][eventType] = EVENT_TYPE_ENABLED;
+ return true;
+ }
+ return false;
}
@Override
@@ -120,7 +140,11 @@
}
int result = nativeDisableActivityEvent(activityType, eventType);
- return result == NATIVE_SUCCESS_RESULT;
+ if (result == NATIVE_SUCCESS_RESULT) {
+ mSupportedActivitiesEnabledEvents[activityType][eventType] = EVENT_TYPE_DISABLED;
+ return true;
+ }
+ return false;
}
@Override
@@ -135,7 +159,7 @@
*/
private void onActivityChanged(Event[] events) {
if (events == null || events.length == 0) {
- Log.d(TAG, "No events to broadcast for onActivityChanged.");
+ if (DEBUG) Log.d(TAG, "No events to broadcast for onActivityChanged.");
return;
}
@@ -161,7 +185,6 @@
}
}
mSinks.finishBroadcast();
-
}
private String getActivityName(int activityType) {
@@ -193,10 +216,7 @@
}
private void checkPermissions() {
- String message = String.format(
- "Permission '%s' not granted to access ActivityRecognitionHardware",
- HARDWARE_PERMISSION);
- mContext.enforceCallingPermission(HARDWARE_PERMISSION, message);
+ mContext.enforceCallingPermission(HARDWARE_PERMISSION, ENFORCE_HW_PERMISSION_MESSAGE);
}
private String[] fetchSupportedActivities() {
@@ -208,6 +228,39 @@
return new String[0];
}
+ private class SinkList extends RemoteCallbackList<IActivityRecognitionHardwareSink> {
+ @Override
+ public void onCallbackDied(IActivityRecognitionHardwareSink callback) {
+ int callbackCount = mSinks.getRegisteredCallbackCount();
+ if (DEBUG) Log.d(TAG, "RegisteredCallbackCount: " + callbackCount);
+ if (callbackCount != 0) {
+ return;
+ }
+ // currently there is only one client for this, so if all its sinks have died, we clean
+ // up after them, this ensures that the AR HAL is not out of sink
+ for (int activity = 0; activity < mSupportedActivitiesCount; ++activity) {
+ for (int event = 0; event < EVENT_TYPE_COUNT; ++event) {
+ disableActivityEventIfEnabled(activity, event);
+ }
+ }
+ }
+
+ private void disableActivityEventIfEnabled(int activityType, int eventType) {
+ if (mSupportedActivitiesEnabledEvents[activityType][eventType] != EVENT_TYPE_ENABLED) {
+ return;
+ }
+
+ int result = nativeDisableActivityEvent(activityType, eventType);
+ mSupportedActivitiesEnabledEvents[activityType][eventType] = EVENT_TYPE_DISABLED;
+ String message = String.format(
+ "DisableActivityEvent: activityType=%d, eventType=%d, result=%d",
+ activityType,
+ eventType,
+ result);
+ Log.e(TAG, message);
+ }
+ }
+
// native bindings
static { nativeClassInit(); }
diff --git a/core/java/android/hardware/location/IActivityRecognitionHardwareClient.aidl b/core/java/android/hardware/location/IActivityRecognitionHardwareClient.aidl
new file mode 100644
index 0000000..d2c3d75
--- /dev/null
+++ b/core/java/android/hardware/location/IActivityRecognitionHardwareClient.aidl
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2015, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/license/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.hardware.location.IActivityRecognitionHardware;
+
+/**
+ * Activity Recognition Hardware client interface.
+ * This interface can be used to receive interfaces to implementations of
+ * {@link IActivityRecognitionHardware}.
+ *
+ * @hide
+ */
+interface IActivityRecognitionHardwareClient {
+ /**
+ * Hardware Activity-Recognition availability event.
+ *
+ * @param isSupported whether the platform has hardware support for the feature
+ * @param instance the available instance to provide access to the feature
+ */
+ void onAvailabilityChanged(in boolean isSupported, in IActivityRecognitionHardware instance);
+}
diff --git a/core/java/android/hardware/location/IActivityRecognitionHardwareWatcher.aidl b/core/java/android/hardware/location/IActivityRecognitionHardwareWatcher.aidl
index 0507f52..12e3117 100644
--- a/core/java/android/hardware/location/IActivityRecognitionHardwareWatcher.aidl
+++ b/core/java/android/hardware/location/IActivityRecognitionHardwareWatcher.aidl
@@ -22,6 +22,8 @@
* Activity Recognition Hardware watcher. This interface can be used to receive interfaces to
* implementations of {@link IActivityRecognitionHardware}.
*
+ * @deprecated use {@link IActivityRecognitionHardwareClient} instead.
+
* @hide
*/
interface IActivityRecognitionHardwareWatcher {
@@ -29,4 +31,4 @@
* Hardware Activity-Recognition availability event.
*/
void onInstanceChanged(in IActivityRecognitionHardware instance);
-}
\ No newline at end of file
+}
diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java
index 8e55736..4d9b759 100644
--- a/core/java/android/net/ConnectivityManager.java
+++ b/core/java/android/net/ConnectivityManager.java
@@ -100,6 +100,16 @@
public static final String CONNECTIVITY_ACTION = "android.net.conn.CONNECTIVITY_CHANGE";
/**
+ * A temporary hack until SUPL system can get off the legacy APIS.
+ * They do too many network requests and the long list of apps listening
+ * and waking due to the CONNECTIVITY_ACTION bcast makes it expensive.
+ * Use this bcast intent instead for SUPL requests.
+ * @hide
+ */
+ public static final String CONNECTIVITY_ACTION_SUPL =
+ "android.net.conn.CONNECTIVITY_CHANGE_SUPL";
+
+ /**
* The device has connected to a network that has presented a captive
* portal, which is blocking Internet connectivity. The user was presented
* with a notification that network sign in is required,
@@ -885,8 +895,12 @@
* Tells the underlying networking system that the caller wants to
* begin using the named feature. The interpretation of {@code feature}
* is completely up to each networking implementation.
- * <p>This method requires the caller to hold the permission
- * {@link android.Manifest.permission#CHANGE_NETWORK_STATE}.
+ *
+ * <p>This method requires the caller to hold either the
+ * {@link android.Manifest.permission#CHANGE_NETWORK_STATE} permission
+ * or the ability to modify system settings as determined by
+ * {@link android.provider.Settings.System#canWrite}.</p>
+ *
* @param networkType specifies which network the request pertains to
* @param feature the name of the feature to be used
* @return an integer value representing the outcome of the request.
@@ -936,8 +950,12 @@
* Tells the underlying networking system that the caller is finished
* using the named feature. The interpretation of {@code feature}
* is completely up to each networking implementation.
- * <p>This method requires the caller to hold the permission
- * {@link android.Manifest.permission#CHANGE_NETWORK_STATE}.
+ *
+ * <p>This method requires the caller to hold either the
+ * {@link android.Manifest.permission#CHANGE_NETWORK_STATE} permission
+ * or the ability to modify system settings as determined by
+ * {@link android.provider.Settings.System#canWrite}.</p>
+ *
* @param networkType specifies which network the request pertains to
* @param feature the name of the feature that is no longer needed
* @return an integer value representing the outcome of the request.
@@ -1181,12 +1199,154 @@
return true;
}
+ /** @hide */
+ public static class PacketKeepaliveCallback {
+ /** The requested keepalive was successfully started. */
+ public void onStarted() {}
+ /** The keepalive was successfully stopped. */
+ public void onStopped() {}
+ /** An error occurred. */
+ public void onError(int error) {}
+ }
+
+ /**
+ * Allows applications to request that the system periodically send specific packets on their
+ * behalf, using hardware offload to save battery power.
+ *
+ * To request that the system send keepalives, call one of the methods that return a
+ * {@link ConnectivityManager.PacketKeepalive} object, such as {@link #startNattKeepalive},
+ * passing in a non-null callback. If the callback is successfully started, the callback's
+ * {@code onStarted} method will be called. If an error occurs, {@code onError} will be called,
+ * specifying one of the {@code ERROR_*} constants in this class.
+ *
+ * To stop an existing keepalive, call {@link stop}. The system will call {@code onStopped} if
+ * the operation was successfull or {@code onError} if an error occurred.
+ *
+ * @hide
+ */
+ public class PacketKeepalive {
+
+ private static final String TAG = "PacketKeepalive";
+
+ /** @hide */
+ public static final int SUCCESS = 0;
+
+ /** @hide */
+ public static final int NO_KEEPALIVE = -1;
+
+ /** @hide */
+ public static final int BINDER_DIED = -10;
+
+ /** The specified {@code Network} is not connected. */
+ public static final int ERROR_INVALID_NETWORK = -20;
+ /** The specified IP addresses are invalid. For example, the specified source IP address is
+ * not configured on the specified {@code Network}. */
+ public static final int ERROR_INVALID_IP_ADDRESS = -21;
+ /** The requested port is invalid. */
+ public static final int ERROR_INVALID_PORT = -22;
+ /** The packet length is invalid (e.g., too long). */
+ public static final int ERROR_INVALID_LENGTH = -23;
+ /** The packet transmission interval is invalid (e.g., too short). */
+ public static final int ERROR_INVALID_INTERVAL = -24;
+
+ /** The hardware does not support this request. */
+ public static final int ERROR_HARDWARE_UNSUPPORTED = -30;
+ /** The hardware returned an error. */
+ public static final int ERROR_HARDWARE_ERROR = -31;
+
+ public static final int NATT_PORT = 4500;
+
+ private final Network mNetwork;
+ private final PacketKeepaliveCallback mCallback;
+ private final Looper mLooper;
+ private final Messenger mMessenger;
+
+ private volatile Integer mSlot;
+
+ void stopLooper() {
+ mLooper.quit();
+ }
+
+ public void stop() {
+ try {
+ mService.stopKeepalive(mNetwork, mSlot);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Error stopping packet keepalive: ", e);
+ stopLooper();
+ }
+ }
+
+ private PacketKeepalive(Network network, PacketKeepaliveCallback callback) {
+ checkNotNull(network, "network cannot be null");
+ checkNotNull(callback, "callback cannot be null");
+ mNetwork = network;
+ mCallback = callback;
+ HandlerThread thread = new HandlerThread(TAG);
+ thread.start();
+ mLooper = thread.getLooper();
+ mMessenger = new Messenger(new Handler(mLooper) {
+ @Override
+ public void handleMessage(Message message) {
+ switch (message.what) {
+ case NetworkAgent.EVENT_PACKET_KEEPALIVE:
+ int error = message.arg2;
+ try {
+ if (error == SUCCESS) {
+ if (mSlot == null) {
+ mSlot = message.arg1;
+ mCallback.onStarted();
+ } else {
+ mSlot = null;
+ stopLooper();
+ mCallback.onStopped();
+ }
+ } else {
+ stopLooper();
+ mCallback.onError(error);
+ }
+ } catch (Exception e) {
+ Log.e(TAG, "Exception in keepalive callback(" + error + ")", e);
+ }
+ break;
+ default:
+ Log.e(TAG, "Unhandled message " + Integer.toHexString(message.what));
+ break;
+ }
+ }
+ });
+ }
+ }
+
+ /**
+ * Starts an IPsec NAT-T keepalive packet with the specified parameters.
+ *
+ * @hide
+ */
+ public PacketKeepalive startNattKeepalive(
+ Network network, int intervalSeconds, PacketKeepaliveCallback callback,
+ InetAddress srcAddr, int srcPort, InetAddress dstAddr) {
+ final PacketKeepalive k = new PacketKeepalive(network, callback);
+ try {
+ mService.startNattKeepalive(network, intervalSeconds, k.mMessenger, new Binder(),
+ srcAddr.getHostAddress(), srcPort, dstAddr.getHostAddress());
+ } catch (RemoteException e) {
+ Log.e(TAG, "Error starting packet keepalive: ", e);
+ k.stopLooper();
+ return null;
+ }
+ return k;
+ }
+
/**
* Ensure that a network route exists to deliver traffic to the specified
* host via the specified network interface. An attempt to add a route that
* already exists is ignored, but treated as successful.
- * <p>This method requires the caller to hold the permission
- * {@link android.Manifest.permission#CHANGE_NETWORK_STATE}.
+ *
+ * <p>This method requires the caller to hold either the
+ * {@link android.Manifest.permission#CHANGE_NETWORK_STATE} permission
+ * or the ability to modify system settings as determined by
+ * {@link android.provider.Settings.System#canWrite}.</p>
+ *
* @param networkType the type of the network over which traffic to the specified
* host is to be routed
* @param hostAddress the IP address of the host to which the route is desired
@@ -1206,8 +1366,12 @@
* Ensure that a network route exists to deliver traffic to the specified
* host via the specified network interface. An attempt to add a route that
* already exists is ignored, but treated as successful.
- * <p>This method requires the caller to hold the permission
- * {@link android.Manifest.permission#CHANGE_NETWORK_STATE}.
+ *
+ * <p>This method requires the caller to hold either the
+ * {@link android.Manifest.permission#CHANGE_NETWORK_STATE} permission
+ * or the ability to modify system settings as determined by
+ * {@link android.provider.Settings.System#canWrite}.</p>
+ *
* @param networkType the type of the network over which traffic to the specified
* host is to be routed
* @param hostAddress the IP address of the host to which the route is desired
@@ -1407,6 +1571,13 @@
return (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
}
+ /** {@hide} */
+ public static final void enforceChangePermission(Context context) {
+ int uid = Binder.getCallingUid();
+ Settings.checkAndNoteChangeNetworkStateOperation(context, uid, Settings
+ .getPackageNameForUid(context, uid), true /* throwException */);
+ }
+
/** {@hide */
public static final void enforceTetherChangePermission(Context context) {
if (context.getResources().getStringArray(
@@ -1417,8 +1588,8 @@
android.Manifest.permission.CONNECTIVITY_INTERNAL, "ConnectivityService");
} else {
int uid = Binder.getCallingUid();
- Settings.checkAndNoteChangeNetworkStateOperation(context, uid, Settings
- .getPackageNameForUid(context, uid), true);
+ Settings.checkAndNoteWriteSettingsOperation(context, uid, Settings
+ .getPackageNameForUid(context, uid), true /* throwException */);
}
}
@@ -1523,8 +1694,11 @@
* allowed between the tethered devices and this device, though upstream net
* access will of course fail until an upstream network interface becomes
* active.
- * <p>This method requires the caller to hold the permission
- * {@link android.Manifest.permission#CHANGE_NETWORK_STATE}.
+ *
+ * <p>This method requires the caller to hold either the
+ * {@link android.Manifest.permission#CHANGE_NETWORK_STATE} permission
+ * or the ability to modify system settings as determined by
+ * {@link android.provider.Settings.System#canWrite}.</p>
*
* @param iface the interface name to tether.
* @return error a {@code TETHER_ERROR} value indicating success or failure type
@@ -1541,8 +1715,11 @@
/**
* Stop tethering the named interface.
- * <p>This method requires the caller to hold the permission
- * {@link android.Manifest.permission#CHANGE_NETWORK_STATE}.
+ *
+ * <p>This method requires the caller to hold either the
+ * {@link android.Manifest.permission#CHANGE_NETWORK_STATE} permission
+ * or the ability to modify system settings as determined by
+ * {@link android.provider.Settings.System#canWrite}.</p>
*
* @param iface the interface name to untether.
* @return error a {@code TETHER_ERROR} value indicating success or failure type
@@ -1642,8 +1819,11 @@
* attempt to switch to Rndis and subsequently tether the resulting
* interface on {@code true} or turn off tethering and switch off
* Rndis on {@code false}.
- * <p>This method requires the caller to hold the permission
- * {@link android.Manifest.permission#CHANGE_NETWORK_STATE}.
+ *
+ * <p>This method requires the caller to hold either the
+ * {@link android.Manifest.permission#CHANGE_NETWORK_STATE} permission
+ * or the ability to modify system settings as determined by
+ * {@link android.provider.Settings.System#canWrite}.</p>
*
* @param enable a boolean - {@code true} to enable tethering
* @return error a {@code TETHER_ERROR} value indicating success or failure type
@@ -2113,6 +2293,7 @@
private final AtomicInteger mRefCount;
private static final String TAG = "ConnectivityManager.CallbackHandler";
private final ConnectivityManager mCm;
+ private static final boolean DBG = false;
CallbackHandler(Looper looper, HashMap<NetworkRequest, NetworkCallback>callbackMap,
AtomicInteger refCount, ConnectivityManager cm) {
@@ -2124,7 +2305,7 @@
@Override
public void handleMessage(Message message) {
- Log.d(TAG, "CM callback handler got msg " + message.what);
+ if (DBG) Log.d(TAG, "CM callback handler got msg " + message.what);
NetworkRequest request = (NetworkRequest) getObject(message, NetworkRequest.class);
Network network = (Network) getObject(message, Network.class);
switch (message.what) {
@@ -2312,8 +2493,11 @@
* network may never attain, and whether a network will attain these states
* is unknown prior to bringing up the network so the framework does not
* know how to go about satisfing a request with these capabilities.
- * <p>This method requires the caller to hold the permission
- * {@link android.Manifest.permission#CHANGE_NETWORK_STATE}.
+ *
+ * <p>This method requires the caller to hold either the
+ * {@link android.Manifest.permission#CHANGE_NETWORK_STATE} permission
+ * or the ability to modify system settings as determined by
+ * {@link android.provider.Settings.System#canWrite}.</p>
*
* @param request {@link NetworkRequest} describing this request.
* @param networkCallback The {@link NetworkCallback} to be utilized for this
@@ -2335,8 +2519,12 @@
* network is not found within the given time (in milliseconds) the
* {@link NetworkCallback#unavailable} callback is called. The request must
* still be released normally by calling {@link releaseNetworkRequest}.
- * <p>This method requires the caller to hold the permission
- * {@link android.Manifest.permission#CHANGE_NETWORK_STATE}.
+ *
+ * <p>This method requires the caller to hold either the
+ * {@link android.Manifest.permission#CHANGE_NETWORK_STATE} permission
+ * or the ability to modify system settings as determined by
+ * {@link android.provider.Settings.System#canWrite}.</p>
+ *
* @param request {@link NetworkRequest} describing this request.
* @param networkCallback The callbacks to be utilized for this request. Note
* the callbacks must not be shared - they uniquely specify
@@ -2409,8 +2597,12 @@
* network may never attain, and whether a network will attain these states
* is unknown prior to bringing up the network so the framework does not
* know how to go about satisfing a request with these capabilities.
- * <p>This method requires the caller to hold the permission
- * {@link android.Manifest.permission#CHANGE_NETWORK_STATE}.
+ *
+ * <p>This method requires the caller to hold either the
+ * {@link android.Manifest.permission#CHANGE_NETWORK_STATE} permission
+ * or the ability to modify system settings as determined by
+ * {@link android.provider.Settings.System#canWrite}.</p>
+ *
* @param request {@link NetworkRequest} describing this request.
* @param operation Action to perform when the network is available (corresponds
* to the {@link NetworkCallback#onAvailable} call. Typically
diff --git a/core/java/android/net/DhcpResults.java b/core/java/android/net/DhcpResults.java
index 87c063f..97bd5d2 100644
--- a/core/java/android/net/DhcpResults.java
+++ b/core/java/android/net/DhcpResults.java
@@ -21,7 +21,6 @@
import android.text.TextUtils;
import android.util.Log;
-import java.net.InetAddress;
import java.net.Inet4Address;
import java.util.Objects;
@@ -34,7 +33,7 @@
public class DhcpResults extends StaticIpConfiguration {
private static final String TAG = "DhcpResults";
- public InetAddress serverAddress;
+ public Inet4Address serverAddress;
/** Vendor specific information (from RFC 2132). */
public String vendorInfo;
@@ -142,7 +141,7 @@
private static void readFromParcel(DhcpResults dhcpResults, Parcel in) {
StaticIpConfiguration.readFromParcel(dhcpResults, in);
dhcpResults.leaseDuration = in.readInt();
- dhcpResults.serverAddress = NetworkUtils.unparcelInetAddress(in);
+ dhcpResults.serverAddress = (Inet4Address) NetworkUtils.unparcelInetAddress(in);
dhcpResults.vendorInfo = in.readString();
}
@@ -183,8 +182,8 @@
public boolean setServerAddress(String addrString) {
try {
- serverAddress = NetworkUtils.numericToInetAddress(addrString);
- } catch (IllegalArgumentException e) {
+ serverAddress = (Inet4Address) NetworkUtils.numericToInetAddress(addrString);
+ } catch (IllegalArgumentException|ClassCastException e) {
Log.e(TAG, "setServerAddress failed with addrString " + addrString);
return true;
}
diff --git a/core/java/android/net/IConnectivityManager.aidl b/core/java/android/net/IConnectivityManager.aidl
index 46c28a6..d4dd669 100644
--- a/core/java/android/net/IConnectivityManager.aidl
+++ b/core/java/android/net/IConnectivityManager.aidl
@@ -160,4 +160,9 @@
boolean setUnderlyingNetworksForVpn(in Network[] networks);
void factoryReset();
+
+ void startNattKeepalive(in Network network, int intervalSeconds, in Messenger messenger,
+ in IBinder binder, String srcAddr, int srcPort, String dstAddr);
+
+ void stopKeepalive(in Network network, int slot);
}
diff --git a/core/java/android/net/IpReachabilityMonitor.java b/core/java/android/net/IpReachabilityMonitor.java
index 88fb014..2283004c 100644
--- a/core/java/android/net/IpReachabilityMonitor.java
+++ b/core/java/android/net/IpReachabilityMonitor.java
@@ -18,6 +18,7 @@
import com.android.internal.annotations.GuardedBy;
+import android.content.Context;
import android.net.LinkAddress;
import android.net.LinkProperties;
import android.net.LinkProperties.ProvisioningChange;
@@ -31,6 +32,7 @@
import android.net.netlink.StructNdaCacheInfo;
import android.net.netlink.StructNdMsg;
import android.net.netlink.StructNlMsgHdr;
+import android.os.PowerManager;
import android.os.SystemClock;
import android.system.ErrnoException;
import android.system.NetlinkSocketAddress;
@@ -74,6 +76,7 @@
}
private final Object mLock = new Object();
+ private final PowerManager.WakeLock mWakeLock;
private final String mInterfaceName;
private final int mInterfaceIndex;
private final Callback mCallback;
@@ -136,7 +139,8 @@
return returnValue;
}
- public IpReachabilityMonitor(String ifName, Callback callback) throws IllegalArgumentException {
+ public IpReachabilityMonitor(Context context, String ifName, Callback callback)
+ throws IllegalArgumentException {
mInterfaceName = ifName;
int ifIndex = -1;
try {
@@ -145,6 +149,8 @@
} catch (SocketException | NullPointerException e) {
throw new IllegalArgumentException("invalid interface '" + ifName + "': ", e);
}
+ mWakeLock = ((PowerManager) context.getSystemService(Context.POWER_SERVICE)).newWakeLock(
+ PowerManager.PARTIAL_WAKE_LOCK, TAG + "." + mInterfaceName);
mCallback = callback;
mNetlinkSocketObserver = new NetlinkSocketObserver();
mObserverThread = new Thread(mNetlinkSocketObserver);
@@ -291,6 +297,17 @@
synchronized (mLock) {
ipProbeList.addAll(mIpWatchList.keySet());
}
+
+ if (!ipProbeList.isEmpty() && stillRunning()) {
+ // Keep the CPU awake long enough to allow all ARP/ND
+ // probes a reasonable chance at success. See b/23197666.
+ //
+ // The wakelock we use is (by default) refcounted, and this version
+ // of acquire(timeout) queues a release message to keep acquisitions
+ // and releases balanced.
+ mWakeLock.acquire(getProbeWakeLockDuration());
+ }
+
for (InetAddress target : ipProbeList) {
if (!stillRunning()) {
break;
@@ -299,6 +316,22 @@
}
}
+ private long getProbeWakeLockDuration() {
+ // Ideally, this would be computed by examining the values of:
+ //
+ // /proc/sys/net/ipv[46]/neigh/<ifname>/ucast_solicit
+ //
+ // and:
+ //
+ // /proc/sys/net/ipv[46]/neigh/<ifname>/retrans_time_ms
+ //
+ // For now, just make some assumptions.
+ final long numUnicastProbes = 3;
+ final long retransTimeMs = 1000;
+ final long gracePeriodMs = 500;
+ return (numUnicastProbes * retransTimeMs) + gracePeriodMs;
+ }
+
// TODO: simply the number of objects by making this extend Thread.
private final class NetlinkSocketObserver implements Runnable {
diff --git a/core/java/android/net/NetworkAgent.java b/core/java/android/net/NetworkAgent.java
index 808a882..20c2168 100644
--- a/core/java/android/net/NetworkAgent.java
+++ b/core/java/android/net/NetworkAgent.java
@@ -17,6 +17,7 @@
package android.net;
import android.content.Context;
+import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
@@ -25,6 +26,7 @@
import com.android.internal.util.AsyncChannel;
import com.android.internal.util.Protocol;
+import android.net.ConnectivityManager.PacketKeepalive;
import java.util.ArrayList;
import java.util.concurrent.atomic.AtomicBoolean;
@@ -143,17 +145,60 @@
*/
public static final int CMD_SAVE_ACCEPT_UNVALIDATED = BASE + 9;
- /** Sent by ConnectivityService to the NetworkAgent to inform the agent to pull
+ /**
+ * Sent by ConnectivityService to the NetworkAgent to inform the agent to pull
* the underlying network connection for updated bandwidth information.
*/
public static final int CMD_REQUEST_BANDWIDTH_UPDATE = BASE + 10;
/**
+ * Sent by ConnectivityService to the NetworkAgent to request that the specified packet be sent
+ * periodically on the given interval.
+ *
+ * arg1 = the slot number of the keepalive to start
+ * arg2 = interval in seconds
+ * obj = KeepalivePacketData object describing the data to be sent
+ *
+ * Also used internally by ConnectivityService / KeepaliveTracker, with different semantics.
+ */
+ public static final int CMD_START_PACKET_KEEPALIVE = BASE + 11;
+
+ /**
+ * Requests that the specified keepalive packet be stopped.
+ *
+ * arg1 = slot number of the keepalive to stop.
+ *
+ * Also used internally by ConnectivityService / KeepaliveTracker, with different semantics.
+ */
+ public static final int CMD_STOP_PACKET_KEEPALIVE = BASE + 12;
+
+ /**
+ * Sent by the NetworkAgent to ConnectivityService to provide status on a packet keepalive
+ * request. This may either be the reply to a CMD_START_PACKET_KEEPALIVE, or an asynchronous
+ * error notification.
+ *
+ * This is also sent by KeepaliveTracker to the app's ConnectivityManager.PacketKeepalive to
+ * so that the app's PacketKeepaliveCallback methods can be called.
+ *
+ * arg1 = slot number of the keepalive
+ * arg2 = error code
+ */
+ public static final int EVENT_PACKET_KEEPALIVE = BASE + 13;
+
+ /**
+ * Sent by ConnectivityService to inform this network transport of signal strength thresholds
+ * that when crossed should trigger a system wakeup and a NetworkCapabilities update.
+ *
+ * obj = int[] describing signal strength thresholds.
+ */
+ public static final int CMD_SET_SIGNAL_STRENGTH_THRESHOLDS = BASE + 14;
+
+ /**
* Sent by ConnectivityService to the NeworkAgent to inform the agent to avoid
* automatically reconnecting to this network (e.g. via autojoin). Happens
* when user selects "No" option on the "Stay connected?" dialog box.
*/
- public static final int CMD_PREVENT_AUTOMATIC_RECONNECT = BASE + 11;
+ public static final int CMD_PREVENT_AUTOMATIC_RECONNECT = BASE + 15;
public NetworkAgent(Looper looper, Context context, String logTag, NetworkInfo ni,
NetworkCapabilities nc, LinkProperties lp, int score) {
@@ -249,6 +294,27 @@
saveAcceptUnvalidated(msg.arg1 != 0);
break;
}
+ case CMD_START_PACKET_KEEPALIVE: {
+ startPacketKeepalive(msg);
+ break;
+ }
+ case CMD_STOP_PACKET_KEEPALIVE: {
+ stopPacketKeepalive(msg);
+ break;
+ }
+
+ case CMD_SET_SIGNAL_STRENGTH_THRESHOLDS: {
+ ArrayList<Integer> thresholds =
+ ((Bundle) msg.obj).getIntegerArrayList("thresholds");
+ // TODO: Change signal strength thresholds API to use an ArrayList<Integer>
+ // rather than convert to int[].
+ int[] intThresholds = new int[(thresholds != null) ? thresholds.size() : 0];
+ for (int i = 0; i < intThresholds.length; i++) {
+ intThresholds[i] = thresholds.get(i);
+ }
+ setSignalStrengthThresholds(intThresholds);
+ break;
+ }
case CMD_PREVENT_AUTOMATIC_RECONNECT: {
preventAutomaticReconnect();
break;
@@ -257,13 +323,27 @@
}
private void queueOrSendMessage(int what, Object obj) {
+ queueOrSendMessage(what, 0, 0, obj);
+ }
+
+ private void queueOrSendMessage(int what, int arg1, int arg2) {
+ queueOrSendMessage(what, arg1, arg2, null);
+ }
+
+ private void queueOrSendMessage(int what, int arg1, int arg2, Object obj) {
+ Message msg = Message.obtain();
+ msg.what = what;
+ msg.arg1 = arg1;
+ msg.arg2 = arg2;
+ msg.obj = obj;
+ queueOrSendMessage(msg);
+ }
+
+ private void queueOrSendMessage(Message msg) {
synchronized (mPreConnectedQueue) {
if (mAsyncChannel != null) {
- mAsyncChannel.sendMessage(what, obj);
+ mAsyncChannel.sendMessage(msg);
} else {
- Message msg = Message.obtain();
- msg.what = what;
- msg.obj = obj;
mPreConnectedQueue.add(msg);
}
}
@@ -378,6 +458,34 @@
}
/**
+ * Requests that the network hardware send the specified packet at the specified interval.
+ */
+ protected void startPacketKeepalive(Message msg) {
+ onPacketKeepaliveEvent(msg.arg1, PacketKeepalive.ERROR_HARDWARE_UNSUPPORTED);
+ }
+
+ /**
+ * Requests that the network hardware send the specified packet at the specified interval.
+ */
+ protected void stopPacketKeepalive(Message msg) {
+ onPacketKeepaliveEvent(msg.arg1, PacketKeepalive.ERROR_HARDWARE_UNSUPPORTED);
+ }
+
+ /**
+ * Called by the network when a packet keepalive event occurs.
+ */
+ public void onPacketKeepaliveEvent(int slot, int reason) {
+ queueOrSendMessage(EVENT_PACKET_KEEPALIVE, slot, reason);
+ }
+
+ /**
+ * Called by ConnectivityService to inform this network transport of signal strength thresholds
+ * that when crossed should trigger a system wakeup and a NetworkCapabilities update.
+ */
+ protected void setSignalStrengthThresholds(int[] thresholds) {
+ }
+
+ /**
* Called when the user asks to not stay connected to this network because it was found to not
* provide Internet access. Usually followed by call to {@code unwanted}. The transport is
* responsible for making sure the device does not automatically reconnect to the same network
diff --git a/core/java/android/net/NetworkCapabilities.java b/core/java/android/net/NetworkCapabilities.java
index d0e0cbe..3bd12c0 100644
--- a/core/java/android/net/NetworkCapabilities.java
+++ b/core/java/android/net/NetworkCapabilities.java
@@ -48,6 +48,7 @@
mLinkUpBandwidthKbps = nc.mLinkUpBandwidthKbps;
mLinkDownBandwidthKbps = nc.mLinkDownBandwidthKbps;
mNetworkSpecifier = nc.mNetworkSpecifier;
+ mSignalStrength = nc.mSignalStrength;
}
}
@@ -60,6 +61,7 @@
mNetworkCapabilities = mTransportTypes = 0;
mLinkUpBandwidthKbps = mLinkDownBandwidthKbps = 0;
mNetworkSpecifier = null;
+ mSignalStrength = SIGNAL_STRENGTH_UNSPECIFIED;
}
/**
@@ -184,6 +186,28 @@
private static final int MAX_NET_CAPABILITY = NET_CAPABILITY_CAPTIVE_PORTAL;
/**
+ * Network capabilities that are expected to be mutable, i.e., can change while a particular
+ * network is connected.
+ */
+ private static final long MUTABLE_CAPABILITIES =
+ // TRUSTED can change when user explicitly connects to an untrusted network in Settings.
+ // http://b/18206275
+ (1 << NET_CAPABILITY_TRUSTED) |
+ (1 << NET_CAPABILITY_VALIDATED) |
+ (1 << NET_CAPABILITY_CAPTIVE_PORTAL);
+
+ /**
+ * Network capabilities that are not allowed in NetworkRequests. This exists because the
+ * NetworkFactory / NetworkAgent model does not deal well with the situation where a
+ * capability's presence cannot be known in advance. If such a capability is requested, then we
+ * can get into a cycle where the NetworkFactory endlessly churns out NetworkAgents that then
+ * get immediately torn down because they do not have the requested capability.
+ */
+ private static final long NON_REQUESTABLE_CAPABILITIES =
+ (1 << NET_CAPABILITY_VALIDATED) |
+ (1 << NET_CAPABILITY_CAPTIVE_PORTAL);
+
+ /**
* Capabilities that are set by default when the object is constructed.
*/
private static final long DEFAULT_CAPABILITIES =
@@ -278,8 +302,31 @@
this.mNetworkCapabilities |= nc.mNetworkCapabilities;
}
- private boolean satisfiedByNetCapabilities(NetworkCapabilities nc) {
- return ((nc.mNetworkCapabilities & this.mNetworkCapabilities) == this.mNetworkCapabilities);
+ /**
+ * Convenience function that returns a human-readable description of the first mutable
+ * capability we find. Used to present an error message to apps that request mutable
+ * capabilities.
+ *
+ * @hide
+ */
+ public String describeFirstNonRequestableCapability() {
+ if (hasCapability(NET_CAPABILITY_VALIDATED)) return "NET_CAPABILITY_VALIDATED";
+ if (hasCapability(NET_CAPABILITY_CAPTIVE_PORTAL)) return "NET_CAPABILITY_CAPTIVE_PORTAL";
+ // This cannot happen unless the preceding checks are incomplete.
+ if ((mNetworkCapabilities & NON_REQUESTABLE_CAPABILITIES) != 0) {
+ return "unknown non-requestable capabilities " + Long.toHexString(mNetworkCapabilities);
+ }
+ if (mLinkUpBandwidthKbps != 0 || mLinkDownBandwidthKbps != 0) return "link bandwidth";
+ if (hasSignalStrength()) return "signalStrength";
+ return null;
+ }
+
+ private boolean satisfiedByNetCapabilities(NetworkCapabilities nc, boolean onlyImmutable) {
+ long networkCapabilities = this.mNetworkCapabilities;
+ if (onlyImmutable) {
+ networkCapabilities = networkCapabilities & ~MUTABLE_CAPABILITIES;
+ }
+ return ((nc.mNetworkCapabilities & networkCapabilities) == networkCapabilities);
}
/** @hide */
@@ -287,6 +334,11 @@
return (nc.mNetworkCapabilities == this.mNetworkCapabilities);
}
+ private boolean equalsNetCapabilitiesImmutable(NetworkCapabilities that) {
+ return ((this.mNetworkCapabilities & ~MUTABLE_CAPABILITIES) ==
+ (that.mNetworkCapabilities & ~MUTABLE_CAPABILITIES));
+ }
+
/**
* Removes the NET_CAPABILITY_NOT_RESTRICTED capability if all the capabilities it provides are
* typically provided by restricted networks.
@@ -555,26 +607,130 @@
}
/**
+ * Magic value that indicates no signal strength provided. A request specifying this value is
+ * always satisfied.
+ *
+ * @hide
+ */
+ public static final int SIGNAL_STRENGTH_UNSPECIFIED = Integer.MIN_VALUE;
+
+ /**
+ * Signal strength. This is a signed integer, and higher values indicate better signal.
+ * The exact units are bearer-dependent. For example, Wi-Fi uses RSSI.
+ */
+ private int mSignalStrength;
+
+ /**
+ * Sets the signal strength. This is a signed integer, with higher values indicating a stronger
+ * signal. The exact units are bearer-dependent. For example, Wi-Fi uses the same RSSI units
+ * reported by WifiManager.
+ * <p>
+ * Note that when used to register a network callback, this specifies the minimum acceptable
+ * signal strength. When received as the state of an existing network it specifies the current
+ * value. A value of code SIGNAL_STRENGTH_UNSPECIFIED} means no value when received and has no
+ * effect when requesting a callback.
+ *
+ * @param signalStrength the bearer-specific signal strength.
+ * @hide
+ */
+ public void setSignalStrength(int signalStrength) {
+ mSignalStrength = signalStrength;
+ }
+
+ /**
+ * Returns {@code true} if this object specifies a signal strength.
+ *
+ * @hide
+ */
+ public boolean hasSignalStrength() {
+ return mSignalStrength > SIGNAL_STRENGTH_UNSPECIFIED;
+ }
+
+ /**
+ * Retrieves the signal strength.
+ *
+ * @return The bearer-specific signal strength.
+ * @hide
+ */
+ public int getSignalStrength() {
+ return mSignalStrength;
+ }
+
+ private void combineSignalStrength(NetworkCapabilities nc) {
+ this.mSignalStrength = Math.max(this.mSignalStrength, nc.mSignalStrength);
+ }
+
+ private boolean satisfiedBySignalStrength(NetworkCapabilities nc) {
+ return this.mSignalStrength <= nc.mSignalStrength;
+ }
+
+ private boolean equalsSignalStrength(NetworkCapabilities nc) {
+ return this.mSignalStrength == nc.mSignalStrength;
+ }
+
+ /**
* Combine a set of Capabilities to this one. Useful for coming up with the complete set
- * {@hide}
+ * @hide
*/
public void combineCapabilities(NetworkCapabilities nc) {
combineNetCapabilities(nc);
combineTransportTypes(nc);
combineLinkBandwidths(nc);
combineSpecifiers(nc);
+ combineSignalStrength(nc);
}
/**
- * Check if our requirements are satisfied by the given Capabilities.
- * {@hide}
+ * Check if our requirements are satisfied by the given {@code NetworkCapabilities}.
+ *
+ * @param nc the {@code NetworkCapabilities} that may or may not satisfy our requirements.
+ * @param onlyImmutable if {@code true}, do not consider mutable requirements such as link
+ * bandwidth, signal strength, or validation / captive portal status.
+ *
+ * @hide
+ */
+ private boolean satisfiedByNetworkCapabilities(NetworkCapabilities nc, boolean onlyImmutable) {
+ return (nc != null &&
+ satisfiedByNetCapabilities(nc, onlyImmutable) &&
+ satisfiedByTransportTypes(nc) &&
+ (onlyImmutable || satisfiedByLinkBandwidths(nc)) &&
+ satisfiedBySpecifier(nc) &&
+ (onlyImmutable || satisfiedBySignalStrength(nc)));
+ }
+
+ /**
+ * Check if our requirements are satisfied by the given {@code NetworkCapabilities}.
+ *
+ * @param nc the {@code NetworkCapabilities} that may or may not satisfy our requirements.
+ *
+ * @hide
*/
public boolean satisfiedByNetworkCapabilities(NetworkCapabilities nc) {
- return (nc != null &&
- satisfiedByNetCapabilities(nc) &&
- satisfiedByTransportTypes(nc) &&
- satisfiedByLinkBandwidths(nc) &&
- satisfiedBySpecifier(nc));
+ return satisfiedByNetworkCapabilities(nc, false);
+ }
+
+ /**
+ * Check if our immutable requirements are satisfied by the given {@code NetworkCapabilities}.
+ *
+ * @param nc the {@code NetworkCapabilities} that may or may not satisfy our requirements.
+ *
+ * @hide
+ */
+ public boolean satisfiedByImmutableNetworkCapabilities(NetworkCapabilities nc) {
+ return satisfiedByNetworkCapabilities(nc, true);
+ }
+
+ /**
+ * Checks that our immutable capabilities are the same as those of the given
+ * {@code NetworkCapabilities}.
+ *
+ * @hide
+ */
+ public boolean equalImmutableCapabilities(NetworkCapabilities nc) {
+ if (nc == null) return false;
+ return (equalsNetCapabilitiesImmutable(nc) &&
+ equalsTransportTypes(nc) &&
+ equalsSpecifier(nc));
}
@Override
@@ -584,6 +740,7 @@
return (equalsNetCapabilities(that) &&
equalsTransportTypes(that) &&
equalsLinkBandwidths(that) &&
+ equalsSignalStrength(that) &&
equalsSpecifier(that));
}
@@ -595,7 +752,8 @@
((int)(mTransportTypes >> 32) * 7) +
(mLinkUpBandwidthKbps * 11) +
(mLinkDownBandwidthKbps * 13) +
- (TextUtils.isEmpty(mNetworkSpecifier) ? 0 : mNetworkSpecifier.hashCode() * 17));
+ (TextUtils.isEmpty(mNetworkSpecifier) ? 0 : mNetworkSpecifier.hashCode() * 17) +
+ (mSignalStrength * 19));
}
@Override
@@ -609,7 +767,9 @@
dest.writeInt(mLinkUpBandwidthKbps);
dest.writeInt(mLinkDownBandwidthKbps);
dest.writeString(mNetworkSpecifier);
+ dest.writeInt(mSignalStrength);
}
+
public static final Creator<NetworkCapabilities> CREATOR =
new Creator<NetworkCapabilities>() {
@Override
@@ -621,6 +781,7 @@
netCap.mLinkUpBandwidthKbps = in.readInt();
netCap.mLinkDownBandwidthKbps = in.readInt();
netCap.mNetworkSpecifier = in.readString();
+ netCap.mSignalStrength = in.readInt();
return netCap;
}
@Override
@@ -678,6 +839,8 @@
String specifier = (mNetworkSpecifier == null ?
"" : " Specifier: <" + mNetworkSpecifier + ">");
- return "[" + transports + capabilities + upBand + dnBand + specifier + "]";
+ String signalStrength = (hasSignalStrength() ? " SignalStrength: " + mSignalStrength : "");
+
+ return "[" + transports + capabilities + upBand + dnBand + specifier + signalStrength + "]";
}
}
diff --git a/core/java/android/net/NetworkFactory.java b/core/java/android/net/NetworkFactory.java
index 5f46c73..cab88b9 100644
--- a/core/java/android/net/NetworkFactory.java
+++ b/core/java/android/net/NetworkFactory.java
@@ -169,7 +169,8 @@
}
}
- private void handleAddRequest(NetworkRequest request, int score) {
+ @VisibleForTesting
+ protected void handleAddRequest(NetworkRequest request, int score) {
NetworkRequestInfo n = mNetworkRequests.get(request.requestId);
if (n == null) {
if (DBG) log("got request " + request + " with score " + score);
@@ -184,7 +185,8 @@
evalRequest(n);
}
- private void handleRemoveRequest(NetworkRequest request) {
+ @VisibleForTesting
+ protected void handleRemoveRequest(NetworkRequest request) {
NetworkRequestInfo n = mNetworkRequests.get(request.requestId);
if (n != null) {
mNetworkRequests.remove(request.requestId);
diff --git a/core/java/android/net/NetworkPolicyManager.java b/core/java/android/net/NetworkPolicyManager.java
index 3f40484..a83e722 100644
--- a/core/java/android/net/NetworkPolicyManager.java
+++ b/core/java/android/net/NetworkPolicyManager.java
@@ -50,12 +50,13 @@
public static final int POLICY_ALLOW_BACKGROUND_BATTERY_SAVE = 0x2;
/* RULE_* are not masks and they must be exclusive */
+ public static final int RULE_UNKNOWN = -1;
/** All network traffic should be allowed. */
- public static final int RULE_ALLOW_ALL = 0x0;
+ public static final int RULE_ALLOW_ALL = 0;
/** Reject traffic on metered networks. */
- public static final int RULE_REJECT_METERED = 0x1;
+ public static final int RULE_REJECT_METERED = 1;
/** Reject traffic on all networks. */
- public static final int RULE_REJECT_ALL = 0x2;
+ public static final int RULE_REJECT_ALL = 2;
public static final int FIREWALL_RULE_DEFAULT = 0;
public static final int FIREWALL_RULE_ALLOW = 1;
@@ -326,25 +327,4 @@
// nothing found above; we can apply policy to UID
return true;
}
-
- /** {@hide} */
- public static void dumpPolicy(PrintWriter fout, int policy) {
- fout.write("[");
- if ((policy & POLICY_REJECT_METERED_BACKGROUND) != 0) {
- fout.write("REJECT_METERED_BACKGROUND");
- }
- fout.write("]");
- }
-
- /** {@hide} */
- public static void dumpRules(PrintWriter fout, int rules) {
- fout.write("[");
- if ((rules & RULE_REJECT_METERED) != 0) {
- fout.write("REJECT_METERED");
- } else if ((rules & RULE_REJECT_ALL) != 0) {
- fout.write("REJECT_ALL");
- }
- fout.write("]");
- }
-
}
diff --git a/core/java/android/net/NetworkRequest.java b/core/java/android/net/NetworkRequest.java
index e184ec4..7da4818 100644
--- a/core/java/android/net/NetworkRequest.java
+++ b/core/java/android/net/NetworkRequest.java
@@ -191,6 +191,24 @@
mNetworkCapabilities.setNetworkSpecifier(networkSpecifier);
return this;
}
+
+ /**
+ * Sets the signal strength. This is a signed integer, with higher values indicating a
+ * stronger signal. The exact units are bearer-dependent. For example, Wi-Fi uses the same
+ * RSSI units reported by WifiManager.
+ * <p>
+ * Note that when used to register a network callback, this specifies the minimum acceptable
+ * signal strength. When received as the state of an existing network it specifies the
+ * current value. A value of {@code SIGNAL_STRENGTH_UNSPECIFIED} means no value when
+ * received and has no effect when requesting a callback.
+ *
+ * @param signalStrength the bearer-specific signal strength.
+ * @hide
+ */
+ public Builder setSignalStrength(int signalStrength) {
+ mNetworkCapabilities.setSignalStrength(signalStrength);
+ return this;
+ }
}
// implement the Parcelable interface
diff --git a/core/java/android/net/NetworkScorerAppManager.java b/core/java/android/net/NetworkScorerAppManager.java
index 29daf35..5880e5d 100644
--- a/core/java/android/net/NetworkScorerAppManager.java
+++ b/core/java/android/net/NetworkScorerAppManager.java
@@ -33,6 +33,7 @@
import java.util.ArrayList;
import java.util.Collection;
+import java.util.Collections;
import java.util.List;
/**
@@ -90,8 +91,13 @@
* @return the list of scorers, or the empty list if there are no valid scorers.
*/
public static Collection<NetworkScorerAppData> getAllValidScorers(Context context) {
- List<NetworkScorerAppData> scorers = new ArrayList<>();
+ // Network scorer apps can only run as the primary user so exit early if we're not the
+ // primary user.
+ if (UserHandle.getCallingUserId() != 0 /*USER_SYSTEM*/) {
+ return Collections.emptyList();
+ }
+ List<NetworkScorerAppData> scorers = new ArrayList<>();
PackageManager pm = context.getPackageManager();
// Only apps installed under the primary user of the device can be scorers.
List<ResolveInfo> receivers =
@@ -104,8 +110,9 @@
continue;
}
if (!permission.BROADCAST_NETWORK_PRIVILEGED.equals(receiverInfo.permission)) {
- // Receiver doesn't require the BROADCAST_NETWORK_PRIVILEGED permission, which means
- // anyone could trigger network scoring and flood the framework with score requests.
+ // Receiver doesn't require the BROADCAST_NETWORK_PRIVILEGED permission, which
+ // means anyone could trigger network scoring and flood the framework with score
+ // requests.
continue;
}
if (pm.checkPermission(permission.SCORE_NETWORKS, receiverInfo.packageName) !=
@@ -127,8 +134,8 @@
}
}
- // NOTE: loadLabel will attempt to load the receiver's label and fall back to the app
- // label if none is present.
+ // NOTE: loadLabel will attempt to load the receiver's label and fall back to the
+ // app label if none is present.
scorers.add(new NetworkScorerAppData(receiverInfo.packageName,
receiverInfo.applicationInfo.uid, receiverInfo.loadLabel(pm),
configurationActivityClassName));
diff --git a/core/java/android/net/NetworkTemplate.java b/core/java/android/net/NetworkTemplate.java
index 57eef83..b7a411e 100644
--- a/core/java/android/net/NetworkTemplate.java
+++ b/core/java/android/net/NetworkTemplate.java
@@ -288,7 +288,8 @@
} else {
final boolean matchesType = (sForceAllNetworkTypes
|| contains(DATA_USAGE_NETWORK_TYPES, ident.mType));
- return matchesType && ArrayUtils.contains(mMatchSubscriberIds, ident.mSubscriberId);
+ return matchesType && !ArrayUtils.isEmpty(mMatchSubscriberIds)
+ && ArrayUtils.contains(mMatchSubscriberIds, ident.mSubscriberId);
}
}
diff --git a/core/java/android/nfc/cardemulation/AidGroup.java b/core/java/android/nfc/cardemulation/AidGroup.java
index 4407c9d..78a9401 100644
--- a/core/java/android/nfc/cardemulation/AidGroup.java
+++ b/core/java/android/nfc/cardemulation/AidGroup.java
@@ -1,3 +1,19 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
package android.nfc.cardemulation;
import java.io.IOException;
diff --git a/core/java/android/nfc/cardemulation/HostApduService.java b/core/java/android/nfc/cardemulation/HostApduService.java
index ad34e61..a299479 100644
--- a/core/java/android/nfc/cardemulation/HostApduService.java
+++ b/core/java/android/nfc/cardemulation/HostApduService.java
@@ -1,3 +1,19 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
package android.nfc.cardemulation;
import android.annotation.SdkConstant;
diff --git a/core/java/android/nfc/cardemulation/OffHostApduService.java b/core/java/android/nfc/cardemulation/OffHostApduService.java
index 0d01762..6a8aeee 100644
--- a/core/java/android/nfc/cardemulation/OffHostApduService.java
+++ b/core/java/android/nfc/cardemulation/OffHostApduService.java
@@ -1,3 +1,19 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
package android.nfc.cardemulation;
import android.annotation.SdkConstant;
diff --git a/core/java/android/os/BatteryManager.java b/core/java/android/os/BatteryManager.java
index cccc4be..1f3e9a7 100644
--- a/core/java/android/os/BatteryManager.java
+++ b/core/java/android/os/BatteryManager.java
@@ -101,6 +101,13 @@
*/
public static final String EXTRA_INVALID_CHARGER = "invalid_charger";
+ /**
+ * Extra for {@link android.content.Intent#ACTION_BATTERY_CHANGED}:
+ * Int value set to the maximum charging current supported by the charger in micro amperes.
+ * {@hide}
+ */
+ public static final String EXTRA_MAX_CHARGING_CURRENT = "max_charging_current";
+
// values for "status" field in the ACTION_BATTERY_CHANGED Intent
public static final int BATTERY_STATUS_UNKNOWN = 1;
public static final int BATTERY_STATUS_CHARGING = 2;
diff --git a/core/java/android/os/BatteryProperties.java b/core/java/android/os/BatteryProperties.java
index 8f5cf8b..29e868c 100644
--- a/core/java/android/os/BatteryProperties.java
+++ b/core/java/android/os/BatteryProperties.java
@@ -22,6 +22,7 @@
public boolean chargerAcOnline;
public boolean chargerUsbOnline;
public boolean chargerWirelessOnline;
+ public int maxChargingCurrent;
public int batteryStatus;
public int batteryHealth;
public boolean batteryPresent;
@@ -37,6 +38,7 @@
chargerAcOnline = other.chargerAcOnline;
chargerUsbOnline = other.chargerUsbOnline;
chargerWirelessOnline = other.chargerWirelessOnline;
+ maxChargingCurrent = other.maxChargingCurrent;
batteryStatus = other.batteryStatus;
batteryHealth = other.batteryHealth;
batteryPresent = other.batteryPresent;
@@ -55,6 +57,7 @@
chargerAcOnline = p.readInt() == 1 ? true : false;
chargerUsbOnline = p.readInt() == 1 ? true : false;
chargerWirelessOnline = p.readInt() == 1 ? true : false;
+ maxChargingCurrent = p.readInt();
batteryStatus = p.readInt();
batteryHealth = p.readInt();
batteryPresent = p.readInt() == 1 ? true : false;
@@ -68,6 +71,7 @@
p.writeInt(chargerAcOnline ? 1 : 0);
p.writeInt(chargerUsbOnline ? 1 : 0);
p.writeInt(chargerWirelessOnline ? 1 : 0);
+ p.writeInt(maxChargingCurrent);
p.writeInt(batteryStatus);
p.writeInt(batteryHealth);
p.writeInt(batteryPresent ? 1 : 0);
diff --git a/core/java/android/os/BatteryStats.java b/core/java/android/os/BatteryStats.java
index 4ad9d6d..8e86a53 100644
--- a/core/java/android/os/BatteryStats.java
+++ b/core/java/android/os/BatteryStats.java
@@ -463,12 +463,15 @@
public abstract long getCpuPowerMaUs(int which);
/**
- * Returns the approximate cpu time (in milliseconds) spent at a certain CPU speed.
+ * Returns the approximate cpu time (in milliseconds) spent at a certain CPU speed for a
+ * given CPU cluster.
+ * @param cluster the index of the CPU cluster.
* @param step the index of the CPU speed. This is not the actual speed of the CPU.
* @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT.
- * @see BatteryStats#getCpuSpeedSteps()
+ * @see PowerProfile.getNumCpuClusters()
+ * @see PowerProfile.getNumSpeedStepsInCpuCluster(int)
*/
- public abstract long getTimeAtCpuSpeed(int step, int which);
+ public abstract long getTimeAtCpuSpeed(int cluster, int step, int which);
public static abstract class Sensor {
/*
@@ -2275,9 +2278,6 @@
public abstract Map<String, ? extends Timer> getKernelWakelockStats();
- /** Returns the number of different speeds that the CPU can run at */
- public abstract int getCpuSpeedSteps();
-
public abstract void writeToParcelWithoutUids(Parcel out, int flags);
private final static void formatTimeRaw(StringBuilder out, long seconds) {
diff --git a/core/java/android/os/Debug.java b/core/java/android/os/Debug.java
index 97b85e2..fdd34f5 100644
--- a/core/java/android/os/Debug.java
+++ b/core/java/android/os/Debug.java
@@ -471,7 +471,7 @@
* </tbody>
* </table>
*/
- public String getMemoryStat(String statName) {
+ public String getMemoryStat(String statName) {
switch(statName) {
case "summary.java-heap":
return Integer.toString(getSummaryJavaHeap());
@@ -1538,7 +1538,13 @@
/**
* Retrieves information about this processes memory usages. This information is broken down by
- * how much is in use by dalivk, the native heap, and everything else.
+ * how much is in use by dalvik, the native heap, and everything else.
+ *
+ * <p><b>Note:</b> this method directly retrieves memory information for the give process
+ * from low-level data available to it. It may not be able to retrieve information about
+ * some protected allocations, such as graphics. If you want to be sure you can see
+ * all information about allocations by the process, use instead
+ * {@link android.app.ActivityManager#getProcessMemoryInfo(int[])}.</p>
*/
public static native void getMemoryInfo(MemoryInfo memoryInfo);
diff --git a/core/java/android/os/Environment.java b/core/java/android/os/Environment.java
index 64d6da5..f346fe7 100644
--- a/core/java/android/os/Environment.java
+++ b/core/java/android/os/Environment.java
@@ -276,8 +276,8 @@
}
/**
- * Return the primary external storage directory. This directory may not
- * currently be accessible if it has been mounted by the user on their
+ * Return the primary shared/external storage directory. This directory may
+ * not currently be accessible if it has been mounted by the user on their
* computer, has been removed from the device, or some other problem has
* happened. You can determine its current state with
* {@link #getExternalStorageState()}.
@@ -291,12 +291,15 @@
* filesystem on a computer.</em>
* <p>
* On devices with multiple users (as described by {@link UserManager}),
- * each user has their own isolated external storage. Applications only have
- * access to the external storage for the user they're running as.
+ * each user has their own isolated shared storage. Applications only have
+ * access to the shared storage for the user they're running as.
* <p>
- * In devices with multiple "external" storage directories, this directory
- * represents the "primary" external storage that the user will interact
+ * In devices with multiple shared/external storage directories, this
+ * directory represents the primary storage that the user will interact
* with. Access to secondary storage is available through
+ * {@link Context#getExternalFilesDirs(String)},
+ * {@link Context#getExternalCacheDirs()}, and
+ * {@link Context#getExternalMediaDirs()}.
* <p>
* Applications should not directly use this top-level directory, in order
* to avoid polluting the user's root namespace. Any files that are private
@@ -315,8 +318,9 @@
* <p>
* Starting in {@link android.os.Build.VERSION_CODES#KITKAT}, if your
* application only needs to store internal data, consider using
- * {@link Context#getExternalFilesDir(String)} or
- * {@link Context#getExternalCacheDir()}, which require no permissions to
+ * {@link Context#getExternalFilesDir(String)},
+ * {@link Context#getExternalCacheDir()}, or
+ * {@link Context#getExternalMediaDirs()}, which require no permissions to
* read or write.
* <p>
* This path may change between platform versions, so applications should
@@ -325,8 +329,7 @@
* Here is an example of typical code to monitor the state of external
* storage:
* <p>
- * {@sample
- * development/samples/ApiDemos/src/com/example/android/apis/content/ExternalStorage.java
+ * {@sample development/samples/ApiDemos/src/com/example/android/apis/content/ExternalStorage.java
* monitor_storage}
*
* @see #getExternalStorageState()
@@ -446,32 +449,32 @@
public static String DIRECTORY_DOCUMENTS = "Documents";
/**
- * Get a top-level public external storage directory for placing files of
- * a particular type. This is where the user will typically place and
- * manage their own files, so you should be careful about what you put here
- * to ensure you don't erase their files or get in the way of their own
+ * Get a top-level shared/external storage directory for placing files of a
+ * particular type. This is where the user will typically place and manage
+ * their own files, so you should be careful about what you put here to
+ * ensure you don't erase their files or get in the way of their own
* organization.
- *
- * <p>On devices with multiple users (as described by {@link UserManager}),
- * each user has their own isolated external storage. Applications only
- * have access to the external storage for the user they're running as.</p>
- *
- * <p>Here is an example of typical code to manipulate a picture on
- * the public external storage:</p>
- *
+ * <p>
+ * On devices with multiple users (as described by {@link UserManager}),
+ * each user has their own isolated shared storage. Applications only have
+ * access to the shared storage for the user they're running as.
+ * </p>
+ * <p>
+ * Here is an example of typical code to manipulate a picture on the public
+ * shared storage:
+ * </p>
* {@sample development/samples/ApiDemos/src/com/example/android/apis/content/ExternalStorage.java
* public_picture}
*
- * @param type The type of storage directory to return. Should be one of
- * {@link #DIRECTORY_MUSIC}, {@link #DIRECTORY_PODCASTS},
- * {@link #DIRECTORY_RINGTONES}, {@link #DIRECTORY_ALARMS},
- * {@link #DIRECTORY_NOTIFICATIONS}, {@link #DIRECTORY_PICTURES},
- * {@link #DIRECTORY_MOVIES}, {@link #DIRECTORY_DOWNLOADS}, or
- * {@link #DIRECTORY_DCIM}. May not be null.
- *
- * @return Returns the File path for the directory. Note that this
- * directory may not yet exist, so you must make sure it exists before
- * using it such as with {@link File#mkdirs File.mkdirs()}.
+ * @param type The type of storage directory to return. Should be one of
+ * {@link #DIRECTORY_MUSIC}, {@link #DIRECTORY_PODCASTS},
+ * {@link #DIRECTORY_RINGTONES}, {@link #DIRECTORY_ALARMS},
+ * {@link #DIRECTORY_NOTIFICATIONS}, {@link #DIRECTORY_PICTURES},
+ * {@link #DIRECTORY_MOVIES}, {@link #DIRECTORY_DOWNLOADS}, or
+ * {@link #DIRECTORY_DCIM}. May not be null.
+ * @return Returns the File path for the directory. Note that this directory
+ * may not yet exist, so you must make sure it exists before using
+ * it such as with {@link File#mkdirs File.mkdirs()}.
*/
public static File getExternalStoragePublicDirectory(String type) {
throwIfUserRequired();
@@ -623,7 +626,7 @@
public static final String MEDIA_EJECTING = "ejecting";
/**
- * Returns the current state of the primary "external" storage device.
+ * Returns the current state of the primary shared/external storage media.
*
* @see #getExternalStorageDirectory()
* @return one of {@link #MEDIA_UNKNOWN}, {@link #MEDIA_REMOVED},
@@ -646,8 +649,8 @@
}
/**
- * Returns the current state of the storage device that provides the given
- * path.
+ * Returns the current state of the shared/external storage media at the
+ * given path.
*
* @return one of {@link #MEDIA_UNKNOWN}, {@link #MEDIA_REMOVED},
* {@link #MEDIA_UNMOUNTED}, {@link #MEDIA_CHECKING},
@@ -665,7 +668,8 @@
}
/**
- * Returns whether the primary "external" storage device is removable.
+ * Returns whether the primary shared/external storage media is physically
+ * removable.
*
* @return true if the storage device can be removed (such as an SD card),
* or false if the storage device is built in and cannot be
@@ -678,8 +682,8 @@
}
/**
- * Returns whether the storage device that provides the given path is
- * removable.
+ * Returns whether the shared/external storage media at the given path is
+ * physically removable.
*
* @return true if the storage device can be removed (such as an SD card),
* or false if the storage device is built in and cannot be
@@ -697,9 +701,15 @@
}
/**
- * Returns whether the primary "external" storage device is emulated. If
- * true, data stored on this device will be stored on a portion of the
- * internal storage system.
+ * Returns whether the primary shared/external storage media is emulated.
+ * <p>
+ * The contents of emulated storage devices are backed by a private user
+ * data partition, which means there is little benefit to apps storing data
+ * here instead of the private directories returned by
+ * {@link Context#getFilesDir()}, etc.
+ * <p>
+ * This returns true when emulated storage is backed by either internal
+ * storage or an adopted storage device.
*
* @see DevicePolicyManager#setStorageEncryption(android.content.ComponentName,
* boolean)
@@ -711,9 +721,16 @@
}
/**
- * Returns whether the storage device that provides the given path is
- * emulated. If true, data stored on this device will be stored on a portion
- * of the internal storage system.
+ * Returns whether the shared/external storage media at the given path is
+ * emulated.
+ * <p>
+ * The contents of emulated storage devices are backed by a private user
+ * data partition, which means there is little benefit to apps storing data
+ * here instead of the private directories returned by
+ * {@link Context#getFilesDir()}, etc.
+ * <p>
+ * This returns true when emulated storage is backed by either internal
+ * storage or an adopted storage device.
*
* @throws IllegalArgumentException if the path is not a valid storage
* device.
diff --git a/core/java/android/os/Parcel.java b/core/java/android/os/Parcel.java
index 1273772b..5852f5f 100644
--- a/core/java/android/os/Parcel.java
+++ b/core/java/android/os/Parcel.java
@@ -16,6 +16,7 @@
package android.os;
+import android.annotation.IntegerRes;
import android.text.TextUtils;
import android.util.ArrayMap;
import android.util.Log;
@@ -42,6 +43,8 @@
import java.util.Map;
import java.util.Set;
+import dalvik.system.VMRuntime;
+
/**
* Container for a message (data and object references) that can
* be sent through an IBinder. A Parcel can contain both flattened data
@@ -193,6 +196,7 @@
* indicating that we're responsible for its lifecycle.
*/
private boolean mOwnsNativeParcelObject;
+ private long mNativeSize;
private RuntimeException mStack;
@@ -244,7 +248,7 @@
private static native int nativeDataAvail(long nativePtr);
private static native int nativeDataPosition(long nativePtr);
private static native int nativeDataCapacity(long nativePtr);
- private static native void nativeSetDataSize(long nativePtr, int size);
+ private static native long nativeSetDataSize(long nativePtr, int size);
private static native void nativeSetDataPosition(long nativePtr, int pos);
private static native void nativeSetDataCapacity(long nativePtr, int size);
@@ -259,7 +263,7 @@
private static native void nativeWriteDouble(long nativePtr, double val);
private static native void nativeWriteString(long nativePtr, String val);
private static native void nativeWriteStrongBinder(long nativePtr, IBinder val);
- private static native void nativeWriteFileDescriptor(long nativePtr, FileDescriptor val);
+ private static native long nativeWriteFileDescriptor(long nativePtr, FileDescriptor val);
private static native byte[] nativeCreateByteArray(long nativePtr);
private static native byte[] nativeReadBlob(long nativePtr);
@@ -272,13 +276,13 @@
private static native FileDescriptor nativeReadFileDescriptor(long nativePtr);
private static native long nativeCreate();
- private static native void nativeFreeBuffer(long nativePtr);
+ private static native long nativeFreeBuffer(long nativePtr);
private static native void nativeDestroy(long nativePtr);
private static native byte[] nativeMarshall(long nativePtr);
- private static native void nativeUnmarshall(
+ private static native long nativeUnmarshall(
long nativePtr, byte[] data, int offset, int length);
- private static native void nativeAppendFrom(
+ private static native long nativeAppendFrom(
long thisNativePtr, long otherNativePtr, int offset, int length);
private static native boolean nativeHasFileDescriptors(long nativePtr);
private static native void nativeWriteInterfaceToken(long nativePtr, String interfaceName);
@@ -390,7 +394,7 @@
* @param size The new number of bytes in the Parcel.
*/
public final void setDataSize(int size) {
- nativeSetDataSize(mNativePtr, size);
+ updateNativeSize(nativeSetDataSize(mNativePtr, size));
}
/**
@@ -442,11 +446,11 @@
* Set the bytes in data to be the raw bytes of this Parcel.
*/
public final void unmarshall(byte[] data, int offset, int length) {
- nativeUnmarshall(mNativePtr, data, offset, length);
+ updateNativeSize(nativeUnmarshall(mNativePtr, data, offset, length));
}
public final void appendFrom(Parcel parcel, int offset, int length) {
- nativeAppendFrom(mNativePtr, parcel.mNativePtr, offset, length);
+ updateNativeSize(nativeAppendFrom(mNativePtr, parcel.mNativePtr, offset, length));
}
/**
@@ -599,7 +603,24 @@
* if {@link Parcelable#PARCELABLE_WRITE_RETURN_VALUE} is set.</p>
*/
public final void writeFileDescriptor(FileDescriptor val) {
- nativeWriteFileDescriptor(mNativePtr, val);
+ updateNativeSize(nativeWriteFileDescriptor(mNativePtr, val));
+ }
+
+ private void updateNativeSize(long newNativeSize) {
+ if (mOwnsNativeParcelObject) {
+ if (newNativeSize > Integer.MAX_VALUE) {
+ newNativeSize = Integer.MAX_VALUE;
+ }
+ if (newNativeSize != mNativeSize) {
+ int delta = (int) (newNativeSize - mNativeSize);
+ if (delta > 0) {
+ VMRuntime.getRuntime().registerNativeAllocation(delta);
+ } else {
+ VMRuntime.getRuntime().registerNativeFree(-delta);
+ }
+ mNativeSize = newNativeSize;
+ }
+ }
}
/**
@@ -2545,7 +2566,7 @@
private void freeBuffer() {
if (mOwnsNativeParcelObject) {
- nativeFreeBuffer(mNativePtr);
+ updateNativeSize(nativeFreeBuffer(mNativePtr));
}
}
@@ -2553,6 +2574,7 @@
if (mNativePtr != 0) {
if (mOwnsNativeParcelObject) {
nativeDestroy(mNativePtr);
+ updateNativeSize(0);
}
mNativePtr = 0;
}
diff --git a/core/java/android/os/PowerManagerInternal.java b/core/java/android/os/PowerManagerInternal.java
index e742f98..17bce30 100644
--- a/core/java/android/os/PowerManagerInternal.java
+++ b/core/java/android/os/PowerManagerInternal.java
@@ -53,6 +53,15 @@
*/
public static final int WAKEFULNESS_DOZING = 3;
+
+ /**
+ * Power hint: The user is interacting with the device. The corresponding data field must be
+ * the expected duration of the fling, or 0 if unknown.
+ *
+ * This must be kept in sync with the values in hardware/libhardware/include/hardware/power.h
+ */
+ public static final int POWER_HINT_INTERACTION = 2;
+
public static String wakefulnessToString(int wakefulness) {
switch (wakefulness) {
case WAKEFULNESS_ASLEEP:
@@ -142,4 +151,6 @@
public abstract void updateUidProcState(int uid, int procState);
public abstract void uidGone(int uid);
+
+ public abstract void powerHint(int hintId, int data);
}
diff --git a/core/java/android/os/storage/IMountService.java b/core/java/android/os/storage/IMountService.java
index fce09dd..9f71ce1 100644
--- a/core/java/android/os/storage/IMountService.java
+++ b/core/java/android/os/storage/IMountService.java
@@ -1180,6 +1180,37 @@
_data.recycle();
}
}
+
+ @Override
+ public void createNewUserDir(int userHandle, String path) throws RemoteException {
+ Parcel _data = Parcel.obtain();
+ Parcel _reply = Parcel.obtain();
+ try {
+ _data.writeInterfaceToken(DESCRIPTOR);
+ _data.writeInt(userHandle);
+ _data.writeString(path);
+ mRemote.transact(Stub.TRANSACTION_createNewUserDir, _data, _reply, 0);
+ _reply.readException();
+ } finally {
+ _reply.recycle();
+ _data.recycle();
+ }
+ }
+
+ @Override
+ public void deleteUserKey(int userHandle) throws RemoteException {
+ Parcel _data = Parcel.obtain();
+ Parcel _reply = Parcel.obtain();
+ try {
+ _data.writeInterfaceToken(DESCRIPTOR);
+ _data.writeInt(userHandle);
+ mRemote.transact(Stub.TRANSACTION_deleteUserKey, _data, _reply, 0);
+ _reply.readException();
+ } finally {
+ _reply.recycle();
+ _data.recycle();
+ }
+ }
}
private static final String DESCRIPTOR = "IMountService";
@@ -1295,6 +1326,9 @@
static final int TRANSACTION_benchmark = IBinder.FIRST_CALL_TRANSACTION + 59;
static final int TRANSACTION_setDebugFlags = IBinder.FIRST_CALL_TRANSACTION + 60;
+ static final int TRANSACTION_createNewUserDir = IBinder.FIRST_CALL_TRANSACTION + 62;
+ static final int TRANSACTION_deleteUserKey = IBinder.FIRST_CALL_TRANSACTION + 63;
+
/**
* Cast an IBinder object into an IMountService interface, generating a
* proxy if needed.
@@ -1850,6 +1884,21 @@
reply.writeNoException();
return true;
}
+ case TRANSACTION_createNewUserDir: {
+ data.enforceInterface(DESCRIPTOR);
+ int userHandle = data.readInt();
+ String path = data.readString();
+ createNewUserDir(userHandle, path);
+ reply.writeNoException();
+ return true;
+ }
+ case TRANSACTION_deleteUserKey: {
+ data.enforceInterface(DESCRIPTOR);
+ int userHandle = data.readInt();
+ deleteUserKey(userHandle);
+ reply.writeNoException();
+ return true;
+ }
}
return super.onTransact(code, data, reply, flags);
}
@@ -2159,4 +2208,19 @@
public String getPrimaryStorageUuid() throws RemoteException;
public void setPrimaryStorageUuid(String volumeUuid, IPackageMoveObserver callback)
throws RemoteException;
+
+ /**
+ * Creates the user data directory, possibly encrypted
+ * @param userHandle Handle of the user whose directory we are creating
+ * @param path Path at which to create the directory.
+ */
+ public void createNewUserDir(int userHandle, String path)
+ throws RemoteException;
+
+ /**
+ * Securely delete the user's encryption key
+ * @param userHandle Handle of the user whose key we are deleting
+ */
+ public void deleteUserKey(int userHandle)
+ throws RemoteException;
}
diff --git a/core/java/android/os/storage/StorageManager.java b/core/java/android/os/storage/StorageManager.java
index d1f3743..1d92453 100644
--- a/core/java/android/os/storage/StorageManager.java
+++ b/core/java/android/os/storage/StorageManager.java
@@ -960,6 +960,24 @@
}
/** {@hide} */
+ public void createNewUserDir(int userHandle, File path) {
+ try {
+ mMountService.createNewUserDir(userHandle, path.getAbsolutePath());
+ } catch (RemoteException e) {
+ throw e.rethrowAsRuntimeException();
+ }
+ }
+
+ /** {@hide} */
+ public void deleteUserKey(int userHandle) {
+ try {
+ mMountService.deleteUserKey(userHandle);
+ } catch (RemoteException e) {
+ throw e.rethrowAsRuntimeException();
+ }
+ }
+
+ /** {@hide} */
public static File maybeTranslateEmulatedPathToInternal(File path) {
final IMountService mountService = IMountService.Stub.asInterface(
ServiceManager.getService("mount"));
diff --git a/core/java/android/preference/SeekBarVolumizer.java b/core/java/android/preference/SeekBarVolumizer.java
index 979c828..2445bc2 100644
--- a/core/java/android/preference/SeekBarVolumizer.java
+++ b/core/java/android/preference/SeekBarVolumizer.java
@@ -383,6 +383,7 @@
final IntentFilter filter = new IntentFilter(AudioManager.VOLUME_CHANGED_ACTION);
filter.addAction(AudioManager.INTERNAL_RINGER_MODE_CHANGED_ACTION);
filter.addAction(NotificationManager.ACTION_INTERRUPTION_FILTER_CHANGED);
+ filter.addAction(AudioManager.STREAM_DEVICES_CHANGED_ACTION);
mContext.registerReceiver(this, filter);
} else {
mContext.unregisterReceiver(this);
@@ -395,13 +396,7 @@
if (AudioManager.VOLUME_CHANGED_ACTION.equals(action)) {
int streamType = intent.getIntExtra(AudioManager.EXTRA_VOLUME_STREAM_TYPE, -1);
int streamValue = intent.getIntExtra(AudioManager.EXTRA_VOLUME_STREAM_VALUE, -1);
- final boolean streamMatch = mNotificationOrRing ? isNotificationOrRing(streamType)
- : (streamType == mStreamType);
- if (mSeekBar != null && streamMatch && streamValue != -1) {
- final boolean muted = mAudioManager.isStreamMute(mStreamType)
- || streamValue == 0;
- mUiHandler.postUpdateSlider(streamValue, mLastAudibleStreamVolume, muted);
- }
+ updateVolumeSlider(streamType, streamValue);
} else if (AudioManager.INTERNAL_RINGER_MODE_CHANGED_ACTION.equals(action)) {
if (mNotificationOrRing) {
mRingerMode = mAudioManager.getRingerModeInternal();
@@ -409,10 +404,24 @@
if (mAffectedByRingerMode) {
updateSlider();
}
+ } else if (AudioManager.STREAM_DEVICES_CHANGED_ACTION.equals(action)) {
+ int streamType = intent.getIntExtra(AudioManager.EXTRA_VOLUME_STREAM_TYPE, -1);
+ int streamVolume = mAudioManager.getStreamVolume(streamType);
+ updateVolumeSlider(streamType, streamVolume);
} else if (NotificationManager.ACTION_INTERRUPTION_FILTER_CHANGED.equals(action)) {
mZenMode = mNotificationManager.getZenMode();
updateSlider();
}
}
+
+ private void updateVolumeSlider(int streamType, int streamValue) {
+ final boolean streamMatch = mNotificationOrRing ? isNotificationOrRing(streamType)
+ : (streamType == mStreamType);
+ if (mSeekBar != null && streamMatch && streamValue != -1) {
+ final boolean muted = mAudioManager.isStreamMute(mStreamType)
+ || streamValue == 0;
+ mUiHandler.postUpdateSlider(streamValue, mLastAudibleStreamVolume, muted);
+ }
+ }
}
}
diff --git a/core/java/android/provider/DocumentsContract.java b/core/java/android/provider/DocumentsContract.java
index c7ba607..f5221c6 100644
--- a/core/java/android/provider/DocumentsContract.java
+++ b/core/java/android/provider/DocumentsContract.java
@@ -130,6 +130,9 @@
*/
private static final int THUMBNAIL_BUFFER_SIZE = (int) (128 * KB_IN_BYTES);
+ /** {@hide} */
+ public static final String PACKAGE_DOCUMENTS_UI = "com.android.documentsui";
+
/**
* Constants related to a document, including {@link Cursor} column names
* and flags.
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index fe95864..14f8fdd 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -1434,25 +1434,6 @@
}
/**
- * An app can use this method to check if it is currently allowed to change the network
- * state. In order to be allowed to do so, an app must first declare either the
- * {@link android.Manifest.permission#CHANGE_NETWORK_STATE} or
- * {@link android.Manifest.permission#WRITE_SETTINGS} permission in its manifest. If it
- * is currently disallowed, it can prompt the user to grant it this capability through a
- * management UI by sending an Intent with action
- * {@link android.provider.Settings#ACTION_MANAGE_WRITE_SETTINGS}.
- *
- * @param context A context
- * @return true if the calling app can change the state of network, false otherwise.
- * @hide
- */
- public static boolean canChangeNetworkState(Context context) {
- int uid = Binder.getCallingUid();
- return Settings.isCallingPackageAllowedToChangeNetworkState(context, uid, Settings
- .getPackageNameForUid(context, uid), false);
- }
-
- /**
* System settings, containing miscellaneous system preferences. This
* table holds simple name/value pairs. There are convenience
* functions for accessing individual settings entries.
@@ -3283,7 +3264,6 @@
DOCK_SOUNDS_ENABLED, // moved to global
LOCKSCREEN_SOUNDS_ENABLED,
SHOW_WEB_SUGGESTIONS,
- NOTIFICATION_LIGHT_PULSE,
SIP_CALL_OPTIONS,
SIP_RECEIVE_CALLS,
POINTER_SPEED,
@@ -5712,6 +5692,22 @@
public static final String ASSISTANT = "assistant";
/**
+ * Whether the camera launch gesture should be disabled.
+ *
+ * @hide
+ */
+ public static final String CAMERA_GESTURE_DISABLED = "camera_gesture_disabled";
+
+ /**
+ * Whether the camera launch gesture to double tap the power button when the screen is off
+ * should be disabled.
+ *
+ * @hide
+ */
+ public static final String CAMERA_DOUBLE_TAP_POWER_GESTURE_DISABLED =
+ "camera_double_tap_power_gesture_disabled";
+
+ /**
* This are the settings to be backed up.
*
* NOTE: Settings are backed up and restored in the order they appear
@@ -5767,6 +5763,7 @@
MOUNT_UMS_NOTIFY_ENABLED,
SLEEP_TIMEOUT,
DOUBLE_TAP_TO_WAKE,
+ CAMERA_GESTURE_DISABLED,
};
/**
@@ -6033,6 +6030,18 @@
public static final String AIRPLANE_MODE_TOGGLEABLE_RADIOS = "airplane_mode_toggleable_radios";
/**
+ * A semi-colon separated list of Bluetooth interoperability workarounds.
+ * Each entry is a partial Bluetooth device address string and an integer representing
+ * the feature to be disabled, separated by a comma. The integer must correspond
+ * to a interoperability feature as defined in "interop.h" in /system/bt.
+ * <p>
+ * Example: <br/>
+ * "00:11:22,0;01:02:03:04,2"
+ * @hide
+ */
+ public static final String BLUETOOTH_INTEROPERABILITY_LIST = "bluetooth_interoperability_list";
+
+ /**
* The policy for deciding when Wi-Fi should go to sleep (which will in
* turn switch to using the mobile data as an Internet connection).
* <p>
@@ -7277,10 +7286,12 @@
* The following keys are supported:
*
* <pre>
- * idle_duration (long)
+ * idle_duration2 (long)
* wallclock_threshold (long)
* parole_interval (long)
* parole_duration (long)
+ *
+ * idle_duration (long) // This is deprecated and used to circumvent b/26355386.
* </pre>
*
* <p>
@@ -8327,7 +8338,7 @@
* write/modify system settings, as the condition differs for pre-M, M+, and
* privileged/preinstalled apps. If the provided uid does not match the
* callingPackage, a negative result will be returned. The caller is expected to have
- * either WRITE_SETTINGS or CHANGE_NETWORK_STATE permission declared.
+ * the WRITE_SETTINGS permission declared.
*
* Note: if the check is successful, the operation of this app will be updated to the
* current time.
@@ -8343,31 +8354,22 @@
/**
* Performs a strict and comprehensive check of whether a calling package is allowed to
* change the state of network, as the condition differs for pre-M, M+, and
- * privileged/preinstalled apps. If the provided uid does not match the
- * callingPackage, a negative result will be returned. The caller is expected to have
- * either of CHANGE_NETWORK_STATE or WRITE_SETTINGS permission declared.
- * @hide
- */
- public static boolean isCallingPackageAllowedToChangeNetworkState(Context context, int uid,
- String callingPackage, boolean throwException) {
- return isCallingPackageAllowedToPerformAppOpsProtectedOperation(context, uid,
- callingPackage, throwException, AppOpsManager.OP_WRITE_SETTINGS,
- PM_CHANGE_NETWORK_STATE, false);
- }
-
- /**
- * Performs a strict and comprehensive check of whether a calling package is allowed to
- * change the state of network, as the condition differs for pre-M, M+, and
- * privileged/preinstalled apps. If the provided uid does not match the
- * callingPackage, a negative result will be returned. The caller is expected to have
- * either CHANGE_NETWORK_STATE or WRITE_SETTINGS permission declared.
+ * privileged/preinstalled apps. The caller is expected to have either the
+ * CHANGE_NETWORK_STATE or the WRITE_SETTINGS permission declared. Either of these
+ * permissions allow changing network state; WRITE_SETTINGS is a runtime permission and
+ * can be revoked, but (except in M, excluding M MRs), CHANGE_NETWORK_STATE is a normal
+ * permission and cannot be revoked. See http://b/23597341
*
- * Note: if the check is successful, the operation of this app will be updated to the
- * current time.
+ * Note: if the check succeeds because the application holds WRITE_SETTINGS, the operation
+ * of this app will be updated to the current time.
* @hide
*/
public static boolean checkAndNoteChangeNetworkStateOperation(Context context, int uid,
String callingPackage, boolean throwException) {
+ if (context.checkCallingOrSelfPermission(android.Manifest.permission.CHANGE_NETWORK_STATE)
+ == PackageManager.PERMISSION_GRANTED) {
+ return true;
+ }
return isCallingPackageAllowedToPerformAppOpsProtectedOperation(context, uid,
callingPackage, throwException, AppOpsManager.OP_WRITE_SETTINGS,
PM_CHANGE_NETWORK_STATE, true);
diff --git a/core/java/android/service/notification/ZenModeConfig.java b/core/java/android/service/notification/ZenModeConfig.java
index db19f7a..8763496 100644
--- a/core/java/android/service/notification/ZenModeConfig.java
+++ b/core/java/android/service/notification/ZenModeConfig.java
@@ -41,6 +41,7 @@
import java.io.IOException;
import java.util.ArrayList;
import java.util.Calendar;
+import java.util.GregorianCalendar;
import java.util.Locale;
import java.util.Objects;
import java.util.UUID;
@@ -68,6 +69,7 @@
public static final int[] MINUTE_BUCKETS = generateMinuteBuckets();
private static final int SECONDS_MS = 1000;
private static final int MINUTES_MS = 60 * SECONDS_MS;
+ private static final int DAY_MINUTES = 24 * 60;
private static final int ZERO_VALUE_MS = 10 * SECONDS_MS;
private static final boolean DEFAULT_ALLOW_CALLS = true;
@@ -652,40 +654,68 @@
boolean shortVersion) {
final long now = System.currentTimeMillis();
final long millis = minutesFromNow == 0 ? ZERO_VALUE_MS : minutesFromNow * MINUTES_MS;
- return toTimeCondition(context, now + millis, minutesFromNow, now, userHandle,
- shortVersion);
+ return toTimeCondition(context, now + millis, minutesFromNow, userHandle, shortVersion);
}
- public static Condition toTimeCondition(Context context, long time, int minutes, long now,
+ public static Condition toTimeCondition(Context context, long time, int minutes,
int userHandle, boolean shortVersion) {
- final int num, summaryResId, line1ResId;
+ final int num;
+ String summary, line1, line2;
+ final CharSequence formattedTime = getFormattedTime(context, time, userHandle);
+ final Resources res = context.getResources();
if (minutes < 60) {
// display as minutes
num = minutes;
- summaryResId = shortVersion ? R.plurals.zen_mode_duration_minutes_summary_short
+ int summaryResId = shortVersion ? R.plurals.zen_mode_duration_minutes_summary_short
: R.plurals.zen_mode_duration_minutes_summary;
- line1ResId = shortVersion ? R.plurals.zen_mode_duration_minutes_short
+ summary = res.getQuantityString(summaryResId, num, num, formattedTime);
+ int line1ResId = shortVersion ? R.plurals.zen_mode_duration_minutes_short
: R.plurals.zen_mode_duration_minutes;
- } else {
+ line1 = res.getQuantityString(line1ResId, num, num, formattedTime);
+ line2 = res.getString(R.string.zen_mode_until, formattedTime);
+ } else if (minutes < DAY_MINUTES) {
// display as hours
num = Math.round(minutes / 60f);
- summaryResId = shortVersion ? R.plurals.zen_mode_duration_hours_summary_short
+ int summaryResId = shortVersion ? R.plurals.zen_mode_duration_hours_summary_short
: R.plurals.zen_mode_duration_hours_summary;
- line1ResId = shortVersion ? R.plurals.zen_mode_duration_hours_short
+ summary = res.getQuantityString(summaryResId, num, num, formattedTime);
+ int line1ResId = shortVersion ? R.plurals.zen_mode_duration_hours_short
: R.plurals.zen_mode_duration_hours;
+ line1 = res.getQuantityString(line1ResId, num, num, formattedTime);
+ line2 = res.getString(R.string.zen_mode_until, formattedTime);
+ } else {
+ // display as day/time
+ summary = line1 = line2 = res.getString(R.string.zen_mode_until, formattedTime);
}
- final String skeleton = DateFormat.is24HourFormat(context, userHandle) ? "Hm" : "hma";
- final String pattern = DateFormat.getBestDateTimePattern(Locale.getDefault(), skeleton);
- final CharSequence formattedTime = DateFormat.format(pattern, time);
- final Resources res = context.getResources();
- final String summary = res.getQuantityString(summaryResId, num, num, formattedTime);
- final String line1 = res.getQuantityString(line1ResId, num, num, formattedTime);
- final String line2 = res.getString(R.string.zen_mode_until, formattedTime);
final Uri id = toCountdownConditionId(time);
return new Condition(id, summary, line1, line2, 0, Condition.STATE_TRUE,
Condition.FLAG_RELEVANT_NOW);
}
+ public static Condition toNextAlarmCondition(Context context, long now, long alarm,
+ int userHandle) {
+ final CharSequence formattedTime = getFormattedTime(context, alarm, userHandle);
+ final Resources res = context.getResources();
+ final String line1 = res.getString(R.string.zen_mode_alarm, formattedTime);
+ final Uri id = toCountdownConditionId(alarm);
+ return new Condition(id, "", line1, "", 0, Condition.STATE_TRUE,
+ Condition.FLAG_RELEVANT_NOW);
+ }
+
+ private static CharSequence getFormattedTime(Context context, long time, int userHandle) {
+ String skeleton = "EEE " + (DateFormat.is24HourFormat(context, userHandle) ? "Hm" : "hma");
+ GregorianCalendar now = new GregorianCalendar();
+ GregorianCalendar endTime = new GregorianCalendar();
+ endTime.setTimeInMillis(time);
+ if (now.get(Calendar.YEAR) == endTime.get(Calendar.YEAR)
+ && now.get(Calendar.MONTH) == endTime.get(Calendar.MONTH)
+ && now.get(Calendar.DATE) == endTime.get(Calendar.DATE)) {
+ skeleton = DateFormat.is24HourFormat(context, userHandle) ? "Hm" : "hma";
+ }
+ final String pattern = DateFormat.getBestDateTimePattern(Locale.getDefault(), skeleton);
+ return DateFormat.format(pattern, time);
+ }
+
// ==== Built-in system conditions ====
public static final String SYSTEM_AUTHORITY = "android";
@@ -883,11 +913,6 @@
return UUID.randomUUID().toString().replace("-", "");
}
- public static String getConditionLine1(Context context, ZenModeConfig config,
- int userHandle, boolean shortVersion) {
- return getConditionLine(context, config, userHandle, true /*useLine1*/, shortVersion);
- }
-
public static String getConditionSummary(Context context, ZenModeConfig config,
int userHandle, boolean shortVersion) {
return getConditionLine(context, config, userHandle, false /*useLine1*/, shortVersion);
@@ -906,8 +931,8 @@
if (time > 0) {
final long now = System.currentTimeMillis();
final long span = time - now;
- c = toTimeCondition(context,
- time, Math.round(span / (float) MINUTES_MS), now, userHandle, shortVersion);
+ c = toTimeCondition(context, time, Math.round(span / (float) MINUTES_MS),
+ userHandle, shortVersion);
}
final String rt = c == null ? "" : useLine1 ? c.line1 : c.summary;
return TextUtils.isEmpty(rt) ? "" : rt;
diff --git a/core/java/android/text/Hyphenator.java b/core/java/android/text/Hyphenator.java
index 10a994a..f2b6041 100644
--- a/core/java/android/text/Hyphenator.java
+++ b/core/java/android/text/Hyphenator.java
@@ -16,15 +16,17 @@
package android.text;
-import com.android.internal.annotations.GuardedBy;
-
import android.annotation.Nullable;
import android.util.Log;
-import libcore.io.IoUtils;
+import com.android.internal.annotations.GuardedBy;
import java.io.File;
import java.io.IOException;
+import java.io.RandomAccessFile;
+import java.nio.ByteBuffer;
+import java.nio.MappedByteBuffer;
+import java.nio.channels.FileChannel;
import java.util.HashMap;
import java.util.Locale;
@@ -45,19 +47,29 @@
@GuardedBy("sLock")
final static HashMap<Locale, Hyphenator> sMap = new HashMap<Locale, Hyphenator>();
- final static Hyphenator sEmptyHyphenator = new Hyphenator(StaticLayout.nLoadHyphenator(""));
+ final static Hyphenator sEmptyHyphenator =
+ new Hyphenator(StaticLayout.nLoadHyphenator(null, 0), null);
final private long mNativePtr;
- private Hyphenator(long nativePtr) {
+ // We retain a reference to the buffer to keep the memory mapping valid
+ @SuppressWarnings("unused")
+ final private ByteBuffer mBuffer;
+
+ private Hyphenator(long nativePtr, ByteBuffer b) {
mNativePtr = nativePtr;
+ mBuffer = b;
}
- public static long get(@Nullable Locale locale) {
+ public long getNativePtr() {
+ return mNativePtr;
+ }
+
+ public static Hyphenator get(@Nullable Locale locale) {
synchronized (sLock) {
Hyphenator result = sMap.get(locale);
if (result != null) {
- return result.mNativePtr;
+ return result;
}
// TODO: Convert this a proper locale-fallback system
@@ -67,7 +79,7 @@
result = sMap.get(languageOnlyLocale);
if (result != null) {
sMap.put(locale, result);
- return result.mNativePtr;
+ return result;
}
// Fall back to script-only, if available
@@ -80,22 +92,28 @@
result = sMap.get(scriptOnlyLocale);
if (result != null) {
sMap.put(locale, result);
- return result.mNativePtr;
+ return result;
}
}
sMap.put(locale, sEmptyHyphenator); // To remember we found nothing.
}
- return sEmptyHyphenator.mNativePtr;
+ return sEmptyHyphenator;
}
private static Hyphenator loadHyphenator(String languageTag) {
- String patternFilename = "hyph-"+languageTag.toLowerCase(Locale.US)+".pat.txt";
+ String patternFilename = "hyph-" + languageTag.toLowerCase(Locale.US) + ".hyb";
File patternFile = new File(getSystemHyphenatorLocation(), patternFilename);
try {
- String patternData = IoUtils.readFileAsString(patternFile.getAbsolutePath());
- long nativePtr = StaticLayout.nLoadHyphenator(patternData);
- return new Hyphenator(nativePtr);
+ RandomAccessFile f = new RandomAccessFile(patternFile, "r");
+ try {
+ FileChannel fc = f.getChannel();
+ MappedByteBuffer buf = fc.map(FileChannel.MapMode.READ_ONLY, 0, fc.size());
+ long nativePtr = StaticLayout.nLoadHyphenator(buf, 0);
+ return new Hyphenator(nativePtr, buf);
+ } finally {
+ f.close();
+ }
} catch (IOException e) {
Log.e(TAG, "error loading hyphenation " + patternFile, e);
return null;
@@ -148,7 +166,7 @@
sMap.put(null, null);
// TODO: replace this with a discovery-based method that looks into /system/usr/hyphen-data
- String[] availableLanguages = {"en-US", "eu", "hu", "hy", "nb", "nn", "sa", "und-Ethi"};
+ String[] availableLanguages = {"en-US", "eu", "hu", "hy", "nb", "nn", "und-Ethi"};
for (int i = 0; i < availableLanguages.length; i++) {
String languageTag = availableLanguages[i];
Hyphenator h = loadHyphenator(languageTag);
diff --git a/core/java/android/text/StaticLayout.java b/core/java/android/text/StaticLayout.java
index 3b0def2..fdc6cb1 100644
--- a/core/java/android/text/StaticLayout.java
+++ b/core/java/android/text/StaticLayout.java
@@ -29,6 +29,7 @@
import com.android.internal.util.ArrayUtils;
import com.android.internal.util.GrowingArrayUtils;
+import java.nio.ByteBuffer;
import java.util.Arrays;
import java.util.Locale;
@@ -341,7 +342,8 @@
private void setLocale(Locale locale) {
if (!locale.equals(mLocale)) {
- nSetLocale(mNativePtr, locale.toLanguageTag(), Hyphenator.get(locale));
+ nSetLocale(mNativePtr, locale.toLanguageTag(),
+ Hyphenator.get(locale).getNativePtr());
mLocale = locale;
}
}
@@ -625,7 +627,9 @@
chooseHt = getParagraphSpans(spanned, paraStart, paraEnd, LineHeightSpan.class);
- if (chooseHt.length != 0) {
+ if (chooseHt.length == 0) {
+ chooseHt = null; // So that out() would not assume it has any contents
+ } else {
if (chooseHtv == null ||
chooseHtv.length < chooseHt.length) {
chooseHtv = ArrayUtils.newUnpaddedIntArray(chooseHt.length);
@@ -808,7 +812,7 @@
v = out(source, here, endPos,
fmAscent, fmDescent, fmTop, fmBottom,
- v, spacingmult, spacingadd, chooseHt,chooseHtv, fm, flags[breakIndex],
+ v, spacingmult, spacingadd, chooseHt, chooseHtv, fm, flags[breakIndex],
needMultiply, chdirs, dir, easy, bufEnd, includepad, trackpad,
chs, widths, paraStart, ellipsize, ellipsizedWidth,
lineWidths[breakIndex], paint, moreChars);
@@ -1243,7 +1247,7 @@
private static native void nFreeBuilder(long nativePtr);
private static native void nFinishBuilder(long nativePtr);
- /* package */ static native long nLoadHyphenator(String patternData);
+ /* package */ static native long nLoadHyphenator(ByteBuffer buf, int offset);
private static native void nSetLocale(long nativePtr, String locale, long nativeHyphenator);
diff --git a/core/java/android/transition/ChangeBounds.java b/core/java/android/transition/ChangeBounds.java
index c82587b..6d1d893 100644
--- a/core/java/android/transition/ChangeBounds.java
+++ b/core/java/android/transition/ChangeBounds.java
@@ -432,23 +432,24 @@
return anim;
}
} else {
- int startX = (Integer) startValues.values.get(PROPNAME_WINDOW_X);
- int startY = (Integer) startValues.values.get(PROPNAME_WINDOW_Y);
- int endX = (Integer) endValues.values.get(PROPNAME_WINDOW_X);
- int endY = (Integer) endValues.values.get(PROPNAME_WINDOW_Y);
+ sceneRoot.getLocationInWindow(tempLocation);
+ int startX = (Integer) startValues.values.get(PROPNAME_WINDOW_X) - tempLocation[0];
+ int startY = (Integer) startValues.values.get(PROPNAME_WINDOW_Y) - tempLocation[1];
+ int endX = (Integer) endValues.values.get(PROPNAME_WINDOW_X) - tempLocation[0];
+ int endY = (Integer) endValues.values.get(PROPNAME_WINDOW_Y) - tempLocation[1];
// TODO: also handle size changes: check bounds and animate size changes
if (startX != endX || startY != endY) {
- sceneRoot.getLocationInWindow(tempLocation);
- Bitmap bitmap = Bitmap.createBitmap(view.getWidth(), view.getHeight(),
- Bitmap.Config.ARGB_8888);
+ final int width = view.getWidth();
+ final int height = view.getHeight();
+ Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
view.draw(canvas);
final BitmapDrawable drawable = new BitmapDrawable(bitmap);
+ drawable.setBounds(startX, startY, startX + width, startY + height);
final float transitionAlpha = view.getTransitionAlpha();
view.setTransitionAlpha(0);
sceneRoot.getOverlay().add(drawable);
- Path topLeftPath = getPathMotion().getPath(startX - tempLocation[0],
- startY - tempLocation[1], endX - tempLocation[0], endY - tempLocation[1]);
+ Path topLeftPath = getPathMotion().getPath(startX, startY, endX, endY);
PropertyValuesHolder origin = PropertyValuesHolder.ofObject(
DRAWABLE_ORIGIN_PROPERTY, null, topLeftPath);
ObjectAnimator anim = ObjectAnimator.ofPropertyValuesHolder(drawable, origin);
diff --git a/core/java/android/view/Display.java b/core/java/android/view/Display.java
index 35c4192..1269ad9 100644
--- a/core/java/android/view/Display.java
+++ b/core/java/android/view/Display.java
@@ -16,7 +16,10 @@
package android.view;
+import android.annotation.RequiresPermission;
+import android.content.Context;
import android.content.res.CompatibilityInfo;
+import android.content.res.Resources;
import android.graphics.PixelFormat;
import android.graphics.Point;
import android.graphics.Rect;
@@ -30,6 +33,8 @@
import java.util.Arrays;
+import static android.Manifest.permission.CONFIGURE_DISPLAY_COLOR_TRANSFORM;
+
/**
* Provides information about the size and density of a logical display.
* <p>
@@ -679,6 +684,49 @@
}
/**
+ * Request the display applies a color transform.
+ * @hide
+ */
+ @RequiresPermission(CONFIGURE_DISPLAY_COLOR_TRANSFORM)
+ public void requestColorTransform(ColorTransform colorTransform) {
+ mGlobal.requestColorTransform(mDisplayId, colorTransform.getId());
+ }
+
+ /**
+ * Returns the active color transform of this display
+ * @hide
+ */
+ public ColorTransform getColorTransform() {
+ synchronized (this) {
+ updateDisplayInfoLocked();
+ return mDisplayInfo.getColorTransform();
+ }
+ }
+
+ /**
+ * Returns the default color transform of this display
+ * @hide
+ */
+ public ColorTransform getDefaultColorTransform() {
+ synchronized (this) {
+ updateDisplayInfoLocked();
+ return mDisplayInfo.getDefaultColorTransform();
+ }
+ }
+
+ /**
+ * Gets the supported color transforms of this device.
+ * @hide
+ */
+ public ColorTransform[] getSupportedColorTransforms() {
+ synchronized (this) {
+ updateDisplayInfoLocked();
+ ColorTransform[] transforms = mDisplayInfo.supportedColorTransforms;
+ return Arrays.copyOf(transforms, transforms.length);
+ }
+ }
+
+ /**
* Gets the app VSYNC offset, in nanoseconds. This is a positive value indicating
* the phase offset of the VSYNC events provided by Choreographer relative to the
* display refresh. For example, if Choreographer reports that the refresh occurred
@@ -1054,4 +1102,89 @@
}
};
}
+
+ /**
+ * A color transform supported by a given display.
+ *
+ * @see Display#getSupportedColorTransforms()
+ * @hide
+ */
+ public static final class ColorTransform implements Parcelable {
+ public static final ColorTransform[] EMPTY_ARRAY = new ColorTransform[0];
+
+ private final int mId;
+ private final int mColorTransform;
+
+ public ColorTransform(int id, int colorTransform) {
+ mId = id;
+ mColorTransform = colorTransform;
+ }
+
+ public int getId() {
+ return mId;
+ }
+
+ public int getColorTransform() {
+ return mColorTransform;
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ if (this == other) {
+ return true;
+ }
+ if (!(other instanceof ColorTransform)) {
+ return false;
+ }
+ ColorTransform that = (ColorTransform) other;
+ return mId == that.mId
+ && mColorTransform == that.mColorTransform;
+ }
+
+ @Override
+ public int hashCode() {
+ int hash = 1;
+ hash = hash * 17 + mId;
+ hash = hash * 17 + mColorTransform;
+ return hash;
+ }
+
+ @Override
+ public String toString() {
+ return new StringBuilder("{")
+ .append("id=").append(mId)
+ .append(", colorTransform=").append(mColorTransform)
+ .append("}")
+ .toString();
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ private ColorTransform(Parcel in) {
+ this(in.readInt(), in.readInt());
+ }
+
+ @Override
+ public void writeToParcel(Parcel out, int parcelableFlags) {
+ out.writeInt(mId);
+ out.writeInt(mColorTransform);
+ }
+
+ @SuppressWarnings("hiding")
+ public static final Parcelable.Creator<ColorTransform> CREATOR
+ = new Parcelable.Creator<ColorTransform>() {
+ @Override
+ public ColorTransform createFromParcel(Parcel in) {
+ return new ColorTransform(in);
+ }
+
+ @Override
+ public ColorTransform[] newArray(int size) {
+ return new ColorTransform[size];
+ }
+ };
+ }
}
diff --git a/core/java/android/view/DisplayInfo.java b/core/java/android/view/DisplayInfo.java
index cf17990..ee76274 100644
--- a/core/java/android/view/DisplayInfo.java
+++ b/core/java/android/view/DisplayInfo.java
@@ -169,6 +169,15 @@
*/
public Display.Mode[] supportedModes = Display.Mode.EMPTY_ARRAY;
+ /** The active color transform. */
+ public int colorTransformId;
+
+ /** The default color transform. */
+ public int defaultColorTransformId;
+
+ /** The list of supported color transforms */
+ public Display.ColorTransform[] supportedColorTransforms = Display.ColorTransform.EMPTY_ARRAY;
+
/**
* The logical display density which is the basis for density-independent
* pixels.
@@ -279,6 +288,8 @@
&& rotation == other.rotation
&& modeId == other.modeId
&& defaultModeId == other.defaultModeId
+ && colorTransformId == other.colorTransformId
+ && defaultColorTransformId == other.defaultColorTransformId
&& logicalDensityDpi == other.logicalDensityDpi
&& physicalXDpi == other.physicalXDpi
&& physicalYDpi == other.physicalYDpi
@@ -317,6 +328,10 @@
modeId = other.modeId;
defaultModeId = other.defaultModeId;
supportedModes = Arrays.copyOf(other.supportedModes, other.supportedModes.length);
+ colorTransformId = other.colorTransformId;
+ defaultColorTransformId = other.defaultColorTransformId;
+ supportedColorTransforms = Arrays.copyOf(
+ other.supportedColorTransforms, other.supportedColorTransforms.length);
logicalDensityDpi = other.logicalDensityDpi;
physicalXDpi = other.physicalXDpi;
physicalYDpi = other.physicalYDpi;
@@ -353,6 +368,13 @@
for (int i = 0; i < nModes; i++) {
supportedModes[i] = Display.Mode.CREATOR.createFromParcel(source);
}
+ colorTransformId = source.readInt();
+ defaultColorTransformId = source.readInt();
+ int nColorTransforms = source.readInt();
+ supportedColorTransforms = new Display.ColorTransform[nColorTransforms];
+ for (int i = 0; i < nColorTransforms; i++) {
+ supportedColorTransforms[i] = Display.ColorTransform.CREATOR.createFromParcel(source);
+ }
logicalDensityDpi = source.readInt();
physicalXDpi = source.readFloat();
physicalYDpi = source.readFloat();
@@ -390,6 +412,12 @@
for (int i = 0; i < supportedModes.length; i++) {
supportedModes[i].writeToParcel(dest, flags);
}
+ dest.writeInt(colorTransformId);
+ dest.writeInt(defaultColorTransformId);
+ dest.writeInt(supportedColorTransforms.length);
+ for (int i = 0; i < supportedColorTransforms.length; i++) {
+ supportedColorTransforms[i].writeToParcel(dest, flags);
+ }
dest.writeInt(logicalDensityDpi);
dest.writeFloat(physicalXDpi);
dest.writeFloat(physicalYDpi);
@@ -461,6 +489,24 @@
return result;
}
+ public Display.ColorTransform getColorTransform() {
+ return findColorTransform(colorTransformId);
+ }
+
+ public Display.ColorTransform getDefaultColorTransform() {
+ return findColorTransform(defaultColorTransformId);
+ }
+
+ private Display.ColorTransform findColorTransform(int colorTransformId) {
+ for (int i = 0; i < supportedColorTransforms.length; i++) {
+ Display.ColorTransform colorTransform = supportedColorTransforms[i];
+ if (colorTransform.getId() == colorTransformId) {
+ return colorTransform;
+ }
+ }
+ throw new IllegalStateException("Unable to locate color transform: " + colorTransformId);
+ }
+
public void getAppMetrics(DisplayMetrics outMetrics) {
getAppMetrics(outMetrics, CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO, null);
}
@@ -562,6 +608,12 @@
sb.append(defaultModeId);
sb.append(", modes ");
sb.append(Arrays.toString(supportedModes));
+ sb.append(", colorTransformId ");
+ sb.append(colorTransformId);
+ sb.append(", defaultColorTransformId ");
+ sb.append(defaultColorTransformId);
+ sb.append(", supportedColorTransforms ");
+ sb.append(Arrays.toString(supportedColorTransforms));
sb.append(", rotation ");
sb.append(rotation);
sb.append(", density ");
diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java
index 5970c3f..bcf9b2c 100644
--- a/core/java/android/view/SurfaceControl.java
+++ b/core/java/android/view/SurfaceControl.java
@@ -484,6 +484,7 @@
public boolean secure;
public long appVsyncOffsetNanos;
public long presentationDeadlineNanos;
+ public int colorTransform;
public PhysicalDisplayInfo() {
}
@@ -507,7 +508,8 @@
&& yDpi == other.yDpi
&& secure == other.secure
&& appVsyncOffsetNanos == other.appVsyncOffsetNanos
- && presentationDeadlineNanos == other.presentationDeadlineNanos;
+ && presentationDeadlineNanos == other.presentationDeadlineNanos
+ && colorTransform == other.colorTransform;
}
@Override
@@ -525,6 +527,7 @@
secure = other.secure;
appVsyncOffsetNanos = other.appVsyncOffsetNanos;
presentationDeadlineNanos = other.presentationDeadlineNanos;
+ colorTransform = other.colorTransform;
}
// For debugging purposes
@@ -533,7 +536,8 @@
return "PhysicalDisplayInfo{" + width + " x " + height + ", " + refreshRate + " fps, "
+ "density " + density + ", " + xDpi + " x " + yDpi + " dpi, secure " + secure
+ ", appVsyncOffset " + appVsyncOffsetNanos
- + ", bufferDeadline " + presentationDeadlineNanos + "}";
+ + ", bufferDeadline " + presentationDeadlineNanos
+ + ", colorTransform " + colorTransform + "}";
}
}
diff --git a/core/java/android/view/SurfaceView.java b/core/java/android/view/SurfaceView.java
index 7d48a9a..db68c29 100644
--- a/core/java/android/view/SurfaceView.java
+++ b/core/java/android/view/SurfaceView.java
@@ -447,10 +447,11 @@
final boolean formatChanged = mFormat != mRequestedFormat;
final boolean sizeChanged = mWidth != myWidth || mHeight != myHeight;
final boolean visibleChanged = mVisible != mRequestedVisible;
+ final boolean layoutSizeChanged = getWidth() != mLayout.width || getHeight() != mLayout.height;
if (force || creating || formatChanged || sizeChanged || visibleChanged
|| mLeft != mLocation[0] || mTop != mLocation[1]
- || mUpdateWindowNeeded || mReportDrawNeeded || redrawNeeded) {
+ || mUpdateWindowNeeded || mReportDrawNeeded || redrawNeeded || layoutSizeChanged) {
if (DEBUG) Log.i(TAG, "Changes: creating=" + creating
+ " format=" + formatChanged + " size=" + sizeChanged
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 43c578f..dea004e 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -2355,7 +2355,13 @@
* 1 PFLAG3_APPLYING_INSETS
* 1 PFLAG3_FITTING_SYSTEM_WINDOWS
* 1 PFLAG3_NESTED_SCROLLING_ENABLED
- * 1 PFLAG3_ASSIST_BLOCKED
+ * 1 PFLAG3_SCROLL_INDICATOR_TOP
+ * 1 PFLAG3_SCROLL_INDICATOR_BOTTOM
+ * 1 PFLAG3_SCROLL_INDICATOR_LEFT
+ * 1 PFLAG3_SCROLL_INDICATOR_RIGHT
+ * 1 PFLAG3_SCROLL_INDICATOR_START
+ * 1 PFLAG3_SCROLL_INDICATOR_END
+ * 1 PFLAG3_ASSIST_BLOCKED
* |-------|-------|-------|-------|
*/
@@ -2549,7 +2555,7 @@
* <p>Indicates that we are allowing {@link ViewStructure} to traverse
* into this view.<p>
*/
- static final int PFLAG3_ASSIST_BLOCKED = 0x100;
+ static final int PFLAG3_ASSIST_BLOCKED = 0x4000;
/**
* Always allow a user to over-scroll this view, provided it is a
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 6e93a30..42402eb 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -6621,6 +6621,19 @@
return false;
}
+ /**
+ * Force the window to report its next draw.
+ * <p>
+ * This method is only supposed to be used to speed up the interaction from SystemUI and window
+ * manager when waiting for the first frame to be drawn when turning on the screen. DO NOT USE
+ * unless you fully understand this interaction.
+ * @hide
+ */
+ public void setReportNextDraw() {
+ mReportNextDraw = true;
+ invalidate();
+ }
+
void changeCanvasOpacity(boolean opaque) {
Log.d(TAG, "changeCanvasOpacity: opaque=" + opaque);
if (mAttachInfo.mHardwareRenderer != null) {
diff --git a/core/java/android/view/Window.java b/core/java/android/view/Window.java
index 07984e9..c222a82 100644
--- a/core/java/android/view/Window.java
+++ b/core/java/android/view/Window.java
@@ -578,7 +578,7 @@
void adjustLayoutParamsForSubWindow(WindowManager.LayoutParams wp) {
CharSequence curTitle = wp.getTitle();
if (wp.type >= WindowManager.LayoutParams.FIRST_SUB_WINDOW &&
- wp.type <= WindowManager.LayoutParams.LAST_SUB_WINDOW) {
+ wp.type <= WindowManager.LayoutParams.LAST_SUB_WINDOW) {
if (wp.token == null) {
View decor = peekDecorView();
if (decor != null) {
@@ -588,25 +588,38 @@
if (curTitle == null || curTitle.length() == 0) {
String title;
if (wp.type == WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA) {
- title="Media";
+ title = "Media";
} else if (wp.type == WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA_OVERLAY) {
- title="MediaOvr";
+ title = "MediaOvr";
} else if (wp.type == WindowManager.LayoutParams.TYPE_APPLICATION_PANEL) {
- title="Panel";
+ title = "Panel";
} else if (wp.type == WindowManager.LayoutParams.TYPE_APPLICATION_SUB_PANEL) {
- title="SubPanel";
+ title = "SubPanel";
} else if (wp.type == WindowManager.LayoutParams.TYPE_APPLICATION_ABOVE_SUB_PANEL) {
- title="AboveSubPanel";
+ title = "AboveSubPanel";
} else if (wp.type == WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG) {
- title="AtchDlg";
+ title = "AtchDlg";
} else {
- title=Integer.toString(wp.type);
+ title = Integer.toString(wp.type);
}
if (mAppName != null) {
title += ":" + mAppName;
}
wp.setTitle(title);
}
+ } else if (wp.type >= WindowManager.LayoutParams.FIRST_SYSTEM_WINDOW &&
+ wp.type <= WindowManager.LayoutParams.LAST_SYSTEM_WINDOW) {
+ // We don't set the app token to this system window because the life cycles should be
+ // independent. If an app creates a system window and then the app goes to the stopped
+ // state, the system window should not be affected (can still show and receive input
+ // events).
+ if (curTitle == null || curTitle.length() == 0) {
+ String title = "Sys" + Integer.toString(wp.type);
+ if (mAppName != null) {
+ title += ":" + mAppName;
+ }
+ wp.setTitle(title);
+ }
} else {
if (wp.token == null) {
wp.token = mContainer == null ? mAppToken : mContainer.mAppToken;
diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java
index ed858e7..6e9a418 100644
--- a/core/java/android/widget/AbsListView.java
+++ b/core/java/android/widget/AbsListView.java
@@ -2395,6 +2395,7 @@
lp.itemId = mAdapter.getItemId(position);
}
lp.viewType = mAdapter.getItemViewType(position);
+ lp.isEnabled = mAdapter.isEnabled(position);
if (lp != vlp) {
child.setLayoutParams(lp);
}
@@ -2416,19 +2417,33 @@
}
final int position = getPositionForView(host);
- final ListAdapter adapter = getAdapter();
-
- if ((position == INVALID_POSITION) || (adapter == null)) {
+ if (position == INVALID_POSITION || mAdapter == null) {
// Cannot perform actions on invalid items.
return false;
}
- if (!isEnabled() || !adapter.isEnabled(position)) {
- // Cannot perform actions on disabled items.
+ if (position >= mAdapter.getCount()) {
+ // The position is no longer valid, likely due to a data set
+ // change. We could fail here for all data set changes, since
+ // there is a chance that the data bound to the view may no
+ // longer exist at the same position within the adapter, but
+ // it's more consistent with the standard touch interaction to
+ // click at whatever may have moved into that position.
return false;
}
- final long id = getItemIdAtPosition(position);
+ final boolean isItemEnabled;
+ final ViewGroup.LayoutParams lp = host.getLayoutParams();
+ if (lp instanceof AbsListView.LayoutParams) {
+ isItemEnabled = ((AbsListView.LayoutParams) lp).isEnabled;
+ } else {
+ isItemEnabled = false;
+ }
+
+ if (!isEnabled() || !isItemEnabled) {
+ // Cannot perform actions on disabled items.
+ return false;
+ }
switch (action) {
case AccessibilityNodeInfo.ACTION_CLEAR_SELECTION: {
@@ -2445,11 +2460,13 @@
} return false;
case AccessibilityNodeInfo.ACTION_CLICK: {
if (isClickable()) {
+ final long id = getItemIdAtPosition(position);
return performItemClick(host, position, id);
}
} return false;
case AccessibilityNodeInfo.ACTION_LONG_CLICK: {
if (isLongClickable()) {
+ final long id = getItemIdAtPosition(position);
return performLongPress(host, position, id);
}
} return false;
@@ -2469,13 +2486,20 @@
*/
public void onInitializeAccessibilityNodeInfoForItem(
View view, int position, AccessibilityNodeInfo info) {
- final ListAdapter adapter = getAdapter();
- if (position == INVALID_POSITION || adapter == null) {
+ if (position == INVALID_POSITION) {
// The item doesn't exist, so there's not much we can do here.
return;
}
- if (!isEnabled() || !adapter.isEnabled(position)) {
+ final boolean isItemEnabled;
+ final ViewGroup.LayoutParams lp = view.getLayoutParams();
+ if (lp instanceof AbsListView.LayoutParams) {
+ isItemEnabled = ((AbsListView.LayoutParams) lp).isEnabled;
+ } else {
+ isItemEnabled = false;
+ }
+
+ if (!isEnabled() || !isItemEnabled) {
info.setEnabled(false);
return;
}
@@ -6315,6 +6339,9 @@
*/
long itemId = -1;
+ /** Whether the adapter considers the item enabled. */
+ boolean isEnabled;
+
public LayoutParams(Context c, AttributeSet attrs) {
super(c, attrs);
}
@@ -6340,6 +6367,7 @@
encoder.addProperty("list:viewType", viewType);
encoder.addProperty("list:recycledHeaderFooter", recycledHeaderFooter);
encoder.addProperty("list:forceAdd", forceAdd);
+ encoder.addProperty("list:isEnabled", isEnabled);
}
}
diff --git a/core/java/android/widget/AdapterView.java b/core/java/android/widget/AdapterView.java
index 0cc1b25..2cfefba 100644
--- a/core/java/android/widget/AdapterView.java
+++ b/core/java/android/widget/AdapterView.java
@@ -600,13 +600,20 @@
}
/**
- * Get the position within the adapter's data set for the view, where view is a an adapter item
- * or a descendant of an adapter item.
+ * Returns the position within the adapter's data set for the view, where
+ * view is a an adapter item or a descendant of an adapter item.
+ * <p>
+ * <strong>Note:</strong> The result of this method only reflects the
+ * position of the data bound to <var>view</var> during the most recent
+ * layout pass. If the adapter's data set has changed without a subsequent
+ * layout pass, the position returned by this method may not match the
+ * current position of the data within the adapter.
*
- * @param view an adapter item, or a descendant of an adapter item. This must be visible in this
- * AdapterView at the time of the call.
- * @return the position within the adapter's data set of the view, or {@link #INVALID_POSITION}
- * if the view does not correspond to a list item (or it is not currently visible).
+ * @param view an adapter item, or a descendant of an adapter item. This
+ * must be visible in this AdapterView at the time of the call.
+ * @return the position within the adapter's data set of the view, or
+ * {@link #INVALID_POSITION} if the view does not correspond to a
+ * list item (or it is not currently visible)
*/
public int getPositionForView(View view) {
View listItem = view;
diff --git a/core/java/android/widget/Editor.java b/core/java/android/widget/Editor.java
index 5b042c6..13c1937 100644
--- a/core/java/android/widget/Editor.java
+++ b/core/java/android/widget/Editor.java
@@ -16,12 +16,6 @@
package android.widget;
-import java.text.BreakIterator;
-import java.util.Arrays;
-import java.util.Comparator;
-import java.util.HashMap;
-import java.util.List;
-
import android.R;
import android.annotation.Nullable;
import android.app.PendingIntent;
@@ -112,6 +106,12 @@
import com.android.internal.util.Preconditions;
import com.android.internal.widget.EditableInputConnection;
+import java.text.BreakIterator;
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.List;
+
/**
* Helper class used by TextView to handle editable text views.
@@ -1004,8 +1004,7 @@
}
if (!handled && mTextActionMode != null) {
- // TODO: Fix dragging in extracted mode.
- if (touchPositionIsInSelection() && !mTextView.isInExtractedMode()) {
+ if (touchPositionIsInSelection()) {
// Start a drag
final int start = mTextView.getSelectionStart();
final int end = mTextView.getSelectionEnd();
@@ -4254,10 +4253,14 @@
positionAtCursorOffset(offset, false);
}
+ /**
+ * @param offset Cursor offset. Must be in [-1, length].
+ * @param parentScrolled If the parent has been scrolled or not.
+ */
@Override
protected void positionAtCursorOffset(int offset, boolean parentScrolled) {
super.positionAtCursorOffset(offset, parentScrolled);
- mInWord = !getWordIteratorWithText().isBoundary(offset);
+ mInWord = (offset != -1) && !getWordIteratorWithText().isBoundary(offset);
}
@Override
@@ -4490,10 +4493,14 @@
positionAtCursorOffset(offset, false);
}
+ /**
+ * @param offset Cursor offset. Must be in [-1, length].
+ * @param parentScrolled If the parent has been scrolled or not.
+ */
@Override
protected void positionAtCursorOffset(int offset, boolean parentScrolled) {
super.positionAtCursorOffset(offset, parentScrolled);
- mInWord = !getWordIteratorWithText().isBoundary(offset);
+ mInWord = (offset != -1) && !getWordIteratorWithText().isBoundary(offset);
}
@Override
@@ -4860,9 +4867,8 @@
mEndHandle.showAtLocation(endOffset);
// No longer the first dragging motion, reset.
- if (!(mTextView.isInExtractedMode())) {
- startSelectionActionMode();
- }
+ startSelectionActionMode();
+
mDragAcceleratorActive = false;
mStartOffset = -1;
mSwitchedLines = false;
diff --git a/core/java/android/widget/GridView.java b/core/java/android/widget/GridView.java
index f994d4a..607e955 100644
--- a/core/java/android/widget/GridView.java
+++ b/core/java/android/widget/GridView.java
@@ -1070,6 +1070,7 @@
child.setLayoutParams(p);
}
p.viewType = mAdapter.getItemViewType(0);
+ p.isEnabled = mAdapter.isEnabled(0);
p.forceAdd = true;
int childHeightSpec = getChildMeasureSpec(
@@ -1480,6 +1481,7 @@
p = (AbsListView.LayoutParams) generateDefaultLayoutParams();
}
p.viewType = mAdapter.getItemViewType(position);
+ p.isEnabled = mAdapter.isEnabled(position);
if (recycled && !p.forceAdd) {
attachViewToParent(child, where, p);
diff --git a/core/java/android/widget/ImageView.java b/core/java/android/widget/ImageView.java
index ddbaa9d..cc6ab65 100644
--- a/core/java/android/widget/ImageView.java
+++ b/core/java/android/widget/ImageView.java
@@ -234,6 +234,8 @@
if (w != mDrawableWidth || h != mDrawableHeight) {
mDrawableWidth = w;
mDrawableHeight = h;
+ // updates the matrix, which is dependent on the bounds
+ configureBounds();
}
}
/* we invalidate the whole view in this case because it's very
diff --git a/core/java/android/widget/ListView.java b/core/java/android/widget/ListView.java
index c5632ec9..00d017f 100644
--- a/core/java/android/widget/ListView.java
+++ b/core/java/android/widget/ListView.java
@@ -1200,6 +1200,7 @@
child.setLayoutParams(p);
}
p.viewType = mAdapter.getItemViewType(position);
+ p.isEnabled = mAdapter.isEnabled(position);
p.forceAdd = true;
final int childWidthSpec = ViewGroup.getChildMeasureSpec(widthMeasureSpec,
@@ -1913,6 +1914,7 @@
p = (AbsListView.LayoutParams) generateDefaultLayoutParams();
}
p.viewType = mAdapter.getItemViewType(position);
+ p.isEnabled = mAdapter.isEnabled(position);
if ((recycled && !p.forceAdd) || (p.recycledHeaderFooter
&& p.viewType == AdapterView.ITEM_VIEW_TYPE_HEADER_OR_FOOTER)) {
diff --git a/core/java/android/widget/RelativeLayout.java b/core/java/android/widget/RelativeLayout.java
index 4dfa7db..abcd614 100644
--- a/core/java/android/widget/RelativeLayout.java
+++ b/core/java/android/widget/RelativeLayout.java
@@ -704,7 +704,7 @@
}
final int heightMode;
- if (params.width == LayoutParams.MATCH_PARENT) {
+ if (params.height == LayoutParams.MATCH_PARENT) {
heightMode = MeasureSpec.EXACTLY;
} else {
heightMode = MeasureSpec.AT_MOST;
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index a1462c4..0c4b60b 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -16,6 +16,8 @@
package android.widget;
+import static android.os.Build.VERSION_CODES.JELLY_BEAN_MR1;
+
import android.R;
import android.annotation.ColorInt;
import android.annotation.DrawableRes;
@@ -115,14 +117,14 @@
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
-import android.view.ViewParent;
-import android.view.ViewStructure;
import android.view.ViewConfiguration;
import android.view.ViewDebug;
import android.view.ViewGroup.LayoutParams;
-import android.view.ViewRootImpl;
-import android.view.ViewTreeObserver;
import android.view.ViewHierarchyEncoder;
+import android.view.ViewParent;
+import android.view.ViewRootImpl;
+import android.view.ViewStructure;
+import android.view.ViewTreeObserver;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityManager;
import android.view.accessibility.AccessibilityNodeInfo;
@@ -149,8 +151,6 @@
import java.util.ArrayList;
import java.util.Locale;
-import static android.os.Build.VERSION_CODES.JELLY_BEAN_MR1;
-
/**
* Displays text to the user and optionally allows them to edit it. A TextView
* is a complete text editor, however the basic class is configured to not
@@ -1474,7 +1474,12 @@
}
}
}
+ } else if (mText instanceof Spannable) {
+ // Reset the selection.
+ stopTextActionMode();
+ Selection.setSelection((Spannable) mText, getSelectionStart(), getSelectionEnd());
}
+
if (mEditor.hasSelectionController()) {
mEditor.startSelectionActionMode();
}
@@ -5243,14 +5248,6 @@
mEditor.mCreatedWithASelection = false;
}
- // Phone specific code (there is no ExtractEditText on tablets).
- // ExtractEditText does not call onFocus when it is displayed, and mHasSelectionOnFocus can
- // not be set. Do the test here instead.
- if (isInExtractedMode() && hasSelection() && mEditor != null
- && mEditor.mTextActionMode == null && isShown() && hasWindowFocus()) {
- mEditor.startSelectionActionMode();
- }
-
unregisterForPreDraw();
return true;
diff --git a/core/java/com/android/internal/app/ChooserActivity.java b/core/java/com/android/internal/app/ChooserActivity.java
index 16190d0..e137f94 100644
--- a/core/java/com/android/internal/app/ChooserActivity.java
+++ b/core/java/com/android/internal/app/ChooserActivity.java
@@ -16,6 +16,8 @@
package com.android.internal.app;
+import android.animation.ObjectAnimator;
+import android.annotation.NonNull;
import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
@@ -29,6 +31,7 @@
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.ResolveInfo;
import android.database.DataSetObserver;
+import android.graphics.Color;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.Icon;
import android.os.Bundle;
@@ -40,18 +43,24 @@
import android.os.ResultReceiver;
import android.os.UserHandle;
import android.os.UserManager;
+import android.provider.DocumentsContract;
import android.service.chooser.ChooserTarget;
import android.service.chooser.ChooserTargetService;
import android.service.chooser.IChooserTargetResult;
import android.service.chooser.IChooserTargetService;
import android.text.TextUtils;
+import android.util.FloatProperty;
import android.util.Log;
import android.util.Slog;
import android.view.LayoutInflater;
import android.view.View;
+import android.view.View.MeasureSpec;
import android.view.View.OnClickListener;
import android.view.View.OnLongClickListener;
import android.view.ViewGroup;
+import android.view.ViewGroup.LayoutParams;
+import android.view.animation.AnimationUtils;
+import android.view.animation.Interpolator;
import android.widget.AbsListView;
import android.widget.BaseAdapter;
import android.widget.ListView;
@@ -79,6 +88,7 @@
private Intent mReferrerFillInIntent;
private ChooserListAdapter mChooserListAdapter;
+ private ChooserRowAdapter mChooserRowAdapter;
private final List<ChooserTargetServiceConnection> mServiceConnections = new ArrayList<>();
@@ -104,6 +114,7 @@
sri.resultTargets);
}
unbindService(sri.connection);
+ sri.connection.destroy();
mServiceConnections.remove(sri.connection);
if (mServiceConnections.isEmpty()) {
mChooserHandler.removeMessages(CHOOSER_TARGET_SERVICE_WATCHDOG_TIMEOUT);
@@ -208,6 +219,8 @@
mRefinementResultReceiver.destroy();
mRefinementResultReceiver = null;
}
+ unbindRemainingServices();
+ mChooserHandler.removeMessages(CHOOSER_TARGET_SERVICE_RESULT);
}
@Override
@@ -249,7 +262,9 @@
boolean alwaysUseOption) {
final ListView listView = adapterView instanceof ListView ? (ListView) adapterView : null;
mChooserListAdapter = (ChooserListAdapter) adapter;
- adapterView.setAdapter(new ChooserRowAdapter(mChooserListAdapter));
+ mChooserRowAdapter = new ChooserRowAdapter(mChooserListAdapter);
+ mChooserRowAdapter.registerDataSetObserver(new OffsetDataSetObserver(adapterView));
+ adapterView.setAdapter(mChooserRowAdapter);
if (listView != null) {
listView.setItemsCanFocus(true);
}
@@ -265,6 +280,24 @@
return true;
}
+ @Override
+ boolean shouldAutoLaunchSingleChoice(TargetInfo target) {
+ final Intent intent = target.getResolvedIntent();
+ final ResolveInfo resolve = target.getResolveInfo();
+
+ // When GET_CONTENT is handled by the DocumentsUI system component,
+ // we're okay automatically launching it, since it offers it's own
+ // intent disambiguation UI.
+ if (intent != null && Intent.ACTION_GET_CONTENT.equals(intent.getAction())
+ && resolve != null && resolve.priority > 0
+ && resolve.activityInfo != null && DocumentsContract.PACKAGE_DOCUMENTS_UI
+ .equals(resolve.activityInfo.packageName)) {
+ return true;
+ }
+
+ return false;
+ }
+
private void modifyTargetIntent(Intent in) {
final String action = in.getAction();
if (Intent.ACTION_SEND.equals(action) ||
@@ -340,6 +373,11 @@
int targetsToQuery = 0;
for (int i = 0, N = adapter.getDisplayResolveInfoCount(); i < N; i++) {
final DisplayResolveInfo dri = adapter.getDisplayResolveInfo(i);
+ if (adapter.getScore(dri) == 0) {
+ // A score of 0 means the app hasn't been used in some time;
+ // don't query it as it's not likely to be relevant.
+ continue;
+ }
final ActivityInfo ai = dri.getResolveInfo().activityInfo;
final Bundle md = ai.metaData;
final String serviceName = md != null ? convertServiceName(ai.packageName,
@@ -371,7 +409,8 @@
continue;
}
- final ChooserTargetServiceConnection conn = new ChooserTargetServiceConnection(dri);
+ final ChooserTargetServiceConnection conn =
+ new ChooserTargetServiceConnection(this, dri);
if (bindServiceAsUser(serviceIntent, conn, BIND_AUTO_CREATE | BIND_NOT_FOREGROUND,
UserHandle.CURRENT)) {
if (DEBUG) {
@@ -425,6 +464,7 @@
final ChooserTargetServiceConnection conn = mServiceConnections.get(i);
if (DEBUG) Log.d(TAG, "unbinding " + conn);
unbindService(conn);
+ conn.destroy();
}
mServiceConnections.clear();
mChooserHandler.removeMessages(CHOOSER_TARGET_SERVICE_WATCHDOG_TIMEOUT);
@@ -649,7 +689,8 @@
@Override
public CharSequence getExtendedInfo() {
- return mSourceInfo != null ? mSourceInfo.getExtendedInfo() : null;
+ // ChooserTargets have badge icons, so we won't show the extended info to disambiguate.
+ return null;
}
@Override
@@ -742,9 +783,8 @@
@Override
public boolean showsExtendedInfo(TargetInfo info) {
- // Reserve space to show extended info if any one of the items in the adapter has
- // extended info. This keeps grid item sizes uniform.
- return hasExtendedInfo();
+ // We have badges so we don't need this text shown.
+ return false;
}
@Override
@@ -897,7 +937,63 @@
@Override
public int compare(ChooserTarget lhs, ChooserTarget rhs) {
// Descending order
- return (int) Math.signum(lhs.getScore() - rhs.getScore());
+ return (int) Math.signum(rhs.getScore() - lhs.getScore());
+ }
+ }
+
+ static class RowScale {
+ private static final int DURATION = 400;
+
+ float mScale;
+ ChooserRowAdapter mAdapter;
+ private final ObjectAnimator mAnimator;
+
+ public static final FloatProperty<RowScale> PROPERTY =
+ new FloatProperty<RowScale>("scale") {
+ @Override
+ public void setValue(RowScale object, float value) {
+ object.mScale = value;
+ object.mAdapter.notifyDataSetChanged();
+ }
+
+ @Override
+ public Float get(RowScale object) {
+ return object.mScale;
+ }
+ };
+
+ public RowScale(@NonNull ChooserRowAdapter adapter, float from, float to) {
+ mAdapter = adapter;
+ mScale = from;
+ if (from == to) {
+ mAnimator = null;
+ return;
+ }
+
+ mAnimator = ObjectAnimator.ofFloat(this, PROPERTY, from, to).setDuration(DURATION);
+ }
+
+ public RowScale setInterpolator(Interpolator interpolator) {
+ if (mAnimator != null) {
+ mAnimator.setInterpolator(interpolator);
+ }
+ return this;
+ }
+
+ public float get() {
+ return mScale;
+ }
+
+ public void startAnimation() {
+ if (mAnimator != null) {
+ mAnimator.start();
+ }
+ }
+
+ public void cancelAnimation() {
+ if (mAnimator != null) {
+ mAnimator.cancel();
+ }
}
}
@@ -905,15 +1001,51 @@
private ChooserListAdapter mChooserListAdapter;
private final LayoutInflater mLayoutInflater;
private final int mColumnCount = 4;
+ private RowScale[] mServiceTargetScale;
+ private final Interpolator mInterpolator;
public ChooserRowAdapter(ChooserListAdapter wrappedAdapter) {
mChooserListAdapter = wrappedAdapter;
mLayoutInflater = LayoutInflater.from(ChooserActivity.this);
+ mInterpolator = AnimationUtils.loadInterpolator(ChooserActivity.this,
+ android.R.interpolator.decelerate_quint);
+
wrappedAdapter.registerDataSetObserver(new DataSetObserver() {
@Override
public void onChanged() {
super.onChanged();
+ final int rcount = getServiceTargetRowCount();
+ if (mServiceTargetScale == null
+ || mServiceTargetScale.length != rcount) {
+ RowScale[] old = mServiceTargetScale;
+ int oldRCount = old != null ? old.length : 0;
+ mServiceTargetScale = new RowScale[rcount];
+ if (old != null && rcount > 0) {
+ System.arraycopy(old, 0, mServiceTargetScale, 0,
+ Math.min(old.length, rcount));
+ }
+
+ for (int i = rcount; i < oldRCount; i++) {
+ old[i].cancelAnimation();
+ }
+
+ for (int i = oldRCount; i < rcount; i++) {
+ final RowScale rs = new RowScale(ChooserRowAdapter.this, 0.f, 1.f)
+ .setInterpolator(mInterpolator);
+ mServiceTargetScale[i] = rs;
+ }
+
+ // Start the animations in a separate loop.
+ // The process of starting animations will result in
+ // binding views to set up initial values, and we must
+ // have ALL of the new RowScale objects created above before
+ // we get started.
+ for (int i = oldRCount; i < rcount; i++) {
+ mServiceTargetScale[i].startAnimation();
+ }
+ }
+
notifyDataSetChanged();
}
@@ -921,19 +1053,43 @@
public void onInvalidated() {
super.onInvalidated();
notifyDataSetInvalidated();
+ if (mServiceTargetScale != null) {
+ for (RowScale rs : mServiceTargetScale) {
+ rs.cancelAnimation();
+ }
+ }
}
});
}
+ private float getRowScale(int rowPosition) {
+ final int start = getCallerTargetRowCount();
+ final int end = start + getServiceTargetRowCount();
+ if (rowPosition >= start && rowPosition < end) {
+ return mServiceTargetScale[rowPosition - start].get();
+ }
+ return 1.f;
+ }
+
@Override
public int getCount() {
return (int) (
- Math.ceil((float) mChooserListAdapter.getCallerTargetCount() / mColumnCount)
- + Math.ceil((float) mChooserListAdapter.getServiceTargetCount() / mColumnCount)
+ getCallerTargetRowCount()
+ + getServiceTargetRowCount()
+ Math.ceil((float) mChooserListAdapter.getStandardTargetCount() / mColumnCount)
);
}
+ public int getCallerTargetRowCount() {
+ return (int) Math.ceil(
+ (float) mChooserListAdapter.getCallerTargetCount() / mColumnCount);
+ }
+
+ public int getServiceTargetRowCount() {
+ return (int) Math.ceil(
+ (float) mChooserListAdapter.getServiceTargetCount() / mColumnCount);
+ }
+
@Override
public Object getItem(int position) {
// We have nothing useful to return here.
@@ -947,33 +1103,69 @@
@Override
public View getView(int position, View convertView, ViewGroup parent) {
- final View[] holder;
+ final RowViewHolder holder;
if (convertView == null) {
holder = createViewHolder(parent);
} else {
- holder = (View[]) convertView.getTag();
+ holder = (RowViewHolder) convertView.getTag();
}
bindViewHolder(position, holder);
- // We keep the actual list item view as the last item in the holder array
- return holder[mColumnCount];
+ return holder.row;
}
- View[] createViewHolder(ViewGroup parent) {
- final View[] holder = new View[mColumnCount + 1];
-
+ RowViewHolder createViewHolder(ViewGroup parent) {
final ViewGroup row = (ViewGroup) mLayoutInflater.inflate(R.layout.chooser_row,
parent, false);
+ final RowViewHolder holder = new RowViewHolder(row, mColumnCount);
+ final int spec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
+
for (int i = 0; i < mColumnCount; i++) {
- holder[i] = mChooserListAdapter.createView(row);
- row.addView(holder[i]);
+ final View v = mChooserListAdapter.createView(row);
+ final int column = i;
+ v.setOnClickListener(new OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ startSelected(holder.itemIndices[column], false, true);
+ }
+ });
+ v.setOnLongClickListener(new OnLongClickListener() {
+ @Override
+ public boolean onLongClick(View v) {
+ showAppDetails(
+ mChooserListAdapter.resolveInfoForPosition(
+ holder.itemIndices[column], true));
+ return true;
+ }
+ });
+ row.addView(v);
+ holder.cells[i] = v;
+
+ // Force height to be a given so we don't have visual disruption during scaling.
+ LayoutParams lp = v.getLayoutParams();
+ v.measure(spec, spec);
+ if (lp == null) {
+ lp = new LayoutParams(LayoutParams.MATCH_PARENT, v.getMeasuredHeight());
+ row.setLayoutParams(lp);
+ } else {
+ lp.height = v.getMeasuredHeight();
+ }
+ }
+
+ // Pre-measure so we can scale later.
+ holder.measure();
+ LayoutParams lp = row.getLayoutParams();
+ if (lp == null) {
+ lp = new LayoutParams(LayoutParams.MATCH_PARENT, holder.measuredRowHeight);
+ row.setLayoutParams(lp);
+ } else {
+ lp.height = holder.measuredRowHeight;
}
row.setTag(holder);
- holder[mColumnCount] = row;
return holder;
}
- void bindViewHolder(int rowPosition, View[] holder) {
+ void bindViewHolder(int rowPosition, RowViewHolder holder) {
final int start = getFirstRowPosition(rowPosition);
final int startType = mChooserListAdapter.getPositionTargetType(start);
@@ -982,34 +1174,26 @@
end--;
}
- final ViewGroup row = (ViewGroup) holder[mColumnCount];
-
if (startType == ChooserListAdapter.TARGET_SERVICE) {
- row.setBackgroundColor(getColor(R.color.chooser_service_row_background_color));
+ holder.row.setBackgroundColor(
+ getColor(R.color.chooser_service_row_background_color));
} else {
- row.setBackground(null);
+ holder.row.setBackgroundColor(Color.TRANSPARENT);
+ }
+
+ final int oldHeight = holder.row.getLayoutParams().height;
+ holder.row.getLayoutParams().height = Math.max(1,
+ (int) (holder.measuredRowHeight * getRowScale(rowPosition)));
+ if (holder.row.getLayoutParams().height != oldHeight) {
+ holder.row.requestLayout();
}
for (int i = 0; i < mColumnCount; i++) {
- final View v = holder[i];
+ final View v = holder.cells[i];
if (start + i <= end) {
v.setVisibility(View.VISIBLE);
- final int itemIndex = start + i;
- mChooserListAdapter.bindView(itemIndex, v);
- v.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- startSelected(itemIndex, false, true);
- }
- });
- v.setOnLongClickListener(new OnLongClickListener() {
- @Override
- public boolean onLongClick(View v) {
- showAppDetails(
- mChooserListAdapter.resolveInfoForPosition(itemIndex, true));
- return true;
- }
- });
+ holder.itemIndices[i] = start + i;
+ mChooserListAdapter.bindView(holder.itemIndices[i], v);
} else {
v.setVisibility(View.GONE);
}
@@ -1036,54 +1220,112 @@
}
}
- class ChooserTargetServiceConnection implements ServiceConnection {
+ static class RowViewHolder {
+ final View[] cells;
+ final ViewGroup row;
+ int measuredRowHeight;
+ int[] itemIndices;
+
+ public RowViewHolder(ViewGroup row, int cellCount) {
+ this.row = row;
+ this.cells = new View[cellCount];
+ this.itemIndices = new int[cellCount];
+ }
+
+ public void measure() {
+ final int spec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
+ row.measure(spec, spec);
+ measuredRowHeight = row.getMeasuredHeight();
+ }
+ }
+
+ static class ChooserTargetServiceConnection implements ServiceConnection {
private final DisplayResolveInfo mOriginalTarget;
+ private ComponentName mConnectedComponent;
+ private ChooserActivity mChooserActivity;
+ private final Object mLock = new Object();
private final IChooserTargetResult mChooserTargetResult = new IChooserTargetResult.Stub() {
@Override
public void sendResult(List<ChooserTarget> targets) throws RemoteException {
- filterServiceTargets(mOriginalTarget.getResolveInfo().activityInfo.packageName,
- targets);
- final Message msg = Message.obtain();
- msg.what = CHOOSER_TARGET_SERVICE_RESULT;
- msg.obj = new ServiceResultInfo(mOriginalTarget, targets,
- ChooserTargetServiceConnection.this);
- mChooserHandler.sendMessage(msg);
+ synchronized (mLock) {
+ if (mChooserActivity == null) {
+ Log.e(TAG, "destroyed ChooserTargetServiceConnection received result from "
+ + mConnectedComponent + "; ignoring...");
+ return;
+ }
+ mChooserActivity.filterServiceTargets(
+ mOriginalTarget.getResolveInfo().activityInfo.packageName, targets);
+ final Message msg = Message.obtain();
+ msg.what = CHOOSER_TARGET_SERVICE_RESULT;
+ msg.obj = new ServiceResultInfo(mOriginalTarget, targets,
+ ChooserTargetServiceConnection.this);
+ mChooserActivity.mChooserHandler.sendMessage(msg);
+ }
}
};
- public ChooserTargetServiceConnection(DisplayResolveInfo dri) {
+ public ChooserTargetServiceConnection(ChooserActivity chooserActivity,
+ DisplayResolveInfo dri) {
+ mChooserActivity = chooserActivity;
mOriginalTarget = dri;
}
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
if (DEBUG) Log.d(TAG, "onServiceConnected: " + name);
- final IChooserTargetService icts = IChooserTargetService.Stub.asInterface(service);
- try {
- icts.getChooserTargets(mOriginalTarget.getResolvedComponentName(),
- mOriginalTarget.getResolveInfo().filter, mChooserTargetResult);
- } catch (RemoteException e) {
- Log.e(TAG, "Querying ChooserTargetService " + name + " failed.", e);
- unbindService(this);
- mServiceConnections.remove(this);
+ synchronized (mLock) {
+ if (mChooserActivity == null) {
+ Log.e(TAG, "destroyed ChooserTargetServiceConnection got onServiceConnected");
+ return;
+ }
+
+ final IChooserTargetService icts = IChooserTargetService.Stub.asInterface(service);
+ try {
+ icts.getChooserTargets(mOriginalTarget.getResolvedComponentName(),
+ mOriginalTarget.getResolveInfo().filter, mChooserTargetResult);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Querying ChooserTargetService " + name + " failed.", e);
+ mChooserActivity.unbindService(this);
+ destroy();
+ mChooserActivity.mServiceConnections.remove(this);
+ }
}
}
@Override
public void onServiceDisconnected(ComponentName name) {
if (DEBUG) Log.d(TAG, "onServiceDisconnected: " + name);
- unbindService(this);
- mServiceConnections.remove(this);
- if (mServiceConnections.isEmpty()) {
- mChooserHandler.removeMessages(CHOOSER_TARGET_SERVICE_WATCHDOG_TIMEOUT);
- sendVoiceChoicesIfNeeded();
+ synchronized (mLock) {
+ if (mChooserActivity == null) {
+ Log.e(TAG,
+ "destroyed ChooserTargetServiceConnection got onServiceDisconnected");
+ return;
+ }
+
+ mChooserActivity.unbindService(this);
+ destroy();
+ mChooserActivity.mServiceConnections.remove(this);
+ if (mChooserActivity.mServiceConnections.isEmpty()) {
+ mChooserActivity.mChooserHandler.removeMessages(
+ CHOOSER_TARGET_SERVICE_WATCHDOG_TIMEOUT);
+ mChooserActivity.sendVoiceChoicesIfNeeded();
+ }
+ mConnectedComponent = null;
+ }
+ }
+
+ public void destroy() {
+ synchronized (mLock) {
+ mChooserActivity = null;
}
}
@Override
public String toString() {
- return mOriginalTarget.getResolveInfo().activityInfo.toString();
+ return "ChooserTargetServiceConnection{service="
+ + mConnectedComponent + ", activity="
+ + mOriginalTarget.getResolveInfo().activityInfo.toString() + "}";
}
}
@@ -1148,4 +1390,44 @@
mSelectedTarget = null;
}
}
+
+ class OffsetDataSetObserver extends DataSetObserver {
+ private final AbsListView mListView;
+ private int mCachedViewType = -1;
+ private View mCachedView;
+
+ public OffsetDataSetObserver(AbsListView listView) {
+ mListView = listView;
+ }
+
+ @Override
+ public void onChanged() {
+ if (mResolverDrawerLayout == null) {
+ return;
+ }
+
+ final int chooserTargetRows = mChooserRowAdapter.getServiceTargetRowCount();
+ int offset = 0;
+ for (int i = 0; i < chooserTargetRows; i++) {
+ final int pos = mChooserRowAdapter.getCallerTargetRowCount() + i;
+ final int vt = mChooserRowAdapter.getItemViewType(pos);
+ if (vt != mCachedViewType) {
+ mCachedView = null;
+ }
+ final View v = mChooserRowAdapter.getView(pos, mCachedView, mListView);
+ int height = ((RowViewHolder) (v.getTag())).measuredRowHeight;
+
+ offset += (int) (height * mChooserRowAdapter.getRowScale(pos));
+
+ if (vt >= 0) {
+ mCachedViewType = vt;
+ mCachedView = v;
+ } else {
+ mCachedViewType = -1;
+ }
+ }
+
+ mResolverDrawerLayout.setCollapsibleHeightReserved(offset);
+ }
+ }
}
diff --git a/core/java/com/android/internal/app/ResolverActivity.java b/core/java/com/android/internal/app/ResolverActivity.java
index 7dd3bed..4ba678c 100644
--- a/core/java/com/android/internal/app/ResolverActivity.java
+++ b/core/java/com/android/internal/app/ResolverActivity.java
@@ -26,6 +26,7 @@
import android.provider.Settings;
import android.text.TextUtils;
import android.util.Slog;
+import android.view.View.OnAttachStateChangeListener;
import android.widget.AbsListView;
import com.android.internal.R;
import com.android.internal.content.PackageMonitor;
@@ -103,6 +104,8 @@
private ResolverComparator mResolverComparator;
private PickTargetOptionRequest mPickOptionRequest;
+ protected ResolverDrawerLayout mResolverDrawerLayout;
+
private boolean mRegistered;
private final PackageMonitor mPackageMonitor = new PackageMonitor() {
@Override public void onSomePackagesChanged() {
@@ -234,7 +237,9 @@
mResolverComparator = new ResolverComparator(this, getTargetIntent(), referrerPackage);
- configureContentView(mIntents, initialIntents, rList, alwaysUseOption);
+ if (configureContentView(mIntents, initialIntents, rList, alwaysUseOption)) {
+ return;
+ }
// Prevent the Resolver window from becoming the top fullscreen window and thus from taking
// control of the system bars.
@@ -251,6 +256,7 @@
if (isVoiceInteraction()) {
rdl.setCollapsed(false);
}
+ mResolverDrawerLayout = rdl;
}
if (title == null) {
@@ -326,6 +332,18 @@
if (isVoiceInteraction()) {
onSetupVoiceInteraction();
}
+
+ getWindow().getDecorView().addOnAttachStateChangeListener(
+ new OnAttachStateChangeListener() {
+ @Override
+ public void onViewAttachedToWindow(View v) {
+ v.getViewRootImpl().setDrawDuringWindowsAnimating(true);
+ }
+
+ @Override
+ public void onViewDetachedFromWindow(View v) {
+ }
+ });
}
/**
@@ -794,6 +812,10 @@
return false;
}
+ boolean shouldAutoLaunchSingleChoice(TargetInfo target) {
+ return true;
+ }
+
void showAppDetails(ResolveInfo ri) {
Intent in = new Intent().setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS)
.setData(Uri.fromParts("package", ri.activityInfo.packageName, null))
@@ -808,7 +830,10 @@
launchedFromUid, filterLastUsed);
}
- void configureContentView(List<Intent> payloadIntents, Intent[] initialIntents,
+ /**
+ * Returns true if the activity is finishing and creation should halt
+ */
+ boolean configureContentView(List<Intent> payloadIntents, Intent[] initialIntents,
List<ResolveInfo> rList, boolean alwaysUseOption) {
// The last argument of createAdapter is whether to do special handling
// of the last used choice to highlight it in the list. We need to always
@@ -828,16 +853,21 @@
mAlwaysUseOption = alwaysUseOption;
int count = mAdapter.getUnfilteredCount();
- if (count > 1 || (count == 1 && mAdapter.getOtherProfile() != null)) {
+ if (count == 1 && mAdapter.getOtherProfile() == null) {
+ // Only one target, so we're a candidate to auto-launch!
+ final TargetInfo target = mAdapter.targetInfoForPosition(0, false);
+ if (shouldAutoLaunchSingleChoice(target)) {
+ safelyStartActivity(target);
+ mPackageMonitor.unregister();
+ mRegistered = false;
+ finish();
+ return true;
+ }
+ }
+ if (count > 0) {
setContentView(layoutId);
mAdapterView = (AbsListView) findViewById(R.id.resolver_list);
onPrepareAdapterView(mAdapterView, mAdapter, alwaysUseOption);
- } else if (count == 1) {
- safelyStartActivity(mAdapter.targetInfoForPosition(0, false));
- mPackageMonitor.unregister();
- mRegistered = false;
- finish();
- return;
} else {
setContentView(R.layout.resolver_list);
@@ -847,6 +877,7 @@
mAdapterView = (AbsListView) findViewById(R.id.resolver_list);
mAdapterView.setVisibility(View.GONE);
}
+ return false;
}
void onPrepareAdapterView(AbsListView adapterView, ResolveListAdapter adapter,
@@ -884,6 +915,7 @@
private final ResolveInfo mResolveInfo;
private final CharSequence mDisplayLabel;
private Drawable mDisplayIcon;
+ private Drawable mBadge;
private final CharSequence mExtendedInfo;
private final Intent mResolvedIntent;
private final List<Intent> mSourceIntents = new ArrayList<>();
@@ -928,7 +960,25 @@
}
public Drawable getBadgeIcon() {
- return null;
+ // We only expose a badge if we have extended info.
+ // The badge is a higher-priority disambiguation signal
+ // but we don't need one if we wouldn't show extended info at all.
+ if (TextUtils.isEmpty(getExtendedInfo())) {
+ return null;
+ }
+
+ if (mBadge == null && mResolveInfo != null && mResolveInfo.activityInfo != null
+ && mResolveInfo.activityInfo.applicationInfo != null) {
+ if (mResolveInfo.activityInfo.icon == 0 || mResolveInfo.activityInfo.icon
+ == mResolveInfo.activityInfo.applicationInfo.icon) {
+ // Badging an icon with exactly the same icon is silly.
+ // If the activityInfo icon resid is 0 it will fall back
+ // to the application's icon, making it a match.
+ return null;
+ }
+ mBadge = mResolveInfo.activityInfo.applicationInfo.loadIcon(mPm);
+ }
+ return mBadge;
}
@Override
@@ -1366,8 +1416,8 @@
} else {
mHasExtendedInfo = true;
boolean usePkg = false;
- CharSequence startApp = ro.getResolveInfoAt(0).activityInfo.applicationInfo
- .loadLabel(mPm);
+ final ApplicationInfo ai = ro.getResolveInfoAt(0).activityInfo.applicationInfo;
+ final CharSequence startApp = ai.loadLabel(mPm);
if (startApp == null) {
usePkg = true;
}
@@ -1536,7 +1586,10 @@
private void onBindView(View view, TargetInfo info) {
final ViewHolder holder = (ViewHolder) view.getTag();
- holder.text.setText(info.getDisplayLabel());
+ final CharSequence label = info.getDisplayLabel();
+ if (!TextUtils.equals(holder.text.getText(), label)) {
+ holder.text.setText(info.getDisplayLabel());
+ }
if (showsExtendedInfo(info)) {
holder.text2.setVisibility(View.VISIBLE);
holder.text2.setText(info.getExtendedInfo());
diff --git a/core/java/com/android/internal/logging/MetricsLogger.java b/core/java/com/android/internal/logging/MetricsLogger.java
index 55493c3..b6240e4 100644
--- a/core/java/com/android/internal/logging/MetricsLogger.java
+++ b/core/java/com/android/internal/logging/MetricsLogger.java
@@ -29,6 +29,23 @@
// Temporary constants go here, to await migration to MetricsConstants.
// next value is 239;
public static final int ACTION_ASSIST_LONG_PRESS = 239;
+ public static final int FINGERPRINT_ENROLLING = 240;
+ public static final int FINGERPRINT_FIND_SENSOR = 241;
+ public static final int FINGERPRINT_ENROLL_FINISH = 242;
+ public static final int FINGERPRINT_ENROLL_INTRO = 243;
+ public static final int FINGERPRINT_ENROLL_ONBOARD = 244;
+ public static final int FINGERPRINT_ENROLL_SIDECAR = 245;
+ public static final int FINGERPRINT_ENROLLING_SETUP = 246;
+ public static final int FINGERPRINT_FIND_SENSOR_SETUP = 247;
+ public static final int FINGERPRINT_ENROLL_FINISH_SETUP = 248;
+ public static final int FINGERPRINT_ENROLL_INTRO_SETUP = 249;
+ public static final int FINGERPRINT_ENROLL_ONBOARD_SETUP = 250;
+ public static final int ACTION_FINGERPRINT_ENROLL = 251;
+ public static final int ACTION_FINGERPRINT_AUTH = 252;
+ public static final int ACTION_FINGERPRINT_DELETE = 253;
+ public static final int ACTION_FINGERPRINT_RENAME = 254;
+ public static final int ACTION_DOUBLE_TAP_POWER_CAMERA_GESTURE = 255;
+ public static final int ACTION_WIGGLE_CAMERA_GESTURE = 256;
public static void visible(Context context, int category) throws IllegalArgumentException {
if (Build.IS_DEBUGGABLE && category == VIEW_UNKNOWN) {
diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java
index 4ff7869..64b7768 100644
--- a/core/java/com/android/internal/os/BatteryStatsImpl.java
+++ b/core/java/com/android/internal/os/BatteryStatsImpl.java
@@ -105,7 +105,7 @@
private static final int MAGIC = 0xBA757475; // 'BATSTATS'
// Current on-disk Parcel version
- private static final int VERSION = 130 + (USE_OLD_HISTORY ? 1000 : 0);
+ private static final int VERSION = 132 + (USE_OLD_HISTORY ? 1000 : 0);
// Maximum number of items we will record in the history.
private static final int MAX_HISTORY_ITEMS = 2000;
@@ -118,8 +118,6 @@
// in to one common name.
private static final int MAX_WAKELOCKS_PER_UID = 100;
- private static int sNumSpeedSteps;
-
private final JournaledFile mFile;
public final AtomicFile mCheckinFile;
public final AtomicFile mDailyFile;
@@ -133,7 +131,7 @@
private final KernelWakelockStats mTmpWakelockStats = new KernelWakelockStats();
private final KernelUidCpuTimeReader mKernelUidCpuTimeReader = new KernelUidCpuTimeReader();
- private final KernelCpuSpeedReader mKernelCpuSpeedReader = new KernelCpuSpeedReader();
+ private KernelCpuSpeedReader[] mKernelCpuSpeedReaders;
public interface BatteryCallback {
public void batteryNeedsCpuUpdate();
@@ -4411,7 +4409,7 @@
LongSamplingCounter mUserCpuTime = new LongSamplingCounter(mOnBatteryTimeBase);
LongSamplingCounter mSystemCpuTime = new LongSamplingCounter(mOnBatteryTimeBase);
LongSamplingCounter mCpuPower = new LongSamplingCounter(mOnBatteryTimeBase);
- LongSamplingCounter[] mSpeedBins;
+ LongSamplingCounter[][] mCpuClusterSpeed;
/**
* The statistics we have collected for this uid's wake locks.
@@ -4470,7 +4468,6 @@
mWifiMulticastTimer = new StopwatchTimer(Uid.this, WIFI_MULTICAST_ENABLED,
mWifiMulticastTimers, mOnBatteryTimeBase);
mProcessStateTimer = new StopwatchTimer[NUM_PROCESS_STATE];
- mSpeedBins = new LongSamplingCounter[getCpuSpeedSteps()];
}
@Override
@@ -5008,10 +5005,18 @@
}
@Override
- public long getTimeAtCpuSpeed(int step, int which) {
- if (step >= 0 && step < mSpeedBins.length) {
- if (mSpeedBins[step] != null) {
- return mSpeedBins[step].getCountLocked(which);
+ public long getTimeAtCpuSpeed(int cluster, int step, int which) {
+ if (mCpuClusterSpeed != null) {
+ if (cluster >= 0 && cluster < mCpuClusterSpeed.length) {
+ final LongSamplingCounter[] cpuSpeeds = mCpuClusterSpeed[cluster];
+ if (cpuSpeeds != null) {
+ if (step >= 0 && step < cpuSpeeds.length) {
+ final LongSamplingCounter c = cpuSpeeds[step];
+ if (c != null) {
+ return c.getCountLocked(which);
+ }
+ }
+ }
}
}
return 0;
@@ -5128,10 +5133,16 @@
mUserCpuTime.reset(false);
mSystemCpuTime.reset(false);
mCpuPower.reset(false);
- for (int i = 0; i < mSpeedBins.length; i++) {
- LongSamplingCounter c = mSpeedBins[i];
- if (c != null) {
- c.reset(false);
+
+ if (mCpuClusterSpeed != null) {
+ for (LongSamplingCounter[] speeds : mCpuClusterSpeed) {
+ if (speeds != null) {
+ for (LongSamplingCounter speed : speeds) {
+ if (speed != null) {
+ speed.reset(false);
+ }
+ }
+ }
}
}
@@ -5280,10 +5291,16 @@
mUserCpuTime.detach();
mSystemCpuTime.detach();
mCpuPower.detach();
- for (int i = 0; i < mSpeedBins.length; i++) {
- LongSamplingCounter c = mSpeedBins[i];
- if (c != null) {
- c.detach();
+
+ if (mCpuClusterSpeed != null) {
+ for (LongSamplingCounter[] cpuSpeeds : mCpuClusterSpeed) {
+ if (cpuSpeeds != null) {
+ for (LongSamplingCounter c : cpuSpeeds) {
+ if (c != null) {
+ c.detach();
+ }
+ }
+ }
}
}
}
@@ -5461,15 +5478,27 @@
mSystemCpuTime.writeToParcel(out);
mCpuPower.writeToParcel(out);
- out.writeInt(mSpeedBins.length);
- for (int i = 0; i < mSpeedBins.length; i++) {
- LongSamplingCounter c = mSpeedBins[i];
- if (c != null) {
- out.writeInt(1);
- c.writeToParcel(out);
- } else {
- out.writeInt(0);
+ if (mCpuClusterSpeed != null) {
+ out.writeInt(1);
+ out.writeInt(mCpuClusterSpeed.length);
+ for (LongSamplingCounter[] cpuSpeeds : mCpuClusterSpeed) {
+ if (cpuSpeeds != null) {
+ out.writeInt(1);
+ out.writeInt(cpuSpeeds.length);
+ for (LongSamplingCounter c : cpuSpeeds) {
+ if (c != null) {
+ out.writeInt(1);
+ c.writeToParcel(out);
+ } else {
+ out.writeInt(0);
+ }
+ }
+ } else {
+ out.writeInt(0);
+ }
}
+ } else {
+ out.writeInt(0);
}
}
@@ -5653,13 +5682,34 @@
mSystemCpuTime = new LongSamplingCounter(mOnBatteryTimeBase, in);
mCpuPower = new LongSamplingCounter(mOnBatteryTimeBase, in);
- int bins = in.readInt();
- int steps = getCpuSpeedSteps();
- mSpeedBins = new LongSamplingCounter[bins >= steps ? bins : steps];
- for (int i = 0; i < bins; i++) {
- if (in.readInt() != 0) {
- mSpeedBins[i] = new LongSamplingCounter(mOnBatteryTimeBase, in);
+ if (in.readInt() != 0) {
+ int numCpuClusters = in.readInt();
+ if (mPowerProfile != null && mPowerProfile.getNumCpuClusters() != numCpuClusters) {
+ throw new ParcelFormatException("Incompatible number of cpu clusters");
}
+
+ mCpuClusterSpeed = new LongSamplingCounter[numCpuClusters][];
+ for (int cluster = 0; cluster < numCpuClusters; cluster++) {
+ if (in.readInt() != 0) {
+ int numSpeeds = in.readInt();
+ if (mPowerProfile != null &&
+ mPowerProfile.getNumSpeedStepsInCpuCluster(cluster) != numSpeeds) {
+ throw new ParcelFormatException("Incompatible number of cpu speeds");
+ }
+
+ final LongSamplingCounter[] cpuSpeeds = new LongSamplingCounter[numSpeeds];
+ mCpuClusterSpeed[cluster] = cpuSpeeds;
+ for (int speed = 0; speed < numSpeeds; speed++) {
+ if (in.readInt() != 0) {
+ cpuSpeeds[speed] = new LongSamplingCounter(mOnBatteryTimeBase, in);
+ }
+ }
+ } else {
+ mCpuClusterSpeed[cluster] = null;
+ }
+ }
+ } else {
+ mCpuClusterSpeed = null;
}
}
@@ -6874,6 +6924,19 @@
public void setPowerProfile(PowerProfile profile) {
synchronized (this) {
mPowerProfile = profile;
+
+ // We need to initialize the KernelCpuSpeedReaders to read from
+ // the first cpu of each core. Once we have the PowerProfile, we have access to this
+ // information.
+ final int numClusters = mPowerProfile.getNumCpuClusters();
+ mKernelCpuSpeedReaders = new KernelCpuSpeedReader[numClusters];
+ int firstCpuOfCluster = 0;
+ for (int i = 0; i < numClusters; i++) {
+ final int numSpeedSteps = mPowerProfile.getNumSpeedStepsInCpuCluster(i);
+ mKernelCpuSpeedReaders[i] = new KernelCpuSpeedReader(firstCpuOfCluster,
+ numSpeedSteps);
+ firstCpuOfCluster += mPowerProfile.getNumCoresInCpuCluster(i);
+ }
}
}
@@ -6881,10 +6944,6 @@
mCallback = cb;
}
- public void setNumSpeedSteps(int steps) {
- if (sNumSpeedSteps == 0) sNumSpeedSteps = steps;
- }
-
public void setRadioScanningTimeout(long timeout) {
if (mPhoneSignalScanningTimer != null) {
mPhoneSignalScanningTimer.setTimeout(timeout);
@@ -7987,6 +8046,10 @@
* wakelocks. If the screen is on, we just assign the actual cpu time an app used.
*/
public void updateCpuTimeLocked() {
+ if (mPowerProfile == null) {
+ return;
+ }
+
if (DEBUG_ENERGY_CPU) {
Slog.d(TAG, "!Cpu updating!");
}
@@ -7997,9 +8060,11 @@
// If no app is holding a wakelock, then the distribution is normal.
final int wakelockWeight = 50;
- // Read the time spent at various cpu frequencies.
- final int cpuSpeedSteps = getCpuSpeedSteps();
- final long[] cpuSpeeds = mKernelCpuSpeedReader.readDelta();
+ // Read the time spent for each cluster at various cpu frequencies.
+ final long[][] clusterSpeeds = new long[mKernelCpuSpeedReaders.length][];
+ for (int cluster = 0; cluster < mKernelCpuSpeedReaders.length; cluster++) {
+ clusterSpeeds[cluster] = mKernelCpuSpeedReaders[cluster].readDelta();
+ }
int numWakelocks = 0;
@@ -8072,11 +8137,28 @@
// Add the cpu speeds to this UID. These are used as a ratio
// for computing the power this UID used.
- for (int i = 0; i < cpuSpeedSteps; i++) {
- if (u.mSpeedBins[i] == null) {
- u.mSpeedBins[i] = new LongSamplingCounter(mOnBatteryTimeBase);
+ final int numClusters = mPowerProfile.getNumCpuClusters();
+ if (u.mCpuClusterSpeed == null || u.mCpuClusterSpeed.length !=
+ numClusters) {
+ u.mCpuClusterSpeed = new LongSamplingCounter[numClusters][];
+ }
+
+ for (int cluster = 0; cluster < clusterSpeeds.length; cluster++) {
+ final int speedsInCluster = mPowerProfile.getNumSpeedStepsInCpuCluster(
+ cluster);
+ if (u.mCpuClusterSpeed[cluster] == null || speedsInCluster !=
+ u.mCpuClusterSpeed[cluster].length) {
+ u.mCpuClusterSpeed[cluster] =
+ new LongSamplingCounter[speedsInCluster];
}
- u.mSpeedBins[i].addCountLocked(cpuSpeeds[i]);
+
+ final LongSamplingCounter[] cpuSpeeds = u.mCpuClusterSpeed[cluster];
+ for (int speed = 0; speed < clusterSpeeds[cluster].length; speed++) {
+ if (cpuSpeeds[speed] == null) {
+ cpuSpeeds[speed] = new LongSamplingCounter(mOnBatteryTimeBase);
+ }
+ cpuSpeeds[speed].addCountLocked(clusterSpeeds[cluster][speed]);
+ }
}
}
});
@@ -8776,11 +8858,6 @@
}
}
- @Override
- public int getCpuSpeedSteps() {
- return sNumSpeedSteps;
- }
-
/**
* Retrieve the statistics object for a particular uid, creating if needed.
*/
@@ -9216,11 +9293,6 @@
}
}
- sNumSpeedSteps = in.readInt();
- if (sNumSpeedSteps < 0 || sNumSpeedSteps > 100) {
- throw new ParcelFormatException("Bad speed steps in data: " + sNumSpeedSteps);
- }
-
final int NU = in.readInt();
if (NU > 10000) {
throw new ParcelFormatException("File corrupt: too many uids " + NU);
@@ -9304,17 +9376,36 @@
u.mSystemCpuTime.readSummaryFromParcelLocked(in);
u.mCpuPower.readSummaryFromParcelLocked(in);
- int NSB = in.readInt();
- if (NSB > 100) {
- throw new ParcelFormatException("File corrupt: too many speed bins " + NSB);
- }
-
- u.mSpeedBins = new LongSamplingCounter[NSB];
- for (int i=0; i<NSB; i++) {
- if (in.readInt() != 0) {
- u.mSpeedBins[i] = new LongSamplingCounter(mOnBatteryTimeBase);
- u.mSpeedBins[i].readSummaryFromParcelLocked(in);
+ if (in.readInt() != 0) {
+ final int numClusters = in.readInt();
+ if (mPowerProfile != null && mPowerProfile.getNumCpuClusters() != numClusters) {
+ throw new ParcelFormatException("Incompatible cpu cluster arrangement");
}
+
+ u.mCpuClusterSpeed = new LongSamplingCounter[numClusters][];
+ for (int cluster = 0; cluster < numClusters; cluster++) {
+ if (in.readInt() != 0) {
+ final int NSB = in.readInt();
+ if (mPowerProfile != null &&
+ mPowerProfile.getNumSpeedStepsInCpuCluster(cluster) != NSB) {
+ throw new ParcelFormatException("File corrupt: too many speed bins " +
+ NSB);
+ }
+
+ u.mCpuClusterSpeed[cluster] = new LongSamplingCounter[NSB];
+ for (int speed = 0; speed < NSB; speed++) {
+ if (in.readInt() != 0) {
+ u.mCpuClusterSpeed[cluster][speed] = new LongSamplingCounter(
+ mOnBatteryTimeBase);
+ u.mCpuClusterSpeed[cluster][speed].readSummaryFromParcelLocked(in);
+ }
+ }
+ } else {
+ u.mCpuClusterSpeed[cluster] = null;
+ }
+ }
+ } else {
+ u.mCpuClusterSpeed = null;
}
int NW = in.readInt();
@@ -9531,7 +9622,6 @@
}
}
- out.writeInt(sNumSpeedSteps);
final int NU = mUidStats.size();
out.writeInt(NU);
for (int iu = 0; iu < NU; iu++) {
@@ -9640,15 +9730,27 @@
u.mSystemCpuTime.writeSummaryFromParcelLocked(out);
u.mCpuPower.writeSummaryFromParcelLocked(out);
- out.writeInt(u.mSpeedBins.length);
- for (int i = 0; i < u.mSpeedBins.length; i++) {
- LongSamplingCounter speedBin = u.mSpeedBins[i];
- if (speedBin != null) {
- out.writeInt(1);
- speedBin.writeSummaryFromParcelLocked(out);
- } else {
- out.writeInt(0);
+ if (u.mCpuClusterSpeed != null) {
+ out.writeInt(1);
+ out.writeInt(u.mCpuClusterSpeed.length);
+ for (LongSamplingCounter[] cpuSpeeds : u.mCpuClusterSpeed) {
+ if (cpuSpeeds != null) {
+ out.writeInt(1);
+ out.writeInt(cpuSpeeds.length);
+ for (LongSamplingCounter c : cpuSpeeds) {
+ if (c != null) {
+ out.writeInt(1);
+ c.writeSummaryFromParcelLocked(out);
+ } else {
+ out.writeInt(0);
+ }
+ }
+ } else {
+ out.writeInt(0);
+ }
}
+ } else {
+ out.writeInt(0);
}
final ArrayMap<String, Uid.Wakelock> wakeStats = u.mWakelockStats.getMap();
@@ -9897,8 +9999,6 @@
mFlashlightTurnedOnTimers.clear();
mCameraTurnedOnTimers.clear();
- sNumSpeedSteps = in.readInt();
-
int numUids = in.readInt();
mUidStats.clear();
for (int i = 0; i < numUids; i++) {
@@ -10037,8 +10137,6 @@
out.writeInt(0);
}
- out.writeInt(sNumSpeedSteps);
-
if (inclUids) {
int size = mUidStats.size();
out.writeInt(size);
diff --git a/core/java/com/android/internal/os/CpuPowerCalculator.java b/core/java/com/android/internal/os/CpuPowerCalculator.java
index a3ef612..8417856 100644
--- a/core/java/com/android/internal/os/CpuPowerCalculator.java
+++ b/core/java/com/android/internal/os/CpuPowerCalculator.java
@@ -22,55 +22,50 @@
public class CpuPowerCalculator extends PowerCalculator {
private static final String TAG = "CpuPowerCalculator";
private static final boolean DEBUG = BatteryStatsHelper.DEBUG;
-
- private final double[] mPowerCpuNormal;
-
- /**
- * Reusable array for calculations.
- */
- private final long[] mSpeedStepTimes;
+ private final PowerProfile mProfile;
public CpuPowerCalculator(PowerProfile profile) {
- final int speedSteps = profile.getNumSpeedSteps();
- mPowerCpuNormal = new double[speedSteps];
- mSpeedStepTimes = new long[speedSteps];
- for (int p = 0; p < speedSteps; p++) {
- mPowerCpuNormal[p] = profile.getAveragePower(PowerProfile.POWER_CPU_ACTIVE, p);
- }
+ mProfile = profile;
}
@Override
public void calculateApp(BatterySipper app, BatteryStats.Uid u, long rawRealtimeUs,
long rawUptimeUs, int statsType) {
- final int speedSteps = mSpeedStepTimes.length;
-
- long totalTimeAtSpeeds = 0;
- for (int step = 0; step < speedSteps; step++) {
- mSpeedStepTimes[step] = u.getTimeAtCpuSpeed(step, statsType);
- totalTimeAtSpeeds += mSpeedStepTimes[step];
- }
- totalTimeAtSpeeds = Math.max(totalTimeAtSpeeds, 1);
app.cpuTimeMs = (u.getUserCpuTimeUs(statsType) + u.getSystemCpuTimeUs(statsType)) / 1000;
- if (DEBUG && app.cpuTimeMs != 0) {
- Log.d(TAG, "UID " + u.getUid() + ": CPU time " + app.cpuTimeMs + " ms");
+
+ // Aggregate total time spent on each cluster.
+ long totalTime = 0;
+ final int numClusters = mProfile.getNumCpuClusters();
+ for (int cluster = 0; cluster < numClusters; cluster++) {
+ final int speedsForCluster = mProfile.getNumSpeedStepsInCpuCluster(cluster);
+ for (int speed = 0; speed < speedsForCluster; speed++) {
+ totalTime += u.getTimeAtCpuSpeed(cluster, speed, statsType);
+ }
}
+ totalTime = Math.max(totalTime, 1);
double cpuPowerMaMs = 0;
- for (int step = 0; step < speedSteps; step++) {
- final double ratio = (double) mSpeedStepTimes[step] / totalTimeAtSpeeds;
- final double cpuSpeedStepPower = ratio * app.cpuTimeMs * mPowerCpuNormal[step];
- if (DEBUG && ratio != 0) {
- Log.d(TAG, "UID " + u.getUid() + ": CPU step #"
- + step + " ratio=" + BatteryStatsHelper.makemAh(ratio) + " power="
- + BatteryStatsHelper.makemAh(cpuSpeedStepPower / (60 * 60 * 1000)));
+ for (int cluster = 0; cluster < numClusters; cluster++) {
+ final int speedsForCluster = mProfile.getNumSpeedStepsInCpuCluster(cluster);
+ for (int speed = 0; speed < speedsForCluster; speed++) {
+ final double ratio = (double) u.getTimeAtCpuSpeed(cluster, speed, statsType) /
+ totalTime;
+ final double cpuSpeedStepPower = ratio * app.cpuTimeMs *
+ mProfile.getAveragePowerForCpu(cluster, speed);
+ if (DEBUG && ratio != 0) {
+ Log.d(TAG, "UID " + u.getUid() + ": CPU cluster #" + cluster + " step #"
+ + speed + " ratio=" + BatteryStatsHelper.makemAh(ratio) + " power="
+ + BatteryStatsHelper.makemAh(cpuSpeedStepPower / (60 * 60 * 1000)));
+ }
+ cpuPowerMaMs += cpuSpeedStepPower;
}
- cpuPowerMaMs += cpuSpeedStepPower;
}
+ app.cpuPowerMah = cpuPowerMaMs / (60 * 60 * 1000);
- if (DEBUG && cpuPowerMaMs != 0) {
- Log.d(TAG, "UID " + u.getUid() + ": cpu total power="
- + BatteryStatsHelper.makemAh(cpuPowerMaMs / (60 * 60 * 1000)));
+ if (DEBUG && (app.cpuTimeMs != 0 || app.cpuPowerMah != 0)) {
+ Log.d(TAG, "UID " + u.getUid() + ": CPU time=" + app.cpuTimeMs + " ms power="
+ + BatteryStatsHelper.makemAh(app.cpuPowerMah));
}
// Keep track of the package with highest drain.
@@ -108,8 +103,5 @@
// Statistics may not have been gathered yet.
app.cpuTimeMs = app.cpuFgTimeMs;
}
-
- // Convert the CPU power to mAh
- app.cpuPowerMah = cpuPowerMaMs / (60 * 60 * 1000);
}
}
diff --git a/core/java/com/android/internal/os/InstallerConnection.java b/core/java/com/android/internal/os/InstallerConnection.java
index dcc6a5e..db2b41f 100644
--- a/core/java/com/android/internal/os/InstallerConnection.java
+++ b/core/java/com/android/internal/os/InstallerConnection.java
@@ -92,14 +92,14 @@
}
public int dexopt(String apkPath, int uid, boolean isPublic,
- String instructionSet, int dexoptNeeded) {
+ String instructionSet, int dexoptNeeded, boolean bootComplete) {
return dexopt(apkPath, uid, isPublic, "*", instructionSet, dexoptNeeded,
- false, false, null);
+ false, false, null, bootComplete);
}
public int dexopt(String apkPath, int uid, boolean isPublic, String pkgName,
String instructionSet, int dexoptNeeded, boolean vmSafeMode,
- boolean debuggable, String outputPath) {
+ boolean debuggable, String outputPath, boolean bootComplete) {
StringBuilder builder = new StringBuilder("dexopt");
builder.append(' ');
builder.append(apkPath);
@@ -116,6 +116,7 @@
builder.append(debuggable ? " 1" : " 0");
builder.append(' ');
builder.append(outputPath != null ? outputPath : "!");
+ builder.append(bootComplete ? " 1" : " 0");
return execute(builder.toString());
}
diff --git a/core/java/com/android/internal/os/KernelCpuSpeedReader.java b/core/java/com/android/internal/os/KernelCpuSpeedReader.java
index c30df28..5b776ac 100644
--- a/core/java/com/android/internal/os/KernelCpuSpeedReader.java
+++ b/core/java/com/android/internal/os/KernelCpuSpeedReader.java
@@ -24,8 +24,8 @@
import java.util.Arrays;
/**
- * Reads CPU time spent at various frequencies and provides a delta from the last call to
- * {@link #readDelta}. Each line in the proc file has the format:
+ * Reads CPU time of a specific core spent at various frequencies and provides a delta from the
+ * last call to {@link #readDelta}. Each line in the proc file has the format:
*
* freq time
*
@@ -33,12 +33,20 @@
*/
public class KernelCpuSpeedReader {
private static final String TAG = "KernelCpuSpeedReader";
- private static final String sProcFile =
- "/sys/devices/system/cpu/cpu0/cpufreq/stats/time_in_state";
- private static final int MAX_SPEEDS = 60;
- private long[] mLastSpeedTimes = new long[MAX_SPEEDS];
- private long[] mDeltaSpeedTimes = new long[MAX_SPEEDS];
+ private final String mProcFile;
+ private final long[] mLastSpeedTimes;
+ private final long[] mDeltaSpeedTimes;
+
+ /**
+ * @param cpuNumber The cpu (cpu0, cpu1, etc) whose state to read.
+ */
+ public KernelCpuSpeedReader(int cpuNumber, int numSpeedSteps) {
+ mProcFile = String.format("/sys/devices/system/cpu/cpu%d/cpufreq/stats/time_in_state",
+ cpuNumber);
+ mLastSpeedTimes = new long[numSpeedSteps];
+ mDeltaSpeedTimes = new long[numSpeedSteps];
+ }
/**
* The returned array is modified in subsequent calls to {@link #readDelta}.
@@ -46,22 +54,28 @@
* {@link #readDelta}.
*/
public long[] readDelta() {
- try (BufferedReader reader = new BufferedReader(new FileReader(sProcFile))) {
+ try (BufferedReader reader = new BufferedReader(new FileReader(mProcFile))) {
TextUtils.SimpleStringSplitter splitter = new TextUtils.SimpleStringSplitter(' ');
String line;
int speedIndex = 0;
- while ((line = reader.readLine()) != null) {
+ while (speedIndex < mLastSpeedTimes.length && (line = reader.readLine()) != null) {
splitter.setString(line);
Long.parseLong(splitter.next());
// The proc file reports time in 1/100 sec, so convert to milliseconds.
long time = Long.parseLong(splitter.next()) * 10;
- mDeltaSpeedTimes[speedIndex] = time - mLastSpeedTimes[speedIndex];
+ if (time < mLastSpeedTimes[speedIndex]) {
+ // The stats reset when the cpu hotplugged. That means that the time
+ // we read is offset from 0, so the time is the delta.
+ mDeltaSpeedTimes[speedIndex] = time;
+ } else {
+ mDeltaSpeedTimes[speedIndex] = time - mLastSpeedTimes[speedIndex];
+ }
mLastSpeedTimes[speedIndex] = time;
speedIndex++;
}
} catch (IOException e) {
- Slog.e(TAG, "Failed to read cpu-freq", e);
+ Slog.e(TAG, "Failed to read cpu-freq: " + e.getMessage());
Arrays.fill(mDeltaSpeedTimes, 0);
}
return mDeltaSpeedTimes;
diff --git a/core/java/com/android/internal/os/KernelUidCpuTimeReader.java b/core/java/com/android/internal/os/KernelUidCpuTimeReader.java
index 0df78ed..5d3043c 100644
--- a/core/java/com/android/internal/os/KernelUidCpuTimeReader.java
+++ b/core/java/com/android/internal/os/KernelUidCpuTimeReader.java
@@ -137,7 +137,7 @@
mLastPowerMaUs.put(uid, powerMaUs);
}
} catch (IOException e) {
- Slog.e(TAG, "Failed to read uid_cputime", e);
+ Slog.e(TAG, "Failed to read uid_cputime: " + e.getMessage());
}
mLastTimeReadUs = nowUs;
}
diff --git a/core/java/com/android/internal/os/PowerProfile.java b/core/java/com/android/internal/os/PowerProfile.java
index 4ede8dda..aaa9f73 100644
--- a/core/java/com/android/internal/os/PowerProfile.java
+++ b/core/java/com/android/internal/os/PowerProfile.java
@@ -59,6 +59,7 @@
/**
* Power consumption when CPU is in power collapse mode.
*/
+ @Deprecated
public static final String POWER_CPU_ACTIVE = "cpu.active";
/**
@@ -163,6 +164,7 @@
*/
public static final String POWER_CAMERA = "camera.avg";
+ @Deprecated
public static final String POWER_CPU_SPEEDS = "cpu.speeds";
/**
@@ -191,6 +193,7 @@
if (sPowerMap.size() == 0) {
readPowerValuesFromXml(context);
}
+ initCpuClusters();
}
private void readPowerValuesFromXml(Context context) {
@@ -249,7 +252,7 @@
}
// Now collect other config variables.
- int[] configResIds = new int[] {
+ int[] configResIds = new int[]{
com.android.internal.R.integer.config_bluetooth_idle_cur_ma,
com.android.internal.R.integer.config_bluetooth_rx_cur_ma,
com.android.internal.R.integer.config_bluetooth_tx_cur_ma,
@@ -260,7 +263,7 @@
com.android.internal.R.integer.config_wifi_operating_voltage_mv,
};
- String[] configResIdKeys = new String[] {
+ String[] configResIdKeys = new String[]{
POWER_BLUETOOTH_CONTROLLER_IDLE,
POWER_BLUETOOTH_CONTROLLER_RX,
POWER_BLUETOOTH_CONTROLLER_TX,
@@ -279,6 +282,69 @@
}
}
+ private CpuClusterKey[] mCpuClusters;
+
+ private static final String POWER_CPU_CLUSTER_CORE_COUNT = "cpu.clusters.cores";
+ private static final String POWER_CPU_CLUSTER_SPEED_PREFIX = "cpu.speeds.cluster";
+ private static final String POWER_CPU_CLUSTER_ACTIVE_PREFIX = "cpu.active.cluster";
+
+ @SuppressWarnings("deprecated")
+ private void initCpuClusters() {
+ // Figure out how many CPU clusters we're dealing with
+ final Object obj = sPowerMap.get(POWER_CPU_CLUSTER_CORE_COUNT);
+ if (obj == null || !(obj instanceof Double[])) {
+ // Default to single.
+ mCpuClusters = new CpuClusterKey[1];
+ mCpuClusters[0] = new CpuClusterKey(POWER_CPU_SPEEDS, POWER_CPU_ACTIVE, 1);
+
+ } else {
+ final Double[] array = (Double[]) obj;
+ mCpuClusters = new CpuClusterKey[array.length];
+ for (int cluster = 0; cluster < array.length; cluster++) {
+ int numCpusInCluster = (int) Math.round(array[cluster]);
+ mCpuClusters[cluster] = new CpuClusterKey(
+ POWER_CPU_CLUSTER_SPEED_PREFIX + cluster,
+ POWER_CPU_CLUSTER_ACTIVE_PREFIX + cluster,
+ numCpusInCluster);
+ }
+ }
+ }
+
+ public static class CpuClusterKey {
+ private final String timeKey;
+ private final String powerKey;
+ private final int numCpus;
+
+ private CpuClusterKey(String timeKey, String powerKey, int numCpus) {
+ this.timeKey = timeKey;
+ this.powerKey = powerKey;
+ this.numCpus = numCpus;
+ }
+ }
+
+ public int getNumCpuClusters() {
+ return mCpuClusters.length;
+ }
+
+ public int getNumCoresInCpuCluster(int index) {
+ return mCpuClusters[index].numCpus;
+ }
+
+ public int getNumSpeedStepsInCpuCluster(int index) {
+ Object value = sPowerMap.get(mCpuClusters[index].timeKey);
+ if (value != null && value instanceof Double[]) {
+ return ((Double[])value).length;
+ }
+ return 1; // Only one speed
+ }
+
+ public double getAveragePowerForCpu(int cluster, int step) {
+ if (cluster >= 0 && cluster < mCpuClusters.length) {
+ return getAveragePower(mCpuClusters[cluster].powerKey, step);
+ }
+ return 0;
+ }
+
/**
* Returns the average current in mA consumed by the subsystem, or the given
* default value if the subsystem has no recorded value.
@@ -344,16 +410,4 @@
public double getBatteryCapacity() {
return getAveragePower(POWER_BATTERY_CAPACITY);
}
-
- /**
- * Returns the number of speeds that the CPU can be run at.
- * @return
- */
- public int getNumSpeedSteps() {
- Object value = sPowerMap.get(POWER_CPU_SPEEDS);
- if (value != null && value instanceof Double[]) {
- return ((Double[])value).length;
- }
- return 1; // Only one speed
- }
}
diff --git a/core/java/com/android/internal/os/ZygoteInit.java b/core/java/com/android/internal/os/ZygoteInit.java
index 06919e1..59283bb 100644
--- a/core/java/com/android/internal/os/ZygoteInit.java
+++ b/core/java/com/android/internal/os/ZygoteInit.java
@@ -477,7 +477,7 @@
classPathElement, "*", instructionSet, false /* defer */);
if (dexoptNeeded != DexFile.NO_DEXOPT_NEEDED) {
installer.dexopt(classPathElement, Process.SYSTEM_UID, false,
- instructionSet, dexoptNeeded);
+ instructionSet, dexoptNeeded, false /* boot complete */);
}
}
} catch (IOException ioe) {
diff --git a/core/java/com/android/internal/policy/PhoneWindow.java b/core/java/com/android/internal/policy/PhoneWindow.java
index a7bdbe0..8e8d352 100644
--- a/core/java/com/android/internal/policy/PhoneWindow.java
+++ b/core/java/com/android/internal/policy/PhoneWindow.java
@@ -3010,16 +3010,16 @@
int vis = show ? VISIBLE : INVISIBLE;
visibilityChanged = state.targetVisibility != vis;
state.targetVisibility = vis;
+ LayoutParams lp = (LayoutParams) view.getLayoutParams();
+ if (lp.height != resolvedHeight || lp.width != resolvedWidth
+ || lp.gravity != resolvedGravity || lp.rightMargin != rightMargin) {
+ lp.height = resolvedHeight;
+ lp.width = resolvedWidth;
+ lp.gravity = resolvedGravity;
+ lp.rightMargin = rightMargin;
+ view.setLayoutParams(lp);
+ }
if (show) {
- LayoutParams lp = (LayoutParams) view.getLayoutParams();
- if (lp.height != resolvedHeight || lp.width != resolvedWidth
- || lp.gravity != resolvedGravity || lp.rightMargin != rightMargin) {
- lp.height = resolvedHeight;
- lp.width = resolvedWidth;
- lp.gravity = resolvedGravity;
- lp.rightMargin = rightMargin;
- view.setLayoutParams(lp);
- }
view.setBackgroundColor(color);
}
}
diff --git a/core/java/com/android/internal/statusbar/IStatusBar.aidl b/core/java/com/android/internal/statusbar/IStatusBar.aidl
index c1645c3..ba67cf4 100644
--- a/core/java/com/android/internal/statusbar/IStatusBar.aidl
+++ b/core/java/com/android/internal/statusbar/IStatusBar.aidl
@@ -69,5 +69,12 @@
void showAssistDisclosure();
void startAssist(in Bundle args);
+
+ /**
+ * Notifies the status bar that a camera launch gesture has been detected.
+ *
+ * @param source the identifier for the gesture, see {@link StatusBarManager}
+ */
+ void onCameraLaunchGestureDetected(int source);
}
diff --git a/core/java/com/android/internal/view/FloatingActionMode.java b/core/java/com/android/internal/view/FloatingActionMode.java
index 44df0ce..b44baa2 100644
--- a/core/java/com/android/internal/view/FloatingActionMode.java
+++ b/core/java/com/android/internal/view/FloatingActionMode.java
@@ -35,7 +35,7 @@
public class FloatingActionMode extends ActionMode {
private static final int MAX_HIDE_DURATION = 3000;
- private static final int MOVING_HIDE_DELAY = 300;
+ private static final int MOVING_HIDE_DELAY = 50;
private final Context mContext;
private final ActionMode.Callback2 mCallback;
@@ -181,7 +181,6 @@
// Content rect is moving.
mOriginatingView.removeCallbacks(mMovingOff);
mFloatingToolbarVisibilityHelper.setMoving(true);
- mFloatingToolbarVisibilityHelper.updateToolbarVisibility();
mOriginatingView.postDelayed(mMovingOff, MOVING_HIDE_DELAY);
mFloatingToolbar.setContentRect(mContentRectOnScreen);
@@ -189,9 +188,9 @@
}
} else {
mFloatingToolbarVisibilityHelper.setOutOfBounds(true);
- mFloatingToolbarVisibilityHelper.updateToolbarVisibility();
mContentRectOnScreen.setEmpty();
}
+ mFloatingToolbarVisibilityHelper.updateToolbarVisibility();
mPreviousContentRectOnScreen.set(mContentRectOnScreen);
}
diff --git a/core/java/com/android/internal/widget/FloatingToolbar.java b/core/java/com/android/internal/widget/FloatingToolbar.java
index ca6fe61..2a25db6 100644
--- a/core/java/com/android/internal/widget/FloatingToolbar.java
+++ b/core/java/com/android/internal/widget/FloatingToolbar.java
@@ -1488,10 +1488,9 @@
private static AnimatorSet createEnterAnimation(View view) {
AnimatorSet animation = new AnimatorSet();
animation.playTogether(
- ObjectAnimator.ofFloat(view, View.ALPHA, 0, 1).setDuration(200),
+ ObjectAnimator.ofFloat(view, View.ALPHA, 0, 1).setDuration(150),
// Make sure that view.x is always fixed throughout the duration of this animation.
ObjectAnimator.ofFloat(view, View.X, view.getX(), view.getX()));
- animation.setStartDelay(50);
return animation;
}
@@ -1506,7 +1505,7 @@
View view, int startDelay, Animator.AnimatorListener listener) {
AnimatorSet animation = new AnimatorSet();
animation.playTogether(
- ObjectAnimator.ofFloat(view, View.ALPHA, 1, 0).setDuration(200));
+ ObjectAnimator.ofFloat(view, View.ALPHA, 1, 0).setDuration(100));
animation.setStartDelay(startDelay);
animation.addListener(listener);
return animation;
diff --git a/core/java/com/android/internal/widget/ILockSettings.aidl b/core/java/com/android/internal/widget/ILockSettings.aidl
index dfb7c50..4e4552d 100644
--- a/core/java/com/android/internal/widget/ILockSettings.aidl
+++ b/core/java/com/android/internal/widget/ILockSettings.aidl
@@ -16,6 +16,7 @@
package com.android.internal.widget;
+import android.app.trust.IStrongAuthTracker;
import com.android.internal.widget.VerifyCredentialResponse;
/** {@hide} */
@@ -35,4 +36,7 @@
boolean checkVoldPassword(int userId);
boolean havePattern(int userId);
boolean havePassword(int userId);
+ void registerStrongAuthTracker(in IStrongAuthTracker tracker);
+ void unregisterStrongAuthTracker(in IStrongAuthTracker tracker);
+ void requireStrongAuth(int strongAuthReason, int userId);
}
diff --git a/core/java/com/android/internal/widget/LockPatternUtils.java b/core/java/com/android/internal/widget/LockPatternUtils.java
index e5b5d63..0aef320 100644
--- a/core/java/com/android/internal/widget/LockPatternUtils.java
+++ b/core/java/com/android/internal/widget/LockPatternUtils.java
@@ -16,18 +16,19 @@
package com.android.internal.widget;
-import android.Manifest;
+import android.annotation.IntDef;
import android.app.ActivityManager;
-import android.app.ActivityManagerNative;
import android.app.admin.DevicePolicyManager;
+import android.app.trust.IStrongAuthTracker;
import android.app.trust.TrustManager;
-import android.bluetooth.BluetoothClass;
import android.content.ComponentName;
import android.content.ContentResolver;
import android.content.Context;
-import android.content.pm.PackageManager;
import android.os.AsyncTask;
+import android.os.Handler;
import android.os.IBinder;
+import android.os.Looper;
+import android.os.Message;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.SystemClock;
@@ -38,9 +39,12 @@
import android.provider.Settings;
import android.text.TextUtils;
import android.util.Log;
+import android.util.SparseIntArray;
import com.google.android.collect.Lists;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
@@ -228,7 +232,7 @@
public void reportFailedPasswordAttempt(int userId) {
getDevicePolicyManager().reportFailedPasswordAttempt(userId);
getTrustManager().reportUnlockAttempt(false /* authenticated */, userId);
- getTrustManager().reportRequireCredentialEntry(userId);
+ requireStrongAuth(StrongAuthTracker.SOME_AUTH_REQUIRED_AFTER_WRONG_CREDENTIAL, userId);
}
public void reportSuccessfulPasswordAttempt(int userId) {
@@ -1067,12 +1071,22 @@
* enter a pattern.
*/
public long getLockoutAttemptDeadline(int userId) {
- final long deadline = getLong(LOCKOUT_ATTEMPT_DEADLINE, 0L, userId);
+ long deadline = getLong(LOCKOUT_ATTEMPT_DEADLINE, 0L, userId);
final long timeoutMs = getLong(LOCKOUT_ATTEMPT_TIMEOUT_MS, 0L, userId);
final long now = SystemClock.elapsedRealtime();
- if (deadline < now || deadline > (now + timeoutMs)) {
+ if (deadline < now && deadline != 0) {
+ // timeout expired
+ setLong(LOCKOUT_ATTEMPT_DEADLINE, 0, userId);
+ setLong(LOCKOUT_ATTEMPT_TIMEOUT_MS, 0, userId);
return 0L;
}
+
+ if (deadline > (now + timeoutMs)) {
+ // device was rebooted, set new deadline
+ deadline = now + timeoutMs;
+ setLong(LOCKOUT_ATTEMPT_DEADLINE, deadline, userId);
+ }
+
return deadline;
}
@@ -1163,10 +1177,32 @@
}
/**
- * @see android.app.trust.TrustManager#reportRequireCredentialEntry(int)
+ * Disable trust until credentials have been entered for user {@param userId}.
+ *
+ * Requires the {@link android.Manifest.permission#ACCESS_KEYGUARD_SECURE_STORAGE} permission.
+ *
+ * @param userId either an explicit user id or {@link android.os.UserHandle#USER_ALL}
*/
public void requireCredentialEntry(int userId) {
- getTrustManager().reportRequireCredentialEntry(userId);
+ requireStrongAuth(StrongAuthTracker.SOME_AUTH_REQUIRED_AFTER_USER_REQUEST, userId);
+ }
+
+ /**
+ * Requests strong authentication for user {@param userId}.
+ *
+ * Requires the {@link android.Manifest.permission#ACCESS_KEYGUARD_SECURE_STORAGE} permission.
+ *
+ * @param strongAuthReason a combination of {@link StrongAuthTracker.StrongAuthFlags} indicating
+ * the reason for and the strength of the requested authentication.
+ * @param userId either an explicit user id or {@link android.os.UserHandle#USER_ALL}
+ */
+ public void requireStrongAuth(@StrongAuthTracker.StrongAuthFlags int strongAuthReason,
+ int userId) {
+ try {
+ getLockSettings().requireStrongAuth(strongAuthReason, userId);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Error while requesting strong auth: " + e);
+ }
}
private void onAfterChangingPassword(int userHandle) {
@@ -1198,4 +1234,161 @@
private boolean shouldEncryptWithCredentials(boolean defaultValue) {
return isCredentialRequiredToDecrypt(defaultValue) && !isDoNotAskCredentialsOnBootSet();
}
+
+
+ public void registerStrongAuthTracker(final StrongAuthTracker strongAuthTracker) {
+ try {
+ getLockSettings().registerStrongAuthTracker(strongAuthTracker.mStub);
+ } catch (RemoteException e) {
+ throw new RuntimeException("Could not register StrongAuthTracker");
+ }
+ }
+
+ public void unregisterStrongAuthTracker(final StrongAuthTracker strongAuthTracker) {
+ try {
+ getLockSettings().unregisterStrongAuthTracker(strongAuthTracker.mStub);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Could not unregister StrongAuthTracker", e);
+ }
+ }
+
+ /**
+ * Tracks the global strong authentication state.
+ */
+ public static class StrongAuthTracker {
+
+ @IntDef(flag = true,
+ value = { STRONG_AUTH_NOT_REQUIRED,
+ STRONG_AUTH_REQUIRED_AFTER_BOOT,
+ STRONG_AUTH_REQUIRED_AFTER_DPM_LOCK_NOW,
+ SOME_AUTH_REQUIRED_AFTER_USER_REQUEST})
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface StrongAuthFlags {}
+
+ /**
+ * Strong authentication is not required.
+ */
+ public static final int STRONG_AUTH_NOT_REQUIRED = 0x0;
+
+ /**
+ * Strong authentication is required because the user has not authenticated since boot.
+ */
+ public static final int STRONG_AUTH_REQUIRED_AFTER_BOOT = 0x1;
+
+ /**
+ * Strong authentication is required because a device admin has requested it.
+ */
+ public static final int STRONG_AUTH_REQUIRED_AFTER_DPM_LOCK_NOW = 0x2;
+
+ /**
+ * Some authentication is required because the user has temporarily disabled trust.
+ */
+ public static final int SOME_AUTH_REQUIRED_AFTER_USER_REQUEST = 0x4;
+
+ /**
+ * Strong authentication is required because the user has been locked out after too many
+ * attempts.
+ */
+ public static final int STRONG_AUTH_REQUIRED_AFTER_LOCKOUT = 0x8;
+
+ /**
+ * Some authentication is required because the user has entered a wrong credential.
+ */
+ public static final int SOME_AUTH_REQUIRED_AFTER_WRONG_CREDENTIAL = 0x10;
+
+ public static final int DEFAULT = STRONG_AUTH_REQUIRED_AFTER_BOOT;
+
+ private static final int ALLOWING_FINGERPRINT = STRONG_AUTH_NOT_REQUIRED
+ | SOME_AUTH_REQUIRED_AFTER_USER_REQUEST
+ | SOME_AUTH_REQUIRED_AFTER_WRONG_CREDENTIAL;
+
+ private final SparseIntArray mStrongAuthRequiredForUser = new SparseIntArray();
+ private final H mHandler;
+
+ public StrongAuthTracker() {
+ this(Looper.myLooper());
+ }
+
+ /**
+ * @param looper the looper on whose thread calls to {@link #onStrongAuthRequiredChanged}
+ * will be scheduled.
+ */
+ public StrongAuthTracker(Looper looper) {
+ mHandler = new H(looper);
+ }
+
+ /**
+ * Returns {@link #STRONG_AUTH_NOT_REQUIRED} if strong authentication is not required,
+ * otherwise returns a combination of {@link StrongAuthFlags} indicating why strong
+ * authentication is required.
+ *
+ * @param userId the user for whom the state is queried.
+ */
+ public @StrongAuthFlags int getStrongAuthForUser(int userId) {
+ return mStrongAuthRequiredForUser.get(userId, DEFAULT);
+ }
+
+ /**
+ * @return true if unlocking with trust alone is allowed for {@param userId} by the current
+ * strong authentication requirements.
+ */
+ public boolean isTrustAllowedForUser(int userId) {
+ return getStrongAuthForUser(userId) == STRONG_AUTH_NOT_REQUIRED;
+ }
+
+ /**
+ * @return true if unlocking with fingerprint alone is allowed for {@param userId} by the
+ * current strong authentication requirements.
+ */
+ public boolean isFingerprintAllowedForUser(int userId) {
+ return (getStrongAuthForUser(userId) & ~ALLOWING_FINGERPRINT) == 0;
+ }
+
+ /**
+ * Called when the strong authentication requirements for {@param userId} changed.
+ */
+ public void onStrongAuthRequiredChanged(int userId) {
+ }
+
+ void handleStrongAuthRequiredChanged(@StrongAuthFlags int strongAuthFlags,
+ int userId) {
+
+ int oldValue = getStrongAuthForUser(userId);
+ if (strongAuthFlags != oldValue) {
+ if (strongAuthFlags == DEFAULT) {
+ mStrongAuthRequiredForUser.delete(userId);
+ } else {
+ mStrongAuthRequiredForUser.put(userId, strongAuthFlags);
+ }
+ onStrongAuthRequiredChanged(userId);
+ }
+ }
+
+
+ final IStrongAuthTracker.Stub mStub = new IStrongAuthTracker.Stub() {
+ @Override
+ public void onStrongAuthRequiredChanged(@StrongAuthFlags int strongAuthFlags,
+ int userId) {
+ mHandler.obtainMessage(H.MSG_ON_STRONG_AUTH_REQUIRED_CHANGED,
+ strongAuthFlags, userId).sendToTarget();
+ }
+ };
+
+ private class H extends Handler {
+ static final int MSG_ON_STRONG_AUTH_REQUIRED_CHANGED = 1;
+
+ public H(Looper looper) {
+ super(looper);
+ }
+
+ @Override
+ public void handleMessage(Message msg) {
+ switch (msg.what) {
+ case MSG_ON_STRONG_AUTH_REQUIRED_CHANGED:
+ handleStrongAuthRequiredChanged(msg.arg1, msg.arg2);
+ break;
+ }
+ }
+ };
+ }
}
diff --git a/core/java/com/android/internal/widget/ResolverDrawerLayout.java b/core/java/com/android/internal/widget/ResolverDrawerLayout.java
index 7679624..c4347f8 100644
--- a/core/java/com/android/internal/widget/ResolverDrawerLayout.java
+++ b/core/java/com/android/internal/widget/ResolverDrawerLayout.java
@@ -69,6 +69,12 @@
private int mCollapsibleHeight;
private int mUncollapsibleHeight;
+ /**
+ * The height in pixels of reserved space added to the top of the collapsed UI;
+ * e.g. chooser targets
+ */
+ private int mCollapsibleHeightReserved;
+
private int mTopOffset;
private boolean mIsDragging;
@@ -153,12 +159,62 @@
}
}
+ public void setCollapsibleHeightReserved(int heightPixels) {
+ final int oldReserved = mCollapsibleHeightReserved;
+ mCollapsibleHeightReserved = heightPixels;
+
+ final int dReserved = mCollapsibleHeightReserved - oldReserved;
+ if (dReserved != 0 && mIsDragging) {
+ mLastTouchY -= dReserved;
+ }
+
+ final int oldCollapsibleHeight = mCollapsibleHeight;
+ mCollapsibleHeight = Math.max(mCollapsibleHeight, getMaxCollapsedHeight());
+
+ if (updateCollapseOffset(oldCollapsibleHeight, !isDragging())) {
+ return;
+ }
+
+ invalidate();
+ }
+
private boolean isMoving() {
return mIsDragging || !mScroller.isFinished();
}
+ private boolean isDragging() {
+ return mIsDragging || getNestedScrollAxes() == SCROLL_AXIS_VERTICAL;
+ }
+
+ private boolean updateCollapseOffset(int oldCollapsibleHeight, boolean remainClosed) {
+ if (oldCollapsibleHeight == mCollapsibleHeight) {
+ return false;
+ }
+
+ if (isLaidOut()) {
+ final boolean isCollapsedOld = mCollapseOffset != 0;
+ if (remainClosed && (oldCollapsibleHeight < mCollapsibleHeight
+ && mCollapseOffset == oldCollapsibleHeight)) {
+ // Stay closed even at the new height.
+ mCollapseOffset = mCollapsibleHeight;
+ } else {
+ mCollapseOffset = Math.min(mCollapseOffset, mCollapsibleHeight);
+ }
+ final boolean isCollapsedNew = mCollapseOffset != 0;
+ if (isCollapsedOld != isCollapsedNew) {
+ notifyViewAccessibilityStateChangedIfNeeded(
+ AccessibilityEvent.CONTENT_CHANGE_TYPE_UNDEFINED);
+ }
+ } else {
+ // Start out collapsed at first unless we restored state for otherwise
+ mCollapseOffset = mOpenOnLayout ? 0 : mCollapsibleHeight;
+ }
+ return true;
+ }
+
private int getMaxCollapsedHeight() {
- return isSmallCollapsed() ? mMaxCollapsedHeightSmall : mMaxCollapsedHeight;
+ return (isSmallCollapsed() ? mMaxCollapsedHeightSmall : mMaxCollapsedHeight)
+ + mCollapsibleHeightReserved;
}
public void setOnDismissedListener(OnDismissedListener listener) {
@@ -676,7 +732,7 @@
final LayoutParams lp = (LayoutParams) child.getLayoutParams();
if (lp.alwaysShow && child.getVisibility() != GONE) {
measureChildWithMargins(child, widthSpec, widthPadding, heightSpec, heightUsed);
- heightUsed += lp.topMargin + child.getMeasuredHeight() + lp.bottomMargin;
+ heightUsed += getHeightUsed(child);
}
}
@@ -688,7 +744,7 @@
final LayoutParams lp = (LayoutParams) child.getLayoutParams();
if (!lp.alwaysShow && child.getVisibility() != GONE) {
measureChildWithMargins(child, widthSpec, widthPadding, heightSpec, heightUsed);
- heightUsed += lp.topMargin + child.getMeasuredHeight() + lp.bottomMargin;
+ heightUsed += getHeightUsed(child);
}
}
@@ -697,30 +753,43 @@
heightUsed - alwaysShowHeight - getMaxCollapsedHeight());
mUncollapsibleHeight = heightUsed - mCollapsibleHeight;
- if (isLaidOut()) {
- final boolean isCollapsedOld = mCollapseOffset != 0;
- if (oldCollapsibleHeight < mCollapsibleHeight
- && mCollapseOffset == oldCollapsibleHeight) {
- // Stay closed even at the new height.
- mCollapseOffset = mCollapsibleHeight;
- } else {
- mCollapseOffset = Math.min(mCollapseOffset, mCollapsibleHeight);
- }
- final boolean isCollapsedNew = mCollapseOffset != 0;
- if (isCollapsedOld != isCollapsedNew) {
- notifyViewAccessibilityStateChangedIfNeeded(
- AccessibilityEvent.CONTENT_CHANGE_TYPE_UNDEFINED);
- }
- } else {
- // Start out collapsed at first unless we restored state for otherwise
- mCollapseOffset = mOpenOnLayout ? 0 : mCollapsibleHeight;
- }
+ updateCollapseOffset(oldCollapsibleHeight, !isDragging());
mTopOffset = Math.max(0, heightSize - heightUsed) + (int) mCollapseOffset;
setMeasuredDimension(sourceWidth, heightSize);
}
+ private int getHeightUsed(View child) {
+ // This method exists because we're taking a fast path at measuring ListViews that
+ // lets us get away with not doing the more expensive wrap_content measurement which
+ // imposes double child view measurement costs. If we're looking at a ListView, we can
+ // check against the lowest child view plus padding and margin instead of the actual
+ // measured height of the ListView. This lets the ListView hang off the edge when
+ // all of the content would fit on-screen.
+
+ int heightUsed = child.getMeasuredHeight();
+ if (child instanceof AbsListView) {
+ final AbsListView lv = (AbsListView) child;
+ final int lvPaddingBottom = lv.getPaddingBottom();
+
+ int lowest = 0;
+ for (int i = 0, N = lv.getChildCount(); i < N; i++) {
+ final int bottom = lv.getChildAt(i).getBottom() + lvPaddingBottom;
+ if (bottom > lowest) {
+ lowest = bottom;
+ }
+ }
+
+ if (lowest < heightUsed) {
+ heightUsed = lowest;
+ }
+ }
+
+ final LayoutParams lp = (LayoutParams) child.getLayoutParams();
+ return lp.topMargin + heightUsed + lp.bottomMargin;
+ }
+
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
final int width = getWidth();
diff --git a/core/jni/Android.mk b/core/jni/Android.mk
index 6b07a47..fc15b964 100644
--- a/core/jni/Android.mk
+++ b/core/jni/Android.mk
@@ -20,6 +20,10 @@
LOCAL_CFLAGS += -DENABLE_CPUSETS
endif
+ifneq ($(ENABLE_SCHED_BOOST),)
+ LOCAL_CFLAGS += -DENABLE_SCHED_BOOST
+endif
+
LOCAL_CFLAGS += -DGL_GLEXT_PROTOTYPES -DEGL_EGLEXT_PROTOTYPES
LOCAL_CFLAGS += -DU_USING_ICU_NAMESPACE=0
diff --git a/core/jni/android/graphics/Bitmap.cpp b/core/jni/android/graphics/Bitmap.cpp
index 02d4334..cd1d81f 100755
--- a/core/jni/android/graphics/Bitmap.cpp
+++ b/core/jni/android/graphics/Bitmap.cpp
@@ -28,6 +28,7 @@
#include <cutils/ashmem.h>
#define DEBUG_PARCEL 0
+#define ASHMEM_BITMAP_MIN_SIZE (128 * (1 << 10))
namespace android {
@@ -993,7 +994,7 @@
// Map the bitmap in place from the ashmem region if possible otherwise copy.
Bitmap* nativeBitmap;
- if (blob.fd() >= 0 && (blob.isMutable() || !isMutable)) {
+ if (blob.fd() >= 0 && (blob.isMutable() || !isMutable) && (size >= ASHMEM_BITMAP_MIN_SIZE)) {
#if DEBUG_PARCEL
ALOGD("Bitmap.createFromParcel: mapped contents of %s bitmap from %s blob "
"(fds %s)",
diff --git a/core/jni/android_hardware_SensorManager.cpp b/core/jni/android_hardware_SensorManager.cpp
index ec56507..7d0afdc 100644
--- a/core/jni/android_hardware_SensorManager.cpp
+++ b/core/jni/android_hardware_SensorManager.cpp
@@ -138,7 +138,7 @@
(JNIEnv *env, jclass clazz, jstring opPackageName)
{
ScopedUtfChars opPackageNameUtf(env, opPackageName);
- return (jlong) new SensorManager(String16(opPackageNameUtf.c_str()));
+ return (jlong) &SensorManager::getInstanceForPackage(String16(opPackageNameUtf.c_str()));
}
static jboolean
diff --git a/core/jni/android_hardware_camera2_DngCreator.cpp b/core/jni/android_hardware_camera2_DngCreator.cpp
index 261cd7c..4faea18 100644
--- a/core/jni/android_hardware_camera2_DngCreator.cpp
+++ b/core/jni/android_hardware_camera2_DngCreator.cpp
@@ -20,6 +20,7 @@
#include <string.h>
#include <algorithm>
#include <memory>
+#include <vector>
#include <utils/Log.h>
#include <utils/Errors.h>
@@ -1649,8 +1650,7 @@
lsmHeight = static_cast<uint32_t>(entry1.data.i32[1]);
}
- camera_metadata_entry entry2 =
- results.find(ANDROID_STATISTICS_LENS_SHADING_MAP);
+ camera_metadata_entry entry2 = results.find(ANDROID_STATISTICS_LENS_SHADING_MAP);
camera_metadata_entry entry =
characteristics.find(ANDROID_SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE);
@@ -1660,10 +1660,11 @@
uint32_t width = static_cast<uint32_t>(entry.data.i32[2]);
uint32_t height = static_cast<uint32_t>(entry.data.i32[3]);
if (entry2.count > 0 && entry2.count == lsmWidth * lsmHeight * 4) {
+ // GainMap rectangle is relative to the active area origin.
err = builder.addGainMapsForMetadata(lsmWidth,
lsmHeight,
- ymin,
- xmin,
+ 0,
+ 0,
height,
width,
opcodeCfaLayout,
@@ -1675,6 +1676,45 @@
}
}
+
+ // Set up bad pixel correction list
+ camera_metadata_entry entry3 = characteristics.find(ANDROID_STATISTICS_HOT_PIXEL_MAP);
+
+ if ((entry3.count % 2) != 0) {
+ ALOGE("%s: Hot pixel map contains odd number of values, cannot map to pairs!",
+ __FUNCTION__);
+ jniThrowRuntimeException(env, "failed to add hotpixel map.");
+ return nullptr;
+ }
+
+ // Adjust the bad pixel coordinates to be relative to the origin of the active area DNG tag
+ std::vector<uint32_t> v;
+ for (size_t i = 0; i < entry3.count; i+=2) {
+ int32_t x = entry3.data.i32[i];
+ int32_t y = entry3.data.i32[i + 1];
+ x -= static_cast<int32_t>(xmin);
+ y -= static_cast<int32_t>(ymin);
+ if (x < 0 || y < 0 || static_cast<uint32_t>(x) >= width ||
+ static_cast<uint32_t>(y) >= width) {
+ continue;
+ }
+ v.push_back(x);
+ v.push_back(y);
+ }
+ const uint32_t* badPixels = &v[0];
+ uint32_t badPixelCount = v.size();
+
+ if (badPixelCount > 0) {
+ err = builder.addBadPixelListForMetadata(badPixels, badPixelCount, opcodeCfaLayout);
+
+ if (err != OK) {
+ ALOGE("%s: Could not add hotpixel map.", __FUNCTION__);
+ jniThrowRuntimeException(env, "failed to add hotpixel map.");
+ return nullptr;
+ }
+ }
+
+
size_t listSize = builder.getSize();
uint8_t opcodeListBuf[listSize];
err = builder.buildOpList(opcodeListBuf);
diff --git a/core/jni/android_os_Debug.cpp b/core/jni/android_os_Debug.cpp
index e8acd97..9b8243d 100644
--- a/core/jni/android_os_Debug.cpp
+++ b/core/jni/android_os_Debug.cpp
@@ -309,7 +309,9 @@
// This is the regular Dalvik heap.
whichHeap = HEAP_DALVIK;
subHeap = HEAP_DALVIK_NORMAL;
- } else if (strstr(name, "/dev/ashmem/dalvik-large object space") == name) {
+ } else if (strstr(name, "/dev/ashmem/dalvik-large object space") == name ||
+ strstr(name, "/dev/ashmem/dalvik-free list large object space")
+ == name) {
whichHeap = HEAP_DALVIK;
subHeap = HEAP_DALVIK_LARGE;
} else if (strstr(name, "/dev/ashmem/dalvik-non moving space") == name) {
diff --git a/core/jni/android_os_Parcel.cpp b/core/jni/android_os_Parcel.cpp
index 0f5ba83f..07b7e60 100644
--- a/core/jni/android_os_Parcel.cpp
+++ b/core/jni/android_os_Parcel.cpp
@@ -114,7 +114,7 @@
return parcel ? parcel->dataCapacity() : 0;
}
-static void android_os_Parcel_setDataSize(JNIEnv* env, jclass clazz, jlong nativePtr, jint size)
+static jlong android_os_Parcel_setDataSize(JNIEnv* env, jclass clazz, jlong nativePtr, jint size)
{
Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
if (parcel != NULL) {
@@ -122,7 +122,9 @@
if (err != NO_ERROR) {
signalExceptionForError(env, clazz, err);
}
+ return parcel->getOpenAshmemSize();
}
+ return 0;
}
static void android_os_Parcel_setDataPosition(JNIEnv* env, jclass clazz, jlong nativePtr, jint pos)
@@ -304,7 +306,7 @@
}
}
-static void android_os_Parcel_writeFileDescriptor(JNIEnv* env, jclass clazz, jlong nativePtr, jobject object)
+static jlong android_os_Parcel_writeFileDescriptor(JNIEnv* env, jclass clazz, jlong nativePtr, jobject object)
{
Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
if (parcel != NULL) {
@@ -313,7 +315,9 @@
if (err != NO_ERROR) {
signalExceptionForError(env, clazz, err);
}
+ return parcel->getOpenAshmemSize();
}
+ return 0;
}
static jbyteArray android_os_Parcel_createByteArray(JNIEnv* env, jclass clazz, jlong nativePtr)
@@ -550,12 +554,14 @@
return reinterpret_cast<jlong>(parcel);
}
-static void android_os_Parcel_freeBuffer(JNIEnv* env, jclass clazz, jlong nativePtr)
+static jlong android_os_Parcel_freeBuffer(JNIEnv* env, jclass clazz, jlong nativePtr)
{
Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
if (parcel != NULL) {
parcel->freeData();
+ return parcel->getOpenAshmemSize();
}
+ return 0;
}
static void android_os_Parcel_destroy(JNIEnv* env, jclass clazz, jlong nativePtr)
@@ -593,12 +599,12 @@
return ret;
}
-static void android_os_Parcel_unmarshall(JNIEnv* env, jclass clazz, jlong nativePtr,
- jbyteArray data, jint offset, jint length)
+static jlong android_os_Parcel_unmarshall(JNIEnv* env, jclass clazz, jlong nativePtr,
+ jbyteArray data, jint offset, jint length)
{
Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
if (parcel == NULL || length < 0) {
- return;
+ return 0;
}
jbyte* array = (jbyte*)env->GetPrimitiveArrayCritical(data, 0);
@@ -612,24 +618,26 @@
env->ReleasePrimitiveArrayCritical(data, array, 0);
}
+ return parcel->getOpenAshmemSize();
}
-static void android_os_Parcel_appendFrom(JNIEnv* env, jclass clazz, jlong thisNativePtr,
- jlong otherNativePtr, jint offset, jint length)
+static jlong android_os_Parcel_appendFrom(JNIEnv* env, jclass clazz, jlong thisNativePtr,
+ jlong otherNativePtr, jint offset, jint length)
{
Parcel* thisParcel = reinterpret_cast<Parcel*>(thisNativePtr);
if (thisParcel == NULL) {
- return;
+ return 0;
}
Parcel* otherParcel = reinterpret_cast<Parcel*>(otherNativePtr);
if (otherParcel == NULL) {
- return;
+ return thisParcel->getOpenAshmemSize();
}
status_t err = thisParcel->appendFrom(otherParcel, offset, length);
if (err != NO_ERROR) {
signalExceptionForError(env, clazz, err);
}
+ return thisParcel->getOpenAshmemSize();
}
static jboolean android_os_Parcel_hasFileDescriptors(JNIEnv* env, jclass clazz, jlong nativePtr)
@@ -722,7 +730,7 @@
{"nativeDataAvail", "(J)I", (void*)android_os_Parcel_dataAvail},
{"nativeDataPosition", "(J)I", (void*)android_os_Parcel_dataPosition},
{"nativeDataCapacity", "(J)I", (void*)android_os_Parcel_dataCapacity},
- {"nativeSetDataSize", "(JI)V", (void*)android_os_Parcel_setDataSize},
+ {"nativeSetDataSize", "(JI)J", (void*)android_os_Parcel_setDataSize},
{"nativeSetDataPosition", "(JI)V", (void*)android_os_Parcel_setDataPosition},
{"nativeSetDataCapacity", "(JI)V", (void*)android_os_Parcel_setDataCapacity},
@@ -737,7 +745,7 @@
{"nativeWriteDouble", "(JD)V", (void*)android_os_Parcel_writeDouble},
{"nativeWriteString", "(JLjava/lang/String;)V", (void*)android_os_Parcel_writeString},
{"nativeWriteStrongBinder", "(JLandroid/os/IBinder;)V", (void*)android_os_Parcel_writeStrongBinder},
- {"nativeWriteFileDescriptor", "(JLjava/io/FileDescriptor;)V", (void*)android_os_Parcel_writeFileDescriptor},
+ {"nativeWriteFileDescriptor", "(JLjava/io/FileDescriptor;)J", (void*)android_os_Parcel_writeFileDescriptor},
{"nativeCreateByteArray", "(J)[B", (void*)android_os_Parcel_createByteArray},
{"nativeReadBlob", "(J)[B", (void*)android_os_Parcel_readBlob},
@@ -755,12 +763,12 @@
{"clearFileDescriptor", "(Ljava/io/FileDescriptor;)V", (void*)android_os_Parcel_clearFileDescriptor},
{"nativeCreate", "()J", (void*)android_os_Parcel_create},
- {"nativeFreeBuffer", "(J)V", (void*)android_os_Parcel_freeBuffer},
+ {"nativeFreeBuffer", "(J)J", (void*)android_os_Parcel_freeBuffer},
{"nativeDestroy", "(J)V", (void*)android_os_Parcel_destroy},
{"nativeMarshall", "(J)[B", (void*)android_os_Parcel_marshall},
- {"nativeUnmarshall", "(J[BII)V", (void*)android_os_Parcel_unmarshall},
- {"nativeAppendFrom", "(JJII)V", (void*)android_os_Parcel_appendFrom},
+ {"nativeUnmarshall", "(J[BII)J", (void*)android_os_Parcel_unmarshall},
+ {"nativeAppendFrom", "(JJII)J", (void*)android_os_Parcel_appendFrom},
{"nativeHasFileDescriptors", "(J)Z", (void*)android_os_Parcel_hasFileDescriptors},
{"nativeWriteInterfaceToken", "(JLjava/lang/String;)V", (void*)android_os_Parcel_writeInterfaceToken},
{"nativeEnforceInterface", "(JLjava/lang/String;)V", (void*)android_os_Parcel_enforceInterface},
diff --git a/core/jni/android_text_StaticLayout.cpp b/core/jni/android_text_StaticLayout.cpp
index 90e4bb6..a94ea8b 100644
--- a/core/jni/android_text_StaticLayout.cpp
+++ b/core/jni/android_text_StaticLayout.cpp
@@ -117,9 +117,17 @@
b->finish();
}
-static jlong nLoadHyphenator(JNIEnv* env, jclass, jstring patternData) {
- ScopedStringChars str(env, patternData);
- Hyphenator* hyphenator = Hyphenator::load(str.get(), str.size());
+static jlong nLoadHyphenator(JNIEnv* env, jclass, jobject buffer, jint offset) {
+ const uint8_t* bytebuf = nullptr;
+ if (buffer != nullptr) {
+ void* rawbuf = env->GetDirectBufferAddress(buffer);
+ if (rawbuf != nullptr) {
+ bytebuf = reinterpret_cast<const uint8_t*>(rawbuf) + offset;
+ } else {
+ ALOGE("failed to get direct buffer address");
+ }
+ }
+ Hyphenator* hyphenator = Hyphenator::loadBinary(bytebuf);
return reinterpret_cast<jlong>(hyphenator);
}
@@ -177,7 +185,7 @@
{"nNewBuilder", "()J", (void*) nNewBuilder},
{"nFreeBuilder", "(J)V", (void*) nFreeBuilder},
{"nFinishBuilder", "(J)V", (void*) nFinishBuilder},
- {"nLoadHyphenator", "(Ljava/lang/String;)J", (void*) nLoadHyphenator},
+ {"nLoadHyphenator", "(Ljava/nio/ByteBuffer;I)J", (void*) nLoadHyphenator},
{"nSetLocale", "(JLjava/lang/String;J)V", (void*) nSetLocale},
{"nSetupParagraph", "(J[CIFIF[IIII)V", (void*) nSetupParagraph},
{"nSetIndents", "(J[I)V", (void*) nSetIndents},
diff --git a/core/jni/android_view_SurfaceControl.cpp b/core/jni/android_view_SurfaceControl.cpp
index 77af341..20352eb 100644
--- a/core/jni/android_view_SurfaceControl.cpp
+++ b/core/jni/android_view_SurfaceControl.cpp
@@ -64,6 +64,7 @@
jfieldID secure;
jfieldID appVsyncOffsetNanos;
jfieldID presentationDeadlineNanos;
+ jfieldID colorTransform;
} gPhysicalDisplayInfoClassInfo;
static struct {
@@ -401,6 +402,8 @@
info.appVsyncOffset);
env->SetLongField(infoObj, gPhysicalDisplayInfoClassInfo.presentationDeadlineNanos,
info.presentationDeadline);
+ env->SetIntField(infoObj, gPhysicalDisplayInfoClassInfo.colorTransform,
+ info.colorTransform);
env->SetObjectArrayElement(configArray, static_cast<jsize>(c), infoObj);
env->DeleteLocalRef(infoObj);
}
@@ -663,6 +666,8 @@
clazz, "appVsyncOffsetNanos", "J");
gPhysicalDisplayInfoClassInfo.presentationDeadlineNanos = GetFieldIDOrDie(env,
clazz, "presentationDeadlineNanos", "J");
+ gPhysicalDisplayInfoClassInfo.colorTransform = GetFieldIDOrDie(env, clazz,
+ "colorTransform", "I");
jclass rectClazz = FindClassOrDie(env, "android/graphics/Rect");
gRectClassInfo.bottom = GetFieldIDOrDie(env, rectClazz, "bottom", "I");
diff --git a/core/jni/com_android_internal_os_Zygote.cpp b/core/jni/com_android_internal_os_Zygote.cpp
index e7835db..a1fef4a 100644
--- a/core/jni/com_android_internal_os_Zygote.cpp
+++ b/core/jni/com_android_internal_os_Zygote.cpp
@@ -92,6 +92,14 @@
pid_t pid;
int status;
+ // It's necessary to save and restore the errno during this function.
+ // Since errno is stored per thread, changing it here modifies the errno
+ // on the thread on which this signal handler executes. If a signal occurs
+ // between a call and an errno check, it's possible to get the errno set
+ // here.
+ // See b/23572286 for extra information.
+ int saved_errno = errno;
+
while ((pid = waitpid(-1, &status, WNOHANG)) > 0) {
// Log process-death status that we care about. In general it is
// not safe to call LOG(...) from a signal handler because of
@@ -127,6 +135,8 @@
if (pid < 0 && errno != ECHILD) {
ALOGW("Zygote SIGCHLD error in waitpid: %s", strerror(errno));
}
+
+ errno = saved_errno;
}
// Configures the SIGCHLD handler for the zygote process. This is configured
@@ -417,6 +427,27 @@
}
}
+#ifdef ENABLE_SCHED_BOOST
+static void SetForkLoad(bool boost) {
+ // set scheduler knob to boost forked processes
+ pid_t currentPid = getpid();
+ // fits at most "/proc/XXXXXXX/sched_init_task_load\0"
+ char schedPath[35];
+ snprintf(schedPath, sizeof(schedPath), "/proc/%u/sched_init_task_load", currentPid);
+ int schedBoostFile = open(schedPath, O_WRONLY);
+ if (schedBoostFile < 0) {
+ ALOGW("Unable to set zygote scheduler boost");
+ return;
+ }
+ if (boost) {
+ write(schedBoostFile, "100\0", 4);
+ } else {
+ write(schedBoostFile, "0\0", 2);
+ }
+ close(schedBoostFile);
+}
+#endif
+
// The list of open zygote file descriptors.
static FileDescriptorTable* gOpenFdTable = NULL;
@@ -430,6 +461,10 @@
jstring instructionSet, jstring dataDir) {
SetSigChldHandler();
+#ifdef ENABLE_SCHED_BOOST
+ SetForkLoad(true);
+#endif
+
// Close any logging related FDs before we start evaluating the list of
// file descriptors.
__android_log_close();
@@ -592,6 +627,12 @@
}
} else if (pid > 0) {
// the parent process
+
+#ifdef ENABLE_SCHED_BOOST
+ // unset scheduler knob
+ SetForkLoad(false);
+#endif
+
}
return pid;
}
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index b2b0b5f..4b54459 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -1056,6 +1056,11 @@
<permission android:name="android.permission.CONNECTIVITY_INTERNAL"
android:protectionLevel="signature|privileged" />
+ <!-- Allows a system application to access hardware packet offload capabilities.
+ @hide -->
+ <permission android:name="android.permission.PACKET_KEEPALIVE_OFFLOAD"
+ android:protectionLevel="signature|privileged" />
+
<!-- @SystemApi
@hide -->
<permission android:name="android.permission.RECEIVE_DATA_ACTIVITY_CHANGE"
@@ -1464,7 +1469,7 @@
<permission android:name="android.permission.SYSTEM_ALERT_WINDOW"
android:label="@string/permlab_systemAlertWindow"
android:description="@string/permdesc_systemAlertWindow"
- android:protectionLevel="signature|preinstalled|appop|pre23" />
+ android:protectionLevel="signature|preinstalled|appop|pre23|development" />
<!-- ================================== -->
<!-- Permissions affecting the system wallpaper -->
@@ -1702,12 +1707,12 @@
android:protectionLevel="signature|privileged" />
<!-- Allows applications to change network connectivity state.
- <p>Protection level: signature
+ <p>Protection level: normal
-->
<permission android:name="android.permission.CHANGE_NETWORK_STATE"
android:description="@string/permdesc_changeNetworkState"
android:label="@string/permlab_changeNetworkState"
- android:protectionLevel="signature|preinstalled|appop|pre23" />
+ android:protectionLevel="normal" />
<!-- Allows an application to clear the caches of all installed
applications on the device.
@@ -2062,6 +2067,13 @@
<permission android:name="android.permission.SET_KEYBOARD_LAYOUT"
android:protectionLevel="signature" />
+ <!-- Allows an application to query tablet mode state and monitor changes
+ in it.
+ <p>Not for use by third-party applications.
+ @hide -->
+ <permission android:name="android.permission.TABLET_MODE"
+ android:protectionLevel="signature" />
+
<!-- Allows an application to request installing packages. Apps
targeting APIs greater than 22 must hold this permission in
order to use {@link android.content.Intent#ACTION_INSTALL_PACKAGE}.
@@ -2108,7 +2120,7 @@
<!-- Allows an application to grant specific permissions.
@hide -->
<permission android:name="android.permission.GRANT_RUNTIME_PERMISSIONS"
- android:protectionLevel="signature|installer" />
+ android:protectionLevel="signature|installer|verifier" />
<!-- Allows an app that has this permission and the permissions to install packages
to request certain runtime permissions to be granted at installation.
@@ -2157,6 +2169,13 @@
<permission android:name="android.permission.CONTROL_WIFI_DISPLAY"
android:protectionLevel="signature" />
+ <!-- Allows an application to control the color transforms applied to
+ displays system-wide.
+ <p>Not for use by third-party applications.</p>
+ @hide -->
+ <permission android:name="android.permission.CONFIGURE_DISPLAY_COLOR_TRANSFORM"
+ android:protectionLevel="signature" />
+
<!-- @SystemApi Allows an application to control VPN.
<p>Not for use by third-party applications.</p>
@hide -->
@@ -2513,6 +2532,10 @@
<permission android:name="android.permission.MANAGE_FINGERPRINT"
android:protectionLevel="system|signature" />
+ <!-- Allows an app to reset fingerprint attempt counter. Reserved for the system. @hide -->
+ <permission android:name="android.permission.RESET_FINGERPRINT_LOCKOUT"
+ android:protectionLevel="signature" />
+
<!-- Allows an application to control keyguard. Only allowed for system processes.
@hide -->
<permission android:name="android.permission.CONTROL_KEYGUARD"
diff --git a/core/res/res/drawable/spinner_background_material.xml b/core/res/res/drawable/spinner_background_material.xml
index d37f5b7..c2a2a26 100644
--- a/core/res/res/drawable/spinner_background_material.xml
+++ b/core/res/res/drawable/spinner_background_material.xml
@@ -17,18 +17,18 @@
<layer-list xmlns:android="http://schemas.android.com/apk/res/android"
android:paddingMode="stack"
android:paddingStart="0dp"
- android:paddingEnd="24dp"
+ android:paddingEnd="48dp"
android:paddingLeft="0dp"
android:paddingRight="0dp">
<item
- android:gravity="end|center_vertical"
- android:width="24dp"
- android:height="24dp"
+ android:gravity="end|fill_vertical"
+ android:width="48dp"
android:drawable="@drawable/control_background_40dp_material" />
<item
android:drawable="@drawable/ic_spinner_caret"
android:gravity="end|center_vertical"
android:width="24dp"
- android:height="24dp" />
+ android:height="24dp"
+ android:end="12dp" />
</layer-list>
diff --git a/core/res/res/layout/chooser_grid.xml b/core/res/res/layout/chooser_grid.xml
index dcdfb6c..41726fb 100644
--- a/core/res/res/layout/chooser_grid.xml
+++ b/core/res/res/layout/chooser_grid.xml
@@ -85,7 +85,7 @@
<ListView
android:layout_width="match_parent"
- android:layout_height="wrap_content"
+ android:layout_height="match_parent"
android:id="@+id/resolver_list"
android:clipToPadding="false"
android:scrollbarStyle="outsideOverlay"
diff --git a/core/res/res/layout/resolve_grid_item.xml b/core/res/res/layout/resolve_grid_item.xml
index 1c496f6..0a7ac77 100644
--- a/core/res/res/layout/resolve_grid_item.xml
+++ b/core/res/res/layout/resolve_grid_item.xml
@@ -70,6 +70,7 @@
android:minLines="2"
android:maxLines="2"
android:gravity="top|center_horizontal"
- android:ellipsize="marquee" />
+ android:ellipsize="marquee"
+ android:visibility="gone" />
</LinearLayout>
diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml
index f784ce5..b7651db 100644
--- a/core/res/res/values-af/strings.xml
+++ b/core/res/res/values-af/strings.xml
@@ -227,23 +227,23 @@
<string name="user_owner_label" msgid="2804351898001038951">"Persoonlik"</string>
<string name="managed_profile_label" msgid="6260850669674791528">"Werk"</string>
<string name="permgrouplab_contacts" msgid="3657758145679177612">"Kontakte"</string>
- <string name="permgroupdesc_contacts" msgid="6951499528303668046">"gaan by jou kontakte in"</string>
+ <string name="permgroupdesc_contacts" msgid="6951499528303668046">"in te gaan by jou kontakte"</string>
<string name="permgrouplab_location" msgid="7275582855722310164">"Ligging"</string>
- <string name="permgroupdesc_location" msgid="1346617465127855033">"verkry toegang tot hierdie toestel se ligging"</string>
+ <string name="permgroupdesc_location" msgid="1346617465127855033">"toegang te verkry tot hierdie toestel se ligging"</string>
<string name="permgrouplab_calendar" msgid="5863508437783683902">"Kalender"</string>
- <string name="permgroupdesc_calendar" msgid="3889615280211184106">"gaan by jou kalender in"</string>
+ <string name="permgroupdesc_calendar" msgid="3889615280211184106">"by jou kalender in te gaan"</string>
<string name="permgrouplab_sms" msgid="228308803364967808">"SMS"</string>
- <string name="permgroupdesc_sms" msgid="4656988620100940350">"stuur en bekyk SMS-boodskappe"</string>
+ <string name="permgroupdesc_sms" msgid="4656988620100940350">"SMS-boodskappe te stuur en te bekyk"</string>
<string name="permgrouplab_storage" msgid="1971118770546336966">"Stoor"</string>
- <string name="permgroupdesc_storage" msgid="637758554581589203">"verkry toegang tot foto\'s, media en lêers op jou toestel"</string>
+ <string name="permgroupdesc_storage" msgid="637758554581589203">"toegang te verkry tot foto\'s, media en lêers op jou toestel"</string>
<string name="permgrouplab_microphone" msgid="171539900250043464">"Mikrofoon"</string>
- <string name="permgroupdesc_microphone" msgid="4988812113943554584">"neem oudio op"</string>
+ <string name="permgroupdesc_microphone" msgid="4988812113943554584">"oudio op te neem"</string>
<string name="permgrouplab_camera" msgid="4820372495894586615">"Kamera"</string>
- <string name="permgroupdesc_camera" msgid="3250611594678347720">"neem foto\'s en neem video op"</string>
+ <string name="permgroupdesc_camera" msgid="3250611594678347720">"foto\'s en video te neem"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"Foon"</string>
- <string name="permgroupdesc_phone" msgid="6234224354060641055">"maak en bestuur foonoproepe"</string>
+ <string name="permgroupdesc_phone" msgid="6234224354060641055">"foonoproepe te maak en te bestuur"</string>
<string name="permgrouplab_sensors" msgid="416037179223226722">"Liggaamsensors"</string>
- <string name="permgroupdesc_sensors" msgid="7147968539346634043">"kry toegang tot sensordata oor jou lewenstekens"</string>
+ <string name="permgroupdesc_sensors" msgid="7147968539346634043">"toegang te verkry tot sensordata oor jou lewenstekens"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Haal venster-inhoud op"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Ondersoek die inhoud van \'n venster waarmee jy interaksie het."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Skakel Verken deur raak aan"</string>
@@ -272,7 +272,7 @@
<string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"Laat die program toe om seluitsending-boodskappe te lees wat deur jou toestel ontvang word. Seluitsending-waarskuwings word in sommige plekke afgelewer om jou van noodsituasies te waarsku. Kwaadwillige programme mag inmeng met die prestasie of die werking van jou toestel wanneer \'n noodgeval se seluitsending ontvang word."</string>
<string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"lees ingetekende nuus"</string>
<string name="permdesc_subscribedFeedsRead" msgid="5557058907906144505">"Laat die program toe om details oor die tans gesinkroniseerde strome te kry."</string>
- <string name="permlab_sendSms" msgid="7544599214260982981">"stuur en bekyk SMS-boodskappe"</string>
+ <string name="permlab_sendSms" msgid="7544599214260982981">"SMS-boodskappe te stuur en te bekyk"</string>
<string name="permdesc_sendSms" msgid="7094729298204937667">"Laat die program toe om SMS-boodskappe te stuur. Dit kan tot onverwagse heffings lei. Kwaadwillige programme kan jou geld kos deur boodskappe sonder jou bevestiging te stuur."</string>
<string name="permlab_readSms" msgid="8745086572213270480">"lees jou teksboodskappe (SMS of MMS)"</string>
<string name="permdesc_readSms" product="tablet" msgid="2467981548684735522">"Laat die program toe om SMS-boodskappe wat op jou tablet of SIM-kaart gestoor is, te lees. Dit laat die program toe om alle SMS-boodskappe te lees, ongeag van die inhoud of vertroulikheid daarvan."</string>
@@ -1488,6 +1488,7 @@
<item quantity="one">1 uur lank</item>
</plurals>
<string name="zen_mode_until" msgid="7336308492289875088">"Tot <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
+ <string name="zen_mode_alarm" msgid="9128205721301330797">"Tot <xliff:g id="FORMATTEDTIME">%1$s</xliff:g> (volgende wekker)"</string>
<string name="zen_mode_forever" msgid="7420011936770086993">"Totdat jy dit afskakel"</string>
<string name="zen_mode_forever_dnd" msgid="3792132696572189081">"Totdat jy Moenie steur nie afskakel"</string>
<string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string>
diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml
index 49fe30d..ddcd80b 100644
--- a/core/res/res/values-am/strings.xml
+++ b/core/res/res/values-am/strings.xml
@@ -1488,6 +1488,7 @@
<item quantity="other">ለ%d ሰዓት</item>
</plurals>
<string name="zen_mode_until" msgid="7336308492289875088">"እስከ <xliff:g id="FORMATTEDTIME">%1$s</xliff:g> ድረስ"</string>
+ <string name="zen_mode_alarm" msgid="9128205721301330797">"እስከ <xliff:g id="FORMATTEDTIME">%1$s</xliff:g> (ቀጣይ ማንቂያ)"</string>
<string name="zen_mode_forever" msgid="7420011936770086993">"ይህን እስኪያጠፉት ድረስ"</string>
<string name="zen_mode_forever_dnd" msgid="3792132696572189081">"አትረብሽን እስኪያጠፉ ድረስ"</string>
<string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string>
diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml
index 169a229..38928d7 100644
--- a/core/res/res/values-ar/strings.xml
+++ b/core/res/res/values-ar/strings.xml
@@ -1556,6 +1556,7 @@
<item quantity="one">لمدة ساعة</item>
</plurals>
<string name="zen_mode_until" msgid="7336308492289875088">"حتى <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
+ <string name="zen_mode_alarm" msgid="9128205721301330797">"حتى <xliff:g id="FORMATTEDTIME">%1$s</xliff:g> (التنبيه التالي)"</string>
<string name="zen_mode_forever" msgid="7420011936770086993">"لحين تعطيل هذا الإعداد"</string>
<string name="zen_mode_forever_dnd" msgid="3792132696572189081">"حتى يتم تعطيل \"الرجاء عدم الإزعاج\""</string>
<string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string>
diff --git a/core/res/res/values-az-rAZ/strings.xml b/core/res/res/values-az-rAZ/strings.xml
index 275d4b9..34df873 100644
--- a/core/res/res/values-az-rAZ/strings.xml
+++ b/core/res/res/values-az-rAZ/strings.xml
@@ -1488,6 +1488,7 @@
<item quantity="one">1 saat üçün</item>
</plurals>
<string name="zen_mode_until" msgid="7336308492289875088">"Saat <xliff:g id="FORMATTEDTIME">%1$s</xliff:g> qədər"</string>
+ <string name="zen_mode_alarm" msgid="9128205721301330797">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g> radəsinə qədər (növbəti siqnal)"</string>
<string name="zen_mode_forever" msgid="7420011936770086993">"Bunu söndürənə kimi"</string>
<string name="zen_mode_forever_dnd" msgid="3792132696572189081">"\"Narahat etməyin\" seçiminini deaktiv edənə kimi"</string>
<string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string>
diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml
index 455f4cf..14f09b7 100644
--- a/core/res/res/values-bg/strings.xml
+++ b/core/res/res/values-bg/strings.xml
@@ -1488,6 +1488,7 @@
<item quantity="one">За 1 ч</item>
</plurals>
<string name="zen_mode_until" msgid="7336308492289875088">"До <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
+ <string name="zen_mode_alarm" msgid="9128205721301330797">"До следващия будилник (<xliff:g id="FORMATTEDTIME">%1$s</xliff:g>)"</string>
<string name="zen_mode_forever" msgid="7420011936770086993">"Докато не изключите това"</string>
<string name="zen_mode_forever_dnd" msgid="3792132696572189081">"Докато не изключите „Не безпокойте“"</string>
<string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g>/<xliff:g id="REST">%2$s</xliff:g>"</string>
diff --git a/core/res/res/values-bn-rBD/strings.xml b/core/res/res/values-bn-rBD/strings.xml
index aa339e3..48f9971 100644
--- a/core/res/res/values-bn-rBD/strings.xml
+++ b/core/res/res/values-bn-rBD/strings.xml
@@ -1167,7 +1167,7 @@
<string name="sync_really_delete" msgid="2572600103122596243">"আইটেমগুলি মুছুন"</string>
<string name="sync_undo_deletes" msgid="2941317360600338602">"মোছাগুলিকে পূর্বাবস্থায় ফেরান"</string>
<string name="sync_do_nothing" msgid="3743764740430821845">"এখন কার মতো কিছু করবেন না"</string>
- <string name="choose_account_label" msgid="5655203089746423927">"একটি অ্যাকাউন্ট নির্বাচন করুন"</string>
+ <string name="choose_account_label" msgid="5655203089746423927">"একটি অ্যাকাউন্ট বাছুন"</string>
<string name="add_account_label" msgid="2935267344849993553">"একটি অ্যাকাউন্ট যোগ করুন"</string>
<string name="add_account_button_label" msgid="3611982894853435874">"অ্যাকাউন্ট যোগ করুন"</string>
<string name="number_picker_increment_button" msgid="2412072272832284313">"বাড়ান"</string>
@@ -1488,6 +1488,7 @@
<item quantity="other">%d ঘন্টার জন্য</item>
</plurals>
<string name="zen_mode_until" msgid="7336308492289875088">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g> পর্যন্ত"</string>
+ <string name="zen_mode_alarm" msgid="9128205721301330797">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g> পর্যন্ত (পরবর্তী অ্যালার্ম)"</string>
<string name="zen_mode_forever" msgid="7420011936770086993">"আপনার দ্বারা এটি বন্ধ করা পর্যন্ত"</string>
<string name="zen_mode_forever_dnd" msgid="3792132696572189081">"যতক্ষণ না পর্যন্ত আপনি বিরক্ত করবেন না বন্ধ করছেন"</string>
<string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string>
diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml
index 0fa7049..7d973a7 100644
--- a/core/res/res/values-ca/strings.xml
+++ b/core/res/res/values-ca/strings.xml
@@ -1047,7 +1047,7 @@
<string name="adb_active_notification_message" msgid="1016654627626476142">"Toca per desactivar la depuració USB"</string>
<string name="select_input_method" msgid="8547250819326693584">"Canvia el teclat"</string>
<string name="configure_input_methods" msgid="4769971288371946846">"Tria els teclats"</string>
- <string name="show_ime" msgid="9157568568695230830">"Mostra mètode d\'entrada."</string>
+ <string name="show_ime" msgid="9157568568695230830">"Mostra mètode d\'introducció"</string>
<string name="hardware" msgid="7517821086888990278">"Maquinari"</string>
<string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"Selecciona una disposició de teclat"</string>
<string name="select_keyboard_layout_notification_message" msgid="4465907700449257063">"Toca per seleccionar una disposició de teclat."</string>
@@ -1488,6 +1488,7 @@
<item quantity="one">Durant 1 h</item>
</plurals>
<string name="zen_mode_until" msgid="7336308492289875088">"Fins a les <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
+ <string name="zen_mode_alarm" msgid="9128205721301330797">"Fins a les <xliff:g id="FORMATTEDTIME">%1$s</xliff:g> (propera alarma)"</string>
<string name="zen_mode_forever" msgid="7420011936770086993">"Fins que no ho desactivis"</string>
<string name="zen_mode_forever_dnd" msgid="3792132696572189081">"Fins que desactivis el mode No molesteu"</string>
<string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string>
diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml
index 3d49f13..03f341d 100644
--- a/core/res/res/values-cs/strings.xml
+++ b/core/res/res/values-cs/strings.xml
@@ -231,7 +231,7 @@
<string name="permgrouplab_contacts" msgid="3657758145679177612">"Kontakty"</string>
<string name="permgroupdesc_contacts" msgid="6951499528303668046">"přístup ke kontaktům"</string>
<string name="permgrouplab_location" msgid="7275582855722310164">"Poloha"</string>
- <string name="permgroupdesc_location" msgid="1346617465127855033">"přístup k poloze tohoto zařízení"</string>
+ <string name="permgroupdesc_location" msgid="1346617465127855033">"přístup k poloze tohoto zařízení"</string>
<string name="permgrouplab_calendar" msgid="5863508437783683902">"Kalendář"</string>
<string name="permgroupdesc_calendar" msgid="3889615280211184106">"přístup ke kalendáři"</string>
<string name="permgrouplab_sms" msgid="228308803364967808">"SMS"</string>
@@ -1522,6 +1522,7 @@
<item quantity="one">1 h</item>
</plurals>
<string name="zen_mode_until" msgid="7336308492289875088">"Do <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
+ <string name="zen_mode_alarm" msgid="9128205721301330797">"Do <xliff:g id="FORMATTEDTIME">%1$s</xliff:g> (příští budík)"</string>
<string name="zen_mode_forever" msgid="7420011936770086993">"Dokud tuto funkci nevypnete"</string>
<string name="zen_mode_forever_dnd" msgid="3792132696572189081">"Dokud nevypnete režim Nerušit"</string>
<string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string>
diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml
index 28d699f..24e1ac1 100644
--- a/core/res/res/values-da/strings.xml
+++ b/core/res/res/values-da/strings.xml
@@ -143,7 +143,7 @@
<string name="fcError" msgid="3327560126588500777">"Forbindelsesproblemer eller ugyldig funktionskode."</string>
<string name="httpErrorOk" msgid="1191919378083472204">"OK"</string>
<string name="httpError" msgid="7956392511146698522">"Der opstod en netværksfejl."</string>
- <string name="httpErrorLookup" msgid="4711687456111963163">"Webadressen kunne ikke findes."</string>
+ <string name="httpErrorLookup" msgid="4711687456111963163">"Webadressen blev ikke fundet."</string>
<string name="httpErrorUnsupportedAuthScheme" msgid="6299980280442076799">"Ordningen for webstedsgodkendelse understøttes ikke."</string>
<string name="httpErrorAuth" msgid="1435065629438044534">"Der kunne ikke godkendes."</string>
<string name="httpErrorProxyAuth" msgid="1788207010559081331">"Godkendelse via proxyserveren mislykkedes."</string>
@@ -155,7 +155,7 @@
<string name="httpErrorFailedSslHandshake" msgid="96549606000658641">"Der kunne ikke oprettes en sikker forbindelse."</string>
<string name="httpErrorBadUrl" msgid="3636929722728881972">"Siden kunne ikke åbnes, fordi webadressen er ugyldig."</string>
<string name="httpErrorFile" msgid="2170788515052558676">"Der kunne ikke fås adgang til filen."</string>
- <string name="httpErrorFileNotFound" msgid="6203856612042655084">"Den ønskede fil kunne ikke findes."</string>
+ <string name="httpErrorFileNotFound" msgid="6203856612042655084">"Den ønskede fil blev ikke fundet."</string>
<string name="httpErrorTooManyRequests" msgid="1235396927087188253">"Der behandles for mange anmodninger. Prøv igen senere."</string>
<string name="notification_title" msgid="8967710025036163822">"Loginfejl for <xliff:g id="ACCOUNT">%1$s</xliff:g>"</string>
<string name="contentServiceSync" msgid="8353523060269335667">"Synkroniser"</string>
@@ -219,7 +219,7 @@
<string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"Flytilstand er slået FRA"</string>
<string name="global_action_settings" msgid="1756531602592545966">"Indstillinger"</string>
<string name="global_action_assist" msgid="3892832961594295030">"Assistance"</string>
- <string name="global_action_voice_assist" msgid="7751191495200504480">"Voice Assist"</string>
+ <string name="global_action_voice_assist" msgid="7751191495200504480">"Taleassistent"</string>
<string name="global_action_lockdown" msgid="8751542514724332873">"Lås nu"</string>
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
<string name="safeMode" msgid="2788228061547930246">"Sikker tilstand"</string>
@@ -248,7 +248,7 @@
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"undersøge indholdet i et vindue, du interagerer med."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"aktivere Udforsk ved berøring"</string>
<string name="capability_desc_canRequestTouchExploration" msgid="5800552516779249356">"De emner, der trykkes på, læses højt, og skærmen kan udforskes ved hjælp af bevægelser."</string>
- <string name="capability_title_canRequestEnhancedWebAccessibility" msgid="1739881766522594073">"aktivere forbedrede webhjælpefunktioner"</string>
+ <string name="capability_title_canRequestEnhancedWebAccessibility" msgid="1739881766522594073">"Aktivér udvidede webhjælpefunktioner"</string>
<string name="capability_desc_canRequestEnhancedWebAccessibility" msgid="7881063961507511765">"Der installeres muligvis scripts for at gøre appindhold mere tilgængeligt."</string>
<string name="capability_title_canRequestFilterKeyEvents" msgid="2103440391902412174">"observere tekst, du skriver"</string>
<string name="capability_desc_canRequestFilterKeyEvents" msgid="7463135292204152818">"Dette omfatter personlige data såsom kreditkortnumre og adgangskoder."</string>
@@ -493,8 +493,8 @@
<string name="permdesc_bindCarrierMessagingService" msgid="2762882888502113944">"Dette giver indehaveren mulighed for at knytte sig til det øverste grænsefladeniveau for et mobilselskabs beskedtjeneste. Dette bør ikke være nødvendigt i normale apps."</string>
<string name="permlab_bindCarrierServices" msgid="3233108656245526783">"knytte til tjenester fra mobilselskabet"</string>
<string name="permdesc_bindCarrierServices" msgid="1391552602551084192">"Tillader, at brugeren knytter sig til tjenester fra mobilselskabet. Dette bør aldrig være nødvendigt for almindelige apps."</string>
- <string name="permlab_access_notification_policy" msgid="4247510821662059671">"Adgang til Vil ikke forstyrres"</string>
- <string name="permdesc_access_notification_policy" msgid="3296832375218749580">"Giver appen tilladelse til at læse og skrive konfigurationen af Vil ikke forstyrres."</string>
+ <string name="permlab_access_notification_policy" msgid="4247510821662059671">"have adgang til Forstyr ikke"</string>
+ <string name="permdesc_access_notification_policy" msgid="3296832375218749580">"Giver appen tilladelse til at læse og skrive konfigurationen af Forstyr ikke."</string>
<string name="policylab_limitPassword" msgid="4497420728857585791">"Angiv regler for adgangskoder"</string>
<string name="policydesc_limitPassword" msgid="2502021457917874968">"Kontrollér længden samt tilladte tegn i adgangskoder og pinkoder til skærmlåsen."</string>
<string name="policylab_watchLogin" msgid="914130646942199503">"Overvåg forsøg på oplåsning af skærm"</string>
@@ -1488,11 +1488,12 @@
<item quantity="other">I %d t.</item>
</plurals>
<string name="zen_mode_until" msgid="7336308492289875088">"Indtil <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
+ <string name="zen_mode_alarm" msgid="9128205721301330797">"Indtil <xliff:g id="FORMATTEDTIME">%1$s</xliff:g> (næste alarm)"</string>
<string name="zen_mode_forever" msgid="7420011936770086993">"Indtil du slår denne indstilling fra"</string>
- <string name="zen_mode_forever_dnd" msgid="3792132696572189081">"Indtil du slår \"Vil ikke forstyrres\" fra"</string>
+ <string name="zen_mode_forever_dnd" msgid="3792132696572189081">"Indtil du slår \"Forstyr ikke\" fra"</string>
<string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g>/<xliff:g id="REST">%2$s</xliff:g>"</string>
<string name="toolbar_collapse_description" msgid="2821479483960330739">"Skjul"</string>
- <string name="zen_mode_feature_name" msgid="5254089399895895004">"Vil ikke forstyrres"</string>
+ <string name="zen_mode_feature_name" msgid="5254089399895895004">"Forstyr ikke"</string>
<string name="zen_mode_downtime_feature_name" msgid="2626974636779860146">"Nedetid"</string>
<string name="zen_mode_default_weeknights_name" msgid="3081318299464998143">"Hverdagsaften"</string>
<string name="zen_mode_default_weekends_name" msgid="2786495801019345244">"Weekend"</string>
diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml
index e460a5d..cf96923 100644
--- a/core/res/res/values-de/strings.xml
+++ b/core/res/res/values-de/strings.xml
@@ -1488,6 +1488,7 @@
<item quantity="one">Für 1 h</item>
</plurals>
<string name="zen_mode_until" msgid="7336308492289875088">"Bis <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
+ <string name="zen_mode_alarm" msgid="9128205721301330797">"Bis <xliff:g id="FORMATTEDTIME">%1$s</xliff:g> (nächste Weckzeit)"</string>
<string name="zen_mode_forever" msgid="7420011936770086993">"Bis zur Deaktivierung"</string>
<string name="zen_mode_forever_dnd" msgid="3792132696572189081">"Bis zur Deaktivierung von \"Nicht stören\""</string>
<string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g>/<xliff:g id="REST">%2$s</xliff:g>"</string>
diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml
index 748b22f..0aca5db 100644
--- a/core/res/res/values-el/strings.xml
+++ b/core/res/res/values-el/strings.xml
@@ -1488,6 +1488,7 @@
<item quantity="one">Για 1 ώρα</item>
</plurals>
<string name="zen_mode_until" msgid="7336308492289875088">"Έως τις <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
+ <string name="zen_mode_alarm" msgid="9128205721301330797">"Μέχρι τις <xliff:g id="FORMATTEDTIME">%1$s</xliff:g> (επόμενο ξυπνητήρι)"</string>
<string name="zen_mode_forever" msgid="7420011936770086993">"Μέχρι να το απενεργοποιήσετε"</string>
<string name="zen_mode_forever_dnd" msgid="3792132696572189081">"Μέχρι να απενεργοποιήσετε τη ρύθμιση \"Μην ενοχλείτε\""</string>
<string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string>
diff --git a/core/res/res/values-en-rAU/strings.xml b/core/res/res/values-en-rAU/strings.xml
index 8ab4859..f85f865 100644
--- a/core/res/res/values-en-rAU/strings.xml
+++ b/core/res/res/values-en-rAU/strings.xml
@@ -223,7 +223,7 @@
<string name="global_action_lockdown" msgid="8751542514724332873">"Lock now"</string>
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
<string name="safeMode" msgid="2788228061547930246">"Safe mode"</string>
- <string name="android_system_label" msgid="6577375335728551336">"Android System"</string>
+ <string name="android_system_label" msgid="6577375335728551336">"Android system"</string>
<string name="user_owner_label" msgid="2804351898001038951">"Personal"</string>
<string name="managed_profile_label" msgid="6260850669674791528">"Work"</string>
<string name="permgrouplab_contacts" msgid="3657758145679177612">"Contacts"</string>
@@ -1488,6 +1488,7 @@
<item quantity="one">For 1 hr</item>
</plurals>
<string name="zen_mode_until" msgid="7336308492289875088">"Until <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
+ <string name="zen_mode_alarm" msgid="9128205721301330797">"Until <xliff:g id="FORMATTEDTIME">%1$s</xliff:g> (next alarm)"</string>
<string name="zen_mode_forever" msgid="7420011936770086993">"Until you turn this off"</string>
<string name="zen_mode_forever_dnd" msgid="3792132696572189081">"Until you turn off Do Not Disturb"</string>
<string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string>
diff --git a/core/res/res/values-en-rGB/strings.xml b/core/res/res/values-en-rGB/strings.xml
index 8ab4859..f85f865 100644
--- a/core/res/res/values-en-rGB/strings.xml
+++ b/core/res/res/values-en-rGB/strings.xml
@@ -223,7 +223,7 @@
<string name="global_action_lockdown" msgid="8751542514724332873">"Lock now"</string>
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
<string name="safeMode" msgid="2788228061547930246">"Safe mode"</string>
- <string name="android_system_label" msgid="6577375335728551336">"Android System"</string>
+ <string name="android_system_label" msgid="6577375335728551336">"Android system"</string>
<string name="user_owner_label" msgid="2804351898001038951">"Personal"</string>
<string name="managed_profile_label" msgid="6260850669674791528">"Work"</string>
<string name="permgrouplab_contacts" msgid="3657758145679177612">"Contacts"</string>
@@ -1488,6 +1488,7 @@
<item quantity="one">For 1 hr</item>
</plurals>
<string name="zen_mode_until" msgid="7336308492289875088">"Until <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
+ <string name="zen_mode_alarm" msgid="9128205721301330797">"Until <xliff:g id="FORMATTEDTIME">%1$s</xliff:g> (next alarm)"</string>
<string name="zen_mode_forever" msgid="7420011936770086993">"Until you turn this off"</string>
<string name="zen_mode_forever_dnd" msgid="3792132696572189081">"Until you turn off Do Not Disturb"</string>
<string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string>
diff --git a/core/res/res/values-en-rIN/strings.xml b/core/res/res/values-en-rIN/strings.xml
index 8ab4859..f85f865 100644
--- a/core/res/res/values-en-rIN/strings.xml
+++ b/core/res/res/values-en-rIN/strings.xml
@@ -223,7 +223,7 @@
<string name="global_action_lockdown" msgid="8751542514724332873">"Lock now"</string>
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
<string name="safeMode" msgid="2788228061547930246">"Safe mode"</string>
- <string name="android_system_label" msgid="6577375335728551336">"Android System"</string>
+ <string name="android_system_label" msgid="6577375335728551336">"Android system"</string>
<string name="user_owner_label" msgid="2804351898001038951">"Personal"</string>
<string name="managed_profile_label" msgid="6260850669674791528">"Work"</string>
<string name="permgrouplab_contacts" msgid="3657758145679177612">"Contacts"</string>
@@ -1488,6 +1488,7 @@
<item quantity="one">For 1 hr</item>
</plurals>
<string name="zen_mode_until" msgid="7336308492289875088">"Until <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
+ <string name="zen_mode_alarm" msgid="9128205721301330797">"Until <xliff:g id="FORMATTEDTIME">%1$s</xliff:g> (next alarm)"</string>
<string name="zen_mode_forever" msgid="7420011936770086993">"Until you turn this off"</string>
<string name="zen_mode_forever_dnd" msgid="3792132696572189081">"Until you turn off Do Not Disturb"</string>
<string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string>
diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml
index 647b301..3bed012 100644
--- a/core/res/res/values-es-rUS/strings.xml
+++ b/core/res/res/values-es-rUS/strings.xml
@@ -629,7 +629,7 @@
<string name="relationTypeFriend" msgid="7313106762483391262">"Amigo"</string>
<string name="relationTypeManager" msgid="6365677861610137895">"Supervisor"</string>
<string name="relationTypeMother" msgid="4578571352962758304">"Madre"</string>
- <string name="relationTypeParent" msgid="4755635567562925226">"Padre"</string>
+ <string name="relationTypeParent" msgid="4755635567562925226">"Padre/madre"</string>
<string name="relationTypePartner" msgid="7266490285120262781">"Socio"</string>
<string name="relationTypeReferredBy" msgid="101573059844135524">"Recomendado por"</string>
<string name="relationTypeRelative" msgid="1799819930085610271">"Pariente"</string>
@@ -1488,6 +1488,7 @@
<item quantity="one">Durante 1 hora</item>
</plurals>
<string name="zen_mode_until" msgid="7336308492289875088">"Hasta la(s) <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
+ <string name="zen_mode_alarm" msgid="9128205721301330797">"Hasta la hora <xliff:g id="FORMATTEDTIME">%1$s</xliff:g> (próxima alarma)"</string>
<string name="zen_mode_forever" msgid="7420011936770086993">"Hasta que lo desactives"</string>
<string name="zen_mode_forever_dnd" msgid="3792132696572189081">"Hasta que desactives No molestar"</string>
<string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g>/<xliff:g id="REST">%2$s</xliff:g>"</string>
diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml
index 8d09cf0..0a1a7d7 100644
--- a/core/res/res/values-es/strings.xml
+++ b/core/res/res/values-es/strings.xml
@@ -890,7 +890,7 @@
<string name="whichHomeApplication" msgid="4307587691506919691">"Selecciona una aplicación de inicio"</string>
<string name="whichHomeApplicationNamed" msgid="4493438593214760979">"Usar %1$s como aplicación de inicio"</string>
<string name="alwaysUse" msgid="4583018368000610438">"Usar siempre para esta acción"</string>
- <string name="use_a_different_app" msgid="8134926230585710243">"Uitliza otra aplicación"</string>
+ <string name="use_a_different_app" msgid="8134926230585710243">"Utiliza otra aplicación"</string>
<string name="clearDefaultHintMsg" msgid="3252584689512077257">"Para borrar los valores predeterminados, accede a Ajustes del sistema > Aplicaciones > Descargadas."</string>
<string name="chooseActivity" msgid="7486876147751803333">"Selecciona una acción"</string>
<string name="chooseUsbActivity" msgid="6894748416073583509">"Elegir una aplicación para el dispositivo USB"</string>
@@ -1488,6 +1488,7 @@
<item quantity="one">Durante 1 hora</item>
</plurals>
<string name="zen_mode_until" msgid="7336308492289875088">"Hasta las <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
+ <string name="zen_mode_alarm" msgid="9128205721301330797">"Hasta las <xliff:g id="FORMATTEDTIME">%1$s</xliff:g> (próxima alarma)"</string>
<string name="zen_mode_forever" msgid="7420011936770086993">"Hasta apagar el dispositivo"</string>
<string name="zen_mode_forever_dnd" msgid="3792132696572189081">"Hasta que desactives la opción No molestar"</string>
<string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g>/<xliff:g id="REST">%2$s</xliff:g>"</string>
diff --git a/core/res/res/values-et-rEE/strings.xml b/core/res/res/values-et-rEE/strings.xml
index 2822119..ddf5a6d 100644
--- a/core/res/res/values-et-rEE/strings.xml
+++ b/core/res/res/values-et-rEE/strings.xml
@@ -1488,6 +1488,7 @@
<item quantity="one">1 h</item>
</plurals>
<string name="zen_mode_until" msgid="7336308492289875088">"Kuni <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
+ <string name="zen_mode_alarm" msgid="9128205721301330797">"Kuni <xliff:g id="FORMATTEDTIME">%1$s</xliff:g> (järgmine äratus)"</string>
<string name="zen_mode_forever" msgid="7420011936770086993">"Kuni lülitate selle välja"</string>
<string name="zen_mode_forever_dnd" msgid="3792132696572189081">"Kuni lülitate välja valiku Mitte segada"</string>
<string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g>/<xliff:g id="REST">%2$s</xliff:g>"</string>
diff --git a/core/res/res/values-eu-rES/strings.xml b/core/res/res/values-eu-rES/strings.xml
index 4d8e621..5bf8f200 100644
--- a/core/res/res/values-eu-rES/strings.xml
+++ b/core/res/res/values-eu-rES/strings.xml
@@ -227,23 +227,23 @@
<string name="user_owner_label" msgid="2804351898001038951">"Pertsonalak"</string>
<string name="managed_profile_label" msgid="6260850669674791528">"Lana"</string>
<string name="permgrouplab_contacts" msgid="3657758145679177612">"Kontaktuak"</string>
- <string name="permgroupdesc_contacts" msgid="6951499528303668046">"Atzitu kontaktuak"</string>
+ <string name="permgroupdesc_contacts" msgid="6951499528303668046">"kontaktuak atzitzeko"</string>
<string name="permgrouplab_location" msgid="7275582855722310164">"Kokapena"</string>
- <string name="permgroupdesc_location" msgid="1346617465127855033">"Atzitu gailuaren kokapena"</string>
+ <string name="permgroupdesc_location" msgid="1346617465127855033">"gailuaren kokapena atzitzeko"</string>
<string name="permgrouplab_calendar" msgid="5863508437783683902">"Egutegia"</string>
- <string name="permgroupdesc_calendar" msgid="3889615280211184106">"Atzitu egutegia"</string>
+ <string name="permgroupdesc_calendar" msgid="3889615280211184106">"egutegia atzitzeko"</string>
<string name="permgrouplab_sms" msgid="228308803364967808">"SMS mezuak"</string>
- <string name="permgroupdesc_sms" msgid="4656988620100940350">"Bidali eta ikusi SMS mezuak"</string>
+ <string name="permgroupdesc_sms" msgid="4656988620100940350">"SMS mezuak bidaltzeko eta ikusteko"</string>
<string name="permgrouplab_storage" msgid="1971118770546336966">"Memoria"</string>
- <string name="permgroupdesc_storage" msgid="637758554581589203">"Atzitu gailuko argazkiak, multimedia-elementuak eta fitxategiak"</string>
+ <string name="permgroupdesc_storage" msgid="637758554581589203">"gailuko argazkiak, multimedia-elementuak eta fitxategiak atzitzeko"</string>
<string name="permgrouplab_microphone" msgid="171539900250043464">"Mikrofonoa"</string>
- <string name="permgroupdesc_microphone" msgid="4988812113943554584">"Grabatu audioa"</string>
+ <string name="permgroupdesc_microphone" msgid="4988812113943554584">"audioa grabatzeko"</string>
<string name="permgrouplab_camera" msgid="4820372495894586615">"Kamera"</string>
- <string name="permgroupdesc_camera" msgid="3250611594678347720">"Atera argazkiak eta grabatu bideoak"</string>
+ <string name="permgroupdesc_camera" msgid="3250611594678347720">"argazkiak ateratzeko eta bideoak grabatzeko"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"Telefonoa"</string>
- <string name="permgroupdesc_phone" msgid="6234224354060641055">"Egin eta kudeatu telefono-deiak"</string>
+ <string name="permgroupdesc_phone" msgid="6234224354060641055">"telefono-deiak egiteko eta kudeatzeko"</string>
<string name="permgrouplab_sensors" msgid="416037179223226722">"Gorputz-sentsoreak"</string>
- <string name="permgroupdesc_sensors" msgid="7147968539346634043">"Atzitu bizi-konstanteei buruzko sentsore-datuak"</string>
+ <string name="permgroupdesc_sensors" msgid="7147968539346634043">"bizi-konstanteei buruzko sentsore-datuak atzitzeko"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Eskuratu leihoko edukia"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Arakatu irekita daukazun leihoko edukia."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Aktibatu ukipen bidez arakatzeko eginbidea"</string>
@@ -1488,6 +1488,7 @@
<item quantity="one">Ordubetez</item>
</plurals>
<string name="zen_mode_until" msgid="7336308492289875088">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g> arte"</string>
+ <string name="zen_mode_alarm" msgid="9128205721301330797">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g> arte (hurrengo alarma)"</string>
<string name="zen_mode_forever" msgid="7420011936770086993">"Zuk desaktibatu arte"</string>
<string name="zen_mode_forever_dnd" msgid="3792132696572189081">"\"Ez molestatu\" desaktibatzen duzun arte"</string>
<string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string>
diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml
index f060200..543a729 100644
--- a/core/res/res/values-fa/strings.xml
+++ b/core/res/res/values-fa/strings.xml
@@ -51,7 +51,7 @@
<string name="serviceDisabled" msgid="1937553226592516411">"سرویس غیرفعال شده است."</string>
<string name="serviceRegistered" msgid="6275019082598102493">"ثبت با موفقیت انجام شد"</string>
<string name="serviceErased" msgid="1288584695297200972">"پاک کردن با موفقیت انجام شد."</string>
- <string name="passwordIncorrect" msgid="7612208839450128715">"رمز ورود اشتباه است."</string>
+ <string name="passwordIncorrect" msgid="7612208839450128715">"گذرواژه اشتباه است."</string>
<string name="mmiComplete" msgid="8232527495411698359">"MMI کامل شد."</string>
<string name="badPin" msgid="9015277645546710014">"پین قدیمی که نوشتهاید صحیح نیست."</string>
<string name="badPuk" msgid="5487257647081132201">"PUK که نوشتهاید صحیح نیست."</string>
@@ -74,7 +74,7 @@
<string name="CfMmi" msgid="5123218989141573515">"هدایت تماس"</string>
<string name="CwMmi" msgid="9129678056795016867">"انتظار تماس"</string>
<string name="BaMmi" msgid="455193067926770581">"محدودیت تماس"</string>
- <string name="PwdMmi" msgid="7043715687905254199">"تغییر رمز ورود"</string>
+ <string name="PwdMmi" msgid="7043715687905254199">"تغییر گذرواژه"</string>
<string name="PinMmi" msgid="3113117780361190304">"تغییر پین"</string>
<string name="CnipMmi" msgid="3110534680557857162">"شماره تماس حاضر"</string>
<string name="CnirMmi" msgid="3062102121430548731">"شماره تماس محدود شده"</string>
@@ -144,14 +144,14 @@
<string name="httpErrorOk" msgid="1191919378083472204">"تأیید"</string>
<string name="httpError" msgid="7956392511146698522">"خطایی در شبکه وجود داشت."</string>
<string name="httpErrorLookup" msgid="4711687456111963163">"URL پیدا نشد."</string>
- <string name="httpErrorUnsupportedAuthScheme" msgid="6299980280442076799">"طرح کلی تأیید اعتبار سایت پشتیبانی نمیشود."</string>
+ <string name="httpErrorUnsupportedAuthScheme" msgid="6299980280442076799">"طرح کلی تأیید اعتبار سایت پشتیبانی نمیشود."</string>
<string name="httpErrorAuth" msgid="1435065629438044534">"تأیید اعتبار انجام نشد."</string>
<string name="httpErrorProxyAuth" msgid="1788207010559081331">"تأیید اعتبار از طریق سرور پروکسی انجام نشد."</string>
<string name="httpErrorConnect" msgid="8714273236364640549">"اتصال به سرور انجام نشد."</string>
<string name="httpErrorIO" msgid="2340558197489302188">"برقراری ارتباط با سرور ممکن نبود. بعداً دوباره امتحان کنید."</string>
<string name="httpErrorTimeout" msgid="4743403703762883954">"زمان اتصال به سرور تمام شده است."</string>
<string name="httpErrorRedirectLoop" msgid="8679596090392779516">"این صفحه دارای تعداد بسیار زیادی تغییر مسیر سرور است."</string>
- <string name="httpErrorUnsupportedScheme" msgid="5015730812906192208">"پروتکل پشتیبانی نمیشود."</string>
+ <string name="httpErrorUnsupportedScheme" msgid="5015730812906192208">"پروتکل پشتیبانی نمیشود."</string>
<string name="httpErrorFailedSslHandshake" msgid="96549606000658641">"اتصال امن ایجاد نشد."</string>
<string name="httpErrorBadUrl" msgid="3636929722728881972">"بدلیل نامعتبر بودن URL، باز کردن صفحه ممکن نیست."</string>
<string name="httpErrorFile" msgid="2170788515052558676">"دسترسی به فایل انجام نشد."</string>
@@ -397,16 +397,16 @@
<string name="permdesc_changeWifiMulticastState" product="tv" msgid="9031975661145014160">"به برنامه اجازه میدهد تا بستههایی را دریافت کند که در شبکه Wi-Fi با استفاده از آدرسهای چندبخشی نه تنها به تلویزیون شما، بلکه به همه دستگاهها ارسال میشود. این حالت نسبت به حالت غیر چندبخشی از انرژی بیشتری استفاده میکند."</string>
<string name="permdesc_changeWifiMulticastState" product="default" msgid="6851949706025349926">"به برنامه اجازه میدهد به دریافت بستههای ارسالی به همه دستگاههای موجود در شبکه Wi-Fi با استفاده از آدرسهای پخش چندگانه و نه فقط به تلفن شما بپردازند. این از توان مصرف بیشتری نسبت به حالت پخش غیرچندگانه استفاده میکند."</string>
<string name="permlab_bluetoothAdmin" msgid="6006967373935926659">"دسترسی به تنظیمات بلوتوث"</string>
- <string name="permdesc_bluetoothAdmin" product="tablet" msgid="6921177471748882137">"به برنامه اجازه میدهد تا رایانهٔ لوحی بلوتوث محلی را پیکربندی کرده، دستگاههای راه دور را شناسایی کرده و با آنها جفت شود."</string>
+ <string name="permdesc_bluetoothAdmin" product="tablet" msgid="6921177471748882137">"به برنامه اجازه میدهد تا رایانهٔ لوحی بلوتوث محلی را پیکربندی کرده، دستگاههای راه دور را شناسایی کرده و با آنها مرتبطسازی شود."</string>
<string name="permdesc_bluetoothAdmin" product="tv" msgid="3373125682645601429">"به برنامه اجازه میدهد تا تلویزیون بلوتوث محلی را پیکربندی کند و دستگاههای از راه دور را شناسایی کند و با آنها مرتبط شود."</string>
- <string name="permdesc_bluetoothAdmin" product="default" msgid="8931682159331542137">"به برنامه اجازه میدهد تا تلفن بلوتوث محلی را پیکربندی کند و دستگاههای راه دور را پیدا کند و با آنها جفت شود."</string>
+ <string name="permdesc_bluetoothAdmin" product="default" msgid="8931682159331542137">"به برنامه اجازه میدهد تا تلفن بلوتوث محلی را پیکربندی کند و دستگاههای راه دور را پیدا کند و با آنها مرتبطسازی شود."</string>
<string name="permlab_accessWimaxState" msgid="4195907010610205703">"اتصال و قطع اتصال از WiMAX"</string>
<string name="permdesc_accessWimaxState" msgid="6360102877261978887">"به برنامه امکان میدهد فعال بودن وایمکس و اطلاعات مربوط به هر یک از شبکههای وایمکس متصل را مشخص کند."</string>
<string name="permlab_changeWimaxState" msgid="2405042267131496579">"تغییر وضعیت WiMAX"</string>
<string name="permdesc_changeWimaxState" product="tablet" msgid="3156456504084201805">"به برنامه امکان میدهد رایانهٔ لوحی را به شبکههای وایمکس متصل کرده یا اتصال آن را از این شبکهها قطع کند."</string>
<string name="permdesc_changeWimaxState" product="tv" msgid="6022307083934827718">"به برنامه اجازه میدهد تا تلویزیون را به شبکههای WiMAX وصل یا ارتباط آن را با این شبکهها قطع کند."</string>
<string name="permdesc_changeWimaxState" product="default" msgid="697025043004923798">"به برنامه امکان میدهد تا تلفن را به شبکههای وایمکس متصل کرده یا اتصال آنرا از این شبکهها قطع کند."</string>
- <string name="permlab_bluetooth" msgid="6127769336339276828">"جفت کردن با دستگاههای بلوتوث"</string>
+ <string name="permlab_bluetooth" msgid="6127769336339276828">"مرتبطسازی با دستگاههای بلوتوث"</string>
<string name="permdesc_bluetooth" product="tablet" msgid="3480722181852438628">"به برنامه اجازه میدهد تا پیکربندی بلوتوث در رایانهٔ لوحی را مشاهده کند و اتصال با دستگاههای مرتبط را برقرار کرده و بپذیرد."</string>
<string name="permdesc_bluetooth" product="tv" msgid="3974124940101104206">"به برنامه اجازه میدهد تا پیکربندی بلوتوث را در تلویزیون مشاهده کند و اتصالات را با دستگاههای مرتبطشده ایجاد کند و بپذیرد."</string>
<string name="permdesc_bluetooth" product="default" msgid="3207106324452312739">"به برنامه اجازه میدهد تا پیکربندی بلوتوث در تلفن را مشاهده کند، و اتصالات دستگاههای مرتبط را برقرار کرده و بپذیرد."</string>
@@ -495,7 +495,7 @@
<string name="permdesc_bindCarrierServices" msgid="1391552602551084192">"به دارنده امکان میدهد به سرویسهای شرکت مخابراتی متصل شود. هرگز نباید برای برنامههای عادی مورد نیاز باشد."</string>
<string name="permlab_access_notification_policy" msgid="4247510821662059671">"دسترسی به حالت «مزاحم نشوید»"</string>
<string name="permdesc_access_notification_policy" msgid="3296832375218749580">"به برنامه امکان میدهد پیکربندی «مزاحم نشوید» را بخواند و بنویسد."</string>
- <string name="policylab_limitPassword" msgid="4497420728857585791">"تنظیم قوانین رمز ورود"</string>
+ <string name="policylab_limitPassword" msgid="4497420728857585791">"تنظیم قوانین گذرواژه"</string>
<string name="policydesc_limitPassword" msgid="2502021457917874968">"کنترل طول و نوع نویسههایی که در گذرواژه و پین قفل صفحه مجاز است."</string>
<string name="policylab_watchLogin" msgid="914130646942199503">"نمایش تلاشهای قفل گشایی صفحه"</string>
<string name="policydesc_watchLogin" product="tablet" msgid="3215729294215070072">"تعداد گذرواژههای نادرست تایپ شده را هنگام بازکردن قفل صفحه کنترل میکند، و اگر دفعات زیادی گذرواژه نادرست وارد شود رایانهٔ لوحی را قفل میکند و همه دادههای رایانهٔ لوحی را پاک میکند."</string>
@@ -532,7 +532,7 @@
<item msgid="7897544654242874543">"محل کار"</item>
<item msgid="1103601433382158155">"نمابر محل کار"</item>
<item msgid="1735177144948329370">"نمابر خانه"</item>
- <item msgid="603878674477207394">"پیجر"</item>
+ <item msgid="603878674477207394">"پیجو"</item>
<item msgid="1650824275177931637">"سایر موارد"</item>
<item msgid="9192514806975898961">"سفارشی"</item>
</string-array>
@@ -575,7 +575,7 @@
<string name="phoneTypeWork" msgid="8863939667059911633">"محل کار"</string>
<string name="phoneTypeFaxWork" msgid="3517792160008890912">"نمابر محل کار"</string>
<string name="phoneTypeFaxHome" msgid="2067265972322971467">"نمابر خانه"</string>
- <string name="phoneTypePager" msgid="7582359955394921732">"پیجر"</string>
+ <string name="phoneTypePager" msgid="7582359955394921732">"پیجو"</string>
<string name="phoneTypeOther" msgid="1544425847868765990">"سایر موارد"</string>
<string name="phoneTypeCallback" msgid="2712175203065678206">"برگرداندن تماس"</string>
<string name="phoneTypeCar" msgid="8738360689616716982">"خودرو"</string>
@@ -700,9 +700,9 @@
<string name="lockscreen_glogin_too_many_attempts" msgid="2751368605287288808">"تلاشهای زیادی برای کشیدن الگو صورت گرفته است"</string>
<string name="lockscreen_glogin_instructions" msgid="3931816256100707784">"برای بازگشایی قفل، با حساب Google خود وارد سیستم شوید."</string>
<string name="lockscreen_glogin_username_hint" msgid="8846881424106484447">"نام کاربری (ایمیل)"</string>
- <string name="lockscreen_glogin_password_hint" msgid="5958028383954738528">"رمز ورود"</string>
+ <string name="lockscreen_glogin_password_hint" msgid="5958028383954738528">"گذرواژه"</string>
<string name="lockscreen_glogin_submit_button" msgid="7130893694795786300">"ورود به سیستم"</string>
- <string name="lockscreen_glogin_invalid_input" msgid="1364051473347485908">"نام کاربر یا رمز ورود نامعتبر است."</string>
+ <string name="lockscreen_glogin_invalid_input" msgid="1364051473347485908">"نام کاربر یا گذرواژه نامعتبر است."</string>
<string name="lockscreen_glogin_account_recovery_hint" msgid="1696924763690379073">"نام کاربری یا گذرواژهٔ خود را فراموش کردید؟\nاز "<b>"google.com/accounts/recovery"</b>" بازدید کنید."</string>
<string name="lockscreen_glogin_checking_password" msgid="7114627351286933867">"در حال بررسی..."</string>
<string name="lockscreen_unlock_label" msgid="737440483220667054">"بازگشایی قفل"</string>
@@ -755,7 +755,7 @@
<string name="js_dialog_before_unload_negative_button" msgid="5614861293026099715">"ماندن در این صفحه"</string>
<string name="js_dialog_before_unload" msgid="3468816357095378590">"<xliff:g id="MESSAGE">%s</xliff:g>\n\nمطمئنید میخواهید این صفحه را ترک کنید؟"</string>
<string name="save_password_label" msgid="6860261758665825069">"تأیید"</string>
- <string name="double_tap_toast" msgid="4595046515400268881">"نکته: برای بزرگنمایی و کوچکنمایی، دو بار ضربه بزنید."</string>
+ <string name="double_tap_toast" msgid="4595046515400268881">"نکته: برای بزرگنمایی و کوچکنمایی، دو بار ضربه بزنید."</string>
<string name="autofill_this_form" msgid="4616758841157816676">"تکمیل خودکار"</string>
<string name="setup_autofill" msgid="7103495070180590814">"راهاندازی تکمیل خودکار"</string>
<string name="autofill_address_name_separator" msgid="6350145154779706772">" "</string>
@@ -775,19 +775,19 @@
<string name="autofill_area" msgid="3547409050889952423">"منطقه"</string>
<string name="autofill_emirate" msgid="2893880978835698818">"امارات"</string>
<string name="permlab_readHistoryBookmarks" msgid="3775265775405106983">"خواندن سابقه و نشانکهای وب شما"</string>
- <string name="permdesc_readHistoryBookmarks" msgid="8462378226600439658">"به برنامه اجازه میدهد سابقه نشانیهای اینترنتی را که مرورگر بازدید کرده است و همه نشانکهای مرورگر را بخواند. توجه: این مجوز توسط مرورگرهای شخص ثالث یا سایر برنامههای دارای قابلیت مرور وب قابل اجرا نیست."</string>
+ <string name="permdesc_readHistoryBookmarks" msgid="8462378226600439658">"به برنامه اجازه میدهد سابقه نشانیهای وب را که مرورگر بازدید کرده است و همه نشانکهای مرورگر را بخواند. توجه: این مجوز توسط مرورگرهای شخص ثالث یا سایر برنامههای دارای قابلیت مرور وب قابل اجرا نیست."</string>
<string name="permlab_writeHistoryBookmarks" msgid="3714785165273314490">"نوشتن نشانکهای وب و سابقه"</string>
<string name="permdesc_writeHistoryBookmarks" product="tablet" msgid="6825527469145760922">"به برنامه اجازه میدهد سابقه مرورگر یا نشانکهای ذخیره شده در رایانهٔ لوحی شما را اصلاح کند. این ویژگی ممکن است به برنامه اجازه دهد دادههای مرورگر را حذف یا اصلاح کند. توجه: این مجوز ممکن است توسط مرورگرهای شخص ثالث یا سایر برنامههای دارای قابلیت مرور وب قابل اجرا نباشد."</string>
<string name="permdesc_writeHistoryBookmarks" product="tv" msgid="7007393823197766548">"به برنامه اجازه میدهد تا سابقه یا نشانکهای ذخیره شده مرورگر در تلویزیون شما را تغییر دهد. شاید به برنامه اجازه دهد تا دادههای «مرورگر» را پاک کند یا تغییر دهد. توجه: این مجوز شاید توسط مرورگرهای شخص ثالث یا سایر برنامهها با قابلیتهای مرور وب اجرا شود."</string>
<string name="permdesc_writeHistoryBookmarks" product="default" msgid="8497389531014185509">"به برنامه اجازه میدهد سابقه مرورگر یا نشانکهای ذخیره شده در تلفن شما را اصلاح کند. این ویژگی ممکن است به برنامه اجازه دهد دادههای مرورگر را حذف یا اصلاح کند. توجه: این مجوز ممکن است توسط مرورگرهای شخص ثالث یا سایر برنامههای دارای قابلیت مرور وب قابل اجرا نباشد."</string>
<string name="permlab_setAlarm" msgid="1379294556362091814">"تنظیم یک هشدار"</string>
- <string name="permdesc_setAlarm" msgid="316392039157473848">"به برنامه اجازه میدهد تا هشداری را در برنامه ساعت زنگدار نصب شده تنظیم کند. برخی از برنامههای ساعت زنگدار نمیتوانند این ویژگی را اعمال کنند."</string>
+ <string name="permdesc_setAlarm" msgid="316392039157473848">"به برنامه اجازه میدهد تا هشداری را در برنامه ساعت زنگدار نصب شده تنظیم کند. برخی از برنامههای ساعت زنگدار نمیتوانند این ویژگی را اعمال کنند."</string>
<string name="permlab_addVoicemail" msgid="5525660026090959044">"افزودن پست صوتی"</string>
- <string name="permdesc_addVoicemail" msgid="6604508651428252437">"به برنامه اجازه میدهد تا پیامها را به صندوق دریافت پست صوتی شما اضافه کند."</string>
+ <string name="permdesc_addVoicemail" msgid="6604508651428252437">"به برنامه اجازه میدهد تا پیامها را به صندوق ورودی پست صوتی شما اضافه کند."</string>
<string name="permlab_writeGeolocationPermissions" msgid="5962224158955273932">"تغییر مجوزهای مکان جغرافیایی مرورگر"</string>
<string name="permdesc_writeGeolocationPermissions" msgid="1083743234522638747">"به برنامه اجازه میدهد تا مجوزهای جغرافیایی مرورگر را تغییر دهد. برنامههای مخرب میتوانند از آن استفاده کنند تا اطلاعات موقعیت مکانی را به سایتهای وب کتابخانه بفرستند."</string>
- <string name="save_password_message" msgid="767344687139195790">"میخواهید مرورگر این رمز ورود را به خاطر داشته باشد؟"</string>
- <string name="save_password_notnow" msgid="6389675316706699758">"الآن نه"</string>
+ <string name="save_password_message" msgid="767344687139195790">"میخواهید مرورگر این گذرواژه را به خاطر داشته باشد؟"</string>
+ <string name="save_password_notnow" msgid="6389675316706699758">"اکنون نه"</string>
<string name="save_password_remember" msgid="6491879678996749466">"به خاطر سپردن"</string>
<string name="save_password_never" msgid="8274330296785855105">"هیچوقت"</string>
<string name="open_permission_deny" msgid="7374036708316629800">"شما اجازه بازکردن این صفحه را ندارید."</string>
@@ -894,15 +894,15 @@
<string name="clearDefaultHintMsg" msgid="3252584689512077257">"پیشفرض را در تنظیمات سیستم> برنامهها> مورد دانلود شده پاک کنید."</string>
<string name="chooseActivity" msgid="7486876147751803333">"انتخاب عملکرد"</string>
<string name="chooseUsbActivity" msgid="6894748416073583509">"انتخاب برنامه برای دستگاه USB"</string>
- <string name="noApplications" msgid="2991814273936504689">"هیچ برنامهای نمیتواند این کار را انجام دهد."</string>
+ <string name="noApplications" msgid="2991814273936504689">"هیچ برنامهای نمیتواند این کار را انجام دهد."</string>
<string name="aerr_title" msgid="1905800560317137752"></string>
<string name="aerr_application" msgid="932628488013092776">"متأسفانه، <xliff:g id="APPLICATION">%1$s</xliff:g> متوقف شده است."</string>
<string name="aerr_process" msgid="4507058997035697579">"متأسفانه، پردازش <xliff:g id="PROCESS">%1$s</xliff:g> متوقف شده است."</string>
<string name="anr_title" msgid="4351948481459135709"></string>
- <string name="anr_activity_application" msgid="1904477189057199066">"<xliff:g id="APPLICATION">%2$s</xliff:g> پاسخ نمیدهد.\n\nآیا میخواهید آنرا ببندید؟"</string>
- <string name="anr_activity_process" msgid="5776209883299089767">"فعالیت <xliff:g id="ACTIVITY">%1$s</xliff:g> پاسخ نمیدهد.\n\nآیا میخواهید آن را ببندید؟"</string>
- <string name="anr_application_process" msgid="8941757607340481057">"<xliff:g id="APPLICATION">%1$s</xliff:g> پاسخ نمیدهد. آیا میخواهید آن را ببندید؟"</string>
- <string name="anr_process" msgid="6513209874880517125">"روند <xliff:g id="PROCESS">%1$s</xliff:g> پاسخ نمیدهد. \n\nآیا میخواهید آن را ببندید؟"</string>
+ <string name="anr_activity_application" msgid="1904477189057199066">"<xliff:g id="APPLICATION">%2$s</xliff:g> پاسخ نمیدهد.\n\nآیا میخواهید آنرا ببندید؟"</string>
+ <string name="anr_activity_process" msgid="5776209883299089767">"فعالیت <xliff:g id="ACTIVITY">%1$s</xliff:g> پاسخ نمیدهد.\n\nآیا میخواهید آن را ببندید؟"</string>
+ <string name="anr_application_process" msgid="8941757607340481057">"<xliff:g id="APPLICATION">%1$s</xliff:g> پاسخ نمیدهد. آیا میخواهید آن را ببندید؟"</string>
+ <string name="anr_process" msgid="6513209874880517125">"روند <xliff:g id="PROCESS">%1$s</xliff:g> پاسخ نمیدهد. \n\nآیا میخواهید آن را ببندید؟"</string>
<string name="force_close" msgid="8346072094521265605">"تأیید"</string>
<string name="report" msgid="4060218260984795706">"گزارش"</string>
<string name="wait" msgid="7147118217226317732">"منتظر بمانید"</string>
@@ -1005,14 +1005,14 @@
<string name="sms_short_code_confirm_never_allow" msgid="446992765774269673">"همیشه غیرمجاز"</string>
<string name="sim_removed_title" msgid="6227712319223226185">"سیم کارت برداشته شد"</string>
<string name="sim_removed_message" msgid="5450336489923274918">"تا زمانی که با یک سیمکارت معتبر دوباره راهاندازی نکنید شبکه تلفن همراه غیر قابل دسترس خواهد بود."</string>
- <string name="sim_done_button" msgid="827949989369963775">"انجام شد"</string>
+ <string name="sim_done_button" msgid="827949989369963775">"تمام"</string>
<string name="sim_added_title" msgid="3719670512889674693">"سیم کارت اضافه شد"</string>
<string name="sim_added_message" msgid="7797975656153714319">"برای دسترسی به شبکه تلفن همراه، دستگاهتان را مجدداً راهاندازی کنید."</string>
<string name="sim_restart_button" msgid="4722407842815232347">"راهاندازی مجدد"</string>
<string name="time_picker_dialog_title" msgid="8349362623068819295">"تنظیم زمان"</string>
<string name="date_picker_dialog_title" msgid="5879450659453782278">"تاریخ تنظیم"</string>
<string name="date_time_set" msgid="5777075614321087758">"تنظیم"</string>
- <string name="date_time_done" msgid="2507683751759308828">"انجام شد"</string>
+ <string name="date_time_done" msgid="2507683751759308828">"تمام"</string>
<string name="perms_new_perm_prefix" msgid="8257740710754301407"><font size="12" fgcolor="#ff33b5e5">"جدید: "</font></string>
<string name="perms_description_app" msgid="5139836143293299417">"ارائه شده توسط <xliff:g id="APP_NAME">%1$s</xliff:g> ."</string>
<string name="no_permissions" msgid="7283357728219338112">"مجوزی لازم نیست"</string>
@@ -1097,13 +1097,13 @@
<string name="permdesc_readInstallSessions" msgid="2049771699626019849">"به برنامه اجازه میدهد جلسات نصب را بخواند. این کار به برنامه اجازه میدهد جزئیات نصبهای بسته فعال را ببیند."</string>
<string name="permlab_requestInstallPackages" msgid="1772330282283082214">"درخواست نصب بستهبندی"</string>
<string name="permdesc_requestInstallPackages" msgid="5740101072486783082">"به برنامه اجازه میدهد درخواست نصب بستهبندی کند."</string>
- <string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"دوبار لمس کنید تا بزرگنمایی کنترل شود"</string>
+ <string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"دوبار لمس کنید تا بزرگنمایی کنترل شود"</string>
<string name="gadget_host_error_inflating" msgid="4882004314906466162">"افزودن ابزارک انجام نشد."</string>
<string name="ime_action_go" msgid="8320845651737369027">"برو"</string>
<string name="ime_action_search" msgid="658110271822807811">"جستجو"</string>
<string name="ime_action_send" msgid="2316166556349314424">"ارسال"</string>
<string name="ime_action_next" msgid="3138843904009813834">"بعدی"</string>
- <string name="ime_action_done" msgid="8971516117910934605">"انجام شد"</string>
+ <string name="ime_action_done" msgid="8971516117910934605">"تمام"</string>
<string name="ime_action_previous" msgid="1443550039250105948">"قبلی"</string>
<string name="ime_action_default" msgid="2840921885558045721">"اجرا کردن"</string>
<string name="dial_number_using" msgid="5789176425167573586">"شماره گیری \nبا استفاده از <xliff:g id="NUMBER">%s</xliff:g>"</string>
@@ -1149,7 +1149,7 @@
<item quantity="one"><xliff:g id="INDEX">%d</xliff:g> از <xliff:g id="TOTAL">%d</xliff:g></item>
<item quantity="other"><xliff:g id="INDEX">%d</xliff:g> از <xliff:g id="TOTAL">%d</xliff:g></item>
</plurals>
- <string name="action_mode_done" msgid="7217581640461922289">"انجام شد"</string>
+ <string name="action_mode_done" msgid="7217581640461922289">"تمام"</string>
<string name="progress_erasing" product="nosdcard" msgid="4521573321524340058">"در حال پاک کردن حافظهٔ USB..."</string>
<string name="progress_erasing" product="default" msgid="6596988875507043042">"در حال پاک کردن کارت SD..."</string>
<string name="share" msgid="1778686618230011964">"اشتراکگذاری"</string>
@@ -1161,7 +1161,7 @@
<string name="gpsNotifTitle" msgid="5446858717157416839">"درخواست موقعیت مکانی"</string>
<string name="gpsNotifMessage" msgid="1374718023224000702">"درخواست شده توسط <xliff:g id="NAME">%1$s</xliff:g> (<xliff:g id="SERVICE">%2$s</xliff:g>)"</string>
<string name="gpsVerifYes" msgid="2346566072867213563">"بله"</string>
- <string name="gpsVerifNo" msgid="1146564937346454865">"خیر"</string>
+ <string name="gpsVerifNo" msgid="1146564937346454865">"نه"</string>
<string name="sync_too_many_deletes" msgid="5296321850662746890">"از حد مجاز حذف فراتر رفت"</string>
<string name="sync_too_many_deletes_desc" msgid="496551671008694245">"<xliff:g id="NUMBER_OF_DELETED_ITEMS">%1$d</xliff:g> مورد حذف شده برای <xliff:g id="TYPE_OF_SYNC">%2$s</xliff:g>، حساب <xliff:g id="ACCOUNT_NAME">%3$s</xliff:g> وجود دارد. میخواهید چه کاری انجام دهید؟"</string>
<string name="sync_really_delete" msgid="2572600103122596243">"حذف موارد"</string>
@@ -1191,7 +1191,7 @@
<string name="keyboardview_keycode_alt" msgid="4856868820040051939">"Alt"</string>
<string name="keyboardview_keycode_cancel" msgid="1203984017245783244">"لغو"</string>
<string name="keyboardview_keycode_delete" msgid="3337914833206635744">"Delete"</string>
- <string name="keyboardview_keycode_done" msgid="1992571118466679775">"انجام شد"</string>
+ <string name="keyboardview_keycode_done" msgid="1992571118466679775">"تمام"</string>
<string name="keyboardview_keycode_mode_change" msgid="4547387741906537519">"تغییر حالت"</string>
<string name="keyboardview_keycode_shift" msgid="2270748814315147690">"Shift"</string>
<string name="keyboardview_keycode_enter" msgid="2985864015076059467">"Enter"</string>
@@ -1274,7 +1274,7 @@
<string name="media_route_status_in_use" msgid="4533786031090198063">"در حال استفاده"</string>
<string name="display_manager_built_in_display_name" msgid="2583134294292563941">"صفحه نمایش از خود"</string>
<string name="display_manager_hdmi_display_name" msgid="1555264559227470109">"صفحه HDMI"</string>
- <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"همپوشانی #<xliff:g id="ID">%1$d</xliff:g>"</string>
+ <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"همپوشانی #<xliff:g id="ID">%1$d</xliff:g>"</string>
<string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g>x<xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
<string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">"، امن"</string>
<string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"الگو را فراموش کردهاید"</string>
@@ -1434,7 +1434,7 @@
<string name="immersive_cling_title" msgid="8394201622932303336">"مشاهده در حالت تمام صفحه"</string>
<string name="immersive_cling_description" msgid="3482371193207536040">"برای خروج، انگشتتان را از بالای صفحه به پایین بکشید."</string>
<string name="immersive_cling_positive" msgid="5016839404568297683">"متوجه شدم"</string>
- <string name="done_label" msgid="2093726099505892398">"انجام شد"</string>
+ <string name="done_label" msgid="2093726099505892398">"تمام"</string>
<string name="hour_picker_description" msgid="6698199186859736512">"لغزنده دایرهای ساعت"</string>
<string name="minute_picker_description" msgid="8606010966873791190">"لغزنده دایرهای دقیقه"</string>
<string name="select_hours" msgid="6043079511766008245">"انتخاب ساعت"</string>
@@ -1454,7 +1454,7 @@
<string name="package_installed_device_owner" msgid="8420696545959087545">"توسط سرپرستتان نصب شد"</string>
<string name="package_updated_device_owner" msgid="8856631322440187071">"توسط سرپرست شما بهروزرسانی شد"</string>
<string name="package_deleted_device_owner" msgid="7650577387493101353">"توسط سرپرستتان حذف شد"</string>
- <string name="battery_saver_description" msgid="1960431123816253034">"برای کمک به بهبود ماندگاری باتری، ذخیره کننده باتری عملکرد دستگاهتان را کاهش میدهد و لرزش، سرویسهای مبتنی بر مکان، و دسترسی به اکثر دادهها در پسزمینه را محدود میکند. ایمیل، پیامرسانی و برنامههای دیگری که به همگامسازی متکی هستند، تا زمانیکه آنها را باز نکنید نمیتوانند بهروز شوند.\n\nذخیره کننده باتری بهصورت خودکار در هنگام شارژ شدن دستگاه خاموش میشود."</string>
+ <string name="battery_saver_description" msgid="1960431123816253034">"برای کمک به بهبود عمر باتری، بهینهسازی باتری عملکرد دستگاهتان را کاهش میدهد و لرزش، سرویسهای مبتنی بر مکان، و دسترسی به اکثر دادهها در پسزمینه را محدود میکند. ایمیل، پیامرسانی و برنامههای دیگری که به همگامسازی وابستهاند، تا زمانیکه آنها را باز نکنید نمیتوانند بهروز شوند.\n\nبهینهسازی باتری بهصورت خودکار در هنگام شارژ شدن دستگاه خاموش میشود."</string>
<plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="4367877408072000848">
<item quantity="one">به مدت %1$d دقیقه (تا <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
<item quantity="other">به مدت %1$d دقیقه (تا <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
@@ -1488,6 +1488,7 @@
<item quantity="other">برای %d ساعت</item>
</plurals>
<string name="zen_mode_until" msgid="7336308492289875088">"تا <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
+ <string name="zen_mode_alarm" msgid="9128205721301330797">"تا <xliff:g id="FORMATTEDTIME">%1$s</xliff:g> (هشدار بعدی)"</string>
<string name="zen_mode_forever" msgid="7420011936770086993">"تا وقتی آن را خاموش کنید"</string>
<string name="zen_mode_forever_dnd" msgid="3792132696572189081">"تا زمانی که «مزاحم نشوید» را خاموش کنید"</string>
<string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string>
diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml
index 6e6c3dd..5e1ecbe 100644
--- a/core/res/res/values-fi/strings.xml
+++ b/core/res/res/values-fi/strings.xml
@@ -1488,6 +1488,7 @@
<item quantity="one">1 tunnin ajan</item>
</plurals>
<string name="zen_mode_until" msgid="7336308492289875088">"Kunnes kello on <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
+ <string name="zen_mode_alarm" msgid="9128205721301330797">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g> asti (seuraava hälytys)"</string>
<string name="zen_mode_forever" msgid="7420011936770086993">"Kunnes poistat tämän käytöstä"</string>
<string name="zen_mode_forever_dnd" msgid="3792132696572189081">"Kunnes poistat Varattu-tilan käytöstä."</string>
<string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g>/<xliff:g id="REST">%2$s</xliff:g>"</string>
diff --git a/core/res/res/values-fr-rCA/strings.xml b/core/res/res/values-fr-rCA/strings.xml
index 22d84cb..461ad1e 100644
--- a/core/res/res/values-fr-rCA/strings.xml
+++ b/core/res/res/values-fr-rCA/strings.xml
@@ -1488,6 +1488,7 @@
<item quantity="other">Pendant %d h</item>
</plurals>
<string name="zen_mode_until" msgid="7336308492289875088">"Jusqu\'à <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
+ <string name="zen_mode_alarm" msgid="9128205721301330797">"Jusqu\'à <xliff:g id="FORMATTEDTIME">%1$s</xliff:g> (alarme suivante)"</string>
<string name="zen_mode_forever" msgid="7420011936770086993">"Jusqu\'à la désactivation"</string>
<string name="zen_mode_forever_dnd" msgid="3792132696572189081">"Jusqu\'à ce que vous désactiviez le mode « Ne pas déranger »"</string>
<string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string>
diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml
index 085e23c..2874e59 100644
--- a/core/res/res/values-fr/strings.xml
+++ b/core/res/res/values-fr/strings.xml
@@ -420,7 +420,7 @@
<string name="permdesc_useFingerprint" msgid="9165097460730684114">"Autoriser l\'application à utiliser le matériel d\'empreintes digitales pour l\'authentification"</string>
<string name="fingerprint_acquired_partial" msgid="735082772341716043">"Empreinte numérique partiellement détectée. Veuillez réessayer."</string>
<string name="fingerprint_acquired_insufficient" msgid="4596546021310923214">"Impossible de reconnaître l\'empreinte numérique. Veuillez réessayer."</string>
- <string name="fingerprint_acquired_imager_dirty" msgid="1087209702421076105">"Le capteur d\'empreintes numériques est sale. Veuillez le nettoyer, puis réessayer."</string>
+ <string name="fingerprint_acquired_imager_dirty" msgid="1087209702421076105">"Le lecteur d\'empreintes numériques est sale. Veuillez le nettoyer, puis réessayer."</string>
<string name="fingerprint_acquired_too_fast" msgid="6470642383109155969">"Vous avez déplacé votre doigt trop rapidement. Veuillez réessayer."</string>
<string name="fingerprint_acquired_too_slow" msgid="59250885689661653">"Vous avez déplacé votre doigt trop lentement. Veuillez réessayer."</string>
<string-array name="fingerprint_acquired_vendor">
@@ -519,7 +519,7 @@
<string name="policylab_setGlobalProxy" msgid="2784828293747791446">"Définir le proxy global du mobile"</string>
<string name="policydesc_setGlobalProxy" msgid="8459859731153370499">"Indiquer le proxy global à utiliser pour l\'appareil lorsque la règle est activée. Seul le propriétaire de l\'appareil peut définir le proxy global."</string>
<string name="policylab_expirePassword" msgid="5610055012328825874">"Config. expir. mot passe verr. écran"</string>
- <string name="policydesc_expirePassword" msgid="5367525762204416046">"Modifier la fréquence de modification du mot de passe, du code d\'accès ou du motif de verrouillage de l\'écran"</string>
+ <string name="policydesc_expirePassword" msgid="5367525762204416046">"Modifier la fréquence de modification du mot de passe, du code d\'accès ou du schéma de verrouillage de l\'écran"</string>
<string name="policylab_encryptedStorage" msgid="8901326199909132915">"Définir chiffrement du stockage"</string>
<string name="policydesc_encryptedStorage" msgid="2637732115325316992">"Exiger le chiffrement des données d\'application stockées"</string>
<string name="policylab_disableCamera" msgid="6395301023152297826">"Désactiver les appareils photo"</string>
@@ -1423,7 +1423,7 @@
<string name="restr_pin_enter_old_pin" msgid="1462206225512910757">"Code PIN actuel"</string>
<string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"Nouveau code PIN"</string>
<string name="restr_pin_confirm_pin" msgid="8501523829633146239">"Confirmer le nouveau code PIN"</string>
- <string name="restr_pin_create_pin" msgid="8017600000263450337">"Créer un code PIN pour modifier les restrictions"</string>
+ <string name="restr_pin_create_pin" msgid="8017600000263450337">"Créer un code pour modifier les restrictions"</string>
<string name="restr_pin_error_doesnt_match" msgid="2224214190906994548">"Les codes PIN ne correspondent pas. Veuillez réessayer."</string>
<string name="restr_pin_error_too_short" msgid="8173982756265777792">"Le code PIN est trop court. Il doit comporter au moins 4 chiffres."</string>
<plurals name="restr_pin_countdown" formatted="false" msgid="9061246974881224688">
@@ -1488,6 +1488,7 @@
<item quantity="other">Pendant %d h</item>
</plurals>
<string name="zen_mode_until" msgid="7336308492289875088">"Jusqu\'à <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
+ <string name="zen_mode_alarm" msgid="9128205721301330797">"Jusqu\'à <xliff:g id="FORMATTEDTIME">%1$s</xliff:g> (alarme suivante)"</string>
<string name="zen_mode_forever" msgid="7420011936770086993">"Jusqu\'à la désactivation"</string>
<string name="zen_mode_forever_dnd" msgid="3792132696572189081">"Jusqu\'à ce que vous désactiviez la fonctionnalité \"Ne pas déranger\""</string>
<string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g>/<xliff:g id="REST">%2$s</xliff:g>"</string>
diff --git a/core/res/res/values-gl-rES/strings.xml b/core/res/res/values-gl-rES/strings.xml
index 6cd1a0d..48dc96e 100644
--- a/core/res/res/values-gl-rES/strings.xml
+++ b/core/res/res/values-gl-rES/strings.xml
@@ -229,7 +229,7 @@
<string name="permgrouplab_contacts" msgid="3657758145679177612">"Contactos"</string>
<string name="permgroupdesc_contacts" msgid="6951499528303668046">"acceder aos teus contactos"</string>
<string name="permgrouplab_location" msgid="7275582855722310164">"Localización"</string>
- <string name="permgroupdesc_location" msgid="1346617465127855033">"acceso á localización deste dispositivo"</string>
+ <string name="permgroupdesc_location" msgid="1346617465127855033">"acceder á localización deste dispositivo"</string>
<string name="permgrouplab_calendar" msgid="5863508437783683902">"Calendario"</string>
<string name="permgroupdesc_calendar" msgid="3889615280211184106">"acceder ao teu calendario"</string>
<string name="permgrouplab_sms" msgid="228308803364967808">"SMS"</string>
@@ -950,7 +950,7 @@
<string name="volume_icon_description_media" msgid="4217311719665194215">"Volume dos elementos multimedia"</string>
<string name="volume_icon_description_notification" msgid="7044986546477282274">"Volume das notificacións"</string>
<string name="ringtone_default" msgid="3789758980357696936">"Ton de chamada predeterminado"</string>
- <string name="ringtone_default_with_actual" msgid="8129563480895990372">"Ton de chamada predeterminado(<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
+ <string name="ringtone_default_with_actual" msgid="8129563480895990372">"Ton de chamada predeterminado (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
<string name="ringtone_silent" msgid="7937634392408977062">"Ningún"</string>
<string name="ringtone_picker_title" msgid="3515143939175119094">"Tons de chamada"</string>
<string name="ringtone_unknown" msgid="5477919988701784788">"Ton de chamada descoñecido"</string>
@@ -1488,6 +1488,7 @@
<item quantity="one">Durante unha h</item>
</plurals>
<string name="zen_mode_until" msgid="7336308492289875088">"Ata as <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
+ <string name="zen_mode_alarm" msgid="9128205721301330797">"Ata as <xliff:g id="FORMATTEDTIME">%1$s</xliff:g> (próxima alarma)"</string>
<string name="zen_mode_forever" msgid="7420011936770086993">"Ata que desactives isto"</string>
<string name="zen_mode_forever_dnd" msgid="3792132696572189081">"Ata que desactives o modo Non molestar"</string>
<string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g>/<xliff:g id="REST">%2$s</xliff:g>"</string>
diff --git a/core/res/res/values-gu-rIN/strings.xml b/core/res/res/values-gu-rIN/strings.xml
index 1e5d0765..823698a 100644
--- a/core/res/res/values-gu-rIN/strings.xml
+++ b/core/res/res/values-gu-rIN/strings.xml
@@ -229,8 +229,8 @@
<string name="permgrouplab_contacts" msgid="3657758145679177612">"સંપર્કો"</string>
<string name="permgroupdesc_contacts" msgid="6951499528303668046">"તમારા સંપર્કોને ઍક્સેસ કરો"</string>
<string name="permgrouplab_location" msgid="7275582855722310164">"સ્થાન"</string>
- <string name="permgroupdesc_location" msgid="1346617465127855033">"આ ઉપકરણના સ્થાનને ઍક્સેસ કરો"</string>
- <string name="permgrouplab_calendar" msgid="5863508437783683902">"કૅલેન્ડર"</string>
+ <string name="permgroupdesc_location" msgid="1346617465127855033">"આ ઉપકરણના સ્થાનને ઍક્સેસ કરવાની"</string>
+ <string name="permgrouplab_calendar" msgid="5863508437783683902">"કેલેન્ડર"</string>
<string name="permgroupdesc_calendar" msgid="3889615280211184106">"તમારા કેલેન્ડરને ઍક્સેસ કરવાની"</string>
<string name="permgrouplab_sms" msgid="228308803364967808">"SMS"</string>
<string name="permgroupdesc_sms" msgid="4656988620100940350">"SMS સંદેશા મોકલો અને જોવાની"</string>
@@ -326,14 +326,14 @@
<string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"એપ્લિકેશનને ઇનકમિંગ અને આઉટગોઇંગ કૉલ્સ વિશેનાં ડેટા સહિત, તમારા ફોનના કૉલ લૉગને સંશોધિત કરવાની મંજૂરી આપે છે. દુર્ભાવનાપૂર્ણ એપ્લિકેશનો આનો ઉપયોગ તમારા કૉલ લૉગને કાઢી નાખવા અથવા સંશોધિત માટે કરી શકે છે."</string>
<string name="permlab_bodySensors" msgid="4871091374767171066">"બૉડી સેન્સર્સ (જેમ કે હાર્ટ રેટ મૉનિટર્સ)"</string>
<string name="permdesc_bodySensors" product="default" msgid="4380015021754180431">"એપ્લિકેશનને તમારી હૃદય ગતિ જેવી તમારી શારીરિક સ્થિતિને મૉનિટર કરતાં સેન્સર્સથી ડેટા ઍક્સેસ કરવાની મંજૂરી આપે છે."</string>
- <string name="permlab_readCalendar" msgid="5972727560257612398">"કૅલેન્ડર ઇવેન્ટ્સ વત્તા ગોપનીયતા માહિતી વાંચો"</string>
- <string name="permdesc_readCalendar" product="tablet" msgid="4216462049057658723">"એપ્લિકેશનને મિત્રોના અથવા સહકાર્યકરો સહિત તમારા ટેબ્લેટ પર સંગ્રહિત તમામ કૅલેન્ડર ઇવેન્ટ્સ વાંચવાની મંજૂરી આપે છે. આ એપ્લિકેશનને તમારા કૅલેન્ડર ડેટાને શેર કરવા કે સાચવવાની મંજૂરી આપી શકે છે, પછી ભલે ગોપનીયતા અથવા સંવેદિતા કોઈપણ હોય."</string>
- <string name="permdesc_readCalendar" product="tv" msgid="3191352452242394196">"એપ્લિકેશનને મિત્રોના અથવા સહકાર્યકરો સહિત તમારા ટીવી પર સંગ્રહિત તમામ કૅલેન્ડર ઇવેન્ટ્સ વાંચવાની મંજૂરી આપે છે. આ એપ્લિકેશનને તમારા કૅલેન્ડર ડેટાને શેર કરવા કે સાચવવાની મંજૂરી આપી શકે છે, પછી ભલે ગોપનીયતા અથવા સંવેદિતા કોઈપણ હોય."</string>
- <string name="permdesc_readCalendar" product="default" msgid="7434548682470851583">"એપ્લિકેશનને મિત્રોના અથવા સહકાર્યકરો સહિત તમારા ફોન પર સંગ્રહિત તમામ કૅલેન્ડર ઇવેન્ટ્સ વાંચવાની મંજૂરી આપે છે. આ એપ્લિકેશનને તમારા કૅલેન્ડર ડેટાને શેર કરવા કે સાચવવાની મંજૂરી આપી શકે છે, પછી ભલે ગોપનીયતા અથવા સંવેદિતા કોઈપણ હોય."</string>
- <string name="permlab_writeCalendar" msgid="8438874755193825647">"કૅલેન્ડર ઇવેન્ટ્સ ઉમેરો અથવા સંશોધિત કરો અને માલિકની જાણ બહાર અતિથિઓને ઇમેઇલ મોકલો"</string>
- <string name="permdesc_writeCalendar" product="tablet" msgid="6679035520113668528">"એપ્લિકેશનને મિત્રોના અથવા સહકાર્યકરો સહિત તમારા ટેબ્લેટ પર તમે સંશોધિત કરી શકો તે ઇવેન્ટ્સ ઉમેરવા, દૂર કરવા, બદલવાની મંજૂરી આપે છે. આ એપ્લિકેશનને કૅલેન્ડર માલિક તરફથી આવતાં હોય તેવા સંદેશા મોકલવાની અથવા માલિકની જાણ વિના ઇવેન્ટ્સ સંશોધિત કરવાની મંજૂરી આપી શકે છે."</string>
- <string name="permdesc_writeCalendar" product="tv" msgid="1273290605500902507">"એપ્લિકેશનને મિત્રોના અથવા સહકાર્યકરો સહિત તમારા ટીવી પર તમે સંશોધિત કરી શકો તે ઇવેન્ટ્સ ઉમેરવા, દૂર કરવા, બદલવાની મંજૂરી આપે છે. આ એપ્લિકેશનને કૅલેન્ડર માલિક તરફથી આવતાં હોય તેવા સંદેશા મોકલવાની અથવા માલિકની જાણ વિના ઇવેન્ટ્સ સંશોધિત કરવાની મંજૂરી આપી શકે છે."</string>
- <string name="permdesc_writeCalendar" product="default" msgid="2324469496327249376">"એપ્લિકેશનને મિત્રોના અથવા સહકાર્યકરો સહિત તમારા ફોન પર તમે સંશોધિત કરી શકો તે ઇવેન્ટ્સ ઉમેરવા, દૂર કરવા, બદલવાની મંજૂરી આપે છે. આ એપ્લિકેશનને કૅલેન્ડર માલિક તરફથી આવતાં હોય તેવા સંદેશા મોકલવાની અથવા માલિકની જાણ વિના ઇવેન્ટ્સ સંશોધિત કરવાની મંજૂરી આપી શકે છે."</string>
+ <string name="permlab_readCalendar" msgid="5972727560257612398">"કેલેન્ડર ઇવેન્ટ્સ વત્તા ગોપનીયતા માહિતી વાંચો"</string>
+ <string name="permdesc_readCalendar" product="tablet" msgid="4216462049057658723">"એપ્લિકેશનને મિત્રોના અથવા સહકાર્યકરો સહિત તમારા ટેબ્લેટ પર સંગ્રહિત તમામ કેલેન્ડર ઇવેન્ટ્સ વાંચવાની મંજૂરી આપે છે. આ એપ્લિકેશનને તમારા કેલેન્ડર ડેટાને શેર કરવા કે સાચવવાની મંજૂરી આપી શકે છે, પછી ભલે ગોપનીયતા અથવા સંવેદિતા કોઈપણ હોય."</string>
+ <string name="permdesc_readCalendar" product="tv" msgid="3191352452242394196">"એપ્લિકેશનને મિત્રોના અથવા સહકાર્યકરો સહિત તમારા ટીવી પર સંગ્રહિત તમામ કેલેન્ડર ઇવેન્ટ્સ વાંચવાની મંજૂરી આપે છે. આ એપ્લિકેશનને તમારા કેલેન્ડર ડેટાને શેર કરવા કે સાચવવાની મંજૂરી આપી શકે છે, પછી ભલે ગોપનીયતા અથવા સંવેદિતા કોઈપણ હોય."</string>
+ <string name="permdesc_readCalendar" product="default" msgid="7434548682470851583">"એપ્લિકેશનને મિત્રોના અથવા સહકાર્યકરો સહિત તમારા ફોન પર સંગ્રહિત તમામ કેલેન્ડર ઇવેન્ટ્સ વાંચવાની મંજૂરી આપે છે. આ એપ્લિકેશનને તમારા કેલેન્ડર ડેટાને શેર કરવા કે સાચવવાની મંજૂરી આપી શકે છે, પછી ભલે ગોપનીયતા અથવા સંવેદિતા કોઈપણ હોય."</string>
+ <string name="permlab_writeCalendar" msgid="8438874755193825647">"કેલેન્ડર ઇવેન્ટ્સ ઉમેરો અથવા સંશોધિત કરો અને માલિકની જાણ બહાર અતિથિઓને ઇમેઇલ મોકલો"</string>
+ <string name="permdesc_writeCalendar" product="tablet" msgid="6679035520113668528">"એપ્લિકેશનને મિત્રોના અથવા સહકાર્યકરો સહિત તમારા ટેબ્લેટ પર તમે સંશોધિત કરી શકો તે ઇવેન્ટ્સ ઉમેરવા, દૂર કરવા, બદલવાની મંજૂરી આપે છે. આ એપ્લિકેશનને કેલેન્ડર માલિક તરફથી આવતાં હોય તેવા સંદેશા મોકલવાની અથવા માલિકની જાણ વિના ઇવેન્ટ્સ સંશોધિત કરવાની મંજૂરી આપી શકે છે."</string>
+ <string name="permdesc_writeCalendar" product="tv" msgid="1273290605500902507">"એપ્લિકેશનને મિત્રોના અથવા સહકાર્યકરો સહિત તમારા ટીવી પર તમે સંશોધિત કરી શકો તે ઇવેન્ટ્સ ઉમેરવા, દૂર કરવા, બદલવાની મંજૂરી આપે છે. આ એપ્લિકેશનને કેલેન્ડર માલિક તરફથી આવતાં હોય તેવા સંદેશા મોકલવાની અથવા માલિકની જાણ વિના ઇવેન્ટ્સ સંશોધિત કરવાની મંજૂરી આપી શકે છે."</string>
+ <string name="permdesc_writeCalendar" product="default" msgid="2324469496327249376">"એપ્લિકેશનને મિત્રોના અથવા સહકાર્યકરો સહિત તમારા ફોન પર તમે સંશોધિત કરી શકો તે ઇવેન્ટ્સ ઉમેરવા, દૂર કરવા, બદલવાની મંજૂરી આપે છે. આ એપ્લિકેશનને કેલેન્ડર માલિક તરફથી આવતાં હોય તેવા સંદેશા મોકલવાની અથવા માલિકની જાણ વિના ઇવેન્ટ્સ સંશોધિત કરવાની મંજૂરી આપી શકે છે."</string>
<string name="permlab_accessLocationExtraCommands" msgid="2836308076720553837">"વધારાના સ્થાન પ્રદાતા આદેશોને ઍક્સેસ કરો"</string>
<string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"એપ્લિકેશનને વધારાના સ્થાન પ્રદાતા આદેશોને ઍક્સેસ કરવાની મંજૂરી આપે છે. આ એપ્લિકેશનને GPS અથવા અન્ય સ્થાન સ્રોતોના ઓપરેશનમાં દખલ કરવાની મંજૂરી આપી શકે છે."</string>
<string name="permlab_accessFineLocation" msgid="1191898061965273372">"નિશ્ચિત સ્થાન (GPS અને નેટવર્ક-આધારિત)"</string>
@@ -1488,6 +1488,7 @@
<item quantity="other">%d કલાક માટે</item>
</plurals>
<string name="zen_mode_until" msgid="7336308492289875088">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g> સુધી"</string>
+ <string name="zen_mode_alarm" msgid="9128205721301330797">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g> (આગલા એલાર્મ) સુધી"</string>
<string name="zen_mode_forever" msgid="7420011936770086993">"તમે આ બંધ ન કરો ત્યાં સુધી"</string>
<string name="zen_mode_forever_dnd" msgid="3792132696572189081">"તમે ખલેલ પાડશો નહીં બંધ ન કરો ત્યાં સુધી"</string>
<string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string>
diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml
index 4b6a686..e030ac1 100644
--- a/core/res/res/values-hi/strings.xml
+++ b/core/res/res/values-hi/strings.xml
@@ -1488,6 +1488,7 @@
<item quantity="other">%d घंटे के लिए</item>
</plurals>
<string name="zen_mode_until" msgid="7336308492289875088">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g> तक"</string>
+ <string name="zen_mode_alarm" msgid="9128205721301330797">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g> (अगले अलार्म) तक"</string>
<string name="zen_mode_forever" msgid="7420011936770086993">"जब तक आप इसे बंद नहीं कर देते"</string>
<string name="zen_mode_forever_dnd" msgid="3792132696572189081">"जब तक कि आप परेशान ना करें को बंद नहीं कर देते"</string>
<string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string>
diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml
index 69b8577..dd58d5c 100644
--- a/core/res/res/values-hr/strings.xml
+++ b/core/res/res/values-hr/strings.xml
@@ -1505,6 +1505,7 @@
<item quantity="other">%d h</item>
</plurals>
<string name="zen_mode_until" msgid="7336308492289875088">"Do <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
+ <string name="zen_mode_alarm" msgid="9128205721301330797">"Do <xliff:g id="FORMATTEDTIME">%1$s</xliff:g> (sljedeći alarm)"</string>
<string name="zen_mode_forever" msgid="7420011936770086993">"Dok ne isključite"</string>
<string name="zen_mode_forever_dnd" msgid="3792132696572189081">"Dok ne isključite \"Ne uznemiravaj\""</string>
<string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g>/<xliff:g id="REST">%2$s</xliff:g>"</string>
diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml
index 1b45d1c..9f7197b 100644
--- a/core/res/res/values-hu/strings.xml
+++ b/core/res/res/values-hu/strings.xml
@@ -53,7 +53,7 @@
<string name="serviceErased" msgid="1288584695297200972">"A törlés sikerült."</string>
<string name="passwordIncorrect" msgid="7612208839450128715">"Helytelen jelszó."</string>
<string name="mmiComplete" msgid="8232527495411698359">"MMI kész."</string>
- <string name="badPin" msgid="9015277645546710014">"A megadott régi PIN kód helytelen."</string>
+ <string name="badPin" msgid="9015277645546710014">"A megadott régi PIN-kód helytelen."</string>
<string name="badPuk" msgid="5487257647081132201">"A megadott PUK kód helytelen."</string>
<string name="mismatchPin" msgid="609379054496863419">"A beírt PIN kódok nem egyeznek."</string>
<string name="invalidPin" msgid="3850018445187475377">"Írjon be egy 4-8 számjegyű PIN kódot."</string>
@@ -75,7 +75,7 @@
<string name="CwMmi" msgid="9129678056795016867">"Hívásvárakoztatás"</string>
<string name="BaMmi" msgid="455193067926770581">"Hívásletiltás"</string>
<string name="PwdMmi" msgid="7043715687905254199">"Jelszómódosítás"</string>
- <string name="PinMmi" msgid="3113117780361190304">"PIN kód módosítása"</string>
+ <string name="PinMmi" msgid="3113117780361190304">"PIN-kód módosítása"</string>
<string name="CnipMmi" msgid="3110534680557857162">"Szám hívása"</string>
<string name="CnirMmi" msgid="3062102121430548731">"Hívószám korlátozva"</string>
<string name="ThreeWCMmi" msgid="9051047170321190368">"Háromutas hívás"</string>
@@ -643,11 +643,11 @@
<string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"Írja be a PIN kódot"</string>
<string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"Írja be a PUK kódot, majd az új PIN kódot"</string>
<string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"PUK kód"</string>
- <string name="keyguard_password_enter_pin_prompt" msgid="8027680321614196258">"Új PIN kód"</string>
+ <string name="keyguard_password_enter_pin_prompt" msgid="8027680321614196258">"Új PIN-kód"</string>
<string name="keyguard_password_entry_touch_hint" msgid="7858547464982981384"><font size="17">"Érintsen jelszó megadásához"</font></string>
<string name="keyguard_password_enter_password_code" msgid="1054721668279049780">"A feloldáshoz írja be a jelszót"</string>
<string name="keyguard_password_enter_pin_password_code" msgid="6391755146112503443">"Feloldáshoz írja be a PIN kódot"</string>
- <string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"Helytelen PIN kód."</string>
+ <string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"Helytelen PIN-kód."</string>
<string name="keyguard_label_text" msgid="861796461028298424">"A feloldáshoz nyomja meg a Menü, majd a 0 gombot."</string>
<string name="emergency_call_dialog_number_for_display" msgid="696192103195090970">"Segélyhívó szám"</string>
<string name="lockscreen_carrier_default" msgid="8963839242565653192">"Nincs szolgáltatás."</string>
@@ -699,7 +699,7 @@
<string name="lockscreen_glogin_forgot_pattern" msgid="2588521501166032747">"Fiók feloldása"</string>
<string name="lockscreen_glogin_too_many_attempts" msgid="2751368605287288808">"Túl sok mintarajzolási próbálkozás"</string>
<string name="lockscreen_glogin_instructions" msgid="3931816256100707784">"A feloldáshoz jelentkezzen be Google-fiókjával."</string>
- <string name="lockscreen_glogin_username_hint" msgid="8846881424106484447">"Felhasználónév (e-mail cím)"</string>
+ <string name="lockscreen_glogin_username_hint" msgid="8846881424106484447">"Felhasználónév (e-mail-cím)"</string>
<string name="lockscreen_glogin_password_hint" msgid="5958028383954738528">"Jelszó"</string>
<string name="lockscreen_glogin_submit_button" msgid="7130893694795786300">"Bejelentkezés"</string>
<string name="lockscreen_glogin_invalid_input" msgid="1364051473347485908">"Érvénytelen felhasználónév vagy jelszó."</string>
@@ -985,7 +985,7 @@
<string name="wifi_p2p_from_message" msgid="570389174731951769">"Feladó:"</string>
<string name="wifi_p2p_to_message" msgid="248968974522044099">"Címzett:"</string>
<string name="wifi_p2p_enter_pin_message" msgid="5920929550367828970">"Adja meg a szükséges PIN kódot:"</string>
- <string name="wifi_p2p_show_pin_message" msgid="8530563323880921094">"PIN kód:"</string>
+ <string name="wifi_p2p_show_pin_message" msgid="8530563323880921094">"PIN-kód:"</string>
<string name="wifi_p2p_frequency_conflict_message" product="tablet" msgid="8012981257742232475">"A táblagép ideiglenesen lecsatlakozik a Wi-Fi hálózatról, míg a(z) <xliff:g id="DEVICE_NAME">%1$s</xliff:g> eszközhöz csatlakozik"</string>
<string name="wifi_p2p_frequency_conflict_message" product="tv" msgid="3087858235069421128">"A tévé ideiglenesen lekapcsolódik a Wi-Fi-hálózatról addig, amíg a(z) <xliff:g id="DEVICE_NAME">%1$s</xliff:g> eszközhöz csatlakozik."</string>
<string name="wifi_p2p_frequency_conflict_message" product="default" msgid="7363907213787469151">"A telefon ideiglenesen kilép a Wi-Fi hálózatról, míg a(z) <xliff:g id="DEVICE_NAME">%1$s</xliff:g> eszközhöz csatlakozik."</string>
@@ -1280,24 +1280,24 @@
<string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Elfelejtett minta"</string>
<string name="kg_wrong_pattern" msgid="1850806070801358830">"Helytelen minta"</string>
<string name="kg_wrong_password" msgid="2333281762128113157">"Helytelen jelszó"</string>
- <string name="kg_wrong_pin" msgid="1131306510833563801">"Helytelen PIN kód"</string>
+ <string name="kg_wrong_pin" msgid="1131306510833563801">"Helytelen PIN-kód"</string>
<string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"Próbálkozzon újra <xliff:g id="NUMBER">%1$d</xliff:g> másodperc múlva."</string>
<string name="kg_pattern_instructions" msgid="398978611683075868">"Rajzolja le a mintát"</string>
<string name="kg_sim_pin_instructions" msgid="2319508550934557331">"Adja meg a SIM kártya PIN kódját"</string>
<string name="kg_pin_instructions" msgid="2377242233495111557">"Adja meg a PIN kódot"</string>
<string name="kg_password_instructions" msgid="5753646556186936819">"Írja be a jelszót"</string>
<string name="kg_puk_enter_puk_hint" msgid="453227143861735537">"A SIM kártya le van tiltva. A folytatáshoz adja meg a PUK kódot. A részletekért vegye fel a kapcsolatot szolgáltatójával."</string>
- <string name="kg_puk_enter_pin_hint" msgid="7871604527429602024">"Kívánt PIN kód megadása"</string>
- <string name="kg_enter_confirm_pin_hint" msgid="325676184762529976">"Kívánt PIN kód megerősítése"</string>
+ <string name="kg_puk_enter_pin_hint" msgid="7871604527429602024">"Kívánt PIN-kód megadása"</string>
+ <string name="kg_enter_confirm_pin_hint" msgid="325676184762529976">"Kívánt PIN-kód megerősítése"</string>
<string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"SIM kártya feloldása..."</string>
- <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"Helytelen PIN kód."</string>
+ <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"Helytelen PIN-kód."</string>
<string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"4–8 számjegyű PIN kódot írjon be."</string>
<string name="kg_invalid_sim_puk_hint" msgid="6025069204539532000">"A PUK kód 8 karakter hosszú kell, hogy legyen."</string>
<string name="kg_invalid_puk" msgid="3638289409676051243">"Adja meg újra a helyes PUK kódot. Az ismételt próbálkozással véglegesen letiltja a SIM kártyát."</string>
<string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"A PIN kódok nem egyeznek."</string>
<string name="kg_login_too_many_attempts" msgid="6486842094005698475">"Túl sok mintarajzolási próbálkozás"</string>
<string name="kg_login_instructions" msgid="1100551261265506448">"A feloldáshoz jelentkezzen be Google-fiókjával."</string>
- <string name="kg_login_username_hint" msgid="5718534272070920364">"Felhasználónév (e-mail cím)"</string>
+ <string name="kg_login_username_hint" msgid="5718534272070920364">"Felhasználónév (e-mail-cím)"</string>
<string name="kg_login_password_hint" msgid="9057289103827298549">"Jelszó"</string>
<string name="kg_login_submit_button" msgid="5355904582674054702">"Bejelentkezés"</string>
<string name="kg_login_invalid_input" msgid="5754664119319872197">"Érvénytelen felhasználónév vagy jelszó."</string>
@@ -1417,15 +1417,15 @@
<string name="reason_service_unavailable" msgid="7824008732243903268">"A nyomtatási szolgáltatás nincs bekapcsolva"</string>
<string name="print_service_installed_title" msgid="2246317169444081628">"A(z) <xliff:g id="NAME">%s</xliff:g> szolgáltatás telepítve"</string>
<string name="print_service_installed_message" msgid="5897362931070459152">"Koppintson az engedélyezéshez"</string>
- <string name="restr_pin_enter_admin_pin" msgid="783643731895143970">"Rendszergazdai PIN kód megadása"</string>
- <string name="restr_pin_enter_pin" msgid="3395953421368476103">"PIN kód megadása"</string>
+ <string name="restr_pin_enter_admin_pin" msgid="783643731895143970">"Rendszergazdai PIN-kód megadása"</string>
+ <string name="restr_pin_enter_pin" msgid="3395953421368476103">"PIN-kód megadása"</string>
<string name="restr_pin_incorrect" msgid="8571512003955077924">"Helytelen"</string>
- <string name="restr_pin_enter_old_pin" msgid="1462206225512910757">"Jelenlegi PIN kód"</string>
- <string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"Új PIN kód"</string>
- <string name="restr_pin_confirm_pin" msgid="8501523829633146239">"Új PIN kód megerősítése"</string>
- <string name="restr_pin_create_pin" msgid="8017600000263450337">"PIN kód létrehozása a korlátozások módosításához"</string>
+ <string name="restr_pin_enter_old_pin" msgid="1462206225512910757">"Jelenlegi PIN-kód"</string>
+ <string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"Új PIN-kód"</string>
+ <string name="restr_pin_confirm_pin" msgid="8501523829633146239">"Új PIN-kód megerősítése"</string>
+ <string name="restr_pin_create_pin" msgid="8017600000263450337">"PIN-kód létrehozása a korlátozások módosításához"</string>
<string name="restr_pin_error_doesnt_match" msgid="2224214190906994548">"A PIN kódok nem egyeznek. Próbálja újra."</string>
- <string name="restr_pin_error_too_short" msgid="8173982756265777792">"A PIN kód túl rövid. Legalább 4 számjegyből kell állnia."</string>
+ <string name="restr_pin_error_too_short" msgid="8173982756265777792">"A PIN-kód túl rövid. Legalább 4 számjegyből kell állnia."</string>
<plurals name="restr_pin_countdown" formatted="false" msgid="9061246974881224688">
<item quantity="other">Próbálja újra <xliff:g id="COUNT">%d</xliff:g> másodperc múlva</item>
<item quantity="one">Próbálja újra 1 másodperc múlva</item>
@@ -1448,7 +1448,7 @@
<string name="lock_to_app_toast_locked" msgid="9125176335701699164">"Az alkalmazás rögzítve van: a rögzítés feloldása nem engedélyezett ezen az eszközön."</string>
<string name="lock_to_app_start" msgid="6643342070839862795">"Képernyő rögzítve"</string>
<string name="lock_to_app_exit" msgid="8598219838213787430">"Képernyő rögzítése feloldva"</string>
- <string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"PIN kód kérése a rögzítés feloldásához"</string>
+ <string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"PIN-kód kérése a rögzítés feloldásához"</string>
<string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"Feloldási minta kérése a rögzítés feloldásához"</string>
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Jelszó kérése a rögzítés feloldásához"</string>
<string name="package_installed_device_owner" msgid="8420696545959087545">"A rendszergazda telepítette"</string>
@@ -1488,6 +1488,7 @@
<item quantity="one">1 órán keresztül</item>
</plurals>
<string name="zen_mode_until" msgid="7336308492289875088">"Eddig: <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
+ <string name="zen_mode_alarm" msgid="9128205721301330797">"Eddig: <xliff:g id="FORMATTEDTIME">%1$s</xliff:g> (ez a következő riasztás)"</string>
<string name="zen_mode_forever" msgid="7420011936770086993">"Amíg ki nem kapcsolja ezt"</string>
<string name="zen_mode_forever_dnd" msgid="3792132696572189081">"Amíg ki nem kapcsolja a „Ne zavarjanak” lehetőséget"</string>
<string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string>
diff --git a/core/res/res/values-hy-rAM/strings.xml b/core/res/res/values-hy-rAM/strings.xml
index 92842b4..1f85bf3 100644
--- a/core/res/res/values-hy-rAM/strings.xml
+++ b/core/res/res/values-hy-rAM/strings.xml
@@ -1488,6 +1488,7 @@
<item quantity="other">%d ժամով</item>
</plurals>
<string name="zen_mode_until" msgid="7336308492289875088">"Մինչև <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
+ <string name="zen_mode_alarm" msgid="9128205721301330797">"Մինչև ժ. <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>-ը (հաջորդ զարթուցիչը)"</string>
<string name="zen_mode_forever" msgid="7420011936770086993">"Քանի դեռ չեք անջատել"</string>
<string name="zen_mode_forever_dnd" msgid="3792132696572189081">"Մինչև չանջատեք «Չանհանգստացնել» գործառույթը"</string>
<string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g>/<xliff:g id="REST">%2$s</xliff:g>"</string>
diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml
index 02299b0..10214c5 100644
--- a/core/res/res/values-in/strings.xml
+++ b/core/res/res/values-in/strings.xml
@@ -1488,6 +1488,7 @@
<item quantity="one">Selama 1 jam</item>
</plurals>
<string name="zen_mode_until" msgid="7336308492289875088">"Hingga <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
+ <string name="zen_mode_alarm" msgid="9128205721301330797">"Hingga <xliff:g id="FORMATTEDTIME">%1$s</xliff:g> (alarm berikutnya)"</string>
<string name="zen_mode_forever" msgid="7420011936770086993">"Hingga Anda menonaktifkan ini"</string>
<string name="zen_mode_forever_dnd" msgid="3792132696572189081">"Hingga Anda menonaktifkan status Jangan Ganggu"</string>
<string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string>
diff --git a/core/res/res/values-is-rIS/strings.xml b/core/res/res/values-is-rIS/strings.xml
index e57400a..76c52cc 100644
--- a/core/res/res/values-is-rIS/strings.xml
+++ b/core/res/res/values-is-rIS/strings.xml
@@ -1488,6 +1488,7 @@
<item quantity="other">Í %d klst.</item>
</plurals>
<string name="zen_mode_until" msgid="7336308492289875088">"Til <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
+ <string name="zen_mode_alarm" msgid="9128205721301330797">"Þangað til <xliff:g id="FORMATTEDTIME">%1$s</xliff:g> (næsta viðvörun)"</string>
<string name="zen_mode_forever" msgid="7420011936770086993">"Þar til þú slekkur á þessu"</string>
<string name="zen_mode_forever_dnd" msgid="3792132696572189081">"Þar til þú slekkur á „Ónáðið ekki“"</string>
<string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string>
diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml
index 5722c6a..f82ee87 100644
--- a/core/res/res/values-it/strings.xml
+++ b/core/res/res/values-it/strings.xml
@@ -239,11 +239,11 @@
<string name="permgrouplab_microphone" msgid="171539900250043464">"Microfono"</string>
<string name="permgroupdesc_microphone" msgid="4988812113943554584">"registrare audio"</string>
<string name="permgrouplab_camera" msgid="4820372495894586615">"Fotocamera"</string>
- <string name="permgroupdesc_camera" msgid="3250611594678347720">"acquisire foto e registrare video"</string>
+ <string name="permgroupdesc_camera" msgid="3250611594678347720">"scattare foto e registrare video"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"Telefono"</string>
<string name="permgroupdesc_phone" msgid="6234224354060641055">"eseguire e gestire le telefonate"</string>
<string name="permgrouplab_sensors" msgid="416037179223226722">"Sensori per il corpo"</string>
- <string name="permgroupdesc_sensors" msgid="7147968539346634043">"accedere ai dati dei sensori sui tuoi parametri vitali"</string>
+ <string name="permgroupdesc_sensors" msgid="7147968539346634043">"accedere ai dati dei sensori relativi ai tuoi parametri vitali"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Recuperare contenuti della finestra"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Esaminare i contenuti di una finestra con cui interagisci."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Attivare Esplora al tocco"</string>
@@ -272,7 +272,7 @@
<string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"Consente all\'applicazione di leggere i messaggi cell broadcast ricevuti dal dispositivo. Gli avvisi cell broadcast vengono trasmessi in alcune località per avvertire di eventuali situazioni di emergenza. Le applicazioni dannose potrebbero interferire con il rendimento o con il funzionamento del dispositivo quando si riceve un messaggio cell broadcast di emergenza."</string>
<string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"lettura feed sottoscritti"</string>
<string name="permdesc_subscribedFeedsRead" msgid="5557058907906144505">"Consente all\'applicazione di ottenere dettagli sui feed attualmente sincronizzati."</string>
- <string name="permlab_sendSms" msgid="7544599214260982981">"invio e lettura di SMS"</string>
+ <string name="permlab_sendSms" msgid="7544599214260982981">"inviare e visualizzare SMS"</string>
<string name="permdesc_sendSms" msgid="7094729298204937667">"Consente all\'applicazione di inviare messaggi SMS. Ciò potrebbe comportare costi imprevisti. Applicazioni dannose potrebbero generare dei costi inviando messaggi senza la tua conferma."</string>
<string name="permlab_readSms" msgid="8745086572213270480">"lettura messaggi di testo personali (SMS o MMS)"</string>
<string name="permdesc_readSms" product="tablet" msgid="2467981548684735522">"Consente all\'applicazione di leggere i messaggi SMS memorizzati sul tablet o sulla scheda SIM. Ciò consente all\'applicazione di leggere tutti i messaggi SMS, indipendentemente dai contenuti o dal livello di riservatezza."</string>
@@ -290,7 +290,7 @@
<string name="permdesc_enableCarMode" msgid="4853187425751419467">"Consente all\'applicazione di abilitare la modalità automobile."</string>
<string name="permlab_killBackgroundProcesses" msgid="3914026687420177202">"chiusura altre applicazioni"</string>
<string name="permdesc_killBackgroundProcesses" msgid="4593353235959733119">"Consente all\'applicazione di terminare i processi in background di altre applicazioni. Ciò potrebbe causare l\'interruzione di altre applicazioni."</string>
- <string name="permlab_systemAlertWindow" msgid="3543347980839518613">"spostamento sopra altre app"</string>
+ <string name="permlab_systemAlertWindow" msgid="3543347980839518613">"posizionamento davanti ad altre app"</string>
<string name="permdesc_systemAlertWindow" msgid="8584678381972820118">"Consente all\'applicazione di spostarsi sopra ad altre applicazioni o parti dell\'interfaccia utente. Potrebbe interferire con il tuo utilizzo dell\'interfaccia in qualsiasi applicazione o cambiare ciò che credi di vedere in altre applicazioni."</string>
<string name="permlab_persistentActivity" msgid="8841113627955563938">"esecuzione permanente delle applicazioni"</string>
<string name="permdesc_persistentActivity" product="tablet" msgid="8525189272329086137">"Consente all\'applicazione di rendere persistenti in memoria alcune sue parti. Ciò può limitare la memoria disponibile per altre applicazioni, rallentando il tablet."</string>
@@ -342,7 +342,7 @@
<string name="permdesc_accessCoarseLocation" msgid="2538200184373302295">"Consente all\'applicazione di ottenere la tua posizione approssimativa. Questa posizione viene ottenuta da servizi di localizzazione utilizzando fonti di geolocalizzazione delle reti come ripetitori di telefonia mobile e Wi-Fi. Questi servizi di localizzazione devono essere attivi e disponibili sul dispositivo per poter essere utilizzati dall\'applicazione. Le applicazioni potrebbero utilizzare questa autorizzazione per stabilire la tua posizione approssimativa."</string>
<string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"modifica impostazioni audio"</string>
<string name="permdesc_modifyAudioSettings" msgid="3522565366806248517">"Consente all\'applicazione di modificare le impostazioni audio globali, come il volume e quale altoparlante viene utilizzato per l\'uscita."</string>
- <string name="permlab_recordAudio" msgid="3876049771427466323">"registrazione audio"</string>
+ <string name="permlab_recordAudio" msgid="3876049771427466323">"registrare audio"</string>
<string name="permdesc_recordAudio" msgid="4906839301087980680">"Consente all\'applicazione di registrare audio con il microfono. Questa autorizzazione consente all\'applicazione di registrare audio in qualsiasi momento senza la tua conferma."</string>
<string name="permlab_sim_communication" msgid="1180265879464893029">"comunicazione SIM"</string>
<string name="permdesc_sim_communication" msgid="5725159654279639498">"Consente all\'app di inviare comandi alla SIM. Questo è molto pericoloso."</string>
@@ -1488,6 +1488,7 @@
<item quantity="one">Per 1 ora</item>
</plurals>
<string name="zen_mode_until" msgid="7336308492289875088">"Fino alle ore <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
+ <string name="zen_mode_alarm" msgid="9128205721301330797">"Fino alle ore <xliff:g id="FORMATTEDTIME">%1$s</xliff:g> (prossima sveglia)"</string>
<string name="zen_mode_forever" msgid="7420011936770086993">"Fino alla disattivazione"</string>
<string name="zen_mode_forever_dnd" msgid="3792132696572189081">"Fino alla disattivazione di Non disturbare"</string>
<string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g>/<xliff:g id="REST">%2$s</xliff:g>"</string>
diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml
index aba5471..2c6b3be 100644
--- a/core/res/res/values-iw/strings.xml
+++ b/core/res/res/values-iw/strings.xml
@@ -1522,6 +1522,7 @@
<item quantity="one">למשך שעה אחת</item>
</plurals>
<string name="zen_mode_until" msgid="7336308492289875088">"עד <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
+ <string name="zen_mode_alarm" msgid="9128205721301330797">"עד <xliff:g id="FORMATTEDTIME">%1$s</xliff:g> (ההתראה הבאה)"</string>
<string name="zen_mode_forever" msgid="7420011936770086993">"עד שתכבה"</string>
<string name="zen_mode_forever_dnd" msgid="3792132696572189081">"עד שתכבה את \'נא לא להפריע\'"</string>
<string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string>
diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml
index 2ce3bad..4062c29 100644
--- a/core/res/res/values-ja/strings.xml
+++ b/core/res/res/values-ja/strings.xml
@@ -282,8 +282,8 @@
<string name="permdesc_receiveWapPush" msgid="748232190220583385">"WAPメッセージの受信と処理をアプリに許可します。これにより、アプリが端末に届いたメッセージを表示することなく監視または削除できるようになります。"</string>
<string name="permlab_getTasks" msgid="6466095396623933906">"実行中のアプリの取得"</string>
<string name="permdesc_getTasks" msgid="7454215995847658102">"現在実行中または最近実行したタスクに関する情報の取得をアプリに許可します。これにより、その端末でどのアプリを使用しているかをアプリから識別できるようになる可能性があります。"</string>
- <string name="permlab_manageProfileAndDeviceOwners" msgid="5979288447973722097">"プロフィールの所有者と端末の所有者の管理"</string>
- <string name="permdesc_manageProfileAndDeviceOwners" msgid="106894851498657169">"プロフィールの所有者と端末の所有者の設定をアプリに許可します。"</string>
+ <string name="permlab_manageProfileAndDeviceOwners" msgid="5979288447973722097">"プロファイルの所有者と端末の所有者の管理"</string>
+ <string name="permdesc_manageProfileAndDeviceOwners" msgid="106894851498657169">"プロファイルの所有者と端末の所有者の設定をアプリに許可します。"</string>
<string name="permlab_reorderTasks" msgid="2018575526934422779">"実行中のアプリの順序変更"</string>
<string name="permdesc_reorderTasks" msgid="7734217754877439351">"タスクをフォアグラウンドやバックグラウンドに移動することをアプリに許可します。これにより、アプリがユーザーからの入力なしでこの処理を実行する可能性があります。"</string>
<string name="permlab_enableCarMode" msgid="5684504058192921098">"運転モードの有効化"</string>
@@ -1042,12 +1042,12 @@
<string name="usb_ptp_notification_title" msgid="1347328437083192112">"USBを写真転送に使用"</string>
<string name="usb_midi_notification_title" msgid="4850904915889144654">"USBをMIDIに使用"</string>
<string name="usb_accessory_notification_title" msgid="7848236974087653666">"USBアクセサリを接続しました"</string>
- <string name="usb_notification_message" msgid="7347368030849048437">"タップするとその他のオプションが表示されます。"</string>
+ <string name="usb_notification_message" msgid="7347368030849048437">"タップしてその他のオプションを表示"</string>
<string name="adb_active_notification_title" msgid="6729044778949189918">"USBデバッグが接続されました"</string>
<string name="adb_active_notification_message" msgid="1016654627626476142">"タップしてUSBデバッグを無効化"</string>
<string name="select_input_method" msgid="8547250819326693584">"キーボードの変更"</string>
<string name="configure_input_methods" msgid="4769971288371946846">"キーボードの選択"</string>
- <string name="show_ime" msgid="9157568568695230830">"入力方法を表示する"</string>
+ <string name="show_ime" msgid="9157568568695230830">"スクリーンキーボードを表示する"</string>
<string name="hardware" msgid="7517821086888990278">"ハードウェア"</string>
<string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"キーボードレイアウトの選択"</string>
<string name="select_keyboard_layout_notification_message" msgid="4465907700449257063">"タップしてキーボードレイアウトを選択してください。"</string>
@@ -1136,7 +1136,7 @@
<string name="no_file_chosen" msgid="6363648562170759465">"ファイルが選択されていません"</string>
<string name="reset" msgid="2448168080964209908">"リセット"</string>
<string name="submit" msgid="1602335572089911941">"送信"</string>
- <string name="car_mode_disable_notification_title" msgid="3164768212003864316">"運転モードになっています"</string>
+ <string name="car_mode_disable_notification_title" msgid="3164768212003864316">"運転モード中"</string>
<string name="car_mode_disable_notification_message" msgid="8035230537563503262">"タップすると運転モードを終了します"</string>
<string name="tethered_notification_title" msgid="3146694234398202601">"テザリングまたはアクセスポイントが有効です"</string>
<string name="tethered_notification_message" msgid="6857031760103062982">"タップしてセットアップします。"</string>
@@ -1488,6 +1488,7 @@
<item quantity="one">1時間</item>
</plurals>
<string name="zen_mode_until" msgid="7336308492289875088">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g>まで"</string>
+ <string name="zen_mode_alarm" msgid="9128205721301330797">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g>(次のアラーム)まで"</string>
<string name="zen_mode_forever" msgid="7420011936770086993">"ユーザーがOFFにするまで"</string>
<string name="zen_mode_forever_dnd" msgid="3792132696572189081">"[通知を非表示]をOFFにするまで"</string>
<string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g>/<xliff:g id="REST">%2$s</xliff:g>"</string>
diff --git a/core/res/res/values-ka-rGE/strings.xml b/core/res/res/values-ka-rGE/strings.xml
index f771679..d88adcb 100644
--- a/core/res/res/values-ka-rGE/strings.xml
+++ b/core/res/res/values-ka-rGE/strings.xml
@@ -1488,6 +1488,7 @@
<item quantity="one">1 სთ.</item>
</plurals>
<string name="zen_mode_until" msgid="7336308492289875088">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g>-მდე"</string>
+ <string name="zen_mode_alarm" msgid="9128205721301330797">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g>-მდე (შემდეგი მაღვიძარა)"</string>
<string name="zen_mode_forever" msgid="7420011936770086993">"სანამ ამას გამორთავდეთ"</string>
<string name="zen_mode_forever_dnd" msgid="3792132696572189081">"სანამ გამორთავთ „არ შემაწუხოთ“ ფუნქციას"</string>
<string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g>/<xliff:g id="REST">%2$s</xliff:g>"</string>
diff --git a/core/res/res/values-kk-rKZ/strings.xml b/core/res/res/values-kk-rKZ/strings.xml
index 1220061..f8426c9 100644
--- a/core/res/res/values-kk-rKZ/strings.xml
+++ b/core/res/res/values-kk-rKZ/strings.xml
@@ -229,7 +229,7 @@
<string name="permgrouplab_contacts" msgid="3657758145679177612">"Контактілер"</string>
<string name="permgroupdesc_contacts" msgid="6951499528303668046">"контактілерге кіру"</string>
<string name="permgrouplab_location" msgid="7275582855722310164">"Орын"</string>
- <string name="permgroupdesc_location" msgid="1346617465127855033">"бұл құрылғының орнына кіру"</string>
+ <string name="permgroupdesc_location" msgid="1346617465127855033">"бұл құрылғының орналасқан жерін көру"</string>
<string name="permgrouplab_calendar" msgid="5863508437783683902">"Күнтізбе"</string>
<string name="permgroupdesc_calendar" msgid="3889615280211184106">"күнтізбеге кіру"</string>
<string name="permgrouplab_sms" msgid="228308803364967808">"SMS"</string>
@@ -1488,6 +1488,7 @@
<item quantity="one">1 сағат</item>
</plurals>
<string name="zen_mode_until" msgid="7336308492289875088">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g> дейін"</string>
+ <string name="zen_mode_alarm" msgid="9128205721301330797">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g> дейін (келесі дабыл)"</string>
<string name="zen_mode_forever" msgid="7420011936770086993">"Сіз осыны өшіргенше"</string>
<string name="zen_mode_forever_dnd" msgid="3792132696572189081">"Өшірмейінше мазаламау"</string>
<string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g>/<xliff:g id="REST">%2$s</xliff:g>"</string>
diff --git a/core/res/res/values-km-rKH/strings.xml b/core/res/res/values-km-rKH/strings.xml
index 99de7b0..97ac9eb 100644
--- a/core/res/res/values-km-rKH/strings.xml
+++ b/core/res/res/values-km-rKH/strings.xml
@@ -1490,6 +1490,7 @@
<item quantity="one">អស់រយៈពេល 1 ម៉ោង</item>
</plurals>
<string name="zen_mode_until" msgid="7336308492289875088">"រហូតដល់ <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
+ <string name="zen_mode_alarm" msgid="9128205721301330797">"រហូតដល់ <xliff:g id="FORMATTEDTIME">%1$s</xliff:g> (ម៉ោងរោទិ៍បន្ទាប់)"</string>
<string name="zen_mode_forever" msgid="7420011936770086993">"រហូតដល់ពេលអ្នកបិទវា"</string>
<string name="zen_mode_forever_dnd" msgid="3792132696572189081">"រហូតទាល់តែអ្នកបិទ កុំរំខាន"</string>
<string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string>
diff --git a/core/res/res/values-kn-rIN/strings.xml b/core/res/res/values-kn-rIN/strings.xml
index e480760..41762b1 100644
--- a/core/res/res/values-kn-rIN/strings.xml
+++ b/core/res/res/values-kn-rIN/strings.xml
@@ -1488,6 +1488,7 @@
<item quantity="other">%d ಗಂಟೆಗೆ</item>
</plurals>
<string name="zen_mode_until" msgid="7336308492289875088">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g> ವರೆಗೆ"</string>
+ <string name="zen_mode_alarm" msgid="9128205721301330797">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g> ವರೆಗೆ (ಮುಂದಿನ ಅಲಾರಮ್)"</string>
<string name="zen_mode_forever" msgid="7420011936770086993">"ನೀವಿದನ್ನು ಆಫ್ ಮಾಡುವವರೆಗೆ"</string>
<string name="zen_mode_forever_dnd" msgid="3792132696572189081">"ನೀವು ಆಫ್ ಮಾಡುವವರೆಗೂ ಅಡಚಣೆ ಮಾಡಬೇಡಿ"</string>
<string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string>
diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml
index 360d723..14f182d 100644
--- a/core/res/res/values-ko/strings.xml
+++ b/core/res/res/values-ko/strings.xml
@@ -431,7 +431,7 @@
<string name="fingerprint_error_canceled" msgid="4402024612660774395">"지문 인식 작업이 취소되었습니다."</string>
<string name="fingerprint_error_lockout" msgid="5536934748136933450">"시도 횟수가 너무 많습니다. 나중에 다시 시도하세요."</string>
<string name="fingerprint_error_unable_to_process" msgid="6107816084103552441">"다시 시도해 보세요."</string>
- <string name="fingerprint_name_template" msgid="5870957565512716938">"<xliff:g id="FINGERID">%d</xliff:g>번째 손가락"</string>
+ <string name="fingerprint_name_template" msgid="5870957565512716938">"손가락 <xliff:g id="FINGERID">%d</xliff:g>"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
<string name="fingerprint_icon_content_description" msgid="2340202869968465936">"지문 아이콘"</string>
@@ -1488,6 +1488,7 @@
<item quantity="one">1시간 동안</item>
</plurals>
<string name="zen_mode_until" msgid="7336308492289875088">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g>까지"</string>
+ <string name="zen_mode_alarm" msgid="9128205721301330797">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g>(다음 알람)까지"</string>
<string name="zen_mode_forever" msgid="7420011936770086993">"이 기능을 사용 중지할 때까지"</string>
<string name="zen_mode_forever_dnd" msgid="3792132696572189081">"알림 일시중지 기능을 사용 중지할 때까지"</string>
<string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string>
diff --git a/core/res/res/values-ky-rKG/strings.xml b/core/res/res/values-ky-rKG/strings.xml
index 4806603..b0a5963 100644
--- a/core/res/res/values-ky-rKG/strings.xml
+++ b/core/res/res/values-ky-rKG/strings.xml
@@ -229,7 +229,7 @@
<string name="permgrouplab_contacts" msgid="3657758145679177612">"Байланыштар"</string>
<string name="permgroupdesc_contacts" msgid="6951499528303668046">"байланыштарыңызга уруксат"</string>
<string name="permgrouplab_location" msgid="7275582855722310164">"Жайгашкан жер"</string>
- <string name="permgroupdesc_location" msgid="1346617465127855033">"бул түзмөктүн жайгашкан жерине кирүү"</string>
+ <string name="permgroupdesc_location" msgid="1346617465127855033">"бул түзмөктүн жайгашкан жери тууралуу дайындарды көрүү"</string>
<string name="permgrouplab_calendar" msgid="5863508437783683902">"Күнбарак"</string>
<string name="permgroupdesc_calendar" msgid="3889615280211184106">"жылнаамаңызды пайдалануу"</string>
<string name="permgrouplab_sms" msgid="228308803364967808">"SMS"</string>
@@ -1495,6 +1495,7 @@
<item quantity="one">1 саатка</item>
</plurals>
<string name="zen_mode_until" msgid="7336308492289875088">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g> чейин"</string>
+ <string name="zen_mode_alarm" msgid="9128205721301330797">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g> чейин (кийинки ойготкуч)"</string>
<string name="zen_mode_forever" msgid="7420011936770086993">"Бул өчүрүлгөнгө чейин"</string>
<string name="zen_mode_forever_dnd" msgid="3792132696572189081">"\"Тынчымды алба\" режими өчүрүлгөнгө чейин"</string>
<string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g>/<xliff:g id="REST">%2$s</xliff:g>"</string>
diff --git a/core/res/res/values-lo-rLA/strings.xml b/core/res/res/values-lo-rLA/strings.xml
index dada9ce..30ecce5 100644
--- a/core/res/res/values-lo-rLA/strings.xml
+++ b/core/res/res/values-lo-rLA/strings.xml
@@ -1488,6 +1488,7 @@
<item quantity="one">ເປັນເວລາ 1 ຊມ</item>
</plurals>
<string name="zen_mode_until" msgid="7336308492289875088">"ຈົນຮອດ <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
+ <string name="zen_mode_alarm" msgid="9128205721301330797">"ຈົນກ່ວາ <xliff:g id="FORMATTEDTIME">%1$s</xliff:g> (ສັນຍານເຕືອນຕໍ່ໄປ)"</string>
<string name="zen_mode_forever" msgid="7420011936770086993">"ຈົນກວ່າທ່ານຈະປິດ"</string>
<string name="zen_mode_forever_dnd" msgid="3792132696572189081">"ຈົນກ່ວາທ່ານປິດຫ້າມລົບກວນ"</string>
<string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string>
diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml
index bdf0f3f..19f54ff 100644
--- a/core/res/res/values-lt/strings.xml
+++ b/core/res/res/values-lt/strings.xml
@@ -1522,6 +1522,7 @@
<item quantity="other">%d val.</item>
</plurals>
<string name="zen_mode_until" msgid="7336308492289875088">"Iki <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
+ <string name="zen_mode_alarm" msgid="9128205721301330797">"Iki <xliff:g id="FORMATTEDTIME">%1$s</xliff:g> (kitas signalas)"</string>
<string name="zen_mode_forever" msgid="7420011936770086993">"Kol išjungsite"</string>
<string name="zen_mode_forever_dnd" msgid="3792132696572189081">"Kol neišjungsite režimo „Netrukdyti“"</string>
<string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string>
diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml
index 4939eb3..54a8575 100644
--- a/core/res/res/values-lv/strings.xml
+++ b/core/res/res/values-lv/strings.xml
@@ -1505,6 +1505,7 @@
<item quantity="other">%d h</item>
</plurals>
<string name="zen_mode_until" msgid="7336308492289875088">"Līdz <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
+ <string name="zen_mode_alarm" msgid="9128205721301330797">"Līdz plkst. <xliff:g id="FORMATTEDTIME">%1$s</xliff:g> (nākamais signāls)"</string>
<string name="zen_mode_forever" msgid="7420011936770086993">"Līdz brīdim, kad izslēgsiet"</string>
<string name="zen_mode_forever_dnd" msgid="3792132696572189081">"Līdz izslēgsiet statusu “Netraucēt”"</string>
<string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g>/<xliff:g id="REST">%2$s</xliff:g>"</string>
diff --git a/core/res/res/values-mcc204-mnc04/config.xml b/core/res/res/values-mcc204-mnc04/config.xml
index fb639ca..0f39e42 100755
--- a/core/res/res/values-mcc204-mnc04/config.xml
+++ b/core/res/res/values-mcc204-mnc04/config.xml
@@ -44,14 +44,5 @@
<item>false</item>
</string-array>
- <!-- String containing the apn value for tethering. May be overriden by secure settings
- TETHER_DUN_APN. Value is a comma separated series of strings:
- "name,apn,proxy,port,username,password,server,mmsc,mmsproxy,mmsport,mcc,mnc,auth,type",
- Or string format of ApnSettingV3.
- note that empty fields can be ommitted: "name,apn,,,,,,,,,310,260,,DUN" -->
- <string-array translatable="false" name="config_tether_apndata">
- <item>[ApnSettingV3]SaskTel Tethering,inet.stm.sk.ca,,,,,,,,,204,04,,DUN,,,true,0,,,,,,,gid,5A</item>
- </string-array>
-
<string translatable="false" name="prohibit_manual_network_selection_in_gobal_mode">true;BAE0000000000000</string>
</resources>
diff --git a/core/res/res/values-mcc204-mnc12/config.xml b/core/res/res/values-mcc204-mnc12/config.xml
new file mode 100644
index 0000000..80432d7
--- /dev/null
+++ b/core/res/res/values-mcc204-mnc12/config.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2015, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my 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.
+*/
+-->
+
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- Don't use roaming icon for considered operators -->
+ <string-array translatable="false" name="config_operatorConsideredNonRoaming">
+ <item>20408</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-mcc219-mnc02/config.xml b/core/res/res/values-mcc219-mnc02/config.xml
new file mode 100644
index 0000000..2ac6ba6
--- /dev/null
+++ b/core/res/res/values-mcc219-mnc02/config.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2015, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my 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.
+*/
+-->
+
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- Don't use roaming icon for considered operators -->
+ <string-array translatable="false" name="config_operatorConsideredNonRoaming">
+ <item>21901</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-mcc240-mnc01/config.xml b/core/res/res/values-mcc240-mnc01/config.xml
new file mode 100644
index 0000000..7fb5c46
--- /dev/null
+++ b/core/res/res/values-mcc240-mnc01/config.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2013, 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 my 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.
+*/
+-->
+
+<!-- These resources are around just to allow their values to be customized
+ for different hardware and product builds. -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+
+ <!-- Do not set the system language as value of EF LI/EF PL -->
+ <bool name="config_use_sim_language_file">false</bool>
+
+</resources>
diff --git a/core/res/res/values-mcc240-mnc05/config.xml b/core/res/res/values-mcc240-mnc05/config.xml
new file mode 100644
index 0000000..7fb5c46
--- /dev/null
+++ b/core/res/res/values-mcc240-mnc05/config.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2013, 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 my 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.
+*/
+-->
+
+<!-- These resources are around just to allow their values to be customized
+ for different hardware and product builds. -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+
+ <!-- Do not set the system language as value of EF LI/EF PL -->
+ <bool name="config_use_sim_language_file">false</bool>
+
+</resources>
diff --git a/core/res/res/values-mcc302-mnc780/config.xml b/core/res/res/values-mcc302-mnc780/config.xml
index 51abd36..a48f695 100644
--- a/core/res/res/values-mcc302-mnc780/config.xml
+++ b/core/res/res/values-mcc302-mnc780/config.xml
@@ -21,25 +21,6 @@
for different hardware and product builds. -->
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <!-- Array of ConnectivityManager.TYPE_xxxx values allowable for tethering -->
- <!-- Common options are [1, 4] for TYPE_WIFI and TYPE_MOBILE_DUN or
- <!== [0,1,5,7] for TYPE_MOBILE, TYPE_WIFI, TYPE_MOBILE_HIPRI and TYPE_BLUETOOTH -->
- <integer-array translatable="false" name="config_tether_upstream_types">
- <item>1</item>
- <item>4</item>
- <item>7</item>
- <item>9</item>
- </integer-array>
-
- <!-- String containing the apn value for tethering. May be overriden by secure settings
- TETHER_DUN_APN. Value is a comma separated series of strings:
- "name,apn,proxy,port,username,password,server,mmsc,mmsproxy,mmsport,mcc,mnc,auth,type",
- Or string format of ApnSettingV3.
- note that empty fields can be ommitted: "name,apn,,,,,,,,,310,260,,DUN" -->
- <string-array translatable="false" name="config_tether_apndata">
- <item>SaskTel Tethering,inet.stm.sk.ca,,,,,,,,,302,780,,DUN</item>
- </string-array>
-
<!-- Don't use roaming icon for considered operators -->
<string-array translatable="false" name="config_operatorConsideredNonRoaming">
<item>302</item>
diff --git a/core/res/res/values-mcc310-mnc260-nl/strings.xml b/core/res/res/values-mcc310-mnc260-nl/strings.xml
index 1c6b892..ac4961c 100644
--- a/core/res/res/values-mcc310-mnc260-nl/strings.xml
+++ b/core/res/res/values-mcc310-mnc260-nl/strings.xml
@@ -23,10 +23,10 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string-array name="wfcOperatorErrorAlertMessages">
- <item msgid="7239039348648848288">"Als u wilt bellen en berichten wilt verzenden via wifi, moet u eerst uw provider vragen deze service in te stellen. Schakel bellen via wifi vervolgens opnieuw in via \'Instellingen\'."</item>
+ <item msgid="7239039348648848288">"Als je wilt bellen en berichten wilt verzenden via wifi, moet je eerst je provider vragen deze service in te stellen. Schakel bellen via wifi vervolgens opnieuw in via \'Instellingen\'."</item>
</string-array>
<string-array name="wfcOperatorErrorNotificationMessages">
- <item msgid="483847327467331298">"Registreren bij uw provider"</item>
+ <item msgid="483847327467331298">"Registreren bij je provider"</item>
</string-array>
<string name="wfcSpnFormat" msgid="4982938551498609442">"Bellen via wifi van %s"</string>
</resources>
diff --git a/core/res/res/values-mcc450-mnc06/config.xml b/core/res/res/values-mcc450-mnc06/config.xml
index 63f9823..819c2a5 100644
--- a/core/res/res/values-mcc450-mnc06/config.xml
+++ b/core/res/res/values-mcc450-mnc06/config.xml
@@ -25,4 +25,7 @@
-->
<integer name="config_mobile_mtu">1428</integer>
+ <!-- Do not set the system language as value of EF LI/EF PL -->
+ <bool name="config_use_sim_language_file">false</bool>
+
</resources>
diff --git a/core/res/res/values-mcc450-mnc08/config.xml b/core/res/res/values-mcc450-mnc08/config.xml
index 950c62b..ca26ec1 100644
--- a/core/res/res/values-mcc450-mnc08/config.xml
+++ b/core/res/res/values-mcc450-mnc08/config.xml
@@ -25,4 +25,7 @@
-->
<integer name="config_mobile_mtu">1450</integer>
+ <!-- Do not set the system language as value of EF LI/EF PL -->
+ <bool name="config_use_sim_language_file">false</bool>
+
</resources>
diff --git a/core/res/res/values-mcc730-mnc01/config.xml b/core/res/res/values-mcc730-mnc01/config.xml
new file mode 100644
index 0000000..22f4027
--- /dev/null
+++ b/core/res/res/values-mcc730-mnc01/config.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2015, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my 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.
+*/
+-->
+
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- Don't use roaming icon for considered operators -->
+ <string-array translatable="false" name="config_operatorConsideredNonRoaming">
+ <item>73010</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-mcc730-mnc07/config.xml b/core/res/res/values-mcc730-mnc07/config.xml
new file mode 100644
index 0000000..836ddf9
--- /dev/null
+++ b/core/res/res/values-mcc730-mnc07/config.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2015, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my 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.
+*/
+-->
+
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- Don't use roaming icon for considered operators -->
+ <string-array translatable="false" name="config_operatorConsideredNonRoaming">
+ <item>73002</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-mcc730-mnc08/config.xml b/core/res/res/values-mcc730-mnc08/config.xml
new file mode 100644
index 0000000..836ddf9
--- /dev/null
+++ b/core/res/res/values-mcc730-mnc08/config.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2015, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my 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.
+*/
+-->
+
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- Don't use roaming icon for considered operators -->
+ <string-array translatable="false" name="config_operatorConsideredNonRoaming">
+ <item>73002</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-mcc730-mnc10/config.xml b/core/res/res/values-mcc730-mnc10/config.xml
new file mode 100644
index 0000000..58b7d78
--- /dev/null
+++ b/core/res/res/values-mcc730-mnc10/config.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2015, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my 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.
+*/
+-->
+
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- Don't use roaming icon for considered operators -->
+ <string-array translatable="false" name="config_operatorConsideredNonRoaming">
+ <item>73001</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-mk-rMK/strings.xml b/core/res/res/values-mk-rMK/strings.xml
index 95cf944..8dfdf1d 100644
--- a/core/res/res/values-mk-rMK/strings.xml
+++ b/core/res/res/values-mk-rMK/strings.xml
@@ -227,23 +227,23 @@
<string name="user_owner_label" msgid="2804351898001038951">"Лични"</string>
<string name="managed_profile_label" msgid="6260850669674791528">"Работа"</string>
<string name="permgrouplab_contacts" msgid="3657758145679177612">"Контакти"</string>
- <string name="permgroupdesc_contacts" msgid="6951499528303668046">"пристапи до контактите"</string>
+ <string name="permgroupdesc_contacts" msgid="6951499528303668046">"пристапува до контактите"</string>
<string name="permgrouplab_location" msgid="7275582855722310164">"Локација"</string>
- <string name="permgroupdesc_location" msgid="1346617465127855033">"да пристапува до локацијата на овој уред"</string>
+ <string name="permgroupdesc_location" msgid="1346617465127855033">"пристапува до локацијата на овој уред"</string>
<string name="permgrouplab_calendar" msgid="5863508437783683902">"Календар"</string>
- <string name="permgroupdesc_calendar" msgid="3889615280211184106">"пристапи до календарот"</string>
+ <string name="permgroupdesc_calendar" msgid="3889615280211184106">"пристапува до календарот"</string>
<string name="permgrouplab_sms" msgid="228308803364967808">"СМС"</string>
<string name="permgroupdesc_sms" msgid="4656988620100940350">"испраќа и прикажува СМС-пораки"</string>
<string name="permgrouplab_storage" msgid="1971118770546336966">"Меморија"</string>
- <string name="permgroupdesc_storage" msgid="637758554581589203">"пристапува до фотографии, медиуми и датотеки на уредот"</string>
+ <string name="permgroupdesc_storage" msgid="637758554581589203">"пристапува до фотографии, аудио-видео и датотеки на уредот"</string>
<string name="permgrouplab_microphone" msgid="171539900250043464">"Микрофон"</string>
- <string name="permgroupdesc_microphone" msgid="4988812113943554584">"снимај аудио"</string>
+ <string name="permgroupdesc_microphone" msgid="4988812113943554584">"снима аудио"</string>
<string name="permgrouplab_camera" msgid="4820372495894586615">"Фотоапарат"</string>
- <string name="permgroupdesc_camera" msgid="3250611594678347720">"фотографирај и снимај видео"</string>
+ <string name="permgroupdesc_camera" msgid="3250611594678347720">"фотографира и снима видео"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"Телефон"</string>
- <string name="permgroupdesc_phone" msgid="6234224354060641055">"повикувај и управувај со телефонски повици"</string>
+ <string name="permgroupdesc_phone" msgid="6234224354060641055">"упатува и управува со телефонски повици"</string>
<string name="permgrouplab_sensors" msgid="416037179223226722">"Телесни сензори"</string>
- <string name="permgroupdesc_sensors" msgid="7147968539346634043">"пристапи до податоците од сензорите за виталните знаци"</string>
+ <string name="permgroupdesc_sensors" msgid="7147968539346634043">"пристапува до податоците од сензорите за виталните знаци"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Врати содржина на прозорец"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Провери ја содржината на прозорецот со кој се комуницира."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Вклучи „Истражувај со допир“"</string>
@@ -1490,6 +1490,7 @@
<item quantity="other">За %d ч.</item>
</plurals>
<string name="zen_mode_until" msgid="7336308492289875088">"До <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
+ <string name="zen_mode_alarm" msgid="9128205721301330797">"До <xliff:g id="FORMATTEDTIME">%1$s</xliff:g> (следниот аларм)"</string>
<string name="zen_mode_forever" msgid="7420011936770086993">"Додека не го исклучите"</string>
<string name="zen_mode_forever_dnd" msgid="3792132696572189081">"Додека не го исклучите Не вознемирувај"</string>
<string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string>
diff --git a/core/res/res/values-ml-rIN/strings.xml b/core/res/res/values-ml-rIN/strings.xml
index edb470b..330c1e9 100644
--- a/core/res/res/values-ml-rIN/strings.xml
+++ b/core/res/res/values-ml-rIN/strings.xml
@@ -1167,7 +1167,7 @@
<string name="sync_really_delete" msgid="2572600103122596243">"ഇനങ്ങൾ ഇല്ലാതാക്കുക"</string>
<string name="sync_undo_deletes" msgid="2941317360600338602">"ഇല്ലാതാക്കിയവ പഴയപടിയാക്കുക"</string>
<string name="sync_do_nothing" msgid="3743764740430821845">"ഇപ്പോൾ ഒന്നും ചെയ്യേണ്ടതില്ല"</string>
- <string name="choose_account_label" msgid="5655203089746423927">"ഒരു അക്കൗണ്ട് തിരഞ്ഞെടുക്കുക"</string>
+ <string name="choose_account_label" msgid="5655203089746423927">"അക്കൗണ്ട് തിരഞ്ഞെടുക്കൂ"</string>
<string name="add_account_label" msgid="2935267344849993553">"ഒരു അക്കൗണ്ട് ചേർക്കുക"</string>
<string name="add_account_button_label" msgid="3611982894853435874">"അക്കൗണ്ട് ചേർക്കുക"</string>
<string name="number_picker_increment_button" msgid="2412072272832284313">"വർദ്ധിപ്പിക്കുക"</string>
@@ -1488,6 +1488,7 @@
<item quantity="one">ഒരു മണിക്കൂറത്തേക്ക്</item>
</plurals>
<string name="zen_mode_until" msgid="7336308492289875088">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g> വരെ"</string>
+ <string name="zen_mode_alarm" msgid="9128205721301330797">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g> വരെ (അടുത്ത അലാറം)"</string>
<string name="zen_mode_forever" msgid="7420011936770086993">"നിങ്ങൾ ഇത് ഓഫാക്കും വരെ"</string>
<string name="zen_mode_forever_dnd" msgid="3792132696572189081">"\'ശല്ല്യപ്പെടുത്തരുത്\' ഓഫാക്കുന്നതുവരെ"</string>
<string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string>
diff --git a/core/res/res/values-mn-rMN/strings.xml b/core/res/res/values-mn-rMN/strings.xml
index bbae506..2e6eb85 100644
--- a/core/res/res/values-mn-rMN/strings.xml
+++ b/core/res/res/values-mn-rMN/strings.xml
@@ -1486,6 +1486,7 @@
<item quantity="one">1 цагийн турш:</item>
</plurals>
<string name="zen_mode_until" msgid="7336308492289875088">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g> хүртэл"</string>
+ <string name="zen_mode_alarm" msgid="9128205721301330797">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g> хүртэл (дараагийн сэрүүлэг)"</string>
<string name="zen_mode_forever" msgid="7420011936770086993">"Таныг унтраах хүртэл"</string>
<string name="zen_mode_forever_dnd" msgid="3792132696572189081">"\"Бүү саад бол\"-ыг унтраах хүртэл"</string>
<string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string>
diff --git a/core/res/res/values-mr-rIN/strings.xml b/core/res/res/values-mr-rIN/strings.xml
index 99262b0..74f36b9 100644
--- a/core/res/res/values-mr-rIN/strings.xml
+++ b/core/res/res/values-mr-rIN/strings.xml
@@ -1488,6 +1488,7 @@
<item quantity="other">%d तासासाठी</item>
</plurals>
<string name="zen_mode_until" msgid="7336308492289875088">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g> पर्यंत"</string>
+ <string name="zen_mode_alarm" msgid="9128205721301330797">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g> पर्यंत (पुढील अलार्म)"</string>
<string name="zen_mode_forever" msgid="7420011936770086993">"आपण हे बंद करेपर्यंत"</string>
<string name="zen_mode_forever_dnd" msgid="3792132696572189081">"आपण बंद करेपर्यंत व्यत्यय आणू नका"</string>
<string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string>
diff --git a/core/res/res/values-ms-rMY/strings.xml b/core/res/res/values-ms-rMY/strings.xml
index 01f5c46..5d666a7 100644
--- a/core/res/res/values-ms-rMY/strings.xml
+++ b/core/res/res/values-ms-rMY/strings.xml
@@ -1488,6 +1488,7 @@
<item quantity="one">Selama 1 jam</item>
</plurals>
<string name="zen_mode_until" msgid="7336308492289875088">"Sehingga <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
+ <string name="zen_mode_alarm" msgid="9128205721301330797">"Sehingga <xliff:g id="FORMATTEDTIME">%1$s</xliff:g> (penggera akan datang)"</string>
<string name="zen_mode_forever" msgid="7420011936770086993">"Sehingga anda matikan"</string>
<string name="zen_mode_forever_dnd" msgid="3792132696572189081">"Hingga anda mematikan Jangan Ganggu"</string>
<string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string>
diff --git a/core/res/res/values-my-rMM/strings.xml b/core/res/res/values-my-rMM/strings.xml
index 690a0ef..e65be4d 100644
--- a/core/res/res/values-my-rMM/strings.xml
+++ b/core/res/res/values-my-rMM/strings.xml
@@ -229,7 +229,7 @@
<string name="permgrouplab_contacts" msgid="3657758145679177612">"အဆက်အသွယ်များ"</string>
<string name="permgroupdesc_contacts" msgid="6951499528303668046">"သင့် အဆက်အသွယ်များအား ဝင်ရောက်သုံးရန်"</string>
<string name="permgrouplab_location" msgid="7275582855722310164">"တည်နေရာ"</string>
- <string name="permgroupdesc_location" msgid="1346617465127855033">"စက်ပစ္စည်း၏ တည်နေရာကို အသုံးပြုမည်"</string>
+ <string name="permgroupdesc_location" msgid="1346617465127855033">"ဤစက်ပစ္စည်း၏ တည်နေရာကို ရယူ"</string>
<string name="permgrouplab_calendar" msgid="5863508437783683902">"ပြက္ခဒိန်"</string>
<string name="permgroupdesc_calendar" msgid="3889615280211184106">"သင့်ပြက္ခဒိန်အား ဝင်ရောက်သုံးရန်"</string>
<string name="permgrouplab_sms" msgid="228308803364967808">"စာတိုစနစ်"</string>
@@ -1488,6 +1488,7 @@
<item quantity="one">၁ နာရီအတွက်</item>
</plurals>
<string name="zen_mode_until" msgid="7336308492289875088">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g>အထိ"</string>
+ <string name="zen_mode_alarm" msgid="9128205721301330797">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g> အထိ (လာမည့် နှိုးစက်)"</string>
<string name="zen_mode_forever" msgid="7420011936770086993">"သင်က ဒါကို ပိတ်မပစ်သည့် အထိ"</string>
<string name="zen_mode_forever_dnd" msgid="3792132696572189081">"မနှောင့်ယှက်ရန် ကိုသင်ပိတ်သည်အထိ"</string>
<string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string>
diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml
index 5df9a82..46d2d04 100644
--- a/core/res/res/values-nb/strings.xml
+++ b/core/res/res/values-nb/strings.xml
@@ -229,7 +229,7 @@
<string name="permgrouplab_contacts" msgid="3657758145679177612">"Kontakter"</string>
<string name="permgroupdesc_contacts" msgid="6951499528303668046">"se kontaktene dine"</string>
<string name="permgrouplab_location" msgid="7275582855722310164">"Posisjon"</string>
- <string name="permgroupdesc_location" msgid="1346617465127855033">"tilgang til enhetens plassering"</string>
+ <string name="permgroupdesc_location" msgid="1346617465127855033">"få tilgang til enhetens plassering"</string>
<string name="permgrouplab_calendar" msgid="5863508437783683902">"Kalender"</string>
<string name="permgroupdesc_calendar" msgid="3889615280211184106">"åpne kalenderen din"</string>
<string name="permgrouplab_sms" msgid="228308803364967808">"SMS"</string>
@@ -1488,6 +1488,7 @@
<item quantity="one">I én time</item>
</plurals>
<string name="zen_mode_until" msgid="7336308492289875088">"Til <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
+ <string name="zen_mode_alarm" msgid="9128205721301330797">"Til <xliff:g id="FORMATTEDTIME">%1$s</xliff:g> (neste alarm)"</string>
<string name="zen_mode_forever" msgid="7420011936770086993">"Inntil du slår av funksjonen"</string>
<string name="zen_mode_forever_dnd" msgid="3792132696572189081">"Inntil du slår av Ikke forstyrr"</string>
<string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g>/<xliff:g id="REST">%2$s</xliff:g>"</string>
diff --git a/core/res/res/values-ne-rNP/strings.xml b/core/res/res/values-ne-rNP/strings.xml
index 3e8e5b6..0d54602 100644
--- a/core/res/res/values-ne-rNP/strings.xml
+++ b/core/res/res/values-ne-rNP/strings.xml
@@ -87,7 +87,7 @@
<string name="CLIRDefaultOffNextCallOn" msgid="6179425182856418465">"कलर ID पूर्वनिर्धारितदेखि प्रतिबन्धित छैन। अर्को कल: प्रतिबन्धित छ"</string>
<string name="CLIRDefaultOffNextCallOff" msgid="2567998633124408552">"कलर ID पूर्वनिर्धारितको लागि रोकावट छैन। अर्को कल: रोकावट छैन"</string>
<string name="serviceNotProvisioned" msgid="8614830180508686666">"सेवाको व्यवस्था छैन।"</string>
- <string name="CLIRPermanent" msgid="3377371145926835671">"तपाईं कलर ID सेटिङ परिवर्तन गर्न सक्नुहुन्न।"</string>
+ <string name="CLIRPermanent" msgid="3377371145926835671">"तपाईँ कलर ID सेटिङ परिवर्तन गर्न सक्नुहुन्न।"</string>
<string name="RestrictedChangedTitle" msgid="5592189398956187498">"प्रतिबन्धित पहुँच परिवर्तन भएको छ"</string>
<string name="RestrictedOnData" msgid="8653794784690065540">"डेटा सेवा रोकिएको छ।"</string>
<string name="RestrictedOnEmergency" msgid="6581163779072833665">"आपतकालीन सेवा रोकिएको छ।"</string>
@@ -198,7 +198,7 @@
<string name="shutdown_confirm" product="tv" msgid="476672373995075359">"तपाईंको TV बन्द हुनेछ।"</string>
<string name="shutdown_confirm" product="watch" msgid="3490275567476369184">"तपाईँको घडी बन्द गरिने छ।"</string>
<string name="shutdown_confirm" product="default" msgid="649792175242821353">"तपाईँको फोन बन्द हुने छ।"</string>
- <string name="shutdown_confirm_question" msgid="2906544768881136183">"के तपाईं बन्द गर्न चाहनुहुन्छ?"</string>
+ <string name="shutdown_confirm_question" msgid="2906544768881136183">"के तपाईँ बन्द गर्न चाहनुहुन्छ?"</string>
<string name="reboot_safemode_title" msgid="7054509914500140361">"सुरक्षित मोडमा पुनःबुट गर्नुहोस्"</string>
<string name="reboot_safemode_confirm" msgid="55293944502784668">"सुरक्षित मोडमा तपाईँ पुनःबुट गर्न चाहनु हुन्छ? तपाईँले स्थापना गरेका सबै तेस्रो पक्षका अनुप्रयोगहरूलाई असक्षम गराउने छ।"</string>
<string name="recent_tasks_title" msgid="3691764623638127888">"नयाँ"</string>
@@ -786,7 +786,7 @@
<string name="permdesc_addVoicemail" msgid="6604508651428252437">"तपाईँको भ्वाइसमेल इनबक्समा सन्देश थप्नको लागि अनुप्रयोगलाई अनुमति दिन्छ।"</string>
<string name="permlab_writeGeolocationPermissions" msgid="5962224158955273932">"भूस्थान अनुमतिहरू ब्राउजर परिवर्तन गर्नुहोस्"</string>
<string name="permdesc_writeGeolocationPermissions" msgid="1083743234522638747">"ब्राउजरको भू-स्थान अनुमतिहरू परिमार्जन गर्न अनुप्रयोगलाई अनुमति दिन्छ। खराब अनुप्रयोगहरूले स्थान सूचना मनपरी वेब साइटहरूमा पठाउने अनुमतिको लागि यसलाई प्रयोग गर्न सक्छन्।"</string>
- <string name="save_password_message" msgid="767344687139195790">"के तपाईं ब्राउजरले यो पासवर्ड सम्झेको चाहनुहुन्छ?"</string>
+ <string name="save_password_message" msgid="767344687139195790">"के तपाईँ ब्राउजरले यो पासवर्ड सम्झेको चाहनुहुन्छ?"</string>
<string name="save_password_notnow" msgid="6389675316706699758">"अहिले होइन"</string>
<string name="save_password_remember" msgid="6491879678996749466">"सम्झनुहोस्"</string>
<string name="save_password_never" msgid="8274330296785855105">"कहिल्यै पनि होइन"</string>
@@ -906,13 +906,13 @@
<string name="aerr_process" msgid="4507058997035697579">"दुर्भाग्यवश, प्रक्रिया <xliff:g id="PROCESS">%1$s</xliff:g> बन्द भयो।"</string>
<string name="anr_title" msgid="4351948481459135709"></string>
<string name="anr_activity_application" msgid="1904477189057199066">"<xliff:g id="APPLICATION">%2$s</xliff:g>ले कार्य गरिरहेको छैन।\n\nके तपाईँ यसलाई बन्द गर्न चाहनु हुन्छ?"</string>
- <string name="anr_activity_process" msgid="5776209883299089767">"गतिविधि <xliff:g id="ACTIVITY">%1$s</xliff:g> ले प्रतिक्रिया देखाइरहेको छैन।\n\nके तपाईं यसलाई बन्द गर्न चाहनु हुन्छ?"</string>
+ <string name="anr_activity_process" msgid="5776209883299089767">"गतिविधि <xliff:g id="ACTIVITY">%1$s</xliff:g> ले प्रतिक्रिया देखाइरहेको छैन।\n\nके तपाईँ यसलाई बन्द गर्न चाहनु हुन्छ?"</string>
<string name="anr_application_process" msgid="8941757607340481057">"<xliff:g id="APPLICATION">%1$s</xliff:g> जवाफ दिइरहेको छैन। के तपाईँ यसलाई बन्द गर्न चाहनु हुन्छ?"</string>
<string name="anr_process" msgid="6513209874880517125">"प्रक्रिया <xliff:g id="PROCESS">%1$s</xliff:g>ले कार्य गरिरहेको छैन।\n\nके तपाईँ यसलाई बन्द गर्न चाहनु हुन्छ?"</string>
<string name="force_close" msgid="8346072094521265605">"ठिक छ"</string>
<string name="report" msgid="4060218260984795706">"रिपोर्ट गर्नुहोस्"</string>
<string name="wait" msgid="7147118217226317732">"प्रतीक्षा गर्नुहोस्"</string>
- <string name="webpage_unresponsive" msgid="3272758351138122503">"पृष्ठ गैर जिम्मेवारी भएको छ।\n\nके तपाईं यसलाई बन्द गर्न चाहनुहुन्छ?"</string>
+ <string name="webpage_unresponsive" msgid="3272758351138122503">"पृष्ठ गैर जिम्मेवारी भएको छ।\n\nके तपाईँ यसलाई बन्द गर्न चाहनुहुन्छ?"</string>
<string name="launch_warning_title" msgid="1547997780506713581">"अनुप्रयोग पुनः निर्देशीत"</string>
<string name="launch_warning_replace" msgid="6202498949970281412">"<xliff:g id="APP_NAME">%1$s</xliff:g> अहिले चलिरहेको छ।"</string>
<string name="launch_warning_original" msgid="188102023021668683">"<xliff:g id="APP_NAME">%1$s</xliff:g> वास्तविक सुरुवात भएको थियो।"</string>
@@ -1025,8 +1025,8 @@
<string name="perm_costs_money" msgid="4902470324142151116">"सायद तपाईँलाई पैसा पर्न सक्छ।"</string>
<string name="usb_storage_activity_title" msgid="4465055157209648641">"USB ठूलो भण्डारण"</string>
<string name="usb_storage_title" msgid="5901459041398751495">"USB जोडिएको छ"</string>
- <string name="usb_storage_message" product="nosdcard" msgid="3308538094316477839">"तपाईं आफ्नो कम्प्युटरमा USB मार्फत जडान हुनुभयो। तलको बटन टच गर्नुहोस् यदि तपाईं आफ्नो कम्प्युटर र एन्ड्रोइडको USB भण्डारण बीच फाइलहरू प्रतिलिपि गर्न चाहनुहुन्छ भने।"</string>
- <string name="usb_storage_message" product="default" msgid="805351000446037811">"तपाईं आफ्नो कम्प्युटरमा USB मार्फत जडान हुनुभयो। तलको बटन टच गर्नुहोस् यदि तपाईं आफ्नो कम्प्युटर र एन्ड्रोइडको SD कार्ड बीच फाइलहरू प्रतिलिपि गर्न चाहनुहुन्छ भने।"</string>
+ <string name="usb_storage_message" product="nosdcard" msgid="3308538094316477839">"तपाईँ आफ्नो कम्प्युटरमा USB मार्फत जडान हुनुभयो। तलको बटन टच गर्नुहोस् यदि तपाईँ आफ्नो कम्प्युटर र एन्ड्रोइडको USB भण्डारण बीच फाइलहरू प्रतिलिपि गर्न चाहनुहुन्छ भने।"</string>
+ <string name="usb_storage_message" product="default" msgid="805351000446037811">"तपाईँ आफ्नो कम्प्युटरमा USB मार्फत जडान हुनुभयो। तलको बटन टच गर्नुहोस् यदि तपाईँ आफ्नो कम्प्युटर र एन्ड्रोइडको SD कार्ड बीच फाइलहरू प्रतिलिपि गर्न चाहनुहुन्छ भने।"</string>
<string name="usb_storage_button_mount" msgid="1052259930369508235">"USB भण्डारण चालु गर्नुहोस्"</string>
<string name="usb_storage_error_message" product="nosdcard" msgid="3017045217365540658">"USB आम भण्डारणको लागि तपाईँको USB भण्डारण प्रयोग गर्दा एउटा समस्या भयो।"</string>
<string name="usb_storage_error_message" product="default" msgid="2876018512716970313">"USB आम भण्डारणको लागि तपाईँको SD कार्ड प्रयोग गर्दा एउटा समस्या भयो।"</string>
@@ -1121,7 +1121,7 @@
<string name="deny" msgid="2081879885755434506">"अस्वीकार गर्नुहोस्"</string>
<string name="permission_request_notification_title" msgid="6486759795926237907">"अनुरोध गरिएको अनुमति"</string>
<string name="permission_request_notification_with_subtitle" msgid="8530393139639560189">\n"खाता <xliff:g id="ACCOUNT">%s</xliff:g>को लागि अनुरोध गरिएको अनुमति।"</string>
- <string name="forward_intent_to_owner" msgid="1207197447013960896">"तपाईं तपाईँको कार्य प्रोफाइल बाहिर यो अनुप्रयोग प्रयोग गरिरहनु भएको छ"</string>
+ <string name="forward_intent_to_owner" msgid="1207197447013960896">"तपाईँ तपाईँको कार्य प्रोफाइल बाहिर यो अनुप्रयोग प्रयोग गरिरहनु भएको छ"</string>
<string name="forward_intent_to_work" msgid="621480743856004612">"तपाईँ आफ्नो कार्य प्रोफाइलमा यो अनुप्रयोग प्रयोग गरिरहनु भएको छ"</string>
<string name="input_method_binding_label" msgid="1283557179944992649">"इनपुट विधि"</string>
<string name="sync_binding_label" msgid="3687969138375092423">"सिङ्क गर्नुहोस्"</string>
@@ -1169,7 +1169,7 @@
<string name="gpsVerifYes" msgid="2346566072867213563">"हो"</string>
<string name="gpsVerifNo" msgid="1146564937346454865">"होइन"</string>
<string name="sync_too_many_deletes" msgid="5296321850662746890">"सीमा नाघेकाहरू मेट्नुहोस्"</string>
- <string name="sync_too_many_deletes_desc" msgid="496551671008694245">"त्यहाँ <xliff:g id="NUMBER_OF_DELETED_ITEMS">%1$d</xliff:g> मेटाइएका आइटमहरू छन् <xliff:g id="TYPE_OF_SYNC">%2$s</xliff:g>को लागि, खाता <xliff:g id="ACCOUNT_NAME">%3$s</xliff:g>। तपाईं के गर्न चाहनु हुन्छ?"</string>
+ <string name="sync_too_many_deletes_desc" msgid="496551671008694245">"त्यहाँ <xliff:g id="NUMBER_OF_DELETED_ITEMS">%1$d</xliff:g> मेटाइएका आइटमहरू छन् <xliff:g id="TYPE_OF_SYNC">%2$s</xliff:g>को लागि, खाता <xliff:g id="ACCOUNT_NAME">%3$s</xliff:g>। तपाईँ के गर्न चाहनु हुन्छ?"</string>
<string name="sync_really_delete" msgid="2572600103122596243">"वस्तुहरू मेट्नुहोस्"</string>
<string name="sync_undo_deletes" msgid="2941317360600338602">"मेटिएकाहरू पूर्ववत बनाउनुहोस्।"</string>
<string name="sync_do_nothing" msgid="3743764740430821845">"अहिलेको लागि केही नगर्नुहोस्"</string>
@@ -1494,6 +1494,7 @@
<item quantity="one">१ घन्टाको लागि</item>
</plurals>
<string name="zen_mode_until" msgid="7336308492289875088">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g> सम्म"</string>
+ <string name="zen_mode_alarm" msgid="9128205721301330797">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g> (अर्को अलार्म) सम्म"</string>
<string name="zen_mode_forever" msgid="7420011936770086993">"तपाईँले यसलाई बन्द नगरेसम्म"</string>
<string name="zen_mode_forever_dnd" msgid="3792132696572189081">"तपाईँले बन्द नगरे सम्म बाधा नपुर्याउँनुहोस्"</string>
<string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string>
diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml
index 27dd5dd..7eef339 100644
--- a/core/res/res/values-nl/strings.xml
+++ b/core/res/res/values-nl/strings.xml
@@ -39,7 +39,7 @@
<string name="durationMinuteSecond" msgid="3989228718067466680">"<xliff:g id="MINUTES">%1$d</xliff:g> min <xliff:g id="SECONDS">%2$d</xliff:g> sec"</string>
<string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> seconden"</string>
<string name="durationSecond" msgid="985669622276420331">"<xliff:g id="SECONDS">%1$d</xliff:g> seconde"</string>
- <string name="untitled" msgid="4638956954852782576">"<Zonder titel>"</string>
+ <string name="untitled" msgid="4638956954852782576">"<Naamloos>"</string>
<string name="emptyPhoneNumber" msgid="7694063042079676517">"(Geen telefoonnummer)"</string>
<string name="unknownName" msgid="6867811765370350269">"Onbekend"</string>
<string name="defaultVoiceMailAlphaTag" msgid="2660020990097733077">"Voicemail"</string>
@@ -53,17 +53,17 @@
<string name="serviceErased" msgid="1288584695297200972">"Wissen uitgevoerd."</string>
<string name="passwordIncorrect" msgid="7612208839450128715">"Onjuist wachtwoord."</string>
<string name="mmiComplete" msgid="8232527495411698359">"MMI voltooid."</string>
- <string name="badPin" msgid="9015277645546710014">"De oude pincode die u heeft ingevoerd, is onjuist."</string>
- <string name="badPuk" msgid="5487257647081132201">"De PUK-code die u heeft ingevoerd, is onjuist."</string>
- <string name="mismatchPin" msgid="609379054496863419">"De pincodes die u heeft ingevoerd, komen niet overeen."</string>
+ <string name="badPin" msgid="9015277645546710014">"De oude pincode die je hebt ingevoerd, is onjuist."</string>
+ <string name="badPuk" msgid="5487257647081132201">"De PUK-code die je hebt ingevoerd, is onjuist."</string>
+ <string name="mismatchPin" msgid="609379054496863419">"De pincodes die je hebt ingevoerd, komen niet overeen."</string>
<string name="invalidPin" msgid="3850018445187475377">"Voer een pincode van 4 tot 8 cijfers in."</string>
<string name="invalidPuk" msgid="8761456210898036513">"Typ een PUK-code die 8 cijfers of langer is."</string>
- <string name="needPuk" msgid="919668385956251611">"Uw SIM-kaart is vergrendeld met de PUK-code. Typ de PUK-code om te ontgrendelen."</string>
+ <string name="needPuk" msgid="919668385956251611">"Je SIM-kaart is vergrendeld met de PUK-code. Typ de PUK-code om te ontgrendelen."</string>
<string name="needPuk2" msgid="4526033371987193070">"Voer de PUK2-code in om de SIM-kaart te ontgrendelen."</string>
<string name="enablePin" msgid="209412020907207950">"Mislukt. Schakel SIM/RUIM-vergrendeling in."</string>
<plurals name="pinpuk_attempts" formatted="false" msgid="1251012001539225582">
- <item quantity="other">U heeft nog <xliff:g id="NUMBER_1">%d</xliff:g> pogingen over voordat de simkaart wordt vergrendeld.</item>
- <item quantity="one">U heeft nog <xliff:g id="NUMBER_0">%d</xliff:g> poging over voordat de simkaart wordt vergrendeld.</item>
+ <item quantity="other">Je hebt nog <xliff:g id="NUMBER_1">%d</xliff:g> pogingen over voordat de simkaart wordt vergrendeld.</item>
+ <item quantity="one">Je hebt nog <xliff:g id="NUMBER_0">%d</xliff:g> poging over voordat de simkaart wordt vergrendeld.</item>
</plurals>
<string name="imei" msgid="2625429890869005782">"IMEI"</string>
<string name="meid" msgid="4841221237681254195">"MEID"</string>
@@ -167,14 +167,14 @@
<string name="low_memory" product="default" msgid="3475999286680000541">"Telefoongeheugen is vol. Verwijder enkele bestanden om ruimte vrij te maken."</string>
<string name="ssl_ca_cert_warning" msgid="5848402127455021714">"Netwerk kan worden gecontroleerd"</string>
<string name="ssl_ca_cert_noti_by_unknown" msgid="4475437862189850602">"Door een onbekende derde partij"</string>
- <string name="ssl_ca_cert_noti_by_administrator" msgid="550758088185764312">"Door uw werkprofielbeheerder"</string>
+ <string name="ssl_ca_cert_noti_by_administrator" msgid="550758088185764312">"Door je werkprofielbeheerder"</string>
<string name="ssl_ca_cert_noti_managed" msgid="4030263497686867141">"Door <xliff:g id="MANAGING_DOMAIN">%s</xliff:g>"</string>
<string name="work_profile_deleted" msgid="5005572078641980632">"Werkprofiel verwijderd"</string>
<string name="work_profile_deleted_description" msgid="6305147513054341102">"Werkprofiel verwijderd wegens ontbrekende beheerapp."</string>
- <string name="work_profile_deleted_details" msgid="226615743462361248">"De beheerapp van het werkprofiel ontbreekt of is beschadigd. Als gevolg hiervan zijn uw werkprofiel en alle gerelateerde gegevens verwijderd. Neem voor hulp contact op met uw beheerder."</string>
- <string name="work_profile_deleted_description_dpm_wipe" msgid="6019770344820507579">"Uw werkprofiel is niet meer beschikbaar op dit apparaat."</string>
- <string name="factory_reset_warning" msgid="5423253125642394387">"Uw apparaat wordt gewist"</string>
- <string name="factory_reset_message" msgid="4905025204141900666">"Er ontbreken onderdelen van de beheerapp of de app is beschadigd, waardoor de app niet kan worden gebruikt. Uw apparaat wordt nu gewist. Neem voor hulp contact op met uw beheerder."</string>
+ <string name="work_profile_deleted_details" msgid="226615743462361248">"De beheerapp van het werkprofiel ontbreekt of is beschadigd. Als gevolg hiervan zijn je werkprofiel en alle gerelateerde gegevens verwijderd. Neem voor hulp contact op met je beheerder."</string>
+ <string name="work_profile_deleted_description_dpm_wipe" msgid="6019770344820507579">"Je werkprofiel is niet meer beschikbaar op dit apparaat."</string>
+ <string name="factory_reset_warning" msgid="5423253125642394387">"Je apparaat wordt gewist"</string>
+ <string name="factory_reset_message" msgid="4905025204141900666">"Er ontbreken onderdelen van de beheerapp of de app is beschadigd, waardoor de app niet kan worden gebruikt. Je apparaat wordt nu gewist. Neem voor hulp contact op met je beheerder."</string>
<string name="me" msgid="6545696007631404292">"Ik"</string>
<string name="power_dialog" product="tablet" msgid="8545351420865202853">"Tabletopties"</string>
<string name="power_dialog" product="tv" msgid="6153888706430556356">"TV-opties"</string>
@@ -194,10 +194,10 @@
<string name="reboot_to_reset_title" msgid="4142355915340627490">"Terugzetten op fabrieksinstellingen"</string>
<string name="reboot_to_reset_message" msgid="2432077491101416345">"Opnieuw opstarten…"</string>
<string name="shutdown_progress" msgid="2281079257329981203">"Uitschakelen..."</string>
- <string name="shutdown_confirm" product="tablet" msgid="3385745179555731470">"Uw tablet wordt uitgeschakeld."</string>
- <string name="shutdown_confirm" product="tv" msgid="476672373995075359">"Uw tv wordt uitgeschakeld.."</string>
- <string name="shutdown_confirm" product="watch" msgid="3490275567476369184">"Uw horloge wordt uitgeschakeld."</string>
- <string name="shutdown_confirm" product="default" msgid="649792175242821353">"Uw telefoon wordt uitgeschakeld."</string>
+ <string name="shutdown_confirm" product="tablet" msgid="3385745179555731470">"Je tablet wordt uitgeschakeld."</string>
+ <string name="shutdown_confirm" product="tv" msgid="476672373995075359">"Je tv wordt uitgeschakeld.."</string>
+ <string name="shutdown_confirm" product="watch" msgid="3490275567476369184">"Je horloge wordt uitgeschakeld."</string>
+ <string name="shutdown_confirm" product="default" msgid="649792175242821353">"Je telefoon wordt uitgeschakeld."</string>
<string name="shutdown_confirm_question" msgid="2906544768881136183">"Wilt u afsluiten?"</string>
<string name="reboot_safemode_title" msgid="7054509914500140361">"Opnieuw opstarten in veilige modus"</string>
<string name="reboot_safemode_confirm" msgid="55293944502784668">"Wilt u opnieuw opstarten in de veilige modus? Als u dit doet, worden alle geïnstalleerde applicaties van derden uitgeschakeld. Ze worden weer ingeschakeld als u weer opnieuw opstart."</string>
@@ -210,7 +210,7 @@
<string name="global_action_power_off" msgid="4471879440839879722">"Uitschakelen"</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 uw 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="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_toggle_silent_mode" msgid="8219525344246810925">"Stille modus"</string>
<string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"Geluid is UIT"</string>
<string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"Geluid is AAN"</string>
@@ -227,15 +227,15 @@
<string name="user_owner_label" msgid="2804351898001038951">"Persoonlijk"</string>
<string name="managed_profile_label" msgid="6260850669674791528">"Werk"</string>
<string name="permgrouplab_contacts" msgid="3657758145679177612">"Contacten"</string>
- <string name="permgroupdesc_contacts" msgid="6951499528303668046">"toegang krijgen tot uw contacten"</string>
+ <string name="permgroupdesc_contacts" msgid="6951499528303668046">"toegang krijgen tot je contacten"</string>
<string name="permgrouplab_location" msgid="7275582855722310164">"Locatie"</string>
<string name="permgroupdesc_location" msgid="1346617465127855033">"de locatie van dit apparaat openen"</string>
<string name="permgrouplab_calendar" msgid="5863508437783683902">"Agenda"</string>
- <string name="permgroupdesc_calendar" msgid="3889615280211184106">"toegang krijgen tot uw agenda"</string>
+ <string name="permgroupdesc_calendar" msgid="3889615280211184106">"toegang krijgen tot je agenda"</string>
<string name="permgrouplab_sms" msgid="228308803364967808">"Sms"</string>
<string name="permgroupdesc_sms" msgid="4656988620100940350">"sms\'jes verzenden en bekijken"</string>
<string name="permgrouplab_storage" msgid="1971118770546336966">"Opslagruimte"</string>
- <string name="permgroupdesc_storage" msgid="637758554581589203">"toegang krijgen tot foto\'s, media en bestanden op uw apparaat"</string>
+ <string name="permgroupdesc_storage" msgid="637758554581589203">"toegang krijgen tot foto\'s, media en bestanden op je apparaat"</string>
<string name="permgrouplab_microphone" msgid="171539900250043464">"Microfoon"</string>
<string name="permgroupdesc_microphone" msgid="4988812113943554584">"audio opnemen"</string>
<string name="permgrouplab_camera" msgid="4820372495894586615">"Camera"</string>
@@ -243,9 +243,9 @@
<string name="permgrouplab_phone" msgid="5229115638567440675">"Telefoon"</string>
<string name="permgroupdesc_phone" msgid="6234224354060641055">"bellen en telefoontjes beheren"</string>
<string name="permgrouplab_sensors" msgid="416037179223226722">"Lichaamssensoren"</string>
- <string name="permgroupdesc_sensors" msgid="7147968539346634043">"toegang tot sensorgegevens over uw vitale functies"</string>
+ <string name="permgroupdesc_sensors" msgid="7147968539346634043">"toegang tot sensorgegevens over je vitale functies"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Inhoud van vensters ophalen"</string>
- <string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"De inhoud inspecteren van een venster waarmee u interactie heeft."</string>
+ <string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"De inhoud inspecteren van een venster waarmee je interactie hebt."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"\'Verkennen via aanraking\' inschakelen"</string>
<string name="capability_desc_canRequestTouchExploration" msgid="5800552516779249356">"Aangeraakte items worden hardop benoemd en het scherm kan worden verkend door middel van aanraking."</string>
<string name="capability_title_canRequestEnhancedWebAccessibility" msgid="1739881766522594073">"Verbeterde internettoegankelijkheid inschakelen"</string>
@@ -265,33 +265,33 @@
<string name="permlab_processOutgoingCalls" msgid="3906007831192990946">"uitgaande oproepen doorschakelen"</string>
<string name="permdesc_processOutgoingCalls" msgid="5156385005547315876">"De app toestaan het nummer te bekijken dat wordt gekozen voor een uitgaande oproep, met de mogelijkheid de oproep om te leiden naar een ander nummer of de oproep helemaal af te breken."</string>
<string name="permlab_receiveSms" msgid="8673471768947895082">"tekstberichten (SMS) ontvangen"</string>
- <string name="permdesc_receiveSms" msgid="6424387754228766939">"Hiermee kan de app sms-berichten ontvangen en verwerken. Dit betekent dat de app berichten die naar uw apparaat zijn verzonden, kan bijhouden of verwijderen zonder deze aan u weer te geven."</string>
+ <string name="permdesc_receiveSms" msgid="6424387754228766939">"Hiermee kan de app sms-berichten ontvangen en verwerken. Dit betekent dat de app berichten die naar je apparaat zijn verzonden, kan bijhouden of verwijderen zonder deze aan u weer te geven."</string>
<string name="permlab_receiveMms" msgid="1821317344668257098">"tekstberichten (MMS) ontvangen"</string>
- <string name="permdesc_receiveMms" msgid="533019437263212260">"Hiermee kan de app MMS-berichten ontvangen en verwerken. Dit betekent dat de app berichten die naar uw apparaat zijn verzonden, kan bijhouden of verwijderen zonder deze aan u weer te geven."</string>
+ <string name="permdesc_receiveMms" msgid="533019437263212260">"Hiermee kan de app MMS-berichten ontvangen en verwerken. Dit betekent dat de app berichten die naar je apparaat zijn verzonden, kan bijhouden of verwijderen zonder deze aan u weer te geven."</string>
<string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"infodienstberichten lezen"</string>
- <string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"Toestaan dat de app infodienstberichten leest die worden ontvangen op uw apparaat. Infodienstberichten worden verzonden naar bepaalde locaties om u te waarschuwen voor noodsituaties. Schadelijke apps kunnen de prestaties of verwerking van uw apparaat verstoren wanneer een infodienstbericht wordt ontvangen."</string>
+ <string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"Toestaan dat de app infodienstberichten leest die worden ontvangen op je apparaat. Infodienstberichten worden verzonden naar bepaalde locaties om u te waarschjeen voor noodsituaties. Schadelijke apps kunnen de prestaties of verwerking van je apparaat verstoren wanneer een infodienstbericht wordt ontvangen."</string>
<string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"Geabonneerde feeds lezen"</string>
<string name="permdesc_subscribedFeedsRead" msgid="5557058907906144505">"Hiermee kan de app details over de huidige gesynchroniseerde feeds achterhalen."</string>
<string name="permlab_sendSms" msgid="7544599214260982981">"sms\'jes verzenden en bekijken"</string>
- <string name="permdesc_sendSms" msgid="7094729298204937667">"Hiermee kan de app sms-berichten verzenden. Dit kan tot onverwachte kosten leiden. Schadelijke apps kunnen u geld kosten doordat ze zonder uw bevestiging berichten kunnen verzenden."</string>
- <string name="permlab_readSms" msgid="8745086572213270480">"uw tekstberichten (SMS of MMS) lezen"</string>
- <string name="permdesc_readSms" product="tablet" msgid="2467981548684735522">"Hiermee kan de app sms-berichten lezen die zijn opgeslagen op uw tablet of simkaart. De app kan alle sms-berichten lezen, ongeacht inhoud of vertrouwelijkheid."</string>
- <string name="permdesc_readSms" product="tv" msgid="5102425513647038535">"Hiermee kan de app sms-berichten lezen die zijn opgeslagen op uw tv of simkaart. De app kan alle sms-berichten lezen, ongeacht inhoud of vertrouwelijkheid."</string>
- <string name="permdesc_readSms" product="default" msgid="3695967533457240550">"Hiermee kan de app sms-berichten lezen die zijn opgeslagen op uw telefoon of simkaart. De app kan alle sms-berichten lezen, ongeacht inhoud of vertrouwelijkheid."</string>
+ <string name="permdesc_sendSms" msgid="7094729298204937667">"Hiermee kan de app sms-berichten verzenden. Dit kan tot onverwachte kosten leiden. Schadelijke apps kunnen u geld kosten doordat ze zonder je bevestiging berichten kunnen verzenden."</string>
+ <string name="permlab_readSms" msgid="8745086572213270480">"je tekstberichten (SMS of MMS) lezen"</string>
+ <string name="permdesc_readSms" product="tablet" msgid="2467981548684735522">"Hiermee kan de app sms-berichten lezen die zijn opgeslagen op je tablet of simkaart. De app kan alle sms-berichten lezen, ongeacht inhoud of vertrouwelijkheid."</string>
+ <string name="permdesc_readSms" product="tv" msgid="5102425513647038535">"Hiermee kan de app sms-berichten lezen die zijn opgeslagen op je tv of simkaart. De app kan alle sms-berichten lezen, ongeacht inhoud of vertrouwelijkheid."</string>
+ <string name="permdesc_readSms" product="default" msgid="3695967533457240550">"Hiermee kan de app sms-berichten lezen die zijn opgeslagen op je telefoon of simkaart. De app kan alle sms-berichten lezen, ongeacht inhoud of vertrouwelijkheid."</string>
<string name="permlab_receiveWapPush" msgid="5991398711936590410">"tekstberichten (WAP) ontvangen"</string>
- <string name="permdesc_receiveWapPush" msgid="748232190220583385">"Hiermee kan de app WAP-berichten ontvangen en verwerken. Dit betekent dat de app berichten die naar uw apparaat zijn verzonden, kan bijhouden of verwijderen zonder deze aan u weer te geven."</string>
+ <string name="permdesc_receiveWapPush" msgid="748232190220583385">"Hiermee kan de app WAP-berichten ontvangen en verwerken. Dit betekent dat de app berichten die naar je apparaat zijn verzonden, kan bijhouden of verwijderen zonder deze aan u weer te geven."</string>
<string name="permlab_getTasks" msgid="6466095396623933906">"actieve apps ophalen"</string>
<string name="permdesc_getTasks" msgid="7454215995847658102">"Hiermee kan de app informatie ophalen over actieve en recent uitgevoerde taken. Zo kan de app informatie vinden over welke apps op het apparaat worden gebruikt."</string>
<string name="permlab_manageProfileAndDeviceOwners" msgid="5979288447973722097">"Profiel- en apparaateigenaren beheren"</string>
<string name="permdesc_manageProfileAndDeviceOwners" msgid="106894851498657169">"Apps toestaan de profieleigenaren en apparaateigenaar in te stellen."</string>
<string name="permlab_reorderTasks" msgid="2018575526934422779">"actieve apps opnieuw rangschikken"</string>
- <string name="permdesc_reorderTasks" msgid="7734217754877439351">"Hiermee kan de app taken naar de voor- en achtergrond verplaatsen. De app kan dit doen zonder om uw bevestiging te vragen."</string>
+ <string name="permdesc_reorderTasks" msgid="7734217754877439351">"Hiermee kan de app taken naar de voor- en achtergrond verplaatsen. De app kan dit doen zonder om je bevestiging te vragen."</string>
<string name="permlab_enableCarMode" msgid="5684504058192921098">"automodus inschakelen"</string>
<string name="permdesc_enableCarMode" msgid="4853187425751419467">"Hiermee kan de app de automodus inschakelen."</string>
<string name="permlab_killBackgroundProcesses" msgid="3914026687420177202">"andere apps sluiten"</string>
<string name="permdesc_killBackgroundProcesses" msgid="4593353235959733119">"Hiermee kan de app achtergrondprocessen van andere apps beëindigen. Hierdoor kunnen andere apps worden gestopt."</string>
<string name="permlab_systemAlertWindow" msgid="3543347980839518613">"Weergeven over andere apps"</string>
- <string name="permdesc_systemAlertWindow" msgid="8584678381972820118">"Hiermee kan de app tekenen op andere apps of de gebruikersinterface. De app kan uw gebruik van de interface in alle apps verstoren, of wijzigen wat u in andere apps denkt te zien."</string>
+ <string name="permdesc_systemAlertWindow" msgid="8584678381972820118">"Hiermee kan de app tekenen op andere apps of de gebruikersinterface. De app kan je gebruik van de interface in alle apps verstoren, of wijzigen wat u in andere apps denkt te zien."</string>
<string name="permlab_persistentActivity" msgid="8841113627955563938">"app altijd laten uitvoeren"</string>
<string name="permdesc_persistentActivity" product="tablet" msgid="8525189272329086137">"Hiermee kan de app gedeelten van zichzelf persistent maken in het geheugen. Dit kan de hoeveelheid geheugen beperken die beschikbaar is voor andere apps, waardoor de tablet trager kan worden."</string>
<string name="permdesc_persistentActivity" product="tv" msgid="5086862529499103587">"Hiermee kan de app gedeelten van zichzelf persistent maken in het geheugen. Dit kan de hoeveelheid geheugen beperken die beschikbaar is voor andere apps, waardoor de tv trager kan worden."</string>
@@ -299,7 +299,7 @@
<string name="permlab_getPackageSize" msgid="7472921768357981986">"opslagruimte van app meten"</string>
<string name="permdesc_getPackageSize" msgid="3921068154420738296">"Hiermee kan de app de bijbehorende code, gegevens en cachegrootten ophalen."</string>
<string name="permlab_writeSettings" msgid="2226195290955224730">"systeeminstellingen aanpassen"</string>
- <string name="permdesc_writeSettings" msgid="7775723441558907181">"Hiermee kan de app de instellingsgegevens van het systeem aanpassen. Schadelijke apps kunnen de configuratie van uw systeem verstoren."</string>
+ <string name="permdesc_writeSettings" msgid="7775723441558907181">"Hiermee kan de app de instellingsgegevens van het systeem aanpassen. Schadelijke apps kunnen de configuratie van je systeem verstoren."</string>
<string name="permlab_receiveBootCompleted" msgid="5312965565987800025">"uitvoeren bij opstarten"</string>
<string name="permdesc_receiveBootCompleted" product="tablet" msgid="7390304664116880704">"Hiermee kan de app zichzelf laten starten zodra het systeem is opgestart. Hierdoor kan het langer duren voordat de tablet is opgestart en een app kan altijd actief zijn, wat de tablet kan vertragen."</string>
<string name="permdesc_receiveBootCompleted" product="tv" msgid="4525890122209673621">"Hiermee kan de app zichzelf laten starten zodra het systeem is opgestart. Hierdoor kan het langer duren voordat de tv is opgestart en een app kan altijd actief zijn, wat de tablet kan vertragen."</string>
@@ -308,54 +308,54 @@
<string name="permdesc_broadcastSticky" product="tablet" msgid="7749760494399915651">"Hiermee kan de app sticky broadcasts verzenden die behouden blijven nadat de broadcast is beëindigd. Bij overmatig gebruik kan de tablet traag of instabiel worden omdat er te veel geheugenruimte wordt gebruikt."</string>
<string name="permdesc_broadcastSticky" product="tv" msgid="6839285697565389467">"Hiermee kan de app sticky broadcasts verzenden die achterblijven nadat de uitzending is afgelopen. Overmatig gebruik kan de tv traag instabiel maken doordat er te veel geheugen wordt gebruikt."</string>
<string name="permdesc_broadcastSticky" product="default" msgid="2825803764232445091">"Hiermee kan de app sticky broadcasts verzenden die behouden blijven nadat de broadcast is beëindigd. Bij overmatig gebruik kan de telefoon traag of instabiel worden omdat er te veel geheugenruimte wordt gebruikt."</string>
- <string name="permlab_readContacts" msgid="8348481131899886131">"uw contacten lezen"</string>
- <string name="permdesc_readContacts" product="tablet" msgid="5294866856941149639">"Hiermee kan de app gegevens lezen over de contacten die zijn opgeslagen op uw tablet, inclusief de frequentie waarmee u heeft gebeld, gemaild of op andere manieren heeft gecommuniceerd met specifieke personen. Met deze toestemming kunnen apps uw contactgegevens opslaan, en schadelijke apps kunnen zonder uw medeweten contactgegevens delen."</string>
- <string name="permdesc_readContacts" product="tv" msgid="1839238344654834087">"Hiermee kan de app gegevens lezen over de contacten die zijn opgeslagen op uw tv, inclusief de frequentie waarmee u heeft gebeld, gemaild of op andere manieren heeft gecommuniceerd met specifieke personen. Met deze toestemming kunnen apps uw contactgegevens opslaan, en schadelijke apps kunnen zonder uw medeweten contactgegevens delen."</string>
- <string name="permdesc_readContacts" product="default" msgid="8440654152457300662">"Hiermee kan de app gegevens lezen over de contacten die zijn opgeslagen op uw telefoon, inclusief de frequentie waarmee u heeft gebeld, gemaild of op andere manieren heeft gecommuniceerd met specifieke personen. Met deze toestemming kunnen apps uw contactgegevens opslaan, en schadelijke apps kunnen zonder uw medeweten contactgegevens delen."</string>
- <string name="permlab_writeContacts" msgid="5107492086416793544">"uw contacten aanpassen"</string>
- <string name="permdesc_writeContacts" product="tablet" msgid="897243932521953602">"Hiermee kan de app gegevens wijzigen over de contacten die zijn opgeslagen op uw tablet, inclusief de frequentie waarmee u heeft gebeld, gemaild of op andere manieren heeft gecommuniceerd met specifieke contacten. Met deze toestemming kunnen apps contactgegevens verwijderen."</string>
- <string name="permdesc_writeContacts" product="tv" msgid="5438230957000018959">"Hiermee kan de app gegevens wijzigen over de contacten die zijn opgeslagen op uw tv, inclusief de frequentie waarmee u heeft gebeld, gemaild of op andere manieren heeft gecommuniceerd met specifieke contacten. Met deze toestemming kunnen apps contactgegevens verwijderen."</string>
- <string name="permdesc_writeContacts" product="default" msgid="589869224625163558">"Hiermee kan de app gegevens wijzigen over de contacten die zijn opgeslagen op uw telefoon, inclusief de frequentie waarmee u heeft gebeld, gemaild of op andere manieren heeft gecommuniceerd met specifieke contacten. Met deze toestemming kunnen apps contactgegevens verwijderen."</string>
+ <string name="permlab_readContacts" msgid="8348481131899886131">"je contacten lezen"</string>
+ <string name="permdesc_readContacts" product="tablet" msgid="5294866856941149639">"Hiermee kan de app gegevens lezen over de contacten die zijn opgeslagen op je tablet, inclusief de frequentie waarmee je hebt gebeld, gemaild of op andere manieren hebt gecommuniceerd met specifieke personen. Met deze toestemming kunnen apps je contactgegevens opslaan, en schadelijke apps kunnen zonder je medeweten contactgegevens delen."</string>
+ <string name="permdesc_readContacts" product="tv" msgid="1839238344654834087">"Hiermee kan de app gegevens lezen over de contacten die zijn opgeslagen op je tv, inclusief de frequentie waarmee je hebt gebeld, gemaild of op andere manieren hebt gecommuniceerd met specifieke personen. Met deze toestemming kunnen apps je contactgegevens opslaan, en schadelijke apps kunnen zonder je medeweten contactgegevens delen."</string>
+ <string name="permdesc_readContacts" product="default" msgid="8440654152457300662">"Hiermee kan de app gegevens lezen over de contacten die zijn opgeslagen op je telefoon, inclusief de frequentie waarmee je hebt gebeld, gemaild of op andere manieren hebt gecommuniceerd met specifieke personen. Met deze toestemming kunnen apps je contactgegevens opslaan, en schadelijke apps kunnen zonder je medeweten contactgegevens delen."</string>
+ <string name="permlab_writeContacts" msgid="5107492086416793544">"je contacten aanpassen"</string>
+ <string name="permdesc_writeContacts" product="tablet" msgid="897243932521953602">"Hiermee kan de app gegevens wijzigen over de contacten die zijn opgeslagen op je tablet, inclusief de frequentie waarmee je hebt gebeld, gemaild of op andere manieren hebt gecommuniceerd met specifieke contacten. Met deze toestemming kunnen apps contactgegevens verwijderen."</string>
+ <string name="permdesc_writeContacts" product="tv" msgid="5438230957000018959">"Hiermee kan de app gegevens wijzigen over de contacten die zijn opgeslagen op je tv, inclusief de frequentie waarmee je hebt gebeld, gemaild of op andere manieren hebt gecommuniceerd met specifieke contacten. Met deze toestemming kunnen apps contactgegevens verwijderen."</string>
+ <string name="permdesc_writeContacts" product="default" msgid="589869224625163558">"Hiermee kan de app gegevens wijzigen over de contacten die zijn opgeslagen op je telefoon, inclusief de frequentie waarmee je hebt gebeld, gemaild of op andere manieren hebt gecommuniceerd met specifieke contacten. Met deze toestemming kunnen apps contactgegevens verwijderen."</string>
<string name="permlab_readCallLog" msgid="3478133184624102739">"gesprekkenlijst lezen"</string>
- <string name="permdesc_readCallLog" product="tablet" msgid="3700645184870760285">"Hiermee kan de app het gesprekkenlijst van uw tablet lezen, inclusief gegevens over inkomende en uitgaande oproepen. Met deze toestemming kunnen apps uw oproeploggegevens opslaan, en schadelijke apps kunnen logoproepgegevens zonder uw medeweten delen."</string>
- <string name="permdesc_readCallLog" product="tv" msgid="5611770887047387926">"Hiermee kan de app het gesprekkenlijst van uw tv lezen, inclusief gegevens over inkomende en uitgaande oproepen. Met deze toestemming kunnen apps uw oproeploggegevens opslaan, en schadelijke apps kunnen oproeploggegevens zonder uw medeweten delen."</string>
- <string name="permdesc_readCallLog" product="default" msgid="5777725796813217244">"Hiermee kan de app het gesprekkenlijst van uw telefoon lezen, inclusief gegevens over inkomende en uitgaande oproepen. Met deze toestemming kunnen apps uw oproeploggegevens opslaan, en schadelijke apps kunnen logoproepgegevens zonder uw medeweten delen."</string>
+ <string name="permdesc_readCallLog" product="tablet" msgid="3700645184870760285">"Hiermee kan de app het gesprekkenlijst van je tablet lezen, inclusief gegevens over inkomende en uitgaande oproepen. Met deze toestemming kunnen apps je oproeploggegevens opslaan, en schadelijke apps kunnen logoproepgegevens zonder je medeweten delen."</string>
+ <string name="permdesc_readCallLog" product="tv" msgid="5611770887047387926">"Hiermee kan de app het gesprekkenlijst van je tv lezen, inclusief gegevens over inkomende en uitgaande oproepen. Met deze toestemming kunnen apps je oproeploggegevens opslaan, en schadelijke apps kunnen oproeploggegevens zonder je medeweten delen."</string>
+ <string name="permdesc_readCallLog" product="default" msgid="5777725796813217244">"Hiermee kan de app het gesprekkenlijst van je telefoon lezen, inclusief gegevens over inkomende en uitgaande oproepen. Met deze toestemming kunnen apps je oproeploggegevens opslaan, en schadelijke apps kunnen logoproepgegevens zonder je medeweten delen."</string>
<string name="permlab_writeCallLog" msgid="8552045664743499354">"gesprekkenlijst schrijven"</string>
- <string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"Toestaan dat de app het gesprekkenlijst van uw tablet aanpast, waaronder gegevens over inkomende en uitgaande oproepen. Schadelijke apps kunnen hiermee uw gesprekkenlijst wissen of aanpassen."</string>
- <string name="permdesc_writeCallLog" product="tv" msgid="4225034892248398019">"Toestaan dat de app het gesprekkenlijst van uw tv aanpast, waaronder gegevens over inkomende en uitgaande oproepen. Schadelijke apps kunnen hiermee uw gesprekkenlijst wissen of aanpassen."</string>
- <string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"Toestaan dat de app het gesprekkenlijst van uw telefoon aanpast, waaronder gegevens over inkomende en uitgaande oproepen. Schadelijke apps kunnen hiermee uw gesprekkenlijst wissen of aanpassen."</string>
+ <string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"Toestaan dat de app het gesprekkenlijst van je tablet aanpast, waaronder gegevens over inkomende en uitgaande oproepen. Schadelijke apps kunnen hiermee je gesprekkenlijst wissen of aanpassen."</string>
+ <string name="permdesc_writeCallLog" product="tv" msgid="4225034892248398019">"Toestaan dat de app het gesprekkenlijst van je tv aanpast, waaronder gegevens over inkomende en uitgaande oproepen. Schadelijke apps kunnen hiermee je gesprekkenlijst wissen of aanpassen."</string>
+ <string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"Toestaan dat de app het gesprekkenlijst van je telefoon aanpast, waaronder gegevens over inkomende en uitgaande oproepen. Schadelijke apps kunnen hiermee je gesprekkenlijst wissen of aanpassen."</string>
<string name="permlab_bodySensors" msgid="4871091374767171066">"lichaamssensoren (zoals hartslagmeters)"</string>
- <string name="permdesc_bodySensors" product="default" msgid="4380015021754180431">"Hiermee kan de app toegang krijgen tot gegevens van sensoren die uw lichamelijke conditie controleren, zoals uw hartslag."</string>
+ <string name="permdesc_bodySensors" product="default" msgid="4380015021754180431">"Hiermee kan de app toegang krijgen tot gegevens van sensoren die je lichamelijke conditie controleren, zoals je hartslag."</string>
<string name="permlab_readCalendar" msgid="5972727560257612398">"agenda-afspraken en vertrouwelijke informatie lezen"</string>
- <string name="permdesc_readCalendar" product="tablet" msgid="4216462049057658723">"Hiermee kan de app alle agenda-afspraken lezen die zijn opgeslagen op uw tablet, inclusief die van vrienden of collega\'s. De app kan uw agenda delen of uw agendagegevens opslaan, ongeacht vertrouwelijkheid of gevoeligheid."</string>
- <string name="permdesc_readCalendar" product="tv" msgid="3191352452242394196">"Hiermee kan de app alle agenda-afspraken lezen die zijn opgeslagen op uw tv, inclusief die van vrienden of collega\'s. De app kan uw agenda delen of uw agendagegevens opslaan, ongeacht vertrouwelijkheid of gevoeligheid."</string>
- <string name="permdesc_readCalendar" product="default" msgid="7434548682470851583">"Hiermee kan de app alle agenda-afspraken lezen die zijn opgeslagen op uw telefoon, inclusief die van vrienden of collega\'s. De app kan uw agenda delen of uw agendagegevens opslaan, ongeacht vertrouwelijkheid of gevoeligheid."</string>
+ <string name="permdesc_readCalendar" product="tablet" msgid="4216462049057658723">"Hiermee kan de app alle agenda-afspraken lezen die zijn opgeslagen op je tablet, inclusief die van vrienden of collega\'s. De app kan je agenda delen of je agendagegevens opslaan, ongeacht vertrouwelijkheid of gevoeligheid."</string>
+ <string name="permdesc_readCalendar" product="tv" msgid="3191352452242394196">"Hiermee kan de app alle agenda-afspraken lezen die zijn opgeslagen op je tv, inclusief die van vrienden of collega\'s. De app kan je agenda delen of je agendagegevens opslaan, ongeacht vertrouwelijkheid of gevoeligheid."</string>
+ <string name="permdesc_readCalendar" product="default" msgid="7434548682470851583">"Hiermee kan de app alle agenda-afspraken lezen die zijn opgeslagen op je telefoon, inclusief die van vrienden of collega\'s. De app kan je agenda delen of je agendagegevens opslaan, ongeacht vertrouwelijkheid of gevoeligheid."</string>
<string name="permlab_writeCalendar" msgid="8438874755193825647">"agenda-afspraken toevoegen of wijzigen en e-mails verzenden aan gasten zonder medeweten van de eigenaren"</string>
- <string name="permdesc_writeCalendar" product="tablet" msgid="6679035520113668528">"Hiermee kan de app afspraken toevoegen, verwijderen en wijzigen die u kunt bewerken op uw tablet, inclusief afspraken van vrienden of collega\'s. Zo kan de app berichten verzenden die afkomstig lijken te zijn van agenda-eigenaren, of afspraken aanpassen zonder medeweten van de eigenaar."</string>
- <string name="permdesc_writeCalendar" product="tv" msgid="1273290605500902507">"Hiermee kan de app afspraken toevoegen, verwijderen en wijzigen die u op uw tv kunt aanpassen, inclusief afspraken van vrienden of collega\'s. Met deze toestemming zou de app berichten kunnen verzenden die afkomstig lijken te zijn van agenda-eigenaren of afspraken kunnen aanpassen zonder medeweten van de eigenaar."</string>
- <string name="permdesc_writeCalendar" product="default" msgid="2324469496327249376">"Hiermee kan de app afspraken toevoegen, verwijderen en wijzigen die u kunt bewerken op uw telefoon, inclusief afspraken van vrienden of collega\'s. Zo kan de app berichten verzenden die afkomstig lijken te zijn van agenda-eigenaren, of afspraken aanpassen zonder medeweten van de eigenaar."</string>
+ <string name="permdesc_writeCalendar" product="tablet" msgid="6679035520113668528">"Hiermee kan de app afspraken toevoegen, verwijderen en wijzigen die u kunt bewerken op je tablet, inclusief afspraken van vrienden of collega\'s. Zo kan de app berichten verzenden die afkomstig lijken te zijn van agenda-eigenaren, of afspraken aanpassen zonder medeweten van de eigenaar."</string>
+ <string name="permdesc_writeCalendar" product="tv" msgid="1273290605500902507">"Hiermee kan de app afspraken toevoegen, verwijderen en wijzigen die u op je tv kunt aanpassen, inclusief afspraken van vrienden of collega\'s. Met deze toestemming zou de app berichten kunnen verzenden die afkomstig lijken te zijn van agenda-eigenaren of afspraken kunnen aanpassen zonder medeweten van de eigenaar."</string>
+ <string name="permdesc_writeCalendar" product="default" msgid="2324469496327249376">"Hiermee kan de app afspraken toevoegen, verwijderen en wijzigen die u kunt bewerken op je telefoon, inclusief afspraken van vrienden of collega\'s. Zo kan de app berichten verzenden die afkomstig lijken te zijn van agenda-eigenaren, of afspraken aanpassen zonder medeweten van de eigenaar."</string>
<string name="permlab_accessLocationExtraCommands" msgid="2836308076720553837">"toegang tot extra opdrachten van locatieaanbieder"</string>
<string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"Hiermee kan de app toegang krijgen tot extra opdrachten voor de locatieprovider. De app kan hiermee de werking van GPS of andere locatiebronnen te verstoren."</string>
<string name="permlab_accessFineLocation" msgid="1191898061965273372">"precieze locatie (GPS- en netwerkgebaseerd)"</string>
- <string name="permdesc_accessFineLocation" msgid="5295047563564981250">"Hiermee kan de app uw precieze locatie bepalen via GPS (Global Positioning System) of netwerklocatiebronnen zoals zendmasten en wifi. Deze locatieservices moeten zijn ingeschakeld en beschikbaar zijn op uw apparaat voordat de app ze kan gebruiken. Apps kunnen dit gebruiken om te bepalen waar u bent en verbruiken mogelijk extra acculading."</string>
+ <string name="permdesc_accessFineLocation" msgid="5295047563564981250">"Hiermee kan de app je precieze locatie bepalen via GPS (Global Positioning System) of netwerklocatiebronnen zoals zendmasten en wifi. Deze locatieservices moeten zijn ingeschakeld en beschikbaar zijn op je apparaat voordat de app ze kan gebruiken. Apps kunnen dit gebruiken om te bepalen waar u bent en verbruiken mogelijk extra acculading."</string>
<string name="permlab_accessCoarseLocation" msgid="4887895362354239628">"geschatte locatie (netwerkgebaseerd)"</string>
- <string name="permdesc_accessCoarseLocation" msgid="2538200184373302295">"Hiermee kan de app beschikken over uw geschatte locatie. Deze locatie wordt afgeleid van locatieservices die netwerklocatiebronnen zoals zendmasten en wifi gebruiken. Deze locatieservices moeten zijn ingeschakeld en beschikbaar zijn op uw apparaat voordat de app ze kan gebruiken. Apps kunnen dit gebruiken om ongeveer te bepalen waar u zich bevindt."</string>
- <string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"uw audio-instellingen wijzigen"</string>
+ <string name="permdesc_accessCoarseLocation" msgid="2538200184373302295">"Hiermee kan de app beschikken over je geschatte locatie. Deze locatie wordt afgeleid van locatieservices die netwerklocatiebronnen zoals zendmasten en wifi gebruiken. Deze locatieservices moeten zijn ingeschakeld en beschikbaar zijn op je apparaat voordat de app ze kan gebruiken. Apps kunnen dit gebruiken om ongeveer te bepalen waar u zich bevindt."</string>
+ <string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"je audio-instellingen wijzigen"</string>
<string name="permdesc_modifyAudioSettings" msgid="3522565366806248517">"Hiermee kan de app algemene audio-instellingen wijzigen zoals het volume en welke luidspreker wordt gebruikt voor de uitvoer."</string>
<string name="permlab_recordAudio" msgid="3876049771427466323">"audio opnemen"</string>
- <string name="permdesc_recordAudio" msgid="4906839301087980680">"Hiermee kan de app audio opnemen met de microfoon. Met deze toestemming kan de app op elk moment audio opnemen, zonder om uw bevestiging te vragen."</string>
+ <string name="permdesc_recordAudio" msgid="4906839301087980680">"Hiermee kan de app audio opnemen met de microfoon. Met deze toestemming kan de app op elk moment audio opnemen, zonder om je bevestiging te vragen."</string>
<string name="permlab_sim_communication" msgid="1180265879464893029">"sim-communicatie"</string>
<string name="permdesc_sim_communication" msgid="5725159654279639498">"Hiermee kan de app opdrachten verzenden naar de simkaart. Dit is erg gevaarlijk."</string>
<string name="permlab_camera" msgid="3616391919559751192">"foto\'s en video\'s maken"</string>
- <string name="permdesc_camera" msgid="8497216524735535009">"Hiermee kan de app foto\'s en video\'s maken met de camera. Met deze toestemming kan de app de camera altijd gebruiken, zonder uw bevestiging."</string>
+ <string name="permdesc_camera" msgid="8497216524735535009">"Hiermee kan de app foto\'s en video\'s maken met de camera. Met deze toestemming kan de app de camera altijd gebruiken, zonder je bevestiging."</string>
<string name="permlab_vibrate" msgid="7696427026057705834">"trilling beheren"</string>
<string name="permdesc_vibrate" msgid="6284989245902300945">"Hiermee kan de app de trilstand beheren."</string>
<string name="permlab_flashlight" msgid="2155920810121984215">"zaklamp bedienen"</string>
<string name="permdesc_flashlight" msgid="6522284794568368310">"Hiermee kan de app de zaklamp bedienen."</string>
<string name="permlab_callPhone" msgid="3925836347681847954">"telefoonnummers rechtstreeks bellen"</string>
- <string name="permdesc_callPhone" msgid="3740797576113760827">"Hiermee kan de app zonder uw tussenkomst telefoonnummers bellen. Dit kan tot onverwachte kosten of oproepen leiden. De app kan hiermee geen noodnummers bellen. Schadelijke apps kunnen u geld kosten door nummers te bellen zonder om uw bevestiging te vragen."</string>
+ <string name="permdesc_callPhone" msgid="3740797576113760827">"Hiermee kan de app zonder je tussenkomst telefoonnummers bellen. Dit kan tot onverwachte kosten of oproepen leiden. De app kan hiermee geen noodnummers bellen. Schadelijke apps kunnen u geld kosten door nummers te bellen zonder om je bevestiging te vragen."</string>
<string name="permlab_accessImsCallService" msgid="3574943847181793918">"toegang tot IMS-service voor bellen"</string>
- <string name="permdesc_accessImsCallService" msgid="8992884015198298775">"Hiermee kan de app de IMS-service gebruiken om te bellen zonder uw tussenkomst."</string>
+ <string name="permdesc_accessImsCallService" msgid="8992884015198298775">"Hiermee kan de app de IMS-service gebruiken om te bellen zonder je tussenkomst."</string>
<string name="permlab_readPhoneState" msgid="9178228524507610486">"telefoonstatus en -identiteit lezen"</string>
<string name="permdesc_readPhoneState" msgid="1639212771826125528">"Hiermee kan de app toegang krijgen tot de telefoonfuncties van het apparaat, Met deze toestemming kan de app het telefoonnummer en de apparaat-ID\'s bepalen, of een oproep actief is, en het andere telefoonnummer waarmee wordt gebeld."</string>
<string name="permlab_wakeLock" product="tablet" msgid="1531731435011495015">"voorkomen dat tablet overschakelt naar slaapmodus"</string>
@@ -370,16 +370,16 @@
<string name="permdesc_transmitIr" product="default" msgid="7957763745020300725">"Hiermee kan de app de infraroodzender van de telefoon gebruiken."</string>
<string name="permlab_setWallpaper" msgid="6627192333373465143">"achtergrond instellen"</string>
<string name="permdesc_setWallpaper" msgid="7373447920977624745">"Hiermee kan de app de systeemachtergrond instellen."</string>
- <string name="permlab_setWallpaperHints" msgid="3278608165977736538">"uw achtergrondformaat aanpassen"</string>
+ <string name="permlab_setWallpaperHints" msgid="3278608165977736538">"je achtergrondformaat aanpassen"</string>
<string name="permdesc_setWallpaperHints" msgid="8235784384223730091">"Hiermee kan de app de grootte van de achtergrond instellen."</string>
<string name="permlab_setTimeZone" msgid="2945079801013077340">"tijdzone instellen"</string>
<string name="permdesc_setTimeZone" product="tablet" msgid="1676983712315827645">"Hiermee kan de app de tijdzone van de tablet wijzigen."</string>
<string name="permdesc_setTimeZone" product="tv" msgid="888864653946175955">"Hiermee kan de app de tijdzone van de tv wijzigen."</string>
<string name="permdesc_setTimeZone" product="default" msgid="4499943488436633398">"Hiermee kan de app de tijdzone van de telefoon wijzigen."</string>
<string name="permlab_getAccounts" msgid="1086795467760122114">"accounts op het apparaat vinden"</string>
- <string name="permdesc_getAccounts" product="tablet" msgid="2741496534769660027">"Hiermee krijgt de app toegang tot de lijst met accounts die op de tablet bekend zijn. Dit kunnen ook accounts zijn die zijn gemaakt door apps die u heeft geïnstalleerd."</string>
- <string name="permdesc_getAccounts" product="tv" msgid="4190633395633907543">"Hiermee krijgt de app toegang tot de lijst met accounts die op de tv bekend zijn. Dit kunnen ook accounts zijn die zijn gemaakt door apps die u heeft geïnstalleerd."</string>
- <string name="permdesc_getAccounts" product="default" msgid="3448316822451807382">"Hiermee krijgt de app toegang tot de lijst met accounts die op de telefoon bekend zijn. Dit kunnen ook accounts zijn die zijn gemaakt door apps die u heeft geïnstalleerd."</string>
+ <string name="permdesc_getAccounts" product="tablet" msgid="2741496534769660027">"Hiermee krijgt de app toegang tot de lijst met accounts die op de tablet bekend zijn. Dit kunnen ook accounts zijn die zijn gemaakt door apps die je hebt geïnstalleerd."</string>
+ <string name="permdesc_getAccounts" product="tv" msgid="4190633395633907543">"Hiermee krijgt de app toegang tot de lijst met accounts die op de tv bekend zijn. Dit kunnen ook accounts zijn die zijn gemaakt door apps die je hebt geïnstalleerd."</string>
+ <string name="permdesc_getAccounts" product="default" msgid="3448316822451807382">"Hiermee krijgt de app toegang tot de lijst met accounts die op de telefoon bekend zijn. Dit kunnen ook accounts zijn die zijn gemaakt door apps die je hebt geïnstalleerd."</string>
<string name="permlab_accessNetworkState" msgid="4951027964348974773">"netwerkverbindingen weergeven"</string>
<string name="permdesc_accessNetworkState" msgid="8318964424675960975">"Hiermee kan de app informatie bekijken over netwerkverbindingen, zoals welke netwerken er zijn en welke verbonden zijn."</string>
<string name="permlab_createNetworkSockets" msgid="8018758136404323658">"volledige netwerktoegang"</string>
@@ -393,9 +393,9 @@
<string name="permlab_changeWifiState" msgid="6550641188749128035">"Wifi-verbinding maken en verbreken"</string>
<string name="permdesc_changeWifiState" msgid="7137950297386127533">"Hiermee kan de app zich koppelen aan en ontkoppelen van wifi-toegangspunten en wijzigingen aanbrengen in de apparaatconfiguratie voor wifi-netwerken."</string>
<string name="permlab_changeWifiMulticastState" msgid="1368253871483254784">"Wifi Multicast-ontvangst toestaan"</string>
- <string name="permdesc_changeWifiMulticastState" product="tablet" msgid="7969774021256336548">"Hiermee kan de app pakketten ontvangen die via multicastadressen naar alle apparaten in een wifi-netwerk worden verzonden, niet alleen naar uw tablet. Het stroomgebruik ligt hierbij hoger dan in de niet-multicastmodus."</string>
- <string name="permdesc_changeWifiMulticastState" product="tv" msgid="9031975661145014160">"Hiermee kan de app pakketten ontvangen die zijn verzonden naar alle apparaten op een Wi-Fi-netwerk met multicastadressen en niet alleen uw tv. Er wordt meer stroom verbruikt dan in de niet-multicastmodus."</string>
- <string name="permdesc_changeWifiMulticastState" product="default" msgid="6851949706025349926">"Hiermee kan de app pakketten ontvangen die via multicastadressen naar alle apparaten in een wifi-netwerk worden verzonden, niet alleen naar uw telefoon. Het stroomgebruik ligt hierbij hoger dan in de niet-multicastmodus."</string>
+ <string name="permdesc_changeWifiMulticastState" product="tablet" msgid="7969774021256336548">"Hiermee kan de app pakketten ontvangen die via multicastadressen naar alle apparaten in een wifi-netwerk worden verzonden, niet alleen naar je tablet. Het stroomgebruik ligt hierbij hoger dan in de niet-multicastmodus."</string>
+ <string name="permdesc_changeWifiMulticastState" product="tv" msgid="9031975661145014160">"Hiermee kan de app pakketten ontvangen die zijn verzonden naar alle apparaten op een Wi-Fi-netwerk met multicastadressen en niet alleen je tv. Er wordt meer stroom verbruikt dan in de niet-multicastmodus."</string>
+ <string name="permdesc_changeWifiMulticastState" product="default" msgid="6851949706025349926">"Hiermee kan de app pakketten ontvangen die via multicastadressen naar alle apparaten in een wifi-netwerk worden verzonden, niet alleen naar je telefoon. Het stroomgebruik ligt hierbij hoger dan in de niet-multicastmodus."</string>
<string name="permlab_bluetoothAdmin" msgid="6006967373935926659">"Bluetooth-instellingen openen"</string>
<string name="permdesc_bluetoothAdmin" product="tablet" msgid="6921177471748882137">"Hiermee kan de app de lokale Bluetooth-tablet configureren en externe apparaten zoeken en koppelen."</string>
<string name="permdesc_bluetoothAdmin" product="tv" msgid="3373125682645601429">"Hiermee kan de app de configuratie van de lokale Bluetooth-tv weergeven en externe apparaten zoeken en een koppeling maken."</string>
@@ -412,7 +412,7 @@
<string name="permdesc_bluetooth" product="default" msgid="3207106324452312739">"Hiermee kan de app de Bluetooth-configuratie van de telefoon bekijken en verbindingen met gekoppelde apparaten maken en accepteren."</string>
<string name="permlab_nfc" msgid="4423351274757876953">"Near Field Communication regelen"</string>
<string name="permdesc_nfc" msgid="7120611819401789907">"Hiermee kan de app communiceren met NFC-tags (Near Field Communication), kaarten en lezers."</string>
- <string name="permlab_disableKeyguard" msgid="3598496301486439258">"uw schermvergrendeling uitschakelen"</string>
+ <string name="permlab_disableKeyguard" msgid="3598496301486439258">"je schermvergrendeling uitschakelen"</string>
<string name="permdesc_disableKeyguard" msgid="6034203065077122992">"Hiermee kan de app de toetsenblokkering en bijbehorende wachtwoordbeveiliging uitschakelen. Zo kan de telefoon de toetsenblokkering uitschakelen wanneer er een oproep binnenkomt en de toetsenblokkering weer inschakelen als de oproep is beëindigd."</string>
<string name="permlab_manageFingerprint" msgid="5640858826254575638">"Vingerafdrukhardware beheren"</string>
<string name="permdesc_manageFingerprint" msgid="178208705828055464">"Hiermee kan de app methoden aanroepen om vingerafdruksjablonen toe te voegen en te verwijderen voor gebruik."</string>
@@ -441,12 +441,12 @@
<string name="permdesc_writeSyncSettings" msgid="8956262591306369868">"Hiermee kan een app de synchronisatie-instellingen aanpassen voor een account. Deze toestemming kan bijvoorbeeld worden gebruikt om synchronisatie van de app Personen in te schakelen voor een account."</string>
<string name="permlab_readSyncStats" msgid="7396577451360202448">"synchronisatiestatistieken lezen"</string>
<string name="permdesc_readSyncStats" msgid="1510143761757606156">"Hiermee kan een app de synchronisatiestatistieken voor een account lezen, inclusief de geschiedenis van synchronisatie-activiteiten en hoeveel gegevens zijn gesynchroniseerd."</string>
- <string name="permlab_sdcardRead" product="nosdcard" msgid="367275095159405468">"de inhoud van uw USB-opslag lezen"</string>
- <string name="permlab_sdcardRead" product="default" msgid="2188156462934977940">"de inhoud van uw SD-kaart lezen"</string>
- <string name="permdesc_sdcardRead" product="nosdcard" msgid="3446988712598386079">"De app toestaan de inhoud van uw USB-opslag te lezen."</string>
- <string name="permdesc_sdcardRead" product="default" msgid="2607362473654975411">"De app toestaan de inhoud van uw SD-kaart te lezen."</string>
- <string name="permlab_sdcardWrite" product="nosdcard" msgid="8485979062254666748">"de inhoud van uw USB-opslag aanpassen of verwijderen"</string>
- <string name="permlab_sdcardWrite" product="default" msgid="8805693630050458763">"de inhoud van uw SD-kaart aanpassen of verwijderen"</string>
+ <string name="permlab_sdcardRead" product="nosdcard" msgid="367275095159405468">"de inhoud van je USB-opslag lezen"</string>
+ <string name="permlab_sdcardRead" product="default" msgid="2188156462934977940">"de inhoud van je SD-kaart lezen"</string>
+ <string name="permdesc_sdcardRead" product="nosdcard" msgid="3446988712598386079">"De app toestaan de inhoud van je USB-opslag te lezen."</string>
+ <string name="permdesc_sdcardRead" product="default" msgid="2607362473654975411">"De app toestaan de inhoud van je SD-kaart te lezen."</string>
+ <string name="permlab_sdcardWrite" product="nosdcard" msgid="8485979062254666748">"de inhoud van je USB-opslag aanpassen of verwijderen"</string>
+ <string name="permlab_sdcardWrite" product="default" msgid="8805693630050458763">"de inhoud van je SD-kaart aanpassen of verwijderen"</string>
<string name="permdesc_sdcardWrite" product="nosdcard" msgid="6175406299445710888">"Hiermee kan de app schrijven naar de USB-opslag."</string>
<string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"Hiermee kan de app schrijven naar de SD-kaart."</string>
<string name="permlab_use_sip" msgid="2052499390128979920">"SIP-oproepen plaatsen/ontvangen"</string>
@@ -668,7 +668,7 @@
<string name="lockscreen_missing_sim_instructions" msgid="5372787138023272615">"Plaats een simkaart."</string>
<string name="lockscreen_missing_sim_instructions_long" msgid="3526573099019319472">"De simkaart ontbreekt of kan niet worden gelezen. Plaats een simkaart."</string>
<string name="lockscreen_permanent_disabled_sim_message_short" msgid="5096149665138916184">"Onbruikbare simkaart."</string>
- <string name="lockscreen_permanent_disabled_sim_instructions" msgid="910904643433151371">"Uw simkaart is permanent uitgeschakeld.\n Neem contact op met uw mobiele serviceprovider voor een nieuwe simkaart."</string>
+ <string name="lockscreen_permanent_disabled_sim_instructions" msgid="910904643433151371">"Je simkaart is permanent uitgeschakeld.\n Neem contact op met je mobiele serviceprovider voor een nieuwe simkaart."</string>
<string name="lockscreen_transport_prev_description" msgid="6300840251218161534">"Vorig nummer"</string>
<string name="lockscreen_transport_next_description" msgid="573285210424377338">"Volgend nummer"</string>
<string name="lockscreen_transport_pause_description" msgid="3980308465056173363">"Onderbreken"</string>
@@ -682,28 +682,28 @@
<string name="lockscreen_sim_puk_locked_instructions" msgid="8127916255245181063">"Raadpleeg de gebruikershandleiding of neem contact op met de klantenservice."</string>
<string name="lockscreen_sim_locked_message" msgid="8066660129206001039">"SIM-kaart is vergrendeld."</string>
<string name="lockscreen_sim_unlock_progress_dialog_message" msgid="595323214052881264">"SIM-kaart ontgrendelen..."</string>
- <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"U heeft uw ontgrendelingspatroon <xliff:g id="NUMBER_0">%d</xliff:g> keer onjuist getekend. \n\nProbeer het opnieuw over <xliff:g id="NUMBER_1">%d</xliff:g> seconden."</string>
- <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"U heeft uw wachtwoord <xliff:g id="NUMBER_0">%d</xliff:g> keer onjuist getypt. \n\nProbeer het opnieuw over <xliff:g id="NUMBER_1">%d</xliff:g> seconden."</string>
- <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"U heeft uw pincode <xliff:g id="NUMBER_0">%d</xliff:g> keer onjuist getypt. \n\nProbeer het opnieuw over <xliff:g id="NUMBER_1">%d</xliff:g> seconden."</string>
- <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"U heeft uw ontgrendelingspatroon <xliff:g id="NUMBER_0">%d</xliff:g> keer onjuist getekend. Na nog eens <xliff:g id="NUMBER_1">%d</xliff:g> mislukte pogingen wordt u gevraagd uw tablet te ontgrendelen met uw aanmeldingsgegevens voor Google.\n\n Probeer het over <xliff:g id="NUMBER_2">%d</xliff:g> seconden opnieuw."</string>
- <string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="5316664559603394684">"U heeft uw ontgrendelingspatroon <xliff:g id="NUMBER_0">%d</xliff:g> keer onjuist getekend. Na nog <xliff:g id="NUMBER_1">%d</xliff:g> onjuiste pogingen, wordt u gevraagd uw tv te ontgrendelen met uw inloggegevens voor Google.\n\n Probeer het opnieuw over <xliff:g id="NUMBER_2">%d</xliff:g> seconden."</string>
- <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"U heeft uw ontgrendelingspatroon <xliff:g id="NUMBER_0">%d</xliff:g> keer onjuist getekend. Na nog eens <xliff:g id="NUMBER_1">%d</xliff:g> mislukte pogingen wordt u gevraagd uw telefoon te ontgrendelen met uw aanmeldingsgegevens voor Google.\n\n Probeer het over <xliff:g id="NUMBER_2">%d</xliff:g> seconden opnieuw."</string>
- <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"U heeft <xliff:g id="NUMBER_0">%d</xliff:g> keer geprobeerd de tablet op een onjuiste manier te ontgrendelen. Na nog eens <xliff:g id="NUMBER_1">%d</xliff:g> mislukte pogingen worden de fabrieksinstellingen hersteld op de tablet en gaan alle gebruikersgegevens verloren."</string>
- <string name="lockscreen_failed_attempts_almost_at_wipe" product="tv" msgid="950408382418270260">"U heeft op onjuiste wijze <xliff:g id="NUMBER_0">%d</xliff:g> keer geprobeerd de tv te ontgrendelen. Na nog <xliff:g id="NUMBER_1">%d</xliff:g> onjuiste pogingen, wordt de tv hersteld naar de fabriekswaarden en gaan alle gebruikersgegevens verloren."</string>
- <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"U heeft nu <xliff:g id="NUMBER_0">%d</xliff:g> keer geprobeerd de telefoon op een onjuiste manier te ontgrendelen. Na nog eens <xliff:g id="NUMBER_1">%d</xliff:g> mislukte pogingen worden de fabrieksinstellingen hersteld op de telefoon en gaan alle gebruikersgegevens verloren."</string>
- <string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="280873516493934365">"U heeft <xliff:g id="NUMBER">%d</xliff:g> keer geprobeerd de tablet op een onjuiste manier te ontgrendelen. De fabrieksinstellingen worden nu hersteld op de tablet."</string>
- <string name="lockscreen_failed_attempts_now_wiping" product="tv" msgid="3195755534096192191">"U heeft op onjuiste wijze <xliff:g id="NUMBER">%d</xliff:g> keer geprobeerd de tv te ontgrendelen. De tv wordt nu hersteld naar de fabrieksinstellingen."</string>
- <string name="lockscreen_failed_attempts_now_wiping" product="default" msgid="3025504721764922246">"U heeft <xliff:g id="NUMBER">%d</xliff:g> keer geprobeerd de telefoon op een onjuiste manier te ontgrendelen. De fabrieksinstellingen worden nu hersteld op de telefoon."</string>
+ <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"Je hebt je ontgrendelingspatroon <xliff:g id="NUMBER_0">%d</xliff:g> keer onjuist getekend. \n\nProbeer het opnieuw over <xliff:g id="NUMBER_1">%d</xliff:g> seconden."</string>
+ <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"Je hebt je wachtwoord <xliff:g id="NUMBER_0">%d</xliff:g> keer onjuist getypt. \n\nProbeer het opnieuw over <xliff:g id="NUMBER_1">%d</xliff:g> seconden."</string>
+ <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"Je hebt je pincode <xliff:g id="NUMBER_0">%d</xliff:g> keer onjuist getypt. \n\nProbeer het opnieuw over <xliff:g id="NUMBER_1">%d</xliff:g> seconden."</string>
+ <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"Je hebt je ontgrendelingspatroon <xliff:g id="NUMBER_0">%d</xliff:g> keer onjuist getekend. Na nog eens <xliff:g id="NUMBER_1">%d</xliff:g> mislukte pogingen wordt u gevraagd je tablet te ontgrendelen met je aanmeldingsgegevens voor Google.\n\n Probeer het over <xliff:g id="NUMBER_2">%d</xliff:g> seconden opnieuw."</string>
+ <string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="5316664559603394684">"Je hebt je ontgrendelingspatroon <xliff:g id="NUMBER_0">%d</xliff:g> keer onjuist getekend. Na nog <xliff:g id="NUMBER_1">%d</xliff:g> onjuiste pogingen, wordt je gevraagd je tv te ontgrendelen met je inloggegevens voor Google.\n\n Probeer het opnieuw over <xliff:g id="NUMBER_2">%d</xliff:g> seconden."</string>
+ <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"Je hebt je ontgrendelingspatroon <xliff:g id="NUMBER_0">%d</xliff:g> keer onjuist getekend. Na nog eens <xliff:g id="NUMBER_1">%d</xliff:g> mislukte pogingen wordt u gevraagd je telefoon te ontgrendelen met je aanmeldingsgegevens voor Google.\n\n Probeer het over <xliff:g id="NUMBER_2">%d</xliff:g> seconden opnieuw."</string>
+ <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"Je hebt <xliff:g id="NUMBER_0">%d</xliff:g> keer geprobeerd de tablet op een onjuiste manier te ontgrendelen. Na nog eens <xliff:g id="NUMBER_1">%d</xliff:g> mislukte pogingen worden de fabrieksinstellingen hersteld op de tablet en gaan alle gebruikersgegevens verloren."</string>
+ <string name="lockscreen_failed_attempts_almost_at_wipe" product="tv" msgid="950408382418270260">"Je hebt op onjuiste wijze <xliff:g id="NUMBER_0">%d</xliff:g> keer geprobeerd de tv te ontgrendelen. Na nog <xliff:g id="NUMBER_1">%d</xliff:g> onjuiste pogingen, wordt de tv hersteld naar de fabriekswaarden en gaan alle gebruikersgegevens verloren."</string>
+ <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"Je hebt nu <xliff:g id="NUMBER_0">%d</xliff:g> keer geprobeerd de telefoon op een onjuiste manier te ontgrendelen. Na nog eens <xliff:g id="NUMBER_1">%d</xliff:g> mislukte pogingen worden de fabrieksinstellingen hersteld op de telefoon en gaan alle gebruikersgegevens verloren."</string>
+ <string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="280873516493934365">"Je hebt <xliff:g id="NUMBER">%d</xliff:g> keer geprobeerd de tablet op een onjuiste manier te ontgrendelen. De fabrieksinstellingen worden nu hersteld op de tablet."</string>
+ <string name="lockscreen_failed_attempts_now_wiping" product="tv" msgid="3195755534096192191">"Je hebt op onjuiste wijze <xliff:g id="NUMBER">%d</xliff:g> keer geprobeerd de tv te ontgrendelen. De tv wordt nu hersteld naar de fabrieksinstellingen."</string>
+ <string name="lockscreen_failed_attempts_now_wiping" product="default" msgid="3025504721764922246">"Je hebt <xliff:g id="NUMBER">%d</xliff:g> keer geprobeerd de telefoon op een onjuiste manier te ontgrendelen. De fabrieksinstellingen worden nu hersteld op de telefoon."</string>
<string name="lockscreen_too_many_failed_attempts_countdown" msgid="6251480343394389665">"Probeer het over <xliff:g id="NUMBER">%d</xliff:g> seconden opnieuw."</string>
<string name="lockscreen_forgot_pattern_button_text" msgid="2626999449610695930">"Patroon vergeten?"</string>
<string name="lockscreen_glogin_forgot_pattern" msgid="2588521501166032747">"Account ontgrendelen"</string>
<string name="lockscreen_glogin_too_many_attempts" msgid="2751368605287288808">"Te veel patroonpogingen"</string>
- <string name="lockscreen_glogin_instructions" msgid="3931816256100707784">"Log in op uw Google-account om te ontgrendelen."</string>
+ <string name="lockscreen_glogin_instructions" msgid="3931816256100707784">"Log in op je Google-account om te ontgrendelen."</string>
<string name="lockscreen_glogin_username_hint" msgid="8846881424106484447">"Gebruikersnaam (e-mail)"</string>
<string name="lockscreen_glogin_password_hint" msgid="5958028383954738528">"Wachtwoord"</string>
<string name="lockscreen_glogin_submit_button" msgid="7130893694795786300">"Inloggen"</string>
<string name="lockscreen_glogin_invalid_input" msgid="1364051473347485908">"Gebruikersnaam of wachtwoord ongeldig."</string>
- <string name="lockscreen_glogin_account_recovery_hint" msgid="1696924763690379073">"Bent u uw gebruikersnaam of wachtwoord vergeten?\nGa naar "<b>"https://www.google.com/accounts/recovery"</b>"."</string>
+ <string name="lockscreen_glogin_account_recovery_hint" msgid="1696924763690379073">"Bent u je gebruikersnaam of wachtwoord vergeten?\nGa naar "<b>"https://www.google.com/accounts/recovery"</b>"."</string>
<string name="lockscreen_glogin_checking_password" msgid="7114627351286933867">"Controleren…"</string>
<string name="lockscreen_unlock_label" msgid="737440483220667054">"Ontgrendelen"</string>
<string name="lockscreen_sound_on_label" msgid="9068877576513425970">"Geluid aan"</string>
@@ -774,23 +774,23 @@
<string name="autofill_parish" msgid="8202206105468820057">"Gemeente"</string>
<string name="autofill_area" msgid="3547409050889952423">"Gebied"</string>
<string name="autofill_emirate" msgid="2893880978835698818">"Emiraat"</string>
- <string name="permlab_readHistoryBookmarks" msgid="3775265775405106983">"uw webbladwijzers en -geschiedenis lezen"</string>
+ <string name="permlab_readHistoryBookmarks" msgid="3775265775405106983">"je webbladwijzers en -geschiedenis lezen"</string>
<string name="permdesc_readHistoryBookmarks" msgid="8462378226600439658">"Hiermee kan de app de geschiedenis lezen van alle URL\'s die in de systeemeigen browser zijn bezocht, en alle bladwijzers in de systeemeigen browser. Let op: deze toestemming kan niet worden geforceerd door andere browsers of andere apps met internetmogelijkheden."</string>
<string name="permlab_writeHistoryBookmarks" msgid="3714785165273314490">"webbladwijzers en -geschiedenis schrijven"</string>
- <string name="permdesc_writeHistoryBookmarks" product="tablet" msgid="6825527469145760922">"Hiermee kan de app de webgeschiedenis wijzigen in de systeemeigen browser en de bladwijzers die zijn opgeslagen op uw tablet. Deze toestemming kan niet worden geforceerd door andere browsers of andere apps met internetmogelijkheden.."</string>
- <string name="permdesc_writeHistoryBookmarks" product="tv" msgid="7007393823197766548">"Hiermee kan de app de webgeschiedenis wijzigen in de systeemeigen browser en de bladwijzers die zijn opgeslagen op uw tv. De app kan browsergegevens wissen of aanpassen. Deze toestemming kan niet worden geforceerd door andere browsers of andere apps met internetmogelijkheden."</string>
- <string name="permdesc_writeHistoryBookmarks" product="default" msgid="8497389531014185509">"Hiermee kan de app de webgeschiedenis wijzigen in de systeemeigen browser en de bladwijzers die zijn opgeslagen op uw telefoon. Deze toestemming kan niet worden geforceerd door andere browsers of andere apps met internetmogelijkheden."</string>
+ <string name="permdesc_writeHistoryBookmarks" product="tablet" msgid="6825527469145760922">"Hiermee kan de app de webgeschiedenis wijzigen in de systeemeigen browser en de bladwijzers die zijn opgeslagen op je tablet. Deze toestemming kan niet worden geforceerd door andere browsers of andere apps met internetmogelijkheden.."</string>
+ <string name="permdesc_writeHistoryBookmarks" product="tv" msgid="7007393823197766548">"Hiermee kan de app de webgeschiedenis wijzigen in de systeemeigen browser en de bladwijzers die zijn opgeslagen op je tv. De app kan browsergegevens wissen of aanpassen. Deze toestemming kan niet worden geforceerd door andere browsers of andere apps met internetmogelijkheden."</string>
+ <string name="permdesc_writeHistoryBookmarks" product="default" msgid="8497389531014185509">"Hiermee kan de app de webgeschiedenis wijzigen in de systeemeigen browser en de bladwijzers die zijn opgeslagen op je telefoon. Deze toestemming kan niet worden geforceerd door andere browsers of andere apps met internetmogelijkheden."</string>
<string name="permlab_setAlarm" msgid="1379294556362091814">"een alarm instellen"</string>
<string name="permdesc_setAlarm" msgid="316392039157473848">"Hiermee kan de app een alarm instellen in een geïnstalleerde wekkerapp. Deze functie wordt door sommige wekkerapps niet geïmplementeerd."</string>
<string name="permlab_addVoicemail" msgid="5525660026090959044">"voicemail toevoegen"</string>
- <string name="permdesc_addVoicemail" msgid="6604508651428252437">"Hiermee kan de app berichten toevoegen aan de inbox van uw voicemail."</string>
+ <string name="permdesc_addVoicemail" msgid="6604508651428252437">"Hiermee kan de app berichten toevoegen aan de inbox van je voicemail."</string>
<string name="permlab_writeGeolocationPermissions" msgid="5962224158955273932">"geolocatiemachtigingen voor browser aanpassen"</string>
<string name="permdesc_writeGeolocationPermissions" msgid="1083743234522638747">"Hiermee kan de app de geolocatiemachtigingen van de browser aanpassen. Schadelijke apps kunnen dit gebruiken om locatiegegevens te verzenden naar willekeurige websites."</string>
<string name="save_password_message" msgid="767344687139195790">"Wilt u dat de browser dit wachtwoord onthoudt?"</string>
<string name="save_password_notnow" msgid="6389675316706699758">"Niet nu"</string>
<string name="save_password_remember" msgid="6491879678996749466">"Onthouden"</string>
<string name="save_password_never" msgid="8274330296785855105">"Nooit"</string>
- <string name="open_permission_deny" msgid="7374036708316629800">"U heeft geen toestemming om deze pagina te openen."</string>
+ <string name="open_permission_deny" msgid="7374036708316629800">"Je hebt geen toestemming om deze pagina te openen."</string>
<string name="text_copied" msgid="4985729524670131385">"Tekst naar klembord gekopieerd."</string>
<string name="more_item_label" msgid="4650918923083320495">"Meer"</string>
<string name="prepend_shortcut_label" msgid="2572214461676015642">"Menu+"</string>
@@ -805,8 +805,8 @@
<string name="searchview_description_submit" msgid="2688450133297983542">"Zoekopdracht verzenden"</string>
<string name="searchview_description_voice" msgid="2453203695674994440">"Gesproken zoekopdrachten"</string>
<string name="enable_explore_by_touch_warning_title" msgid="7460694070309730149">"\'Verkennen via aanraking\' aan?"</string>
- <string name="enable_explore_by_touch_warning_message" product="tablet" msgid="8655887539089910577">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> wil \'Verkennen via aanraking\' inschakelen. Wanneer \'Verkennen via aanraking\' is ingeschakeld, kunt u beschrijvingen beluisteren of bekijken van wat er onder uw vinger staat of aanraakbewerkingen uitvoeren op de tablet."</string>
- <string name="enable_explore_by_touch_warning_message" product="default" msgid="2708199672852373195">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> wil \'Verkennen via aanraking\' inschakelen. Wanneer \'Verkennen via aanraking\' is ingeschakeld, kunt u beschrijvingen beluisteren of bekijken van wat er onder uw vinger staat of aanraakbewerkingen uitvoeren op de telefoon."</string>
+ <string name="enable_explore_by_touch_warning_message" product="tablet" msgid="8655887539089910577">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> wil \'Verkennen via aanraking\' inschakelen. Wanneer \'Verkennen via aanraking\' is ingeschakeld, kunt u beschrijvingen beluisteren of bekijken van wat er onder je vinger staat of aanraakbewerkingen uitvoeren op de tablet."</string>
+ <string name="enable_explore_by_touch_warning_message" product="default" msgid="2708199672852373195">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> wil \'Verkennen via aanraking\' inschakelen. Wanneer \'Verkennen via aanraking\' is ingeschakeld, kunt u beschrijvingen beluisteren of bekijken van wat er onder je vinger staat of aanraakbewerkingen uitvoeren op de telefoon."</string>
<string name="oneMonthDurationPast" msgid="7396384508953779925">"1 maand geleden"</string>
<string name="beforeOneMonthDurationPast" msgid="909134546836499826">"Meer dan 1 maand geleden"</string>
<plurals name="last_num_days" formatted="false" msgid="5104533550723932025">
@@ -868,7 +868,7 @@
<string name="editTextMenuTitle" msgid="4909135564941815494">"Tekstacties"</string>
<string name="low_internal_storage_view_title" msgid="5576272496365684834">"Opslagruimte is bijna vol"</string>
<string name="low_internal_storage_view_text" msgid="6640505817617414371">"Bepaalde systeemfuncties werken mogelijk niet"</string>
- <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"Onvoldoende opslagruimte voor het systeem. Zorg ervoor dat u 250 MB vrije ruimte heeft en start opnieuw."</string>
+ <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"Onvoldoende opslagruimte voor het systeem. Zorg ervoor dat je 250 MB vrije ruimte hebt en start opnieuw."</string>
<string name="app_running_notification_title" msgid="8718335121060787914">"<xliff:g id="APP_NAME">%1$s</xliff:g> wordt uitgevoerd"</string>
<string name="app_running_notification_text" msgid="4653586947747330058">"Raak aan voor meer informatie of om de app te stoppen."</string>
<string name="ok" msgid="5970060430562524910">"OK"</string>
@@ -995,8 +995,8 @@
<string name="sms_control_yes" msgid="3663725993855816807">"Toestaan"</string>
<string name="sms_control_no" msgid="625438561395534982">"Weigeren"</string>
<string name="sms_short_code_confirm_message" msgid="1645436466285310855">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> wil graag een bericht verzenden naar <b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b>."</string>
- <string name="sms_short_code_details" msgid="5873295990846059400">"Hiervoor "<b>"worden mogelijk kosten in rekening gebracht"</b>" op uw mobiele account."</string>
- <string name="sms_premium_short_code_details" msgid="7869234868023975"><b>"Hiervoor worden kosten in rekening gebracht op uw mobiele account."</b></string>
+ <string name="sms_short_code_details" msgid="5873295990846059400">"Hiervoor "<b>"worden mogelijk kosten in rekening gebracht"</b>" op je mobiele account."</string>
+ <string name="sms_premium_short_code_details" msgid="7869234868023975"><b>"Hiervoor worden kosten in rekening gebracht op je mobiele account."</b></string>
<string name="sms_short_code_confirm_allow" msgid="4458878637111023413">"Verzenden"</string>
<string name="sms_short_code_confirm_deny" msgid="2927389840209170706">"Annuleren"</string>
<string name="sms_short_code_remember_choice" msgid="5289538592272218136">"Mijn keuze onthouden"</string>
@@ -1007,7 +1007,7 @@
<string name="sim_removed_message" msgid="5450336489923274918">"Het mobiele netwerk is pas beschikbaar zodra u het apparaat opnieuw start met een geldige simkaart."</string>
<string name="sim_done_button" msgid="827949989369963775">"Gereed"</string>
<string name="sim_added_title" msgid="3719670512889674693">"Simkaart aangesloten"</string>
- <string name="sim_added_message" msgid="7797975656153714319">"Start uw apparaat opnieuw voor toegang tot het mobiele netwerk."</string>
+ <string name="sim_added_message" msgid="7797975656153714319">"Start je apparaat opnieuw voor toegang tot het mobiele netwerk."</string>
<string name="sim_restart_button" msgid="4722407842815232347">"Opnieuw starten"</string>
<string name="time_picker_dialog_title" msgid="8349362623068819295">"Tijd instellen"</string>
<string name="date_picker_dialog_title" msgid="5879450659453782278">"Datum instellen"</string>
@@ -1019,20 +1019,20 @@
<string name="perm_costs_money" msgid="4902470324142151116">"hieraan kunnen kosten zijn verbonden"</string>
<string name="usb_storage_activity_title" msgid="4465055157209648641">"USB-massaopslag"</string>
<string name="usb_storage_title" msgid="5901459041398751495">"USB-verbinding"</string>
- <string name="usb_storage_message" product="nosdcard" msgid="3308538094316477839">"U heeft uw telefoon via USB op uw computer aangesloten. Raak de knop hieronder aan als u bestanden tussen uw computer en de USB-opslag van uw Android wilt kopiëren."</string>
- <string name="usb_storage_message" product="default" msgid="805351000446037811">"U heeft uw telefoon via USB op uw computer aangesloten. Raak de onderstaande knop aan als u bestanden tussen uw computer en de SD-kaart van uw Android wilt kopiëren."</string>
+ <string name="usb_storage_message" product="nosdcard" msgid="3308538094316477839">"Je hebt je telefoon via USB op je computer aangesloten. Raak de knop hieronder aan als u bestanden tussen je computer en de USB-opslag van je Android wilt kopiëren."</string>
+ <string name="usb_storage_message" product="default" msgid="805351000446037811">"Je hebt je telefoon via USB op je computer aangesloten. Raak de onderstaande knop aan als u bestanden tussen je computer en de SD-kaart van je Android wilt kopiëren."</string>
<string name="usb_storage_button_mount" msgid="1052259930369508235">"USB-opslag inschakelen"</string>
- <string name="usb_storage_error_message" product="nosdcard" msgid="3017045217365540658">"Er is een probleem bij het gebruik van uw USB-opslag voor USB-massaopslag."</string>
- <string name="usb_storage_error_message" product="default" msgid="2876018512716970313">"Er is een probleem bij het gebruik van uw SD-kaart voor USB-massaopslag."</string>
+ <string name="usb_storage_error_message" product="nosdcard" msgid="3017045217365540658">"Er is een probleem bij het gebruik van je USB-opslag voor USB-massaopslag."</string>
+ <string name="usb_storage_error_message" product="default" msgid="2876018512716970313">"Er is een probleem bij het gebruik van je SD-kaart voor USB-massaopslag."</string>
<string name="usb_storage_notification_title" msgid="8175892554757216525">"USB-verbinding"</string>
- <string name="usb_storage_notification_message" msgid="939822783828183763">"Raak aan om bestanden naar/van uw computer te kopiëren."</string>
+ <string name="usb_storage_notification_message" msgid="939822783828183763">"Raak aan om bestanden naar/van je computer te kopiëren."</string>
<string name="usb_storage_stop_notification_title" msgid="2336058396663516017">"USB-opslag uitschakelen"</string>
<string name="usb_storage_stop_notification_message" msgid="1656852098555623822">"Raak aan om USB-opslag uit te schakelen."</string>
<string name="usb_storage_stop_title" msgid="660129851708775853">"USB-opslag in gebruik"</string>
- <string name="usb_storage_stop_message" product="nosdcard" msgid="4264025280777219521">"Voordat u USB-opslag uitschakelt, moet u de USB-opslag van uw Android ontkoppelen van uw computer (\'uitwerpen\')."</string>
- <string name="usb_storage_stop_message" product="default" msgid="8043969782460613114">"Voordat u USB-opslag uitschakelt, moet u de SD-kaart van uw Android ontkoppelen van uw computer (\'uitwerpen\')."</string>
+ <string name="usb_storage_stop_message" product="nosdcard" msgid="4264025280777219521">"Voordat u USB-opslag uitschakelt, moet u de USB-opslag van je Android ontkoppelen van je computer (\'uitwerpen\')."</string>
+ <string name="usb_storage_stop_message" product="default" msgid="8043969782460613114">"Voordat u USB-opslag uitschakelt, moet u de SD-kaart van je Android ontkoppelen van je computer (\'uitwerpen\')."</string>
<string name="usb_storage_stop_button_mount" msgid="7060218034900696029">"USB-opslag uitschakelen"</string>
- <string name="usb_storage_stop_error_message" msgid="1970374898263063836">"Er is een probleem opgetreden tijdens het uitschakelen van de USB-opslag. Controleer of u de USB-host heeft losgekoppeld en probeer het opnieuw."</string>
+ <string name="usb_storage_stop_error_message" msgid="1970374898263063836">"Er is een probleem opgetreden tijdens het uitschakelen van de USB-opslag. Controleer of je de USB-host hebt losgekoppeld en probeer het opnieuw."</string>
<string name="dlg_confirm_kill_storage_users_title" msgid="963039033470478697">"USB-opslag inschakelen"</string>
<string name="dlg_confirm_kill_storage_users_text" msgid="5100428757107469454">"Als u USB-opslag inschakelt, worden bepaalde apps die u gebruikt, gestopt en zijn deze mogelijk pas weer beschikbaar wanneer u USB-opslag uitschakelt."</string>
<string name="dlg_error_title" msgid="7323658469626514207">"USB-bewerking mislukt"</string>
@@ -1108,15 +1108,15 @@
<string name="ime_action_default" msgid="2840921885558045721">"Uitvoeren"</string>
<string name="dial_number_using" msgid="5789176425167573586">"Nummer bellen\nmet <xliff:g id="NUMBER">%s</xliff:g>"</string>
<string name="create_contact_using" msgid="4947405226788104538">"Contact maken\nmet <xliff:g id="NUMBER">%s</xliff:g>"</string>
- <string name="grant_credentials_permission_message_header" msgid="2106103817937859662">"De volgende apps verzoeken om toegang tot uw account, nu en in de toekomst."</string>
+ <string name="grant_credentials_permission_message_header" msgid="2106103817937859662">"De volgende apps verzoeken om toegang tot je account, nu en in de toekomst."</string>
<string name="grant_credentials_permission_message_footer" msgid="3125211343379376561">"Wilt u dit verzoek toestaan?"</string>
<string name="grant_permissions_header_text" msgid="6874497408201826708">"Verzoek om toegang"</string>
<string name="allow" msgid="7225948811296386551">"Toestaan"</string>
<string name="deny" msgid="2081879885755434506">"Weigeren"</string>
<string name="permission_request_notification_title" msgid="6486759795926237907">"Toestemming gevraagd"</string>
<string name="permission_request_notification_with_subtitle" msgid="8530393139639560189">"Toestemming gevraagd\nvoor account <xliff:g id="ACCOUNT">%s</xliff:g>."</string>
- <string name="forward_intent_to_owner" msgid="1207197447013960896">"U gebruikt deze app buiten uw werkprofiel"</string>
- <string name="forward_intent_to_work" msgid="621480743856004612">"U gebruikt deze app in uw werkprofiel"</string>
+ <string name="forward_intent_to_owner" msgid="1207197447013960896">"U gebruikt deze app buiten je werkprofiel"</string>
+ <string name="forward_intent_to_work" msgid="621480743856004612">"U gebruikt deze app in je werkprofiel"</string>
<string name="input_method_binding_label" msgid="1283557179944992649">"Invoermethode"</string>
<string name="sync_binding_label" msgid="3687969138375092423">"Synchroniseren"</string>
<string name="accessibility_binding_label" msgid="4148120742096474641">"Toegankelijkheid"</string>
@@ -1282,7 +1282,7 @@
<string name="kg_wrong_password" msgid="2333281762128113157">"Onjuist wachtwoord"</string>
<string name="kg_wrong_pin" msgid="1131306510833563801">"Onjuiste pincode"</string>
<string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"Probeer het over <xliff:g id="NUMBER">%1$d</xliff:g> seconden opnieuw."</string>
- <string name="kg_pattern_instructions" msgid="398978611683075868">"Teken uw patroon"</string>
+ <string name="kg_pattern_instructions" msgid="398978611683075868">"Teken je patroon"</string>
<string name="kg_sim_pin_instructions" msgid="2319508550934557331">"Geef de pincode van de simkaart op"</string>
<string name="kg_pin_instructions" msgid="2377242233495111557">"Pincode opgeven"</string>
<string name="kg_password_instructions" msgid="5753646556186936819">"Wachtwoord invoeren"</string>
@@ -1296,28 +1296,28 @@
<string name="kg_invalid_puk" msgid="3638289409676051243">"Geef de juiste PUK-code opnieuw op. Bij herhaalde pogingen wordt de simkaart permanent uitgeschakeld."</string>
<string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"Pincodes komen niet overeen"</string>
<string name="kg_login_too_many_attempts" msgid="6486842094005698475">"Te veel patroonpogingen"</string>
- <string name="kg_login_instructions" msgid="1100551261265506448">"Als u wilt ontgrendelen, moet u inloggen op uw Google-account."</string>
+ <string name="kg_login_instructions" msgid="1100551261265506448">"Als u wilt ontgrendelen, moet u inloggen op je Google-account."</string>
<string name="kg_login_username_hint" msgid="5718534272070920364">"Gebruikersnaam (e-mail)"</string>
<string name="kg_login_password_hint" msgid="9057289103827298549">"Wachtwoord"</string>
<string name="kg_login_submit_button" msgid="5355904582674054702">"Inloggen"</string>
<string name="kg_login_invalid_input" msgid="5754664119319872197">"Ongeldige gebruikersnaam of wachtwoord."</string>
- <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Bent u uw gebruikersnaam of wachtwoord vergeten?\nGa naar "<b>"google.com/accounts/recovery"</b>"."</string>
+ <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Bent u je gebruikersnaam of wachtwoord vergeten?\nGa naar "<b>"google.com/accounts/recovery"</b>"."</string>
<string name="kg_login_checking_password" msgid="1052685197710252395">"Account controleren…"</string>
- <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"U heeft uw pincode <xliff:g id="NUMBER_0">%d</xliff:g> keer onjuist getypt. \n\nProbeer het opnieuw over <xliff:g id="NUMBER_1">%d</xliff:g> seconden."</string>
- <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"U heeft uw wachtwoord <xliff:g id="NUMBER_0">%d</xliff:g> keer onjuist getypt. \n\nProbeer het opnieuw over <xliff:g id="NUMBER_1">%d</xliff:g> seconden."</string>
- <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"U heeft uw ontgrendelingspatroon <xliff:g id="NUMBER_0">%d</xliff:g> keer onjuist getekend. \n\nProbeer het opnieuw over <xliff:g id="NUMBER_1">%d</xliff:g> seconden."</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"U heeft <xliff:g id="NUMBER_0">%d</xliff:g> keer geprobeerd de tablet op een onjuiste manier te ontgrendelen. Na nog eens <xliff:g id="NUMBER_1">%d</xliff:g> mislukte pogingen worden de fabrieksinstellingen hersteld op de tablet en gaan alle gebruikersgegevens verloren."</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="tv" msgid="5621231220154419413">"U heeft op onjuiste wijze <xliff:g id="NUMBER_0">%d</xliff:g> keer geprobeerd de tv te ontgrendelen. Na nog <xliff:g id="NUMBER_1">%d</xliff:g> onjuiste pogingen, wordt de tv hersteld naar de fabriekswaarden en gaan alle gebruikersgegevens verloren."</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"U heeft nu <xliff:g id="NUMBER_0">%d</xliff:g> keer geprobeerd de telefoon op een onjuiste manier te ontgrendelen. Na nog eens <xliff:g id="NUMBER_1">%d</xliff:g> mislukte pogingen worden de fabrieksinstellingen hersteld op de telefoon en gaan alle gebruikersgegevens verloren."</string>
- <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"U heeft <xliff:g id="NUMBER">%d</xliff:g> keer geprobeerd de tablet op een onjuiste manier te ontgrendelen. De fabrieksinstellingen worden nu hersteld op de tablet."</string>
- <string name="kg_failed_attempts_now_wiping" product="tv" msgid="4987878286750741463">"U heeft op onjuiste wijze <xliff:g id="NUMBER">%d</xliff:g> keer geprobeerd de tv te ontgrendelen. De tv wordt nu hersteld naar de fabrieksinstellingen."</string>
- <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"U heeft <xliff:g id="NUMBER">%d</xliff:g> keer geprobeerd de telefoon op een onjuiste manier te ontgrendelen. De fabrieksinstellingen worden nu hersteld op de telefoon."</string>
- <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"U heeft uw ontgrendelingspatroon <xliff:g id="NUMBER_0">%d</xliff:g> keer onjuist getekend. Na nog eens <xliff:g id="NUMBER_1">%d</xliff:g> mislukte pogingen wordt u gevraagd uw tablet te ontgrendelen via een e-mailaccount.\n\n Probeer het over <xliff:g id="NUMBER_2">%d</xliff:g> seconden opnieuw."</string>
- <string name="kg_failed_attempts_almost_at_login" product="tv" msgid="4224651132862313471">"U heeft uw ontgrendelingspatroon <xliff:g id="NUMBER_0">%d</xliff:g> keer onjuist getekend. Na nog <xliff:g id="NUMBER_1">%d</xliff:g> onjuiste pogingen, wordt u gevraagd uw tv te ontgrendelen met een e-mailaccount.\n\n Probeer het opnieuw over <xliff:g id="NUMBER_2">%d</xliff:g> seconden."</string>
- <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"U heeft uw ontgrendelingspatroon <xliff:g id="NUMBER_0">%d</xliff:g> keer onjuist getekend. Na nog eens <xliff:g id="NUMBER_1">%d</xliff:g> mislukte pogingen wordt u gevraagd uw telefoon te ontgrendelen via een e-mailaccount.\n\n Probeer het over <xliff:g id="NUMBER_2">%d</xliff:g> seconden opnieuw."</string>
+ <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Je hebt je pincode <xliff:g id="NUMBER_0">%d</xliff:g> keer onjuist getypt. \n\nProbeer het opnieuw over <xliff:g id="NUMBER_1">%d</xliff:g> seconden."</string>
+ <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Je hebt je wachtwoord <xliff:g id="NUMBER_0">%d</xliff:g> keer onjuist getypt. \n\nProbeer het opnieuw over <xliff:g id="NUMBER_1">%d</xliff:g> seconden."</string>
+ <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Je hebt je ontgrendelingspatroon <xliff:g id="NUMBER_0">%d</xliff:g> keer onjuist getekend. \n\nProbeer het opnieuw over <xliff:g id="NUMBER_1">%d</xliff:g> seconden."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Je hebt <xliff:g id="NUMBER_0">%d</xliff:g> keer geprobeerd de tablet op een onjuiste manier te ontgrendelen. Na nog eens <xliff:g id="NUMBER_1">%d</xliff:g> mislukte pogingen worden de fabrieksinstellingen hersteld op de tablet en gaan alle gebruikersgegevens verloren."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="tv" msgid="5621231220154419413">"Je hebt op onjuiste wijze <xliff:g id="NUMBER_0">%d</xliff:g> keer geprobeerd de tv te ontgrendelen. Na nog <xliff:g id="NUMBER_1">%d</xliff:g> onjuiste pogingen, wordt de tv hersteld naar de fabriekswaarden en gaan alle gebruikersgegevens verloren."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Je hebt nu <xliff:g id="NUMBER_0">%d</xliff:g> keer geprobeerd de telefoon op een onjuiste manier te ontgrendelen. Na nog eens <xliff:g id="NUMBER_1">%d</xliff:g> mislukte pogingen worden de fabrieksinstellingen hersteld op de telefoon en gaan alle gebruikersgegevens verloren."</string>
+ <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"Je hebt <xliff:g id="NUMBER">%d</xliff:g> keer geprobeerd de tablet op een onjuiste manier te ontgrendelen. De fabrieksinstellingen worden nu hersteld op de tablet."</string>
+ <string name="kg_failed_attempts_now_wiping" product="tv" msgid="4987878286750741463">"Je hebt op onjuiste wijze <xliff:g id="NUMBER">%d</xliff:g> keer geprobeerd de tv te ontgrendelen. De tv wordt nu hersteld naar de fabrieksinstellingen."</string>
+ <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"Je hebt <xliff:g id="NUMBER">%d</xliff:g> keer geprobeerd de telefoon op een onjuiste manier te ontgrendelen. De fabrieksinstellingen worden nu hersteld op de telefoon."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Je hebt je ontgrendelingspatroon <xliff:g id="NUMBER_0">%d</xliff:g> keer onjuist getekend. Na nog eens <xliff:g id="NUMBER_1">%d</xliff:g> mislukte pogingen wordt u gevraagd je tablet te ontgrendelen via een e-mailaccount.\n\n Probeer het over <xliff:g id="NUMBER_2">%d</xliff:g> seconden opnieuw."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="tv" msgid="4224651132862313471">"Je hebt je ontgrendelingspatroon <xliff:g id="NUMBER_0">%d</xliff:g> keer onjuist getekend. Na nog <xliff:g id="NUMBER_1">%d</xliff:g> onjuiste pogingen, wordt je gevraagd je tv te ontgrendelen met een e-mailaccount.\n\n Probeer het opnieuw over <xliff:g id="NUMBER_2">%d</xliff:g> seconden."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Je hebt je ontgrendelingspatroon <xliff:g id="NUMBER_0">%d</xliff:g> keer onjuist getekend. Na nog eens <xliff:g id="NUMBER_1">%d</xliff:g> mislukte pogingen wordt u gevraagd je telefoon te ontgrendelen via een e-mailaccount.\n\n Probeer het over <xliff:g id="NUMBER_2">%d</xliff:g> seconden opnieuw."</string>
<string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" — "</string>
<string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"Verwijderen"</string>
- <string name="safe_media_volume_warning" product="default" msgid="2276318909314492312">"Volume verhogen tot boven het aanbevolen niveau?\n\nAls u langere tijd op hoog volume naar muziek luistert, raakt uw gehoor mogelijk beschadigd."</string>
+ <string name="safe_media_volume_warning" product="default" msgid="2276318909314492312">"Volume verhogen tot boven het aanbevolen niveau?\n\nAls u langere tijd op hoog volume naar muziek luistert, raakt je gehoor mogelijk beschadigd."</string>
<string name="continue_to_enable_accessibility" msgid="1626427372316070258">"Blijf het scherm met twee vingers aanraken om toegankelijkheid in te schakelen."</string>
<string name="accessibility_enabled" msgid="1381972048564547685">"Toegankelijkheid ingeschakeld."</string>
<string name="enable_accessibility_canceled" msgid="3833923257966635673">"Toegankelijkheid geannuleerd."</string>
@@ -1325,7 +1325,7 @@
<string name="user_switching_message" msgid="2871009331809089783">"Overschakelen naar <xliff:g id="NAME">%1$s</xliff:g>…"</string>
<string name="owner_name" msgid="2716755460376028154">"Eigenaar"</string>
<string name="error_message_title" msgid="4510373083082500195">"Fout"</string>
- <string name="error_message_change_not_allowed" msgid="1347282344200417578">"Deze wijziging is niet toegestaan door uw beheerder"</string>
+ <string name="error_message_change_not_allowed" msgid="1347282344200417578">"Deze wijziging is niet toegestaan door je beheerder"</string>
<string name="app_not_found" msgid="3429141853498927379">"Er is geen app gevonden om deze actie uit te voeren"</string>
<string name="revoke" msgid="5404479185228271586">"Intrekken"</string>
<string name="mediasize_iso_a0" msgid="1994474252931294172">"ISO A0"</string>
@@ -1451,10 +1451,10 @@
<string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"Vraag pin voor losmaken"</string>
<string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"Vraag patroon voor losmaken"</string>
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Vraag wachtwoord voor losmaken"</string>
- <string name="package_installed_device_owner" msgid="8420696545959087545">"Geïnstalleerd door uw beheerder"</string>
- <string name="package_updated_device_owner" msgid="8856631322440187071">"Geüpdatet door uw beheerder"</string>
- <string name="package_deleted_device_owner" msgid="7650577387493101353">"Verwijderd door uw beheerder"</string>
- <string name="battery_saver_description" msgid="1960431123816253034">"Accubesparing beperkt de prestaties van uw apparaat, de trilstand, locatieservices en de meeste achtergrondgegevens om de gebruiksduur van de accu te verlengen.\n\nAccubesparing wordt automatisch uitgeschakeld terwijl uw apparaat wordt opgeladen."</string>
+ <string name="package_installed_device_owner" msgid="8420696545959087545">"Geïnstalleerd door je beheerder"</string>
+ <string name="package_updated_device_owner" msgid="8856631322440187071">"Geüpdatet door je beheerder"</string>
+ <string name="package_deleted_device_owner" msgid="7650577387493101353">"Verwijderd door je beheerder"</string>
+ <string name="battery_saver_description" msgid="1960431123816253034">"Accubesparing beperkt de prestaties van je apparaat, de trilstand, locatieservices en de meeste achtergrondgegevens om de gebruiksduur van de accu te verlengen.\n\nAccubesparing wordt automatisch uitgeschakeld terwijl je apparaat wordt opgeladen."</string>
<plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="4367877408072000848">
<item quantity="other">%1$d minuten (tot <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
<item quantity="one">Eén minuut (tot <xliff:g id="FORMATTEDTIME_0">%2$s</xliff:g>)</item>
@@ -1488,6 +1488,7 @@
<item quantity="one">Gedurende 1 u</item>
</plurals>
<string name="zen_mode_until" msgid="7336308492289875088">"Tot <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
+ <string name="zen_mode_alarm" msgid="9128205721301330797">"Tot <xliff:g id="FORMATTEDTIME">%1$s</xliff:g> (volgend alarm)"</string>
<string name="zen_mode_forever" msgid="7420011936770086993">"Totdat u dit uitschakelt"</string>
<string name="zen_mode_forever_dnd" msgid="3792132696572189081">"Totdat u \'Niet storen\' uitschakelt"</string>
<string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g>/<xliff:g id="REST">%2$s</xliff:g>"</string>
@@ -1498,8 +1499,8 @@
<string name="zen_mode_default_weekends_name" msgid="2786495801019345244">"Weekend"</string>
<string name="zen_mode_default_events_name" msgid="8158334939013085363">"Evenement"</string>
<string name="muted_by" msgid="6147073845094180001">"Gedempt door <xliff:g id="THIRD_PARTY">%1$s</xliff:g>"</string>
- <string name="system_error_wipe_data" msgid="6608165524785354962">"Er is een intern probleem met uw apparaat. Het apparaat kan instabiel zijn totdat u het apparaat terugzet naar de fabrieksinstellingen."</string>
- <string name="system_error_manufacturer" msgid="8086872414744210668">"Er is een intern probleem met uw apparaat. Neem contact op met de fabrikant voor meer informatie."</string>
+ <string name="system_error_wipe_data" msgid="6608165524785354962">"Er is een intern probleem met je apparaat. Het apparaat kan instabiel zijn totdat u het apparaat terugzet naar de fabrieksinstellingen."</string>
+ <string name="system_error_manufacturer" msgid="8086872414744210668">"Er is een intern probleem met je apparaat. Neem contact op met de fabrikant voor meer informatie."</string>
<string name="stk_cc_ussd_to_dial" msgid="5202342984749947872">"USSD-verzoek is gewijzigd in DIAL-verzoek."</string>
<string name="stk_cc_ussd_to_ss" msgid="2345360594181405482">"USSD-verzoek is gewijzigd in SS-verzoek."</string>
<string name="stk_cc_ussd_to_ussd" msgid="7466087659967191653">"USSD-verzoek is gewijzigd in nieuw USSD-verzoek."</string>
diff --git a/core/res/res/values-pa-rIN/strings.xml b/core/res/res/values-pa-rIN/strings.xml
index 5a9d2c1..1743570 100644
--- a/core/res/res/values-pa-rIN/strings.xml
+++ b/core/res/res/values-pa-rIN/strings.xml
@@ -1488,6 +1488,7 @@
<item quantity="other">%d ਘੰਟਿਆਂ ਲਈ</item>
</plurals>
<string name="zen_mode_until" msgid="7336308492289875088">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g> ਤੱਕ"</string>
+ <string name="zen_mode_alarm" msgid="9128205721301330797">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g> ਤੱਕ (ਅਗਲਾ ਅਲਾਰਮ)"</string>
<string name="zen_mode_forever" msgid="7420011936770086993">"ਜਦੋਂ ਤੱਕ ਤੁਸੀਂ ਇਸਨੂੰ ਬੰਦ ਨਹੀਂ ਕਰਦੇ ਹੋ"</string>
<string name="zen_mode_forever_dnd" msgid="3792132696572189081">"ਜਦੋਂ ਤੱਕ ਤੁਸੀਂ ਪਰੇਸ਼ਾਨ ਨਾ ਕਰੋ ਨੂੰ ਬੰਦ ਨਹੀਂ ਕਰਦੇ ਹੋ"</string>
<string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string>
diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml
index 488ee30..308bf89 100644
--- a/core/res/res/values-pl/strings.xml
+++ b/core/res/res/values-pl/strings.xml
@@ -69,8 +69,8 @@
</plurals>
<string name="imei" msgid="2625429890869005782">"IMEI"</string>
<string name="meid" msgid="4841221237681254195">"MEID"</string>
- <string name="ClipMmi" msgid="6952821216480289285">"Nazwa rozmówcy przy połączeniach przychodzących"</string>
- <string name="ClirMmi" msgid="7784673673446833091">"Nazwa rozmówcy przy połączeniach wychodzących"</string>
+ <string name="ClipMmi" msgid="6952821216480289285">"ID rozmówcy przy połączeniach przychodzących"</string>
+ <string name="ClirMmi" msgid="7784673673446833091">"ID rozmówcy przy połączeniach wychodzących"</string>
<string name="ColpMmi" msgid="3065121483740183974">"Identyfikator połączonej linii"</string>
<string name="ColrMmi" msgid="4996540314421889589">"Ograniczenie identyfikatora połączonej linii"</string>
<string name="CfMmi" msgid="5123218989141573515">"Przekierowanie połączeń"</string>
@@ -84,12 +84,12 @@
<string name="RuacMmi" msgid="7827887459138308886">"Odrzucanie niepożądanych, irytujących połączeń"</string>
<string name="CndMmi" msgid="3116446237081575808">"Dostarczanie numeru telefonującego"</string>
<string name="DndMmi" msgid="1265478932418334331">"Nie przeszkadzać"</string>
- <string name="CLIRDefaultOnNextCallOn" msgid="429415409145781923">"Nazwa rozmówcy ustawiona jest domyślnie na „zastrzeżony”. Następne połączenie: zastrzeżony"</string>
- <string name="CLIRDefaultOnNextCallOff" msgid="3092918006077864624">"Nazwa rozmówcy ustawiona jest domyślnie na „zastrzeżony”. Następne połączenie: nie zastrzeżony"</string>
- <string name="CLIRDefaultOffNextCallOn" msgid="6179425182856418465">"Nazwa rozmówcy ustawiona jest domyślnie na „nie zastrzeżony”. Następne połączenie: zastrzeżony"</string>
- <string name="CLIRDefaultOffNextCallOff" msgid="2567998633124408552">"Nazwa rozmówcy ustawiona jest domyślnie na „nie zastrzeżony”. Następne połączenie: nie zastrzeżony"</string>
+ <string name="CLIRDefaultOnNextCallOn" msgid="429415409145781923">"ID rozmówcy ustawiony jest domyślnie na „zastrzeżony”. Następne połączenie: zastrzeżony"</string>
+ <string name="CLIRDefaultOnNextCallOff" msgid="3092918006077864624">"ID rozmówcy ustawiony jest domyślnie na „zastrzeżony”. Następne połączenie: nie zastrzeżony"</string>
+ <string name="CLIRDefaultOffNextCallOn" msgid="6179425182856418465">"ID rozmówcy ustawiony jest domyślnie na „nie zastrzeżony”. Następne połączenie: zastrzeżony"</string>
+ <string name="CLIRDefaultOffNextCallOff" msgid="2567998633124408552">"ID rozmówcy ustawiony jest domyślnie na „nie zastrzeżony”. Następne połączenie: nie zastrzeżony"</string>
<string name="serviceNotProvisioned" msgid="8614830180508686666">"Usługa nie jest świadczona."</string>
- <string name="CLIRPermanent" msgid="3377371145926835671">"Nie możesz zmienić ustawienia identyfikatora rozmówcy."</string>
+ <string name="CLIRPermanent" msgid="3377371145926835671">"Nie możesz zmienić ustawienia ID rozmówcy."</string>
<string name="RestrictedChangedTitle" msgid="5592189398956187498">"Zmieniono ograniczenie dostępu"</string>
<string name="RestrictedOnData" msgid="8653794784690065540">"Usługa transmisji danych jest zablokowana."</string>
<string name="RestrictedOnEmergency" msgid="6581163779072833665">"Usługa połączeń alarmowych jest zablokowana."</string>
@@ -421,10 +421,10 @@
<string name="permlab_useFingerprint" msgid="3150478619915124905">"używanie czytnika linii papilarnych"</string>
<string name="permdesc_useFingerprint" msgid="9165097460730684114">"Zezwala aplikacji na używanie czytnika linii papilarnych na potrzeby autoryzacji"</string>
<string name="fingerprint_acquired_partial" msgid="735082772341716043">"Odcisk palca został odczytany tylko częściowo. Spróbuj ponownie."</string>
- <string name="fingerprint_acquired_insufficient" msgid="4596546021310923214">"Nie udało się przetworzyć linii papilarnych. Spróbuj ponownie."</string>
+ <string name="fingerprint_acquired_insufficient" msgid="4596546021310923214">"Nie udało się przetworzyć odcisku palca. Spróbuj ponownie."</string>
<string name="fingerprint_acquired_imager_dirty" msgid="1087209702421076105">"Czytnik linii papilarnych jest zabrudzony. Wyczyść go i spróbuj ponownie."</string>
- <string name="fingerprint_acquired_too_fast" msgid="6470642383109155969">"Palec został uniesiony zbyt szybko. Spróbuj ponownie."</string>
- <string name="fingerprint_acquired_too_slow" msgid="59250885689661653">"Palec został przesunięty zbyt wolno. Spróbuj ponownie."</string>
+ <string name="fingerprint_acquired_too_fast" msgid="6470642383109155969">"Palec został podniesiony zbyt wcześnie. Spróbuj jeszcze raz."</string>
+ <string name="fingerprint_acquired_too_slow" msgid="59250885689661653">"Palec został obrócony zbyt wolno. Spróbuj ponownie."</string>
<string-array name="fingerprint_acquired_vendor">
</string-array>
<string name="fingerprint_error_hw_not_available" msgid="7955921658939936596">"Czytnik linii papilarnych nie jest dostępny."</string>
@@ -433,7 +433,7 @@
<string name="fingerprint_error_canceled" msgid="4402024612660774395">"Odczyt odcisku palca został anulowany."</string>
<string name="fingerprint_error_lockout" msgid="5536934748136933450">"Zbyt wiele prób. Spróbuj ponownie później."</string>
<string name="fingerprint_error_unable_to_process" msgid="6107816084103552441">"Spróbuj ponownie."</string>
- <string name="fingerprint_name_template" msgid="5870957565512716938">"Palec <xliff:g id="FINGERID">%d</xliff:g>"</string>
+ <string name="fingerprint_name_template" msgid="5870957565512716938">"Odcisk palca <xliff:g id="FINGERID">%d</xliff:g>"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
<string name="fingerprint_icon_content_description" msgid="2340202869968465936">"Ikona odcisku palca"</string>
@@ -1522,6 +1522,7 @@
<item quantity="one">1 godz.</item>
</plurals>
<string name="zen_mode_until" msgid="7336308492289875088">"Do <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
+ <string name="zen_mode_alarm" msgid="9128205721301330797">"Do <xliff:g id="FORMATTEDTIME">%1$s</xliff:g> (następny alarm)"</string>
<string name="zen_mode_forever" msgid="7420011936770086993">"Dopóki nie wyłączysz"</string>
<string name="zen_mode_forever_dnd" msgid="3792132696572189081">"Do wyłączenia Nie przeszkadzać"</string>
<string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string>
diff --git a/core/res/res/values-pt-rBR/strings.xml b/core/res/res/values-pt-rBR/strings.xml
index 4972ce9..7050cf8 100644
--- a/core/res/res/values-pt-rBR/strings.xml
+++ b/core/res/res/values-pt-rBR/strings.xml
@@ -227,23 +227,23 @@
<string name="user_owner_label" msgid="2804351898001038951">"Pessoal"</string>
<string name="managed_profile_label" msgid="6260850669674791528">"Trabalho"</string>
<string name="permgrouplab_contacts" msgid="3657758145679177612">"Contatos"</string>
- <string name="permgroupdesc_contacts" msgid="6951499528303668046">"acessar seus contatos"</string>
+ <string name="permgroupdesc_contacts" msgid="6951499528303668046">"acesse seus contatos"</string>
<string name="permgrouplab_location" msgid="7275582855722310164">"Local"</string>
<string name="permgroupdesc_location" msgid="1346617465127855033">"acesse o local do dispositivo"</string>
<string name="permgrouplab_calendar" msgid="5863508437783683902">"Agenda"</string>
- <string name="permgroupdesc_calendar" msgid="3889615280211184106">"acessar sua agenda"</string>
+ <string name="permgroupdesc_calendar" msgid="3889615280211184106">"acesse sua agenda"</string>
<string name="permgrouplab_sms" msgid="228308803364967808">"SMS"</string>
<string name="permgroupdesc_sms" msgid="4656988620100940350">"enviar e ver mensagens SMS"</string>
<string name="permgrouplab_storage" msgid="1971118770546336966">"Armazenamento"</string>
- <string name="permgroupdesc_storage" msgid="637758554581589203">"acesse fotos, mídia e arquivos do seu dispositivo"</string>
+ <string name="permgroupdesc_storage" msgid="637758554581589203">"acesse fotos, mídia e arquivos do dispositivo"</string>
<string name="permgrouplab_microphone" msgid="171539900250043464">"Microfone"</string>
<string name="permgroupdesc_microphone" msgid="4988812113943554584">"grave áudio"</string>
<string name="permgrouplab_camera" msgid="4820372495894586615">"Câmera"</string>
<string name="permgroupdesc_camera" msgid="3250611594678347720">"tire fotos e grave vídeos"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"Telefone"</string>
- <string name="permgroupdesc_phone" msgid="6234224354060641055">"fazer e gerenciar chamadas telefônicas"</string>
+ <string name="permgroupdesc_phone" msgid="6234224354060641055">"faça e gerencie chamadas telefônicas"</string>
<string name="permgrouplab_sensors" msgid="416037179223226722">"Sensores corporais"</string>
- <string name="permgroupdesc_sensors" msgid="7147968539346634043">"acessar dados do sensor sobre seus sinais vitais"</string>
+ <string name="permgroupdesc_sensors" msgid="7147968539346634043">"acesse dados do sensor sobre seus sinais vitais"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Recuperar cont. da janela"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Inspecionar o conteúdo da janela com que você está interagindo."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Ativar Explorar por toque"</string>
@@ -272,7 +272,7 @@
<string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"Permite que o app leia mensagens de difusão celular recebidas por seu dispositivo. Alertas de difusão celular são recebidos em alguns locais para avisar você de situações de emergência. Apps maliciosos podem interferir no desempenho ou funcionamento de seu dispositivo quando uma difusão celular de emergência é recebida."</string>
<string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"ler feeds inscritos"</string>
<string name="permdesc_subscribedFeedsRead" msgid="5557058907906144505">"Permite que o app obtenha detalhes sobre os feeds sincronizados no momento."</string>
- <string name="permlab_sendSms" msgid="7544599214260982981">"enviar e ver mensagens SMS"</string>
+ <string name="permlab_sendSms" msgid="7544599214260982981">"envie e veja mensagens SMS"</string>
<string name="permdesc_sendSms" msgid="7094729298204937667">"Permite que o app envie mensagens SMS. Isso pode resultar em cobranças inesperadas. Apps maliciosos podem gerar custos através do envio de mensagens sem sua confirmação."</string>
<string name="permlab_readSms" msgid="8745086572213270480">"ler suas mensagens de texto (SMS ou MMS)"</string>
<string name="permdesc_readSms" product="tablet" msgid="2467981548684735522">"Permite que o app leia mensagens SMS armazenadas no tablet ou cartão SIM. Isso permite que o app leia todas as mensagens SMS, independentemente de seu conteúdo ou confidencialidade."</string>
@@ -1488,6 +1488,7 @@
<item quantity="other">Por %d horas</item>
</plurals>
<string name="zen_mode_until" msgid="7336308492289875088">"Até às <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
+ <string name="zen_mode_alarm" msgid="9128205721301330797">"Até <xliff:g id="FORMATTEDTIME">%1$s</xliff:g> (próximo alarme)"</string>
<string name="zen_mode_forever" msgid="7420011936770086993">"Até você desativar"</string>
<string name="zen_mode_forever_dnd" msgid="3792132696572189081">"Até que você desative \"Não perturbe\""</string>
<string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string>
diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml
index ff41c14..48baf70 100644
--- a/core/res/res/values-pt-rPT/strings.xml
+++ b/core/res/res/values-pt-rPT/strings.xml
@@ -1488,6 +1488,7 @@
<item quantity="one">Durante 1 h</item>
</plurals>
<string name="zen_mode_until" msgid="7336308492289875088">"Até às <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
+ <string name="zen_mode_alarm" msgid="9128205721301330797">"Até às <xliff:g id="FORMATTEDTIME">%1$s</xliff:g> (próximo alarme)"</string>
<string name="zen_mode_forever" msgid="7420011936770086993">"Até que o utilizador desative"</string>
<string name="zen_mode_forever_dnd" msgid="3792132696572189081">"Até desativar Não incomodar"</string>
<string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g>/<xliff:g id="REST">%2$s</xliff:g>"</string>
diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml
index 4972ce9..7050cf8 100644
--- a/core/res/res/values-pt/strings.xml
+++ b/core/res/res/values-pt/strings.xml
@@ -227,23 +227,23 @@
<string name="user_owner_label" msgid="2804351898001038951">"Pessoal"</string>
<string name="managed_profile_label" msgid="6260850669674791528">"Trabalho"</string>
<string name="permgrouplab_contacts" msgid="3657758145679177612">"Contatos"</string>
- <string name="permgroupdesc_contacts" msgid="6951499528303668046">"acessar seus contatos"</string>
+ <string name="permgroupdesc_contacts" msgid="6951499528303668046">"acesse seus contatos"</string>
<string name="permgrouplab_location" msgid="7275582855722310164">"Local"</string>
<string name="permgroupdesc_location" msgid="1346617465127855033">"acesse o local do dispositivo"</string>
<string name="permgrouplab_calendar" msgid="5863508437783683902">"Agenda"</string>
- <string name="permgroupdesc_calendar" msgid="3889615280211184106">"acessar sua agenda"</string>
+ <string name="permgroupdesc_calendar" msgid="3889615280211184106">"acesse sua agenda"</string>
<string name="permgrouplab_sms" msgid="228308803364967808">"SMS"</string>
<string name="permgroupdesc_sms" msgid="4656988620100940350">"enviar e ver mensagens SMS"</string>
<string name="permgrouplab_storage" msgid="1971118770546336966">"Armazenamento"</string>
- <string name="permgroupdesc_storage" msgid="637758554581589203">"acesse fotos, mídia e arquivos do seu dispositivo"</string>
+ <string name="permgroupdesc_storage" msgid="637758554581589203">"acesse fotos, mídia e arquivos do dispositivo"</string>
<string name="permgrouplab_microphone" msgid="171539900250043464">"Microfone"</string>
<string name="permgroupdesc_microphone" msgid="4988812113943554584">"grave áudio"</string>
<string name="permgrouplab_camera" msgid="4820372495894586615">"Câmera"</string>
<string name="permgroupdesc_camera" msgid="3250611594678347720">"tire fotos e grave vídeos"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"Telefone"</string>
- <string name="permgroupdesc_phone" msgid="6234224354060641055">"fazer e gerenciar chamadas telefônicas"</string>
+ <string name="permgroupdesc_phone" msgid="6234224354060641055">"faça e gerencie chamadas telefônicas"</string>
<string name="permgrouplab_sensors" msgid="416037179223226722">"Sensores corporais"</string>
- <string name="permgroupdesc_sensors" msgid="7147968539346634043">"acessar dados do sensor sobre seus sinais vitais"</string>
+ <string name="permgroupdesc_sensors" msgid="7147968539346634043">"acesse dados do sensor sobre seus sinais vitais"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Recuperar cont. da janela"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Inspecionar o conteúdo da janela com que você está interagindo."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Ativar Explorar por toque"</string>
@@ -272,7 +272,7 @@
<string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"Permite que o app leia mensagens de difusão celular recebidas por seu dispositivo. Alertas de difusão celular são recebidos em alguns locais para avisar você de situações de emergência. Apps maliciosos podem interferir no desempenho ou funcionamento de seu dispositivo quando uma difusão celular de emergência é recebida."</string>
<string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"ler feeds inscritos"</string>
<string name="permdesc_subscribedFeedsRead" msgid="5557058907906144505">"Permite que o app obtenha detalhes sobre os feeds sincronizados no momento."</string>
- <string name="permlab_sendSms" msgid="7544599214260982981">"enviar e ver mensagens SMS"</string>
+ <string name="permlab_sendSms" msgid="7544599214260982981">"envie e veja mensagens SMS"</string>
<string name="permdesc_sendSms" msgid="7094729298204937667">"Permite que o app envie mensagens SMS. Isso pode resultar em cobranças inesperadas. Apps maliciosos podem gerar custos através do envio de mensagens sem sua confirmação."</string>
<string name="permlab_readSms" msgid="8745086572213270480">"ler suas mensagens de texto (SMS ou MMS)"</string>
<string name="permdesc_readSms" product="tablet" msgid="2467981548684735522">"Permite que o app leia mensagens SMS armazenadas no tablet ou cartão SIM. Isso permite que o app leia todas as mensagens SMS, independentemente de seu conteúdo ou confidencialidade."</string>
@@ -1488,6 +1488,7 @@
<item quantity="other">Por %d horas</item>
</plurals>
<string name="zen_mode_until" msgid="7336308492289875088">"Até às <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
+ <string name="zen_mode_alarm" msgid="9128205721301330797">"Até <xliff:g id="FORMATTEDTIME">%1$s</xliff:g> (próximo alarme)"</string>
<string name="zen_mode_forever" msgid="7420011936770086993">"Até você desativar"</string>
<string name="zen_mode_forever_dnd" msgid="3792132696572189081">"Até que você desative \"Não perturbe\""</string>
<string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string>
diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml
index 5315a7d..609b980 100644
--- a/core/res/res/values-ro/strings.xml
+++ b/core/res/res/values-ro/strings.xml
@@ -45,12 +45,12 @@
<string name="defaultVoiceMailAlphaTag" msgid="2660020990097733077">"Mesaj vocal"</string>
<string name="defaultMsisdnAlphaTag" msgid="2850889754919584674">"MSISDN1"</string>
<string name="mmiError" msgid="5154499457739052907">"Problemă de conexiune sau cod MMI nevalid."</string>
- <string name="mmiFdnError" msgid="5224398216385316471">"Operaţia este limitată la numerele cu apelări restricţionate."</string>
+ <string name="mmiFdnError" msgid="5224398216385316471">"Operația este limitată la numerele cu apelări restricţionate."</string>
<string name="serviceEnabled" msgid="8147278346414714315">"Serviciul a fost activat."</string>
<string name="serviceEnabledFor" msgid="6856228140453471041">"Serviciul a fost activat pentru:"</string>
<string name="serviceDisabled" msgid="1937553226592516411">"Serviciul a fost dezactivat."</string>
<string name="serviceRegistered" msgid="6275019082598102493">"Înregistrarea a reuşit."</string>
- <string name="serviceErased" msgid="1288584695297200972">"Ștergerea a reuşit."</string>
+ <string name="serviceErased" msgid="1288584695297200972">"Ștergerea a reușit."</string>
<string name="passwordIncorrect" msgid="7612208839450128715">"Parolă incorectă."</string>
<string name="mmiComplete" msgid="8232527495411698359">"MMI finalizat."</string>
<string name="badPin" msgid="9015277645546710014">"Codul PIN vechi introdus nu este corect."</string>
@@ -59,7 +59,7 @@
<string name="invalidPin" msgid="3850018445187475377">"Introduceţi un cod PIN alcătuit din 4 până la 8 cifre."</string>
<string name="invalidPuk" msgid="8761456210898036513">"Introduceţi un cod PUK care să aibă 8 cifre sau mai mult."</string>
<string name="needPuk" msgid="919668385956251611">"Cardul SIM este blocat cu codul PUK. Introduceţi codul PUK pentru a-l debloca."</string>
- <string name="needPuk2" msgid="4526033371987193070">"Introduceţi codul PUK2 pentru a debloca cardul SIM."</string>
+ <string name="needPuk2" msgid="4526033371987193070">"Introduceți codul PUK2 pentru a debloca cardul SIM."</string>
<string name="enablePin" msgid="209412020907207950">"Operațiunea nu a reușit. Activați blocarea cardului SIM/RUIM."</string>
<plurals name="pinpuk_attempts" formatted="false" msgid="1251012001539225582">
<item quantity="few">V-au mai rămas <xliff:g id="NUMBER_1">%d</xliff:g> încercări până la blocarea cardului SIM.</item>
@@ -72,8 +72,8 @@
<string name="ClirMmi" msgid="7784673673446833091">"ID apelant"</string>
<string name="ColpMmi" msgid="3065121483740183974">"ID-ul liniei conectate"</string>
<string name="ColrMmi" msgid="4996540314421889589">"Restricționarea ID-ului liniei conectate"</string>
- <string name="CfMmi" msgid="5123218989141573515">"Redirecţionarea apelurilor"</string>
- <string name="CwMmi" msgid="9129678056795016867">"Apel în aşteptare"</string>
+ <string name="CfMmi" msgid="5123218989141573515">"Redirecționarea apelurilor"</string>
+ <string name="CwMmi" msgid="9129678056795016867">"Apel în așteptare"</string>
<string name="BaMmi" msgid="455193067926770581">"Blocarea apelurilor"</string>
<string name="PwdMmi" msgid="7043715687905254199">"Modificare parolă"</string>
<string name="PinMmi" msgid="3113117780361190304">"Cod PIN modificat"</string>
@@ -84,14 +84,14 @@
<string name="CndMmi" msgid="3116446237081575808">"Se apelează serviciul de furnizare a numerelor"</string>
<string name="DndMmi" msgid="1265478932418334331">"Nu deranjaţi"</string>
<string name="CLIRDefaultOnNextCallOn" msgid="429415409145781923">"ID-ul apelantului este restricţionat în mod prestabilit. Apelul următor: restricţionat"</string>
- <string name="CLIRDefaultOnNextCallOff" msgid="3092918006077864624">"ID-ul apelantului este restricţionat în mod prestabilit. Apelul următor: nerestricţionat"</string>
- <string name="CLIRDefaultOffNextCallOn" msgid="6179425182856418465">"ID-ul apelantului este nerestricţionat în mod prestabilit. Apelul următor: Restricţionat."</string>
- <string name="CLIRDefaultOffNextCallOff" msgid="2567998633124408552">"ID-ul apelantului este nerestricţionat în mod prestabilit. Apelul următor: nerestricţionat"</string>
+ <string name="CLIRDefaultOnNextCallOff" msgid="3092918006077864624">"ID-ul apelantului este restricționat în mod prestabilit. Apelul următor: nerestricționat"</string>
+ <string name="CLIRDefaultOffNextCallOn" msgid="6179425182856418465">"ID-ul apelantului este nerestricționat în mod prestabilit. Apelul următor: Restricționat."</string>
+ <string name="CLIRDefaultOffNextCallOff" msgid="2567998633124408552">"ID-ul apelantului este nerestricționat în mod prestabilit. Apelul următor: nerestricționat"</string>
<string name="serviceNotProvisioned" msgid="8614830180508686666">"Nu se asigură accesul la acest serviciu."</string>
- <string name="CLIRPermanent" msgid="3377371145926835671">"Nu puteţi să modificaţi setarea pentru ID-ul apelantului."</string>
- <string name="RestrictedChangedTitle" msgid="5592189398956187498">"Acces restricţionat modificat"</string>
+ <string name="CLIRPermanent" msgid="3377371145926835671">"Nu puteți să modificaţi setarea pentru ID-ul apelantului."</string>
+ <string name="RestrictedChangedTitle" msgid="5592189398956187498">"Acces restricționat modificat"</string>
<string name="RestrictedOnData" msgid="8653794784690065540">"Serviciul de date este blocat."</string>
- <string name="RestrictedOnEmergency" msgid="6581163779072833665">"Serviciul de urgenţă este blocat."</string>
+ <string name="RestrictedOnEmergency" msgid="6581163779072833665">"Serviciul de urgență este blocat."</string>
<string name="RestrictedOnNormal" msgid="4953867011389750673">"Serviciul de voce este blocat."</string>
<string name="RestrictedOnAllVoice" msgid="3396963652108151260">"Toate serviciile de voce sunt blocate."</string>
<string name="RestrictedOnSms" msgid="8314352327461638897">"Serviciul SMS este blocat."</string>
@@ -135,15 +135,15 @@
<string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Se preferă conexiunea Wi-Fi"</string>
<string name="wfc_mode_cellular_preferred_summary" msgid="5920549484600758786">"Se preferă conexiunea mobilă"</string>
<string name="wfc_mode_wifi_only_summary" msgid="2379919155237869320">"Numai Wi-Fi"</string>
- <string name="cfTemplateNotForwarded" msgid="1683685883841272560">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: neredirecţionată"</string>
+ <string name="cfTemplateNotForwarded" msgid="1683685883841272560">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: neredirecționată"</string>
<string name="cfTemplateForwarded" msgid="1302922117498590521">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g>"</string>
<string name="cfTemplateForwardedTime" msgid="9206251736527085256">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g> după <xliff:g id="TIME_DELAY">{2}</xliff:g> (de) secunde"</string>
<string name="cfTemplateRegistered" msgid="5073237827620166285">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: neredirecţionat"</string>
<string name="cfTemplateRegisteredTime" msgid="6781621964320635172">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: neredirecţionat"</string>
- <string name="fcComplete" msgid="3118848230966886575">"Cod de funcţie complet."</string>
- <string name="fcError" msgid="3327560126588500777">"Problemă de conectare sau cod de funcţie nevalid."</string>
+ <string name="fcComplete" msgid="3118848230966886575">"Cod de funcție complet."</string>
+ <string name="fcError" msgid="3327560126588500777">"Problemă de conectare sau cod de funcție nevalid."</string>
<string name="httpErrorOk" msgid="1191919378083472204">"OK"</string>
- <string name="httpError" msgid="7956392511146698522">"A apărut o eroare de reţea."</string>
+ <string name="httpError" msgid="7956392511146698522">"A apărut o eroare de rețea."</string>
<string name="httpErrorLookup" msgid="4711687456111963163">"Nu s-a putut găsi adresa URL."</string>
<string name="httpErrorUnsupportedAuthScheme" msgid="6299980280442076799">"Schema de autentificare a site-ului nu este acceptată."</string>
<string name="httpErrorAuth" msgid="1435065629438044534">"Nu s-a realizat autentificarea."</string>
@@ -151,7 +151,7 @@
<string name="httpErrorConnect" msgid="8714273236364640549">"Nu s-a putut stabili conexiunea cu serverul."</string>
<string name="httpErrorIO" msgid="2340558197489302188">"Nu s-a putut efectua comunicarea cu serverul. Încercați din nou mai târziu."</string>
<string name="httpErrorTimeout" msgid="4743403703762883954">"Conexiunea la server a expirat."</string>
- <string name="httpErrorRedirectLoop" msgid="8679596090392779516">"Pagina conţine prea multe redirecţionări de server."</string>
+ <string name="httpErrorRedirectLoop" msgid="8679596090392779516">"Pagina conține prea multe redirecționări de server."</string>
<string name="httpErrorUnsupportedScheme" msgid="5015730812906192208">"Protocolul nu este acceptat."</string>
<string name="httpErrorFailedSslHandshake" msgid="96549606000658641">"Nu s-a putut stabili o conexiune securizată."</string>
<string name="httpErrorBadUrl" msgid="3636929722728881972">"Pagina nu a putut fi deschisă, deoarece adresa URL nu este validă."</string>
@@ -162,10 +162,10 @@
<string name="contentServiceSync" msgid="8353523060269335667">"Sincronizare"</string>
<string name="contentServiceSyncNotificationTitle" msgid="397743349191901458">"Sincronizare"</string>
<string name="contentServiceTooManyDeletesNotificationDesc" msgid="8100981435080696431">"Prea multe ştergeri <xliff:g id="CONTENT_TYPE">%s</xliff:g>."</string>
- <string name="low_memory" product="tablet" msgid="6494019234102154896">"Stocarea pe tabletă este plină. Ștergeţi câteva fişiere pentru a elibera spaţiu."</string>
+ <string name="low_memory" product="tablet" msgid="6494019234102154896">"Stocarea pe tabletă este plină. Ștergeți câteva fișiere pentru a elibera spaţiu."</string>
<string name="low_memory" product="watch" msgid="4415914910770005166">"Spațiul de stocare de pe ceas este plin! Ștergeți câteva fișiere pentru a elibera spațiu."</string>
<string name="low_memory" product="tv" msgid="516619861191025923">"Spațiul de stocare al televizorului este plin. Ștergeți câteva fișiere pentru a elibera spațiu."</string>
- <string name="low_memory" product="default" msgid="3475999286680000541">"Stocarea pe telefon este plină. Ștergeţi câteva fişiere pentru a elibera spaţiu."</string>
+ <string name="low_memory" product="default" msgid="3475999286680000541">"Stocarea pe telefon este plină. Ștergeți câteva fișiere pentru a elibera spaţiu."</string>
<string name="ssl_ca_cert_warning" msgid="5848402127455021714">"Rețeaua poate fi monitorizată"</string>
<string name="ssl_ca_cert_noti_by_unknown" msgid="4475437862189850602">"De o terță parte necunoscută"</string>
<string name="ssl_ca_cert_noti_by_administrator" msgid="550758088185764312">"De administratorul profilului de serviciu"</string>
@@ -180,9 +180,9 @@
<string name="power_dialog" product="tablet" msgid="8545351420865202853">"Opţiuni tablet PC"</string>
<string name="power_dialog" product="tv" msgid="6153888706430556356">"Opțiuni TV"</string>
<string name="power_dialog" product="default" msgid="1319919075463988638">"Opţiuni telefon"</string>
- <string name="silent_mode" msgid="7167703389802618663">"Mod Silenţios"</string>
- <string name="turn_on_radio" msgid="3912793092339962371">"Activați funcţia wireless"</string>
- <string name="turn_off_radio" msgid="8198784949987062346">"Dezactivați funcţia wireless"</string>
+ <string name="silent_mode" msgid="7167703389802618663">"Mod Silențios"</string>
+ <string name="turn_on_radio" msgid="3912793092339962371">"Activați funcția wireless"</string>
+ <string name="turn_off_radio" msgid="8198784949987062346">"Dezactivați funcția wireless"</string>
<string name="screen_lock" msgid="799094655496098153">"Blocați ecranul"</string>
<string name="power_off" msgid="4266614107412865048">"Opriți alimentarea"</string>
<string name="silent_mode_silent" msgid="319298163018473078">"Sonerie dezactivată"</string>
@@ -199,20 +199,20 @@
<string name="shutdown_confirm" product="tv" msgid="476672373995075359">"Televizorul se va închide."</string>
<string name="shutdown_confirm" product="watch" msgid="3490275567476369184">"Ceasul dvs. se va închide."</string>
<string name="shutdown_confirm" product="default" msgid="649792175242821353">"Telefonul dvs. se va închide."</string>
- <string name="shutdown_confirm_question" msgid="2906544768881136183">"Doriţi să închideţi?"</string>
+ <string name="shutdown_confirm_question" msgid="2906544768881136183">"Doriți să închideţi?"</string>
<string name="reboot_safemode_title" msgid="7054509914500140361">"Reporniţi în modul sigur"</string>
- <string name="reboot_safemode_confirm" msgid="55293944502784668">"Doriţi să reporniţi în modul sigur? Astfel vor fi dezactivate toate aplicațiile terţă parte pe care le-aţi instalat. Acestea vor fi restabilite când reporniţi din nou."</string>
+ <string name="reboot_safemode_confirm" msgid="55293944502784668">"Doriți să reporniţi în modul sigur? Astfel vor fi dezactivate toate aplicațiile terţă parte pe care le-ați instalat. Acestea vor fi restabilite când reporniţi din nou."</string>
<string name="recent_tasks_title" msgid="3691764623638127888">"Recente"</string>
<string name="no_recent_tasks" msgid="8794906658732193473">"Nu există aplicații recente."</string>
<string name="global_actions" product="tablet" msgid="408477140088053665">"Opţiuni tablet PC"</string>
<string name="global_actions" product="tv" msgid="7240386462508182976">"Opțiuni TV"</string>
- <string name="global_actions" product="default" msgid="2406416831541615258">"Opţiuni telefon"</string>
+ <string name="global_actions" product="default" msgid="2406416831541615258">"Opțiuni telefon"</string>
<string name="global_action_lock" msgid="2844945191792119712">"Blocați ecranul"</string>
<string name="global_action_power_off" msgid="4471879440839879722">"Opriți alimentarea"</string>
<string name="global_action_bug_report" msgid="7934010578922304799">"Raport despre erori"</string>
- <string name="bugreport_title" msgid="2667494803742548533">"Executaţi un raport despre erori"</string>
- <string name="bugreport_message" msgid="398447048750350456">"Acest raport va colecta informaţii despre starea actuală a dispozitivului, pentru a le trimite într-un e-mail. Aveți răbdare după pornirea raportului despre erori până când va fi gata de trimis."</string>
- <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"Mod Silenţios"</string>
+ <string name="bugreport_title" msgid="2667494803742548533">"Executați un raport despre erori"</string>
+ <string name="bugreport_message" msgid="398447048750350456">"Acest raport va colecta informații despre starea actuală a dispozitivului, pentru a le trimite într-un e-mail. Aveți răbdare după pornirea raportului despre erori până când va fi gata de trimis."</string>
+ <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"Mod Silențios"</string>
<string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"Sunetul este DEZACTIVAT"</string>
<string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"Sunetul este ACTIVAT"</string>
<string name="global_actions_toggle_airplane_mode" msgid="5884330306926307456">"Mod Avion"</string>
@@ -232,19 +232,19 @@
<string name="permgrouplab_location" msgid="7275582855722310164">"Locație"</string>
<string name="permgroupdesc_location" msgid="1346617465127855033">"acceseze locația acestui dispozitiv"</string>
<string name="permgrouplab_calendar" msgid="5863508437783683902">"Calendar"</string>
- <string name="permgroupdesc_calendar" msgid="3889615280211184106">"accesează calendarul"</string>
+ <string name="permgroupdesc_calendar" msgid="3889615280211184106">"acceseze calendarul"</string>
<string name="permgrouplab_sms" msgid="228308803364967808">"SMS"</string>
- <string name="permgroupdesc_sms" msgid="4656988620100940350">"trimite și vede mesajele SMS"</string>
+ <string name="permgroupdesc_sms" msgid="4656988620100940350">"trimită și să vadă mesajele SMS"</string>
<string name="permgrouplab_storage" msgid="1971118770546336966">"Stocare"</string>
<string name="permgroupdesc_storage" msgid="637758554581589203">"acceseze fotografiile, conținutul media și fișierele de pe dispozitiv"</string>
<string name="permgrouplab_microphone" msgid="171539900250043464">"Microfonul"</string>
- <string name="permgroupdesc_microphone" msgid="4988812113943554584">"înregistreze conținut audio"</string>
+ <string name="permgroupdesc_microphone" msgid="4988812113943554584">"înregistreze sunet"</string>
<string name="permgrouplab_camera" msgid="4820372495894586615">"Camera foto"</string>
- <string name="permgroupdesc_camera" msgid="3250611594678347720">"fotografieze și să înregistreze videoclipuri"</string>
+ <string name="permgroupdesc_camera" msgid="3250611594678347720">"fotografieze și să înregistreze imagini"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"Telefon"</string>
<string name="permgroupdesc_phone" msgid="6234224354060641055">"inițieze și să gestioneze apeluri telefonice"</string>
<string name="permgrouplab_sensors" msgid="416037179223226722">"Senzori corporali"</string>
- <string name="permgroupdesc_sensors" msgid="7147968539346634043">"accesează datele înregistrate de senzori despre semnele vitale"</string>
+ <string name="permgroupdesc_sensors" msgid="7147968539346634043">"acceseze datele de la senzori despre semnele vitale"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Recuperează conținutul ferestrei"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Inspectează conținutul unei ferestre cu care interacționați."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Activează funcția Explorați prin atingere"</string>
@@ -266,23 +266,23 @@
<string name="permlab_processOutgoingCalls" msgid="3906007831192990946">"redirecţionează apelurile efectuate"</string>
<string name="permdesc_processOutgoingCalls" msgid="5156385005547315876">"Permite aplicației să vadă numărul format în timpul unui apel de ieșire, cu opțiunea de a redirecționa apelul către un alt număr sau de a întrerupe apelul."</string>
<string name="permlab_receiveSms" msgid="8673471768947895082">"primeşte mesaje text (SMS)"</string>
- <string name="permdesc_receiveSms" msgid="6424387754228766939">"Permite aplicației să primească și să proceseze mesaje SMS. Acest lucru înseamnă că aplicația ar putea monitoriza sau şterge mesajele trimise pe dispozitivul dvs. fără a vi le arăta."</string>
+ <string name="permdesc_receiveSms" msgid="6424387754228766939">"Permite aplicației să primească și să proceseze mesaje SMS. Acest lucru înseamnă că aplicația ar putea monitoriza sau șterge mesajele trimise pe dispozitivul dvs. fără a vi le arăta."</string>
<string name="permlab_receiveMms" msgid="1821317344668257098">"primeşte mesaje text (MMS)"</string>
- <string name="permdesc_receiveMms" msgid="533019437263212260">"Permite aplicației să primească și să proceseze mesaje MMS. Acest lucru înseamnă că aplicația ar putea monitoriza sau şterge mesajele trimise pe dispozitivul dvs. fără a vi le arăta."</string>
+ <string name="permdesc_receiveMms" msgid="533019437263212260">"Permite aplicației să primească și să proceseze mesaje MMS. Acest lucru înseamnă că aplicația ar putea monitoriza sau șterge mesajele trimise pe dispozitivul dvs. fără a vi le arăta."</string>
<string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"citeşte mesajele cu transmisie celulară"</string>
- <string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"Permite aplicației să citească mesajele primite prin transmisie celulară de dispozitivul dvs. Alertele cu transmisie celulară sunt difuzate în unele locaţii pentru a vă avertiza cu privire la situaţiile de urgenţă. Aplicaţiile rău intenţionate pot afecta performanţa sau funcţionarea dispozitivului dvs. când este primită o transmisie celulară de urgenţă."</string>
+ <string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"Permite aplicației să citească mesajele primite prin transmisie celulară de dispozitivul dvs. Alertele cu transmisie celulară sunt difuzate în unele locații pentru a vă avertiza cu privire la situațiile de urgenţă. Aplicaţiile rău intenţionate pot afecta performanța sau funcționarea dispozitivului dvs. când este primită o transmisie celulară de urgenţă."</string>
<string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"citire feeduri abonat"</string>
<string name="permdesc_subscribedFeedsRead" msgid="5557058907906144505">"Permite aplicației să obţină detalii despre feedurile sincronizate în prezent."</string>
- <string name="permlab_sendSms" msgid="7544599214260982981">"trimite și vede mesajele SMS"</string>
- <string name="permdesc_sendSms" msgid="7094729298204937667">"Permite aplicației să trimită mesaje SMS, ceea ce ar putea determina apariţia unor taxe neaşteptate. Aplicaţiile rău intenţionate pot acumula costuri prin trimiterea mesajelor fără confirmarea dvs."</string>
+ <string name="permlab_sendSms" msgid="7544599214260982981">"trimită și să vadă mesajele SMS"</string>
+ <string name="permdesc_sendSms" msgid="7094729298204937667">"Permite aplicației să trimită mesaje SMS, ceea ce ar putea determina apariția unor taxe neaşteptate. Aplicaţiile rău intenţionate pot acumula costuri prin trimiterea mesajelor fără confirmarea dvs."</string>
<string name="permlab_readSms" msgid="8745086572213270480">"citeşte mesajele text (SMS sau MMS)"</string>
<string name="permdesc_readSms" product="tablet" msgid="2467981548684735522">"Permite aplicației să citească mesajele SMS stocate pe tabletă sau pe cardul SIM. În acest fel, aplicația poate citi toate mesajele SMS, indiferent de conţinutul sau de gradul de confidenţialitate al acestora."</string>
<string name="permdesc_readSms" product="tv" msgid="5102425513647038535">"Permite aplicației să citească mesajele SMS stocate pe televizor sau pe cardul SIM. Cu această permisiune, aplicația poate citi toate mesajele SMS, indiferent de conținutul sau de gradul de confidențialitate al acestora."</string>
<string name="permdesc_readSms" product="default" msgid="3695967533457240550">"Permite aplicației să citească mesajele SMS stocate pe telefon sau pe cardul SIM. În acest fel, aplicația poate citi toate mesajele SMS, indiferent de conţinutul sau de gradul de confidenţialitate al acestora."</string>
<string name="permlab_receiveWapPush" msgid="5991398711936590410">"primeşte mesaje text (WAP)"</string>
- <string name="permdesc_receiveWapPush" msgid="748232190220583385">"Permite aplicației să primească și să proceseze mesaje WAP. Această permisiune include capacitatea de a monitoriza sau şterge mesajele care v-au fost trimise fără a vi le arăta."</string>
+ <string name="permdesc_receiveWapPush" msgid="748232190220583385">"Permite aplicației să primească și să proceseze mesaje WAP. Această permisiune include capacitatea de a monitoriza sau șterge mesajele care v-au fost trimise fără a vi le arăta."</string>
<string name="permlab_getTasks" msgid="6466095396623933906">"preluare aplicații care rulează"</string>
- <string name="permdesc_getTasks" msgid="7454215995847658102">"Permite aplicației să preia informaţiile despre activităţile care rulează în prezent și care au rulat recent. În acest fel, aplicația poate descoperi informaţii despre aplicațiile care sunt utilizate pe dispozitiv."</string>
+ <string name="permdesc_getTasks" msgid="7454215995847658102">"Permite aplicației să preia informațiile despre activităţile care rulează în prezent și care au rulat recent. În acest fel, aplicația poate descoperi informații despre aplicațiile care sunt utilizate pe dispozitiv."</string>
<string name="permlab_manageProfileAndDeviceOwners" msgid="5979288447973722097">"Gestionează proprietarii de profiluri și proprietarul dispozitivului"</string>
<string name="permdesc_manageProfileAndDeviceOwners" msgid="106894851498657169">"Permite aplicațiilor să seteze proprietarii de profiluri și proprietarul dispozitivului."</string>
<string name="permlab_reorderTasks" msgid="2018575526934422779">"reordonare aplicații care rulează"</string>
@@ -292,11 +292,11 @@
<string name="permlab_killBackgroundProcesses" msgid="3914026687420177202">"închide alte aplicații"</string>
<string name="permdesc_killBackgroundProcesses" msgid="4593353235959733119">"Permite aplicației să oprească procesele derulate în fundal de alte aplicații. Acest lucru poate face ca respectivele aplicații să nu mai ruleze."</string>
<string name="permlab_systemAlertWindow" msgid="3543347980839518613">"suprapune elemente vizuale peste alte aplicații"</string>
- <string name="permdesc_systemAlertWindow" msgid="8584678381972820118">"Permite aplicației să suprapună elemente vizuale peste alte aplicații sau părţi ale interfeţei cu utilizatorul. Acestea pot interfera cu utilizarea de către dvs. a interfeţei în orice aplicație sau pot schimba ceea ce credeţi că vedeţi în alte aplicații."</string>
+ <string name="permdesc_systemAlertWindow" msgid="8584678381972820118">"Permite aplicației să suprapună elemente vizuale peste alte aplicații sau părți ale interfeței cu utilizatorul. Acestea pot interfera cu utilizarea de către dvs. a interfeței în orice aplicație sau pot schimba ceea ce credeți că vedeţi în alte aplicații."</string>
<string name="permlab_persistentActivity" msgid="8841113627955563938">"rulare continuă a aplicației"</string>
- <string name="permdesc_persistentActivity" product="tablet" msgid="8525189272329086137">"Permite aplicației să declare persistente în memorie anumite părţi ale sale. Acest lucru poate limita memoria disponibilă pentru alte aplicații și poate încetini funcţionarea tabletei."</string>
+ <string name="permdesc_persistentActivity" product="tablet" msgid="8525189272329086137">"Permite aplicației să declare persistente în memorie anumite părți ale sale. Acest lucru poate limita memoria disponibilă pentru alte aplicații și poate încetini funcționarea tabletei."</string>
<string name="permdesc_persistentActivity" product="tv" msgid="5086862529499103587">"Permite aplicației să declare persistente în memorie anumite părți ale sale. Acest lucru poate limita memoria disponibilă pentru alte aplicații și poate încetini funcționarea televizorului."</string>
- <string name="permdesc_persistentActivity" product="default" msgid="4384760047508278272">"Permite aplicației să declare persistente în memorie anumite părţi ale sale. Acest lucru poate limita memoria disponibilă pentru alte aplicații și poate încetini funcţionarea telefonului."</string>
+ <string name="permdesc_persistentActivity" product="default" msgid="4384760047508278272">"Permite aplicației să declare persistente în memorie anumite părți ale sale. Acest lucru poate limita memoria disponibilă pentru alte aplicații și poate încetini funcționarea telefonului."</string>
<string name="permlab_getPackageSize" msgid="7472921768357981986">"măsurare spaţiu de stocare al aplicației"</string>
<string name="permdesc_getPackageSize" msgid="3921068154420738296">"Permite aplicației să preia dimensiunile codului, ale datelor și ale memoriei cache"</string>
<string name="permlab_writeSettings" msgid="2226195290955224730">"modifică setări de sistem"</string>
@@ -306,44 +306,44 @@
<string name="permdesc_receiveBootCompleted" product="tv" msgid="4525890122209673621">"Permite aplicației să pornească imediat ce s-a terminat încărcarea sistemului. Din acest motiv, pornirea televizorului poate dura mai mult timp, iar funcționarea continuă a aplicației poate încetini televizorul."</string>
<string name="permdesc_receiveBootCompleted" product="default" msgid="513950589102617504">"Permite aplicației să pornească imediat ce s-a terminat încărcarea sistemului. Din acest motiv, pornirea telefonului poate dura mai mult timp, iar rularea continuă a aplicației poate încetini dispozitivul."</string>
<string name="permlab_broadcastSticky" msgid="7919126372606881614">"trimitere mesaj difuzat persistent"</string>
- <string name="permdesc_broadcastSticky" product="tablet" msgid="7749760494399915651">"Permite aplicației să trimită mesaje difuzate persistente, care se păstrează după terminarea difuzării mesajului. Utilizarea excesivă a acestei funcţii poate să încetinească sau să destabilizeze tableta, determinând-o să utilizeze prea multă memorie."</string>
+ <string name="permdesc_broadcastSticky" product="tablet" msgid="7749760494399915651">"Permite aplicației să trimită mesaje difuzate persistente, care se păstrează după terminarea difuzării mesajului. Utilizarea excesivă a acestei funcții poate să încetinească sau să destabilizeze tableta, determinând-o să utilizeze prea multă memorie."</string>
<string name="permdesc_broadcastSticky" product="tv" msgid="6839285697565389467">"Permite aplicației să trimită mesaje difuzate persistente, care se păstrează după terminarea difuzării mesajului. Utilizarea excesivă a acestei funcții poate să încetinească sau să destabilizeze televizorul, determinându-l să utilizeze prea multă memorie."</string>
- <string name="permdesc_broadcastSticky" product="default" msgid="2825803764232445091">"Permite aplicației să trimită mesaje difuzate persistente, care se păstrează după terminarea difuzării mesajului. Utilizarea excesivă a acestei funcţii poate să încetinească sau să destabilizeze telefonul, determinându-l să utilizeze prea multă memorie."</string>
+ <string name="permdesc_broadcastSticky" product="default" msgid="2825803764232445091">"Permite aplicației să trimită mesaje difuzate persistente, care se păstrează după terminarea difuzării mesajului. Utilizarea excesivă a acestei funcții poate să încetinească sau să destabilizeze telefonul, determinându-l să utilizeze prea multă memorie."</string>
<string name="permlab_readContacts" msgid="8348481131899886131">"citeşte agenda"</string>
- <string name="permdesc_readContacts" product="tablet" msgid="5294866856941149639">"Permite aplicației să citească datele despre persoanele din agenda stocată pe tabletă, inclusiv frecvenţa cu care aţi apelat, aţi trimis e-mailuri sau aţi comunicat în alte moduri cu anumite persoane. Cu această permisiune aplicația salvează datele dvs. de contact, iar aplicațiile rău intenţionate pot distribui datele de contact fără ştirea dvs."</string>
+ <string name="permdesc_readContacts" product="tablet" msgid="5294866856941149639">"Permite aplicației să citească datele despre persoanele din agenda stocată pe tabletă, inclusiv frecvența cu care aţi apelat, aţi trimis e-mailuri sau aţi comunicat în alte moduri cu anumite persoane. Cu această permisiune aplicația salvează datele dvs. de contact, iar aplicațiile rău intenţionate pot distribui datele de contact fără știrea dvs."</string>
<string name="permdesc_readContacts" product="tv" msgid="1839238344654834087">"Permite aplicației să citească datele despre persoanele de contact salvate pe televizor, inclusiv frecvența cu care ați apelat, ați trimis e-mailuri sau ați comunicat în alte moduri cu anumite persoane. Cu această permisiune, aplicațiile pot salva datele de contact, iar aplicațiile rău-intenționate pot permite accesul la datele de contact fără cunoștința dvs."</string>
- <string name="permdesc_readContacts" product="default" msgid="8440654152457300662">"Permite aplicației să citească datele despre persoanele din agenda stocată pe telefon, inclusiv frecvenţa cu care aţi apelat, aţi trimis e-mailuri sau aţi comunicat în alte moduri cu anumite persoane. Cu această permisiune aplicația salvează datele dvs. de contact, iar aplicațiile rău intenţionate pot distribui datele de contact fără ştirea dvs."</string>
+ <string name="permdesc_readContacts" product="default" msgid="8440654152457300662">"Permite aplicației să citească datele despre persoanele din agenda stocată pe telefon, inclusiv frecvența cu care aţi apelat, aţi trimis e-mailuri sau aţi comunicat în alte moduri cu anumite persoane. Cu această permisiune aplicația salvează datele dvs. de contact, iar aplicațiile rău intenţionate pot distribui datele de contact fără știrea dvs."</string>
<string name="permlab_writeContacts" msgid="5107492086416793544">"modifică agenda"</string>
- <string name="permdesc_writeContacts" product="tablet" msgid="897243932521953602">"Permite aplicației să modifice datele despre persoanele din agenda stocată pe tabletă, inclusiv frecvenţa cu care aţi apelat, aţi trimis e-mailuri sau aţi comunicat în alte moduri cu anumite persoane din agendă. Cu această permisiune aplicația poate şterge datele de contact."</string>
+ <string name="permdesc_writeContacts" product="tablet" msgid="897243932521953602">"Permite aplicației să modifice datele despre persoanele din agenda stocată pe tabletă, inclusiv frecvența cu care aţi apelat, aţi trimis e-mailuri sau aţi comunicat în alte moduri cu anumite persoane din agendă. Cu această permisiune aplicația poate șterge datele de contact."</string>
<string name="permdesc_writeContacts" product="tv" msgid="5438230957000018959">"Permite aplicației să modifice datele despre persoanele de contact salvate pe televizor, inclusiv frecvența cu care ați apelat, ați trimis e-mailuri sau ați comunicat în alte moduri cu anumite persoane de contact. Cu această permisiune, aplicația poate șterge datele de contact."</string>
- <string name="permdesc_writeContacts" product="default" msgid="589869224625163558">"Permite aplicației să modifice datele despre persoanele din agenda stocată pe telefon, inclusiv frecvenţa cu care aţi apelat, aţi trimis e-mailuri sau aţi comunicat în alte moduri cu anumite persoane din agendă. Cu această permisiune aplicația poate şterge datele de contact."</string>
+ <string name="permdesc_writeContacts" product="default" msgid="589869224625163558">"Permite aplicației să modifice datele despre persoanele din agenda stocată pe telefon, inclusiv frecvența cu care aţi apelat, aţi trimis e-mailuri sau aţi comunicat în alte moduri cu anumite persoane din agendă. Cu această permisiune aplicația poate șterge datele de contact."</string>
<string name="permlab_readCallLog" msgid="3478133184624102739">"citeşte jurnalul de apeluri"</string>
- <string name="permdesc_readCallLog" product="tablet" msgid="3700645184870760285">"Permite aplicației să citească jurnalul de apeluri al tabletei, inclusiv datele despre apelurile primite și efectuate. Cu această permisiune aplicația salvează datele dvs. din jurnalul de apeluri, iar aplicațiile rău intenţionate pot distribui aceste date fără ştirea dvs."</string>
+ <string name="permdesc_readCallLog" product="tablet" msgid="3700645184870760285">"Permite aplicației să citească jurnalul de apeluri al tabletei, inclusiv datele despre apelurile primite și efectuate. Cu această permisiune aplicația salvează datele dvs. din jurnalul de apeluri, iar aplicațiile rău intenţionate pot distribui aceste date fără știrea dvs."</string>
<string name="permdesc_readCallLog" product="tv" msgid="5611770887047387926">"Permite aplicației să citească jurnalul de apeluri al televizorului, inclusiv datele despre apelurile primite și efectuate. Cu această permisiune, aplicațiile pot să salveze datele din jurnalul de apeluri, iar aplicațiile rău-intenționate pot permite accesul la datele din jurnalul de apeluri fără cunoștința dvs."</string>
- <string name="permdesc_readCallLog" product="default" msgid="5777725796813217244">"Permite aplicației să citească jurnalul de apeluri al telefonului, inclusiv datele despre apelurile primite și efectuate. Cu această permisiune aplicația salvează datele dvs. din jurnalul de apeluri, iar aplicațiile rău intenţionate pot distribui aceste date fără ştirea dvs."</string>
+ <string name="permdesc_readCallLog" product="default" msgid="5777725796813217244">"Permite aplicației să citească jurnalul de apeluri al telefonului, inclusiv datele despre apelurile primite și efectuate. Cu această permisiune aplicația salvează datele dvs. din jurnalul de apeluri, iar aplicațiile rău intenţionate pot distribui aceste date fără știrea dvs."</string>
<string name="permlab_writeCallLog" msgid="8552045664743499354">"scrie jurnalul de apeluri"</string>
- <string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"Permite aplicației să modifice jurnalul de apeluri al tabletei dvs., inclusiv datele despre apelurile primite sau efectuate. Aplicaţiile rău intenţionate pot utiliza această permisiune pentru a şterge sau pentru a modifica jurnalul dvs. de apeluri."</string>
+ <string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"Permite aplicației să modifice jurnalul de apeluri al tabletei dvs., inclusiv datele despre apelurile primite sau efectuate. Aplicaţiile rău intenţionate pot utiliza această permisiune pentru a șterge sau pentru a modifica jurnalul dvs. de apeluri."</string>
<string name="permdesc_writeCallLog" product="tv" msgid="4225034892248398019">"Permite aplicației să modifice jurnalul de apeluri al televizorului, inclusiv datele despre apelurile primite sau efectuate. Aplicațiile rău-intenționate pot utiliza această permisiune pentru a șterge sau pentru a modifica jurnalul de apeluri."</string>
- <string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"Permite aplicației să modifice jurnalul de apeluri al telefonului dvs., inclusiv datele despre apelurile primite sau efectuate. Aplicaţiile rău intenţionate pot utiliza această permisiune pentru a şterge sau pentru a modifica jurnalul dvs. de apeluri."</string>
+ <string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"Permite aplicației să modifice jurnalul de apeluri al telefonului dvs., inclusiv datele despre apelurile primite sau efectuate. Aplicaţiile rău intenţionate pot utiliza această permisiune pentru a șterge sau pentru a modifica jurnalul dvs. de apeluri."</string>
<string name="permlab_bodySensors" msgid="4871091374767171066">"senzori (ex.: senzori de ritm cardiac)"</string>
<string name="permdesc_bodySensors" product="default" msgid="4380015021754180431">"Permite aplicației să acceseze date de la senzorii care vă monitorizează starea fizică, cum ar fi ritmul cardiac."</string>
<string name="permlab_readCalendar" msgid="5972727560257612398">"citirea evenimentelor din calendar și a informaţiilor confidenţiale"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="4216462049057658723">"Permite aplicației să citească toate evenimentele din calendar stocate pe tabletă, inclusiv cele ale prietenilor sau colegilor. Acest lucru poate permite aplicației să distribuie sau să salveze datele din calendar, indiferent dacă acestea sunt confidenţiale sau sensibile."</string>
<string name="permdesc_readCalendar" product="tv" msgid="3191352452242394196">"Permite aplicației să citească toate evenimentele din calendar stocate pe televizor, inclusiv cele ale prietenilor sau colegilor. Cu această permisiune, aplicația poate să permită accesul la datele din calendar sau să le salveze, indiferent dacă acestea sunt confidențiale sau sensibile."</string>
<string name="permdesc_readCalendar" product="default" msgid="7434548682470851583">"Permite aplicației să citească toate evenimentele din calendar stocate pe telefon, inclusiv cele ale prietenilor sau colegilor. Acest lucru poate permite aplicației să distribuie sau să salveze datele din calendar, indiferent dacă acestea sunt confidenţiale sau sensibile."</string>
- <string name="permlab_writeCalendar" msgid="8438874755193825647">"adăugarea sau modificarea evenimentelor din calendar și trimiterea de e-mailuri invitaţilor fără ştirea proprietarului"</string>
- <string name="permdesc_writeCalendar" product="tablet" msgid="6679035520113668528">"Permite aplicației să adauge, să elimine și să modifice evenimentele pe care le puteţi modifica pe tabletă, inclusiv cele ale prietenilor sau colegilor dvs. În acest fel, aplicația poate trimite mesaje care par să vină de la proprietarii calendarelor sau să modifice evenimentele fără ştirea proprietarilor."</string>
+ <string name="permlab_writeCalendar" msgid="8438874755193825647">"adăugarea sau modificarea evenimentelor din calendar și trimiterea de e-mailuri invitaților fără știrea proprietarului"</string>
+ <string name="permdesc_writeCalendar" product="tablet" msgid="6679035520113668528">"Permite aplicației să adauge, să elimine și să modifice evenimentele pe care le puteți modifica pe tabletă, inclusiv cele ale prietenilor sau colegilor dvs. În acest fel, aplicația poate trimite mesaje care par să vină de la proprietarii calendarelor sau să modifice evenimentele fără știrea proprietarilor."</string>
<string name="permdesc_writeCalendar" product="tv" msgid="1273290605500902507">"Permite aplicației să adauge, să elimine și să modifice evenimentele pe care le puteți modifica pe televizor, inclusiv pe cele ale prietenilor sau ale colegilor. Cu această permisiune, aplicația poate să trimită mesaje care par că vin din partea proprietarilor calendarului sau să modifice evenimentele fără cunoștința acestora."</string>
- <string name="permdesc_writeCalendar" product="default" msgid="2324469496327249376">"Permite aplicației să adauge, să elimine și să modifice evenimentele pe care le puteţi modifica pe telefon, inclusiv cele ale prietenilor sau colegilor dvs. În acest fel, aplicația poate trimite mesaje care par să vină de la proprietarii calendarelor sau să modifice evenimentele fără ştirea proprietarilor."</string>
- <string name="permlab_accessLocationExtraCommands" msgid="2836308076720553837">"accesare comenzi suplimentare ale furnizorului locaţiei"</string>
+ <string name="permdesc_writeCalendar" product="default" msgid="2324469496327249376">"Permite aplicației să adauge, să elimine și să modifice evenimentele pe care le puteți modifica pe telefon, inclusiv cele ale prietenilor sau colegilor dvs. În acest fel, aplicația poate trimite mesaje care par să vină de la proprietarii calendarelor sau să modifice evenimentele fără știrea proprietarilor."</string>
+ <string name="permlab_accessLocationExtraCommands" msgid="2836308076720553837">"accesare comenzi suplimentare ale furnizorului locației"</string>
<string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"Permite aplicației să acceseze comenzi suplimentare pentru furnizorul locației. Aplicația ar putea să utilizeze această permisiune pentru a influența operațiile GPS sau ale altor surse de locații."</string>
- <string name="permlab_accessFineLocation" msgid="1191898061965273372">"locaţia exactă (bazată pe reţea și GPS)"</string>
- <string name="permdesc_accessFineLocation" msgid="5295047563564981250">"Permite aplicației să obţină locaţia dvs. exactă utilizând sistemul GPS (Global Positioning System) sau surse de localizare prin reţele, cum ar fi cele prin turn de celule și Wi-Fi. Pentru a fi utilizate de aplicație, aceste servicii de localizare trebuie să fie activate și disponibile pe dispozitivul dvs. Aplicaţiile pot utiliza această permisiune pentru a determina locaţia dvs. și pot să consume mai multă energie a bateriei."</string>
- <string name="permlab_accessCoarseLocation" msgid="4887895362354239628">"locaţia aproximativă (bazată pe reţea)"</string>
- <string name="permdesc_accessCoarseLocation" msgid="2538200184373302295">"Permite aplicației să obţină locaţia dvs. aproximativă. Această locaţie este dedusă de serviciile de localizare utilizând surse de localizare prin reţele, cum ar fi cele prin turn de celule și Wi-Fi. Pentru a fi utilizate de aplicație, aceste servicii de localizare trebuie să fie activate și disponibile pe dispozitivul dvs. Aplicaţiile pot utiliza această permisiune pentru a determina locaţia dvs. aproximativă."</string>
+ <string name="permlab_accessFineLocation" msgid="1191898061965273372">"locația exactă (bazată pe rețea și GPS)"</string>
+ <string name="permdesc_accessFineLocation" msgid="5295047563564981250">"Permite aplicației să obţină locația dvs. exactă utilizând sistemul GPS (Global Positioning System) sau surse de localizare prin rețele, cum ar fi cele prin turn de celule și Wi-Fi. Pentru a fi utilizate de aplicație, aceste servicii de localizare trebuie să fie activate și disponibile pe dispozitivul dvs. Aplicaţiile pot utiliza această permisiune pentru a determina locația dvs. și pot să consume mai multă energie a bateriei."</string>
+ <string name="permlab_accessCoarseLocation" msgid="4887895362354239628">"locația aproximativă (bazată pe rețea)"</string>
+ <string name="permdesc_accessCoarseLocation" msgid="2538200184373302295">"Permite aplicației să obţină locația dvs. aproximativă. Această locație este dedusă de serviciile de localizare utilizând surse de localizare prin rețele, cum ar fi cele prin turn de celule și Wi-Fi. Pentru a fi utilizate de aplicație, aceste servicii de localizare trebuie să fie activate și disponibile pe dispozitivul dvs. Aplicaţiile pot utiliza această permisiune pentru a determina locația dvs. aproximativă."</string>
<string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"modificare setări audio"</string>
<string name="permdesc_modifyAudioSettings" msgid="3522565366806248517">"Permite aplicației să modifice setările audio globale, cum ar fi volumul și difuzorul care este utilizat pentru ieșire."</string>
- <string name="permlab_recordAudio" msgid="3876049771427466323">"înregistrare audio"</string>
+ <string name="permlab_recordAudio" msgid="3876049771427466323">"înregistreze sunet"</string>
<string name="permdesc_recordAudio" msgid="4906839301087980680">"Permite aplicației să efectueze înregistrări audio cu ajutorul microfonului. Cu această permisiune aplicația efectuează oricând înregistrări audio fără confirmare."</string>
<string name="permlab_sim_communication" msgid="1180265879464893029">"comunicare cu cardul SIM"</string>
<string name="permdesc_sim_communication" msgid="5725159654279639498">"Permite aplicației să trimită comenzi pe cardul SIM. Această permisiune este foarte periculoasă."</string>
@@ -354,11 +354,11 @@
<string name="permlab_flashlight" msgid="2155920810121984215">"control lanternă"</string>
<string name="permdesc_flashlight" msgid="6522284794568368310">"Permite aplicației să controleze lanterna."</string>
<string name="permlab_callPhone" msgid="3925836347681847954">"apelare directă numere de telefon"</string>
- <string name="permdesc_callPhone" msgid="3740797576113760827">"Permite aplicației să apeleze numere de telefon fără intervenţia dvs. Acest lucru poate determina apariţia unor taxe sau a unor apeluri neaşteptate. Cu această permisiune aplicația nu poate apela numerele de urgenţă. Aplicaţiile rău intenţionate pot acumula costuri prin efectuarea unor apeluri fără confirmare."</string>
+ <string name="permdesc_callPhone" msgid="3740797576113760827">"Permite aplicației să apeleze numere de telefon fără intervenţia dvs. Acest lucru poate determina apariția unor taxe sau a unor apeluri neaşteptate. Cu această permisiune aplicația nu poate apela numerele de urgenţă. Aplicaţiile rău intenţionate pot acumula costuri prin efectuarea unor apeluri fără confirmare."</string>
<string name="permlab_accessImsCallService" msgid="3574943847181793918">"accesează serviciul de apelare IMS"</string>
<string name="permdesc_accessImsCallService" msgid="8992884015198298775">"Permite aplicației să folosească serviciul IMS pentru apeluri, fără intervenția dvs."</string>
<string name="permlab_readPhoneState" msgid="9178228524507610486">"citeşte starea și identitatea telefonului"</string>
- <string name="permdesc_readPhoneState" msgid="1639212771826125528">"Permite aplicației să acceseze funcţiile de telefon ale dispozitivului. Cu această permisiune aplicația stabileşte numărul de telefon și ID-urile de dispozitiv, dacă un apel este activ, precum și numărul de la distanţă conectat printr-un apel."</string>
+ <string name="permdesc_readPhoneState" msgid="1639212771826125528">"Permite aplicației să acceseze funcţiile de telefon ale dispozitivului. Cu această permisiune aplicația stabilește numărul de telefon și ID-urile de dispozitiv, dacă un apel este activ, precum și numărul de la distanță conectat printr-un apel."</string>
<string name="permlab_wakeLock" product="tablet" msgid="1531731435011495015">"împiedicarea computerului tablet PC să intre în repaus"</string>
<string name="permlab_wakeLock" product="tv" msgid="2601193288949154131">"împiedică intrarea televizorului în stare de inactivitate"</string>
<string name="permlab_wakeLock" product="default" msgid="573480187941496130">"împiedicare intrare telefon în repaus"</string>
@@ -378,31 +378,31 @@
<string name="permdesc_setTimeZone" product="tv" msgid="888864653946175955">"Permite aplicației să modifice fusul orar al televizorului."</string>
<string name="permdesc_setTimeZone" product="default" msgid="4499943488436633398">"Permite aplicației să schimbe fusul orar al telefonului."</string>
<string name="permlab_getAccounts" msgid="1086795467760122114">"găseşte conturi pe dispozitiv"</string>
- <string name="permdesc_getAccounts" product="tablet" msgid="2741496534769660027">"Permite aplicației să obţină lista de conturi cunoscute de tabletă. Aceasta poate include conturile create de aplicațiile pe care le-aţi instalat."</string>
+ <string name="permdesc_getAccounts" product="tablet" msgid="2741496534769660027">"Permite aplicației să obţină lista de conturi cunoscute de tabletă. Aceasta poate include conturile create de aplicațiile pe care le-ați instalat."</string>
<string name="permdesc_getAccounts" product="tv" msgid="4190633395633907543">"Permite aplicației să obțină lista de conturi cunoscute de televizor. Aceasta poate include conturile create de aplicațiile pe care le-ați instalat."</string>
- <string name="permdesc_getAccounts" product="default" msgid="3448316822451807382">"Permite aplicației să obţină lista de conturi cunoscute de telefon. Aceasta poate include conturile create de aplicațiile pe care le-aţi instalat."</string>
- <string name="permlab_accessNetworkState" msgid="4951027964348974773">"vizualizează conexiunile la reţea"</string>
- <string name="permdesc_accessNetworkState" msgid="8318964424675960975">"Permite aplicației să vadă informaţiile despre conexiunile la reţea, cum ar fi reţelele existente și cele care sunt conectate."</string>
- <string name="permlab_createNetworkSockets" msgid="8018758136404323658">"acces deplin la reţea"</string>
- <string name="permdesc_createNetworkSockets" msgid="3403062187779724185">"Permite aplicației să creeze socluri de reţea și să utilizeze protocoale de reţea personalizate. Browserul și alte aplicații oferă mijloacele de trimitere a datelor pe internet, astfel încât această permisiune nu este necesară pentru trimiterea datelor pe internet."</string>
- <string name="permlab_changeNetworkState" msgid="958884291454327309">"modificare conectivitate în reţea"</string>
- <string name="permdesc_changeNetworkState" msgid="6789123912476416214">"Permite aplicației să modifice starea de conectivitate la reţea."</string>
+ <string name="permdesc_getAccounts" product="default" msgid="3448316822451807382">"Permite aplicației să obţină lista de conturi cunoscute de telefon. Aceasta poate include conturile create de aplicațiile pe care le-ați instalat."</string>
+ <string name="permlab_accessNetworkState" msgid="4951027964348974773">"vizualizează conexiunile la rețea"</string>
+ <string name="permdesc_accessNetworkState" msgid="8318964424675960975">"Permite aplicației să vadă informațiile despre conexiunile la rețea, cum ar fi reţelele existente și cele care sunt conectate."</string>
+ <string name="permlab_createNetworkSockets" msgid="8018758136404323658">"acces deplin la rețea"</string>
+ <string name="permdesc_createNetworkSockets" msgid="3403062187779724185">"Permite aplicației să creeze socluri de rețea și să utilizeze protocoale de rețea personalizate. Browserul și alte aplicații oferă mijloacele de trimitere a datelor pe internet, astfel încât această permisiune nu este necesară pentru trimiterea datelor pe internet."</string>
+ <string name="permlab_changeNetworkState" msgid="958884291454327309">"modificare conectivitate în rețea"</string>
+ <string name="permdesc_changeNetworkState" msgid="6789123912476416214">"Permite aplicației să modifice starea de conectivitate la rețea."</string>
<string name="permlab_changeTetherState" msgid="5952584964373017960">"modificare conectivitate tethering"</string>
- <string name="permdesc_changeTetherState" msgid="1524441344412319780">"Permite aplicației să modifice starea de conectivitate prin tethering la reţea."</string>
+ <string name="permdesc_changeTetherState" msgid="1524441344412319780">"Permite aplicației să modifice starea de conectivitate prin tethering la rețea."</string>
<string name="permlab_accessWifiState" msgid="5202012949247040011">"vizualizează conexiunile Wi-Fi"</string>
- <string name="permdesc_accessWifiState" msgid="5002798077387803726">"Permite aplicației să vadă informaţiile despre reţelele Wi-Fi, de ex. dacă o reţea Wi-Fi este activată, precum și numele dispozitivelor conectate la reţeaua Wi-Fi."</string>
+ <string name="permdesc_accessWifiState" msgid="5002798077387803726">"Permite aplicației să vadă informațiile despre reţelele Wi-Fi, de ex. dacă o rețea Wi-Fi este activată, precum și numele dispozitivelor conectate la rețeaua Wi-Fi."</string>
<string name="permlab_changeWifiState" msgid="6550641188749128035">"se conectează și se deconectează de la Wi-Fi"</string>
<string name="permdesc_changeWifiState" msgid="7137950297386127533">"Permite aplicației să se conecteze și să se deconecteze de la punctele de acces Wi-Fi, precum și să efectueze modificări în configuraţia dispozitivului pentru reţelele Wi-Fi."</string>
<string name="permlab_changeWifiMulticastState" msgid="1368253871483254784">"permitere recepţionare difuzare multiplă Wi-Fi"</string>
- <string name="permdesc_changeWifiMulticastState" product="tablet" msgid="7969774021256336548">"Permite aplicației să primească pachetele trimise către toate dispozitivele dintr-o reţea Wi-Fi, utilizând adrese cu difuzare multiplă, nu doar tableta dvs. Această funcţie utilizează mai multă energie decât modul fără difuzare multiplă."</string>
+ <string name="permdesc_changeWifiMulticastState" product="tablet" msgid="7969774021256336548">"Permite aplicației să primească pachetele trimise către toate dispozitivele dintr-o rețea Wi-Fi, utilizând adrese cu difuzare multiplă, nu doar tableta dvs. Această funcție utilizează mai multă energie decât modul fără difuzare multiplă."</string>
<string name="permdesc_changeWifiMulticastState" product="tv" msgid="9031975661145014160">"Permite aplicației să primească pachetele trimise către toate dispozitivele dintr-o rețea Wi-Fi, utilizând adrese cu difuzare multiplă, nu doar televizorul dvs. Această funcție utilizează mai multă energie decât modul fără difuzare multiplă."</string>
- <string name="permdesc_changeWifiMulticastState" product="default" msgid="6851949706025349926">"Permite aplicației să primească pachetele trimise către toate dispozitivele dintr-o reţea Wi-Fi, utilizând adrese cu difuzare multiplă, nu doar telefonul dvs. Această funcţie utilizează mai multă energie decât modul fără difuzare multiplă."</string>
+ <string name="permdesc_changeWifiMulticastState" product="default" msgid="6851949706025349926">"Permite aplicației să primească pachetele trimise către toate dispozitivele dintr-o rețea Wi-Fi, utilizând adrese cu difuzare multiplă, nu doar telefonul dvs. Această funcție utilizează mai multă energie decât modul fără difuzare multiplă."</string>
<string name="permlab_bluetoothAdmin" msgid="6006967373935926659">"accesează setările Bluetooth"</string>
- <string name="permdesc_bluetoothAdmin" product="tablet" msgid="6921177471748882137">"Permite aplicației să configureze tableta Bluetooth locală, să descopere și să se împerecheze cu dispozitive la distanţă."</string>
+ <string name="permdesc_bluetoothAdmin" product="tablet" msgid="6921177471748882137">"Permite aplicației să configureze tableta Bluetooth locală, să descopere și să se împerecheze cu dispozitive la distanță."</string>
<string name="permdesc_bluetoothAdmin" product="tv" msgid="3373125682645601429">"Permite aplicației să configureze televizorul Bluetooth local, precum și să descopere și să se asocieze cu dispozitive la distanță."</string>
- <string name="permdesc_bluetoothAdmin" product="default" msgid="8931682159331542137">"Permite aplicației să configureze telefonul Bluetooth local, să descopere și să se împerecheze cu dispozitive la distanţă."</string>
+ <string name="permdesc_bluetoothAdmin" product="default" msgid="8931682159331542137">"Permite aplicației să configureze telefonul Bluetooth local, să descopere și să se împerecheze cu dispozitive la distanță."</string>
<string name="permlab_accessWimaxState" msgid="4195907010610205703">"se conectează și se deconectează de la WiMAX"</string>
- <string name="permdesc_accessWimaxState" msgid="6360102877261978887">"Permite aplicației să stabilească dacă o reţea WiMAX este activată și să vadă informaţiile cu privire la toate reţelele WiMAX conectate."</string>
+ <string name="permdesc_accessWimaxState" msgid="6360102877261978887">"Permite aplicației să stabilească dacă o rețea WiMAX este activată și să vadă informațiile cu privire la toate reţelele WiMAX conectate."</string>
<string name="permlab_changeWimaxState" msgid="2405042267131496579">"Schimbaţi starea WiMAX"</string>
<string name="permdesc_changeWimaxState" product="tablet" msgid="3156456504084201805">"Permite aplicației să conecteze și să deconecteze tableta la și de la reţelele WiMAX."</string>
<string name="permdesc_changeWimaxState" product="tv" msgid="6022307083934827718">"Permite aplicației să conecteze și să deconecteze televizorul la și de la rețelele WiMAX."</string>
@@ -446,8 +446,8 @@
<string name="permlab_sdcardRead" product="default" msgid="2188156462934977940">"citeşte conţinutul cardului SD"</string>
<string name="permdesc_sdcardRead" product="nosdcard" msgid="3446988712598386079">"Permite aplic. citirea conținutului stoc. USB."</string>
<string name="permdesc_sdcardRead" product="default" msgid="2607362473654975411">"Permite aplicației citirea conținutul cardului SD."</string>
- <string name="permlab_sdcardWrite" product="nosdcard" msgid="8485979062254666748">"modifică sau şterge conţinutul stocării USB"</string>
- <string name="permlab_sdcardWrite" product="default" msgid="8805693630050458763">"modifică sau şterge conţinutul cardului SD"</string>
+ <string name="permlab_sdcardWrite" product="nosdcard" msgid="8485979062254666748">"modifică sau șterge conţinutul stocării USB"</string>
+ <string name="permlab_sdcardWrite" product="default" msgid="8805693630050458763">"modifică sau șterge conţinutul cardului SD"</string>
<string name="permdesc_sdcardWrite" product="nosdcard" msgid="6175406299445710888">"Permite scriere în stoc. USB."</string>
<string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"Permite aplicației să scrie pe cardul SD."</string>
<string name="permlab_use_sip" msgid="2052499390128979920">"efectuarea/primirea apelurilor SIP"</string>
@@ -464,12 +464,12 @@
<string name="permdesc_bind_connection_service" msgid="4008754499822478114">"Permite aplicației să interacționeze cu servicii de telefonie pentru a da / a primi apeluri."</string>
<string name="permlab_control_incall_experience" msgid="9061024437607777619">"oferă o experiență de utilizare în timpul unui apel"</string>
<string name="permdesc_control_incall_experience" msgid="915159066039828124">"Permite aplicației să ofere o experiență de utilizare în timpul unui apel."</string>
- <string name="permlab_readNetworkUsageHistory" msgid="7862593283611493232">"citeşte utilizarea statistică a reţelei"</string>
- <string name="permdesc_readNetworkUsageHistory" msgid="7689060749819126472">"Permite aplicației să citească utilizarea statistică a reţelei pentru anumite reţele și aplicații."</string>
- <string name="permlab_manageNetworkPolicy" msgid="2562053592339859990">"gestionează politica de reţea"</string>
- <string name="permdesc_manageNetworkPolicy" msgid="7537586771559370668">"Permite aplicației să gestioneze politicile de reţea și să definească regulile specifice aplicațiilor."</string>
- <string name="permlab_modifyNetworkAccounting" msgid="5088217309088729650">"modificaţi modul de calcul al utilizării reţelei"</string>
- <string name="permdesc_modifyNetworkAccounting" msgid="5443412866746198123">"Permite aplicației să modifice modul în care este calculată utilizarea reţelei pentru aplicații. Nu se utilizează de aplicațiile obişnuite."</string>
+ <string name="permlab_readNetworkUsageHistory" msgid="7862593283611493232">"citeşte utilizarea statistică a rețelei"</string>
+ <string name="permdesc_readNetworkUsageHistory" msgid="7689060749819126472">"Permite aplicației să citească utilizarea statistică a rețelei pentru anumite rețele și aplicații."</string>
+ <string name="permlab_manageNetworkPolicy" msgid="2562053592339859990">"gestionează politica de rețea"</string>
+ <string name="permdesc_manageNetworkPolicy" msgid="7537586771559370668">"Permite aplicației să gestioneze politicile de rețea și să definească regulile specifice aplicațiilor."</string>
+ <string name="permlab_modifyNetworkAccounting" msgid="5088217309088729650">"modificaţi modul de calcul al utilizării rețelei"</string>
+ <string name="permdesc_modifyNetworkAccounting" msgid="5443412866746198123">"Permite aplicației să modifice modul în care este calculată utilizarea rețelei pentru aplicații. Nu se utilizează de aplicațiile obişnuite."</string>
<string name="permlab_accessNotifications" msgid="7673416487873432268">"accesare notificări"</string>
<string name="permdesc_accessNotifications" msgid="458457742683431387">"Permite aplicației să recupereze, să examineze și să șteargă notificări, inclusiv pe cele postate de alte aplicații."</string>
<string name="permlab_bindNotificationListenerService" msgid="7057764742211656654">"conectare la un serviciu de citire a notificărilor"</string>
@@ -499,7 +499,7 @@
<string name="policylab_limitPassword" msgid="4497420728857585791">"Setați reguli pentru parolă"</string>
<string name="policydesc_limitPassword" msgid="2502021457917874968">"Stabiliți lungimea și tipul de caractere permise pentru parolele și codurile PIN de blocare a ecranului."</string>
<string name="policylab_watchLogin" msgid="914130646942199503">"Monitorizați încercările de deblocare a ecranului"</string>
- <string name="policydesc_watchLogin" product="tablet" msgid="3215729294215070072">"Monitorizaţi numărul de parole incorecte introduse la deblocarea ecranului și blocaţi tableta sau ştergeţi datele acesteia dacă sunt introduse prea multe parole incorecte."</string>
+ <string name="policydesc_watchLogin" product="tablet" msgid="3215729294215070072">"Monitorizați numărul de parole incorecte introduse la deblocarea ecranului și blocaţi tableta sau ștergeți datele acesteia dacă sunt introduse prea multe parole incorecte."</string>
<string name="policydesc_watchLogin" product="TV" msgid="2707817988309890256">"Monitorizați numărul de parole incorecte introduse la deblocarea ecranului și blocați televizorul sau ștergeți toate datele acestuia dacă sunt introduse prea multe parole incorecte."</string>
<string name="policydesc_watchLogin" product="default" msgid="5712323091846761073">"Monitorizați numărul de parole incorecte introduse la deblocarea ecranului și blocați telefonul sau ștergeți toate datele acestuia dacă sunt introduse prea multe parole incorecte."</string>
<string name="policydesc_watchLogin_secondaryUser" product="tablet" msgid="4280246270601044505">"Monitorizați numărul de parole incorecte introduse la deblocarea ecranului și blocați tableta sau ștergeți toate datele acestui utilizator dacă se introduc prea multe parole incorecte."</string>
@@ -510,9 +510,9 @@
<string name="policylab_forceLock" msgid="2274085384704248431">"Blocați ecranul"</string>
<string name="policydesc_forceLock" msgid="1141797588403827138">"Stabiliți modul și timpul în care se blochează ecranul."</string>
<string name="policylab_wipeData" msgid="3910545446758639713">"Ștergere integrală date"</string>
- <string name="policydesc_wipeData" product="tablet" msgid="4306184096067756876">"Ștergeţi datele de pe tabletă fără avertisment, efectuând resetarea configurării din fabrică."</string>
+ <string name="policydesc_wipeData" product="tablet" msgid="4306184096067756876">"Ștergeți datele de pe tabletă fără avertisment, efectuând resetarea configurării din fabrică."</string>
<string name="policydesc_wipeData" product="tv" msgid="5816221315214527028">"Ștergeți datele de pe televizor fără avertisment, prin revenirea la setările din fabrică."</string>
- <string name="policydesc_wipeData" product="default" msgid="5096895604574188391">"Ștergeţi datele din telefon fără avertisment, efectuând resetarea configurării din fabrică."</string>
+ <string name="policydesc_wipeData" product="default" msgid="5096895604574188391">"Ștergeți datele din telefon fără avertisment, efectuând resetarea configurării din fabrică."</string>
<string name="policylab_wipeData_secondaryUser" msgid="8362863289455531813">"Ștergeți datele utilizatorului"</string>
<string name="policydesc_wipeData_secondaryUser" product="tablet" msgid="6336255514635308054">"Ștergeți datele acestui utilizator de pe această tabletă fără avertisment."</string>
<string name="policydesc_wipeData_secondaryUser" product="tv" msgid="2086473496848351810">"Ștergeți datele acestui utilizator de pe acest televizor fără avertisment."</string>
@@ -635,7 +635,7 @@
<string name="relationTypeReferredBy" msgid="101573059844135524">"Denumit după"</string>
<string name="relationTypeRelative" msgid="1799819930085610271">"Rudă"</string>
<string name="relationTypeSister" msgid="1735983554479076481">"Soră"</string>
- <string name="relationTypeSpouse" msgid="394136939428698117">"Soţ/Soţie"</string>
+ <string name="relationTypeSpouse" msgid="394136939428698117">"Soț/Soție"</string>
<string name="sipAddressTypeCustom" msgid="2473580593111590945">"Personalizată"</string>
<string name="sipAddressTypeHome" msgid="6093598181069359295">"Ecran pornire"</string>
<string name="sipAddressTypeWork" msgid="6920725730797099047">"Serviciu"</string>
@@ -645,15 +645,15 @@
<string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"Introduceţi codul PUK și noul cod PIN"</string>
<string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"Codul PUK"</string>
<string name="keyguard_password_enter_pin_prompt" msgid="8027680321614196258">"Noul cod PIN"</string>
- <string name="keyguard_password_entry_touch_hint" msgid="7858547464982981384"><font size="17">"Atingeţi și introduceţi parola"</font></string>
+ <string name="keyguard_password_entry_touch_hint" msgid="7858547464982981384"><font size="17">"Atingeți și introduceţi parola"</font></string>
<string name="keyguard_password_enter_password_code" msgid="1054721668279049780">"Introduceţi parola pentru a debloca"</string>
<string name="keyguard_password_enter_pin_password_code" msgid="6391755146112503443">"Introduceţi codul PIN pentru a debloca"</string>
<string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"Cod PIN incorect."</string>
<string name="keyguard_label_text" msgid="861796461028298424">"Pentru a debloca, apăsaţi Meniu, apoi 0."</string>
- <string name="emergency_call_dialog_number_for_display" msgid="696192103195090970">"Număr de urgenţă"</string>
+ <string name="emergency_call_dialog_number_for_display" msgid="696192103195090970">"Număr de urgență"</string>
<string name="lockscreen_carrier_default" msgid="8963839242565653192">"Fără serviciu."</string>
<string name="lockscreen_screen_locked" msgid="7288443074806832904">"Ecranul este blocat."</string>
- <string name="lockscreen_instructions_when_pattern_enabled" msgid="46154051614126049">"Apăsaţi Meniu pentru a debloca sau pentru a efectua apeluri de urgenţă."</string>
+ <string name="lockscreen_instructions_when_pattern_enabled" msgid="46154051614126049">"Apăsați Meniu pentru a debloca sau pentru a efectua apeluri de urgență."</string>
<string name="lockscreen_instructions_when_pattern_disabled" msgid="686260028797158364">"Apăsaţi Meniu pentru deblocare."</string>
<string name="lockscreen_pattern_instructions" msgid="7478703254964810302">"Desenaţi modelul pentru a debloca"</string>
<string name="lockscreen_emergency_call" msgid="5298642613417801888">"Urgență"</string>
@@ -677,8 +677,8 @@
<string name="lockscreen_transport_stop_description" msgid="5907083260651210034">"Opriți"</string>
<string name="lockscreen_transport_rew_description" msgid="6944412838651990410">"Derulaţi"</string>
<string name="lockscreen_transport_ffw_description" msgid="42987149870928985">"Derulaţi rapid înainte"</string>
- <string name="emergency_calls_only" msgid="6733978304386365407">"Numai apeluri de urgenţă"</string>
- <string name="lockscreen_network_locked_message" msgid="143389224986028501">"Reţea blocată"</string>
+ <string name="emergency_calls_only" msgid="6733978304386365407">"Numai apeluri de urgență"</string>
+ <string name="lockscreen_network_locked_message" msgid="143389224986028501">"Rețea blocată"</string>
<string name="lockscreen_sim_puk_locked_message" msgid="7441797339976230">"Cardul SIM este blocat cu codul PUK."</string>
<string name="lockscreen_sim_puk_locked_instructions" msgid="8127916255245181063">"Consultaţi Ghidul de utilizare sau contactaţi Serviciul de relaţii cu clienţii."</string>
<string name="lockscreen_sim_locked_message" msgid="8066660129206001039">"Cardul SIM este blocat."</string>
@@ -696,27 +696,27 @@
<string name="lockscreen_failed_attempts_now_wiping" product="tv" msgid="3195755534096192191">"Ați efectuat <xliff:g id="NUMBER">%d</xliff:g> încercări incorecte de deblocare a televizorului. Televizorul va reveni acum la setările prestabilite din fabrică."</string>
<string name="lockscreen_failed_attempts_now_wiping" product="default" msgid="3025504721764922246">"Aţi efectuat <xliff:g id="NUMBER">%d</xliff:g> încercări incorecte de deblocare a telefonului. Acesta va fi acum resetat la setările prestabilite din fabrică."</string>
<string name="lockscreen_too_many_failed_attempts_countdown" msgid="6251480343394389665">"Încercați din nou peste <xliff:g id="NUMBER">%d</xliff:g> (de) secunde."</string>
- <string name="lockscreen_forgot_pattern_button_text" msgid="2626999449610695930">"Aţi uitat modelul?"</string>
+ <string name="lockscreen_forgot_pattern_button_text" msgid="2626999449610695930">"Ați uitat modelul?"</string>
<string name="lockscreen_glogin_forgot_pattern" msgid="2588521501166032747">"Deblocare cont"</string>
<string name="lockscreen_glogin_too_many_attempts" msgid="2751368605287288808">"Prea multe încercări de desenare a modelului"</string>
<string name="lockscreen_glogin_instructions" msgid="3931816256100707784">"Pentru a debloca, conectaţi-vă folosind Contul Google."</string>
<string name="lockscreen_glogin_username_hint" msgid="8846881424106484447">"Nume de utilizator (e-mail)"</string>
<string name="lockscreen_glogin_password_hint" msgid="5958028383954738528">"Parolă"</string>
- <string name="lockscreen_glogin_submit_button" msgid="7130893694795786300">"Conectaţi-vă"</string>
+ <string name="lockscreen_glogin_submit_button" msgid="7130893694795786300">"Conectați-vă"</string>
<string name="lockscreen_glogin_invalid_input" msgid="1364051473347485908">"Nume de utilizator sau parolă nevalide."</string>
- <string name="lockscreen_glogin_account_recovery_hint" msgid="1696924763690379073">"Aţi uitat numele de utilizator sau parola?\nAccesaţi "<b>"google.com/accounts/recovery"</b>"."</string>
+ <string name="lockscreen_glogin_account_recovery_hint" msgid="1696924763690379073">"Aţi uitat numele de utilizator sau parola?\nAccesați "<b>"google.com/accounts/recovery"</b>"."</string>
<string name="lockscreen_glogin_checking_password" msgid="7114627351286933867">"Se verifică..."</string>
<string name="lockscreen_unlock_label" msgid="737440483220667054">"Deblocaţi"</string>
<string name="lockscreen_sound_on_label" msgid="9068877576513425970">"Sunet activat"</string>
<string name="lockscreen_sound_off_label" msgid="996822825154319026">"Sunet dezactivat"</string>
<string name="lockscreen_access_pattern_start" msgid="3941045502933142847">"Desenarea modelului a început"</string>
- <string name="lockscreen_access_pattern_cleared" msgid="5583479721001639579">"Modelul a fost şters"</string>
+ <string name="lockscreen_access_pattern_cleared" msgid="5583479721001639579">"Modelul a fost șters"</string>
<string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"Celulă adăugată"</string>
<string name="lockscreen_access_pattern_cell_added_verbose" msgid="7264580781744026939">"Celula <xliff:g id="CELL_INDEX">%1$s</xliff:g> a fost adăugată"</string>
<string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"Modelul a fost desenat"</string>
<string name="lockscreen_access_pattern_area" msgid="400813207572953209">"Zonă model."</string>
<string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. Widget %2$d din %3$d."</string>
- <string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"Adăugaţi un widget."</string>
+ <string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"Adăugați un widget."</string>
<string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"Gol"</string>
<string name="keyguard_accessibility_unlock_area_expanded" msgid="2278106022311170299">"Zona de deblocare a fost extinsă."</string>
<string name="keyguard_accessibility_unlock_area_collapsed" msgid="6366992066936076396">"Zona de deblocare a fost restrânsă."</string>
@@ -747,16 +747,16 @@
<string name="hour_cap_ampm" msgid="2083465992940444366">"<xliff:g id="HOUR">%-l</xliff:g> <xliff:g id="AMPM">%p</xliff:g>"</string>
<string name="factorytest_failed" msgid="5410270329114212041">"Testarea de fabrică nu a reuşit"</string>
<string name="factorytest_not_system" msgid="4435201656767276723">"Acţiunea FACTORY_TEST este acceptată doar pentru pachetele instalate în /system/app."</string>
- <string name="factorytest_no_action" msgid="872991874799998561">"Nu s-a găsit niciun pachet care să ofere acţiunea FACTORY_TEST."</string>
- <string name="factorytest_reboot" msgid="6320168203050791643">"Reporniţi"</string>
+ <string name="factorytest_no_action" msgid="872991874799998561">"Nu s-a găsit niciun pachet care să ofere acțiunea FACTORY_TEST."</string>
+ <string name="factorytest_reboot" msgid="6320168203050791643">"Reporniți"</string>
<string name="js_dialog_title" msgid="1987483977834603872">"La pagina de la „<xliff:g id="TITLE">%s</xliff:g>” apare:"</string>
<string name="js_dialog_title_default" msgid="6961903213729667573">"JavaScript"</string>
<string name="js_dialog_before_unload_title" msgid="2619376555525116593">"Confirmați părăsirea paginii"</string>
<string name="js_dialog_before_unload_positive_button" msgid="3112752010600484130">"Părăsiți această pagină"</string>
<string name="js_dialog_before_unload_negative_button" msgid="5614861293026099715">"Rămâneți în această pagină"</string>
<string name="js_dialog_before_unload" msgid="3468816357095378590">"<xliff:g id="MESSAGE">%s</xliff:g>\n\nSigur doriți să părăsiți această pagină?"</string>
- <string name="save_password_label" msgid="6860261758665825069">"Confirmaţi"</string>
- <string name="double_tap_toast" msgid="4595046515400268881">"Sfat: măriţi și micşoraţi prin dublă atingere."</string>
+ <string name="save_password_label" msgid="6860261758665825069">"Confirmați"</string>
+ <string name="double_tap_toast" msgid="4595046515400268881">"Sfat: măriți și micșorați prin dublă atingere."</string>
<string name="autofill_this_form" msgid="4616758841157816676">"Automat"</string>
<string name="setup_autofill" msgid="7103495070180590814">"Conf.Compl.auto."</string>
<string name="autofill_address_name_separator" msgid="6350145154779706772">" "</string>
@@ -767,7 +767,7 @@
<string name="autofill_postal_code" msgid="4696430407689377108">"Cod poştal"</string>
<string name="autofill_state" msgid="6988894195520044613">"Stat"</string>
<string name="autofill_zip_code" msgid="8697544592627322946">"Cod ZIP"</string>
- <string name="autofill_county" msgid="237073771020362891">"Judeţ"</string>
+ <string name="autofill_county" msgid="237073771020362891">"Județ"</string>
<string name="autofill_island" msgid="4020100875984667025">"Insulă"</string>
<string name="autofill_district" msgid="8400735073392267672">"District"</string>
<string name="autofill_department" msgid="5343279462564453309">"Departament"</string>
@@ -776,38 +776,38 @@
<string name="autofill_area" msgid="3547409050889952423">"Zonă"</string>
<string name="autofill_emirate" msgid="2893880978835698818">"Emirat"</string>
<string name="permlab_readHistoryBookmarks" msgid="3775265775405106983">"citeşte marcajele și istoricul web"</string>
- <string name="permdesc_readHistoryBookmarks" msgid="8462378226600439658">"Permite aplicației să citească istoricul tuturor adreselor URL accesate de Browser și toate marcajele din Browser. Notă: această permisiune nu poate fi aplicată de browsere terţă parte sau de alte aplicații cu capacităţi de navigare pe web."</string>
+ <string name="permdesc_readHistoryBookmarks" msgid="8462378226600439658">"Permite aplicației să citească istoricul tuturor adreselor URL accesate de Browser și toate marcajele din Browser. Notă: această permisiune nu poate fi aplicată de browsere terţă parte sau de alte aplicații cu capacități de navigare pe web."</string>
<string name="permlab_writeHistoryBookmarks" msgid="3714785165273314490">"scrie în marcajele și în istoricul web"</string>
- <string name="permdesc_writeHistoryBookmarks" product="tablet" msgid="6825527469145760922">"Permite aplicației să modifice istoricul Browserului sau marcajele stocate pe tabletă. În acest fel, aplicația poate şterge sau modifica datele din Browser. Notă: această permisiune nu poate fi aplicată de browsere terţă parte sau de alte aplicații cu capacităţi de navigare pe web."</string>
+ <string name="permdesc_writeHistoryBookmarks" product="tablet" msgid="6825527469145760922">"Permite aplicației să modifice istoricul Browserului sau marcajele stocate pe tabletă. În acest fel, aplicația poate șterge sau modifica datele din Browser. Notă: această permisiune nu poate fi aplicată de browsere terţă parte sau de alte aplicații cu capacități de navigare pe web."</string>
<string name="permdesc_writeHistoryBookmarks" product="tv" msgid="7007393823197766548">"Permite aplicației să modifice istoricul sau marcajele browserului stocate pe televizor. Cu această permisiune, aplicația poate șterge sau modifica datele din browser. Notă: această permisiune nu poate fi aplicată de browsere terță parte sau de alte aplicații cu capacități de navigare pe web."</string>
- <string name="permdesc_writeHistoryBookmarks" product="default" msgid="8497389531014185509">"Permite aplicației să modifice istoricul Browserului sau marcajele stocate pe telefon. În acest fel, aplicația poate şterge sau modifica datele din Browser. Notă: această permisiune nu poate fi aplicată de browsere terţă parte sau de alte aplicații cu capacităţi de navigare pe web."</string>
+ <string name="permdesc_writeHistoryBookmarks" product="default" msgid="8497389531014185509">"Permite aplicației să modifice istoricul Browserului sau marcajele stocate pe telefon. În acest fel, aplicația poate șterge sau modifica datele din Browser. Notă: această permisiune nu poate fi aplicată de browsere terţă parte sau de alte aplicații cu capacități de navigare pe web."</string>
<string name="permlab_setAlarm" msgid="1379294556362091814">"setează o alarmă"</string>
- <string name="permdesc_setAlarm" msgid="316392039157473848">"Permite aplicației să seteze o alarmă într-o aplicație de ceas cu alarmă instalată. Este posibil ca unele aplicații de ceas cu alarmă să nu implementeze această funcţie."</string>
+ <string name="permdesc_setAlarm" msgid="316392039157473848">"Permite aplicației să seteze o alarmă într-o aplicație de ceas cu alarmă instalată. Este posibil ca unele aplicații de ceas cu alarmă să nu implementeze această funcție."</string>
<string name="permlab_addVoicemail" msgid="5525660026090959044">"adăugare mesagerie vocală"</string>
<string name="permdesc_addVoicemail" msgid="6604508651428252437">"Permite aplicației să adauge mesaje în Mesaje primite în mesageria vocală."</string>
- <string name="permlab_writeGeolocationPermissions" msgid="5962224158955273932">"modificare permisiuni pentru locaţia geografică a browserului"</string>
- <string name="permdesc_writeGeolocationPermissions" msgid="1083743234522638747">"Permite aplicației să modifice permisiunile privind locaţia geografică a browserului. Aplicaţiile rău intenţionate pot utiliza această permisiune pentru a permite trimiterea informaţiilor privind locaţia către site-uri web arbitrare."</string>
- <string name="save_password_message" msgid="767344687139195790">"Doriţi ca browserul să reţină această parolă?"</string>
+ <string name="permlab_writeGeolocationPermissions" msgid="5962224158955273932">"modificare permisiuni pentru locația geografică a browserului"</string>
+ <string name="permdesc_writeGeolocationPermissions" msgid="1083743234522638747">"Permite aplicației să modifice permisiunile privind locația geografică a browserului. Aplicaţiile rău intenţionate pot utiliza această permisiune pentru a permite trimiterea informaţiilor privind locația către site-uri web arbitrare."</string>
+ <string name="save_password_message" msgid="767344687139195790">"Doriți ca browserul să reţină această parolă?"</string>
<string name="save_password_notnow" msgid="6389675316706699758">"Nu acum"</string>
<string name="save_password_remember" msgid="6491879678996749466">"Reţineţi"</string>
<string name="save_password_never" msgid="8274330296785855105">"Niciodată"</string>
- <string name="open_permission_deny" msgid="7374036708316629800">"Nu aveţi permisiunea de a deschide această pagină."</string>
+ <string name="open_permission_deny" msgid="7374036708316629800">"Nu aveți permisiunea de a deschide această pagină."</string>
<string name="text_copied" msgid="4985729524670131385">"Text copiat în clipboard."</string>
<string name="more_item_label" msgid="4650918923083320495">"Mai multe"</string>
<string name="prepend_shortcut_label" msgid="2572214461676015642">"Meniu+"</string>
- <string name="menu_space_shortcut_label" msgid="2410328639272162537">"spaţiu"</string>
+ <string name="menu_space_shortcut_label" msgid="2410328639272162537">"spațiu"</string>
<string name="menu_enter_shortcut_label" msgid="2743362785111309668">"enter"</string>
<string name="menu_delete_shortcut_label" msgid="3658178007202748164">"delete"</string>
- <string name="search_go" msgid="8298016669822141719">"Căutaţi"</string>
+ <string name="search_go" msgid="8298016669822141719">"Căutați"</string>
<string name="search_hint" msgid="1733947260773056054">"Căutați…"</string>
- <string name="searchview_description_search" msgid="6749826639098512120">"Căutaţi"</string>
+ <string name="searchview_description_search" msgid="6749826639098512120">"Căutați"</string>
<string name="searchview_description_query" msgid="5911778593125355124">"Interogare de căutare"</string>
- <string name="searchview_description_clear" msgid="1330281990951833033">"Ștergeţi interogarea"</string>
- <string name="searchview_description_submit" msgid="2688450133297983542">"Trimiteţi interogarea"</string>
+ <string name="searchview_description_clear" msgid="1330281990951833033">"Ștergeți interogarea"</string>
+ <string name="searchview_description_submit" msgid="2688450133297983542">"Trimiteți interogarea"</string>
<string name="searchview_description_voice" msgid="2453203695674994440">"Căutare vocală"</string>
- <string name="enable_explore_by_touch_warning_title" msgid="7460694070309730149">"Activați Exploraţi prin atingere?"</string>
- <string name="enable_explore_by_touch_warning_message" product="tablet" msgid="8655887539089910577">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> doreşte să activeze funcţia Exploraţi prin atingere. Când această funcţie este activată, puteţi auzi sau vedea descrieri pentru ceea ce se află sub degetul dvs. sau puteţi efectua gesturi pentru a interacţiona cu tableta."</string>
- <string name="enable_explore_by_touch_warning_message" product="default" msgid="2708199672852373195">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> doreşte să activeze funcţia Exploraţi prin atingere. Când această funcţie este activată, puteţi auzi sau vedea descrieri pentru ceea ce se află sub degetul dvs. sau puteţi efectua gesturi pentru a interacţiona cu telefonul."</string>
+ <string name="enable_explore_by_touch_warning_title" msgid="7460694070309730149">"Activați Explorați prin atingere?"</string>
+ <string name="enable_explore_by_touch_warning_message" product="tablet" msgid="8655887539089910577">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> doreşte să activeze funcția Explorați prin atingere. Când această funcție este activată, puteți auzi sau vedea descrieri pentru ceea ce se află sub degetul dvs. sau puteți efectua gesturi pentru a interacţiona cu tableta."</string>
+ <string name="enable_explore_by_touch_warning_message" product="default" msgid="2708199672852373195">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> doreşte să activeze funcția Explorați prin atingere. Când această funcție este activată, puteți auzi sau vedea descrieri pentru ceea ce se află sub degetul dvs. sau puteți efectua gesturi pentru a interacţiona cu telefonul."</string>
<string name="oneMonthDurationPast" msgid="7396384508953779925">"cu 1 lună în urmă"</string>
<string name="beforeOneMonthDurationPast" msgid="909134546836499826">"Cu mai mult de 1 lună în urmă"</string>
<plurals name="last_num_days" formatted="false" msgid="5104533550723932025">
@@ -848,8 +848,8 @@
<item quantity="one">O oră</item>
</plurals>
<string name="VideoView_error_title" msgid="3534509135438353077">"Problemă video"</string>
- <string name="VideoView_error_text_invalid_progressive_playback" msgid="3186670335938670444">"Acest fişier video nu este valid pentru a fi transmis în flux către acest dispozitiv."</string>
- <string name="VideoView_error_text_unknown" msgid="3450439155187810085">"Nu puteţi reda acest videoclip"</string>
+ <string name="VideoView_error_text_invalid_progressive_playback" msgid="3186670335938670444">"Acest fișier video nu este valid pentru a fi transmis în flux către acest dispozitiv."</string>
+ <string name="VideoView_error_text_unknown" msgid="3450439155187810085">"Nu puteți reda acest videoclip"</string>
<string name="VideoView_error_button" msgid="2822238215100679592">"OK"</string>
<string name="relative_time" msgid="1818557177829411417">"<xliff:g id="DATE">%1$s</xliff:g>, <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="noon" msgid="7245353528818587908">"prânz"</string>
@@ -858,21 +858,21 @@
<string name="Midnight" msgid="5630806906897892201">"Miezul nopţii"</string>
<string name="elapsed_time_short_format_mm_ss" msgid="4431555943828711473">"<xliff:g id="MINUTES">%1$02d</xliff:g>:<xliff:g id="SECONDS">%2$02d</xliff:g>"</string>
<string name="elapsed_time_short_format_h_mm_ss" msgid="1846071997616654124">"<xliff:g id="HOURS">%1$d</xliff:g>:<xliff:g id="MINUTES">%2$02d</xliff:g>:<xliff:g id="SECONDS">%3$02d</xliff:g>"</string>
- <string name="selectAll" msgid="6876518925844129331">"Selectaţi-le pe toate"</string>
+ <string name="selectAll" msgid="6876518925844129331">"Selectați-le pe toate"</string>
<string name="cut" msgid="3092569408438626261">"Decupaţi"</string>
- <string name="copy" msgid="2681946229533511987">"Copiaţi"</string>
- <string name="paste" msgid="5629880836805036433">"Inseraţi"</string>
+ <string name="copy" msgid="2681946229533511987">"Copiați"</string>
+ <string name="paste" msgid="5629880836805036433">"Inserați"</string>
<string name="replace" msgid="5781686059063148930">"Înlocuiţi..."</string>
- <string name="delete" msgid="6098684844021697789">"Ștergeţi"</string>
- <string name="copyUrl" msgid="2538211579596067402">"Copiaţi adresa URL"</string>
- <string name="selectTextMode" msgid="1018691815143165326">"Selectaţi text"</string>
+ <string name="delete" msgid="6098684844021697789">"Ștergeți"</string>
+ <string name="copyUrl" msgid="2538211579596067402">"Copiați adresa URL"</string>
+ <string name="selectTextMode" msgid="1018691815143165326">"Selectați text"</string>
<string name="textSelectionCABTitle" msgid="5236850394370820357">"Selectare text"</string>
- <string name="addToDictionary" msgid="4352161534510057874">"Adăugaţi în dicţionar"</string>
- <string name="deleteText" msgid="6979668428458199034">"Ștergeţi"</string>
+ <string name="addToDictionary" msgid="4352161534510057874">"Adăugați în dicţionar"</string>
+ <string name="deleteText" msgid="6979668428458199034">"Ștergeți"</string>
<string name="inputMethod" msgid="1653630062304567879">"Metodă de intrare"</string>
<string name="editTextMenuTitle" msgid="4909135564941815494">"Acţiuni pentru text"</string>
<string name="low_internal_storage_view_title" msgid="5576272496365684834">"Spaţiul de stocare aproape ocupat"</string>
- <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Este posibil ca unele funcţii de sistem să nu funcţioneze"</string>
+ <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Este posibil ca unele funcții de sistem să nu funcţioneze"</string>
<string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"Spațiu de stocare insuficient pentru sistem. Asigurați-vă că aveți 250 MB de spațiu liber și reporniți."</string>
<string name="app_running_notification_title" msgid="8718335121060787914">"<xliff:g id="APP_NAME">%1$s</xliff:g> rulează acum"</string>
<string name="app_running_notification_text" msgid="4653586947747330058">"Atingeți pentru mai multe informații sau pentru a opri aplicația."</string>
@@ -884,7 +884,7 @@
<string name="loading" msgid="7933681260296021180">"Se încarcă…"</string>
<string name="capital_on" msgid="1544682755514494298">"DA"</string>
<string name="capital_off" msgid="6815870386972805832">"NU"</string>
- <string name="whichApplication" msgid="4533185947064773386">"Finalizare acţiune utilizând"</string>
+ <string name="whichApplication" msgid="4533185947064773386">"Finalizare acțiune utilizând"</string>
<string name="whichApplicationNamed" msgid="8260158865936942783">"Finalizați acțiunea utilizând %1$s"</string>
<string name="whichViewApplication" msgid="3272778576700572102">"Deschideți cu"</string>
<string name="whichViewApplicationNamed" msgid="2286418824011249620">"Deschideți cu %1$s"</string>
@@ -896,28 +896,28 @@
<string name="whichHomeApplicationNamed" msgid="4493438593214760979">"Utilizați %1$s ca ecran de pornire"</string>
<string name="alwaysUse" msgid="4583018368000610438">"Se utilizează în mod prestabilit pentru această acţiune."</string>
<string name="use_a_different_app" msgid="8134926230585710243">"Utilizați altă aplicație"</string>
- <string name="clearDefaultHintMsg" msgid="3252584689512077257">"Ștergeţi setările prestabilite din Setări de sistem > Aplicaţii > Descărcate."</string>
- <string name="chooseActivity" msgid="7486876147751803333">"Alegeţi o acţiune"</string>
- <string name="chooseUsbActivity" msgid="6894748416073583509">"Alegeţi o aplicație pentru dispozitivul USB"</string>
+ <string name="clearDefaultHintMsg" msgid="3252584689512077257">"Ștergeți setările prestabilite din Setări de sistem > Aplicații > Descărcate."</string>
+ <string name="chooseActivity" msgid="7486876147751803333">"Alegeți o acţiune"</string>
+ <string name="chooseUsbActivity" msgid="6894748416073583509">"Alegeți o aplicație pentru dispozitivul USB"</string>
<string name="noApplications" msgid="2991814273936504689">"Această acţiune nu poate fi efectuată de nicio aplicație."</string>
<string name="aerr_title" msgid="1905800560317137752"></string>
<string name="aerr_application" msgid="932628488013092776">"Din păcate, <xliff:g id="APPLICATION">%1$s</xliff:g> s-a oprit."</string>
<string name="aerr_process" msgid="4507058997035697579">"Din păcate, procesul <xliff:g id="PROCESS">%1$s</xliff:g> s-a oprit."</string>
<string name="anr_title" msgid="4351948481459135709"></string>
- <string name="anr_activity_application" msgid="1904477189057199066">"Aplicaţia <xliff:g id="APPLICATION">%2$s</xliff:g> nu răspunde.\n\nDoriţi să o închideţi?"</string>
- <string name="anr_activity_process" msgid="5776209883299089767">"Activitatea <xliff:g id="ACTIVITY">%1$s</xliff:g> nu răspunde.\n\nDoriţi să o închideţi?"</string>
- <string name="anr_application_process" msgid="8941757607340481057">"Aplicaţia <xliff:g id="APPLICATION">%1$s</xliff:g> nu răspunde. Doriţi să o închideţi?"</string>
- <string name="anr_process" msgid="6513209874880517125">"Procesul <xliff:g id="PROCESS">%1$s</xliff:g> nu răspunde.\n\nDoriţi să îl închideţi?"</string>
+ <string name="anr_activity_application" msgid="1904477189057199066">"Aplicaţia <xliff:g id="APPLICATION">%2$s</xliff:g> nu răspunde.\n\nDoriți să o închideţi?"</string>
+ <string name="anr_activity_process" msgid="5776209883299089767">"Activitatea <xliff:g id="ACTIVITY">%1$s</xliff:g> nu răspunde.\n\nDoriți să o închideţi?"</string>
+ <string name="anr_application_process" msgid="8941757607340481057">"Aplicaţia <xliff:g id="APPLICATION">%1$s</xliff:g> nu răspunde. Doriți să o închideţi?"</string>
+ <string name="anr_process" msgid="6513209874880517125">"Procesul <xliff:g id="PROCESS">%1$s</xliff:g> nu răspunde.\n\nDoriți să îl închideţi?"</string>
<string name="force_close" msgid="8346072094521265605">"OK"</string>
<string name="report" msgid="4060218260984795706">"Raportaţi"</string>
<string name="wait" msgid="7147118217226317732">"Aşteptaţi"</string>
- <string name="webpage_unresponsive" msgid="3272758351138122503">"Pagina a devenit inactivă.\n\nDoriţi să o închideţi?"</string>
+ <string name="webpage_unresponsive" msgid="3272758351138122503">"Pagina a devenit inactivă.\n\nDoriți să o închideţi?"</string>
<string name="launch_warning_title" msgid="1547997780506713581">"Aplicaţie redirecţionată"</string>
<string name="launch_warning_replace" msgid="6202498949970281412">"<xliff:g id="APP_NAME">%1$s</xliff:g> funcţionează acum."</string>
<string name="launch_warning_original" msgid="188102023021668683">"<xliff:g id="APP_NAME">%1$s</xliff:g> a fost lansată iniţial."</string>
<string name="screen_compat_mode_scale" msgid="3202955667675944499">"Scară"</string>
<string name="screen_compat_mode_show" msgid="4013878876486655892">"Afişaţi întotdeauna"</string>
- <string name="screen_compat_mode_hint" msgid="1064524084543304459">"Reactivaţi acest mod din Setări de sistem > Aplicaţii > Descărcate."</string>
+ <string name="screen_compat_mode_hint" msgid="1064524084543304459">"Reactivați acest mod din Setări de sistem > Aplicații > Descărcate."</string>
<string name="smv_application" msgid="3307209192155442829">"Aplicaţia <xliff:g id="APPLICATION">%1$s</xliff:g> (procesul <xliff:g id="PROCESS">%2$s</xliff:g>) a încălcat propria politică StrictMode."</string>
<string name="smv_process" msgid="5120397012047462446">"Procesul <xliff:g id="PROCESS">%1$s</xliff:g> a încălcat propria politică StrictMode."</string>
<string name="android_upgrading_title" msgid="1584192285441405746">"Android trece la o versiune superioară..."</string>
@@ -928,18 +928,18 @@
<string name="android_upgrading_starting_apps" msgid="451464516346926713">"Se pornesc aplicațiile."</string>
<string name="android_upgrading_complete" msgid="1405954754112999229">"Se finalizează pornirea."</string>
<string name="heavy_weight_notification" msgid="9087063985776626166">"Rulează <xliff:g id="APP">%1$s</xliff:g>"</string>
- <string name="heavy_weight_notification_detail" msgid="1721681741617898865">"Atingeţi pentru a comuta la aplicație"</string>
+ <string name="heavy_weight_notification_detail" msgid="1721681741617898865">"Atingeți pentru a comuta la aplicație"</string>
<string name="heavy_weight_switcher_title" msgid="7153167085403298169">"Comutaţi între aplicații?"</string>
<string name="heavy_weight_switcher_text" msgid="7022631924534406403">"O altă aplicație rulează deja și trebuie oprită înainte a putea porni o aplicație nouă."</string>
<string name="old_app_action" msgid="493129172238566282">"Reveniţi la <xliff:g id="OLD_APP">%1$s</xliff:g>"</string>
- <string name="old_app_description" msgid="2082094275580358049">"Nu porniţi aplicația nouă."</string>
+ <string name="old_app_description" msgid="2082094275580358049">"Nu porniți aplicația nouă."</string>
<string name="new_app_action" msgid="5472756926945440706">"Porniţi <xliff:g id="OLD_APP">%1$s</xliff:g>"</string>
- <string name="new_app_description" msgid="1932143598371537340">"Opriți vechea aplicație fără să salvaţi."</string>
+ <string name="new_app_description" msgid="1932143598371537340">"Opriți vechea aplicație fără să salvați."</string>
<string name="dump_heap_notification" msgid="2618183274836056542">"<xliff:g id="PROC">%1$s</xliff:g> a depășit limita de memorie"</string>
<string name="dump_heap_notification_detail" msgid="2075673362317481664">"Datele privind memoria au fost culese; atingeți pentru a trimite"</string>
<string name="dump_heap_title" msgid="5864292264307651673">"Trimiteți datele privind memoria?"</string>
<string name="dump_heap_text" msgid="4809417337240334941">"Procesul <xliff:g id="PROC">%1$s</xliff:g> și-a depășit limita de memorie de <xliff:g id="SIZE">%2$s</xliff:g>. Sunt disponibile datele privind memoria, pe care le puteți trimite dezvoltatorului. Atenție: aceste date privind memoria pot conține informațiile personale la care aplicația are acces."</string>
- <string name="sendText" msgid="5209874571959469142">"Alegeţi o acţiune pentru text"</string>
+ <string name="sendText" msgid="5209874571959469142">"Alegeți o acţiune pentru text"</string>
<string name="volume_ringtone" msgid="6885421406845734650">"Volum sonerie"</string>
<string name="volume_music" msgid="5421651157138628171">"Volum media"</string>
<string name="volume_music_hint_playing_through_bluetooth" msgid="9165984379394601533">"Redare prin Bluetooth"</string>
@@ -969,7 +969,7 @@
<item quantity="other">Rețele Wi-Fi deschise disponibile</item>
<item quantity="one">Rețea Wi-Fi deschisă disponibilă</item>
</plurals>
- <string name="wifi_available_sign_in" msgid="9157196203958866662">"Conectaţi-vă la reţeaua Wi-Fi"</string>
+ <string name="wifi_available_sign_in" msgid="9157196203958866662">"Conectați-vă la reţeaua Wi-Fi"</string>
<string name="network_available_sign_in" msgid="1848877297365446605">"Conectați-vă la rețea"</string>
<!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
<skip />
@@ -984,11 +984,11 @@
<string name="wifi_p2p_turnon_message" msgid="2909250942299627244">"Porniţi Wi-Fi Direct. Acest lucru va dezactiva clientul/hotspotul Wi-Fi."</string>
<string name="wifi_p2p_failed_message" msgid="3763669677935623084">"Wi-Fi Direct nu a putut porni."</string>
<string name="wifi_p2p_enabled_notification_title" msgid="2068321881673734886">"Wi-Fi Direct este activat"</string>
- <string name="wifi_p2p_enabled_notification_message" msgid="1638949953993894335">"Atingeţi pentru setări"</string>
+ <string name="wifi_p2p_enabled_notification_message" msgid="1638949953993894335">"Atingeți pentru setări"</string>
<string name="accept" msgid="1645267259272829559">"Acceptaţi"</string>
<string name="decline" msgid="2112225451706137894">"Refuzaţi"</string>
<string name="wifi_p2p_invitation_sent_title" msgid="1318975185112070734">"Invitaţia a fost trimisă."</string>
- <string name="wifi_p2p_invitation_to_connect_title" msgid="4958803948658533637">"Invitaţie pentru conectare"</string>
+ <string name="wifi_p2p_invitation_to_connect_title" msgid="4958803948658533637">"Invitație pentru conectare"</string>
<string name="wifi_p2p_from_message" msgid="570389174731951769">"De la:"</string>
<string name="wifi_p2p_to_message" msgid="248968974522044099">"Către:"</string>
<string name="wifi_p2p_enter_pin_message" msgid="5920929550367828970">"Introduceţi codul PIN necesar:"</string>
@@ -998,18 +998,18 @@
<string name="wifi_p2p_frequency_conflict_message" product="default" msgid="7363907213787469151">"Telefonul se va deconecta temporar de la reţeaua Wi-Fi cât timp este conectat la <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
<string name="select_character" msgid="3365550120617701745">"Introduceţi caracterul"</string>
<string name="sms_control_title" msgid="7296612781128917719">"Se trimit mesaje SMS"</string>
- <string name="sms_control_message" msgid="3867899169651496433">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> trimite un număr mare de mesaje SMS. Permiteţi acestei aplicații să trimită în continuare mesaje?"</string>
- <string name="sms_control_yes" msgid="3663725993855816807">"Permiteţi"</string>
+ <string name="sms_control_message" msgid="3867899169651496433">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> trimite un număr mare de mesaje SMS. Permiteți acestei aplicații să trimită în continuare mesaje?"</string>
+ <string name="sms_control_yes" msgid="3663725993855816807">"Permiteți"</string>
<string name="sms_control_no" msgid="625438561395534982">"Refuzaţi"</string>
- <string name="sms_short_code_confirm_message" msgid="1645436466285310855">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> intenţionează să trimită un mesaj la <b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b>."</string>
+ <string name="sms_short_code_confirm_message" msgid="1645436466285310855">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> intenționează să trimită un mesaj la <b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b>."</string>
<string name="sms_short_code_details" msgid="5873295990846059400">"Acest lucru "<b>"poate genera costuri"</b>" în contul dvs. mobil."</string>
<string name="sms_premium_short_code_details" msgid="7869234868023975"><b>"Acest lucru va genera costuri în contul dvs. mobil."</b></string>
- <string name="sms_short_code_confirm_allow" msgid="4458878637111023413">"Trimiteţi"</string>
+ <string name="sms_short_code_confirm_allow" msgid="4458878637111023413">"Trimiteți"</string>
<string name="sms_short_code_confirm_deny" msgid="2927389840209170706">"Anulați"</string>
- <string name="sms_short_code_remember_choice" msgid="5289538592272218136">"Doresc să se reţină opţiunea"</string>
- <string name="sms_short_code_remember_undo_instruction" msgid="4960944133052287484">"Puteţi modifica ulterior în Setări > Aplicaţii"</string>
- <string name="sms_short_code_confirm_always_allow" msgid="3241181154869493368">"Permiteţi întotdeauna"</string>
- <string name="sms_short_code_confirm_never_allow" msgid="446992765774269673">"Nu permiteţi niciodată"</string>
+ <string name="sms_short_code_remember_choice" msgid="5289538592272218136">"Doresc să se reţină opțiunea"</string>
+ <string name="sms_short_code_remember_undo_instruction" msgid="4960944133052287484">"Puteți modifica ulterior în Setări > Aplicații"</string>
+ <string name="sms_short_code_confirm_always_allow" msgid="3241181154869493368">"Permiteți întotdeauna"</string>
+ <string name="sms_short_code_confirm_never_allow" msgid="446992765774269673">"Nu permiteți niciodată"</string>
<string name="sim_removed_title" msgid="6227712319223226185">"Card SIM eliminat"</string>
<string name="sim_removed_message" msgid="5450336489923274918">"Rețeaua mobilă va fi indisponibilă până când reporniți cu un card SIM valabil introdus."</string>
<string name="sim_done_button" msgid="827949989369963775">"Terminat"</string>
@@ -1018,7 +1018,7 @@
<string name="sim_restart_button" msgid="4722407842815232347">"Reporniţi"</string>
<string name="time_picker_dialog_title" msgid="8349362623068819295">"Setaţi ora"</string>
<string name="date_picker_dialog_title" msgid="5879450659453782278">"Setaţi data"</string>
- <string name="date_time_set" msgid="5777075614321087758">"Setaţi"</string>
+ <string name="date_time_set" msgid="5777075614321087758">"Setați"</string>
<string name="date_time_done" msgid="2507683751759308828">"Terminat"</string>
<string name="perms_new_perm_prefix" msgid="8257740710754301407"><font size="12" fgcolor="#ff33b5e5">"NOU: "</font></string>
<string name="perms_description_app" msgid="5139836143293299417">"Furnizată de <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
@@ -1026,18 +1026,18 @@
<string name="perm_costs_money" msgid="4902470324142151116">"aceasta poate să genereze costuri"</string>
<string name="usb_storage_activity_title" msgid="4465055157209648641">"Stocare masivă USB"</string>
<string name="usb_storage_title" msgid="5901459041398751495">"USB conectat"</string>
- <string name="usb_storage_message" product="nosdcard" msgid="3308538094316477839">"V-aţi conectat la computer prin USB. Atingeţi butonul de mai jos dacă doriţi să copiaţi fişiere de pe computer pe stocarea USB Android sau invers."</string>
- <string name="usb_storage_message" product="default" msgid="805351000446037811">"V-aţi conectat la computer prin USB. Atingeţi butonul de mai jos dacă doriţi să copiaţi fişiere de pe computer pe cardul SD Android sau invers."</string>
+ <string name="usb_storage_message" product="nosdcard" msgid="3308538094316477839">"V-aţi conectat la computer prin USB. Atingeți butonul de mai jos dacă doriți să copiați fișiere de pe computer pe stocarea USB Android sau invers."</string>
+ <string name="usb_storage_message" product="default" msgid="805351000446037811">"V-aţi conectat la computer prin USB. Atingeți butonul de mai jos dacă doriți să copiați fișiere de pe computer pe cardul SD Android sau invers."</string>
<string name="usb_storage_button_mount" msgid="1052259930369508235">"Activați stocarea USB"</string>
<string name="usb_storage_error_message" product="nosdcard" msgid="3017045217365540658">"A apărut o problemă la utilizarea stocării USB pentru stocarea masivă USB."</string>
<string name="usb_storage_error_message" product="default" msgid="2876018512716970313">"A apărut o problemă la utilizarea cardului SD pentru stocarea masivă USB."</string>
<string name="usb_storage_notification_title" msgid="8175892554757216525">"USB conectat"</string>
- <string name="usb_storage_notification_message" msgid="939822783828183763">"Atingeţi pentru a copia fişiere în/din computerul dvs."</string>
+ <string name="usb_storage_notification_message" msgid="939822783828183763">"Atingeți pentru a copia fișiere în/din computerul dvs."</string>
<string name="usb_storage_stop_notification_title" msgid="2336058396663516017">"Dezactivați stocarea USB"</string>
- <string name="usb_storage_stop_notification_message" msgid="1656852098555623822">"Atingeţi pentru a dezactiva stocarea USB."</string>
+ <string name="usb_storage_stop_notification_message" msgid="1656852098555623822">"Atingeți pentru a dezactiva stocarea USB."</string>
<string name="usb_storage_stop_title" msgid="660129851708775853">"Stocarea USB este în curs de utilizare"</string>
- <string name="usb_storage_stop_message" product="nosdcard" msgid="4264025280777219521">"Înainte de a dezactiva stocarea USB, demontaţi („extrageţi”) din computer stocarea USB Android."</string>
- <string name="usb_storage_stop_message" product="default" msgid="8043969782460613114">"Înainte de a dezactiva stocarea USB, demontaţi („extrageţi”) din computer cardul SD Android."</string>
+ <string name="usb_storage_stop_message" product="nosdcard" msgid="4264025280777219521">"Înainte de a dezactiva stocarea USB, demontaţi („extrageți”) din computer stocarea USB Android."</string>
+ <string name="usb_storage_stop_message" product="default" msgid="8043969782460613114">"Înainte de a dezactiva stocarea USB, demontaţi („extrageți”) din computer cardul SD Android."</string>
<string name="usb_storage_stop_button_mount" msgid="7060218034900696029">"Dezactivați stocarea USB"</string>
<string name="usb_storage_stop_error_message" msgid="1970374898263063836">"Problemă la dezactivarea stocării USB. Verificaţi dacă aţi demontat dispozitivul gazdă USB, apoi încercaţi din nou."</string>
<string name="dlg_confirm_kill_storage_users_title" msgid="963039033470478697">"Activați stocarea USB"</string>
@@ -1051,13 +1051,13 @@
<string name="usb_accessory_notification_title" msgid="7848236974087653666">"Conectat la un accesoriu USB"</string>
<string name="usb_notification_message" msgid="7347368030849048437">"Atingeți pentru mai multe opțiuni."</string>
<string name="adb_active_notification_title" msgid="6729044778949189918">"Depanarea USB este conectată"</string>
- <string name="adb_active_notification_message" msgid="1016654627626476142">"Atingeţi pentru a dezactiva depanarea USB."</string>
+ <string name="adb_active_notification_message" msgid="1016654627626476142">"Atingeți pentru a dezactiva depanarea USB."</string>
<string name="select_input_method" msgid="8547250819326693584">"Schimbați tastatura"</string>
<string name="configure_input_methods" msgid="4769971288371946846">"Alegeți tastaturi"</string>
<string name="show_ime" msgid="9157568568695230830">"Afișați metoda de introducere a textului"</string>
<string name="hardware" msgid="7517821086888990278">"Hardware"</string>
- <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"Selectaţi aspectul tastaturii"</string>
- <string name="select_keyboard_layout_notification_message" msgid="4465907700449257063">"Atingeţi pentru a selecta un aspect de tastatură."</string>
+ <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"Selectați aspectul tastaturii"</string>
+ <string name="select_keyboard_layout_notification_message" msgid="4465907700449257063">"Atingeți pentru a selecta un aspect de tastatură."</string>
<string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="candidates_style" msgid="4333913089637062257"><u>"candidaţi"</u></string>
@@ -1098,27 +1098,27 @@
<string name="ext_media_status_formatting" msgid="1085079556538644861">"Se formatează…"</string>
<string name="ext_media_status_missing" msgid="5638633895221670766">"Nu este introdus"</string>
<string name="activity_list_empty" msgid="1675388330786841066">"Nu s-a găsit nicio activitate potrivită."</string>
- <string name="permlab_route_media_output" msgid="1642024455750414694">"Direcţionează rezultatele media"</string>
- <string name="permdesc_route_media_output" msgid="4932818749547244346">"Permite unei aplicații să direcţioneze rezultate media către alte dispozitive externe."</string>
+ <string name="permlab_route_media_output" msgid="1642024455750414694">"Direcționează rezultatele media"</string>
+ <string name="permdesc_route_media_output" msgid="4932818749547244346">"Permite unei aplicații să direcționeze rezultate media către alte dispozitive externe."</string>
<string name="permlab_readInstallSessions" msgid="6165432407628065939">"Citirea sesiunilor de instalare"</string>
<string name="permdesc_readInstallSessions" msgid="2049771699626019849">"Permite unei aplicații accesul la citirea sesiunilor de instalare. Aceasta poate vedea detalii despre instalările de pachete active."</string>
<string name="permlab_requestInstallPackages" msgid="1772330282283082214">"Solicită instalarea pachetelor"</string>
<string name="permdesc_requestInstallPackages" msgid="5740101072486783082">"Permite unei aplicații să solicite instalarea pachetelor."</string>
- <string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"Atingeţi de două ori pentru a mări/micşora"</string>
+ <string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"Atingeți de două ori pentru a mări/micşora"</string>
<string name="gadget_host_error_inflating" msgid="4882004314906466162">"Nu s-a putut adăuga widgetul."</string>
- <string name="ime_action_go" msgid="8320845651737369027">"Accesaţi"</string>
- <string name="ime_action_search" msgid="658110271822807811">"Căutaţi"</string>
- <string name="ime_action_send" msgid="2316166556349314424">"Trimiteţi"</string>
+ <string name="ime_action_go" msgid="8320845651737369027">"Accesați"</string>
+ <string name="ime_action_search" msgid="658110271822807811">"Căutați"</string>
+ <string name="ime_action_send" msgid="2316166556349314424">"Trimiteți"</string>
<string name="ime_action_next" msgid="3138843904009813834">"Înainte"</string>
<string name="ime_action_done" msgid="8971516117910934605">"Terminat"</string>
<string name="ime_action_previous" msgid="1443550039250105948">"Înapoi"</string>
- <string name="ime_action_default" msgid="2840921885558045721">"Executaţi"</string>
+ <string name="ime_action_default" msgid="2840921885558045721">"Executați"</string>
<string name="dial_number_using" msgid="5789176425167573586">"Formaţi numărul\nutilizând <xliff:g id="NUMBER">%s</xliff:g>"</string>
- <string name="create_contact_using" msgid="4947405226788104538">"Creaţi contactul\nutilizând <xliff:g id="NUMBER">%s</xliff:g>"</string>
+ <string name="create_contact_using" msgid="4947405226788104538">"Creați contactul\nutilizând <xliff:g id="NUMBER">%s</xliff:g>"</string>
<string name="grant_credentials_permission_message_header" msgid="2106103817937859662">"Următoarele aplicații solicită permisiunea de a accesa contul dvs. acum și în viitor."</string>
- <string name="grant_credentials_permission_message_footer" msgid="3125211343379376561">"Permiteţi această solicitare?"</string>
+ <string name="grant_credentials_permission_message_footer" msgid="3125211343379376561">"Permiteți această solicitare?"</string>
<string name="grant_permissions_header_text" msgid="6874497408201826708">"Solicitare de acces"</string>
- <string name="allow" msgid="7225948811296386551">"Permiteţi"</string>
+ <string name="allow" msgid="7225948811296386551">"Permiteți"</string>
<string name="deny" msgid="2081879885755434506">"Refuzaţi"</string>
<string name="permission_request_notification_title" msgid="6486759795926237907">"Permisiune solicitată"</string>
<string name="permission_request_notification_with_subtitle" msgid="8530393139639560189">"Permisiune solicitată\npentru contul <xliff:g id="ACCOUNT">%s</xliff:g>."</string>
@@ -1133,20 +1133,20 @@
<string name="condition_provider_service_binding_label" msgid="1321343352906524564">"Furnizor de condiții"</string>
<string name="vpn_title" msgid="19615213552042827">"VPN activat"</string>
<string name="vpn_title_long" msgid="6400714798049252294">"VPN este activată de <xliff:g id="APP">%s</xliff:g>"</string>
- <string name="vpn_text" msgid="3011306607126450322">"Atingeţi pentru a gestiona reţeaua."</string>
- <string name="vpn_text_long" msgid="6407351006249174473">"Conectat la <xliff:g id="SESSION">%s</xliff:g>. Atingeţi pentru a gestiona reţeaua."</string>
+ <string name="vpn_text" msgid="3011306607126450322">"Atingeți pentru a gestiona reţeaua."</string>
+ <string name="vpn_text_long" msgid="6407351006249174473">"Conectat la <xliff:g id="SESSION">%s</xliff:g>. Atingeți pentru a gestiona reţeaua."</string>
<string name="vpn_lockdown_connecting" msgid="6443438964440960745">"Se efectuează conectarea la reţeaua VPN activată permanent…"</string>
<string name="vpn_lockdown_connected" msgid="8202679674819213931">"Conectat(ă) la reţeaua VPN activată permanent"</string>
- <string name="vpn_lockdown_error" msgid="6009249814034708175">"Eroare de reţea VPN activată permanent"</string>
+ <string name="vpn_lockdown_error" msgid="6009249814034708175">"Eroare de rețea VPN activată permanent"</string>
<string name="vpn_lockdown_config" msgid="6415899150671537970">"Atingeți pentru a configura"</string>
- <string name="upload_file" msgid="2897957172366730416">"Alegeţi un fişier"</string>
- <string name="no_file_chosen" msgid="6363648562170759465">"Nu au fost găsite fişiere"</string>
+ <string name="upload_file" msgid="2897957172366730416">"Alegeți un fișier"</string>
+ <string name="no_file_chosen" msgid="6363648562170759465">"Nu au fost găsite fișiere"</string>
<string name="reset" msgid="2448168080964209908">"Resetaţi"</string>
- <string name="submit" msgid="1602335572089911941">"Trimiteţi"</string>
+ <string name="submit" msgid="1602335572089911941">"Trimiteți"</string>
<string name="car_mode_disable_notification_title" msgid="3164768212003864316">"Mod Maşină activat"</string>
- <string name="car_mode_disable_notification_message" msgid="8035230537563503262">"Atingeţi pentru a ieşi din modul Maşină."</string>
+ <string name="car_mode_disable_notification_message" msgid="8035230537563503262">"Atingeți pentru a ieşi din modul Maşină."</string>
<string name="tethered_notification_title" msgid="3146694234398202601">"Tethering sau hotspot activ"</string>
- <string name="tethered_notification_message" msgid="6857031760103062982">"Atingeţi pentru a configura."</string>
+ <string name="tethered_notification_message" msgid="6857031760103062982">"Atingeți pentru a configura."</string>
<string name="back_button_label" msgid="2300470004503343439">"Înapoi"</string>
<string name="next_button_label" msgid="1080555104677992408">"Înainte"</string>
<string name="skip_button_label" msgid="1275362299471631819">"Omiteţi"</string>
@@ -1158,62 +1158,62 @@
<item quantity="one">Un rezultat</item>
</plurals>
<string name="action_mode_done" msgid="7217581640461922289">"Terminat"</string>
- <string name="progress_erasing" product="nosdcard" msgid="4521573321524340058">"Se şterge stocarea USB..."</string>
- <string name="progress_erasing" product="default" msgid="6596988875507043042">"Se şterge cardul SD..."</string>
+ <string name="progress_erasing" product="nosdcard" msgid="4521573321524340058">"Se șterge stocarea USB..."</string>
+ <string name="progress_erasing" product="default" msgid="6596988875507043042">"Se șterge cardul SD..."</string>
<string name="share" msgid="1778686618230011964">"Distribuiţi"</string>
<string name="find" msgid="4808270900322985960">"Găsiţi"</string>
<string name="websearch" msgid="4337157977400211589">"Căutare pe web"</string>
<string name="find_next" msgid="5742124618942193978">"Următorul rezultat"</string>
<string name="find_previous" msgid="2196723669388360506">"Rezultatul anterior"</string>
- <string name="gpsNotifTicker" msgid="5622683912616496172">"Solicitare de locaţie de la <xliff:g id="NAME">%s</xliff:g>"</string>
- <string name="gpsNotifTitle" msgid="5446858717157416839">"Solicitare de locaţie"</string>
+ <string name="gpsNotifTicker" msgid="5622683912616496172">"Solicitare de locație de la <xliff:g id="NAME">%s</xliff:g>"</string>
+ <string name="gpsNotifTitle" msgid="5446858717157416839">"Solicitare de locație"</string>
<string name="gpsNotifMessage" msgid="1374718023224000702">"Solicitat de <xliff:g id="NAME">%1$s</xliff:g> (<xliff:g id="SERVICE">%2$s</xliff:g>)"</string>
<string name="gpsVerifYes" msgid="2346566072867213563">"Da"</string>
<string name="gpsVerifNo" msgid="1146564937346454865">"Nu"</string>
<string name="sync_too_many_deletes" msgid="5296321850662746890">"Limita pentru ştergere a fost depăşită"</string>
- <string name="sync_too_many_deletes_desc" msgid="496551671008694245">"Există <xliff:g id="NUMBER_OF_DELETED_ITEMS">%1$d</xliff:g> (de) elemente şterse pentru <xliff:g id="TYPE_OF_SYNC">%2$s</xliff:g>, contul <xliff:g id="ACCOUNT_NAME">%3$s</xliff:g>. Ce doriţi să faceţi?"</string>
- <string name="sync_really_delete" msgid="2572600103122596243">"Ștergeţi elementele"</string>
+ <string name="sync_too_many_deletes_desc" msgid="496551671008694245">"Există <xliff:g id="NUMBER_OF_DELETED_ITEMS">%1$d</xliff:g> (de) elemente şterse pentru <xliff:g id="TYPE_OF_SYNC">%2$s</xliff:g>, contul <xliff:g id="ACCOUNT_NAME">%3$s</xliff:g>. Ce doriți să faceţi?"</string>
+ <string name="sync_really_delete" msgid="2572600103122596243">"Ștergeți elementele"</string>
<string name="sync_undo_deletes" msgid="2941317360600338602">"Anulați aceste ştergeri"</string>
- <string name="sync_do_nothing" msgid="3743764740430821845">"Nu trebuie să luaţi nicio măsură deocamdată"</string>
- <string name="choose_account_label" msgid="5655203089746423927">"Alegeţi un cont"</string>
- <string name="add_account_label" msgid="2935267344849993553">"Adăugaţi un cont"</string>
- <string name="add_account_button_label" msgid="3611982894853435874">"Adăugaţi un cont"</string>
- <string name="number_picker_increment_button" msgid="2412072272832284313">"Creşteţi"</string>
- <string name="number_picker_decrement_button" msgid="476050778386779067">"Reduceţi"</string>
- <string name="number_picker_increment_scroll_mode" msgid="3073101067441638428">"Atingeţi și ţineţi apăsat <xliff:g id="VALUE">%s</xliff:g>."</string>
+ <string name="sync_do_nothing" msgid="3743764740430821845">"Nu trebuie să luați nicio măsură deocamdată"</string>
+ <string name="choose_account_label" msgid="5655203089746423927">"Alegeți un cont"</string>
+ <string name="add_account_label" msgid="2935267344849993553">"Adăugați un cont"</string>
+ <string name="add_account_button_label" msgid="3611982894853435874">"Adăugați un cont"</string>
+ <string name="number_picker_increment_button" msgid="2412072272832284313">"Creșteți"</string>
+ <string name="number_picker_decrement_button" msgid="476050778386779067">"Reduceți"</string>
+ <string name="number_picker_increment_scroll_mode" msgid="3073101067441638428">"Atingeți și țineți apăsat <xliff:g id="VALUE">%s</xliff:g>."</string>
<string name="number_picker_increment_scroll_action" msgid="9101473045891835490">"Glisaţi în sus pentru a creşte și în jos pentru a reduce."</string>
- <string name="time_picker_increment_minute_button" msgid="8865885114028614321">"Creşteţi valoarea pentru minute"</string>
- <string name="time_picker_decrement_minute_button" msgid="6246834937080684791">"Reduceţi valoarea pentru minute"</string>
- <string name="time_picker_increment_hour_button" msgid="3652056055810223139">"Creşteţi valoarea pentru oră"</string>
- <string name="time_picker_decrement_hour_button" msgid="1377479863429214792">"Reduceţi valoarea pentru oră"</string>
+ <string name="time_picker_increment_minute_button" msgid="8865885114028614321">"Creșteți valoarea pentru minute"</string>
+ <string name="time_picker_decrement_minute_button" msgid="6246834937080684791">"Reduceți valoarea pentru minute"</string>
+ <string name="time_picker_increment_hour_button" msgid="3652056055810223139">"Creșteți valoarea pentru oră"</string>
+ <string name="time_picker_decrement_hour_button" msgid="1377479863429214792">"Reduceți valoarea pentru oră"</string>
<string name="time_picker_increment_set_pm_button" msgid="4147590696151230863">"Setaţi valoarea PM"</string>
<string name="time_picker_decrement_set_am_button" msgid="8302140353539486752">"Setaţi valoarea AM"</string>
- <string name="date_picker_increment_month_button" msgid="5369998479067934110">"Creşteţi valoarea pentru lună"</string>
- <string name="date_picker_decrement_month_button" msgid="1832698995541726019">"Reduceţi valoarea pentru lună"</string>
- <string name="date_picker_increment_day_button" msgid="7130465412308173903">"Creşteţi valoarea pentru zi"</string>
- <string name="date_picker_decrement_day_button" msgid="4131881521818750031">"Reduceţi valoarea pentru zi"</string>
- <string name="date_picker_increment_year_button" msgid="6318697384310808899">"Creşteţi valoarea pentru an"</string>
- <string name="date_picker_decrement_year_button" msgid="4482021813491121717">"Reduceţi valoarea pentru an"</string>
+ <string name="date_picker_increment_month_button" msgid="5369998479067934110">"Creșteți valoarea pentru lună"</string>
+ <string name="date_picker_decrement_month_button" msgid="1832698995541726019">"Reduceți valoarea pentru lună"</string>
+ <string name="date_picker_increment_day_button" msgid="7130465412308173903">"Creșteți valoarea pentru zi"</string>
+ <string name="date_picker_decrement_day_button" msgid="4131881521818750031">"Reduceți valoarea pentru zi"</string>
+ <string name="date_picker_increment_year_button" msgid="6318697384310808899">"Creșteți valoarea pentru an"</string>
+ <string name="date_picker_decrement_year_button" msgid="4482021813491121717">"Reduceți valoarea pentru an"</string>
<string name="date_picker_prev_month_button" msgid="2858244643992056505">"Luna trecută"</string>
<string name="date_picker_next_month_button" msgid="5559507736887605055">"Luna viitoare"</string>
<string name="keyboardview_keycode_alt" msgid="4856868820040051939">"Alt"</string>
<string name="keyboardview_keycode_cancel" msgid="1203984017245783244">"Anulați"</string>
- <string name="keyboardview_keycode_delete" msgid="3337914833206635744">"Ștergeţi"</string>
+ <string name="keyboardview_keycode_delete" msgid="3337914833206635744">"Ștergeți"</string>
<string name="keyboardview_keycode_done" msgid="1992571118466679775">"Terminat"</string>
<string name="keyboardview_keycode_mode_change" msgid="4547387741906537519">"Schimbarea modului"</string>
<string name="keyboardview_keycode_shift" msgid="2270748814315147690">"Shift"</string>
<string name="keyboardview_keycode_enter" msgid="2985864015076059467">"Enter"</string>
- <string name="activitychooserview_choose_application" msgid="2125168057199941199">"Alegeţi o aplicație"</string>
+ <string name="activitychooserview_choose_application" msgid="2125168057199941199">"Alegeți o aplicație"</string>
<string name="activitychooserview_choose_application_error" msgid="8624618365481126668">"Nu s-a putut lansa <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
- <string name="shareactionprovider_share_with" msgid="806688056141131819">"Permiteţi accesul pentru"</string>
- <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Permiteţi accesul pentru <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
- <string name="content_description_sliding_handle" msgid="415975056159262248">"Mâner glisant. Atingeţi și ţineţi apăsat."</string>
+ <string name="shareactionprovider_share_with" msgid="806688056141131819">"Permiteți accesul pentru"</string>
+ <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Permiteți accesul pentru <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
+ <string name="content_description_sliding_handle" msgid="415975056159262248">"Mâner glisant. Atingeți și țineți apăsat."</string>
<string name="description_target_unlock_tablet" msgid="3833195335629795055">"Glisaţi pentru a debloca."</string>
<string name="keyboard_headset_required_to_hear_password" msgid="7011927352267668657">"Conectaţi un set căşti-microfon pentru a auzi tastele apăsate când introduceţi parola."</string>
<string name="keyboard_password_character_no_headset" msgid="2859873770886153678">"Punct."</string>
<string name="action_bar_home_description" msgid="5293600496601490216">"Navigaţi la ecranul de pornire"</string>
<string name="action_bar_up_description" msgid="2237496562952152589">"Navigaţi în sus"</string>
- <string name="action_menu_overflow_description" msgid="2295659037509008453">"Mai multe opţiuni"</string>
+ <string name="action_menu_overflow_description" msgid="2295659037509008453">"Mai multe opțiuni"</string>
<string name="action_bar_home_description_format" msgid="7965984360903693903">"%1$s, %2$s"</string>
<string name="action_bar_home_subtitle_description_format" msgid="6985546530471780727">"%1$s, %2$s, %3$s"</string>
<string name="storage_internal" msgid="4891916833657929263">"Stocare internă"</string>
@@ -1223,7 +1223,7 @@
<string name="storage_usb_drive_label" msgid="4501418548927759953">"Unitate USB <xliff:g id="MANUFACTURER">%s</xliff:g>"</string>
<string name="storage_usb" msgid="3017954059538517278">"Dsipozitiv de stocare USB"</string>
<string name="data_usage_warning_title" msgid="1955638862122232342">"Avertisment de utiliz. a datelor"</string>
- <string name="data_usage_warning_body" msgid="2814673551471969954">"Atingeţi pt. a afişa utiliz./set."</string>
+ <string name="data_usage_warning_body" msgid="2814673551471969954">"Atingeți pt. a afişa utiliz./set."</string>
<string name="data_usage_3g_limit_title" msgid="4361523876818447683">"Ați atins limita de date 2G-3G"</string>
<string name="data_usage_4g_limit_title" msgid="4609566827219442376">"Ați atins limita de date 4G"</string>
<string name="data_usage_mobile_limit_title" msgid="557158376602636112">"Ați atins limita de date mobile"</string>
@@ -1235,7 +1235,7 @@
<string name="data_usage_wifi_limit_snoozed_title" msgid="8743856006384825974">"S-a depăşit limita de date Wi-Fi"</string>
<string name="data_usage_limit_snoozed_body" msgid="7035490278298441767">"<xliff:g id="SIZE">%s</xliff:g> peste limita specificată."</string>
<string name="data_usage_restricted_title" msgid="5965157361036321914">"Datele de fundal restricţionate"</string>
- <string name="data_usage_restricted_body" msgid="6741521330997452990">"Atingeţi pt. a elimina limita."</string>
+ <string name="data_usage_restricted_body" msgid="6741521330997452990">"Atingeți pt. a elimina limita."</string>
<string name="ssl_certificate" msgid="6510040486049237639">"Certificat de securitate"</string>
<string name="ssl_certificate_is_valid" msgid="6825263250774569373">"Certificatul este valid."</string>
<string name="issued_to" msgid="454239480274921032">"Emis către:"</string>
@@ -1251,7 +1251,7 @@
<string name="sha256_fingerprint" msgid="4391271286477279263">"Amprentă SHA-256:"</string>
<string name="sha1_fingerprint" msgid="7930330235269404581">"Amprentă SHA-1:"</string>
<string name="activity_chooser_view_see_all" msgid="4292569383976636200">"Afişaţi-le pe toate"</string>
- <string name="activity_chooser_view_dialog_title_default" msgid="4710013864974040615">"Alegeţi activitatea"</string>
+ <string name="activity_chooser_view_dialog_title_default" msgid="4710013864974040615">"Alegeți activitatea"</string>
<string name="share_action_provider_share_with" msgid="5247684435979149216">"Distribuiţi pentru"</string>
<string name="list_delimeter" msgid="3975117572185494152">", "</string>
<string name="sending" msgid="3245653681008218030">"Se trimite..."</string>
@@ -1263,7 +1263,7 @@
<string name="default_audio_route_name" product="tablet" msgid="4617053898167127471">"Tabletă"</string>
<string name="default_audio_route_name" product="tv" msgid="9158088547603019321">"TV"</string>
<string name="default_audio_route_name" product="default" msgid="4239291273420140123">"Telefon"</string>
- <string name="default_audio_route_name_headphones" msgid="8119971843803439110">"Căşti"</string>
+ <string name="default_audio_route_name_headphones" msgid="8119971843803439110">"Căști"</string>
<string name="default_audio_route_name_dock_speakers" msgid="6240602982276591864">"Difuz. dispozit. andocare"</string>
<string name="default_media_route_name_hdmi" msgid="2450970399023478055">"HDMI"</string>
<string name="default_audio_route_category_name" msgid="3722811174003886946">"Sistem"</string>
@@ -1307,9 +1307,9 @@
<string name="kg_login_instructions" msgid="1100551261265506448">"Pentru a debloca, conectaţi-vă cu Contul dvs. Google."</string>
<string name="kg_login_username_hint" msgid="5718534272070920364">"Nume de utilizator (e-mail)"</string>
<string name="kg_login_password_hint" msgid="9057289103827298549">"Parolă"</string>
- <string name="kg_login_submit_button" msgid="5355904582674054702">"Conectaţi-vă"</string>
+ <string name="kg_login_submit_button" msgid="5355904582674054702">"Conectați-vă"</string>
<string name="kg_login_invalid_input" msgid="5754664119319872197">"Nume de utilizator sau parolă nevalide."</string>
- <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Aţi uitat numele de utilizator sau parola?\nAccesaţi "<b>"google.com/accounts/recovery"</b>"."</string>
+ <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Aţi uitat numele de utilizator sau parola?\nAccesați "<b>"google.com/accounts/recovery"</b>"."</string>
<string name="kg_login_checking_password" msgid="1052685197710252395">"Se verifică contul…"</string>
<string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Aţi introdus incorect codul PIN de <xliff:g id="NUMBER_0">%d</xliff:g> ori.\n\nÎncercați din nou peste <xliff:g id="NUMBER_1">%d</xliff:g> (de) secunde."</string>
<string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Aţi introdus incorect parola de <xliff:g id="NUMBER_0">%d</xliff:g> ori. \n\nÎncercați din nou peste <xliff:g id="NUMBER_1">%d</xliff:g> (de) secunde."</string>
@@ -1505,6 +1505,7 @@
<item quantity="one">Pentru 1 h</item>
</plurals>
<string name="zen_mode_until" msgid="7336308492289875088">"Până la <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
+ <string name="zen_mode_alarm" msgid="9128205721301330797">"Până la <xliff:g id="FORMATTEDTIME">%1$s</xliff:g> (următoarea alarmă)"</string>
<string name="zen_mode_forever" msgid="7420011936770086993">"Până la dezactivare"</string>
<string name="zen_mode_forever_dnd" msgid="3792132696572189081">"Până când dezactivați „Nu deranja”"</string>
<string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g>/<xliff:g id="REST">%2$s</xliff:g>"</string>
diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml
index be9b3fc..b857f27 100644
--- a/core/res/res/values-ru/strings.xml
+++ b/core/res/res/values-ru/strings.xml
@@ -914,7 +914,7 @@
<string name="anr_application_process" msgid="8941757607340481057">"Приложение \"<xliff:g id="APPLICATION">%1$s</xliff:g>\" не отвечает. Закрыть его?"</string>
<string name="anr_process" msgid="6513209874880517125">"Приложение \"<xliff:g id="PROCESS">%1$s</xliff:g>\" не отвечает.\n\nЗакрыть его?"</string>
<string name="force_close" msgid="8346072094521265605">"ОК"</string>
- <string name="report" msgid="4060218260984795706">"Отзыв"</string>
+ <string name="report" msgid="4060218260984795706">"Отправить отчет"</string>
<string name="wait" msgid="7147118217226317732">"Подождать"</string>
<string name="webpage_unresponsive" msgid="3272758351138122503">"Страница не отвечает.\n\nЗакрыть ее?"</string>
<string name="launch_warning_title" msgid="1547997780506713581">"Приложение перенаправлено"</string>
@@ -1056,7 +1056,7 @@
<string name="usb_ptp_notification_title" msgid="1347328437083192112">"Передача фото через USB"</string>
<string name="usb_midi_notification_title" msgid="4850904915889144654">"MIDI через USB"</string>
<string name="usb_accessory_notification_title" msgid="7848236974087653666">"USB-устройство подключено"</string>
- <string name="usb_notification_message" msgid="7347368030849048437">"Ещё варианты"</string>
+ <string name="usb_notification_message" msgid="7347368030849048437">"Нажмите, чтобы настроить."</string>
<string name="adb_active_notification_title" msgid="6729044778949189918">"Отладка по USB разрешена"</string>
<string name="adb_active_notification_message" msgid="1016654627626476142">"Нажмите, чтобы отключить отладку по USB."</string>
<string name="select_input_method" msgid="8547250819326693584">"Выбор раскладки"</string>
@@ -1150,7 +1150,7 @@
<string name="no_file_chosen" msgid="6363648562170759465">"Не выбран файл"</string>
<string name="reset" msgid="2448168080964209908">"Сбросить"</string>
<string name="submit" msgid="1602335572089911941">"Отправить"</string>
- <string name="car_mode_disable_notification_title" msgid="3164768212003864316">"Включен режим \"Штурман\""</string>
+ <string name="car_mode_disable_notification_title" msgid="3164768212003864316">"Режим \"В автомобиле\""</string>
<string name="car_mode_disable_notification_message" msgid="8035230537563503262">"Чтобы выйти, нажмите здесь."</string>
<string name="tethered_notification_title" msgid="3146694234398202601">"Включен режим модема"</string>
<string name="tethered_notification_message" msgid="6857031760103062982">"Нажмите для настройки."</string>
@@ -1522,6 +1522,7 @@
<item quantity="other">На %d часа</item>
</plurals>
<string name="zen_mode_until" msgid="7336308492289875088">"До <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
+ <string name="zen_mode_alarm" msgid="9128205721301330797">"Следующий сигнал в <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
<string name="zen_mode_forever" msgid="7420011936770086993">"Пока я не отключу"</string>
<string name="zen_mode_forever_dnd" msgid="3792132696572189081">"Пока вы не отключите режим \"Не беспокоить\""</string>
<string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string>
diff --git a/core/res/res/values-si-rLK/strings.xml b/core/res/res/values-si-rLK/strings.xml
index 81e90d2..7663333 100644
--- a/core/res/res/values-si-rLK/strings.xml
+++ b/core/res/res/values-si-rLK/strings.xml
@@ -229,7 +229,7 @@
<string name="permgrouplab_contacts" msgid="3657758145679177612">"සම්බන්ධතා"</string>
<string name="permgroupdesc_contacts" msgid="6951499528303668046">"ඔබේ සම්බන්ධතාවලට පිවිසෙන්න"</string>
<string name="permgrouplab_location" msgid="7275582855722310164">"ස්ථානය"</string>
- <string name="permgroupdesc_location" msgid="1346617465127855033">"මෙම උපාංගයේ ස්ථානය ප්රවේශ කිරීම"</string>
+ <string name="permgroupdesc_location" msgid="1346617465127855033">"මෙම උපාංගයේ ස්ථානයට ප්රවේශ කරන්න"</string>
<string name="permgrouplab_calendar" msgid="5863508437783683902">"දින දර්ශනය"</string>
<string name="permgroupdesc_calendar" msgid="3889615280211184106">"ඔබේ දින දර්ශනයට පිවිසෙන්න"</string>
<string name="permgrouplab_sms" msgid="228308803364967808">"කෙටි පණිවිඩ"</string>
@@ -1490,6 +1490,7 @@
<item quantity="other">පැය %d ක් සඳහා</item>
</plurals>
<string name="zen_mode_until" msgid="7336308492289875088">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g> තෙක්"</string>
+ <string name="zen_mode_alarm" msgid="9128205721301330797">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g> තෙක් (ඊළඟ එලාමය)"</string>
<string name="zen_mode_forever" msgid="7420011936770086993">"ඔබ මෙය අක්රිය කරන තුරු"</string>
<string name="zen_mode_forever_dnd" msgid="3792132696572189081">"බාධා නොකරන්න ඔබ අක්රිය කරන තුරු"</string>
<string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string>
diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml
index cbff7d5..933c3fe 100644
--- a/core/res/res/values-sk/strings.xml
+++ b/core/res/res/values-sk/strings.xml
@@ -1522,6 +1522,7 @@
<item quantity="one">Na 1 h</item>
</plurals>
<string name="zen_mode_until" msgid="7336308492289875088">"Do <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
+ <string name="zen_mode_alarm" msgid="9128205721301330797">"Do <xliff:g id="FORMATTEDTIME">%1$s</xliff:g> (ďalší budík)"</string>
<string name="zen_mode_forever" msgid="7420011936770086993">"Dokým túto funkciu nevypnete"</string>
<string name="zen_mode_forever_dnd" msgid="3792132696572189081">"Dokým nevypnete stav Nerušiť"</string>
<string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string>
diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml
index ddeff80..304fe52 100644
--- a/core/res/res/values-sl/strings.xml
+++ b/core/res/res/values-sl/strings.xml
@@ -992,7 +992,7 @@
<string name="wifi_p2p_failed_message" msgid="3763669677935623084">"Wi-Fi Direct ni bilo mogoče zagnati."</string>
<string name="wifi_p2p_enabled_notification_title" msgid="2068321881673734886">"Wi-Fi Direct je vklopljen"</string>
<string name="wifi_p2p_enabled_notification_message" msgid="1638949953993894335">"Dotaknite se za nastavitve"</string>
- <string name="accept" msgid="1645267259272829559">"Sprejmi"</string>
+ <string name="accept" msgid="1645267259272829559">"Sprejmem"</string>
<string name="decline" msgid="2112225451706137894">"Zavrni"</string>
<string name="wifi_p2p_invitation_sent_title" msgid="1318975185112070734">"Povabilo je poslano"</string>
<string name="wifi_p2p_invitation_to_connect_title" msgid="4958803948658533637">"Povabilo za povezavo"</string>
@@ -1522,6 +1522,7 @@
<item quantity="other">%d h</item>
</plurals>
<string name="zen_mode_until" msgid="7336308492289875088">"Do <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
+ <string name="zen_mode_alarm" msgid="9128205721301330797">"Do <xliff:g id="FORMATTEDTIME">%1$s</xliff:g> (naslednji alarm)"</string>
<string name="zen_mode_forever" msgid="7420011936770086993">"Dokler tega ne izklopite"</string>
<string name="zen_mode_forever_dnd" msgid="3792132696572189081">"Dokler ne izklopite načina »ne moti«"</string>
<string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g>/<xliff:g id="REST">%2$s</xliff:g>"</string>
diff --git a/core/res/res/values-sq-rAL/strings.xml b/core/res/res/values-sq-rAL/strings.xml
index 508e88e0..3d11d24 100644
--- a/core/res/res/values-sq-rAL/strings.xml
+++ b/core/res/res/values-sq-rAL/strings.xml
@@ -229,7 +229,7 @@
<string name="permgrouplab_contacts" msgid="3657758145679177612">"Kontaktet"</string>
<string name="permgroupdesc_contacts" msgid="6951499528303668046">"qasu te kontaktet e tua"</string>
<string name="permgrouplab_location" msgid="7275582855722310164">"Vendndodhja"</string>
- <string name="permgroupdesc_location" msgid="1346617465127855033">"qasu te vendndodhja e kësaj pajisjeje"</string>
+ <string name="permgroupdesc_location" msgid="1346617465127855033">"qasjen te vendndodhja e kësaj pajisjeje"</string>
<string name="permgrouplab_calendar" msgid="5863508437783683902">"Kalendari"</string>
<string name="permgroupdesc_calendar" msgid="3889615280211184106">"qasu te kalendari yt"</string>
<string name="permgrouplab_sms" msgid="228308803364967808">"SMS"</string>
@@ -1488,6 +1488,7 @@
<item quantity="one">Për 1 orë</item>
</plurals>
<string name="zen_mode_until" msgid="7336308492289875088">"Deri në <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
+ <string name="zen_mode_alarm" msgid="9128205721301330797">"Deri në <xliff:g id="FORMATTEDTIME">%1$s</xliff:g> (alarmi tjetër)"</string>
<string name="zen_mode_forever" msgid="7420011936770086993">"Deri sa ta çaktivizosh këtë"</string>
<string name="zen_mode_forever_dnd" msgid="3792132696572189081">"Deri sa të çaktivizosh gjendjen \"Mos shqetëso\""</string>
<string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string>
diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml
index b283250..d4f3ffb 100644
--- a/core/res/res/values-sr/strings.xml
+++ b/core/res/res/values-sr/strings.xml
@@ -230,21 +230,21 @@
<string name="permgrouplab_contacts" msgid="3657758145679177612">"Контакти"</string>
<string name="permgroupdesc_contacts" msgid="6951499528303668046">"приступи контактима"</string>
<string name="permgrouplab_location" msgid="7275582855722310164">"Локација"</string>
- <string name="permgroupdesc_location" msgid="1346617465127855033">"приступ локацији овог уређаја"</string>
+ <string name="permgroupdesc_location" msgid="1346617465127855033">"приступи локацији овог уређаја"</string>
<string name="permgrouplab_calendar" msgid="5863508437783683902">"Календар"</string>
<string name="permgroupdesc_calendar" msgid="3889615280211184106">"приступи календару"</string>
<string name="permgrouplab_sms" msgid="228308803364967808">"SMS"</string>
<string name="permgroupdesc_sms" msgid="4656988620100940350">"шаље и прегледа SMS поруке"</string>
<string name="permgrouplab_storage" msgid="1971118770546336966">"Складиште"</string>
- <string name="permgroupdesc_storage" msgid="637758554581589203">"приступи сликама, медијима и датотекама на уређају"</string>
+ <string name="permgroupdesc_storage" msgid="637758554581589203">"приступа сликама, медијима и датотекама на уређају"</string>
<string name="permgrouplab_microphone" msgid="171539900250043464">"Микрофон"</string>
- <string name="permgroupdesc_microphone" msgid="4988812113943554584">"снимање аудио снимака"</string>
+ <string name="permgroupdesc_microphone" msgid="4988812113943554584">"снима аудио снимке"</string>
<string name="permgrouplab_camera" msgid="4820372495894586615">"Камера"</string>
- <string name="permgroupdesc_camera" msgid="3250611594678347720">"снимање слика и видео снимака"</string>
+ <string name="permgroupdesc_camera" msgid="3250611594678347720">"снима слике и видео снимке"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"Телефон"</string>
- <string name="permgroupdesc_phone" msgid="6234224354060641055">"упућивање телефонских позива и управљање њима"</string>
+ <string name="permgroupdesc_phone" msgid="6234224354060641055">"упућује телефонске позиве и управља њима"</string>
<string name="permgrouplab_sensors" msgid="416037179223226722">"Сензори за тело"</string>
- <string name="permgroupdesc_sensors" msgid="7147968539346634043">"приступ подацима сензора о виталним функцијама"</string>
+ <string name="permgroupdesc_sensors" msgid="7147968539346634043">"приступа подацима сензора о виталним функцијама"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Преузима садржај прозора"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Проверава садржај прозора са којим остварујете интеракцију."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Укључи Истраживања додиром"</string>
@@ -273,7 +273,7 @@
<string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"Омогућава апликацији да чита поруке инфо сервиса које уређај прима. Упозорења инфо сервиса се на неким локацијама примају као упозорења на хитне случајеве. Злонамерне апликације могу да утичу на учинак или ометају функционисање уређаја када се прими порука инфо сервиса о хитном случају."</string>
<string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"читање пријављених фидова"</string>
<string name="permdesc_subscribedFeedsRead" msgid="5557058907906144505">"Дозвољава апликацији да преузима детаље о тренутно синхронизованим фидовима."</string>
- <string name="permlab_sendSms" msgid="7544599214260982981">"шаљи и прегледај SMS поруке"</string>
+ <string name="permlab_sendSms" msgid="7544599214260982981">"шаље и прегледа SMS поруке"</string>
<string name="permdesc_sendSms" msgid="7094729298204937667">"Дозвољава апликацији да шаље SMS поруке. Ово може да доведе до неочекиваних трошкова. Злонамерне апликације могу да шаљу поруке без ваше потврде, што може да изазове трошкове."</string>
<string name="permlab_readSms" msgid="8745086572213270480">"читање текстуалних порука (SMS или MMS)"</string>
<string name="permdesc_readSms" product="tablet" msgid="2467981548684735522">"Дозвољава апликацији да чита SMS поруке ускладиштене на таблету или SIM картици. Ово омогућава апликацији да чита све SMS поруке, без обзира на садржај или поверљивост."</string>
@@ -1505,6 +1505,7 @@
<item quantity="other">За %d с</item>
</plurals>
<string name="zen_mode_until" msgid="7336308492289875088">"До <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
+ <string name="zen_mode_alarm" msgid="9128205721301330797">"До <xliff:g id="FORMATTEDTIME">%1$s</xliff:g> (следећи аларм)"</string>
<string name="zen_mode_forever" msgid="7420011936770086993">"Док не искључите"</string>
<string name="zen_mode_forever_dnd" msgid="3792132696572189081">"Док не искључите режим Не узнемиравај"</string>
<string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g>/<xliff:g id="REST">%2$s</xliff:g>"</string>
diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml
index b293655..e815fdb 100644
--- a/core/res/res/values-sv/strings.xml
+++ b/core/res/res/values-sv/strings.xml
@@ -163,7 +163,7 @@
<string name="contentServiceTooManyDeletesNotificationDesc" msgid="8100981435080696431">"För många <xliff:g id="CONTENT_TYPE">%s</xliff:g>-borttagningar."</string>
<string name="low_memory" product="tablet" msgid="6494019234102154896">"Pekdatorns lagringsutrymme är fullt. Ta bort några filer för att frigöra utrymme."</string>
<string name="low_memory" product="watch" msgid="4415914910770005166">"Klockans lagringsutrymme är fullt. Ta bort några filer för att frigöra utrymme."</string>
- <string name="low_memory" product="tv" msgid="516619861191025923">"Lagringsutrymmet på tv:n är fullt. Ta bort några filer för att frigöra utrymme."</string>
+ <string name="low_memory" product="tv" msgid="516619861191025923">"Lagringsutrymmet på TV:n är fullt. Ta bort några filer för att frigöra utrymme."</string>
<string name="low_memory" product="default" msgid="3475999286680000541">"Mobilens lagringsutrymme är fullt. Ta bort några filer för att frigöra utrymme."</string>
<string name="ssl_ca_cert_warning" msgid="5848402127455021714">"Nätverket kan vara övervakat"</string>
<string name="ssl_ca_cert_noti_by_unknown" msgid="4475437862189850602">"Av en okänd tredje part"</string>
@@ -177,7 +177,7 @@
<string name="factory_reset_message" msgid="4905025204141900666">"Administratörsappen saknar delar eller är skadad och kan inte användas. Enheten kommer nu att rensas. Kontakta administratören om du behöver hjälp."</string>
<string name="me" msgid="6545696007631404292">"Jag"</string>
<string name="power_dialog" product="tablet" msgid="8545351420865202853">"Alternativ för surfplattan"</string>
- <string name="power_dialog" product="tv" msgid="6153888706430556356">"Tv-alternativ"</string>
+ <string name="power_dialog" product="tv" msgid="6153888706430556356">"TV-alternativ"</string>
<string name="power_dialog" product="default" msgid="1319919075463988638">"Telefonalternativ"</string>
<string name="silent_mode" msgid="7167703389802618663">"Tyst läge"</string>
<string name="turn_on_radio" msgid="3912793092339962371">"Aktivera trådlöst"</string>
@@ -195,7 +195,7 @@
<string name="reboot_to_reset_message" msgid="2432077491101416345">"Startar om …"</string>
<string name="shutdown_progress" msgid="2281079257329981203">"Avslutar…"</string>
<string name="shutdown_confirm" product="tablet" msgid="3385745179555731470">"Din surfplatta stängs av."</string>
- <string name="shutdown_confirm" product="tv" msgid="476672373995075359">"Tv:n stängs av."</string>
+ <string name="shutdown_confirm" product="tv" msgid="476672373995075359">"TV:n stängs av."</string>
<string name="shutdown_confirm" product="watch" msgid="3490275567476369184">"Klockan stängs av."</string>
<string name="shutdown_confirm" product="default" msgid="649792175242821353">"Din telefon stängs av."</string>
<string name="shutdown_confirm_question" msgid="2906544768881136183">"Vill du stänga av?"</string>
@@ -276,7 +276,7 @@
<string name="permdesc_sendSms" msgid="7094729298204937667">"Tillåter att appen skickar SMS. Detta kan leda till oväntade avgifter. Skadliga appar kan skicka meddelanden utan ditt godkännande vilket kan kosta pengar."</string>
<string name="permlab_readSms" msgid="8745086572213270480">"läsa dina textmeddelanden (SMS eller MMS)"</string>
<string name="permdesc_readSms" product="tablet" msgid="2467981548684735522">"Tillåter att appen läser SMS som sparats på surfplattan eller på SIM-kortet. Med den här behörigheten tillåts appen att läsa alla SMS oavsett innehåll eller sekretess."</string>
- <string name="permdesc_readSms" product="tv" msgid="5102425513647038535">"Tillåter att appen läser sms som har sparats på tv:n eller SIM-kortet. På så sätt kan appen läsa alla sms oavsett innehåll eller sekretess."</string>
+ <string name="permdesc_readSms" product="tv" msgid="5102425513647038535">"Tillåter att appen läser sms som har sparats på TV:n eller SIM-kortet. På så sätt kan appen läsa alla sms oavsett innehåll eller sekretess."</string>
<string name="permdesc_readSms" product="default" msgid="3695967533457240550">"Tillåter att appen läser SMS som sparats på mobilen eller på SIM-kortet. Med den här behörigheten tillåts appen att läsa alla SMS oavsett innehåll eller sekretess."</string>
<string name="permlab_receiveWapPush" msgid="5991398711936590410">"ta emot textmeddelanden (WAP)"</string>
<string name="permdesc_receiveWapPush" msgid="748232190220583385">"Tillåter att appen tar emot och hanterar WAP-meddelanden. Med den här behörigheten kan appen övervaka eller ta bort meddelanden som skickats till dig utan att visa dem för dig."</string>
@@ -294,7 +294,7 @@
<string name="permdesc_systemAlertWindow" msgid="8584678381972820118">"Tillåter att appen att dras ovanpå andra appar eller delar av användargränssnittet. De kan störa din användning av gränssnittet i olika appar eller ändra vad du tror visas i andra appar."</string>
<string name="permlab_persistentActivity" msgid="8841113627955563938">"se till att appen alltid körs"</string>
<string name="permdesc_persistentActivity" product="tablet" msgid="8525189272329086137">"Tillåter att delar av appen läggs beständigt i minnet. Detta kan innebära att det tillgängliga minnet för andra appar begränsas, vilket gör surfplattan långsam."</string>
- <string name="permdesc_persistentActivity" product="tv" msgid="5086862529499103587">"Tillåter att en app gör vissa delar beständiga i minnet. Det kan begränsa mängden minne som är tillgänglig för andra appar och gör tv:n långsammare."</string>
+ <string name="permdesc_persistentActivity" product="tv" msgid="5086862529499103587">"Tillåter att en app gör vissa delar beständiga i minnet. Det kan begränsa mängden minne som är tillgänglig för andra appar och gör TV:n långsammare."</string>
<string name="permdesc_persistentActivity" product="default" msgid="4384760047508278272">"Tillåter att delar av appen läggs beständigt i minnet. Detta kan innebära att det tillgängliga minnet för andra appar begränsas, vilket gör mobilen långsam."</string>
<string name="permlab_getPackageSize" msgid="7472921768357981986">"mäta appens lagringsplats"</string>
<string name="permdesc_getPackageSize" msgid="3921068154420738296">"Tillåter att appen hämtar kod, data och cachestorlekar"</string>
@@ -306,33 +306,33 @@
<string name="permdesc_receiveBootCompleted" product="default" msgid="513950589102617504">"Tillåter att appen startar automatiskt när systemet har startats om. Detta kan innebära att det tar längre tid att starta mobilen och att mobilen blir långsammare i och med att appen hela tiden körs i bakgrunden."</string>
<string name="permlab_broadcastSticky" msgid="7919126372606881614">"Skicka sticky broadcast"</string>
<string name="permdesc_broadcastSticky" product="tablet" msgid="7749760494399915651">"Tillåter att appen skickar sticky broadcasts, som finns kvar när sändningen är slut. Vid intensiv användning kan mobilen bli långsam eller instabil eftersom minnet överbelastas."</string>
- <string name="permdesc_broadcastSticky" product="tv" msgid="6839285697565389467">"Tillåter att appen skickar sticky broadcasts som finns kvar när sändningen är slut. Överdriven användning kan göra tv:n seg eller instabil eftersom den använder för mycket minne."</string>
+ <string name="permdesc_broadcastSticky" product="tv" msgid="6839285697565389467">"Tillåter att appen skickar sticky broadcasts som finns kvar när sändningen är slut. Överdriven användning kan göra TV:n seg eller instabil eftersom den använder för mycket minne."</string>
<string name="permdesc_broadcastSticky" product="default" msgid="2825803764232445091">"Tillåter att appen skickar sticky broadcast, som finns kvar när sändningen är slut. Vid intensiv användning kan mobilen bli långsam eller instabil eftersom minnet överbelastas."</string>
<string name="permlab_readContacts" msgid="8348481131899886131">"läsa dina kontakter"</string>
<string name="permdesc_readContacts" product="tablet" msgid="5294866856941149639">"Tillåter att appen läser kontaktuppgifter som sparats på surfplattan, inklusive information om hur ofta du har ringt, skickat e-post till eller på andra sätt kommunicerat med specifika personer. Med den här behörigheten tillåts appen att spara kontaktuppgifter. Skadliga appar kan dela uppgifterna med andra utan din vetskap."</string>
- <string name="permdesc_readContacts" product="tv" msgid="1839238344654834087">"Tillåter att appen läser data om dina kontakter som sparats på tv:n, bland annat hur ofta du har ringt, skickat e-post eller kommunicerat på andra sätt med enskilda individer. Med den här behörigheten kan appar spara dina kontaktuppgifter och skadliga appar kan dela kontaktuppgifter utan att du vet om det."</string>
+ <string name="permdesc_readContacts" product="tv" msgid="1839238344654834087">"Tillåter att appen läser data om dina kontakter som sparats på TV:n, bland annat hur ofta du har ringt, skickat e-post eller kommunicerat på andra sätt med enskilda individer. Med den här behörigheten kan appar spara dina kontaktuppgifter och skadliga appar kan dela kontaktuppgifter utan att du vet om det."</string>
<string name="permdesc_readContacts" product="default" msgid="8440654152457300662">"Tillåter att appen läser kontaktuppgifter som sparats på mobilen, inklusive information om hur ofta du har ringt, skickat e-post till eller på andra sätt kommunicerat med specifika personer. Med den här behörigheten tillåts appen att spara kontaktuppgifter. Skadliga appar kan dela uppgifterna med andra utan din vetskap."</string>
<string name="permlab_writeContacts" msgid="5107492086416793544">"ändra kontakterna"</string>
<string name="permdesc_writeContacts" product="tablet" msgid="897243932521953602">"Tillåter att appen ändrar kontaktuppgifter som sparats på surfplattan, inklusive information om hur ofta du har ringt, skickat e-post till eller på andra sätt kommunicerat med specifika personer. Med den här behörigheten tillåts appar att ta bort kontaktuppgifter."</string>
- <string name="permdesc_writeContacts" product="tv" msgid="5438230957000018959">"Tillåter att appen ändrar uppgifterna om dina kontakter som har sparats på tv:n, bland annat hur ofta du har ringt, skickat e-post eller kommunicerat på andra sätt med särskilda kontakter. Med den här behörigheten kan appar ta bort kontaktuppgifter."</string>
+ <string name="permdesc_writeContacts" product="tv" msgid="5438230957000018959">"Tillåter att appen ändrar uppgifterna om dina kontakter som har sparats på TV:n, bland annat hur ofta du har ringt, skickat e-post eller kommunicerat på andra sätt med särskilda kontakter. Med den här behörigheten kan appar ta bort kontaktuppgifter."</string>
<string name="permdesc_writeContacts" product="default" msgid="589869224625163558">"Tillåter att appen ändrar kontaktuppgifter som sparats på mobilen, inklusive information om hur ofta du har ringt, skickat e-post till eller på andra sätt kommunicerat med specifika personer. Med den här behörigheten tillåts appar att ta bort kontaktuppgifter."</string>
<string name="permlab_readCallLog" msgid="3478133184624102739">"läs samtalslogg"</string>
<string name="permdesc_readCallLog" product="tablet" msgid="3700645184870760285">"Tillåter att appen läser pekdatorns samtalslista, inklusive uppgifter om inkommande och utgående samtal. Med den här behörigheten tillåts appen att spara samtalshistoriken. Skadliga appar kan dela uppgifterna med andra utan din vetskap."</string>
- <string name="permdesc_readCallLog" product="tv" msgid="5611770887047387926">"Tillåter att appen läser tv:ns samtalslista, bland annat data om inkommande och utgående samtal. Med den här behörigheten kan appar spara data i dina samtalslistor och skadliga appar kan dela data i samtalslistor utan att du vet om det."</string>
+ <string name="permdesc_readCallLog" product="tv" msgid="5611770887047387926">"Tillåter att appen läser TV:ns samtalslista, bland annat data om inkommande och utgående samtal. Med den här behörigheten kan appar spara data i dina samtalslistor och skadliga appar kan dela data i samtalslistor utan att du vet om det."</string>
<string name="permdesc_readCallLog" product="default" msgid="5777725796813217244">"Tillåter att appen läser mobilens samtalslista, inklusive uppgifter om inkommande och utgående samtal. Med den här behörigheten tillåts appen att spara samtalshistoriken. Skadliga appar kan dela uppgifterna med andra utan din vetskap."</string>
<string name="permlab_writeCallLog" msgid="8552045664743499354">"skriv samtalslogg"</string>
<string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"Tillåter att appen gör ändringar i pekdatorns samtalslista, inklusive i uppgifter om inkommande och utgående samtal. Skadliga program kan använda detta för att radera eller ändra din samtalslista."</string>
- <string name="permdesc_writeCallLog" product="tv" msgid="4225034892248398019">"Tillåter att appen gör ändringar i tv:ns samtalslista, inklusive i uppgifter om inkommande och utgående samtal. Skadliga appar kan använda detta för att rensa eller ändra din samtalslista."</string>
+ <string name="permdesc_writeCallLog" product="tv" msgid="4225034892248398019">"Tillåter att appen gör ändringar i TV:ns samtalslista, inklusive i uppgifter om inkommande och utgående samtal. Skadliga appar kan använda detta för att rensa eller ändra din samtalslista."</string>
<string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"Tillåter att appen gör ändringar i mobilens samtalslista, inklusive i uppgifter om inkommande och utgående samtal. Skadliga program kan använda detta för att radera eller ändra din samtalslista."</string>
<string name="permlab_bodySensors" msgid="4871091374767171066">"kroppssens. (för hjärtat m.m.)"</string>
<string name="permdesc_bodySensors" product="default" msgid="4380015021754180431">"Ger appen åtkomst till information från sensorer om ditt fysiska tillstånd, till exempel din puls."</string>
<string name="permlab_readCalendar" msgid="5972727560257612398">"läsa kalenderuppgifter plus konfidentiell information"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="4216462049057658723">"Tillåter att appen läser alla kalenderuppgifter som sparats på surfplattan, inklusive dina vänners eller kollegors uppgifter. Med den här behörigheten kan appen tillåtas att dela eller spara kalenderuppgifter även om de är sekretessbelagda eller känsliga."</string>
- <string name="permdesc_readCalendar" product="tv" msgid="3191352452242394196">"Tillåter att appen läser alla kalenderhändelser som sparats på tv:n, bland annat de som tillhör vänner eller kollegor. På så sätt kan appen dela eller spara dina kalenderhändelser oavsett sekretess eller känslighet."</string>
+ <string name="permdesc_readCalendar" product="tv" msgid="3191352452242394196">"Tillåter att appen läser alla kalenderhändelser som sparats på TV:n, bland annat de som tillhör vänner eller kollegor. På så sätt kan appen dela eller spara dina kalenderhändelser oavsett sekretess eller känslighet."</string>
<string name="permdesc_readCalendar" product="default" msgid="7434548682470851583">"Tillåter att appen läser alla kalenderuppgifter som sparats på mobilen, inklusive dina vänners eller kollegors uppgifter. Med den här behörigheten kan appen tillåtas att dela eller spara kalenderuppgifter även om de är sekretessbelagda eller känsliga."</string>
<string name="permlab_writeCalendar" msgid="8438874755193825647">"lägga till eller ändra kalenderuppgifter och skicka e-post till gäster utan ägarens vetskap"</string>
<string name="permdesc_writeCalendar" product="tablet" msgid="6679035520113668528">"Tillåter att appen lägger till, tar bort och ändrar sådana händelser som du kan ändra på surfplattan, inklusive dina vänners eller kollegors uppgifter. Detta kan innebära att appen tillåts skicka meddelanden som ser ut att komma från kalenderns ägare eller ändra händelser utan ägarens vetskap."</string>
- <string name="permdesc_writeCalendar" product="tv" msgid="1273290605500902507">"Tillåter att appen lägger till, tar bort och ändrar händelser som du kan ändra på tv:n, inklusive dina vänners eller kollegors uppgifter. Appen kan på så sätt skicka meddelanden som ser ut att komma från kalenderns ägare eller ändra uppgifter utan ägarens vetskap."</string>
+ <string name="permdesc_writeCalendar" product="tv" msgid="1273290605500902507">"Tillåter att appen lägger till, tar bort och ändrar händelser som du kan ändra på TV:n, inklusive dina vänners eller kollegors uppgifter. Appen kan på så sätt skicka meddelanden som ser ut att komma från kalenderns ägare eller ändra uppgifter utan ägarens vetskap."</string>
<string name="permdesc_writeCalendar" product="default" msgid="2324469496327249376">"Tillåter att appen lägger till, tar bort och ändrar sådana händelser som du kan ändra på mobilen, inklusive dina vänners eller kollegors uppgifter. Detta kan innebära att appen tillåts skicka meddelanden som ser ut att komma från kalenderns ägare eller ändra händelser utan ägarens vetskap."</string>
<string name="permlab_accessLocationExtraCommands" msgid="2836308076720553837">"få åtkomst till extra kommandon för platsleverantör"</string>
<string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"Tillåter att appen får åtkomst till extra kommandon för platsleverantör. Detta kan innebära att appen tillåts störa funktionen för GPS eller andra platskällor."</string>
@@ -359,14 +359,14 @@
<string name="permlab_readPhoneState" msgid="9178228524507610486">"läsa telefonens status och identitet"</string>
<string name="permdesc_readPhoneState" msgid="1639212771826125528">"Tillåter att appen kommer åt enhetens telefonfunktioner. Med den här behörigheten tillåts appen att identifiera mobilens telefonnummer och enhets-ID, om ett samtal pågår och vilket nummer samtalet är kopplat till."</string>
<string name="permlab_wakeLock" product="tablet" msgid="1531731435011495015">"förhindra att surfplattan går in i viloläge"</string>
- <string name="permlab_wakeLock" product="tv" msgid="2601193288949154131">"förhindra att tv:n försätts i viloläge"</string>
+ <string name="permlab_wakeLock" product="tv" msgid="2601193288949154131">"förhindra att TV:n försätts i viloläge"</string>
<string name="permlab_wakeLock" product="default" msgid="573480187941496130">"förhindra att telefonen sätts i viloläge"</string>
<string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"Tillåter att appen förhindrar att surfplattan går in i viloläge."</string>
- <string name="permdesc_wakeLock" product="tv" msgid="3208534859208996974">"Tillåter att appen förhindrar att tv:n försätts i viloläge."</string>
+ <string name="permdesc_wakeLock" product="tv" msgid="3208534859208996974">"Tillåter att appen förhindrar att TV:n försätts i viloläge."</string>
<string name="permdesc_wakeLock" product="default" msgid="8559100677372928754">"Tillåter att appen förhindrar att mobilen går in i viloläge."</string>
<string name="permlab_transmitIr" msgid="7545858504238530105">"tillåt IR-sändning"</string>
<string name="permdesc_transmitIr" product="tablet" msgid="5358308854306529170">"Tillåter att appen använder surfplattans IR-sändare."</string>
- <string name="permdesc_transmitIr" product="tv" msgid="3926790828514867101">"Tillåter att appen använder den infraröda sändaren på tv:n."</string>
+ <string name="permdesc_transmitIr" product="tv" msgid="3926790828514867101">"Tillåter att appen använder den infraröda sändaren på TV:n."</string>
<string name="permdesc_transmitIr" product="default" msgid="7957763745020300725">"Tillåter att appen använder mobilens IR-sändare."</string>
<string name="permlab_setWallpaper" msgid="6627192333373465143">"ange bakgrund"</string>
<string name="permdesc_setWallpaper" msgid="7373447920977624745">"Tillåter att appen anger systemets bakgrund."</string>
@@ -374,11 +374,11 @@
<string name="permdesc_setWallpaperHints" msgid="8235784384223730091">"Tillåter att appen ger tips om systemets bakgrundsstorlek."</string>
<string name="permlab_setTimeZone" msgid="2945079801013077340">"ange tidszon"</string>
<string name="permdesc_setTimeZone" product="tablet" msgid="1676983712315827645">"Tillåter att appen ändrar pekdatorns tidszon."</string>
- <string name="permdesc_setTimeZone" product="tv" msgid="888864653946175955">"Tillåter att appen ändrar tidszonen på tv:n."</string>
+ <string name="permdesc_setTimeZone" product="tv" msgid="888864653946175955">"Tillåter att appen ändrar tidszonen på TV:n."</string>
<string name="permdesc_setTimeZone" product="default" msgid="4499943488436633398">"Tillåter att appen ändrar mobilens tidszon."</string>
<string name="permlab_getAccounts" msgid="1086795467760122114">"hitta konton på enheten"</string>
<string name="permdesc_getAccounts" product="tablet" msgid="2741496534769660027">"Tillåter att appen hämtar en lista över alla kända konton på surfplattan. Detta kan inkludera konton som har skapats av appar som du har installerat."</string>
- <string name="permdesc_getAccounts" product="tv" msgid="4190633395633907543">"Tillåter att appen hämtar listan med konton som tv:n kan identifiera. Den kan innehålla konton som skapats av appar som du har installerat."</string>
+ <string name="permdesc_getAccounts" product="tv" msgid="4190633395633907543">"Tillåter att appen hämtar listan med konton som TV:n kan identifiera. Den kan innehålla konton som skapats av appar som du har installerat."</string>
<string name="permdesc_getAccounts" product="default" msgid="3448316822451807382">"Tillåter att appen hämtar en lista över alla kända konton på mobilen. Detta kan inkludera konton som har skapats av appar som du har installerat."</string>
<string name="permlab_accessNetworkState" msgid="4951027964348974773">"visa nätverksanslutningar"</string>
<string name="permdesc_accessNetworkState" msgid="8318964424675960975">"Tillåter att appen kommer åt information om nätverksanslutningarna, till exempel vilka nätverk som finns och är anslutna."</string>
@@ -394,21 +394,21 @@
<string name="permdesc_changeWifiState" msgid="7137950297386127533">"Tillåter att appen ansluter till och kopplar från Wi-Fi-åtkomstpunkter samt gör ändringar i enhetens konfiguration för Wi-Fi-nätverk."</string>
<string name="permlab_changeWifiMulticastState" msgid="1368253871483254784">"tillåt Wi-Fi multicast-mottagning"</string>
<string name="permdesc_changeWifiMulticastState" product="tablet" msgid="7969774021256336548">"Tillåter att appen tar emot paket som skickats med multicast-adress till alla enheter i ett Wi-Fi-nätverk och inte bara till den här surfplattan. Detta drar mer batteri än när multicastläget inte används."</string>
- <string name="permdesc_changeWifiMulticastState" product="tv" msgid="9031975661145014160">"Tillåter att appen tar emot paket som skickats till alla enheter i ett Wi-Fi-nätverk med multicastadress, inte bara till tv:n. Detta drar mer batteri än när multicastläget inte används."</string>
+ <string name="permdesc_changeWifiMulticastState" product="tv" msgid="9031975661145014160">"Tillåter att appen tar emot paket som skickats till alla enheter i ett Wi-Fi-nätverk med multicastadress, inte bara till TV:n. Detta drar mer batteri än när multicastläget inte används."</string>
<string name="permdesc_changeWifiMulticastState" product="default" msgid="6851949706025349926">"Tillåter att appen tar emot paket som skickats med multicast-adress till alla enheter i ett Wi-Fi-nätverk och inte bara till den här mobilen. Detta drar mer batteri än när multicastläget inte används."</string>
<string name="permlab_bluetoothAdmin" msgid="6006967373935926659">"få åtkomst till Bluetooth-inställningar"</string>
<string name="permdesc_bluetoothAdmin" product="tablet" msgid="6921177471748882137">"Tillåter att appen konfigurerar den lokala Bluetooth-surfplattan samt upptäcker och parkopplar den med fjärranslutna enheter."</string>
- <string name="permdesc_bluetoothAdmin" product="tv" msgid="3373125682645601429">"Tillåter att appen konfigurerar den lokala Bluetooth-tv:n och identifierar och kopplar den till fjärrenheter."</string>
+ <string name="permdesc_bluetoothAdmin" product="tv" msgid="3373125682645601429">"Tillåter att appen konfigurerar den lokala Bluetooth-TV:n och identifierar och kopplar den till fjärrenheter."</string>
<string name="permdesc_bluetoothAdmin" product="default" msgid="8931682159331542137">"Tillåter att appen konfigurerar den lokala Bluetooth-mobilen samt upptäcker och parkopplar den med fjärranslutna enheter."</string>
<string name="permlab_accessWimaxState" msgid="4195907010610205703">"ansluta till och koppla från WiMAX"</string>
<string name="permdesc_accessWimaxState" msgid="6360102877261978887">"Tillåter att appen avgör om WiMAX är aktiverat och kommer åt information om eventuella anslutna WiMAX-nätverk."</string>
<string name="permlab_changeWimaxState" msgid="2405042267131496579">"ändra WiMAX-status"</string>
<string name="permdesc_changeWimaxState" product="tablet" msgid="3156456504084201805">"Tillåter att appen ansluter surfplattan till eller kopplar från WiMAX-nätverk."</string>
- <string name="permdesc_changeWimaxState" product="tv" msgid="6022307083934827718">"Tillåter att appen ansluter tv:n till och kopplar från tv:n från WiMAX-nätverk."</string>
+ <string name="permdesc_changeWimaxState" product="tv" msgid="6022307083934827718">"Tillåter att appen ansluter TV:n till och kopplar från TV:n från WiMAX-nätverk."</string>
<string name="permdesc_changeWimaxState" product="default" msgid="697025043004923798">"Tillåter att appen ansluter mobilen till eller kopplar från WiMAX-nätverk."</string>
<string name="permlab_bluetooth" msgid="6127769336339276828">"koppla till Bluetooth-enheter"</string>
<string name="permdesc_bluetooth" product="tablet" msgid="3480722181852438628">"Tillåter att appen kommer åt pekdatorns Bluetooth-konfiguration och upprättar och godkänner anslutningar till parkopplade enheter."</string>
- <string name="permdesc_bluetooth" product="tv" msgid="3974124940101104206">"Tillåter att appen visar konfigurationen av Bluetooth på tv:n och godkänner alla anslutningar till kopplade enheter."</string>
+ <string name="permdesc_bluetooth" product="tv" msgid="3974124940101104206">"Tillåter att appen visar konfigurationen av Bluetooth på TV:n och godkänner alla anslutningar till kopplade enheter."</string>
<string name="permdesc_bluetooth" product="default" msgid="3207106324452312739">"Tillåter att appen kommer åt mobilens Bluetooth-konfiguration och upprättar och godkänner anslutningar till parkopplade enheter."</string>
<string name="permlab_nfc" msgid="4423351274757876953">"kontrollera närfältskommunikationen"</string>
<string name="permdesc_nfc" msgid="7120611819401789907">"Tillåter att appen kommunicerar med etiketter, kort och läsare för närfältskommunikation (NFC)."</string>
@@ -499,10 +499,10 @@
<string name="policydesc_limitPassword" msgid="2502021457917874968">"Styr tillåten längd och tillåtna tecken i lösenord och pinkoder för skärmlåset."</string>
<string name="policylab_watchLogin" msgid="914130646942199503">"Övervaka försök att låsa upp skärmen"</string>
<string name="policydesc_watchLogin" product="tablet" msgid="3215729294215070072">"Övervaka antalet felaktiga lösenord som angetts för skärmlåset och lås surfplattan eller ta bort alla data från surfplattan om för många felaktiga försök görs."</string>
- <string name="policydesc_watchLogin" product="TV" msgid="2707817988309890256">"Övervakar antalet felaktiga lösenord som skrivits in vid upplåsning av skärmen och låser tv:n eller rensar alla uppgifter på tv:n om för många felaktiga lösenord har skrivits in."</string>
+ <string name="policydesc_watchLogin" product="TV" msgid="2707817988309890256">"Övervakar antalet felaktiga lösenord som skrivits in vid upplåsning av skärmen och låser TV:n eller rensar alla uppgifter på TV:n om för många felaktiga lösenord har skrivits in."</string>
<string name="policydesc_watchLogin" product="default" msgid="5712323091846761073">"Övervaka antalet felaktiga lösenord som angivits för skärmlåset och lås mobilen eller ta bort alla data från mobilen om för många felaktiga försök görs."</string>
<string name="policydesc_watchLogin_secondaryUser" product="tablet" msgid="4280246270601044505">"Övervaka antalet felaktiga lösenord som skrivits in vid upplåsning av skärmen och lås surfplattan eller rensa alla uppgifter för den här användaren om för många felaktiga lösenord har skrivits in."</string>
- <string name="policydesc_watchLogin_secondaryUser" product="TV" msgid="3484832653564483250">"Övervaka antalet felaktiga lösenord som skrivits in vid upplåsning av skärmen och lås tv:n eller rensa alla uppgifter för den här användaren om för många felaktiga lösenord har skrivits in."</string>
+ <string name="policydesc_watchLogin_secondaryUser" product="TV" msgid="3484832653564483250">"Övervaka antalet felaktiga lösenord som skrivits in vid upplåsning av skärmen och lås TV:n eller rensa alla uppgifter för den här användaren om för många felaktiga lösenord har skrivits in."</string>
<string name="policydesc_watchLogin_secondaryUser" product="default" msgid="2185480427217127147">"Övervaka antalet felaktiga lösenord som skrivits in vid upplåsning av skärmen och lås mobilen eller rensa alla uppgifter för den här användaren om för många felaktiga lösenord har skrivits in."</string>
<string name="policylab_resetPassword" msgid="4934707632423915395">"Ändra skärmlåset"</string>
<string name="policydesc_resetPassword" msgid="1278323891710619128">"Ändra skärmlåset."</string>
@@ -510,11 +510,11 @@
<string name="policydesc_forceLock" msgid="1141797588403827138">"Kontrollera hur och när skärmlåset aktiveras."</string>
<string name="policylab_wipeData" msgid="3910545446758639713">"Radera all data"</string>
<string name="policydesc_wipeData" product="tablet" msgid="4306184096067756876">"Ta bort data från surfplattan utan förvarning genom att återställa standardinställningarna."</string>
- <string name="policydesc_wipeData" product="tv" msgid="5816221315214527028">"Rensar uppgifterna på tv:n utan föregående varning genom att återställa standardinställningarna."</string>
+ <string name="policydesc_wipeData" product="tv" msgid="5816221315214527028">"Rensar uppgifterna på TV:n utan föregående varning genom att återställa standardinställningarna."</string>
<string name="policydesc_wipeData" product="default" msgid="5096895604574188391">"Ta bort data från mobilen utan förvarning genom att återställa standardinställningarna."</string>
<string name="policylab_wipeData_secondaryUser" msgid="8362863289455531813">"Radera användaruppgifter"</string>
<string name="policydesc_wipeData_secondaryUser" product="tablet" msgid="6336255514635308054">"Rensa användarens uppgifter på den här surfplattan utan förvarning."</string>
- <string name="policydesc_wipeData_secondaryUser" product="tv" msgid="2086473496848351810">"Rensa användarens uppgifter på den här tv:n utan förvarning."</string>
+ <string name="policydesc_wipeData_secondaryUser" product="tv" msgid="2086473496848351810">"Rensa användarens uppgifter på den här TV:n utan förvarning."</string>
<string name="policydesc_wipeData_secondaryUser" product="default" msgid="6787904546711590238">"Rensa användarens data på den här mobilen utan förvarning."</string>
<string name="policylab_setGlobalProxy" msgid="2784828293747791446">"Ange global proxyserver"</string>
<string name="policydesc_setGlobalProxy" msgid="8459859731153370499">"Ange enhetens globala proxy som ska användas när policyn aktiveras. Det är bara enhetens ägare som kan ange global proxy."</string>
@@ -663,7 +663,7 @@
<string name="faceunlock_multiple_failures" msgid="754137583022792429">"Du har försökt låsa upp med Ansiktslås för många gånger"</string>
<string name="lockscreen_missing_sim_message_short" msgid="5099439277819215399">"Inget SIM-kort"</string>
<string name="lockscreen_missing_sim_message" product="tablet" msgid="151659196095791474">"Inget SIM-kort i surfplattan."</string>
- <string name="lockscreen_missing_sim_message" product="tv" msgid="1943633865476989599">"Det finns inget SIM-kort i tv:n."</string>
+ <string name="lockscreen_missing_sim_message" product="tv" msgid="1943633865476989599">"Det finns inget SIM-kort i TV:n."</string>
<string name="lockscreen_missing_sim_message" product="default" msgid="2186920585695169078">"Inget SIM-kort i telefonen."</string>
<string name="lockscreen_missing_sim_instructions" msgid="5372787138023272615">"Sätt i ett SIM-kort."</string>
<string name="lockscreen_missing_sim_instructions_long" msgid="3526573099019319472">"SIM-kort saknas eller kan inte läsas. Sätt i ett SIM-kort."</string>
@@ -686,13 +686,13 @@
<string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"Du har angett fel lösenord <xliff:g id="NUMBER_0">%d</xliff:g> gånger. \n\nFörsök igen om <xliff:g id="NUMBER_1">%d</xliff:g> sekunder."</string>
<string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"Du har angett fel lösenord <xliff:g id="NUMBER_0">%d</xliff:g> gånger. \n\nFörsök igen om <xliff:g id="NUMBER_1">%d</xliff:g> sekunder."</string>
<string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"Du har ritat ditt grafiska lösenord fel <xliff:g id="NUMBER_0">%d</xliff:g> gånger. Efter <xliff:g id="NUMBER_1">%d</xliff:g> försök till ombeds du att låsa upp surfplattan med din Google-inloggning.\n\n Försök igen om <xliff:g id="NUMBER_2">%d</xliff:g> sekunder."</string>
- <string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="5316664559603394684">"Du har ritat fel mönster för upplåsning <xliff:g id="NUMBER_0">%d</xliff:g> gånger. Efter ytterligare <xliff:g id="NUMBER_1">%d</xliff:g> misslyckade försök blir du ombedd att låsa upp tv:n genom att logga in på Google.\n\n Försök igen om <xliff:g id="NUMBER_2">%d</xliff:g> sekunder."</string>
+ <string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="5316664559603394684">"Du har ritat fel mönster för upplåsning <xliff:g id="NUMBER_0">%d</xliff:g> gånger. Efter ytterligare <xliff:g id="NUMBER_1">%d</xliff:g> misslyckade försök blir du ombedd att låsa upp TV:n genom att logga in på Google.\n\n Försök igen om <xliff:g id="NUMBER_2">%d</xliff:g> sekunder."</string>
<string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"Du har ritat ditt grafiska lösenord fel <xliff:g id="NUMBER_0">%d</xliff:g> gånger. Efter <xliff:g id="NUMBER_1">%d</xliff:g> försök till ombeds du att låsa upp mobilen med uppgifterna som du använder när du loggar in på Google.\n\n Försök igen om <xliff:g id="NUMBER_2">%d</xliff:g> sekunder."</string>
<string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"Du har försökt låsa upp surfplattan på fel sätt <xliff:g id="NUMBER_0">%d</xliff:g> gånger. Efter <xliff:g id="NUMBER_1">%d</xliff:g> misslyckade försök till kommer surfplattan att återställas till fabriksinställningarna. Du förlorar då alla användardata."</string>
- <string name="lockscreen_failed_attempts_almost_at_wipe" product="tv" msgid="950408382418270260">"Du har misslyckats med att låsa upp tv:n <xliff:g id="NUMBER_0">%d</xliff:g> gånger. Efter ytterligare <xliff:g id="NUMBER_1">%d</xliff:g> misslyckade försök kommer tv:n att återställas till standardinställningarna och alla användaruppgifter kommer att gå förlorade."</string>
+ <string name="lockscreen_failed_attempts_almost_at_wipe" product="tv" msgid="950408382418270260">"Du har misslyckats med att låsa upp TV:n <xliff:g id="NUMBER_0">%d</xliff:g> gånger. Efter ytterligare <xliff:g id="NUMBER_1">%d</xliff:g> misslyckade försök kommer TV:n att återställas till standardinställningarna och alla användaruppgifter kommer att gå förlorade."</string>
<string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"Du har försökt låsa upp mobilen på fel sätt <xliff:g id="NUMBER_0">%d</xliff:g> gånger. Efter <xliff:g id="NUMBER_1">%d</xliff:g> misslyckade försök till kommer mobilen att återställas till fabriksinställningarna. Du förlorar då alla användardata."</string>
<string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="280873516493934365">"Du har försökt låsa upp surfplattan på fel sätt <xliff:g id="NUMBER">%d</xliff:g> gånger. Surfplattan återställs nu till fabriksinställningarna."</string>
- <string name="lockscreen_failed_attempts_now_wiping" product="tv" msgid="3195755534096192191">"Du har misslyckats med att låsa upp tv:n <xliff:g id="NUMBER">%d</xliff:g> gånger. Tv:n kommer nu att återställas till standardinställningarna."</string>
+ <string name="lockscreen_failed_attempts_now_wiping" product="tv" msgid="3195755534096192191">"Du har misslyckats med att låsa upp TV:n <xliff:g id="NUMBER">%d</xliff:g> gånger. TV:n kommer nu att återställas till standardinställningarna."</string>
<string name="lockscreen_failed_attempts_now_wiping" product="default" msgid="3025504721764922246">"Du har försökt låsa upp mobilen på fel sätt <xliff:g id="NUMBER">%d</xliff:g> gånger. Mobilen återställs nu till fabriksinställningarna."</string>
<string name="lockscreen_too_many_failed_attempts_countdown" msgid="6251480343394389665">"Försök igen om <xliff:g id="NUMBER">%d</xliff:g> sekunder."</string>
<string name="lockscreen_forgot_pattern_button_text" msgid="2626999449610695930">"Glömt ditt grafiska lösenord?"</string>
@@ -778,7 +778,7 @@
<string name="permdesc_readHistoryBookmarks" msgid="8462378226600439658">"Tillåter att appen läser historiken för besökta sidor och alla bokmärken i webbläsaren. Observera att den här behörigheten kanske inte är tillämplig för webbläsare från tredje part eller andra appar med surffunktion."</string>
<string name="permlab_writeHistoryBookmarks" msgid="3714785165273314490">"skriva bokmärken och historik på webben"</string>
<string name="permdesc_writeHistoryBookmarks" product="tablet" msgid="6825527469145760922">"Tillåter att appen ändrar historiken för besökta sidor i webbläsaren eller bokmärken som sparats på surfplattan. Det kan innebära att appen kan ta bort eller ändra webbläsarinformation. Observera att den här behörigheten kanske inte är tillämplig för webbläsare från tredje part eller andra appar med surffunktion."</string>
- <string name="permdesc_writeHistoryBookmarks" product="tv" msgid="7007393823197766548">"Tillåter att appen ändrar webbläsarens historik eller bokmärken som har sparats på tv:n. Appen kan därmed rensa eller ändra uppgifter i webbläsaren. Obs! Den här behörigheten kanske inte gäller för webbläsare från tredje part eller andra appar med webbfunktioner."</string>
+ <string name="permdesc_writeHistoryBookmarks" product="tv" msgid="7007393823197766548">"Tillåter att appen ändrar webbläsarens historik eller bokmärken som har sparats på TV:n. Appen kan därmed rensa eller ändra uppgifter i webbläsaren. Obs! Den här behörigheten kanske inte gäller för webbläsare från tredje part eller andra appar med webbfunktioner."</string>
<string name="permdesc_writeHistoryBookmarks" product="default" msgid="8497389531014185509">"Tillåter att appen ändrar historiken för besökta sidor i webbläsaren eller bokmärken som sparats på telefonen. Det kan innebära att appen kan ta bort eller ändra webbläsarinformation. Observera att den här behörigheten kanske inte är tillämplig för webbläsare från tredje part eller andra appar med surffunktion."</string>
<string name="permlab_setAlarm" msgid="1379294556362091814">"ställa in ett alarm"</string>
<string name="permdesc_setAlarm" msgid="316392039157473848">"Tillåter att appen ställer in ett alarm i en befintlig alarmapp. Vissa alarmappar har inte den här funktionen."</string>
@@ -853,7 +853,7 @@
<string name="Midnight" msgid="5630806906897892201">"Midnatt"</string>
<string name="elapsed_time_short_format_mm_ss" msgid="4431555943828711473">"<xliff:g id="MINUTES">%1$02d</xliff:g>:<xliff:g id="SECONDS">%2$02d</xliff:g>"</string>
<string name="elapsed_time_short_format_h_mm_ss" msgid="1846071997616654124">"<xliff:g id="HOURS">%1$d</xliff:g>:<xliff:g id="MINUTES">%2$02d</xliff:g>:<xliff:g id="SECONDS">%3$02d</xliff:g>"</string>
- <string name="selectAll" msgid="6876518925844129331">"Välj alla"</string>
+ <string name="selectAll" msgid="6876518925844129331">"Markera allt"</string>
<string name="cut" msgid="3092569408438626261">"Klipp ut"</string>
<string name="copy" msgid="2681946229533511987">"Kopiera"</string>
<string name="paste" msgid="5629880836805036433">"Klistra in"</string>
@@ -987,7 +987,7 @@
<string name="wifi_p2p_enter_pin_message" msgid="5920929550367828970">"Ange den obligatoriska PIN-koden:"</string>
<string name="wifi_p2p_show_pin_message" msgid="8530563323880921094">"PIN-kod:"</string>
<string name="wifi_p2p_frequency_conflict_message" product="tablet" msgid="8012981257742232475">"Surfplattans Wi-Fi-anslutning kommer tillfälligt att avbrytas när den är ansluten till <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="tv" msgid="3087858235069421128">"Tv:n kopplas tillfälligt från Wi-Fi-nätverket när den är ansluten till <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
+ <string name="wifi_p2p_frequency_conflict_message" product="tv" msgid="3087858235069421128">"TV:n kopplas tillfälligt från Wi-Fi-nätverket när den är ansluten till <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
<string name="wifi_p2p_frequency_conflict_message" product="default" msgid="7363907213787469151">"Mobilen kommer tillfälligt att kopplas från Wi-Fi när den är ansluten till <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
<string name="select_character" msgid="3365550120617701745">"Infoga tecken"</string>
<string name="sms_control_title" msgid="7296612781128917719">"Skickar SMS"</string>
@@ -1200,7 +1200,7 @@
<string name="shareactionprovider_share_with" msgid="806688056141131819">"Dela med"</string>
<string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Dela med <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
<string name="content_description_sliding_handle" msgid="415975056159262248">"Skärmlåsfunktion. Tryck och dra."</string>
- <string name="description_target_unlock_tablet" msgid="3833195335629795055">"Lås upp genom att dra."</string>
+ <string name="description_target_unlock_tablet" msgid="3833195335629795055">"Lås upp genom att svepa."</string>
<string name="keyboard_headset_required_to_hear_password" msgid="7011927352267668657">"Anslut mikrofonlurar om du vill att lösenordet ska läsas upp."</string>
<string name="keyboard_password_character_no_headset" msgid="2859873770886153678">"Punkt."</string>
<string name="action_bar_home_description" msgid="5293600496601490216">"Visa startsidan"</string>
@@ -1208,7 +1208,7 @@
<string name="action_menu_overflow_description" msgid="2295659037509008453">"Fler alternativ"</string>
<string name="action_bar_home_description_format" msgid="7965984360903693903">"%1$s, %2$s"</string>
<string name="action_bar_home_subtitle_description_format" msgid="6985546530471780727">"%1$s, %2$s, %3$s"</string>
- <string name="storage_internal" msgid="4891916833657929263">"Internminne"</string>
+ <string name="storage_internal" msgid="4891916833657929263">"lagring"</string>
<string name="storage_sd_card" msgid="3282948861378286745">"SD-kort"</string>
<string name="storage_sd_card_label" msgid="6347111320774379257">"SD-kort (<xliff:g id="MANUFACTURER">%s</xliff:g>)"</string>
<string name="storage_usb_drive" msgid="6261899683292244209">"USB-enhet"</string>
@@ -1253,7 +1253,7 @@
<string name="activity_resolver_use_once" msgid="2404644797149173758">"Bara en gång"</string>
<string name="activity_resolver_work_profiles_support" msgid="185598180676883455">"%1$s har inte stöd för arbetsprofil"</string>
<string name="default_audio_route_name" product="tablet" msgid="4617053898167127471">"Surfplatta"</string>
- <string name="default_audio_route_name" product="tv" msgid="9158088547603019321">"Tv"</string>
+ <string name="default_audio_route_name" product="tv" msgid="9158088547603019321">"TV"</string>
<string name="default_audio_route_name" product="default" msgid="4239291273420140123">"Mobil"</string>
<string name="default_audio_route_name_headphones" msgid="8119971843803439110">"Hörlurar"</string>
<string name="default_audio_route_name_dock_speakers" msgid="6240602982276591864">"Dockningsstationens högtalare"</string>
@@ -1307,13 +1307,13 @@
<string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Du har angett fel lösenord <xliff:g id="NUMBER_0">%d</xliff:g> gånger. \n\nFörsök igen om <xliff:g id="NUMBER_1">%d</xliff:g> sekunder."</string>
<string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Du har ritat ditt grafiska lösenord fel <xliff:g id="NUMBER_0">%d</xliff:g> gånger. \n\nFörsök igen om <xliff:g id="NUMBER_1">%d</xliff:g> sekunder."</string>
<string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Du har försökt låsa upp mobilen på fel sätt <xliff:g id="NUMBER_0">%d</xliff:g> gånger. Efter ytterligare <xliff:g id="NUMBER_1">%d</xliff:g> misslyckade försök återställs surfplattan till fabriksinställningarna. Du förlorar då alla användardata."</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="tv" msgid="5621231220154419413">"Du har misslyckats med att låsa upp tv:n <xliff:g id="NUMBER_0">%d</xliff:g> gånger. Efter ytterligare <xliff:g id="NUMBER_1">%d</xliff:g> misslyckade försök kommer tv:n att återställas till standardinställningarna och alla användaruppgifter kommer att gå förlorade."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="tv" msgid="5621231220154419413">"Du har misslyckats med att låsa upp TV:n <xliff:g id="NUMBER_0">%d</xliff:g> gånger. Efter ytterligare <xliff:g id="NUMBER_1">%d</xliff:g> misslyckade försök kommer TV:n att återställas till standardinställningarna och alla användaruppgifter kommer att gå förlorade."</string>
<string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Du har försökt låsa upp mobilen på fel sätt <xliff:g id="NUMBER_0">%d</xliff:g> gånger. Efter ytterligare <xliff:g id="NUMBER_1">%d</xliff:g> misslyckade försök återställs mobilen till fabriksinställningarna. Du förlorar då alla användardata."</string>
<string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"Du har försökt låsa upp surfplattan på fel sätt <xliff:g id="NUMBER">%d</xliff:g> gånger. Surfplattan återställs nu till fabriksinställningarna."</string>
- <string name="kg_failed_attempts_now_wiping" product="tv" msgid="4987878286750741463">"Du har misslyckats med att låsa upp tv:n <xliff:g id="NUMBER">%d</xliff:g> gånger. Tv:n kommer nu att återställas till standardinställningarna."</string>
+ <string name="kg_failed_attempts_now_wiping" product="tv" msgid="4987878286750741463">"Du har misslyckats med att låsa upp TV:n <xliff:g id="NUMBER">%d</xliff:g> gånger. TV:n kommer nu att återställas till standardinställningarna."</string>
<string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"Du har försökt låsa upp mobilen på fel sätt <xliff:g id="NUMBER">%d</xliff:g> gånger. Mobilen återställs nu till fabriksinställningarna."</string>
<string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Du har ritat ditt grafiska lösenord fel <xliff:g id="NUMBER_0">%d</xliff:g> gånger. Efter ytterligare <xliff:g id="NUMBER_1">%d</xliff:g> försök ombeds du låsa upp surfplattan med ett e-postkonto.\n\n Försök igen om <xliff:g id="NUMBER_2">%d</xliff:g> sekunder."</string>
- <string name="kg_failed_attempts_almost_at_login" product="tv" msgid="4224651132862313471">"Du har ritat fel mönster för upplåsning <xliff:g id="NUMBER_0">%d</xliff:g> gånger. Efter ytterligare <xliff:g id="NUMBER_1">%d</xliff:g> misslyckade försök blir du ombedd att låsa upp tv:n via ett e-postkonto.\n\n Försök igen om <xliff:g id="NUMBER_2">%d</xliff:g> sekunder."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="tv" msgid="4224651132862313471">"Du har ritat fel mönster för upplåsning <xliff:g id="NUMBER_0">%d</xliff:g> gånger. Efter ytterligare <xliff:g id="NUMBER_1">%d</xliff:g> misslyckade försök blir du ombedd att låsa upp TV:n via ett e-postkonto.\n\n Försök igen om <xliff:g id="NUMBER_2">%d</xliff:g> sekunder."</string>
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Du har ritat ditt grafiska lösenord fel <xliff:g id="NUMBER_0">%d</xliff:g> gånger. Efter ytterligare <xliff:g id="NUMBER_1">%d</xliff:g> försök ombeds du låsa upp mobilen med hjälp av ett e-postkonto.\n\n Försök igen om <xliff:g id="NUMBER_2">%d</xliff:g> sekunder."</string>
<string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" – "</string>
<string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"Ta bort"</string>
@@ -1432,7 +1432,7 @@
</plurals>
<string name="restr_pin_try_later" msgid="973144472490532377">"Försök igen senare"</string>
<string name="immersive_cling_title" msgid="8394201622932303336">"Visar på fullskärm"</string>
- <string name="immersive_cling_description" msgid="3482371193207536040">"Dra nedåt från skärmens överkant för att avsluta."</string>
+ <string name="immersive_cling_description" msgid="3482371193207536040">"Svep nedåt från skärmens överkant för att avsluta."</string>
<string name="immersive_cling_positive" msgid="5016839404568297683">"OK"</string>
<string name="done_label" msgid="2093726099505892398">"Klart"</string>
<string name="hour_picker_description" msgid="6698199186859736512">"Cirkelreglage för timmar"</string>
@@ -1488,6 +1488,7 @@
<item quantity="one">I en 1 tim</item>
</plurals>
<string name="zen_mode_until" msgid="7336308492289875088">"Till kl. <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
+ <string name="zen_mode_alarm" msgid="9128205721301330797">"Till <xliff:g id="FORMATTEDTIME">%1$s</xliff:g> (nästa alarm)"</string>
<string name="zen_mode_forever" msgid="7420011936770086993">"Tills du inaktiverar detta"</string>
<string name="zen_mode_forever_dnd" msgid="3792132696572189081">"Tills du inaktiverar Stör ej"</string>
<string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g>/<xliff:g id="REST">%2$s</xliff:g>"</string>
diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml
index 3800c92..da5d6a3 100644
--- a/core/res/res/values-sw/strings.xml
+++ b/core/res/res/values-sw/strings.xml
@@ -229,9 +229,9 @@
<string name="user_owner_label" msgid="2804351898001038951">"Binafsi"</string>
<string name="managed_profile_label" msgid="6260850669674791528">"Kazini"</string>
<string name="permgrouplab_contacts" msgid="3657758145679177612">"Anwani"</string>
- <string name="permgroupdesc_contacts" msgid="6951499528303668046">"fikia anwani zako"</string>
+ <string name="permgroupdesc_contacts" msgid="6951499528303668046">"ifikie anwani zako"</string>
<string name="permgrouplab_location" msgid="7275582855722310164">"Mahali"</string>
- <string name="permgroupdesc_location" msgid="1346617465127855033">"fikia mahali kilipo kifaa hiki"</string>
+ <string name="permgroupdesc_location" msgid="1346617465127855033">"ifikie mahali kilipo kifaa hiki"</string>
<string name="permgrouplab_calendar" msgid="5863508437783683902">"Kalenda"</string>
<string name="permgroupdesc_calendar" msgid="3889615280211184106">"fikia kalenda yako"</string>
<string name="permgrouplab_sms" msgid="228308803364967808">"SMS"</string>
@@ -589,7 +589,7 @@
<string name="phoneTypeTelex" msgid="3367879952476250512">"Teleksi"</string>
<string name="phoneTypeTtyTdd" msgid="8606514378585000044">"TTY TDD"</string>
<string name="phoneTypeWorkMobile" msgid="1311426989184065709">"Nambari ya Simu ya Mkononi ya Kazini"</string>
- <string name="phoneTypeWorkPager" msgid="649938731231157056">"Kiunda ujumbe cha Kazini"</string>
+ <string name="phoneTypeWorkPager" msgid="649938731231157056">"Peja ya Kazini"</string>
<string name="phoneTypeAssistant" msgid="5596772636128562884">"Msaidizi"</string>
<string name="phoneTypeMms" msgid="7254492275502768992">"MMS"</string>
<string name="eventTypeCustom" msgid="7837586198458073404">"Maalum"</string>
@@ -1490,6 +1490,7 @@
<item quantity="one">Kwa saa 1 </item>
</plurals>
<string name="zen_mode_until" msgid="7336308492289875088">"Hadi <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
+ <string name="zen_mode_alarm" msgid="9128205721301330797">"Mpaka <xliff:g id="FORMATTEDTIME">%1$s</xliff:g> (kengele inayofuata)"</string>
<string name="zen_mode_forever" msgid="7420011936770086993">"Hadi utakapozima hili"</string>
<string name="zen_mode_forever_dnd" msgid="3792132696572189081">"Hadi utakapozima Usinisumbue"</string>
<string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string>
diff --git a/core/res/res/values-ta-rIN/strings.xml b/core/res/res/values-ta-rIN/strings.xml
index ae9be63..48b1e64 100644
--- a/core/res/res/values-ta-rIN/strings.xml
+++ b/core/res/res/values-ta-rIN/strings.xml
@@ -1488,6 +1488,7 @@
<item quantity="one">1 மணிநேரத்திற்கு</item>
</plurals>
<string name="zen_mode_until" msgid="7336308492289875088">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g> வரை"</string>
+ <string name="zen_mode_alarm" msgid="9128205721301330797">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g> மணி (அடுத்த அலாரம்) வரை"</string>
<string name="zen_mode_forever" msgid="7420011936770086993">"இதை முடக்கும்வரை"</string>
<string name="zen_mode_forever_dnd" msgid="3792132696572189081">"தொந்தரவு செய்ய வேண்டாம் என்பதை முடக்கும் வரை"</string>
<string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string>
diff --git a/core/res/res/values-te-rIN/strings.xml b/core/res/res/values-te-rIN/strings.xml
index 7eca8ee..ff639a9 100644
--- a/core/res/res/values-te-rIN/strings.xml
+++ b/core/res/res/values-te-rIN/strings.xml
@@ -1488,6 +1488,7 @@
<item quantity="one">1 గం పాటు</item>
</plurals>
<string name="zen_mode_until" msgid="7336308492289875088">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g> వరకు"</string>
+ <string name="zen_mode_alarm" msgid="9128205721301330797">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g> (తదుపరి అలారం) వరకు"</string>
<string name="zen_mode_forever" msgid="7420011936770086993">"మీరు దీన్ని ఆఫ్ చేసే వరకు"</string>
<string name="zen_mode_forever_dnd" msgid="3792132696572189081">"మీరు అంతరాయం కలిగించవద్దు ఎంపిక ఆఫ్ చేసే వరకు"</string>
<string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string>
diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml
index 549e755..2db50ee 100644
--- a/core/res/res/values-th/strings.xml
+++ b/core/res/res/values-th/strings.xml
@@ -1044,7 +1044,7 @@
<string name="usb_accessory_notification_title" msgid="7848236974087653666">"เชื่อมต่อกับอุปกรณ์เสริม USB แล้ว"</string>
<string name="usb_notification_message" msgid="7347368030849048437">"แตะเพื่อดูตัวเลือกเพิ่มเติม"</string>
<string name="adb_active_notification_title" msgid="6729044778949189918">"เชื่อมต่อการแก้ไขข้อบกพร่อง USB แล้ว"</string>
- <string name="adb_active_notification_message" msgid="1016654627626476142">"แตะเพื่อปิดใช้งานการแก้ไขข้อบกพร่องของ USB"</string>
+ <string name="adb_active_notification_message" msgid="1016654627626476142">"แตะเพื่อปิดใช้งานการแก้ไขข้อบกพร่อง USB"</string>
<string name="select_input_method" msgid="8547250819326693584">"เปลี่ยนแป้นพิมพ์"</string>
<string name="configure_input_methods" msgid="4769971288371946846">"เลือกแป้นพิมพ์"</string>
<string name="show_ime" msgid="9157568568695230830">"แสดงวิธีการป้อนข้อมูล"</string>
@@ -1488,6 +1488,7 @@
<item quantity="one">เป็นเวลา 1 ชม.</item>
</plurals>
<string name="zen_mode_until" msgid="7336308492289875088">"จนถึงเวลา <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
+ <string name="zen_mode_alarm" msgid="9128205721301330797">"จนถึงเวลา <xliff:g id="FORMATTEDTIME">%1$s</xliff:g> (การปลุกครั้งถัดไป)"</string>
<string name="zen_mode_forever" msgid="7420011936770086993">"จนกว่าคุณจะปิดฟังก์ชันนี้"</string>
<string name="zen_mode_forever_dnd" msgid="3792132696572189081">"จนกว่าคุณจะปิดห้ามรบกวน"</string>
<string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string>
diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml
index 004b3f8..27cd5bb 100644
--- a/core/res/res/values-tl/strings.xml
+++ b/core/res/res/values-tl/strings.xml
@@ -1488,6 +1488,7 @@
<item quantity="other">Sa loob ng %d na oras</item>
</plurals>
<string name="zen_mode_until" msgid="7336308492289875088">"Hanggang <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
+ <string name="zen_mode_alarm" msgid="9128205721301330797">"Hanggang <xliff:g id="FORMATTEDTIME">%1$s</xliff:g> (susunod na alarm)"</string>
<string name="zen_mode_forever" msgid="7420011936770086993">"Hanggang sa i-off mo ito"</string>
<string name="zen_mode_forever_dnd" msgid="3792132696572189081">"Hanggang sa i-off mo ang Huwag Istorbohin"</string>
<string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string>
diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml
index 72cbf87..909061b 100644
--- a/core/res/res/values-tr/strings.xml
+++ b/core/res/res/values-tr/strings.xml
@@ -350,8 +350,8 @@
<string name="permdesc_camera" msgid="8497216524735535009">"Uygulamaya kamerayla fotoğraf ve video çekme izni verir. Bu izin, uygulamanın sizin onayınız olmadan istediği zaman kamerayı kullanmasına olanak sağlar."</string>
<string name="permlab_vibrate" msgid="7696427026057705834">"titreşimi denetleme"</string>
<string name="permdesc_vibrate" msgid="6284989245902300945">"Uygulamaya, titreşimi denetleme izni verir."</string>
- <string name="permlab_flashlight" msgid="2155920810121984215">"flaşı denetle"</string>
- <string name="permdesc_flashlight" msgid="6522284794568368310">"Uygulamaya, flaş ışığını denetleme izni verir."</string>
+ <string name="permlab_flashlight" msgid="2155920810121984215">"el fenerini denetle"</string>
+ <string name="permdesc_flashlight" msgid="6522284794568368310">"Uygulamaya, el fenerini denetleme izni verir."</string>
<string name="permlab_callPhone" msgid="3925836347681847954">"telefon numaralarına doğrudan çağrı yap"</string>
<string name="permdesc_callPhone" msgid="3740797576113760827">"Uygulamaya sizin müdahaleniz olmadan telefon numaralarına çağrı yapma izni verir. Bu durum beklenmeyen ödemelere veya çağrılara neden olabilir. Ancak bu iznin, uygulamanın acil numaralara çağrı yapmasına olanak sağlamadığını unutmayın. Kötü amaçlı uygulamalar onayınız olmadan çağrılar yaparak sizi zarara sokabilir."</string>
<string name="permlab_accessImsCallService" msgid="3574943847181793918">"IMS çağrı hizmetine erişme"</string>
@@ -1005,14 +1005,14 @@
<string name="sms_short_code_confirm_never_allow" msgid="446992765774269673">"Asla İzin Verme"</string>
<string name="sim_removed_title" msgid="6227712319223226185">"SIM kart çıkarıldı"</string>
<string name="sim_removed_message" msgid="5450336489923274918">"Hücresel ağ, geçerli bir SIM kart takıp cihazınızı yeniden başlatıncaya kadar kullanılamayacak."</string>
- <string name="sim_done_button" msgid="827949989369963775">"Tamamlandı"</string>
+ <string name="sim_done_button" msgid="827949989369963775">"Bitti"</string>
<string name="sim_added_title" msgid="3719670512889674693">"SIM kart eklendi"</string>
<string name="sim_added_message" msgid="7797975656153714319">"Hücresel ağa erişmek için cihazınızı yeniden başlatın."</string>
<string name="sim_restart_button" msgid="4722407842815232347">"Yeniden başlat"</string>
<string name="time_picker_dialog_title" msgid="8349362623068819295">"Saati ayarlayın"</string>
<string name="date_picker_dialog_title" msgid="5879450659453782278">"Tarihi ayarlayın"</string>
<string name="date_time_set" msgid="5777075614321087758">"Ayarla"</string>
- <string name="date_time_done" msgid="2507683751759308828">"Tamamlandı"</string>
+ <string name="date_time_done" msgid="2507683751759308828">"Bitti"</string>
<string name="perms_new_perm_prefix" msgid="8257740710754301407"><font size="12" fgcolor="#ff33b5e5">"YENİ: "</font></string>
<string name="perms_description_app" msgid="5139836143293299417">"Sağlayan: <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
<string name="no_permissions" msgid="7283357728219338112">"İzin gerektirmez"</string>
@@ -1488,6 +1488,7 @@
<item quantity="one">1 saat için</item>
</plurals>
<string name="zen_mode_until" msgid="7336308492289875088">"Şu saate kadar: <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
+ <string name="zen_mode_alarm" msgid="9128205721301330797">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g> (sonraki alarma) saatine kadar"</string>
<string name="zen_mode_forever" msgid="7420011936770086993">"Siz bunu kapatana kadar"</string>
<string name="zen_mode_forever_dnd" msgid="3792132696572189081">"Rahatsız Etmeyin ayarını kapatana kadar"</string>
<string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string>
diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml
index ea3c941..aee730d 100644
--- a/core/res/res/values-uk/strings.xml
+++ b/core/res/res/values-uk/strings.xml
@@ -1522,6 +1522,7 @@
<item quantity="other">Протягом %d год</item>
</plurals>
<string name="zen_mode_until" msgid="7336308492289875088">"До <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
+ <string name="zen_mode_alarm" msgid="9128205721301330797">"До <xliff:g id="FORMATTEDTIME">%1$s</xliff:g> (наступний будильник)"</string>
<string name="zen_mode_forever" msgid="7420011936770086993">"Доки ви не вимкнете"</string>
<string name="zen_mode_forever_dnd" msgid="3792132696572189081">"Доки ввімкнено режим \"Не турбувати\""</string>
<string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string>
diff --git a/core/res/res/values-ur-rPK/strings.xml b/core/res/res/values-ur-rPK/strings.xml
index 76495e1..4e4d069 100644
--- a/core/res/res/values-ur-rPK/strings.xml
+++ b/core/res/res/values-ur-rPK/strings.xml
@@ -429,7 +429,7 @@
<string name="fingerprint_error_no_space" msgid="1055819001126053318">"فنگر پرنٹ اسٹور نہیں کیا جا سکتا ہے۔ براہ کرم ایک موجودہ فنگر پرنٹ ہٹائیں۔"</string>
<string name="fingerprint_error_timeout" msgid="3927186043737732875">"فنگر پرنٹ کی میعاد ختم ہوگئی۔ دوبارہ کوشش کریں۔"</string>
<string name="fingerprint_error_canceled" msgid="4402024612660774395">"فنگر پرنٹ کی کارروائی منسوخ ہوگئی۔"</string>
- <string name="fingerprint_error_lockout" msgid="5536934748136933450">"کافی زیادہ کوششیں کی گئیں۔ بعد میں دوباہ کوشش کریں۔"</string>
+ <string name="fingerprint_error_lockout" msgid="5536934748136933450">"کافی زیادہ کوششیں کی گئیں۔ بعد میں دوبارہ کوشش کریں۔"</string>
<string name="fingerprint_error_unable_to_process" msgid="6107816084103552441">"دوبارہ کوشش کریں۔"</string>
<string name="fingerprint_name_template" msgid="5870957565512716938">"انگلی <xliff:g id="FINGERID">%d</xliff:g>"</string>
<string-array name="fingerprint_error_vendor">
@@ -1488,6 +1488,7 @@
<item quantity="one">1 گھنٹہ کیلئے</item>
</plurals>
<string name="zen_mode_until" msgid="7336308492289875088">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g> تک"</string>
+ <string name="zen_mode_alarm" msgid="9128205721301330797">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g> تک (اگلا الارم)"</string>
<string name="zen_mode_forever" msgid="7420011936770086993">"جب تک آپ اسے آف نہ کر دیں"</string>
<string name="zen_mode_forever_dnd" msgid="3792132696572189081">"جب تک آپ ڈسڑب نہ کریں کو آف نہیں کر دیتے"</string>
<string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string>
diff --git a/core/res/res/values-uz-rUZ/strings.xml b/core/res/res/values-uz-rUZ/strings.xml
index 1d28eb1..81e2219 100644
--- a/core/res/res/values-uz-rUZ/strings.xml
+++ b/core/res/res/values-uz-rUZ/strings.xml
@@ -62,8 +62,8 @@
<string name="needPuk2" msgid="4526033371987193070">"SIM kartani blokdan chiqarish uchun PUK2 raqamini kiriting."</string>
<string name="enablePin" msgid="209412020907207950">"Ishlamadi, SIM/RUIM qulfni yoqish."</string>
<plurals name="pinpuk_attempts" formatted="false" msgid="1251012001539225582">
- <item quantity="other">Yana <xliff:g id="NUMBER_1">%d</xliff:g> ta muvaffaqiyatsiz urinishdan so‘ng SIM-karta qulflanadi.</item>
- <item quantity="one">Yana <xliff:g id="NUMBER_0">%d</xliff:g> ta muvaffaqiyatsiz urinishdan so‘ng SIM-karta qulflanadi.</item>
+ <item quantity="other">Yana <xliff:g id="NUMBER_1">%d</xliff:g> ta muvaffaqiyatsiz urinishdan so‘ng SIM karta qulflanadi.</item>
+ <item quantity="one">Yana <xliff:g id="NUMBER_0">%d</xliff:g> ta muvaffaqiyatsiz urinishdan so‘ng SIM karta qulflanadi.</item>
</plurals>
<string name="imei" msgid="2625429890869005782">"IMEI"</string>
<string name="meid" msgid="4841221237681254195">"MEID"</string>
@@ -231,19 +231,19 @@
<string name="permgrouplab_location" msgid="7275582855722310164">"Joylashuv"</string>
<string name="permgroupdesc_location" msgid="1346617465127855033">"qurilmaning joylashuvi haqidagi ma’lumotlarga kirish"</string>
<string name="permgrouplab_calendar" msgid="5863508437783683902">"Taqvim"</string>
- <string name="permgroupdesc_calendar" msgid="3889615280211184106">"taqvimga kirish"</string>
+ <string name="permgroupdesc_calendar" msgid="3889615280211184106">"taqvim ma’lumotlariga kirish"</string>
<string name="permgrouplab_sms" msgid="228308803364967808">"SMS"</string>
<string name="permgroupdesc_sms" msgid="4656988620100940350">"SMS xabarlarni yuborish va ko‘rish"</string>
<string name="permgrouplab_storage" msgid="1971118770546336966">"Xotira"</string>
- <string name="permgroupdesc_storage" msgid="637758554581589203">"qurilmangizdagi rasm, media va fayllarga kirish"</string>
+ <string name="permgroupdesc_storage" msgid="637758554581589203">"qurilmangizdagi rasm, multimedia va fayllarga kirish"</string>
<string name="permgrouplab_microphone" msgid="171539900250043464">"Mikrofon"</string>
<string name="permgroupdesc_microphone" msgid="4988812113943554584">"ovoz yozib olish"</string>
<string name="permgrouplab_camera" msgid="4820372495894586615">"Kamera"</string>
- <string name="permgroupdesc_camera" msgid="3250611594678347720">"rasm va videoga olish"</string>
+ <string name="permgroupdesc_camera" msgid="3250611594678347720">"suratga olish va video yozib olish"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"Telefon"</string>
<string name="permgroupdesc_phone" msgid="6234224354060641055">"telefon qo‘ng‘iroqlarini amalga oshirish va boshqarish"</string>
<string name="permgrouplab_sensors" msgid="416037179223226722">"Tana sezgichlari"</string>
- <string name="permgroupdesc_sensors" msgid="7147968539346634043">"asosiy belgilaringiz haqidagi sezgich ma’lumotlariga kirish"</string>
+ <string name="permgroupdesc_sensors" msgid="7147968539346634043">"organizm holati haqidagi sezgich ma’lumotlariga kirish"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Oynadagi kontentni o‘qiydi"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Joriy oynadagi kontent mazmunini aniqlaydi."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Teginib o‘rganish xizmatini yoqadi"</string>
@@ -342,7 +342,7 @@
<string name="permdesc_accessCoarseLocation" msgid="2538200184373302295">"Ilovaga sizning taxminiy joylashuvingizni topishga ruxsat beradi. Ushbu joylashuv Wi-Fi va uyali tarmoq antennalari kabi tarmoq joylashuv manbalaridan foydlanuvchi joylashuv xizmatlari orqali aniqlanadi. Ushbu joylashuv xizmatlari yoqib qo‘yilgan bo‘lishi va qurilmangizdagi ilovaga ulardan foydalanish uchun mavjud bo‘lishi kerak. Ilovalar bundan foydalanib, sizning taxminiy joylashuvingizni aniqlaydi."</string>
<string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"audio sozlamalaringizni o‘zgartirish"</string>
<string name="permdesc_modifyAudioSettings" msgid="3522565366806248517">"Ilovalarga tovush va ovoz chiqarish uchun foydalaniladigan karnay kabi global audio sozlamalarini o‘zgartirish uchun ruxsat beradi."</string>
- <string name="permlab_recordAudio" msgid="3876049771427466323">"audioni yozib olish"</string>
+ <string name="permlab_recordAudio" msgid="3876049771427466323">"ovoz yozib olish"</string>
<string name="permdesc_recordAudio" msgid="4906839301087980680">"Ilovaga mikrofon yordamida audio yozish uchun ruxsat beradi. Bu huquq ilovaga ruxsatingizsiz audio fayllarni yozib olishga ruxsat beradi."</string>
<string name="permlab_sim_communication" msgid="1180265879464893029">"sim orqali ulanish"</string>
<string name="permdesc_sim_communication" msgid="5725159654279639498">"Dasturga SIM kartaga buyruqlar jo‘natishga ruxsat beradi. Bu juda ham xavfli."</string>
@@ -414,18 +414,18 @@
<string name="permdesc_nfc" msgid="7120611819401789907">"Ilova qisqa masofali aloqa (NFC) texnologiyasi yordamida NFC yorliqlari, kartalar va o‘qish moslamalari bilan ma’lumot almashishi mumkin."</string>
<string name="permlab_disableKeyguard" msgid="3598496301486439258">"ekran qulfini o‘chirib qo‘yish"</string>
<string name="permdesc_disableKeyguard" msgid="6034203065077122992">"Ilovaga ekran qulfini va har qanday parol yordamidagi xavfsizlik himoyalarini o‘chirishga ruxsat beradi. Masalan, kirish qo‘ng‘irog‘ida telefon ekran qulfini o‘chiradi va qo‘ng‘iroq tugashi bilan qulfni yoqadi."</string>
- <string name="permlab_manageFingerprint" msgid="5640858826254575638">"barmoq izi sensorini boshqarish"</string>
+ <string name="permlab_manageFingerprint" msgid="5640858826254575638">"barmoq izi skanerini boshqarish"</string>
<string name="permdesc_manageFingerprint" msgid="178208705828055464">"Ilova foydalanish uchun barmoq izi namunalarini qo‘shish va o‘chirish usullarini qo‘llashi mumkin."</string>
<string name="permlab_useFingerprint" msgid="3150478619915124905">"barmoq izi sensoridan foydalanish"</string>
<string name="permdesc_useFingerprint" msgid="9165097460730684114">"Ilova haqiqiylikni tekshirish uchun barmoq izi sensoridan foydalanishi mumkin"</string>
<string name="fingerprint_acquired_partial" msgid="735082772341716043">"Barmoq izi qisman aniqlandi. Qayta urinib ko‘ring."</string>
<string name="fingerprint_acquired_insufficient" msgid="4596546021310923214">"Barmoq izi aniqlanmadi. Qayta urinib ko‘ring."</string>
- <string name="fingerprint_acquired_imager_dirty" msgid="1087209702421076105">"Barmoq izi sensori kirlangan. Uni tozalab, keyin qayta urinib ko‘ring."</string>
+ <string name="fingerprint_acquired_imager_dirty" msgid="1087209702421076105">"Barmoq izi skaneri kirlangan. Uni tozalab, keyin qayta urinib ko‘ring."</string>
<string name="fingerprint_acquired_too_fast" msgid="6470642383109155969">"Barmoq juda tez harakatlandi. Qayta urinib ko‘ring."</string>
<string name="fingerprint_acquired_too_slow" msgid="59250885689661653">"Barmoq juda sekin harakatlandi. Qayta urinib ko‘ring."</string>
<string-array name="fingerprint_acquired_vendor">
</string-array>
- <string name="fingerprint_error_hw_not_available" msgid="7955921658939936596">"Barmoq izi sensori ish holatida emas."</string>
+ <string name="fingerprint_error_hw_not_available" msgid="7955921658939936596">"Barmoq izi skaneri ish holatida emas."</string>
<string name="fingerprint_error_no_space" msgid="1055819001126053318">"Barmoq izini saqlab bo‘lmadi. Mavjud barmoq izlaridan birini o‘chirib tashlang."</string>
<string name="fingerprint_error_timeout" msgid="3927186043737732875">"Barmoq izini aniqlash vaqti tugab qoldi. Qayta urinib ko‘ring."</string>
<string name="fingerprint_error_canceled" msgid="4402024612660774395">"Barmoq izi tekshiruvi bekor qilindi."</string>
@@ -661,14 +661,14 @@
<string name="lockscreen_pattern_wrong" msgid="4317955014948108794">"Qaytadan urining"</string>
<string name="lockscreen_password_wrong" msgid="5737815393253165301">"Qaytadan urining"</string>
<string name="faceunlock_multiple_failures" msgid="754137583022792429">"Yuzni tanitib qulfni ochishga urinish miqdoridan oshib ketdi"</string>
- <string name="lockscreen_missing_sim_message_short" msgid="5099439277819215399">"SIM-karta yo‘q"</string>
- <string name="lockscreen_missing_sim_message" product="tablet" msgid="151659196095791474">"Planshetingizga SIM-karta yo‘q."</string>
- <string name="lockscreen_missing_sim_message" product="tv" msgid="1943633865476989599">"Televizorda SIM-karta yo‘q."</string>
- <string name="lockscreen_missing_sim_message" product="default" msgid="2186920585695169078">"Telefoningizga SIM-karta yo‘q."</string>
+ <string name="lockscreen_missing_sim_message_short" msgid="5099439277819215399">"SIM karta yo‘q"</string>
+ <string name="lockscreen_missing_sim_message" product="tablet" msgid="151659196095791474">"Planshetingizga SIM karta yo‘q."</string>
+ <string name="lockscreen_missing_sim_message" product="tv" msgid="1943633865476989599">"Televizorda SIM karta yo‘q."</string>
+ <string name="lockscreen_missing_sim_message" product="default" msgid="2186920585695169078">"Telefoningizga SIM karta yo‘q."</string>
<string name="lockscreen_missing_sim_instructions" msgid="5372787138023272615">"SIM kartani soling."</string>
- <string name="lockscreen_missing_sim_instructions_long" msgid="3526573099019319472">"SIM-karta solinmagan yoki uni o‘qib bo‘lmaydi. SIM-kartani soling."</string>
- <string name="lockscreen_permanent_disabled_sim_message_short" msgid="5096149665138916184">"Foydalanib bo‘lmaydigan SIM-karta."</string>
- <string name="lockscreen_permanent_disabled_sim_instructions" msgid="910904643433151371">"SIM-kartangiz butunlay bloklab qo‘yilgan.\n Yangi SIM-karta olish uchun aloqa operatoringiz bilan bog‘laning."</string>
+ <string name="lockscreen_missing_sim_instructions_long" msgid="3526573099019319472">"SIM karta solinmagan yoki uni o‘qib bo‘lmaydi. SIM kartani soling."</string>
+ <string name="lockscreen_permanent_disabled_sim_message_short" msgid="5096149665138916184">"Foydalanib bo‘lmaydigan SIM karta."</string>
+ <string name="lockscreen_permanent_disabled_sim_instructions" msgid="910904643433151371">"SIM kartangiz butunlay bloklab qo‘yilgan.\n Yangi SIM karta olish uchun aloqa operatoringiz bilan bog‘laning."</string>
<string name="lockscreen_transport_prev_description" msgid="6300840251218161534">"Avvalgi musiqa"</string>
<string name="lockscreen_transport_next_description" msgid="573285210424377338">"Keyingi musiqa"</string>
<string name="lockscreen_transport_pause_description" msgid="3980308465056173363">"To‘xtatib turish"</string>
@@ -676,12 +676,12 @@
<string name="lockscreen_transport_stop_description" msgid="5907083260651210034">"To‘xtatish"</string>
<string name="lockscreen_transport_rew_description" msgid="6944412838651990410">"Orqaga o‘tkazish"</string>
<string name="lockscreen_transport_ffw_description" msgid="42987149870928985">"Oldinga o‘tkazish"</string>
- <string name="emergency_calls_only" msgid="6733978304386365407">"Faqat favqulodda chaqiruvlar"</string>
+ <string name="emergency_calls_only" msgid="6733978304386365407">"Faqat favqulodda qo‘ng‘iroqlar"</string>
<string name="lockscreen_network_locked_message" msgid="143389224986028501">"Tarmoq qulflangan"</string>
- <string name="lockscreen_sim_puk_locked_message" msgid="7441797339976230">"SIM-karta PUK kod bilan qulflangan."</string>
+ <string name="lockscreen_sim_puk_locked_message" msgid="7441797339976230">"SIM karta PUK kod bilan qulflangan."</string>
<string name="lockscreen_sim_puk_locked_instructions" msgid="8127916255245181063">"Foydalanuvchi qo‘llanmasiga qarang yoki Abonentlarni qo‘llab-quvvatlash markaziga murojaat qiling."</string>
- <string name="lockscreen_sim_locked_message" msgid="8066660129206001039">"SIM-karta qulflangan."</string>
- <string name="lockscreen_sim_unlock_progress_dialog_message" msgid="595323214052881264">"SIM-karta qulfdan chiqarilmoqda…"</string>
+ <string name="lockscreen_sim_locked_message" msgid="8066660129206001039">"SIM karta qulflangan."</string>
+ <string name="lockscreen_sim_unlock_progress_dialog_message" msgid="595323214052881264">"SIM karta qulfdan chiqarilmoqda…"</string>
<string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"Siz chizmali kalitni <xliff:g id="NUMBER_0">%d</xliff:g> marta noto‘g‘ri kiritdingiz. \n\n<xliff:g id="NUMBER_1">%d</xliff:g> soniyadan so‘ng qayta urining."</string>
<string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"Siz parolni <xliff:g id="NUMBER_0">%d</xliff:g> marta noto‘g‘ri kiritdingiz. \n\n <xliff:g id="NUMBER_1">%d</xliff:g> soniyadan so‘ng qayta urining."</string>
<string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"Siz PIN-kodni <xliff:g id="NUMBER_0">%d</xliff:g> marta noto‘g‘ri kiritdingiz. \n\n <xliff:g id="NUMBER_1">%d</xliff:g> soniyadan so‘ng qayta urining."</string>
@@ -797,9 +797,9 @@
<string name="menu_space_shortcut_label" msgid="2410328639272162537">"space"</string>
<string name="menu_enter_shortcut_label" msgid="2743362785111309668">"enter"</string>
<string name="menu_delete_shortcut_label" msgid="3658178007202748164">"delete"</string>
- <string name="search_go" msgid="8298016669822141719">"Izlash"</string>
+ <string name="search_go" msgid="8298016669822141719">"Qidirish"</string>
<string name="search_hint" msgid="1733947260773056054">"Qidirish…"</string>
- <string name="searchview_description_search" msgid="6749826639098512120">"Izlash"</string>
+ <string name="searchview_description_search" msgid="6749826639098512120">"Qidirish"</string>
<string name="searchview_description_query" msgid="5911778593125355124">"Qidiruv so‘rovi"</string>
<string name="searchview_description_clear" msgid="1330281990951833033">"So‘rovni tozalash"</string>
<string name="searchview_description_submit" msgid="2688450133297983542">"So‘rov yaratish"</string>
@@ -1003,10 +1003,10 @@
<string name="sms_short_code_remember_undo_instruction" msgid="4960944133052287484">"Siz buni keyinroq sozlamalar > ilovalar menusidan o‘zgartirishingiz mumkin"</string>
<string name="sms_short_code_confirm_always_allow" msgid="3241181154869493368">"Doimo ruxsat berilsin"</string>
<string name="sms_short_code_confirm_never_allow" msgid="446992765774269673">"Hech qachon ruxsat berilmasin"</string>
- <string name="sim_removed_title" msgid="6227712319223226185">"SIM-karta olib tashlandi"</string>
+ <string name="sim_removed_title" msgid="6227712319223226185">"SIM karta olib tashlandi"</string>
<string name="sim_removed_message" msgid="5450336489923274918">"Mobil tarmoqqa ulanish uchun faol SIM kartani joylang va qurilmani o‘chirib yoqing."</string>
<string name="sim_done_button" msgid="827949989369963775">"Tayyor"</string>
- <string name="sim_added_title" msgid="3719670512889674693">"SIM-karta qo‘shildi"</string>
+ <string name="sim_added_title" msgid="3719670512889674693">"SIM karta qo‘shildi"</string>
<string name="sim_added_message" msgid="7797975656153714319">"Mobil tarmoqqa ulanish uchun qurilmangizni o‘chirib yoqing."</string>
<string name="sim_restart_button" msgid="4722407842815232347">"O‘chirib-yoqish"</string>
<string name="time_picker_dialog_title" msgid="8349362623068819295">"Vaqtni o‘rnatish"</string>
@@ -1042,9 +1042,9 @@
<string name="usb_ptp_notification_title" msgid="1347328437083192112">"USB orqali rasm o‘tkazish"</string>
<string name="usb_midi_notification_title" msgid="4850904915889144654">"USB orqali MIDI"</string>
<string name="usb_accessory_notification_title" msgid="7848236974087653666">"USB jihozga ulangan"</string>
- <string name="usb_notification_message" msgid="7347368030849048437">"Boshqa variantlar"</string>
- <string name="adb_active_notification_title" msgid="6729044778949189918">"USB orqali nosozlikni tuzatish"</string>
- <string name="adb_active_notification_message" msgid="1016654627626476142">"O‘chirib qo‘yish uchun bosing"</string>
+ <string name="usb_notification_message" msgid="7347368030849048437">"Sozlash uchun bosing."</string>
+ <string name="adb_active_notification_title" msgid="6729044778949189918">"USB orqali nosozliklarni tuzatish"</string>
+ <string name="adb_active_notification_message" msgid="1016654627626476142">"O‘chirib qo‘yish uchun bosing."</string>
<string name="select_input_method" msgid="8547250819326693584">"Klaviaturani o‘zgartirish"</string>
<string name="configure_input_methods" msgid="4769971288371946846">"Klaviaturani tanlash"</string>
<string name="show_ime" msgid="9157568568695230830">"Kiritish usulini ko‘rish"</string>
@@ -1100,7 +1100,7 @@
<string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"Masshtabni o‘zgartirish uchun ikki marta bosing"</string>
<string name="gadget_host_error_inflating" msgid="4882004314906466162">"Vidjet qo‘shilmadi."</string>
<string name="ime_action_go" msgid="8320845651737369027">"O‘tish"</string>
- <string name="ime_action_search" msgid="658110271822807811">"Izlash"</string>
+ <string name="ime_action_search" msgid="658110271822807811">"Qidirish"</string>
<string name="ime_action_send" msgid="2316166556349314424">"Jo‘natish"</string>
<string name="ime_action_next" msgid="3138843904009813834">"Keyingi"</string>
<string name="ime_action_done" msgid="8971516117910934605">"Tayyor"</string>
@@ -1209,8 +1209,8 @@
<string name="action_bar_home_description_format" msgid="7965984360903693903">"%1$s, %2$s"</string>
<string name="action_bar_home_subtitle_description_format" msgid="6985546530471780727">"%1$s, %2$s, %3$s"</string>
<string name="storage_internal" msgid="4891916833657929263">"Ichki xotira"</string>
- <string name="storage_sd_card" msgid="3282948861378286745">"SD-karta"</string>
- <string name="storage_sd_card_label" msgid="6347111320774379257">"<xliff:g id="MANUFACTURER">%s</xliff:g> SD-kartasi"</string>
+ <string name="storage_sd_card" msgid="3282948861378286745">"SD karta"</string>
+ <string name="storage_sd_card_label" msgid="6347111320774379257">"<xliff:g id="MANUFACTURER">%s</xliff:g> SD kartasi"</string>
<string name="storage_usb_drive" msgid="6261899683292244209">"USB xotira"</string>
<string name="storage_usb_drive_label" msgid="4501418548927759953">"<xliff:g id="MANUFACTURER">%s</xliff:g> USB xotira qurilmasi"</string>
<string name="storage_usb" msgid="3017954059538517278">"USB xotira"</string>
@@ -1286,10 +1286,10 @@
<string name="kg_sim_pin_instructions" msgid="2319508550934557331">"SIM kartaning PIN kodini kiriting"</string>
<string name="kg_pin_instructions" msgid="2377242233495111557">"PIN kodni tering"</string>
<string name="kg_password_instructions" msgid="5753646556186936819">"Parol kiriting"</string>
- <string name="kg_puk_enter_puk_hint" msgid="453227143861735537">"SIM-karta hozir o‘chirilgan. Davom etish uchun PUK kodni kiriting. To‘liqroq ma’lumot olish uchun tarmoq operatori bilan bog‘laning."</string>
+ <string name="kg_puk_enter_puk_hint" msgid="453227143861735537">"SIM karta hozir o‘chirilgan. Davom etish uchun PUK kodni kiriting. To‘liqroq ma’lumot olish uchun tarmoq operatori bilan bog‘laning."</string>
<string name="kg_puk_enter_pin_hint" msgid="7871604527429602024">"So‘ralgan PIN kodni kiriting"</string>
<string name="kg_enter_confirm_pin_hint" msgid="325676184762529976">"So‘ralgan PIN kodni tasdiqlang"</string>
- <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"SIM-karta qulfi ochilmoqda…"</string>
+ <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"SIM karta qulfi ochilmoqda…"</string>
<string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"Xato PIN kodi."</string>
<string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"4 tadan 8 ta raqamgacha bo‘lgan PIN kodni kiriting."</string>
<string name="kg_invalid_sim_puk_hint" msgid="6025069204539532000">"PUK kod 8 ta raqam bo‘lishi shart."</string>
@@ -1488,6 +1488,7 @@
<item quantity="one">1 soat</item>
</plurals>
<string name="zen_mode_until" msgid="7336308492289875088">"Ushbu vaqtgacha: <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
+ <string name="zen_mode_alarm" msgid="9128205721301330797">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g> gacha (keyingi signal)"</string>
<string name="zen_mode_forever" msgid="7420011936770086993">"Men o‘chirmaguncha"</string>
<string name="zen_mode_forever_dnd" msgid="3792132696572189081">"“Bezovta qilinmasin” rejimi o‘chirilmaguncha"</string>
<string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string>
diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml
index e4c5ee7..b2a6608 100644
--- a/core/res/res/values-vi/strings.xml
+++ b/core/res/res/values-vi/strings.xml
@@ -530,8 +530,8 @@
<item msgid="8901098336658710359">"Nhà riêng"</item>
<item msgid="869923650527136615">"Di Động"</item>
<item msgid="7897544654242874543">"Cơ quan"</item>
- <item msgid="1103601433382158155">"Số fax Cơ quan"</item>
- <item msgid="1735177144948329370">"Số fax Nhà riêng"</item>
+ <item msgid="1103601433382158155">"Số fax cơ quan"</item>
+ <item msgid="1735177144948329370">"Số fax nhà riêng"</item>
<item msgid="603878674477207394">"Số máy nhắn tin"</item>
<item msgid="1650824275177931637">"Khác"</item>
<item msgid="9192514806975898961">"Tùy chỉnh"</item>
@@ -573,8 +573,8 @@
<string name="phoneTypeHome" msgid="2570923463033985887">"Nhà riêng"</string>
<string name="phoneTypeMobile" msgid="6501463557754751037">"Di Động"</string>
<string name="phoneTypeWork" msgid="8863939667059911633">"Cơ quan"</string>
- <string name="phoneTypeFaxWork" msgid="3517792160008890912">"Số fax Cơ quan"</string>
- <string name="phoneTypeFaxHome" msgid="2067265972322971467">"Số fax Nhà riêng"</string>
+ <string name="phoneTypeFaxWork" msgid="3517792160008890912">"Số fax cơ quan"</string>
+ <string name="phoneTypeFaxHome" msgid="2067265972322971467">"Số fax nhà riêng"</string>
<string name="phoneTypePager" msgid="7582359955394921732">"Số máy nhắn tin"</string>
<string name="phoneTypeOther" msgid="1544425847868765990">"Khác"</string>
<string name="phoneTypeCallback" msgid="2712175203065678206">"Số gọi lại"</string>
@@ -586,8 +586,8 @@
<string name="phoneTypeRadio" msgid="4093738079908667513">"Radio"</string>
<string name="phoneTypeTelex" msgid="3367879952476250512">"Số telex"</string>
<string name="phoneTypeTtyTdd" msgid="8606514378585000044">"TTY TDD"</string>
- <string name="phoneTypeWorkMobile" msgid="1311426989184065709">"Số điện thoại di động tại Cơ quan"</string>
- <string name="phoneTypeWorkPager" msgid="649938731231157056">"Số Máy nhắn tin tại Cơ quan"</string>
+ <string name="phoneTypeWorkMobile" msgid="1311426989184065709">"Di động tại cơ quan"</string>
+ <string name="phoneTypeWorkPager" msgid="649938731231157056">"Số máy nhắn tin cơ quan"</string>
<string name="phoneTypeAssistant" msgid="5596772636128562884">"Số điện thoại Hỗ trợ"</string>
<string name="phoneTypeMms" msgid="7254492275502768992">"MMS"</string>
<string name="eventTypeCustom" msgid="7837586198458073404">"Tùy chỉnh"</string>
@@ -1488,6 +1488,7 @@
<item quantity="one">Trong 1 giờ</item>
</plurals>
<string name="zen_mode_until" msgid="7336308492289875088">"Cho đến <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
+ <string name="zen_mode_alarm" msgid="9128205721301330797">"Cho tới <xliff:g id="FORMATTEDTIME">%1$s</xliff:g> (cảnh báo tiếp theo)"</string>
<string name="zen_mode_forever" msgid="7420011936770086993">"Cho đến khi bạn tắt tính năng này"</string>
<string name="zen_mode_forever_dnd" msgid="3792132696572189081">"Cho đến khi bạn tắt Đừng làm phiền"</string>
<string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string>
diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml
index 3ffb555..c005f0b 100644
--- a/core/res/res/values-zh-rCN/strings.xml
+++ b/core/res/res/values-zh-rCN/strings.xml
@@ -223,7 +223,7 @@
<string name="global_action_lockdown" msgid="8751542514724332873">"立即锁定"</string>
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
<string name="safeMode" msgid="2788228061547930246">"安全模式"</string>
- <string name="android_system_label" msgid="6577375335728551336">"Android系统"</string>
+ <string name="android_system_label" msgid="6577375335728551336">"Android 系统"</string>
<string name="user_owner_label" msgid="2804351898001038951">"个人"</string>
<string name="managed_profile_label" msgid="6260850669674791528">"工作"</string>
<string name="permgrouplab_contacts" msgid="3657758145679177612">"通讯录"</string>
@@ -376,10 +376,10 @@
<string name="permdesc_setTimeZone" product="tablet" msgid="1676983712315827645">"允许应用更改平板电脑的时区。"</string>
<string name="permdesc_setTimeZone" product="tv" msgid="888864653946175955">"允许应用更改电视的时区。"</string>
<string name="permdesc_setTimeZone" product="default" msgid="4499943488436633398">"允许应用更改手机的时区。"</string>
- <string name="permlab_getAccounts" msgid="1086795467760122114">"查找设备上的帐户"</string>
- <string name="permdesc_getAccounts" product="tablet" msgid="2741496534769660027">"允许该应用获取平板电脑已知的帐户列表,其中可能包括由已安装的应用创建的所有帐户。"</string>
- <string name="permdesc_getAccounts" product="tv" msgid="4190633395633907543">"允许应用获取电视已知的帐户列表,其中可能包括由已安装的应用创建的所有帐户。"</string>
- <string name="permdesc_getAccounts" product="default" msgid="3448316822451807382">"允许该应用获取手机已知的帐户列表,其中可能包括由已安装的应用创建的所有帐户。"</string>
+ <string name="permlab_getAccounts" msgid="1086795467760122114">"查找设备上的帐号"</string>
+ <string name="permdesc_getAccounts" product="tablet" msgid="2741496534769660027">"允许该应用获取平板电脑已知的帐号列表,其中可能包括由已安装的应用创建的所有帐号。"</string>
+ <string name="permdesc_getAccounts" product="tv" msgid="4190633395633907543">"允许应用获取电视已知的帐号列表,其中可能包括由已安装的应用创建的所有帐号。"</string>
+ <string name="permdesc_getAccounts" product="default" msgid="3448316822451807382">"允许该应用获取手机已知的帐号列表,其中可能包括由已安装的应用创建的所有帐号。"</string>
<string name="permlab_accessNetworkState" msgid="4951027964348974773">"查看网络连接"</string>
<string name="permdesc_accessNetworkState" msgid="8318964424675960975">"允许该应用查看网络连接的相关信息,例如存在和连接的网络。"</string>
<string name="permlab_createNetworkSockets" msgid="8018758136404323658">"完全的网络访问权限"</string>
@@ -436,11 +436,11 @@
</string-array>
<string name="fingerprint_icon_content_description" msgid="2340202869968465936">"指纹图标"</string>
<string name="permlab_readSyncSettings" msgid="6201810008230503052">"读取同步设置"</string>
- <string name="permdesc_readSyncSettings" msgid="2706745674569678644">"允许该应用读取某个帐户的同步设置。例如,此权限可确定“联系人”应用是否与某个帐户同步。"</string>
+ <string name="permdesc_readSyncSettings" msgid="2706745674569678644">"允许该应用读取某个帐号的同步设置。例如,此权限可确定“联系人”应用是否与某个帐号同步。"</string>
<string name="permlab_writeSyncSettings" msgid="5408694875793945314">"启用和停用同步"</string>
- <string name="permdesc_writeSyncSettings" msgid="8956262591306369868">"允许该应用修改某个帐户的同步设置。例如,此权限可用于在“联系人”应用与某个帐户之间启用同步。"</string>
+ <string name="permdesc_writeSyncSettings" msgid="8956262591306369868">"允许该应用修改某个帐号的同步设置。例如,此权限可用于在“联系人”应用与某个帐号之间启用同步。"</string>
<string name="permlab_readSyncStats" msgid="7396577451360202448">"读取同步统计信息"</string>
- <string name="permdesc_readSyncStats" msgid="1510143761757606156">"允许该应用读取某个帐户的同步统计信息,包括同步活动历史记录和同步数据量。"</string>
+ <string name="permdesc_readSyncStats" msgid="1510143761757606156">"允许该应用读取某个帐号的同步统计信息,包括同步活动历史记录和同步数据量。"</string>
<string name="permlab_sdcardRead" product="nosdcard" msgid="367275095159405468">"读取您的USB存储设备中的内容"</string>
<string name="permlab_sdcardRead" product="default" msgid="2188156462934977940">"读取您的SD卡中的内容"</string>
<string name="permdesc_sdcardRead" product="nosdcard" msgid="3446988712598386079">"允许应用读取您USB存储设备中的内容。"</string>
@@ -696,9 +696,9 @@
<string name="lockscreen_failed_attempts_now_wiping" product="default" msgid="3025504721764922246">"您已经<xliff:g id="NUMBER">%d</xliff:g>次错误地尝试解锁手机。手机现在将恢复为出厂默认设置。"</string>
<string name="lockscreen_too_many_failed_attempts_countdown" msgid="6251480343394389665">"<xliff:g id="NUMBER">%d</xliff:g>秒后重试。"</string>
<string name="lockscreen_forgot_pattern_button_text" msgid="2626999449610695930">"忘记了图案?"</string>
- <string name="lockscreen_glogin_forgot_pattern" msgid="2588521501166032747">"帐户解锁"</string>
+ <string name="lockscreen_glogin_forgot_pattern" msgid="2588521501166032747">"帐号解锁"</string>
<string name="lockscreen_glogin_too_many_attempts" msgid="2751368605287288808">"图案尝试次数过多"</string>
- <string name="lockscreen_glogin_instructions" msgid="3931816256100707784">"要解除锁定,请使用您的Google帐户登录。"</string>
+ <string name="lockscreen_glogin_instructions" msgid="3931816256100707784">"要解除锁定,请使用您的Google帐号登录。"</string>
<string name="lockscreen_glogin_username_hint" msgid="8846881424106484447">"用户名(电子邮件)"</string>
<string name="lockscreen_glogin_password_hint" msgid="5958028383954738528">"密码"</string>
<string name="lockscreen_glogin_submit_button" msgid="7130893694795786300">"登录"</string>
@@ -1108,13 +1108,13 @@
<string name="ime_action_default" msgid="2840921885558045721">"执行"</string>
<string name="dial_number_using" msgid="5789176425167573586">"拨打电话\n<xliff:g id="NUMBER">%s</xliff:g>"</string>
<string name="create_contact_using" msgid="4947405226788104538">"创建电话号码为\n<xliff:g id="NUMBER">%s</xliff:g> 的联系人"</string>
- <string name="grant_credentials_permission_message_header" msgid="2106103817937859662">"以下一个或多个应用请求获得相应权限,以便在当前和以后访问您的帐户。"</string>
+ <string name="grant_credentials_permission_message_header" msgid="2106103817937859662">"以下一个或多个应用请求获得相应权限,以便在当前和以后访问您的帐号。"</string>
<string name="grant_credentials_permission_message_footer" msgid="3125211343379376561">"您是否同意此请求?"</string>
<string name="grant_permissions_header_text" msgid="6874497408201826708">"访问权限请求"</string>
<string name="allow" msgid="7225948811296386551">"允许"</string>
<string name="deny" msgid="2081879885755434506">"拒绝"</string>
<string name="permission_request_notification_title" msgid="6486759795926237907">"权限请求"</string>
- <string name="permission_request_notification_with_subtitle" msgid="8530393139639560189">"应用对帐户 <xliff:g id="ACCOUNT">%s</xliff:g>\n 提出权限请求。"</string>
+ <string name="permission_request_notification_with_subtitle" msgid="8530393139639560189">"应用对帐号 <xliff:g id="ACCOUNT">%s</xliff:g>\n 提出权限请求。"</string>
<string name="forward_intent_to_owner" msgid="1207197447013960896">"您目前是在工作资料之外使用此应用"</string>
<string name="forward_intent_to_work" msgid="621480743856004612">"您目前是在工作资料内使用此应用"</string>
<string name="input_method_binding_label" msgid="1283557179944992649">"输入法"</string>
@@ -1163,13 +1163,13 @@
<string name="gpsVerifYes" msgid="2346566072867213563">"是"</string>
<string name="gpsVerifNo" msgid="1146564937346454865">"否"</string>
<string name="sync_too_many_deletes" msgid="5296321850662746890">"超出删除限制"</string>
- <string name="sync_too_many_deletes_desc" msgid="496551671008694245">"帐户 <xliff:g id="ACCOUNT_NAME">%3$s</xliff:g> 在进行“<xliff:g id="TYPE_OF_SYNC">%2$s</xliff:g>”同步时删除了 <xliff:g id="NUMBER_OF_DELETED_ITEMS">%1$d</xliff:g> 项内容。您要如何处理这些删除的内容?"</string>
+ <string name="sync_too_many_deletes_desc" msgid="496551671008694245">"帐号 <xliff:g id="ACCOUNT_NAME">%3$s</xliff:g> 在进行“<xliff:g id="TYPE_OF_SYNC">%2$s</xliff:g>”同步时删除了 <xliff:g id="NUMBER_OF_DELETED_ITEMS">%1$d</xliff:g> 项内容。您要如何处理这些删除的内容?"</string>
<string name="sync_really_delete" msgid="2572600103122596243">"删除这些内容"</string>
<string name="sync_undo_deletes" msgid="2941317360600338602">"撤消删除"</string>
<string name="sync_do_nothing" msgid="3743764740430821845">"目前不进行任何操作"</string>
- <string name="choose_account_label" msgid="5655203089746423927">"选择帐户"</string>
- <string name="add_account_label" msgid="2935267344849993553">"添加帐户"</string>
- <string name="add_account_button_label" msgid="3611982894853435874">"添加帐户"</string>
+ <string name="choose_account_label" msgid="5655203089746423927">"选择帐号"</string>
+ <string name="add_account_label" msgid="2935267344849993553">"添加帐号"</string>
+ <string name="add_account_button_label" msgid="3611982894853435874">"添加帐号"</string>
<string name="number_picker_increment_button" msgid="2412072272832284313">"增大"</string>
<string name="number_picker_decrement_button" msgid="476050778386779067">"减小"</string>
<string name="number_picker_increment_scroll_mode" msgid="3073101067441638428">"触摸 <xliff:g id="VALUE">%s</xliff:g> 次并按住。"</string>
@@ -1296,13 +1296,13 @@
<string name="kg_invalid_puk" msgid="3638289409676051243">"请重新输入正确的PUK码。如果尝试错误次数过多,SIM卡将永久停用。"</string>
<string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"PIN码不匹配"</string>
<string name="kg_login_too_many_attempts" msgid="6486842094005698475">"图案尝试次数过多"</string>
- <string name="kg_login_instructions" msgid="1100551261265506448">"要解锁,请登录您的Google帐户。"</string>
+ <string name="kg_login_instructions" msgid="1100551261265506448">"要解锁,请登录您的Google帐号。"</string>
<string name="kg_login_username_hint" msgid="5718534272070920364">"用户名(电子邮件地址)"</string>
<string name="kg_login_password_hint" msgid="9057289103827298549">"密码"</string>
<string name="kg_login_submit_button" msgid="5355904582674054702">"登录"</string>
<string name="kg_login_invalid_input" msgid="5754664119319872197">"用户名或密码无效。"</string>
<string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"忘记了用户名或密码?\n请访问 "<b>"google.com/accounts/recovery"</b>"。"</string>
- <string name="kg_login_checking_password" msgid="1052685197710252395">"正在检查帐户…"</string>
+ <string name="kg_login_checking_password" msgid="1052685197710252395">"正在检查帐号…"</string>
<string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"您已经<xliff:g id="NUMBER_0">%d</xliff:g>次输错了PIN码。\n\n请在<xliff:g id="NUMBER_1">%d</xliff:g>秒后重试。"</string>
<string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"您已连续 <xliff:g id="NUMBER_0">%d</xliff:g> 次输错密码。\n\n请在 <xliff:g id="NUMBER_1">%d</xliff:g> 秒后重试。"</string>
<string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"您已连续 <xliff:g id="NUMBER_0">%d</xliff:g> 次画错解锁图案。\n\n请在 <xliff:g id="NUMBER_1">%d</xliff:g> 秒后重试。"</string>
@@ -1312,9 +1312,9 @@
<string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"您已经<xliff:g id="NUMBER">%d</xliff:g>次错误地尝试解锁平板电脑。平板电脑现在将恢复为出厂默认设置。"</string>
<string name="kg_failed_attempts_now_wiping" product="tv" msgid="4987878286750741463">"您已经 <xliff:g id="NUMBER">%d</xliff:g> 次错误地尝试解锁电视。电视现在将恢复为出厂默认设置。"</string>
<string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"您已经<xliff:g id="NUMBER">%d</xliff:g>次错误地尝试解锁手机。手机现在将恢复为出厂默认设置。"</string>
- <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"您已连续 <xliff:g id="NUMBER_0">%d</xliff:g> 次画错解锁图案。如果再尝试 <xliff:g id="NUMBER_1">%d</xliff:g> 次后仍不成功,系统就会要求您使用自己的电子邮件帐户解锁平板电脑。\n\n请在 <xliff:g id="NUMBER_2">%d</xliff:g> 秒后重试。"</string>
- <string name="kg_failed_attempts_almost_at_login" product="tv" msgid="4224651132862313471">"您已连续 <xliff:g id="NUMBER_0">%d</xliff:g> 次画错解锁图案。如果再尝试 <xliff:g id="NUMBER_1">%d</xliff:g> 次后仍不成功,系统就会要求您使用电子邮件帐户解锁电视。\n\n请在 <xliff:g id="NUMBER_2">%d</xliff:g> 秒后重试。"</string>
- <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"您已连续 <xliff:g id="NUMBER_0">%d</xliff:g> 次画错解锁图案。如果再尝试 <xliff:g id="NUMBER_1">%d</xliff:g> 次后仍不成功,系统就会要求您使用自己的电子邮件帐户解锁手机。\n\n请在 <xliff:g id="NUMBER_2">%d</xliff:g> 秒后重试。"</string>
+ <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"您已连续 <xliff:g id="NUMBER_0">%d</xliff:g> 次画错解锁图案。如果再尝试 <xliff:g id="NUMBER_1">%d</xliff:g> 次后仍不成功,系统就会要求您使用自己的电子邮件帐号解锁平板电脑。\n\n请在 <xliff:g id="NUMBER_2">%d</xliff:g> 秒后重试。"</string>
+ <string name="kg_failed_attempts_almost_at_login" product="tv" msgid="4224651132862313471">"您已连续 <xliff:g id="NUMBER_0">%d</xliff:g> 次画错解锁图案。如果再尝试 <xliff:g id="NUMBER_1">%d</xliff:g> 次后仍不成功,系统就会要求您使用电子邮件帐号解锁电视。\n\n请在 <xliff:g id="NUMBER_2">%d</xliff:g> 秒后重试。"</string>
+ <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"您已连续 <xliff:g id="NUMBER_0">%d</xliff:g> 次画错解锁图案。如果再尝试 <xliff:g id="NUMBER_1">%d</xliff:g> 次后仍不成功,系统就会要求您使用自己的电子邮件帐号解锁手机。\n\n请在 <xliff:g id="NUMBER_2">%d</xliff:g> 秒后重试。"</string>
<string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" — "</string>
<string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"删除"</string>
<string name="safe_media_volume_warning" product="default" msgid="2276318909314492312">"要将音量调高到推荐水平以上吗?\n\n长时间保持高音量可能会损伤听力。"</string>
@@ -1488,6 +1488,7 @@
<item quantity="one">1 小时</item>
</plurals>
<string name="zen_mode_until" msgid="7336308492289875088">"到<xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
+ <string name="zen_mode_alarm" msgid="9128205721301330797">"直到<xliff:g id="FORMATTEDTIME">%1$s</xliff:g>(闹钟下次响铃时)"</string>
<string name="zen_mode_forever" msgid="7420011936770086993">"直到您将其关闭"</string>
<string name="zen_mode_forever_dnd" msgid="3792132696572189081">"直到您关闭“勿扰”模式"</string>
<string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string>
diff --git a/core/res/res/values-zh-rHK/strings.xml b/core/res/res/values-zh-rHK/strings.xml
index ffa6fb1..ef52d00 100644
--- a/core/res/res/values-zh-rHK/strings.xml
+++ b/core/res/res/values-zh-rHK/strings.xml
@@ -1488,6 +1488,7 @@
<item quantity="one">需時 1 小時</item>
</plurals>
<string name="zen_mode_until" msgid="7336308492289875088">"完成時間:<xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
+ <string name="zen_mode_alarm" msgid="9128205721301330797">"直至<xliff:g id="FORMATTEDTIME">%1$s</xliff:g> (下一次響鬧)"</string>
<string name="zen_mode_forever" msgid="7420011936770086993">"直至您關閉這項設定"</string>
<string name="zen_mode_forever_dnd" msgid="3792132696572189081">"直至您關閉「請勿騷擾」功能"</string>
<string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g>/<xliff:g id="REST">%2$s</xliff:g>"</string>
diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml
index f141374..175f7dc 100644
--- a/core/res/res/values-zh-rTW/strings.xml
+++ b/core/res/res/values-zh-rTW/strings.xml
@@ -1488,6 +1488,7 @@
<item quantity="one">1 小時</item>
</plurals>
<string name="zen_mode_until" msgid="7336308492289875088">"結束時間:<xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
+ <string name="zen_mode_alarm" msgid="9128205721301330797">"到<xliff:g id="FORMATTEDTIME">%1$s</xliff:g> 為止 (下一個鬧鐘)"</string>
<string name="zen_mode_forever" msgid="7420011936770086993">"手動關閉這項設定前一律啟用"</string>
<string name="zen_mode_forever_dnd" msgid="3792132696572189081">"直到您關閉「零打擾」模式"</string>
<string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g>/<xliff:g id="REST">%2$s</xliff:g>"</string>
diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml
index f29e9f9..5df3318 100644
--- a/core/res/res/values-zu/strings.xml
+++ b/core/res/res/values-zu/strings.xml
@@ -1488,6 +1488,7 @@
<item quantity="other">Ngamahora angu-%d</item>
</plurals>
<string name="zen_mode_until" msgid="7336308492289875088">"Kuze kube ngu-<xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
+ <string name="zen_mode_alarm" msgid="9128205721301330797">"Kuze kube ngu-<xliff:g id="FORMATTEDTIME">%1$s</xliff:g> (i-alamu elandelayo)"</string>
<string name="zen_mode_forever" msgid="7420011936770086993">"Uze uvale lokhu"</string>
<string name="zen_mode_forever_dnd" msgid="3792132696572189081">"Uze uvale ungaphazamisi"</string>
<string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string>
diff --git a/core/res/res/values/attrs_manifest.xml b/core/res/res/values/attrs_manifest.xml
index 1a45b3a..cf08dea 100644
--- a/core/res/res/values/attrs_manifest.xml
+++ b/core/res/res/values/attrs_manifest.xml
@@ -2095,6 +2095,10 @@
<enum name="hdpi" value="240" />
<!-- An extra high density screen, approximately 320dpi. -->
<enum name="xhdpi" value="320" />
+ <!-- An extra extra high density screen, approximately 480dpi. -->
+ <enum name="xxhdpi" value="480" />
+ <!-- An extra extra extra high density screen, approximately 640dpi. -->
+ <enum name="xxxhdpi" value="640" />
</attr>
</declare-styleable>
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
old mode 100755
new mode 100644
index ae8cae8..6c96f84
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -387,6 +387,13 @@
<!-- Boolean indicating autojoin will prefer 5GHz and choose 5GHz BSSIDs -->
<bool translatable="true" name="config_wifi_enable_5GHz_preference">true</bool>
+ <!-- Boolean indicating whether or not to revert to default country code when cellular
+ radio is unable to find any MCC information to infer wifi country code from -->
+ <bool translatable="false" name="config_wifi_revert_country_code_on_cellular_loss">false</bool>
+
+ <!-- Boolean indicating whether or not wifi firmware debugging is enabled -->
+ <bool translatable="false" name="config_wifi_enable_wifi_firmware_debugging">false</bool>
+
<!-- Integer specifying the basic autojoin parameters -->
<integer translatable="false" name="config_wifi_framework_5GHz_preference_boost_threshold">-65</integer>
<integer translatable="false" name="config_wifi_framework_5GHz_preference_boost_factor">5</integer>
@@ -619,6 +626,17 @@
<!-- rotation: 270 (rotate CW) --> <item>-25</item> <item>65</item>
</integer-array>
+ <!-- Indicate the name of the window orientation sensor type if present. A
+ window orientation sensor produces values to be used in lieu of the
+ typical, accelerometer based sensor. It must only produce integral
+ values between 0 and 3, inclusive, with each one corresponding to a
+ given rotation:
+ 0: 0 degrees of rotation (natural)
+ 1: 90 degrees of rotation (rotate CCW)
+ 2: 180 degrees of rotation (reverse)
+ 3: 270 degrees of rotation (rotate CW) -->
+ <string name="config_orientationSensorType" translatable="false">@null</string>
+
<!-- Lid switch behavior -->
<!-- The number of degrees to rotate the display when the keyboard is open.
@@ -1725,6 +1743,28 @@
-->
<bool name="config_enableWifiDisplay">false</bool>
+ <!-- The color transform values that correspond to each respective configuration mode for the
+ built-in display, or -1 if the mode is unsupported by the device. The possible
+ configuration modes are:
+ 1. Wide-gamut ("Vibrant")
+ 2. Adobe RGB ("Natural")
+ 3. sRGB ("Standard")
+
+ For example, if a device had Wide-gamut as color transform mode 1, sRGB mode as color
+ transform mode 7, and did not support Adobe RGB at all this would look like:
+
+ <integer-array name="config_colorTransforms">
+ <item>1</item>
+ <item>-1</item>
+ <item>7</item>
+ </integer-array>
+ -->
+ <integer-array name="config_colorTransforms">
+ <item>-1</item>
+ <item>-1</item>
+ <item>-1</item>
+ </integer-array>
+
<!-- When true use the linux /dev/input/event subsystem to detect the switch changes
on the headphone/microphone jack. When false use the older uevent framework. -->
<bool name="config_useDevInputEventForAudioJack">false</bool>
@@ -2270,4 +2310,20 @@
<string-array name="config_cell_retries_per_error_code">
</string-array>
+ <!-- Set initial MaxRetry value for operators -->
+ <integer name="config_mdc_initial_max_retry">1</integer>
+
+ <!-- The OEM specified sensor type for the gesture to launch the camear app. -->
+ <integer name="config_cameraLaunchGestureSensorType">-1</integer>
+ <!-- The OEM specified sensor string type for the gesture to launch camera app, this value
+ must match the value of config_cameraLaunchGestureSensorType in OEM's HAL -->
+ <string translatable="false" name="config_cameraLaunchGestureSensorStringType"></string>
+
+ <!-- Allow the gesture to double tap the power button twice to start the camera while the device
+ is non-interactive. -->
+ <bool name="config_cameraDoubleTapPowerGestureEnabled">true</bool>
+
+ <!-- The BT name of the keyboard packaged with the device. If this is defined, SystemUI will
+ automatically try to pair with it when the device exits tablet mode. -->
+ <string translatable="false" name="config_packagedKeyboardName"></string>
</resources>
diff --git a/core/res/res/values/dimens.xml b/core/res/res/values/dimens.xml
index 09c1e6f..8635a4f 100644
--- a/core/res/res/values/dimens.xml
+++ b/core/res/res/values/dimens.xml
@@ -37,7 +37,7 @@
<!-- Height of the bottom navigation bar in portrait; often the same as @dimen/navigation_bar_height -->
<dimen name="navigation_bar_height_landscape">48dp</dimen>
<!-- Width of the navigation bar when it is placed vertically on the screen -->
- <dimen name="navigation_bar_width">42dp</dimen>
+ <dimen name="navigation_bar_width">48dp</dimen>
<!-- Height of notification icons in the status bar -->
<dimen name="status_bar_icon_size">24dip</dimen>
<!-- Size of the giant number (unread count) in the notifications -->
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index d9fa287..8a9b9cf 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -4036,6 +4036,9 @@
<!-- Zen mode condition - line two: ending time. [CHAR LIMIT=NONE] -->
<string name="zen_mode_until">Until <xliff:g id="formattedTime" example="10:00 PM">%1$s</xliff:g></string>
+ <!-- Zen mode condition - line one: Until next alarm. [CHAR LIMIT=NONE] -->
+ <string name="zen_mode_alarm">Until <xliff:g id="formattedTime" example="10:00 PM">%1$s</xliff:g> (next alarm)</string>
+
<!-- Zen mode condition: no exit criteria. [CHAR LIMIT=NONE] -->
<string name="zen_mode_forever">Until you turn this off</string>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
old mode 100755
new mode 100644
index 262aa76..1bfb06c
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -301,6 +301,8 @@
<java-symbol type="bool" name="config_wifi_only_link_same_credential_configurations" />
<java-symbol type="bool" name="config_wifi_enable_disconnection_debounce" />
<java-symbol type="bool" name="config_wifi_enable_5GHz_preference" />
+ <java-symbol type="bool" name="config_wifi_revert_country_code_on_cellular_loss" />
+ <java-symbol type="bool" name="config_wifi_enable_wifi_firmware_debugging" />
<java-symbol type="bool" name="config_supportMicNearUltrasound" />
<java-symbol type="bool" name="config_supportSpeakerNearUltrasound" />
<java-symbol type="integer" name="config_wifi_framework_5GHz_preference_boost_threshold" />
@@ -403,6 +405,7 @@
<java-symbol type="integer" name="config_volte_replacement_rat"/>
<java-symbol type="integer" name="config_valid_wappush_index" />
<java-symbol type="integer" name="config_overrideHasPermanentMenuKey" />
+ <java-symbol type="integer" name="config_mdc_initial_max_retry" />
<java-symbol type="bool" name="config_hasPermanentDpad" />
<java-symbol type="color" name="tab_indicator_text_v4" />
@@ -1128,6 +1131,7 @@
<java-symbol type="array" name="config_telephonyHardware" />
<java-symbol type="array" name="config_keySystemUuidMapping" />
<java-symbol type="array" name="config_gpsParameters" />
+ <java-symbol type="array" name="config_colorTransforms" />
<java-symbol type="drawable" name="default_wallpaper" />
<java-symbol type="drawable" name="indicator_input_error" />
@@ -1547,6 +1551,7 @@
<java-symbol type="string" name="bugreport_title" />
<java-symbol type="string" name="bugreport_message" />
<java-symbol type="string" name="bugreport_status" />
+ <java-symbol type="string" name="config_orientationSensorType" />
<java-symbol type="string" name="faceunlock_multiple_failures" />
<java-symbol type="string" name="global_action_power_off" />
<java-symbol type="string" name="global_actions_airplane_mode_off_status" />
@@ -2078,6 +2083,7 @@
<java-symbol type="string" name="zen_mode_default_events_name" />
<java-symbol type="array" name="config_system_condition_providers" />
<java-symbol type="string" name="muted_by" />
+ <java-symbol type="string" name="zen_mode_alarm" />
<java-symbol type="string" name="select_day" />
<java-symbol type="string" name="select_year" />
@@ -2318,6 +2324,12 @@
<java-symbol type="array" name="config_cell_retries_per_error_code" />
<java-symbol type="drawable" name="ic_more_items" />
+ <!-- Gesture -->
+ <java-symbol type="integer" name="config_cameraLaunchGestureSensorType" />
+ <java-symbol type="string" name="config_cameraLaunchGestureSensorStringType" />
+ <java-symbol type="bool" name="config_cameraDoubleTapPowerGestureEnabled" />
+
<java-symbol type="drawable" name="platlogo_m" />
+ <java-symbol type="string" name="config_packagedKeyboardName" />
</resources>
diff --git a/core/res/res/xml/power_profile.xml b/core/res/res/xml/power_profile.xml
index 28d99d8..ddd0ca2 100644
--- a/core/res/res/xml/power_profile.xml
+++ b/core/res/res/xml/power_profile.xml
@@ -47,17 +47,38 @@
<value>0.2</value> <!-- ~2mA -->
<value>0.1</value> <!-- ~1mA -->
</array>
- <!-- Different CPU speeds as reported in
- /sys/devices/system/cpu/cpu0/cpufreq/stats/time_in_state -->
- <array name="cpu.speeds">
+
+ <!-- A list of heterogeneous CPU clusters, where the value for each cluster represents the
+ number of CPU cores for that cluster.
+
+ Ex:
+ <array name="cpu.clusters.cores">
+ <value>4</value> // cluster 0 has cpu0, cpu1, cpu2, cpu3
+ <value>2</value> // cluster 1 has cpu4, cpu5
+ </array> -->
+ <array name="cpu.clusters.cores">
+ <value>1</value> <!-- cluster 0 has cpu0 -->
+ </array>
+
+ <!-- Different CPU speeds for cluster 0 as reported in
+ /sys/devices/system/cpu/cpu0/cpufreq/stats/time_in_state.
+
+ There must be one of these for each cluster, labeled:
+ cpu.speeds.cluster0, cpu.speeds.cluster1, etc... -->
+ <array name="cpu.speeds.cluster0">
<value>400000</value> <!-- 400 MHz CPU speed -->
</array>
- <!-- Current when CPU is idle -->
- <item name="cpu.idle">0.1</item>
- <!-- Current at each CPU speed, as per 'cpu.speeds' -->
- <array name="cpu.active">
+
+ <!-- Current at each CPU speed for cluster 0, as per 'cpu.speeds.cluster0'.
+ Like cpu.speeds.cluster0, there must be one of these present for
+ each heterogeneous CPU cluster. -->
+ <array name="cpu.active.cluster0">
<value>0.1</value> <!-- ~100mA -->
</array>
+
+ <!-- Current when CPU is idle -->
+ <item name="cpu.idle">0.1</item>
+
<!-- This is the battery capacity in mAh (measured at nominal voltage) -->
<item name="battery.capacity">1000</item>
diff --git a/data/keyboards/Vendor_18d1_Product_5018.kcm b/data/keyboards/Vendor_18d1_Product_5018.kcm
new file mode 100644
index 0000000..0ca85a2
--- /dev/null
+++ b/data/keyboards/Vendor_18d1_Product_5018.kcm
@@ -0,0 +1,321 @@
+# Copyright (C) 2015 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+#
+# Key character map for Google Pixel C Keyboard
+#
+
+type FULL
+
+### Basic QWERTY keys ###
+
+key A {
+ label: 'A'
+ base: 'a'
+ shift, capslock: 'A'
+}
+
+key B {
+ label: 'B'
+ base: 'b'
+ shift, capslock: 'B'
+}
+
+key C {
+ label: 'C'
+ base: 'c'
+ shift, capslock: 'C'
+ alt: '\u00e7'
+ shift+alt: '\u00c7'
+}
+
+key D {
+ label: 'D'
+ base: 'd'
+ shift, capslock: 'D'
+}
+
+key E {
+ label: 'E'
+ base: 'e'
+ shift, capslock: 'E'
+ alt: '\u0301'
+}
+
+key F {
+ label: 'F'
+ base: 'f'
+ shift, capslock: 'F'
+}
+
+key G {
+ label: 'G'
+ base: 'g'
+ shift, capslock: 'G'
+}
+
+key H {
+ label: 'H'
+ base: 'h'
+ shift, capslock: 'H'
+}
+
+key I {
+ label: 'I'
+ base: 'i'
+ shift, capslock: 'I'
+ alt: '\u0302'
+}
+
+key J {
+ label: 'J'
+ base: 'j'
+ shift, capslock: 'J'
+}
+
+key K {
+ label: 'K'
+ base: 'k'
+ shift, capslock: 'K'
+}
+
+key L {
+ label: 'L'
+ base: 'l'
+ shift, capslock: 'L'
+}
+
+key M {
+ label: 'M'
+ base: 'm'
+ shift, capslock: 'M'
+}
+
+key N {
+ label: 'N'
+ base: 'n'
+ shift, capslock: 'N'
+ alt: '\u0303'
+}
+
+key O {
+ label: 'O'
+ base: 'o'
+ shift, capslock: 'O'
+ ralt: '['
+ ralt+shift: '{'
+}
+
+key P {
+ label: 'P'
+ base: 'p'
+ shift, capslock: 'P'
+ ralt: ']'
+ ralt+shift: '}'
+}
+
+key Q {
+ label: 'Q'
+ base: 'q'
+ shift, capslock: 'Q'
+}
+
+key R {
+ label: 'R'
+ base: 'r'
+ shift, capslock: 'R'
+}
+
+key S {
+ label: 'S'
+ base: 's'
+ shift, capslock: 'S'
+ alt: '\u00df'
+}
+
+key T {
+ label: 'T'
+ base: 't'
+ shift, capslock: 'T'
+}
+
+key U {
+ label: 'U'
+ base: 'u'
+ shift, capslock: 'U'
+ alt: '\u0308'
+}
+
+key V {
+ label: 'V'
+ base: 'v'
+ shift, capslock: 'V'
+}
+
+key W {
+ label: 'W'
+ base: 'w'
+ shift, capslock: 'W'
+}
+
+key X {
+ label: 'X'
+ base: 'x'
+ shift, capslock: 'X'
+}
+
+key Y {
+ label: 'Y'
+ base: 'y'
+ shift, capslock: 'Y'
+}
+
+key Z {
+ label: 'Z'
+ base: 'z'
+ shift, capslock: 'Z'
+}
+
+key 0 {
+ label: '0'
+ base: '0'
+ shift: ')'
+}
+
+key 1 {
+ label: '1'
+ base: '1'
+ shift: '!'
+ ralt: replace ESCAPE
+}
+
+key 2 {
+ label: '2'
+ base: '2'
+ shift: '@'
+ ralt: '`'
+ ralt+shift: '~'
+}
+
+key 3 {
+ label: '3'
+ base: '3'
+ shift: '#'
+}
+
+key 4 {
+ label: '4'
+ base: '4'
+ shift: '$'
+}
+
+key 5 {
+ label: '5'
+ base: '5'
+ shift: '%'
+}
+
+key 6 {
+ label: '6'
+ base: '6'
+ shift: '^'
+ alt+shift: '\u0302'
+}
+
+key 7 {
+ label: '7'
+ base: '7'
+ shift: '&'
+}
+
+key 8 {
+ label: '8'
+ base: '8'
+ shift: '*'
+}
+
+key 9 {
+ label: '9'
+ base: '9'
+ shift: '('
+}
+
+key SPACE {
+ label: ' '
+ base: ' '
+ alt, meta: fallback SEARCH
+ ctrl: fallback LANGUAGE_SWITCH
+}
+
+key ENTER {
+ label: '\n'
+ base: '\n'
+}
+
+key TAB {
+ label: '\t'
+ base: '\t'
+}
+
+key COMMA {
+ label: ','
+ base: ','
+ shift: '<'
+}
+
+key PERIOD {
+ label: '.'
+ base: '.'
+ shift: '>'
+}
+
+key SLASH {
+ label: '/'
+ base: '/'
+ shift: '?'
+}
+
+key MINUS {
+ label: '-'
+ base: '-'
+ shift: '_'
+}
+
+key EQUALS {
+ label: '='
+ base: '='
+ shift: '+'
+ ralt: '\\'
+ ralt+shift: '|'
+}
+
+key SEMICOLON {
+ label: ';'
+ base: ';'
+ shift: ':'
+}
+
+key APOSTROPHE {
+ label: '\''
+ base: '\''
+ shift: '"'
+}
+
+### Non-printing keys ###
+
+key ESCAPE {
+ base: fallback BACK
+ alt, meta: fallback HOME
+ ctrl: fallback MENU
+}
diff --git a/data/keyboards/Vendor_18d1_Product_5018.kl b/data/keyboards/Vendor_18d1_Product_5018.kl
new file mode 100644
index 0000000..e95ccb5
--- /dev/null
+++ b/data/keyboards/Vendor_18d1_Product_5018.kl
@@ -0,0 +1,84 @@
+# Copyright (C) 2015 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+#
+# Key layout for Google Pixel C Keyboard
+#
+
+# Row 1
+key 2 1
+key 3 2
+key 4 3
+key 5 4
+key 6 5
+key 7 6
+key 8 7
+key 9 8
+key 10 9
+key 11 0
+key 12 MINUS
+key 14 DEL # Backspace
+
+# Row 2
+key 15 TAB
+key 16 Q
+key 17 W
+key 18 E
+key 19 R
+key 20 T
+key 21 Y
+key 22 U
+key 23 I
+key 24 O
+key 25 P
+key 13 EQUALS
+key 28 ENTER
+
+# Row 3
+key 125 META_LEFT # "Search key"
+key 30 A
+key 31 S
+key 32 D
+key 33 F
+key 34 G
+key 35 H
+key 36 J
+key 37 K
+key 38 L
+key 39 SEMICOLON
+key 40 APOSTROPHE
+
+# Row 4
+key 42 SHIFT_LEFT
+key 44 Z
+key 45 X
+key 46 C
+key 47 V
+key 48 B
+key 49 N
+key 50 M
+key 51 COMMA
+key 52 PERIOD
+key 53 SLASH
+key 54 SHIFT_RIGHT
+
+# Row 5
+key 29 CTRL_LEFT
+key 56 ALT_LEFT
+key 57 SPACE
+key 100 ALT_RIGHT
+key 103 DPAD_UP
+key 105 DPAD_LEFT
+key 106 DPAD_RIGHT
+key 108 DPAD_DOWN
diff --git a/docs/html/guide/topics/manifest/compatible-screens-element.jd b/docs/html/guide/topics/manifest/compatible-screens-element.jd
index 3606b15..de921d2 100644
--- a/docs/html/guide/topics/manifest/compatible-screens-element.jd
+++ b/docs/html/guide/topics/manifest/compatible-screens-element.jd
@@ -9,7 +9,7 @@
<pre>
<<a href="#compatible-screens">compatible-screens</a>>
<<a href="#screen">screen</a> android:<a href="#screenSize">screenSize</a>=["small" | "normal" | "large" | "xlarge"]
- android:<a href="#screenDensity">screenDensity</a>=["ldpi" | "mdpi" | "hdpi" | "xhdpi"] />
+ android:<a href="#screenDensity">screenDensity</a>=["ldpi" | "mdpi" | "hdpi" | "xhdpi" | "xxhdpi" | "xxxhdpi"] />
...
</compatible-screens>
</pre>
@@ -94,11 +94,9 @@
<li>{@code mdpi}</li>
<li>{@code hdpi}</li>
<li>{@code xhdpi}</li>
+ <li>{@code xxhdpi}</li>
+ <li>{@code xxxhdpi}</li>
</ul>
- <p class="note"><strong>Note:</strong> This attribute currently does not accept
- {@code xxhdpi} as a valid value, but you can instead specify {@code 480}
- as the value, which is the approximate threshold for xhdpi screens.</p>
-
<p>For information about the different screen densities, see <a
href="{@docRoot}guide/practices/screens_support.html#range">Supporting Multiple Screens</a>.</p>
</dd>
@@ -110,8 +108,8 @@
<dt>example</dt>
<dd>
<p>If your application is compatible with only small and normal screens, regardless
-of screen density, then you must specify eight different {@code <screen>} elements,
-because each screen size has four different density configurations. You must declare each one of
+of screen density, then you must specify twelve different {@code <screen>} elements,
+because each screen size has six different density configurations. You must declare each one of
these; any combination of size and density that you do <em>not</em> specify is considered a screen
configuration with which your application is <em>not</em> compatible. Here's what the manifest
entry looks like if your application is compatible with only small and normal screens:</p>
@@ -125,11 +123,15 @@
<screen android:screenSize="small" android:screenDensity="mdpi" />
<screen android:screenSize="small" android:screenDensity="hdpi" />
<screen android:screenSize="small" android:screenDensity="xhdpi" />
+ <screen android:screenSize="small" android:screenDensity="xxhdpi" />
+ <screen android:screenSize="small" android:screenDensity="xxxhdpi" />
<!-- all normal size screens -->
<screen android:screenSize="normal" android:screenDensity="ldpi" />
<screen android:screenSize="normal" android:screenDensity="mdpi" />
<screen android:screenSize="normal" android:screenDensity="hdpi" />
<screen android:screenSize="normal" android:screenDensity="xhdpi" />
+ <screen android:screenSize="normal" android:screenDensity="xxhdpi" />
+ <screen android:screenSize="normal" android:screenDensity="xxxhdpi" />
</compatible-screens>
<application ... >
...
diff --git a/graphics/java/android/graphics/drawable/Icon.java b/graphics/java/android/graphics/drawable/Icon.java
index 26232a9..d800acb 100644
--- a/graphics/java/android/graphics/drawable/Icon.java
+++ b/graphics/java/android/graphics/drawable/Icon.java
@@ -377,12 +377,17 @@
return loadDrawable(context);
}
+ /** @hide */
+ public static final int MIN_ASHMEM_ICON_SIZE = 128 * (1 << 10);
+
/**
* Puts the memory used by this instance into Ashmem memory, if possible.
* @hide
*/
public void convertToAshmem() {
- if (mType == TYPE_BITMAP && getBitmap().isMutable()) {
+ if (mType == TYPE_BITMAP &&
+ getBitmap().isMutable() &&
+ getBitmap().getAllocationByteCount() >= MIN_ASHMEM_ICON_SIZE) {
setBitmap(getBitmap().createAshmemBitmap());
}
}
diff --git a/graphics/java/android/graphics/drawable/RippleBackground.java b/graphics/java/android/graphics/drawable/RippleBackground.java
index 1c14e2f..c7aa8c3 100644
--- a/graphics/java/android/graphics/drawable/RippleBackground.java
+++ b/graphics/java/android/graphics/drawable/RippleBackground.java
@@ -48,8 +48,8 @@
// Software rendering properties.
private float mOpacity = 0;
- public RippleBackground(RippleDrawable owner, Rect bounds) {
- super(owner, bounds);
+ public RippleBackground(RippleDrawable owner, Rect bounds, boolean forceSoftware) {
+ super(owner, bounds, forceSoftware);
}
public boolean isVisible() {
diff --git a/graphics/java/android/graphics/drawable/RippleComponent.java b/graphics/java/android/graphics/drawable/RippleComponent.java
index 23a3ee3..2d378c6 100644
--- a/graphics/java/android/graphics/drawable/RippleComponent.java
+++ b/graphics/java/android/graphics/drawable/RippleComponent.java
@@ -52,9 +52,16 @@
/** Screen density used to adjust pixel-based constants. */
protected float mDensity;
- public RippleComponent(RippleDrawable owner, Rect bounds) {
+ /**
+ * If set, force all ripple animations to not run on RenderThread, even if it would be
+ * available.
+ */
+ private final boolean mForceSoftware;
+
+ public RippleComponent(RippleDrawable owner, Rect bounds, boolean forceSoftware) {
mOwner = owner;
mBounds = bounds;
+ mForceSoftware = forceSoftware;
}
public void onBoundsChange() {
@@ -143,7 +150,7 @@
* @return {@code true} if something was drawn, {@code false} otherwise
*/
public boolean draw(Canvas c, Paint p) {
- final boolean hasDisplayListCanvas = c.isHardwareAccelerated()
+ final boolean hasDisplayListCanvas = !mForceSoftware && c.isHardwareAccelerated()
&& c instanceof DisplayListCanvas;
if (mHasDisplayListCanvas != hasDisplayListCanvas) {
mHasDisplayListCanvas = hasDisplayListCanvas;
diff --git a/graphics/java/android/graphics/drawable/RippleDrawable.java b/graphics/java/android/graphics/drawable/RippleDrawable.java
index 464f3de..2690223 100644
--- a/graphics/java/android/graphics/drawable/RippleDrawable.java
+++ b/graphics/java/android/graphics/drawable/RippleDrawable.java
@@ -166,6 +166,12 @@
private boolean mOverrideBounds;
/**
+ * If set, force all ripple animations to not run on RenderThread, even if it would be
+ * available.
+ */
+ private boolean mForceSoftware;
+
+ /**
* Constructor used for drawable inflation.
*/
RippleDrawable() {
@@ -546,7 +552,7 @@
*/
private void tryBackgroundEnter(boolean focused) {
if (mBackground == null) {
- mBackground = new RippleBackground(this, mHotspotBounds);
+ mBackground = new RippleBackground(this, mHotspotBounds, mForceSoftware);
}
mBackground.setup(mState.mMaxRadius, mDensity);
@@ -584,7 +590,7 @@
}
final boolean isBounded = isBounded();
- mRipple = new RippleForeground(this, mHotspotBounds, x, y, isBounded);
+ mRipple = new RippleForeground(this, mHotspotBounds, x, y, isBounded, mForceSoftware);
}
mRipple.setup(mState.mMaxRadius, mDensity);
@@ -949,6 +955,16 @@
}
}
+ /**
+ * Sets whether to disable RenderThread animations for this ripple.
+ *
+ * @param forceSoftware true if RenderThread animations should be disabled, false otherwise
+ * @hide
+ */
+ public void setForceSoftware(boolean forceSoftware) {
+ mForceSoftware = forceSoftware;
+ }
+
@Override
public ConstantState getConstantState() {
return mState;
diff --git a/graphics/java/android/graphics/drawable/RippleForeground.java b/graphics/java/android/graphics/drawable/RippleForeground.java
index 4853b04..c660846 100644
--- a/graphics/java/android/graphics/drawable/RippleForeground.java
+++ b/graphics/java/android/graphics/drawable/RippleForeground.java
@@ -87,8 +87,8 @@
private boolean mHasFinishedExit;
public RippleForeground(RippleDrawable owner, Rect bounds, float startingX, float startingY,
- boolean isBounded) {
- super(owner, bounds);
+ boolean isBounded, boolean forceSoftware) {
+ super(owner, bounds, forceSoftware);
mIsBounded = isBounded;
mStartingX = startingX;
diff --git a/libs/hwui/RenderNode.cpp b/libs/hwui/RenderNode.cpp
index 0951fc1..642ec25 100644
--- a/libs/hwui/RenderNode.cpp
+++ b/libs/hwui/RenderNode.cpp
@@ -666,7 +666,9 @@
void RenderNode::issueDrawShadowOperation(const Matrix4& transformFromParent, T& handler) {
if (properties().getAlpha() <= 0.0f
|| properties().getOutline().getAlpha() <= 0.0f
- || !properties().getOutline().getPath()) {
+ || !properties().getOutline().getPath()
+ || properties().getScaleX() == 0
+ || properties().getScaleY() == 0) {
// no shadow to draw
return;
}
@@ -856,7 +858,10 @@
const bool useViewProperties = (!mLayer || drawLayer);
if (useViewProperties) {
const Outline& outline = properties().getOutline();
- if (properties().getAlpha() <= 0 || (outline.getShouldClip() && outline.isEmpty())) {
+ if (properties().getAlpha() <= 0
+ || (outline.getShouldClip() && outline.isEmpty())
+ || properties().getScaleX() == 0
+ || properties().getScaleY() == 0) {
DISPLAY_LIST_LOGD("%*sRejected display list (%p, %s)", handler.level() * 2, "",
this, getName());
return;
diff --git a/libs/hwui/ShadowTessellator.cpp b/libs/hwui/ShadowTessellator.cpp
index 09d1258..6c8665b 100644
--- a/libs/hwui/ShadowTessellator.cpp
+++ b/libs/hwui/ShadowTessellator.cpp
@@ -77,9 +77,14 @@
}
#if DEBUG_SHADOW
- ALOGD("light center %f %f %f",
- adjustedLightCenter.x, adjustedLightCenter.y, adjustedLightCenter.z);
+ ALOGD("light center %f %f %f %d",
+ adjustedLightCenter.x, adjustedLightCenter.y, adjustedLightCenter.z, lightRadius);
#endif
+ if (isnan(adjustedLightCenter.x)
+ || isnan(adjustedLightCenter.y)
+ || isnan(adjustedLightCenter.z)) {
+ return;
+ }
// light position (because it's in local space) needs to compensate for receiver transform
// TODO: should apply to light orientation, not just position
diff --git a/libs/hwui/SpotShadow.cpp b/libs/hwui/SpotShadow.cpp
index b8c9804..7a2b9af 100644
--- a/libs/hwui/SpotShadow.cpp
+++ b/libs/hwui/SpotShadow.cpp
@@ -1052,7 +1052,7 @@
*/
void SpotShadow::dumpPolygon(const Vector3* poly, int polyLength, const char* polyName) {
for (int i = 0; i < polyLength; i++) {
- ALOGD("polygon %s i %d x %f y %f", polyName, i, poly[i].x, poly[i].y);
+ ALOGD("polygon %s i %d x %f y %f z %f", polyName, i, poly[i].x, poly[i].y, poly[i].z);
}
}
diff --git a/libs/hwui/thread/TaskManager.cpp b/libs/hwui/thread/TaskManager.cpp
index f0ed0bb..e9dde29 100644
--- a/libs/hwui/thread/TaskManager.cpp
+++ b/libs/hwui/thread/TaskManager.cpp
@@ -33,7 +33,9 @@
// Get the number of available CPUs. This value does not change over time.
int cpuCount = sysconf(_SC_NPROCESSORS_CONF);
- int workerCount = MathUtils::max(1, cpuCount / 2);
+ // Really no point in making more than 2 of these worker threads, but
+ // we do want to limit ourselves to 1 worker thread on dual-core devices.
+ int workerCount = cpuCount > 2 ? 2 : 1;
for (int i = 0; i < workerCount; i++) {
String8 name;
name.appendFormat("hwuiTask%d", i + 1);
diff --git a/location/lib/java/com/android/location/provider/ActivityRecognitionProvider.java b/location/lib/java/com/android/location/provider/ActivityRecognitionProvider.java
index da33464..bc2dae1 100644
--- a/location/lib/java/com/android/location/provider/ActivityRecognitionProvider.java
+++ b/location/lib/java/com/android/location/provider/ActivityRecognitionProvider.java
@@ -31,8 +31,7 @@
*/
public final class ActivityRecognitionProvider {
private final IActivityRecognitionHardware mService;
- private final HashSet<Sink> mSinkSet = new HashSet<Sink>();
- private final SinkTransport mSinkTransport = new SinkTransport();
+ private final HashSet<Sink> mSinkSet = new HashSet<>();
// the following constants must remain in sync with activity_recognition.h
@@ -43,6 +42,8 @@
public static final String ACTIVITY_STILL = "android.activity_recognition.still";
public static final String ACTIVITY_TILTING = "android.activity_recognition.tilting";
+ // NOTE: when adding an additional EVENT_TYPE_, EVENT_TYPE_COUNT needs to be updated in
+ // android.hardware.location.ActivityRecognitionHardware
public static final int EVENT_TYPE_FLUSH_COMPLETE = 0;
public static final int EVENT_TYPE_ENTER = 1;
public static final int EVENT_TYPE_EXIT = 2;
@@ -60,7 +61,7 @@
throws RemoteException {
Preconditions.checkNotNull(service);
mService = service;
- mService.registerSink(mSinkTransport);
+ mService.registerSink(new SinkTransport());
}
public String[] getSupportedActivities() throws RemoteException {
@@ -102,26 +103,23 @@
private final class SinkTransport extends IActivityRecognitionHardwareSink.Stub {
@Override
- public void onActivityChanged(
- android.hardware.location.ActivityChangedEvent activityChangedEvent) {
+ public void onActivityChanged(android.hardware.location.ActivityChangedEvent event) {
Collection<Sink> sinks;
synchronized (mSinkSet) {
if (mSinkSet.isEmpty()) {
return;
}
-
- sinks = new ArrayList<Sink>(mSinkSet);
+ sinks = new ArrayList<>(mSinkSet);
}
// translate the event from platform internal and GmsCore types
- ArrayList<ActivityRecognitionEvent> gmsEvents =
- new ArrayList<ActivityRecognitionEvent>();
- for (android.hardware.location.ActivityRecognitionEvent event
- : activityChangedEvent.getActivityRecognitionEvents()) {
+ ArrayList<ActivityRecognitionEvent> gmsEvents = new ArrayList<>();
+ for (android.hardware.location.ActivityRecognitionEvent reportingEvent
+ : event.getActivityRecognitionEvents()) {
ActivityRecognitionEvent gmsEvent = new ActivityRecognitionEvent(
- event.getActivity(),
- event.getEventType(),
- event.getTimestampNs());
+ reportingEvent.getActivity(),
+ reportingEvent.getEventType(),
+ reportingEvent.getTimestampNs());
gmsEvents.add(gmsEvent);
}
ActivityChangedEvent gmsEvent = new ActivityChangedEvent(gmsEvents);
diff --git a/location/lib/java/com/android/location/provider/ActivityRecognitionProviderClient.java b/location/lib/java/com/android/location/provider/ActivityRecognitionProviderClient.java
new file mode 100644
index 0000000..0b878d7
--- /dev/null
+++ b/location/lib/java/com/android/location/provider/ActivityRecognitionProviderClient.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.location.provider;
+
+import android.annotation.NonNull;
+import android.hardware.location.IActivityRecognitionHardware;
+import android.hardware.location.IActivityRecognitionHardwareClient;
+import android.os.Binder;
+import android.os.IBinder;
+import android.os.Process;
+import android.os.RemoteException;
+import android.util.Log;
+
+/**
+ * A client class for interaction with an Activity-Recognition provider.
+ */
+public abstract class ActivityRecognitionProviderClient {
+ private static final String TAG = "ArProviderClient";
+
+ protected ActivityRecognitionProviderClient() {}
+
+ private IActivityRecognitionHardwareClient.Stub mClient =
+ new IActivityRecognitionHardwareClient.Stub() {
+ @Override
+ public void onAvailabilityChanged(
+ boolean isSupported,
+ IActivityRecognitionHardware instance) {
+ int callingUid = Binder.getCallingUid();
+ if (callingUid != Process.SYSTEM_UID) {
+ Log.d(TAG, "Ignoring calls from non-system server. Uid: " + callingUid);
+ return;
+ }
+ ActivityRecognitionProvider provider;
+ try {
+ provider = isSupported ? new ActivityRecognitionProvider(instance) : null;
+ } catch (RemoteException e) {
+ Log.e(TAG, "Error creating Hardware Activity-Recognition Provider.", e);
+ return;
+ }
+ onProviderChanged(isSupported, provider);
+ }
+ };
+
+ /**
+ * Gets the binder needed to interact with proxy provider in the platform.
+ */
+ @NonNull
+ public IBinder getBinder() {
+ return mClient;
+ }
+
+ /**
+ * Called when a change in the availability of {@link ActivityRecognitionProvider} is detected.
+ *
+ * @param isSupported whether the platform supports the provider natively
+ * @param instance the available provider's instance
+ */
+ public abstract void onProviderChanged(
+ boolean isSupported,
+ ActivityRecognitionProvider instance);
+}
diff --git a/location/lib/java/com/android/location/provider/ActivityRecognitionProviderWatcher.java b/location/lib/java/com/android/location/provider/ActivityRecognitionProviderWatcher.java
index 03dd042..7139025 100644
--- a/location/lib/java/com/android/location/provider/ActivityRecognitionProviderWatcher.java
+++ b/location/lib/java/com/android/location/provider/ActivityRecognitionProviderWatcher.java
@@ -28,7 +28,10 @@
/**
* A watcher class for Activity-Recognition instances.
+ *
+ * @deprecated use {@link ActivityRecognitionProviderClient} instead.
*/
+@Deprecated
public class ActivityRecognitionProviderWatcher {
private static final String TAG = "ActivityRecognitionProviderWatcher";
diff --git a/media/java/android/media/MediaActionSound.java b/media/java/android/media/MediaActionSound.java
index 2f4d136..1fee587 100644
--- a/media/java/android/media/MediaActionSound.java
+++ b/media/java/android/media/MediaActionSound.java
@@ -52,7 +52,7 @@
"/system/media/audio/ui/camera_click.ogg",
"/system/media/audio/ui/camera_focus.ogg",
"/system/media/audio/ui/VideoRecord.ogg",
- "/system/media/audio/ui/VideoRecord.ogg"
+ "/system/media/audio/ui/VideoStop.ogg"
};
private static final String TAG = "MediaActionSound";
diff --git a/media/java/android/media/MediaPlayer.java b/media/java/android/media/MediaPlayer.java
index 13b2878..587d494 100644
--- a/media/java/android/media/MediaPlayer.java
+++ b/media/java/android/media/MediaPlayer.java
@@ -479,11 +479,6 @@
* <td>{} </p></td>
* <td>This method can be called in any state and calling it does not change
* the object state. </p></td></tr>
- * <tr><td>setPlaybackRate</p></td>
- * <td>any </p></td>
- * <td>{} </p></td>
- * <td>This method can be called in any state and calling it does not change
- * the object state. </p></td></tr>
* <tr><td>setPlaybackParams</p></td>
* <td>any </p></td>
* <td>{} </p></td>
@@ -2243,10 +2238,14 @@
final InputStream fIs = is;
final MediaFormat fFormat = format;
- // Ensure all input streams are closed. It is also a handy
- // way to implement timeouts in the future.
- synchronized(mOpenSubtitleSources) {
- mOpenSubtitleSources.add(is);
+ if (is != null) {
+ // Ensure all input streams are closed. It is also a handy
+ // way to implement timeouts in the future.
+ synchronized(mOpenSubtitleSources) {
+ mOpenSubtitleSources.add(is);
+ }
+ } else {
+ Log.w(TAG, "addSubtitleSource called with null InputStream");
}
// process each subtitle in its own thread
diff --git a/media/java/android/media/midi/IBluetoothMidiService.aidl b/media/java/android/media/midi/IBluetoothMidiService.aidl
new file mode 100644
index 0000000..fe5566d
--- /dev/null
+++ b/media/java/android/media/midi/IBluetoothMidiService.aidl
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.media.midi;
+
+import android.bluetooth.BluetoothDevice;
+import android.os.IBinder;
+
+/** @hide */
+interface IBluetoothMidiService
+{
+ IBinder addBluetoothDevice(in BluetoothDevice bluetoothDevice);
+}
diff --git a/media/java/android/media/midi/MidiManager.java b/media/java/android/media/midi/MidiManager.java
index 7197dc0..266b0d9 100644
--- a/media/java/android/media/midi/MidiManager.java
+++ b/media/java/android/media/midi/MidiManager.java
@@ -169,6 +169,13 @@
/**
* Registers a callback to receive notifications when MIDI devices are added and removed.
*
+ * The {@link DeviceCallback#onDeviceStatusChanged} method will be called immediately
+ * for any devices that have open ports. This allows applications to know which input
+ * ports are already in use and, therefore, unavailable.
+ *
+ * Applications should call {@link #getDevices} before registering the callback
+ * to get a list of devices already added.
+ *
* @param callback a {@link DeviceCallback} for MIDI device notifications
* @param handler The {@link android.os.Handler Handler} that will be used for delivering the
* device notifications. If handler is null, then the thread used for the
@@ -288,7 +295,6 @@
// fetch MidiDeviceInfo from the server
MidiDeviceInfo deviceInfo = server.getDeviceInfo();
device = new MidiDevice(deviceInfo, server, mService, mToken, deviceToken);
- sendOpenDeviceResponse(device, listenerF, handlerF);
} catch (RemoteException e) {
Log.e(TAG, "remote exception in getDeviceInfo()");
}
diff --git a/media/packages/BluetoothMidiService/Android.mk b/media/packages/BluetoothMidiService/Android.mk
index 2c9c3c5..0565925 100644
--- a/media/packages/BluetoothMidiService/Android.mk
+++ b/media/packages/BluetoothMidiService/Android.mk
@@ -3,7 +3,8 @@
LOCAL_MODULE_TAGS := optional
-LOCAL_SRC_FILES := $(call all-subdir-java-files)
+LOCAL_SRC_FILES += \
+ $(call all-java-files-under,src)
LOCAL_PACKAGE_NAME := BluetoothMidiService
LOCAL_CERTIFICATE := platform
diff --git a/media/packages/BluetoothMidiService/AndroidManifest.xml b/media/packages/BluetoothMidiService/AndroidManifest.xml
index b0b389a..1cfd55d 100644
--- a/media/packages/BluetoothMidiService/AndroidManifest.xml
+++ b/media/packages/BluetoothMidiService/AndroidManifest.xml
@@ -8,7 +8,7 @@
<application
android:label="@string/app_name">
- <service android:name="BluetoothMidiService"
+ <service android:name=".BluetoothMidiService"
android:permission="android.permission.BIND_MIDI_DEVICE_SERVICE">
<intent-filter>
<action android:name="android.media.midi.BluetoothMidiService" />
diff --git a/media/packages/BluetoothMidiService/src/com/android/bluetoothmidiservice/BluetoothMidiDevice.java b/media/packages/BluetoothMidiService/src/com/android/bluetoothmidiservice/BluetoothMidiDevice.java
index e6d59e4..444705c 100644
--- a/media/packages/BluetoothMidiService/src/com/android/bluetoothmidiservice/BluetoothMidiDevice.java
+++ b/media/packages/BluetoothMidiService/src/com/android/bluetoothmidiservice/BluetoothMidiDevice.java
@@ -147,14 +147,22 @@
// switch to receiving notifications after initial characteristic read
mBluetoothGatt.setCharacteristicNotification(characteristic, true);
+ // Use writeType that requests acknowledgement.
+ // This improves compatibility with various BLE-MIDI devices.
+ int originalWriteType = characteristic.getWriteType();
+ characteristic.setWriteType(BluetoothGattCharacteristic.WRITE_TYPE_DEFAULT);
+
BluetoothGattDescriptor descriptor = characteristic.getDescriptor(
CLIENT_CHARACTERISTIC_CONFIG);
if (descriptor != null) {
descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
- mBluetoothGatt.writeDescriptor(descriptor);
+ boolean result = mBluetoothGatt.writeDescriptor(descriptor);
+ Log.d(TAG, "writeDescriptor returned " + result);
} else {
Log.e(TAG, "No CLIENT_CHARACTERISTIC_CONFIG for device " + mBluetoothDevice);
}
+
+ characteristic.setWriteType(originalWriteType);
}
@Override
diff --git a/media/packages/BluetoothMidiService/src/com/android/bluetoothmidiservice/BluetoothMidiService.java b/media/packages/BluetoothMidiService/src/com/android/bluetoothmidiservice/BluetoothMidiService.java
index fbde2b4..5541f9f 100644
--- a/media/packages/BluetoothMidiService/src/com/android/bluetoothmidiservice/BluetoothMidiService.java
+++ b/media/packages/BluetoothMidiService/src/com/android/bluetoothmidiservice/BluetoothMidiService.java
@@ -19,6 +19,7 @@
import android.app.Service;
import android.bluetooth.BluetoothDevice;
import android.content.Intent;
+import android.media.midi.IBluetoothMidiService;
import android.media.midi.MidiManager;
import android.os.IBinder;
import android.util.Log;
@@ -34,24 +35,31 @@
@Override
public IBinder onBind(Intent intent) {
- if (MidiManager.BLUETOOTH_MIDI_SERVICE_INTENT.equals(intent.getAction())) {
- BluetoothDevice bluetoothDevice = (BluetoothDevice)intent.getParcelableExtra("device");
+ // Return the interface
+ return mBinder;
+ }
+
+
+ private final IBluetoothMidiService.Stub mBinder = new IBluetoothMidiService.Stub() {
+
+ public IBinder addBluetoothDevice(BluetoothDevice bluetoothDevice) {
+ BluetoothMidiDevice device;
if (bluetoothDevice == null) {
- Log.e(TAG, "no BluetoothDevice in onBind intent");
+ Log.e(TAG, "no BluetoothDevice in addBluetoothDevice()");
return null;
}
-
- BluetoothMidiDevice device;
synchronized (mDeviceServerMap) {
device = mDeviceServerMap.get(bluetoothDevice);
if (device == null) {
- device = new BluetoothMidiDevice(this, bluetoothDevice, this);
+ device = new BluetoothMidiDevice(BluetoothMidiService.this,
+ bluetoothDevice, BluetoothMidiService.this);
+ mDeviceServerMap.put(bluetoothDevice, device);
}
}
return device.getBinder();
}
- return null;
- }
+
+ };
void deviceClosed(BluetoothDevice device) {
synchronized (mDeviceServerMap) {
diff --git a/native/android/sensor.cpp b/native/android/sensor.cpp
index 26b41e8..76c701a 100644
--- a/native/android/sensor.cpp
+++ b/native/android/sensor.cpp
@@ -38,10 +38,6 @@
using android::String16;
/*****************************************************************************/
-
-android::Mutex android::SensorManager::sLock;
-std::map<String16, SensorManager*> android::SensorManager::sPackageInstances;
-
ASensorManager* ASensorManager_getInstance()
{
return ASensorManager_getInstanceForPackage(NULL);
@@ -206,4 +202,4 @@
bool ASensor_isWakeUpSensor(ASensor const* sensor)
{
return static_cast<Sensor const*>(sensor)->isWakeUpSensor();
-}
\ No newline at end of file
+}
diff --git a/packages/BackupRestoreConfirmation/res/values-fa/strings.xml b/packages/BackupRestoreConfirmation/res/values-fa/strings.xml
index 96ef731..d8155a6 100644
--- a/packages/BackupRestoreConfirmation/res/values-fa/strings.xml
+++ b/packages/BackupRestoreConfirmation/res/values-fa/strings.xml
@@ -29,7 +29,7 @@
<string name="device_encryption_backup_text" msgid="5866590762672844664">"لطفاً گذرواژه رمزگذاری دستگاه خود را در زیر وارد کنید. این برای رمزگذاری بایگانی پشتیبان نیز مورد استفاده قرار میگیرد."</string>
<string name="backup_enc_password_text" msgid="4981585714795233099">"لطفاً یک گذرواژه برای رمزگذاری دادههای کامل نسخهٔ پشتیبانی وارد کنید. اگر این خالی بماند، گذرواژه فعلی نسخهٔ پشتیبان مورد استفاده قرار خواهد گرفت:"</string>
<string name="backup_enc_password_optional" msgid="1350137345907579306">"اگر میخواهید تمام نسخه پشتیبانی داده را رمزدار کنید، یک گذرواژه در زیر وارد کنید:"</string>
- <string name="backup_enc_password_required" msgid="7889652203371654149">"چون دستگاهتان رمزگذاری شده است، باید نسخه پشتیبان خودتان را رمزگذاری کنید. لطفاً گذرواژهای را در زیر وارد کنید:"</string>
+ <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>
diff --git a/packages/BackupRestoreConfirmation/res/values-it/strings.xml b/packages/BackupRestoreConfirmation/res/values-it/strings.xml
index 2325d40..b84edbc 100644
--- a/packages/BackupRestoreConfirmation/res/values-it/strings.xml
+++ b/packages/BackupRestoreConfirmation/res/values-it/strings.xml
@@ -29,7 +29,7 @@
<string name="device_encryption_backup_text" msgid="5866590762672844664">"Inserisci la tua password di crittografia dispositivo di seguito. Verrà utilizzata anche per crittografare l\'archivio di backup."</string>
<string name="backup_enc_password_text" msgid="4981585714795233099">"Inserisci una password da utilizzare per la crittografia dei dati di backup completi. Se non ne inserisci una, verrà utilizzata la tua password di backup corrente:"</string>
<string name="backup_enc_password_optional" msgid="1350137345907579306">"Se desideri crittografare tutti i dati di backup, inserisci una password qui di seguito:"</string>
- <string name="backup_enc_password_required" msgid="7889652203371654149">"Il dispositivo è crittografato, pertanto devi crittografare il backup. Inserisci una password di seguito:"</string>
+ <string name="backup_enc_password_required" msgid="7889652203371654149">"Il dispositivo è criptato, quindi devi criptare il backup. Inserisci una password di seguito:"</string>
<string name="restore_enc_password_text" msgid="6140898525580710823">"Se i dati di ripristino sono crittografati, inserisci la password qui di seguito:"</string>
<string name="toast_backup_started" msgid="550354281452756121">"Avvio del backup..."</string>
<string name="toast_backup_ended" msgid="3818080769548726424">"Backup terminato"</string>
diff --git a/packages/BackupRestoreConfirmation/res/values-nl/strings.xml b/packages/BackupRestoreConfirmation/res/values-nl/strings.xml
index f483b14..81f2712 100644
--- a/packages/BackupRestoreConfirmation/res/values-nl/strings.xml
+++ b/packages/BackupRestoreConfirmation/res/values-nl/strings.xml
@@ -18,18 +18,18 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="backup_confirm_title" msgid="827563724209303345">"Volledige back-up"</string>
<string name="restore_confirm_title" msgid="5469365809567486602">"Volledig herstel"</string>
- <string name="backup_confirm_text" msgid="1878021282758896593">"Er is een volledige back-up van alle gegevens naar een verbonden desktopcomputer aangevraagd. Wilt u dit toestaan?\n\nAls u de back-up zelf niet heeft aangevraagd, moet u niet toestaan dat de bewerking wordt uitgevoerd."</string>
+ <string name="backup_confirm_text" msgid="1878021282758896593">"Er is een volledige back-up van alle gegevens naar een verbonden desktopcomputer aangevraagd. Wil je dit toestaan?\n\nAls je de back-up niet zelf hebt aangevraagd, moet je niet toestaan dat de bewerking wordt uitgevoerd."</string>
<string name="allow_backup_button_label" msgid="4217228747769644068">"Back-up maken van mijn gegevens"</string>
<string name="deny_backup_button_label" msgid="6009119115581097708">"Geen back-up maken"</string>
- <string name="restore_confirm_text" msgid="7499866728030461776">"Er is volledig herstel van alle gegevens van een verbonden desktopcomputer aangevraagd. Wilt u dit toestaan?\n\nAls u het herstel zelf niet heeft aangevraagd, moet u niet toestaan dat de bewerking wordt uitgevoerd. Bij herstel worden alle gegevens op het apparaat vervangen."</string>
+ <string name="restore_confirm_text" msgid="7499866728030461776">"Er is volledig herstel van alle gegevens van een verbonden desktopcomputer aangevraagd. Wil je dit toestaan?\n\nAls je het herstel niet zelf hebt aangevraagd, moet je niet toestaan dat de bewerking wordt uitgevoerd. Bij herstel worden alle gegevens op het apparaat vervangen."</string>
<string name="allow_restore_button_label" msgid="3081286752277127827">"Mijn gegevens herstellen"</string>
<string name="deny_restore_button_label" msgid="1724367334453104378">"Niet herstellen"</string>
- <string name="current_password_text" msgid="8268189555578298067">"Geef hieronder uw huidige back-upwachtwoord op:"</string>
- <string name="device_encryption_restore_text" msgid="1570864916855208992">"Geef hieronder uw wachtwoord voor apparaatcodering op."</string>
- <string name="device_encryption_backup_text" msgid="5866590762672844664">"Geef hieronder uw wachtwoord voor apparaatversleuteling op. Dit wordt ook gebruikt om het back-uparchief te versleutelen."</string>
- <string name="backup_enc_password_text" msgid="4981585714795233099">"Geef een wachtwoord op dat u wilt gebruiken voor het coderen van de gegevens van de volledige back-up. Als u dit leeg laat, wordt uw huidige back-upwachtwoord gebruikt:"</string>
+ <string name="current_password_text" msgid="8268189555578298067">"Geef hieronder je huidige back-upwachtwoord op:"</string>
+ <string name="device_encryption_restore_text" msgid="1570864916855208992">"Geef hieronder je wachtwoord voor apparaatcodering op."</string>
+ <string name="device_encryption_backup_text" msgid="5866590762672844664">"Geef hieronder je wachtwoord voor apparaatversleuteling op. Dit wordt ook gebruikt om het back-uparchief te versleutelen."</string>
+ <string name="backup_enc_password_text" msgid="4981585714795233099">"Geef een wachtwoord op dat u wilt gebruiken voor het coderen van de gegevens van de volledige back-up. Als u dit leeg laat, wordt je huidige back-upwachtwoord gebruikt:"</string>
<string name="backup_enc_password_optional" msgid="1350137345907579306">"Als u de gegevens van de volledige back-up wilt versleutelen, geeft u daarvoor hieronder een wachtwoord op:"</string>
- <string name="backup_enc_password_required" msgid="7889652203371654149">"Aangezien uw apparaat is gecodeerd, moet u uw back-up coderen. Geef hieronder een wachtwoord op:"</string>
+ <string name="backup_enc_password_required" msgid="7889652203371654149">"Aangezien je apparaat is gecodeerd, moet u je back-up coderen. Geef hieronder een wachtwoord op:"</string>
<string name="restore_enc_password_text" msgid="6140898525580710823">"Als deze herstelgegevens zijn gecodeerd, geeft u hieronder het wachtwoord op:"</string>
<string name="toast_backup_started" msgid="550354281452756121">"Back-up starten..."</string>
<string name="toast_backup_ended" msgid="3818080769548726424">"Back-up voltooid"</string>
diff --git a/packages/BackupRestoreConfirmation/res/values-pt-rBR/strings.xml b/packages/BackupRestoreConfirmation/res/values-pt-rBR/strings.xml
new file mode 100644
index 0000000..cbc579e
--- /dev/null
+++ b/packages/BackupRestoreConfirmation/res/values-pt-rBR/strings.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2011 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="backup_confirm_title" msgid="827563724209303345">"Backup completo"</string>
+ <string name="restore_confirm_title" msgid="5469365809567486602">"Restauração completa"</string>
+ <string name="backup_confirm_text" msgid="1878021282758896593">"Foi solicitado um backup completo de todos os dados para um computador conectado. Deseja permitir que isso aconteça?\n\nCaso você não tenha solicitado o backup, não permita que a operação prossiga."</string>
+ <string name="allow_backup_button_label" msgid="4217228747769644068">"Fazer backup de meus dados"</string>
+ <string name="deny_backup_button_label" msgid="6009119115581097708">"Não fazer backup"</string>
+ <string name="restore_confirm_text" msgid="7499866728030461776">"Foi solicitada uma restauração completa de todos os dados de um computador conectado. Deseja permitir que isso ocorra?\n\nCaso você não tenha solicitado a restauração, não permita que a operação prossiga. Isso substituirá todos os dados existentes no dispositivo!"</string>
+ <string name="allow_restore_button_label" msgid="3081286752277127827">"Restaurar meus dados"</string>
+ <string name="deny_restore_button_label" msgid="1724367334453104378">"Não restaurar"</string>
+ <string name="current_password_text" msgid="8268189555578298067">"Digite sua senha de backup atual abaixo:"</string>
+ <string name="device_encryption_restore_text" msgid="1570864916855208992">"Insira sua senha de criptografia do dispositivo abaixo."</string>
+ <string name="device_encryption_backup_text" msgid="5866590762672844664">"Insira sua senha de criptografia do dispositivo abaixo. Ela também será usada para criptografar o arquivo de backup."</string>
+ <string name="backup_enc_password_text" msgid="4981585714795233099">"Digite uma senha para usar para criptografar os dados de backup por completo. Se isso for deixado em branco, sua senha atual de backup será usada:"</string>
+ <string name="backup_enc_password_optional" msgid="1350137345907579306">"Se você deseja criptografar os dados de backup por completo, digite uma senha abaixo:"</string>
+ <string name="backup_enc_password_required" msgid="7889652203371654149">"Como seu dispositivo está criptografado, é necessário criptografar seu backup. Insira uma senha abaixo:"</string>
+ <string name="restore_enc_password_text" msgid="6140898525580710823">"Se os dados restaurados forem criptografada, digite a senha abaixo:"</string>
+ <string name="toast_backup_started" msgid="550354281452756121">"Iniciando backup..."</string>
+ <string name="toast_backup_ended" msgid="3818080769548726424">"O backup foi concluído"</string>
+ <string name="toast_restore_started" msgid="7881679218971277385">"Iniciando restauração..."</string>
+ <string name="toast_restore_ended" msgid="1764041639199696132">"A restauração foi concluída"</string>
+ <string name="toast_timeout" msgid="5276598587087626877">"A operação atingiu o tempo limite"</string>
+</resources>
diff --git a/packages/BackupRestoreConfirmation/res/values-ro/strings.xml b/packages/BackupRestoreConfirmation/res/values-ro/strings.xml
index 1cf438b..6a7dbbd 100644
--- a/packages/BackupRestoreConfirmation/res/values-ro/strings.xml
+++ b/packages/BackupRestoreConfirmation/res/values-ro/strings.xml
@@ -18,17 +18,17 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="backup_confirm_title" msgid="827563724209303345">"Copiere de rezervă completă"</string>
<string name="restore_confirm_title" msgid="5469365809567486602">"Restabilire completă"</string>
- <string name="backup_confirm_text" msgid="1878021282758896593">"S-a solicitat crearea unei copii de rezervă complete a tuturor datelor pe un computer desktop conectat. Doriţi să permiteţi acest lucru?\n\nDacă nu aţi solicitat dvs. copierea de rezervă, nu permiteţi ca operaţiunea să continue."</string>
+ <string name="backup_confirm_text" msgid="1878021282758896593">"S-a solicitat crearea unei copii de rezervă complete a tuturor datelor pe un computer desktop conectat. Doriți să permiteți acest lucru?\n\nDacă nu aţi solicitat dvs. copierea de rezervă, nu permiteți ca operațiunea să continue."</string>
<string name="allow_backup_button_label" msgid="4217228747769644068">"Creaţi copii de rezervă pentru datele dvs."</string>
<string name="deny_backup_button_label" msgid="6009119115581097708">"Nu creaţi copii de rezervă"</string>
- <string name="restore_confirm_text" msgid="7499866728030461776">"S-a solicitat o restabilire completă a tuturor datelor de pe un computer desktop conectat. Doriţi să permiteţi acest lucru?\n\nDacă nu dvs. aţi solicitat această restabilire, nu permiteţi continuarea operaţiunii. Acest proces va înlocui toate datele existente în prezent pe dispozitiv!"</string>
+ <string name="restore_confirm_text" msgid="7499866728030461776">"S-a solicitat o restabilire completă a tuturor datelor de pe un computer desktop conectat. Doriți să permiteți acest lucru?\n\nDacă nu dvs. aţi solicitat această restabilire, nu permiteți continuarea operațiunii. Acest proces va înlocui toate datele existente în prezent pe dispozitiv!"</string>
<string name="allow_restore_button_label" msgid="3081286752277127827">"Restabiliţi datele dvs."</string>
<string name="deny_restore_button_label" msgid="1724367334453104378">"Nu restabiliţi"</string>
<string name="current_password_text" msgid="8268189555578298067">"Introduceţi mai jos parola actuală pentru copia de rezervă:"</string>
<string name="device_encryption_restore_text" msgid="1570864916855208992">"Introduceţi mai jos parola pentru criptarea dispozitivului."</string>
<string name="device_encryption_backup_text" msgid="5866590762672844664">"Introduceţi mai jos parola de criptare a dispozitivului. Aceasta va fi utilizată, de asemenea, pentru a cripta arhiva copiei de rezervă."</string>
<string name="backup_enc_password_text" msgid="4981585714795233099">"Introduceţi o parolă pentru a o utiliza la criptarea datelor copiei de rezervă complete. Dacă acest câmp rămâne necompletat, pentru copierea de rezervă se va utiliza parola dvs. actuală."</string>
- <string name="backup_enc_password_optional" msgid="1350137345907579306">"Dacă doriţi să criptaţi datele copiei de rezervă complete, introduceţi o parolă mai jos:"</string>
+ <string name="backup_enc_password_optional" msgid="1350137345907579306">"Dacă doriți să criptaţi datele copiei de rezervă complete, introduceţi o parolă mai jos:"</string>
<string name="backup_enc_password_required" msgid="7889652203371654149">"Întrucât dispozitivul este criptat, trebuie să criptați backupurile. Introduceți o parolă mai jos:"</string>
<string name="restore_enc_password_text" msgid="6140898525580710823">"Dacă datele pentru restabilire sunt criptate, introduceţi parola mai jos:"</string>
<string name="toast_backup_started" msgid="550354281452756121">"Se începe copierea de rezervă..."</string>
diff --git a/packages/CaptivePortalLogin/res/values-pt-rBR/strings.xml b/packages/CaptivePortalLogin/res/values-pt-rBR/strings.xml
new file mode 100644
index 0000000..e1d420f
--- /dev/null
+++ b/packages/CaptivePortalLogin/res/values-pt-rBR/strings.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
+ <string name="action_use_network" msgid="6076184727448466030">"Usar esta rede como está"</string>
+ <string name="action_do_not_use_network" msgid="4577366536956516683">"Não usar esta rede"</string>
+ <string name="action_bar_label" msgid="917235635415966620">"Fazer login na rede"</string>
+ <string name="ssl_error_warning" msgid="6653188881418638872">"A rede à qual você está tentando se conectar tem problemas de segurança."</string>
+ <string name="ssl_error_example" msgid="647898534624078900">"Por exemplo, a página de login pode não pertencer à organização mostrada."</string>
+ <string name="ssl_error_continue" msgid="6492718244923937110">"Continuar mesmo assim pelo navegador"</string>
+</resources>
diff --git a/packages/DefaultContainerService/res/values-pt-rBR/strings.xml b/packages/DefaultContainerService/res/values-pt-rBR/strings.xml
new file mode 100644
index 0000000..5fbd949
--- /dev/null
+++ b/packages/DefaultContainerService/res/values-pt-rBR/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/*
+**
+** Copyright 2008, 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.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="service_name" msgid="4841491635055379553">"Assistente de pacote"</string>
+</resources>
diff --git a/packages/DocumentsUI/AndroidManifest.xml b/packages/DocumentsUI/AndroidManifest.xml
index 382b2d0..ff14f94 100644
--- a/packages/DocumentsUI/AndroidManifest.xml
+++ b/packages/DocumentsUI/AndroidManifest.xml
@@ -3,6 +3,7 @@
<uses-permission android:name="android.permission.MANAGE_DOCUMENTS" />
<uses-permission android:name="android.permission.REMOVE_TASKS" />
+ <uses-permission android:name="android.permission.WAKE_LOCK" />
<application
android:name=".DocumentsApplication"
diff --git a/packages/DocumentsUI/res/values-fa/strings.xml b/packages/DocumentsUI/res/values-fa/strings.xml
index b414b07..ac3ccab 100644
--- a/packages/DocumentsUI/res/values-fa/strings.xml
+++ b/packages/DocumentsUI/res/values-fa/strings.xml
@@ -21,8 +21,8 @@
<string name="title_save" msgid="2433679664882857999">"ذخیره در"</string>
<string name="menu_create_dir" msgid="5947289605844398389">"ایجاد پوشه"</string>
<string name="menu_grid" msgid="6878021334497835259">"نمای جدولی"</string>
- <string name="menu_list" msgid="7279285939892417279">"نمای فهرستوار"</string>
- <string name="menu_sort" msgid="7677740407158414452">"مرتبسازی بر اساس"</string>
+ <string name="menu_list" msgid="7279285939892417279">"نمای فهرستی"</string>
+ <string name="menu_sort" msgid="7677740407158414452">"مرتبسازی براساس"</string>
<string name="menu_search" msgid="3816712084502856974">"جستجو"</string>
<string name="menu_settings" msgid="6008033148948428823">"تنظیمات"</string>
<string name="menu_open" msgid="432922957274920903">"باز کردن"</string>
@@ -39,9 +39,9 @@
<string name="menu_file_size_hide" msgid="8881975928502581042">"پنهان کردن اندازه فایل"</string>
<string name="button_select" msgid="527196987259139214">"انتخاب"</string>
<string name="button_copy" msgid="8706475544635021302">"کپی"</string>
- <string name="sort_name" msgid="9183560467917256779">"بر اساس نام"</string>
- <string name="sort_date" msgid="586080032956151448">"بر اساس تاریخ اصلاح"</string>
- <string name="sort_size" msgid="3350681319735474741">"بر اساس اندازه"</string>
+ <string name="sort_name" msgid="9183560467917256779">"براساس نام"</string>
+ <string name="sort_date" msgid="586080032956151448">"براساس تاریخ اصلاح"</string>
+ <string name="sort_size" msgid="3350681319735474741">"براساس اندازه"</string>
<string name="drawer_open" msgid="4545466532430226949">"نمایش ریشهها"</string>
<string name="drawer_close" msgid="7602734368552123318">"پنهان کردن ریشهها"</string>
<string name="save_error" msgid="6167009778003223664">"ذخیره سند انجام نشد"</string>
diff --git a/packages/DocumentsUI/res/values-hy-rAM/strings.xml b/packages/DocumentsUI/res/values-hy-rAM/strings.xml
index eb49b1d..4e6a096 100644
--- a/packages/DocumentsUI/res/values-hy-rAM/strings.xml
+++ b/packages/DocumentsUI/res/values-hy-rAM/strings.xml
@@ -20,7 +20,7 @@
<string name="title_open" msgid="4353228937663917801">"Բացել այստեղից"</string>
<string name="title_save" msgid="2433679664882857999">"Պահել այստեղ"</string>
<string name="menu_create_dir" msgid="5947289605844398389">"Ստեղծել պանակ"</string>
- <string name="menu_grid" msgid="6878021334497835259">"Ցանցի տեսք"</string>
+ <string name="menu_grid" msgid="6878021334497835259">"Ցանցի տեսքով"</string>
<string name="menu_list" msgid="7279285939892417279">"Ցուցակի տեսք"</string>
<string name="menu_sort" msgid="7677740407158414452">"Դասավորել ըստ"</string>
<string name="menu_search" msgid="3816712084502856974">"Որոնել"</string>
diff --git a/packages/DocumentsUI/res/values-pt-rBR/strings.xml b/packages/DocumentsUI/res/values-pt-rBR/strings.xml
new file mode 100644
index 0000000..5e96100
--- /dev/null
+++ b/packages/DocumentsUI/res/values-pt-rBR/strings.xml
@@ -0,0 +1,74 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2013 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_label" msgid="2783841764617238354">"Documentos"</string>
+ <string name="title_open" msgid="4353228937663917801">"Abrir de"</string>
+ <string name="title_save" msgid="2433679664882857999">"Salvar em"</string>
+ <string name="menu_create_dir" msgid="5947289605844398389">"Criar pasta"</string>
+ <string name="menu_grid" msgid="6878021334497835259">"Visualização em grade"</string>
+ <string name="menu_list" msgid="7279285939892417279">"Visualização em lista"</string>
+ <string name="menu_sort" msgid="7677740407158414452">"Classificar por"</string>
+ <string name="menu_search" msgid="3816712084502856974">"Pesquisar"</string>
+ <string name="menu_settings" msgid="6008033148948428823">"Configurações"</string>
+ <string name="menu_open" msgid="432922957274920903">"Abrir"</string>
+ <string name="menu_save" msgid="2394743337684426338">"Salvar"</string>
+ <string name="menu_share" msgid="3075149983979628146">"Compartilhar"</string>
+ <string name="menu_delete" msgid="8138799623850614177">"Excluir"</string>
+ <string name="menu_select_all" msgid="8323579667348729928">"Selecionar tudo"</string>
+ <string name="menu_copy" msgid="3612326052677229148">"Copiar para..."</string>
+ <string name="menu_advanced_show" product="nosdcard" msgid="4693652895715631401">"Mostrar armaz. interno"</string>
+ <string name="menu_advanced_show" product="default" msgid="5792182900084144261">"Mostrar cartão SD"</string>
+ <string name="menu_advanced_hide" product="nosdcard" msgid="4218809952721972589">"Ocultar armaz. interno"</string>
+ <string name="menu_advanced_hide" product="default" msgid="4845869969015718848">"Ocultar cartão SD"</string>
+ <string name="menu_file_size_show" msgid="3240323619260823076">"Mostrar tam. do arquivo"</string>
+ <string name="menu_file_size_hide" msgid="8881975928502581042">"Ocultar tam. do arquivo"</string>
+ <string name="button_select" msgid="527196987259139214">"Selecionar"</string>
+ <string name="button_copy" msgid="8706475544635021302">"Copiar"</string>
+ <string name="sort_name" msgid="9183560467917256779">"Por nome"</string>
+ <string name="sort_date" msgid="586080032956151448">"Por data de modificação"</string>
+ <string name="sort_size" msgid="3350681319735474741">"Por tamanho"</string>
+ <string name="drawer_open" msgid="4545466532430226949">"Mostrar raízes"</string>
+ <string name="drawer_close" msgid="7602734368552123318">"Ocultar raízes"</string>
+ <string name="save_error" msgid="6167009778003223664">"Falha ao salvar o documento"</string>
+ <string name="create_error" msgid="3735649141335444215">"Falha ao criar a pasta"</string>
+ <string name="query_error" msgid="1222448261663503501">"Falha ao consultar documentos"</string>
+ <string name="root_recent" msgid="4470053704320518133">"Recentes"</string>
+ <string name="root_available_bytes" msgid="8568452858617033281">"<xliff:g id="SIZE">%1$s</xliff:g> livres"</string>
+ <string name="root_type_service" msgid="2178854894416775409">"Serviços de armazenamento"</string>
+ <string name="root_type_shortcut" msgid="3318760609471618093">"Atalhos"</string>
+ <string name="root_type_device" msgid="7121342474653483538">"Dispositivos"</string>
+ <string name="root_type_apps" msgid="8838065367985945189">"Mais apps"</string>
+ <string name="empty" msgid="7858882803708117596">"Nenhum item"</string>
+ <string name="toast_no_application" msgid="1339885974067891667">"Não é possível abrir o arquivo"</string>
+ <string name="toast_failed_delete" msgid="2180678019407244069">"Não foi possível excluir alguns documentos"</string>
+ <string name="share_via" msgid="8966594246261344259">"Compartilhar via"</string>
+ <string name="copy_notification_title" msgid="6374299806748219777">"Copiando arquivos"</string>
+ <string name="copy_remaining" msgid="6283790937387975095">"<xliff:g id="DURATION">%s</xliff:g> restantes"</string>
+ <plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
+ <item quantity="one">Copiando <xliff:g id="COUNT_1">%1$d</xliff:g> arquivos.</item>
+ <item quantity="other">Copiando <xliff:g id="COUNT_1">%1$d</xliff:g> arquivos.</item>
+ </plurals>
+ <string name="copy_preparing" msgid="3896202461003039386">"Preparando para copiar..."</string>
+ <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
+ <item quantity="one">Não foi possível copiar <xliff:g id="COUNT_1">%1$d</xliff:g> arquivos</item>
+ <item quantity="other">Não foi possível copiar <xliff:g id="COUNT_1">%1$d</xliff:g> arquivos</item>
+ </plurals>
+ <string name="notification_touch_for_details" msgid="4483108577842961665">"Toque para ver detalhes"</string>
+ <string name="retry" msgid="7564024179122207376">"Repetir"</string>
+ <string name="copy_failure_alert_content" msgid="3715575000297709082">"Estes arquivos não foram copiados: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+</resources>
diff --git a/packages/DocumentsUI/res/values-uz-rUZ/strings.xml b/packages/DocumentsUI/res/values-uz-rUZ/strings.xml
index f92fcf1..2450645 100644
--- a/packages/DocumentsUI/res/values-uz-rUZ/strings.xml
+++ b/packages/DocumentsUI/res/values-uz-rUZ/strings.xml
@@ -23,7 +23,7 @@
<string name="menu_grid" msgid="6878021334497835259">"Katak ko‘rinishida"</string>
<string name="menu_list" msgid="7279285939892417279">"Ro‘yxat ko‘rinishida"</string>
<string name="menu_sort" msgid="7677740407158414452">"Saralash"</string>
- <string name="menu_search" msgid="3816712084502856974">"Izlash"</string>
+ <string name="menu_search" msgid="3816712084502856974">"Qidirish"</string>
<string name="menu_settings" msgid="6008033148948428823">"Sozlamalar"</string>
<string name="menu_open" msgid="432922957274920903">"Ochish"</string>
<string name="menu_save" msgid="2394743337684426338">"Saqlash"</string>
diff --git a/packages/DocumentsUI/src/com/android/documentsui/CopyService.java b/packages/DocumentsUI/src/com/android/documentsui/CopyService.java
index 506ec5833..f270d9e 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/CopyService.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/CopyService.java
@@ -32,6 +32,7 @@
import android.os.CancellationSignal;
import android.os.ParcelFileDescriptor;
import android.os.Parcelable;
+import android.os.PowerManager;
import android.os.RemoteException;
import android.os.SystemClock;
import android.provider.DocumentsContract;
@@ -65,6 +66,8 @@
// TODO: Move it to a shared file when more operations are implemented.
public static final int FAILURE_COPY = 1;
+ private PowerManager mPowerManager;
+
private NotificationManager mNotificationManager;
private Notification.Builder mProgressBuilder;
@@ -129,10 +132,14 @@
return;
}
+ final PowerManager.WakeLock wakeLock = mPowerManager
+ .newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG);
final ArrayList<DocumentInfo> srcs = intent.getParcelableArrayListExtra(EXTRA_SRC_LIST);
final DocumentStack stack = intent.getParcelableExtra(EXTRA_STACK);
try {
+ wakeLock.acquire();
+
// Acquire content providers.
mSrcClient = DocumentsApplication.acquireUnstableProviderOrThrow(getContentResolver(),
srcs.get(0).authority);
@@ -151,6 +158,8 @@
ContentProviderClient.releaseQuietly(mSrcClient);
ContentProviderClient.releaseQuietly(mDstClient);
+ wakeLock.release();
+
// Dismiss the ongoing copy notification when the copy is done.
mNotificationManager.cancel(mJobId, 0);
@@ -179,7 +188,8 @@
@Override
public void onCreate() {
super.onCreate();
- mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
+ mPowerManager = getSystemService(PowerManager.class);
+ mNotificationManager = getSystemService(NotificationManager.class);
}
/**
diff --git a/packages/DocumentsUI/src/com/android/documentsui/DirectoryFragment.java b/packages/DocumentsUI/src/com/android/documentsui/DirectoryFragment.java
index 006f6e9..0d326ec 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/DirectoryFragment.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/DirectoryFragment.java
@@ -19,7 +19,10 @@
import static com.android.documentsui.BaseActivity.State.ACTION_BROWSE;
import static com.android.documentsui.BaseActivity.State.ACTION_BROWSE_ALL;
import static com.android.documentsui.BaseActivity.State.ACTION_CREATE;
+import static com.android.documentsui.BaseActivity.State.ACTION_GET_CONTENT;
import static com.android.documentsui.BaseActivity.State.ACTION_MANAGE;
+import static com.android.documentsui.BaseActivity.State.ACTION_OPEN;
+import static com.android.documentsui.BaseActivity.State.ACTION_OPEN_TREE;
import static com.android.documentsui.BaseActivity.State.MODE_GRID;
import static com.android.documentsui.BaseActivity.State.MODE_LIST;
import static com.android.documentsui.BaseActivity.State.MODE_UNKNOWN;
@@ -578,11 +581,23 @@
// Directories and footer items cannot be checked
boolean valid = false;
+ final State state = getDisplayState(DirectoryFragment.this);
final Cursor cursor = mAdapter.getItem(position);
if (cursor != null) {
final String docMimeType = getCursorString(cursor, Document.COLUMN_MIME_TYPE);
final int docFlags = getCursorInt(cursor, Document.COLUMN_FLAGS);
- valid = isDocumentEnabled(docMimeType, docFlags);
+ switch (state.action) {
+ case ACTION_OPEN:
+ case ACTION_CREATE:
+ case ACTION_GET_CONTENT:
+ case ACTION_OPEN_TREE:
+ valid = isDocumentEnabled(docMimeType, docFlags)
+ && !Document.MIME_TYPE_DIR.equals(docMimeType);
+ break;
+ default:
+ valid = isDocumentEnabled(docMimeType, docFlags);
+ break;
+ }
}
if (!valid) {
diff --git a/packages/DocumentsUI/src/com/android/documentsui/RecentLoader.java b/packages/DocumentsUI/src/com/android/documentsui/RecentLoader.java
index f5908c5..407838a 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/RecentLoader.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/RecentLoader.java
@@ -36,6 +36,7 @@
import com.android.documentsui.BaseActivity.State;
import com.android.documentsui.model.RootInfo;
+import com.android.internal.annotations.GuardedBy;
import com.google.android.collect.Maps;
import com.google.common.collect.Lists;
import com.google.common.util.concurrent.AbstractFuture;
@@ -81,6 +82,7 @@
private final RootsCache mRoots;
private final State mState;
+ @GuardedBy("mTasks")
private final HashMap<RootInfo, RecentTask> mTasks = Maps.newHashMap();
private final int mSortOrder = State.SORT_ORDER_LAST_MODIFIED;
@@ -167,6 +169,12 @@
@Override
public DirectoryResult loadInBackground() {
+ synchronized (mTasks) {
+ return loadInBackgroundLocked();
+ }
+ }
+
+ private DirectoryResult loadInBackgroundLocked() {
if (mFirstPassLatch == null) {
// First time through we kick off all the recent tasks, and wait
// around to see if everyone finishes quickly.
@@ -304,8 +312,10 @@
// Ensure the loader is stopped
onStopLoading();
- for (RecentTask task : mTasks.values()) {
- IoUtils.closeQuietly(task);
+ synchronized (mTasks) {
+ for (RecentTask task : mTasks.values()) {
+ IoUtils.closeQuietly(task);
+ }
}
IoUtils.closeQuietly(mResult);
diff --git a/packages/ExternalStorageProvider/res/values-fa/strings.xml b/packages/ExternalStorageProvider/res/values-fa/strings.xml
index 8471fc7..9ae8a47 100644
--- a/packages/ExternalStorageProvider/res/values-fa/strings.xml
+++ b/packages/ExternalStorageProvider/res/values-fa/strings.xml
@@ -16,7 +16,7 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label" msgid="7123375275748530234">"فضای ذخیره خارجی"</string>
+ <string name="app_label" msgid="7123375275748530234">"حافظه خارجی"</string>
<string name="root_internal_storage" msgid="827844243068584127">"حافظهٔ داخلی"</string>
<string name="root_documents" msgid="4051252304075469250">"اسناد"</string>
</resources>
diff --git a/packages/ExternalStorageProvider/res/values-pt-rBR/strings.xml b/packages/ExternalStorageProvider/res/values-pt-rBR/strings.xml
new file mode 100644
index 0000000..77c89b8
--- /dev/null
+++ b/packages/ExternalStorageProvider/res/values-pt-rBR/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2013 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_label" msgid="7123375275748530234">"Armazenamento externo"</string>
+ <string name="root_internal_storage" msgid="827844243068584127">"Armazenamento interno"</string>
+ <string name="root_documents" msgid="4051252304075469250">"Documentos"</string>
+</resources>
diff --git a/packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java b/packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java
index 393771a..18335b6 100644
--- a/packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java
+++ b/packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java
@@ -38,6 +38,7 @@
import android.provider.DocumentsContract.Document;
import android.provider.DocumentsContract.Root;
import android.provider.DocumentsProvider;
+import android.provider.MediaStore;
import android.text.TextUtils;
import android.util.ArrayMap;
import android.util.DebugUtils;
@@ -380,12 +381,31 @@
@Override
public void deleteDocument(String docId) throws FileNotFoundException {
final File file = getFileForDocId(docId);
- if (file.isDirectory()) {
+ final boolean isDirectory = file.isDirectory();
+ if (isDirectory) {
FileUtils.deleteContents(file);
}
if (!file.delete()) {
throw new IllegalStateException("Failed to delete " + file);
}
+
+ final ContentResolver resolver = getContext().getContentResolver();
+ final Uri externalUri = MediaStore.Files.getContentUri("external");
+
+ // Remove media store entries for any files inside this directory, using
+ // path prefix match. Logic borrowed from MtpDatabase.
+ if (isDirectory) {
+ final String path = file.getAbsolutePath() + "/";
+ resolver.delete(externalUri,
+ "_data LIKE ?1 AND lower(substr(_data,1,?2))=lower(?3)",
+ new String[] { path + "%", Integer.toString(path.length()), path });
+ }
+
+ // Remove media store entry for this exact file.
+ final String path = file.getAbsolutePath();
+ resolver.delete(externalUri,
+ "_data LIKE ?1 AND lower(_data)=lower(?2)",
+ new String[] { path, path });
}
@Override
diff --git a/packages/FusedLocation/res/values-pt-rBR/strings.xml b/packages/FusedLocation/res/values-pt-rBR/strings.xml
new file mode 100644
index 0000000..4f8277a
--- /dev/null
+++ b/packages/FusedLocation/res/values-pt-rBR/strings.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_label" msgid="5379477904423203699">"Localização combinada"</string>
+</resources>
diff --git a/packages/FusedLocation/src/com/android/location/fused/FusionEngine.java b/packages/FusedLocation/src/com/android/location/fused/FusionEngine.java
index 5e9ec10..7a49524 100644
--- a/packages/FusedLocation/src/com/android/location/fused/FusionEngine.java
+++ b/packages/FusedLocation/src/com/android/location/fused/FusionEngine.java
@@ -37,7 +37,7 @@
public class FusionEngine implements LocationListener {
public interface Callback {
- public void reportLocation(Location location);
+ void reportLocation(Location location);
}
private static final String TAG = "FusedLocation";
@@ -45,7 +45,7 @@
private static final String GPS = LocationManager.GPS_PROVIDER;
private static final String FUSED = LocationProviderBase.FUSED_PROVIDER;
- public static final long SWITCH_ON_FRESHNESS_CLIFF_NS = 11 * 1000000000; // 11 seconds
+ public static final long SWITCH_ON_FRESHNESS_CLIFF_NS = 11 * 1000000000L; // 11 seconds
private final Context mContext;
private final LocationManager mLocationManager;
@@ -60,7 +60,7 @@
private boolean mEnabled;
private ProviderRequestUnbundled mRequest;
- private final HashMap<String, ProviderStats> mStats = new HashMap<String, ProviderStats>();
+ private final HashMap<String, ProviderStats> mStats = new HashMap<>();
public FusionEngine(Context context, Looper looper) {
mContext = context;
@@ -72,9 +72,7 @@
mLooper = looper;
mStats.put(GPS, new ProviderStats());
- mStats.get(GPS).available = mLocationManager.isProviderEnabled(GPS);
mStats.put(NETWORK, new ProviderStats());
- mStats.get(NETWORK).available = mLocationManager.isProviderEnabled(NETWORK);
}
@@ -119,35 +117,35 @@
}
private static class ProviderStats {
- public boolean available;
public boolean requested;
public long requestTime;
public long minTime;
@Override
public String toString() {
- StringBuilder s = new StringBuilder();
- s.append(available ? "AVAILABLE" : "UNAVAILABLE");
- s.append(requested ? " REQUESTED" : " ---");
- return s.toString();
+ return (requested ? " REQUESTED" : " ---");
}
}
private void enableProvider(String name, long minTime) {
ProviderStats stats = mStats.get(name);
+ if (stats == null) return;
- if (!stats.requested) {
- stats.requestTime = SystemClock.elapsedRealtime();
- stats.requested = true;
- stats.minTime = minTime;
- mLocationManager.requestLocationUpdates(name, minTime, 0, this, mLooper);
- } else if (stats.minTime != minTime) {
- stats.minTime = minTime;
- mLocationManager.requestLocationUpdates(name, minTime, 0, this, mLooper);
+ if (mLocationManager.isProviderEnabled(name)) {
+ if (!stats.requested) {
+ stats.requestTime = SystemClock.elapsedRealtime();
+ stats.requested = true;
+ stats.minTime = minTime;
+ mLocationManager.requestLocationUpdates(name, minTime, 0, this, mLooper);
+ } else if (stats.minTime != minTime) {
+ stats.minTime = minTime;
+ mLocationManager.requestLocationUpdates(name, minTime, 0, this, mLooper);
+ }
}
}
private void disableProvider(String name) {
ProviderStats stats = mStats.get(name);
+ if (stats == null) return;
if (stats.requested) {
stats.requested = false;
@@ -156,7 +154,7 @@
}
private void updateRequirements() {
- if (mEnabled == false || mRequest == null) {
+ if (!mEnabled || mRequest == null) {
mRequest = null;
disableProvider(NETWORK);
disableProvider(GPS);
@@ -248,7 +246,7 @@
mFusedLocation.setExtras(dstExtras);
}
dstExtras.putParcelable(LocationProviderBase.EXTRA_NO_GPS_LOCATION,
- (Location) srcParcelable);
+ srcParcelable);
}
}
}
@@ -278,25 +276,15 @@
/** Called on mLooper thread */
@Override
- public void onProviderEnabled(String provider) {
- ProviderStats stats = mStats.get(provider);
- if (stats == null) return;
-
- stats.available = true;
- }
+ public void onProviderEnabled(String provider) { }
/** Called on mLooper thread */
@Override
- public void onProviderDisabled(String provider) {
- ProviderStats stats = mStats.get(provider);
- if (stats == null) return;
-
- stats.available = false;
- }
+ public void onProviderDisabled(String provider) { }
public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
StringBuilder s = new StringBuilder();
- s.append("mEnabled=" + mEnabled).append(' ').append(mRequest).append('\n');
+ s.append("mEnabled=").append(mEnabled).append(' ').append(mRequest).append('\n');
s.append("fused=").append(mFusedLocation).append('\n');
s.append(String.format("gps %s\n", mGpsLocation));
s.append(" ").append(mStats.get(GPS)).append('\n');
diff --git a/packages/InputDevices/res/values-pt-rBR/strings.xml b/packages/InputDevices/res/values-pt-rBR/strings.xml
new file mode 100644
index 0000000..e9a0a38
--- /dev/null
+++ b/packages/InputDevices/res/values-pt-rBR/strings.xml
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_label" msgid="8016145283189546017">"Dispositivos de entrada"</string>
+ <string name="keyboard_layouts_label" msgid="6688773268302087545">"Teclado do Android"</string>
+ <string name="keyboard_layout_english_uk_label" msgid="6664258463319999632">"Inglês (Reino Unido)"</string>
+ <string name="keyboard_layout_english_us_label" msgid="8994890249649106291">"Inglês (EUA)"</string>
+ <string name="keyboard_layout_english_us_intl" msgid="3705168594034233583">"Inglês (EUA), estilo internacional"</string>
+ <string name="keyboard_layout_english_us_colemak_label" msgid="4194969610343455380">"Inglês (EUA), estilo Colemak"</string>
+ <string name="keyboard_layout_english_us_dvorak_label" msgid="793528923171145202">"Inglês (EUA), estilo Dvorak"</string>
+ <string name="keyboard_layout_german_label" msgid="8451565865467909999">"Alemão"</string>
+ <string name="keyboard_layout_french_label" msgid="813450119589383723">"Francês"</string>
+ <string name="keyboard_layout_french_ca_label" msgid="365352601060604832">"Francês (Canadá)"</string>
+ <string name="keyboard_layout_russian_label" msgid="8724879775815042968">"Russo"</string>
+ <string name="keyboard_layout_russian_mac_label" msgid="3795866869038264796">"Russo, estilo Mac"</string>
+ <string name="keyboard_layout_spanish_label" msgid="7091555148131908240">"Espanhol"</string>
+ <string name="keyboard_layout_swiss_french_label" msgid="4659191025396371684">"Francês suíço"</string>
+ <string name="keyboard_layout_swiss_german_label" msgid="2305520941993314258">"Alemão suíço"</string>
+ <string name="keyboard_layout_belgian" msgid="2011984572838651558">"Belga"</string>
+ <string name="keyboard_layout_bulgarian" msgid="8951224309972028398">"Búlgaro"</string>
+ <string name="keyboard_layout_italian" msgid="6497079660449781213">"Italiano"</string>
+ <string name="keyboard_layout_danish" msgid="8036432066627127851">"Dinamarquês"</string>
+ <string name="keyboard_layout_norwegian" msgid="9090097917011040937">"Norueguês"</string>
+ <string name="keyboard_layout_swedish" msgid="732959109088479351">"Sueco"</string>
+ <string name="keyboard_layout_finnish" msgid="5585659438924315466">"Finlandês"</string>
+ <string name="keyboard_layout_croatian" msgid="4172229471079281138">"Croata"</string>
+ <string name="keyboard_layout_czech" msgid="1349256901452975343">"Tcheco"</string>
+ <string name="keyboard_layout_estonian" msgid="8775830985185665274">"Estoniano"</string>
+ <string name="keyboard_layout_hungarian" msgid="4154963661406035109">"Húngaro"</string>
+ <string name="keyboard_layout_icelandic" msgid="5836645650912489642">"Islandês"</string>
+ <string name="keyboard_layout_brazilian" msgid="5117896443147781939">"Brasileiro"</string>
+ <string name="keyboard_layout_portuguese" msgid="2888198587329660305">"Português"</string>
+ <string name="keyboard_layout_slovak" msgid="2469379934672837296">"Eslovaco"</string>
+ <string name="keyboard_layout_slovenian" msgid="1735933028924982368">"Esloveno"</string>
+ <string name="keyboard_layout_turkish" msgid="7736163250907964898">"Turco"</string>
+ <string name="keyboard_layout_ukrainian" msgid="8176637744389480417">"Ucraniano"</string>
+ <string name="keyboard_layout_arabic" msgid="5671970465174968712">"Árabe"</string>
+ <string name="keyboard_layout_greek" msgid="7289253560162386040">"Grego"</string>
+ <string name="keyboard_layout_hebrew" msgid="7241473985890173812">"Hebraico"</string>
+ <string name="keyboard_layout_lithuanian" msgid="6943110873053106534">"Lituano"</string>
+ <string name="keyboard_layout_spanish_latin" msgid="5690539836069535697">"Espanhol (América Latina)"</string>
+ <string name="keyboard_layout_latvian" msgid="4405417142306250595">"Letão"</string>
+</resources>
diff --git a/packages/InputDevices/res/values-uz-rUZ/strings.xml b/packages/InputDevices/res/values-uz-rUZ/strings.xml
index 0a99ad3..3b6772b 100644
--- a/packages/InputDevices/res/values-uz-rUZ/strings.xml
+++ b/packages/InputDevices/res/values-uz-rUZ/strings.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label" msgid="8016145283189546017">"Kiruvchi qurilmalar"</string>
+ <string name="app_label" msgid="8016145283189546017">"Kiritish qurilmalari"</string>
<string name="keyboard_layouts_label" msgid="6688773268302087545">"Android klaviaturasi"</string>
<string name="keyboard_layout_english_uk_label" msgid="6664258463319999632">"Inglizcha (BQ)"</string>
<string name="keyboard_layout_english_us_label" msgid="8994890249649106291">"Inglizcha (AQSH)"</string>
diff --git a/packages/Keyguard/res/values-af/strings.xml b/packages/Keyguard/res/values-af/strings.xml
index 91f4c81..efff2a8 100644
--- a/packages/Keyguard/res/values-af/strings.xml
+++ b/packages/Keyguard/res/values-af/strings.xml
@@ -31,6 +31,8 @@
<string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"Verkeerde PIN-kode."</string>
<string name="keyguard_charged" msgid="3272223906073492454">"Gelaai"</string>
<string name="keyguard_plugged_in" msgid="9087497435553252863">"Laai tans"</string>
+ <string name="keyguard_plugged_in_charging_fast" msgid="6671162730167305479">"Laai tans vinnig"</string>
+ <string name="keyguard_plugged_in_charging_slowly" msgid="1964714661071163229">"Laai tans stadig"</string>
<string name="keyguard_low_battery" msgid="8143808018719173859">"Koppel jou herlaaier."</string>
<string name="keyguard_instructions_when_pattern_disabled" msgid="1332288268600329841">"Druk kieslys om te ontsluit."</string>
<string name="keyguard_network_locked_message" msgid="9169717779058037168">"Netwerk gesluit"</string>
@@ -111,6 +113,9 @@
<string name="kg_prompt_reason_restart_pattern" msgid="489430505491862444">"Patroon word vereis wanneer jy die toestel herbegin."</string>
<string name="kg_prompt_reason_restart_pin" msgid="994878216570694974">"PIN word vereis wanneer jy die toestel herbegin."</string>
<string name="kg_prompt_reason_restart_password" msgid="2375742919528461664">"Wagwoord word vereis wanneer jy die toestel herbegin."</string>
+ <string name="kg_prompt_reason_timeout_pattern" msgid="8930047492617900785">"Patroon word vir bykomende sekuriteit vereis."</string>
+ <string name="kg_prompt_reason_timeout_pin" msgid="7470468607947726377">"PIN word vir bykomende sekuriteit vereis."</string>
+ <string name="kg_prompt_reason_timeout_password" msgid="1177412542773936957">"Wagwoord word vir bykomende sekuriteit vereis."</string>
<string name="kg_prompt_reason_switch_profiles_pattern" msgid="3802056699323773969">"Patroon word vereis wanneer jy profiele wissel."</string>
<string name="kg_prompt_reason_switch_profiles_pin" msgid="8108020184731052246">"PIN word vereis wanneer jy profiele wissel."</string>
<string name="kg_prompt_reason_switch_profiles_password" msgid="6755997057852042672">"Wagwoord word vereis wanneer jy profiele wissel."</string>
diff --git a/packages/Keyguard/res/values-am/strings.xml b/packages/Keyguard/res/values-am/strings.xml
index e541b09..24f87ed 100644
--- a/packages/Keyguard/res/values-am/strings.xml
+++ b/packages/Keyguard/res/values-am/strings.xml
@@ -31,6 +31,8 @@
<string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"ትክክል ያልሆነ ፒን ኮድ።"</string>
<string name="keyguard_charged" msgid="3272223906073492454">"ባትሪ ሞልቷል"</string>
<string name="keyguard_plugged_in" msgid="9087497435553252863">"ኃይል በመሙላት ላይ"</string>
+ <string name="keyguard_plugged_in_charging_fast" msgid="6671162730167305479">"ኃይል በፍጥነት በመሙላት ላይ"</string>
+ <string name="keyguard_plugged_in_charging_slowly" msgid="1964714661071163229">"ኃይል በዝግታ በመሙላት ላይ"</string>
<string name="keyguard_low_battery" msgid="8143808018719173859">"የኃይል መሙያዎን ይሰኩ።"</string>
<string name="keyguard_instructions_when_pattern_disabled" msgid="1332288268600329841">"ለመክፈት ምናሌውን ይጫኑ።"</string>
<string name="keyguard_network_locked_message" msgid="9169717779058037168">"አውታረ መረብ ተቆልፏል"</string>
@@ -111,6 +113,9 @@
<string name="kg_prompt_reason_restart_pattern" msgid="489430505491862444">"መሳሪያውን ዳግም በሚያስጀምሩ ጊዜ ስርዓተ ጥለት ያስፈልጋል።"</string>
<string name="kg_prompt_reason_restart_pin" msgid="994878216570694974">"መሳሪያውን ዳግም በሚያስጀምሩ ጊዜ ፒን ያስፈልጋል።"</string>
<string name="kg_prompt_reason_restart_password" msgid="2375742919528461664">"መሳሪያውን ዳግም በሚያስጀምሩ ጊዜ የይለፍ ቃል ያስፈልጋል።"</string>
+ <string name="kg_prompt_reason_timeout_pattern" msgid="8930047492617900785">"ለተጨማሪ ደህንነት ስርዓተ ጥለት ያስፈልጋል።"</string>
+ <string name="kg_prompt_reason_timeout_pin" msgid="7470468607947726377">"ለተጨማሪ ደህንነት ፒን ያስፈልጋል።"</string>
+ <string name="kg_prompt_reason_timeout_password" msgid="1177412542773936957">"ለተጨማሪ ደህንነት የይለፍ ቃል ያስፈልጋል።"</string>
<string name="kg_prompt_reason_switch_profiles_pattern" msgid="3802056699323773969">"መገለጫዎችን በሚቀይሩ ጊዜ ስርዓተ ጥለት ያስፈልጋል።"</string>
<string name="kg_prompt_reason_switch_profiles_pin" msgid="8108020184731052246">"መገለጫዎችን በሚቀይሩ ጊዜ ፒን ያስፈልጋል።"</string>
<string name="kg_prompt_reason_switch_profiles_password" msgid="6755997057852042672">"መገለጫዎችን በሚቀይሩ ጊዜ የይለፍ ቃል ያስፈልጋል።"</string>
diff --git a/packages/Keyguard/res/values-ar/strings.xml b/packages/Keyguard/res/values-ar/strings.xml
index 0b62031..b326238 100644
--- a/packages/Keyguard/res/values-ar/strings.xml
+++ b/packages/Keyguard/res/values-ar/strings.xml
@@ -31,6 +31,8 @@
<string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"رمز PIN غير صحيح."</string>
<string name="keyguard_charged" msgid="3272223906073492454">"تم الشحن"</string>
<string name="keyguard_plugged_in" msgid="9087497435553252863">"جارٍ الشحن"</string>
+ <string name="keyguard_plugged_in_charging_fast" msgid="6671162730167305479">"الشحن سريعًا"</string>
+ <string name="keyguard_plugged_in_charging_slowly" msgid="1964714661071163229">"الشحن ببطء"</string>
<string name="keyguard_low_battery" msgid="8143808018719173859">"توصيل جهاز الشحن."</string>
<string name="keyguard_instructions_when_pattern_disabled" msgid="1332288268600329841">"اضغط على \"القائمة\" لإلغاء القفل."</string>
<string name="keyguard_network_locked_message" msgid="9169717779058037168">"الشبكة مؤمّنة"</string>
@@ -119,6 +121,9 @@
<string name="kg_prompt_reason_restart_pattern" msgid="489430505491862444">"يجب رسم النقش عند إعادة تشغيل الجهاز."</string>
<string name="kg_prompt_reason_restart_pin" msgid="994878216570694974">"يجب إدخال رقم التعريف الشخصي عند إعادة تشغيل الجهاز."</string>
<string name="kg_prompt_reason_restart_password" msgid="2375742919528461664">"يجب إدخال كلمة المرور عند إعادة تشغيل الجهاز."</string>
+ <string name="kg_prompt_reason_timeout_pattern" msgid="8930047492617900785">"يلزم إدخال النمط لمزيد من الأمان."</string>
+ <string name="kg_prompt_reason_timeout_pin" msgid="7470468607947726377">"يلزم إدخال رقم التعريف الشخصي لمزيد من الأمان."</string>
+ <string name="kg_prompt_reason_timeout_password" msgid="1177412542773936957">"يلزم إدخال كلمة المرور لمزيد من الأمان."</string>
<string name="kg_prompt_reason_switch_profiles_pattern" msgid="3802056699323773969">"يجب رسم النقش عند تبديل الملفات الشخصية."</string>
<string name="kg_prompt_reason_switch_profiles_pin" msgid="8108020184731052246">"يجب إدخال رقم التعريف الشخصي عند تبديل الملفات الشخصية."</string>
<string name="kg_prompt_reason_switch_profiles_password" msgid="6755997057852042672">"يجب إدخال كلمة المرور عند تبديل الملفات الشخصية."</string>
diff --git a/packages/Keyguard/res/values-az-rAZ/strings.xml b/packages/Keyguard/res/values-az-rAZ/strings.xml
index 5376266..6e336be 100644
--- a/packages/Keyguard/res/values-az-rAZ/strings.xml
+++ b/packages/Keyguard/res/values-az-rAZ/strings.xml
@@ -31,6 +31,8 @@
<string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"Yanlış PIN kodu."</string>
<string name="keyguard_charged" msgid="3272223906073492454">"Dolmuş"</string>
<string name="keyguard_plugged_in" msgid="9087497435553252863">"Enerji doldurulur"</string>
+ <string name="keyguard_plugged_in_charging_fast" msgid="6671162730167305479">"Enerji sürətlə dolur"</string>
+ <string name="keyguard_plugged_in_charging_slowly" msgid="1964714661071163229">"Enerji yavaş dolur"</string>
<string name="keyguard_low_battery" msgid="8143808018719173859">"Elektrikə qoşun."</string>
<string name="keyguard_instructions_when_pattern_disabled" msgid="1332288268600329841">"Kilidi açmaq üçün Menyu düyməsinə baxın."</string>
<string name="keyguard_network_locked_message" msgid="9169717779058037168">"Şəbəkə kilidləndi"</string>
@@ -111,6 +113,9 @@
<string name="kg_prompt_reason_restart_pattern" msgid="489430505491862444">"Cihazı yenidən başladarkən nümunə kod tələb olunur."</string>
<string name="kg_prompt_reason_restart_pin" msgid="994878216570694974">"Cihazı yenidən başladarkən PIN kod tələb olunur."</string>
<string name="kg_prompt_reason_restart_password" msgid="2375742919528461664">"Cihazı yenidən başladarkən parol tələb olunur."</string>
+ <string name="kg_prompt_reason_timeout_pattern" msgid="8930047492617900785">"Əlavə təhlükəsizlik üçün model tələb olunur."</string>
+ <string name="kg_prompt_reason_timeout_pin" msgid="7470468607947726377">"Əlavə təhlükəsizlik üçün PIN tələb olunur."</string>
+ <string name="kg_prompt_reason_timeout_password" msgid="1177412542773936957">"Əlavə təhlükəsizlik üçün parol tələb olunur."</string>
<string name="kg_prompt_reason_switch_profiles_pattern" msgid="3802056699323773969">"Profillər arasında keçid edərkən nümunə kod tələb olunur."</string>
<string name="kg_prompt_reason_switch_profiles_pin" msgid="8108020184731052246">"Profillər arasında keçid edərkən PIN kod tələb olunur."</string>
<string name="kg_prompt_reason_switch_profiles_password" msgid="6755997057852042672">"Profillər arasında keçid edərkən parol tələb olunur."</string>
diff --git a/packages/Keyguard/res/values-bg/strings.xml b/packages/Keyguard/res/values-bg/strings.xml
index 7ce7d78..7fbf46a 100644
--- a/packages/Keyguard/res/values-bg/strings.xml
+++ b/packages/Keyguard/res/values-bg/strings.xml
@@ -31,6 +31,8 @@
<string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"Неправилен ПИН код."</string>
<string name="keyguard_charged" msgid="3272223906073492454">"Заредена"</string>
<string name="keyguard_plugged_in" msgid="9087497435553252863">"Зарежда се"</string>
+ <string name="keyguard_plugged_in_charging_fast" msgid="6671162730167305479">"Зарежда се бързо"</string>
+ <string name="keyguard_plugged_in_charging_slowly" msgid="1964714661071163229">"Зарежда се бавно"</string>
<string name="keyguard_low_battery" msgid="8143808018719173859">"Свържете зарядното си устройство."</string>
<string name="keyguard_instructions_when_pattern_disabled" msgid="1332288268600329841">"Натиснете иконата за меню, за да отключите."</string>
<string name="keyguard_network_locked_message" msgid="9169717779058037168">"Мрежата е заключена"</string>
@@ -111,6 +113,9 @@
<string name="kg_prompt_reason_restart_pattern" msgid="489430505491862444">"При рестартиране на устройството ви се изисква фигура."</string>
<string name="kg_prompt_reason_restart_pin" msgid="994878216570694974">"При рестартиране на устройството ви се изисква ПИН код."</string>
<string name="kg_prompt_reason_restart_password" msgid="2375742919528461664">"При рестартиране на устройството ви се изисква парола."</string>
+ <string name="kg_prompt_reason_timeout_pattern" msgid="8930047492617900785">"За допълнителна сигурност се изисква фигура."</string>
+ <string name="kg_prompt_reason_timeout_pin" msgid="7470468607947726377">"За допълнителна сигурност се изисква ПИН."</string>
+ <string name="kg_prompt_reason_timeout_password" msgid="1177412542773936957">"За допълнителна сигурност се изисква парола."</string>
<string name="kg_prompt_reason_switch_profiles_pattern" msgid="3802056699323773969">"При превключване между потребителските профили се изисква фигура."</string>
<string name="kg_prompt_reason_switch_profiles_pin" msgid="8108020184731052246">"При превключване между потребителските профили се изисква ПИН код."</string>
<string name="kg_prompt_reason_switch_profiles_password" msgid="6755997057852042672">"При превключване между потребителските профили се изисква парола."</string>
diff --git a/packages/Keyguard/res/values-bn-rBD/strings.xml b/packages/Keyguard/res/values-bn-rBD/strings.xml
index 92bdad9..83ca30e 100644
--- a/packages/Keyguard/res/values-bn-rBD/strings.xml
+++ b/packages/Keyguard/res/values-bn-rBD/strings.xml
@@ -31,6 +31,8 @@
<string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"ভুল পিন কোড৷"</string>
<string name="keyguard_charged" msgid="3272223906073492454">"চার্জ হয়েছে"</string>
<string name="keyguard_plugged_in" msgid="9087497435553252863">"চার্জ হচ্ছে"</string>
+ <string name="keyguard_plugged_in_charging_fast" msgid="6671162730167305479">"দ্রুত চার্জ হচ্ছে"</string>
+ <string name="keyguard_plugged_in_charging_slowly" msgid="1964714661071163229">"ধীরে ধীরে চার্জ হচ্ছে"</string>
<string name="keyguard_low_battery" msgid="8143808018719173859">"আপনার চার্জার সংযুক্ত করুন৷"</string>
<string name="keyguard_instructions_when_pattern_disabled" msgid="1332288268600329841">"আনলক করতে মেনু টিপুন৷"</string>
<string name="keyguard_network_locked_message" msgid="9169717779058037168">"নেটওয়ার্ক লক হয়েছে"</string>
@@ -111,6 +113,9 @@
<string name="kg_prompt_reason_restart_pattern" msgid="489430505491862444">"যখন আপনি ডিভাইস পুনর্সূচনা করবেন তখন প্যাটার্নের প্রয়োজন হবে৷"</string>
<string name="kg_prompt_reason_restart_pin" msgid="994878216570694974">"যখন আপনি ডিভাইস পুনর্সূচনা করবেন তখন পিন এর প্রয়োজন হবে৷"</string>
<string name="kg_prompt_reason_restart_password" msgid="2375742919528461664">"যখন আপনি ডিভাইস পুনর্সূচনা করবেন তখন পাসওয়ার্ডের প্রয়োজন হবে৷"</string>
+ <string name="kg_prompt_reason_timeout_pattern" msgid="8930047492617900785">"অতিরিক্ত সুরক্ষার জন্য প্যাটার্ন প্রয়োজন৷"</string>
+ <string name="kg_prompt_reason_timeout_pin" msgid="7470468607947726377">"অতিরিক্ত সুরক্ষার জন্য PIN প্রয়োজন৷"</string>
+ <string name="kg_prompt_reason_timeout_password" msgid="1177412542773936957">"অতিরিক্ত সুরক্ষার জন্য পাসওয়ার্ড প্রয়োজন৷"</string>
<string name="kg_prompt_reason_switch_profiles_pattern" msgid="3802056699323773969">"যখন আপনি প্রোফাইলগুলি পাল্টাবেন তখন প্যাটার্নের প্রয়োজন হবে৷"</string>
<string name="kg_prompt_reason_switch_profiles_pin" msgid="8108020184731052246">"যখন আপনি প্রোফাইলগুলি পাল্টাবেন তখন পিন এর প্রয়োজন হবে৷"</string>
<string name="kg_prompt_reason_switch_profiles_password" msgid="6755997057852042672">"যখন আপনি প্রোফাইলগুলি পাল্টাবেন তখন পাসওয়ার্ডের প্রয়োজন হবে৷"</string>
diff --git a/packages/Keyguard/res/values-ca/strings.xml b/packages/Keyguard/res/values-ca/strings.xml
index db24df2..42ae52e 100644
--- a/packages/Keyguard/res/values-ca/strings.xml
+++ b/packages/Keyguard/res/values-ca/strings.xml
@@ -31,6 +31,8 @@
<string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"Codi PIN incorrecte."</string>
<string name="keyguard_charged" msgid="3272223906073492454">"Carregada"</string>
<string name="keyguard_plugged_in" msgid="9087497435553252863">"Carregant"</string>
+ <string name="keyguard_plugged_in_charging_fast" msgid="6671162730167305479">"S\'està carregant ràpidament"</string>
+ <string name="keyguard_plugged_in_charging_slowly" msgid="1964714661071163229">"S\'està carregant lentament"</string>
<string name="keyguard_low_battery" msgid="8143808018719173859">"Connecta el carregador."</string>
<string name="keyguard_instructions_when_pattern_disabled" msgid="1332288268600329841">"Prem Menú per desbloquejar."</string>
<string name="keyguard_network_locked_message" msgid="9169717779058037168">"Xarxa bloquejada"</string>
@@ -111,6 +113,9 @@
<string name="kg_prompt_reason_restart_pattern" msgid="489430505491862444">"Cal introduir el patró en reiniciar el dispositiu."</string>
<string name="kg_prompt_reason_restart_pin" msgid="994878216570694974">"Cal introduir el PIN en reiniciar el dispositiu."</string>
<string name="kg_prompt_reason_restart_password" msgid="2375742919528461664">"Cal introduir la contrasenya en reiniciar el dispositiu."</string>
+ <string name="kg_prompt_reason_timeout_pattern" msgid="8930047492617900785">"El patró és necessari per disposar de més seguretat."</string>
+ <string name="kg_prompt_reason_timeout_pin" msgid="7470468607947726377">"El PIN és necessari per disposar de més seguretat."</string>
+ <string name="kg_prompt_reason_timeout_password" msgid="1177412542773936957">"La contrasenya és necessària per disposar de més seguretat."</string>
<string name="kg_prompt_reason_switch_profiles_pattern" msgid="3802056699323773969">"Cal introduir el patró en canviar de perfil."</string>
<string name="kg_prompt_reason_switch_profiles_pin" msgid="8108020184731052246">"Cal introduir el PIN en canviar de perfil."</string>
<string name="kg_prompt_reason_switch_profiles_password" msgid="6755997057852042672">"Cal introduir la contrasenya en canviar de perfil."</string>
diff --git a/packages/Keyguard/res/values-cs/strings.xml b/packages/Keyguard/res/values-cs/strings.xml
index 00f4cf3..23e1420 100644
--- a/packages/Keyguard/res/values-cs/strings.xml
+++ b/packages/Keyguard/res/values-cs/strings.xml
@@ -31,6 +31,8 @@
<string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"Nesprávný kód PIN."</string>
<string name="keyguard_charged" msgid="3272223906073492454">"Nabito"</string>
<string name="keyguard_plugged_in" msgid="9087497435553252863">"Nabíjení"</string>
+ <string name="keyguard_plugged_in_charging_fast" msgid="6671162730167305479">"Rychlé nabíjení"</string>
+ <string name="keyguard_plugged_in_charging_slowly" msgid="1964714661071163229">"Pomalé nabíjení"</string>
<string name="keyguard_low_battery" msgid="8143808018719173859">"Připojte dobíjecí zařízení."</string>
<string name="keyguard_instructions_when_pattern_disabled" msgid="1332288268600329841">"Telefon odemknete stisknutím tlačítka Menu."</string>
<string name="keyguard_network_locked_message" msgid="9169717779058037168">"Síť je blokována"</string>
@@ -115,6 +117,9 @@
<string name="kg_prompt_reason_restart_pattern" msgid="489430505491862444">"Po restartu zařízení je vyžadováno gesto."</string>
<string name="kg_prompt_reason_restart_pin" msgid="994878216570694974">"Po restartu zařízení je vyžadován PIN."</string>
<string name="kg_prompt_reason_restart_password" msgid="2375742919528461664">"Po restartu zařízení je vyžadováno heslo."</string>
+ <string name="kg_prompt_reason_timeout_pattern" msgid="8930047492617900785">"Za účelem zvýšení zabezpečení je vyžadováno gesto."</string>
+ <string name="kg_prompt_reason_timeout_pin" msgid="7470468607947726377">"Za účelem zvýšení zabezpečení je vyžadován kód PIN."</string>
+ <string name="kg_prompt_reason_timeout_password" msgid="1177412542773936957">"Za účelem zvýšení zabezpečení je vyžadováno heslo."</string>
<string name="kg_prompt_reason_switch_profiles_pattern" msgid="3802056699323773969">"Po přepnutí profilů je vyžadováno gesto."</string>
<string name="kg_prompt_reason_switch_profiles_pin" msgid="8108020184731052246">"Po přepnutí profilů je vyžadován PIN."</string>
<string name="kg_prompt_reason_switch_profiles_password" msgid="6755997057852042672">"Po přepnutí profilů je vyžadováno heslo."</string>
diff --git a/packages/Keyguard/res/values-da/strings.xml b/packages/Keyguard/res/values-da/strings.xml
index fb67606..2c39241 100644
--- a/packages/Keyguard/res/values-da/strings.xml
+++ b/packages/Keyguard/res/values-da/strings.xml
@@ -31,6 +31,8 @@
<string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"Forkert pinkode."</string>
<string name="keyguard_charged" msgid="3272223906073492454">"Opladet"</string>
<string name="keyguard_plugged_in" msgid="9087497435553252863">"Oplader"</string>
+ <string name="keyguard_plugged_in_charging_fast" msgid="6671162730167305479">"Oplader hurtigt"</string>
+ <string name="keyguard_plugged_in_charging_slowly" msgid="1964714661071163229">"Oplader langsomt"</string>
<string name="keyguard_low_battery" msgid="8143808018719173859">"Tilslut din oplader."</string>
<string name="keyguard_instructions_when_pattern_disabled" msgid="1332288268600329841">"Tryk på Menu for at låse op."</string>
<string name="keyguard_network_locked_message" msgid="9169717779058037168">"Netværket er låst"</string>
@@ -111,6 +113,9 @@
<string name="kg_prompt_reason_restart_pattern" msgid="489430505491862444">"Du skal indtaste et mønster, når du genstarter enheden."</string>
<string name="kg_prompt_reason_restart_pin" msgid="994878216570694974">"Du skal indtaste en pinkode, når du genstarter enheden."</string>
<string name="kg_prompt_reason_restart_password" msgid="2375742919528461664">"Du skal indtaste en adgangskode, når du genstarter enheden."</string>
+ <string name="kg_prompt_reason_timeout_pattern" msgid="8930047492617900785">"Der kræves et mønster som ekstra beskyttelse."</string>
+ <string name="kg_prompt_reason_timeout_pin" msgid="7470468607947726377">"Der kræves en pinkode som ekstra beskyttelse."</string>
+ <string name="kg_prompt_reason_timeout_password" msgid="1177412542773936957">"Der kræves en adgangskode som ekstra beskyttelse."</string>
<string name="kg_prompt_reason_switch_profiles_pattern" msgid="3802056699323773969">"Du skal indtaste et mønster, når du skifter profiler."</string>
<string name="kg_prompt_reason_switch_profiles_pin" msgid="8108020184731052246">"Du skal indtaste en pinkode, når du skifter profiler."</string>
<string name="kg_prompt_reason_switch_profiles_password" msgid="6755997057852042672">"Du skal indtaste en adgangskode, når du skifter profiler."</string>
diff --git a/packages/Keyguard/res/values-de/strings.xml b/packages/Keyguard/res/values-de/strings.xml
index 72aa72b..737f533 100644
--- a/packages/Keyguard/res/values-de/strings.xml
+++ b/packages/Keyguard/res/values-de/strings.xml
@@ -31,6 +31,8 @@
<string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"Falscher PIN-Code"</string>
<string name="keyguard_charged" msgid="3272223906073492454">"Aufgeladen"</string>
<string name="keyguard_plugged_in" msgid="9087497435553252863">"Wird aufgeladen"</string>
+ <string name="keyguard_plugged_in_charging_fast" msgid="6671162730167305479">"Schnelles Aufladen"</string>
+ <string name="keyguard_plugged_in_charging_slowly" msgid="1964714661071163229">"Langsames Aufladen"</string>
<string name="keyguard_low_battery" msgid="8143808018719173859">"Bitte Ladegerät anschließen"</string>
<string name="keyguard_instructions_when_pattern_disabled" msgid="1332288268600329841">"Zum Entsperren die Menütaste drücken"</string>
<string name="keyguard_network_locked_message" msgid="9169717779058037168">"Netzwerk gesperrt"</string>
@@ -111,6 +113,9 @@
<string name="kg_prompt_reason_restart_pattern" msgid="489430505491862444">"Beim Neustart des Geräts ist die Eingabe des Musters erforderlich."</string>
<string name="kg_prompt_reason_restart_pin" msgid="994878216570694974">"Beim Neustart des Geräts ist die Eingabe der PIN erforderlich."</string>
<string name="kg_prompt_reason_restart_password" msgid="2375742919528461664">"Beim Neustart des Geräts ist die Eingabe des Passworts erforderlich."</string>
+ <string name="kg_prompt_reason_timeout_pattern" msgid="8930047492617900785">"Zur Verbesserung der Sicherheit ist ein Muster erforderlich."</string>
+ <string name="kg_prompt_reason_timeout_pin" msgid="7470468607947726377">"Zur Verbesserung der Sicherheit ist eine PIN erforderlich."</string>
+ <string name="kg_prompt_reason_timeout_password" msgid="1177412542773936957">"Zur Verbesserung der Sicherheit ist ein Passwort erforderlich."</string>
<string name="kg_prompt_reason_switch_profiles_pattern" msgid="3802056699323773969">"Beim Profilwechsel ist die Eingabe des Musters erforderlich."</string>
<string name="kg_prompt_reason_switch_profiles_pin" msgid="8108020184731052246">"Beim Profilwechsel ist die Eingabe der PIN erforderlich."</string>
<string name="kg_prompt_reason_switch_profiles_password" msgid="6755997057852042672">"Beim Profilwechsel ist die Eingabe des Passworts erforderlich."</string>
diff --git a/packages/Keyguard/res/values-el/strings.xml b/packages/Keyguard/res/values-el/strings.xml
index 8c38901..b915275 100644
--- a/packages/Keyguard/res/values-el/strings.xml
+++ b/packages/Keyguard/res/values-el/strings.xml
@@ -31,6 +31,8 @@
<string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"Λανθασμένος κωδικός PIN."</string>
<string name="keyguard_charged" msgid="3272223906073492454">"Φορτίστηκε"</string>
<string name="keyguard_plugged_in" msgid="9087497435553252863">"Φόρτιση"</string>
+ <string name="keyguard_plugged_in_charging_fast" msgid="6671162730167305479">"Ταχύτατη φόρτιση"</string>
+ <string name="keyguard_plugged_in_charging_slowly" msgid="1964714661071163229">"Αργή φόρτιση"</string>
<string name="keyguard_low_battery" msgid="8143808018719173859">"Συνδέστε τον φορτιστή."</string>
<string name="keyguard_instructions_when_pattern_disabled" msgid="1332288268600329841">"Πατήστε \"Μενού\" για ξεκλείδωμα."</string>
<string name="keyguard_network_locked_message" msgid="9169717779058037168">"Το δίκτυο κλειδώθηκε"</string>
@@ -111,6 +113,9 @@
<string name="kg_prompt_reason_restart_pattern" msgid="489430505491862444">"Απαιτείται μοτίβο κατά την επανεκκίνηση της συσκευής."</string>
<string name="kg_prompt_reason_restart_pin" msgid="994878216570694974">"Απαιτείται PIN κατά την επανεκκίνηση της συσκευής."</string>
<string name="kg_prompt_reason_restart_password" msgid="2375742919528461664">"Απαιτείται κωδικός πρόσβασης κατά την επανεκκίνηση της συσκευής."</string>
+ <string name="kg_prompt_reason_timeout_pattern" msgid="8930047492617900785">"Απαιτείται μοτίβο για πρόσθετη ασφάλεια."</string>
+ <string name="kg_prompt_reason_timeout_pin" msgid="7470468607947726377">"Απαιτείται PIN για πρόσθετη ασφάλεια."</string>
+ <string name="kg_prompt_reason_timeout_password" msgid="1177412542773936957">"Απαιτείται κωδικός πρόσβασης για πρόσθετη ασφάλεια."</string>
<string name="kg_prompt_reason_switch_profiles_pattern" msgid="3802056699323773969">"Απαιτείται μοτίβο κατά την εναλλαγή προφίλ."</string>
<string name="kg_prompt_reason_switch_profiles_pin" msgid="8108020184731052246">"Απαιτείται PIN κατά την εναλλαγή προφίλ."</string>
<string name="kg_prompt_reason_switch_profiles_password" msgid="6755997057852042672">"Απαιτείται κωδικός πρόσβασης κατά την εναλλαγή προφίλ."</string>
diff --git a/packages/Keyguard/res/values-en-rAU/strings.xml b/packages/Keyguard/res/values-en-rAU/strings.xml
index 9fbc9ee..0979d9a 100644
--- a/packages/Keyguard/res/values-en-rAU/strings.xml
+++ b/packages/Keyguard/res/values-en-rAU/strings.xml
@@ -31,6 +31,8 @@
<string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"Incorrect PIN code."</string>
<string name="keyguard_charged" msgid="3272223906073492454">"Charged"</string>
<string name="keyguard_plugged_in" msgid="9087497435553252863">"Charging"</string>
+ <string name="keyguard_plugged_in_charging_fast" msgid="6671162730167305479">"Charging rapidly"</string>
+ <string name="keyguard_plugged_in_charging_slowly" msgid="1964714661071163229">"Charging slowly"</string>
<string name="keyguard_low_battery" msgid="8143808018719173859">"Connect your charger."</string>
<string name="keyguard_instructions_when_pattern_disabled" msgid="1332288268600329841">"Press Menu to unlock."</string>
<string name="keyguard_network_locked_message" msgid="9169717779058037168">"Network locked"</string>
@@ -111,6 +113,9 @@
<string name="kg_prompt_reason_restart_pattern" msgid="489430505491862444">"Pattern required when you restart device."</string>
<string name="kg_prompt_reason_restart_pin" msgid="994878216570694974">"PIN required when you restart device."</string>
<string name="kg_prompt_reason_restart_password" msgid="2375742919528461664">"Password required when you restart device."</string>
+ <string name="kg_prompt_reason_timeout_pattern" msgid="8930047492617900785">"Pattern required for additional security."</string>
+ <string name="kg_prompt_reason_timeout_pin" msgid="7470468607947726377">"PIN required for additional security."</string>
+ <string name="kg_prompt_reason_timeout_password" msgid="1177412542773936957">"Password required for additional security."</string>
<string name="kg_prompt_reason_switch_profiles_pattern" msgid="3802056699323773969">"Pattern required when you switch profiles."</string>
<string name="kg_prompt_reason_switch_profiles_pin" msgid="8108020184731052246">"PIN required when you switch profiles."</string>
<string name="kg_prompt_reason_switch_profiles_password" msgid="6755997057852042672">"Password required when you switch profiles."</string>
diff --git a/packages/Keyguard/res/values-en-rGB/strings.xml b/packages/Keyguard/res/values-en-rGB/strings.xml
index 9fbc9ee..0979d9a 100644
--- a/packages/Keyguard/res/values-en-rGB/strings.xml
+++ b/packages/Keyguard/res/values-en-rGB/strings.xml
@@ -31,6 +31,8 @@
<string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"Incorrect PIN code."</string>
<string name="keyguard_charged" msgid="3272223906073492454">"Charged"</string>
<string name="keyguard_plugged_in" msgid="9087497435553252863">"Charging"</string>
+ <string name="keyguard_plugged_in_charging_fast" msgid="6671162730167305479">"Charging rapidly"</string>
+ <string name="keyguard_plugged_in_charging_slowly" msgid="1964714661071163229">"Charging slowly"</string>
<string name="keyguard_low_battery" msgid="8143808018719173859">"Connect your charger."</string>
<string name="keyguard_instructions_when_pattern_disabled" msgid="1332288268600329841">"Press Menu to unlock."</string>
<string name="keyguard_network_locked_message" msgid="9169717779058037168">"Network locked"</string>
@@ -111,6 +113,9 @@
<string name="kg_prompt_reason_restart_pattern" msgid="489430505491862444">"Pattern required when you restart device."</string>
<string name="kg_prompt_reason_restart_pin" msgid="994878216570694974">"PIN required when you restart device."</string>
<string name="kg_prompt_reason_restart_password" msgid="2375742919528461664">"Password required when you restart device."</string>
+ <string name="kg_prompt_reason_timeout_pattern" msgid="8930047492617900785">"Pattern required for additional security."</string>
+ <string name="kg_prompt_reason_timeout_pin" msgid="7470468607947726377">"PIN required for additional security."</string>
+ <string name="kg_prompt_reason_timeout_password" msgid="1177412542773936957">"Password required for additional security."</string>
<string name="kg_prompt_reason_switch_profiles_pattern" msgid="3802056699323773969">"Pattern required when you switch profiles."</string>
<string name="kg_prompt_reason_switch_profiles_pin" msgid="8108020184731052246">"PIN required when you switch profiles."</string>
<string name="kg_prompt_reason_switch_profiles_password" msgid="6755997057852042672">"Password required when you switch profiles."</string>
diff --git a/packages/Keyguard/res/values-en-rIN/strings.xml b/packages/Keyguard/res/values-en-rIN/strings.xml
index 9fbc9ee..0979d9a 100644
--- a/packages/Keyguard/res/values-en-rIN/strings.xml
+++ b/packages/Keyguard/res/values-en-rIN/strings.xml
@@ -31,6 +31,8 @@
<string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"Incorrect PIN code."</string>
<string name="keyguard_charged" msgid="3272223906073492454">"Charged"</string>
<string name="keyguard_plugged_in" msgid="9087497435553252863">"Charging"</string>
+ <string name="keyguard_plugged_in_charging_fast" msgid="6671162730167305479">"Charging rapidly"</string>
+ <string name="keyguard_plugged_in_charging_slowly" msgid="1964714661071163229">"Charging slowly"</string>
<string name="keyguard_low_battery" msgid="8143808018719173859">"Connect your charger."</string>
<string name="keyguard_instructions_when_pattern_disabled" msgid="1332288268600329841">"Press Menu to unlock."</string>
<string name="keyguard_network_locked_message" msgid="9169717779058037168">"Network locked"</string>
@@ -111,6 +113,9 @@
<string name="kg_prompt_reason_restart_pattern" msgid="489430505491862444">"Pattern required when you restart device."</string>
<string name="kg_prompt_reason_restart_pin" msgid="994878216570694974">"PIN required when you restart device."</string>
<string name="kg_prompt_reason_restart_password" msgid="2375742919528461664">"Password required when you restart device."</string>
+ <string name="kg_prompt_reason_timeout_pattern" msgid="8930047492617900785">"Pattern required for additional security."</string>
+ <string name="kg_prompt_reason_timeout_pin" msgid="7470468607947726377">"PIN required for additional security."</string>
+ <string name="kg_prompt_reason_timeout_password" msgid="1177412542773936957">"Password required for additional security."</string>
<string name="kg_prompt_reason_switch_profiles_pattern" msgid="3802056699323773969">"Pattern required when you switch profiles."</string>
<string name="kg_prompt_reason_switch_profiles_pin" msgid="8108020184731052246">"PIN required when you switch profiles."</string>
<string name="kg_prompt_reason_switch_profiles_password" msgid="6755997057852042672">"Password required when you switch profiles."</string>
diff --git a/packages/Keyguard/res/values-es-rUS/strings.xml b/packages/Keyguard/res/values-es-rUS/strings.xml
index 63b9a9a..0becc66 100644
--- a/packages/Keyguard/res/values-es-rUS/strings.xml
+++ b/packages/Keyguard/res/values-es-rUS/strings.xml
@@ -31,6 +31,8 @@
<string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"Código PIN incorrecto"</string>
<string name="keyguard_charged" msgid="3272223906073492454">"Cargada"</string>
<string name="keyguard_plugged_in" msgid="9087497435553252863">"Cargando"</string>
+ <string name="keyguard_plugged_in_charging_fast" msgid="6671162730167305479">"Carga rápida"</string>
+ <string name="keyguard_plugged_in_charging_slowly" msgid="1964714661071163229">"Carga lenta"</string>
<string name="keyguard_low_battery" msgid="8143808018719173859">"Conecta tu cargador."</string>
<string name="keyguard_instructions_when_pattern_disabled" msgid="1332288268600329841">"Presiona Menú para desbloquear."</string>
<string name="keyguard_network_locked_message" msgid="9169717779058037168">"Bloqueada para la red"</string>
@@ -111,6 +113,9 @@
<string name="kg_prompt_reason_restart_pattern" msgid="489430505491862444">"Se solicita el patrón al reiniciar el dispositivo."</string>
<string name="kg_prompt_reason_restart_pin" msgid="994878216570694974">"Se solicita el PIN al reiniciar el dispositivo."</string>
<string name="kg_prompt_reason_restart_password" msgid="2375742919528461664">"Se solicita la contraseña al reiniciar el dispositivo."</string>
+ <string name="kg_prompt_reason_timeout_pattern" msgid="8930047492617900785">"Por razones de seguridad, debe resolverse el patrón."</string>
+ <string name="kg_prompt_reason_timeout_pin" msgid="7470468607947726377">"Por razones de seguridad, escribe el PIN."</string>
+ <string name="kg_prompt_reason_timeout_password" msgid="1177412542773936957">"Por razones de seguridad, ingresa la contraseña."</string>
<string name="kg_prompt_reason_switch_profiles_pattern" msgid="3802056699323773969">"Se solicita el patrón al cambiar de perfil."</string>
<string name="kg_prompt_reason_switch_profiles_pin" msgid="8108020184731052246">"Se solicita el PIN al cambiar de perfil."</string>
<string name="kg_prompt_reason_switch_profiles_password" msgid="6755997057852042672">"Se solicita la contraseña al cambiar de perfil."</string>
diff --git a/packages/Keyguard/res/values-es/strings.xml b/packages/Keyguard/res/values-es/strings.xml
index d7be26f..6f37d8b 100644
--- a/packages/Keyguard/res/values-es/strings.xml
+++ b/packages/Keyguard/res/values-es/strings.xml
@@ -31,6 +31,8 @@
<string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"Código PIN incorrecto"</string>
<string name="keyguard_charged" msgid="3272223906073492454">"Cargado"</string>
<string name="keyguard_plugged_in" msgid="9087497435553252863">"Cargando"</string>
+ <string name="keyguard_plugged_in_charging_fast" msgid="6671162730167305479">"Cargando rápidamente"</string>
+ <string name="keyguard_plugged_in_charging_slowly" msgid="1964714661071163229">"Cargando lentamente"</string>
<string name="keyguard_low_battery" msgid="8143808018719173859">"Conecta el cargador."</string>
<string name="keyguard_instructions_when_pattern_disabled" msgid="1332288268600329841">"Ve al menú para desbloquear la pantalla."</string>
<string name="keyguard_network_locked_message" msgid="9169717779058037168">"Bloqueada para la red"</string>
@@ -111,6 +113,9 @@
<string name="kg_prompt_reason_restart_pattern" msgid="489430505491862444">"Se debe introducir el patrón cuando se reinicia el dispositivo."</string>
<string name="kg_prompt_reason_restart_pin" msgid="994878216570694974">"Se debe introducir el PIN cuando se reinicia el dispositivo."</string>
<string name="kg_prompt_reason_restart_password" msgid="2375742919528461664">"Se debe introducir la contraseña cuando se reinicia el dispositivo."</string>
+ <string name="kg_prompt_reason_timeout_pattern" msgid="8930047492617900785">"Es necesario introducir el patrón como medida de seguridad adicional."</string>
+ <string name="kg_prompt_reason_timeout_pin" msgid="7470468607947726377">"Es necesario introducir el PIN como medida de seguridad adicional."</string>
+ <string name="kg_prompt_reason_timeout_password" msgid="1177412542773936957">"Es necesario introducir la contraseña como medida de seguridad adicional."</string>
<string name="kg_prompt_reason_switch_profiles_pattern" msgid="3802056699323773969">"Se debe introducir el patrón cuando se cambia de perfil."</string>
<string name="kg_prompt_reason_switch_profiles_pin" msgid="8108020184731052246">"Se debe introducir el PIN cuando se cambia de perfil."</string>
<string name="kg_prompt_reason_switch_profiles_password" msgid="6755997057852042672">"Se debe introducir la contraseña cuando se cambia de perfil."</string>
diff --git a/packages/Keyguard/res/values-et-rEE/strings.xml b/packages/Keyguard/res/values-et-rEE/strings.xml
index 10dd3f4..89ffbde 100644
--- a/packages/Keyguard/res/values-et-rEE/strings.xml
+++ b/packages/Keyguard/res/values-et-rEE/strings.xml
@@ -31,6 +31,8 @@
<string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"Vale PIN-kood."</string>
<string name="keyguard_charged" msgid="3272223906073492454">"Laetud"</string>
<string name="keyguard_plugged_in" msgid="9087497435553252863">"Laadimine"</string>
+ <string name="keyguard_plugged_in_charging_fast" msgid="6671162730167305479">"Kiiresti laadimine"</string>
+ <string name="keyguard_plugged_in_charging_slowly" msgid="1964714661071163229">"Aeglaselt laadimine"</string>
<string name="keyguard_low_battery" msgid="8143808018719173859">"Ühendage laadija."</string>
<string name="keyguard_instructions_when_pattern_disabled" msgid="1332288268600329841">"Avamiseks vajutage menüüklahvi."</string>
<string name="keyguard_network_locked_message" msgid="9169717779058037168">"Võrk on suletud"</string>
@@ -111,6 +113,9 @@
<string name="kg_prompt_reason_restart_pattern" msgid="489430505491862444">"Seadme taaskäivitamisel on vaja mustrit."</string>
<string name="kg_prompt_reason_restart_pin" msgid="994878216570694974">"Seadme taaskäivitamisel on vaja PIN-koodi."</string>
<string name="kg_prompt_reason_restart_password" msgid="2375742919528461664">"Seadme taaskäivitamisel on vaja parooli."</string>
+ <string name="kg_prompt_reason_timeout_pattern" msgid="8930047492617900785">"Täiendava turvalisuse huvides on vaja sisestada muster."</string>
+ <string name="kg_prompt_reason_timeout_pin" msgid="7470468607947726377">"Täiendava turvalisuse huvides on vaja sisestada PIN-kood."</string>
+ <string name="kg_prompt_reason_timeout_password" msgid="1177412542773936957">"Täiendava turvalisuse huvides on vaja sisestada parool."</string>
<string name="kg_prompt_reason_switch_profiles_pattern" msgid="3802056699323773969">"Profiilide vahetamisel on vaja mustrit."</string>
<string name="kg_prompt_reason_switch_profiles_pin" msgid="8108020184731052246">"Profiilide vahetamisel on vaja PIN-koodi."</string>
<string name="kg_prompt_reason_switch_profiles_password" msgid="6755997057852042672">"Profiilide vahetamisel on vaja parooli."</string>
diff --git a/packages/Keyguard/res/values-eu-rES/strings.xml b/packages/Keyguard/res/values-eu-rES/strings.xml
index d51add6..3a740f6 100644
--- a/packages/Keyguard/res/values-eu-rES/strings.xml
+++ b/packages/Keyguard/res/values-eu-rES/strings.xml
@@ -31,6 +31,8 @@
<string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"PIN kode okerra."</string>
<string name="keyguard_charged" msgid="3272223906073492454">"Kargatuta"</string>
<string name="keyguard_plugged_in" msgid="9087497435553252863">"Kargatzen"</string>
+ <string name="keyguard_plugged_in_charging_fast" msgid="6671162730167305479">"Bizkor kargatzen"</string>
+ <string name="keyguard_plugged_in_charging_slowly" msgid="1964714661071163229">"Motel kargatzen"</string>
<string name="keyguard_low_battery" msgid="8143808018719173859">"Konektatu kargagailura."</string>
<string name="keyguard_instructions_when_pattern_disabled" msgid="1332288268600329841">"Desblokeatzeko, sakatu Menua."</string>
<string name="keyguard_network_locked_message" msgid="9169717779058037168">"Sarea blokeatuta"</string>
@@ -111,6 +113,9 @@
<string name="kg_prompt_reason_restart_pattern" msgid="489430505491862444">"Gailua berrabiarazi duzunez, eredua marraztu behar duzu."</string>
<string name="kg_prompt_reason_restart_pin" msgid="994878216570694974">"Gailua berrabiarazi duzunez, PIN kodea idatzi behar duzu."</string>
<string name="kg_prompt_reason_restart_password" msgid="2375742919528461664">"Gailua berrabiarazi duzunez, pasahitza idatzi behar duzu."</string>
+ <string name="kg_prompt_reason_timeout_pattern" msgid="8930047492617900785">"Segurtasun handiagoa izateko, eredua behar da."</string>
+ <string name="kg_prompt_reason_timeout_pin" msgid="7470468607947726377">"Segurtasun handiagoa izateko, PIN kodea behar da."</string>
+ <string name="kg_prompt_reason_timeout_password" msgid="1177412542773936957">"Segurtasun handiagoa izateko, pasahitza behar da."</string>
<string name="kg_prompt_reason_switch_profiles_pattern" msgid="3802056699323773969">"Profilez aldatu duzunez, eredua marraztu behar duzu."</string>
<string name="kg_prompt_reason_switch_profiles_pin" msgid="8108020184731052246">"Profilez aldatu duzunez, PIN kodea idatzi behar duzu."</string>
<string name="kg_prompt_reason_switch_profiles_password" msgid="6755997057852042672">"Profilez aldatu duzunez, pasahitza idatzi behar duzu."</string>
diff --git a/packages/Keyguard/res/values-fa/strings.xml b/packages/Keyguard/res/values-fa/strings.xml
index 7f516a7..975fe7f 100644
--- a/packages/Keyguard/res/values-fa/strings.xml
+++ b/packages/Keyguard/res/values-fa/strings.xml
@@ -31,6 +31,8 @@
<string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"پین کد اشتباه است."</string>
<string name="keyguard_charged" msgid="3272223906073492454">"شارژ شد"</string>
<string name="keyguard_plugged_in" msgid="9087497435553252863">"در حال شارژ شدن"</string>
+ <string name="keyguard_plugged_in_charging_fast" msgid="6671162730167305479">"شارژ سریع"</string>
+ <string name="keyguard_plugged_in_charging_slowly" msgid="1964714661071163229">"شارژ آهسته"</string>
<string name="keyguard_low_battery" msgid="8143808018719173859">"شارژر خود را وصل کنید."</string>
<string name="keyguard_instructions_when_pattern_disabled" msgid="1332288268600329841">"برای بازگشایی قفل روی منو فشار دهید."</string>
<string name="keyguard_network_locked_message" msgid="9169717779058037168">"شبکه قفل شد"</string>
@@ -40,7 +42,7 @@
<string name="keyguard_missing_sim_instructions" msgid="5210891509995942250">"سیم کارت را وارد کنید."</string>
<string name="keyguard_missing_sim_instructions_long" msgid="5968985489463870358">"سیم کارت موجود نیست یا قابل خواندن نیست. یک سیم کارت وارد کنید."</string>
<string name="keyguard_permanent_disabled_sim_message_short" msgid="8340813989586622356">"سیم کارت غیرقابل استفاده است."</string>
- <string name="keyguard_permanent_disabled_sim_instructions" msgid="5892940909699723544">"سیم کارت شما به طور دائم غیر فعال شده است. \nبرای داشتن سیم کارت دیگر با ارائهدهنده سرویس بیسیم خود تماس بگیرید."</string>
+ <string name="keyguard_permanent_disabled_sim_instructions" msgid="5892940909699723544">"سیم کارت شما بهطور دائم غیر فعال شده است. \nبرای داشتن سیم کارت دیگر با ارائهدهنده سرویس بیسیم خود تماس بگیرید."</string>
<string name="keyguard_sim_locked_message" msgid="6875773413306380902">"سیم کارت قفل شد."</string>
<string name="keyguard_sim_puk_locked_message" msgid="3747232467471801633">"سیم کارت با PUK قفل شده است."</string>
<string name="keyguard_sim_unlock_progress_dialog_message" msgid="7975221805033614426">"درحال بازگشایی قفل سیم کارت..."</string>
@@ -111,6 +113,9 @@
<string name="kg_prompt_reason_restart_pattern" msgid="489430505491862444">"هنگامی که دستگاه را راهاندازی مجدد میکنید الگو درخواست میشود."</string>
<string name="kg_prompt_reason_restart_pin" msgid="994878216570694974">"هنگامی که دستگاه را راهاندازی مجدد میکنید پین درخواست میشود."</string>
<string name="kg_prompt_reason_restart_password" msgid="2375742919528461664">"هنگامی که دستگاه را راهاندازی مجدد میکنید گذرواژه درخواست میشود."</string>
+ <string name="kg_prompt_reason_timeout_pattern" msgid="8930047492617900785">"برای ایمنی بیشتر به الگو نیاز است."</string>
+ <string name="kg_prompt_reason_timeout_pin" msgid="7470468607947726377">"برای ایمنی بیشتر به پین نیاز است."</string>
+ <string name="kg_prompt_reason_timeout_password" msgid="1177412542773936957">"برای ایمنی بیشتر به گذرواژه نیاز است."</string>
<string name="kg_prompt_reason_switch_profiles_pattern" msgid="3802056699323773969">"هنگامی که میان نمایهها جابجا میشوید، الگو درخواست میشود."</string>
<string name="kg_prompt_reason_switch_profiles_pin" msgid="8108020184731052246">"هنگامی که میان نمایهها جابجا میشوید، پین درخواست میشود."</string>
<string name="kg_prompt_reason_switch_profiles_password" msgid="6755997057852042672">"هنگامی که میان نمایهها جابجا میشوید، گذرواژه درخواست میشود."</string>
diff --git a/packages/Keyguard/res/values-fi/strings.xml b/packages/Keyguard/res/values-fi/strings.xml
index 6264e5d..94c8d62 100644
--- a/packages/Keyguard/res/values-fi/strings.xml
+++ b/packages/Keyguard/res/values-fi/strings.xml
@@ -31,6 +31,8 @@
<string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"PIN-koodi väärin."</string>
<string name="keyguard_charged" msgid="3272223906073492454">"Täynnä"</string>
<string name="keyguard_plugged_in" msgid="9087497435553252863">"Ladataan"</string>
+ <string name="keyguard_plugged_in_charging_fast" msgid="6671162730167305479">"Nopea lataus"</string>
+ <string name="keyguard_plugged_in_charging_slowly" msgid="1964714661071163229">"Hidas lataus"</string>
<string name="keyguard_low_battery" msgid="8143808018719173859">"Kytke laturi."</string>
<string name="keyguard_instructions_when_pattern_disabled" msgid="1332288268600329841">"Poista lukitus painamalla Valikko-painiketta."</string>
<string name="keyguard_network_locked_message" msgid="9169717779058037168">"Verkko lukittu"</string>
@@ -111,6 +113,9 @@
<string name="kg_prompt_reason_restart_pattern" msgid="489430505491862444">"Kuvio vaaditaan laitteen uudelleenkäynnistyksen yhteydessä."</string>
<string name="kg_prompt_reason_restart_pin" msgid="994878216570694974">"PIN-koodi vaaditaan laitteen uudelleenkäynnistyksen yhteydessä."</string>
<string name="kg_prompt_reason_restart_password" msgid="2375742919528461664">"Salasana vaaditaan laitteen uudelleenkäynnistyksen yhteydessä."</string>
+ <string name="kg_prompt_reason_timeout_pattern" msgid="8930047492617900785">"Kuvio parantaa suojaustasi."</string>
+ <string name="kg_prompt_reason_timeout_pin" msgid="7470468607947726377">"PIN-koodi parantaa suojaustasi."</string>
+ <string name="kg_prompt_reason_timeout_password" msgid="1177412542773936957">"Salasana parantaa suojaustasi."</string>
<string name="kg_prompt_reason_switch_profiles_pattern" msgid="3802056699323773969">"Kuvio vaaditaan profiilia vaihdettaessa."</string>
<string name="kg_prompt_reason_switch_profiles_pin" msgid="8108020184731052246">"PIN-koodi vaaditaan profiilia vaihdettaessa."</string>
<string name="kg_prompt_reason_switch_profiles_password" msgid="6755997057852042672">"Salasana vaaditaan profiilia vaihdettaessa."</string>
diff --git a/packages/Keyguard/res/values-fr-rCA/strings.xml b/packages/Keyguard/res/values-fr-rCA/strings.xml
index 6263583..c8afb91 100644
--- a/packages/Keyguard/res/values-fr-rCA/strings.xml
+++ b/packages/Keyguard/res/values-fr-rCA/strings.xml
@@ -31,6 +31,8 @@
<string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"NIP erroné."</string>
<string name="keyguard_charged" msgid="3272223906073492454">"Chargé"</string>
<string name="keyguard_plugged_in" msgid="9087497435553252863">"Charge en cours..."</string>
+ <string name="keyguard_plugged_in_charging_fast" msgid="6671162730167305479">"Charge rapide"</string>
+ <string name="keyguard_plugged_in_charging_slowly" msgid="1964714661071163229">"Charge lente"</string>
<string name="keyguard_low_battery" msgid="8143808018719173859">"Branchez votre chargeur."</string>
<string name="keyguard_instructions_when_pattern_disabled" msgid="1332288268600329841">"Appuyez sur \"Menu\" pour déverrouiller l\'appareil."</string>
<string name="keyguard_network_locked_message" msgid="9169717779058037168">"Réseau verrouillé"</string>
@@ -111,6 +113,9 @@
<string name="kg_prompt_reason_restart_pattern" msgid="489430505491862444">"Veuillez entrer le motif au redémarrage de l\'appareil."</string>
<string name="kg_prompt_reason_restart_pin" msgid="994878216570694974">"Veuillez entrer le NIP au redémarrage de l\'appareil."</string>
<string name="kg_prompt_reason_restart_password" msgid="2375742919528461664">"Veuillez entrer le mot de passe au redémarrage de l\'appareil."</string>
+ <string name="kg_prompt_reason_timeout_pattern" msgid="8930047492617900785">"Motif requis pour plus de sécurité."</string>
+ <string name="kg_prompt_reason_timeout_pin" msgid="7470468607947726377">"NIP requis pour plus de sécurité."</string>
+ <string name="kg_prompt_reason_timeout_password" msgid="1177412542773936957">"Mot de passe requis pour plus de sécurité."</string>
<string name="kg_prompt_reason_switch_profiles_pattern" msgid="3802056699323773969">"Veuillez tracer le motif lorsque vous changez de profil."</string>
<string name="kg_prompt_reason_switch_profiles_pin" msgid="8108020184731052246">"Veuillez entrer le NIP lorsque vous changez de profil."</string>
<string name="kg_prompt_reason_switch_profiles_password" msgid="6755997057852042672">"Veuillez entrer le mot de passe lorsque vous changez de profil."</string>
diff --git a/packages/Keyguard/res/values-fr/strings.xml b/packages/Keyguard/res/values-fr/strings.xml
index 6581006..afefc9a 100644
--- a/packages/Keyguard/res/values-fr/strings.xml
+++ b/packages/Keyguard/res/values-fr/strings.xml
@@ -31,6 +31,8 @@
<string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"Le code PIN est erroné."</string>
<string name="keyguard_charged" msgid="3272223906073492454">"Chargé"</string>
<string name="keyguard_plugged_in" msgid="9087497435553252863">"Batterie en charge…"</string>
+ <string name="keyguard_plugged_in_charging_fast" msgid="6671162730167305479">"Rechargement rapide en cours…"</string>
+ <string name="keyguard_plugged_in_charging_slowly" msgid="1964714661071163229">"Rechargement lent en cours…"</string>
<string name="keyguard_low_battery" msgid="8143808018719173859">"Branchez votre chargeur."</string>
<string name="keyguard_instructions_when_pattern_disabled" msgid="1332288268600329841">"Appuyez sur \"Menu\" pour déverrouiller l\'appareil."</string>
<string name="keyguard_network_locked_message" msgid="9169717779058037168">"Réseau verrouillé"</string>
@@ -108,15 +110,18 @@
<string name="keyguard_carrier_default" msgid="8700650403054042153">"Aucun service"</string>
<string name="accessibility_ime_switch_button" msgid="5032926134740456424">"Bouton \"Changer le mode de saisie\""</string>
<string name="airplane_mode" msgid="3122107900897202805">"Mode Avion"</string>
- <string name="kg_prompt_reason_restart_pattern" msgid="489430505491862444">"Veuillez saisir le motif au redémarrage de l\'appareil."</string>
+ <string name="kg_prompt_reason_restart_pattern" msgid="489430505491862444">"Veuillez saisir le schéma au redémarrage de l\'appareil."</string>
<string name="kg_prompt_reason_restart_pin" msgid="994878216570694974">"Veuillez saisir le code d\'accès au redémarrage de l\'appareil."</string>
<string name="kg_prompt_reason_restart_password" msgid="2375742919528461664">"Veuillez saisir le mot de passe au redémarrage de l\'appareil."</string>
- <string name="kg_prompt_reason_switch_profiles_pattern" msgid="3802056699323773969">"Veuillez saisir le motif lorsque vous changez de profil."</string>
+ <string name="kg_prompt_reason_timeout_pattern" msgid="8930047492617900785">"Veuillez saisir le schéma pour renforcer la sécurité."</string>
+ <string name="kg_prompt_reason_timeout_pin" msgid="7470468607947726377">"Veuillez saisir le code d\'accès pour renforcer la sécurité."</string>
+ <string name="kg_prompt_reason_timeout_password" msgid="1177412542773936957">"Veuillez saisir le mot de passe pour renforcer la sécurité."</string>
+ <string name="kg_prompt_reason_switch_profiles_pattern" msgid="3802056699323773969">"Veuillez saisir le schéma lorsque vous changez de profil."</string>
<string name="kg_prompt_reason_switch_profiles_pin" msgid="8108020184731052246">"Veuillez saisir le code d\'accès lorsque vous changez de profil."</string>
<string name="kg_prompt_reason_switch_profiles_password" msgid="6755997057852042672">"Veuillez saisir le mot de passe lorsque vous changez de profil."</string>
<plurals name="kg_prompt_reason_time_pattern" formatted="false" msgid="2697444392228541853">
- <item quantity="one">L\'appareil n\'a pas été déverrouillé depuis <xliff:g id="NUMBER_1">%d</xliff:g> heure. Confirmez le motif.</item>
- <item quantity="other">L\'appareil n\'a pas été déverrouillé depuis <xliff:g id="NUMBER_1">%d</xliff:g> heures. Confirmez le motif.</item>
+ <item quantity="one">L\'appareil n\'a pas été déverrouillé depuis <xliff:g id="NUMBER_1">%d</xliff:g> heure. Confirmez le schéma.</item>
+ <item quantity="other">L\'appareil n\'a pas été déverrouillé depuis <xliff:g id="NUMBER_1">%d</xliff:g> heures. Confirmez le schéma.</item>
</plurals>
<plurals name="kg_prompt_reason_time_pin" formatted="false" msgid="2118758475374354849">
<item quantity="one">L\'appareil n\'a pas été déverrouillé depuis <xliff:g id="NUMBER_1">%d</xliff:g> heure. Confirmez le code d\'accès.</item>
diff --git a/packages/Keyguard/res/values-gl-rES/strings.xml b/packages/Keyguard/res/values-gl-rES/strings.xml
index 62cf3f5..4713abf 100644
--- a/packages/Keyguard/res/values-gl-rES/strings.xml
+++ b/packages/Keyguard/res/values-gl-rES/strings.xml
@@ -31,6 +31,8 @@
<string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"Código PIN incorrecto"</string>
<string name="keyguard_charged" msgid="3272223906073492454">"Cargado"</string>
<string name="keyguard_plugged_in" msgid="9087497435553252863">"Cargando"</string>
+ <string name="keyguard_plugged_in_charging_fast" msgid="6671162730167305479">"Cargando rapidamente"</string>
+ <string name="keyguard_plugged_in_charging_slowly" msgid="1964714661071163229">"Cargando lentamente"</string>
<string name="keyguard_low_battery" msgid="8143808018719173859">"Conecta o cargador."</string>
<string name="keyguard_instructions_when_pattern_disabled" msgid="1332288268600329841">"Preme Menú para desbloquear."</string>
<string name="keyguard_network_locked_message" msgid="9169717779058037168">"Bloqueada pola rede"</string>
@@ -111,6 +113,9 @@
<string name="kg_prompt_reason_restart_pattern" msgid="489430505491862444">"É necesario o padrón para reiniciar o dispositivo."</string>
<string name="kg_prompt_reason_restart_pin" msgid="994878216570694974">"É necesario o PIN para reiniciar o dispositivo."</string>
<string name="kg_prompt_reason_restart_password" msgid="2375742919528461664">"É necesario o contrasinal para reiniciar o dispositivo."</string>
+ <string name="kg_prompt_reason_timeout_pattern" msgid="8930047492617900785">"Necesítase o padrón para obter seguranza adicional."</string>
+ <string name="kg_prompt_reason_timeout_pin" msgid="7470468607947726377">"Necesítase o PIN para obter seguranza adicional."</string>
+ <string name="kg_prompt_reason_timeout_password" msgid="1177412542773936957">"Necesítase o contrasinal para obter seguranza adicional."</string>
<string name="kg_prompt_reason_switch_profiles_pattern" msgid="3802056699323773969">"É necesario o padrón para cambiar os perfís."</string>
<string name="kg_prompt_reason_switch_profiles_pin" msgid="8108020184731052246">"É necesario o PIN para cambiar os perfís."</string>
<string name="kg_prompt_reason_switch_profiles_password" msgid="6755997057852042672">"É necesario o contrasinal para cambiar os perfís."</string>
diff --git a/packages/Keyguard/res/values-gu-rIN/strings.xml b/packages/Keyguard/res/values-gu-rIN/strings.xml
index 145c196..f74c8aa 100644
--- a/packages/Keyguard/res/values-gu-rIN/strings.xml
+++ b/packages/Keyguard/res/values-gu-rIN/strings.xml
@@ -31,6 +31,8 @@
<string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"ખોટો PIN કોડ."</string>
<string name="keyguard_charged" msgid="3272223906073492454">"ચાર્જ થયું"</string>
<string name="keyguard_plugged_in" msgid="9087497435553252863">"ચાર્જ થઈ રહ્યું છે"</string>
+ <string name="keyguard_plugged_in_charging_fast" msgid="6671162730167305479">"ઝડપથી ચાર્જિંગ થઇ રહી છે"</string>
+ <string name="keyguard_plugged_in_charging_slowly" msgid="1964714661071163229">"ધીમેથી ચાર્જિંગ થઇ રહી છે"</string>
<string name="keyguard_low_battery" msgid="8143808018719173859">"તમારું ચાર્જર કનેક્ટ કરો."</string>
<string name="keyguard_instructions_when_pattern_disabled" msgid="1332288268600329841">"અનલૉક કરવા માટે મેનૂ દબાવો."</string>
<string name="keyguard_network_locked_message" msgid="9169717779058037168">"નેટવર્ક લૉક થયું"</string>
@@ -111,6 +113,9 @@
<string name="kg_prompt_reason_restart_pattern" msgid="489430505491862444">"જ્યારે તમે ઉપકરણ ફરીથી સેટ કરો ત્યારે પેટર્ન જરૂરી છે."</string>
<string name="kg_prompt_reason_restart_pin" msgid="994878216570694974">"જ્યારે તમે ઉપકરણ ફરીથી સેટ કરો ત્યારે PIN જરૂરી છે."</string>
<string name="kg_prompt_reason_restart_password" msgid="2375742919528461664">"જ્યારે તમે ઉપકરણ ફરીથી સેટ કરો ત્યારે પાસવર્ડ જરૂરી છે."</string>
+ <string name="kg_prompt_reason_timeout_pattern" msgid="8930047492617900785">"વધારાની સુરક્ષા માટે પેટર્ન જરૂરી છે."</string>
+ <string name="kg_prompt_reason_timeout_pin" msgid="7470468607947726377">"વધારાની સુરક્ષા માટે PIN જરૂરી છે."</string>
+ <string name="kg_prompt_reason_timeout_password" msgid="1177412542773936957">"વધારાની સુરક્ષા માટે પાસવર્ડ જરૂરી છે."</string>
<string name="kg_prompt_reason_switch_profiles_pattern" msgid="3802056699323773969">"જ્યારે તમે પ્રોફાઇલ્સ સ્વિચ કરો ત્યારે પેટર્ન જરૂરી છે."</string>
<string name="kg_prompt_reason_switch_profiles_pin" msgid="8108020184731052246">"જ્યારે તમે પ્રોફાઇલ્સ સ્વિચ કરો ત્યારે PIN જરૂરી છે."</string>
<string name="kg_prompt_reason_switch_profiles_password" msgid="6755997057852042672">"જ્યારે તમે પ્રોફાઇલ્સ સ્વિચ કરો ત્યારે પાસવર્ડ જરૂરી છે."</string>
diff --git a/packages/Keyguard/res/values-hi/strings.xml b/packages/Keyguard/res/values-hi/strings.xml
index 2d455d0..612d16c 100644
--- a/packages/Keyguard/res/values-hi/strings.xml
+++ b/packages/Keyguard/res/values-hi/strings.xml
@@ -31,6 +31,8 @@
<string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"गलत पिन कोड."</string>
<string name="keyguard_charged" msgid="3272223906073492454">"चार्ज हो गई है"</string>
<string name="keyguard_plugged_in" msgid="9087497435553252863">"चार्ज हो रहा है"</string>
+ <string name="keyguard_plugged_in_charging_fast" msgid="6671162730167305479">"तेज़ी से चार्ज हो रही है"</string>
+ <string name="keyguard_plugged_in_charging_slowly" msgid="1964714661071163229">"धीमे चार्ज हो रही है"</string>
<string name="keyguard_low_battery" msgid="8143808018719173859">"अपना चार्जर कनेक्ट करें."</string>
<string name="keyguard_instructions_when_pattern_disabled" msgid="1332288268600329841">"अनलॉक करने के लिए मेनू दबाएं."</string>
<string name="keyguard_network_locked_message" msgid="9169717779058037168">"नेटवर्क लॉक किया गया"</string>
@@ -111,6 +113,9 @@
<string name="kg_prompt_reason_restart_pattern" msgid="489430505491862444">"डिवाइस को पुनः प्रारंभ करते समय पैटर्न की आवश्यकता होती है."</string>
<string name="kg_prompt_reason_restart_pin" msgid="994878216570694974">"डिवाइस को पुनः प्रारंभ करते समय पिन की आवश्यकता होती है."</string>
<string name="kg_prompt_reason_restart_password" msgid="2375742919528461664">"डिवाइस को पुनः प्रारंभ करते समय पासवर्ड की आवश्यकता होती है."</string>
+ <string name="kg_prompt_reason_timeout_pattern" msgid="8930047492617900785">"अतिरिक्त सुरक्षा के लिए पैटर्न आवश्यक है."</string>
+ <string name="kg_prompt_reason_timeout_pin" msgid="7470468607947726377">"अतिरिक्त सुरक्षा के लिए पिन आवश्यक है."</string>
+ <string name="kg_prompt_reason_timeout_password" msgid="1177412542773936957">"अतिरिक्त सुरक्षा के लिए पासवर्ड आवश्यक है."</string>
<string name="kg_prompt_reason_switch_profiles_pattern" msgid="3802056699323773969">"प्रोफ़ाइल में स्विच करते समय पैटर्न की आवश्यकता होती है."</string>
<string name="kg_prompt_reason_switch_profiles_pin" msgid="8108020184731052246">"प्रोफ़ाइल में स्विच करते समय पिन की आवश्यकता होती है."</string>
<string name="kg_prompt_reason_switch_profiles_password" msgid="6755997057852042672">"प्रोफ़ाइल में स्विच करते समय पासवर्ड की आवश्यकता होती है."</string>
diff --git a/packages/Keyguard/res/values-hr/strings.xml b/packages/Keyguard/res/values-hr/strings.xml
index 9d8786a..d77176b 100644
--- a/packages/Keyguard/res/values-hr/strings.xml
+++ b/packages/Keyguard/res/values-hr/strings.xml
@@ -31,6 +31,8 @@
<string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"Netočan PIN kôd."</string>
<string name="keyguard_charged" msgid="3272223906073492454">"Napunjeno"</string>
<string name="keyguard_plugged_in" msgid="9087497435553252863">"Punjenje"</string>
+ <string name="keyguard_plugged_in_charging_fast" msgid="6671162730167305479">"Brzo punjenje"</string>
+ <string name="keyguard_plugged_in_charging_slowly" msgid="1964714661071163229">"Sporo punjenje"</string>
<string name="keyguard_low_battery" msgid="8143808018719173859">"Priključite punjač."</string>
<string name="keyguard_instructions_when_pattern_disabled" msgid="1332288268600329841">"Pritisnite Izbornik za otključavanje."</string>
<string name="keyguard_network_locked_message" msgid="9169717779058037168">"Mreža je zaključana"</string>
@@ -113,6 +115,9 @@
<string name="kg_prompt_reason_restart_pattern" msgid="489430505491862444">"Za ponovno pokretanje uređaja morate unijeti uzorak."</string>
<string name="kg_prompt_reason_restart_pin" msgid="994878216570694974">"Za ponovno pokretanje uređaja morate unijeti PIN."</string>
<string name="kg_prompt_reason_restart_password" msgid="2375742919528461664">"Za ponovno pokretanje uređaja morate unijeti zaporku."</string>
+ <string name="kg_prompt_reason_timeout_pattern" msgid="8930047492617900785">"Unesite uzorak radi dodatne sigurnosti."</string>
+ <string name="kg_prompt_reason_timeout_pin" msgid="7470468607947726377">"Unesite PIN radi dodatne sigurnosti."</string>
+ <string name="kg_prompt_reason_timeout_password" msgid="1177412542773936957">"Unesite zaporku radi dodatne sigurnosti."</string>
<string name="kg_prompt_reason_switch_profiles_pattern" msgid="3802056699323773969">"Za promjenu profila morate unijeti uzorak."</string>
<string name="kg_prompt_reason_switch_profiles_pin" msgid="8108020184731052246">"Za promjenu profila morate unijeti PIN."</string>
<string name="kg_prompt_reason_switch_profiles_password" msgid="6755997057852042672">"Za promjenu profila morate unijeti zaporku."</string>
diff --git a/packages/Keyguard/res/values-hu/strings.xml b/packages/Keyguard/res/values-hu/strings.xml
index e10d197..6f8f189 100644
--- a/packages/Keyguard/res/values-hu/strings.xml
+++ b/packages/Keyguard/res/values-hu/strings.xml
@@ -31,6 +31,8 @@
<string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"Helytelen PIN kód."</string>
<string name="keyguard_charged" msgid="3272223906073492454">"Feltöltve"</string>
<string name="keyguard_plugged_in" msgid="9087497435553252863">"Töltés"</string>
+ <string name="keyguard_plugged_in_charging_fast" msgid="6671162730167305479">"Gyors töltés folyamatban"</string>
+ <string name="keyguard_plugged_in_charging_slowly" msgid="1964714661071163229">"Lassú töltés folyamatban"</string>
<string name="keyguard_low_battery" msgid="8143808018719173859">"Csatlakoztassa a töltőt."</string>
<string name="keyguard_instructions_when_pattern_disabled" msgid="1332288268600329841">"A feloldáshoz nyomja meg a Menü gombot."</string>
<string name="keyguard_network_locked_message" msgid="9169717779058037168">"A hálózat lezárva"</string>
@@ -111,6 +113,9 @@
<string name="kg_prompt_reason_restart_pattern" msgid="489430505491862444">"Ha újraindítja az eszközt, meg kell adnia a mintát."</string>
<string name="kg_prompt_reason_restart_pin" msgid="994878216570694974">"Ha újraindítja az eszközt, meg kell adnia a PIN kódot."</string>
<string name="kg_prompt_reason_restart_password" msgid="2375742919528461664">"Ha újraindítja az eszközt, meg kell adnia a jelszót."</string>
+ <string name="kg_prompt_reason_timeout_pattern" msgid="8930047492617900785">"Minta szükséges a nagyobb biztonság érdekében."</string>
+ <string name="kg_prompt_reason_timeout_pin" msgid="7470468607947726377">"PIN kód szükséges a nagyobb biztonság érdekében."</string>
+ <string name="kg_prompt_reason_timeout_password" msgid="1177412542773936957">"Jelszó szükséges a nagyobb biztonság érdekében."</string>
<string name="kg_prompt_reason_switch_profiles_pattern" msgid="3802056699323773969">"Ha vált a profilok között, meg kell adnia a mintát."</string>
<string name="kg_prompt_reason_switch_profiles_pin" msgid="8108020184731052246">"Ha vált a profilok között, meg kell adnia a PIN kódot."</string>
<string name="kg_prompt_reason_switch_profiles_password" msgid="6755997057852042672">"Ha vált a profilok között, meg kell adnia a jelszót."</string>
diff --git a/packages/Keyguard/res/values-hy-rAM/strings.xml b/packages/Keyguard/res/values-hy-rAM/strings.xml
index a17f6e2..7c771ca 100644
--- a/packages/Keyguard/res/values-hy-rAM/strings.xml
+++ b/packages/Keyguard/res/values-hy-rAM/strings.xml
@@ -31,6 +31,8 @@
<string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"Սխալ PIN ծածկագիր:"</string>
<string name="keyguard_charged" msgid="3272223906073492454">"Լիցքավորված է"</string>
<string name="keyguard_plugged_in" msgid="9087497435553252863">"Լիցքավորում"</string>
+ <string name="keyguard_plugged_in_charging_fast" msgid="6671162730167305479">"Արագ լիցքավորում"</string>
+ <string name="keyguard_plugged_in_charging_slowly" msgid="1964714661071163229">"Դանդաղ լիցքավորում"</string>
<string name="keyguard_low_battery" msgid="8143808018719173859">"Միացրեք ձեր լիցքավորիչը:"</string>
<string name="keyguard_instructions_when_pattern_disabled" msgid="1332288268600329841">"Ապակողպելու համար սեղմեք Ցանկը:"</string>
<string name="keyguard_network_locked_message" msgid="9169717779058037168">"Ցանցը կողպված է"</string>
@@ -111,6 +113,9 @@
<string name="kg_prompt_reason_restart_pattern" msgid="489430505491862444">"Սարքը վերագործարկելիս անհրաժեշտ է մուտքագրել ապակողպման նախշը:"</string>
<string name="kg_prompt_reason_restart_pin" msgid="994878216570694974">"Սարքը վերագործարկելիս անհրաժեշտ է մուտքագրել PIN կոդը:"</string>
<string name="kg_prompt_reason_restart_password" msgid="2375742919528461664">"Սարքը վերագործարկելիս անհրաժեշտ է մուտքագրել գաղտնաբառը:"</string>
+ <string name="kg_prompt_reason_timeout_pattern" msgid="8930047492617900785">"Անվտանգության նկատառումներից ելնելով անհրաժեշտ է մուտքագրել նախշը:"</string>
+ <string name="kg_prompt_reason_timeout_pin" msgid="7470468607947726377">"Անվտանգության նկատառումներից ելնելով անհրաժեշտ է մուտքագրել PIN կոդը:"</string>
+ <string name="kg_prompt_reason_timeout_password" msgid="1177412542773936957">"Անվտանգության նկատառումներից ելնելով անհրաժեշտ է մուտքագրել գաղտնաբառը:"</string>
<string name="kg_prompt_reason_switch_profiles_pattern" msgid="3802056699323773969">"Պրոֆիլները փոխարկելիս անհրաժեշտ է մուտքագրել ապակողպման նախշը:"</string>
<string name="kg_prompt_reason_switch_profiles_pin" msgid="8108020184731052246">"Պրոֆիլները փոխարկելիս անհրաժեշտ է մուտքագրել PIN կոդը:"</string>
<string name="kg_prompt_reason_switch_profiles_password" msgid="6755997057852042672">"Պրոֆիլները փոխարկելիս անհրաժեշտ է մուտքագրել գաղտնաբառը:"</string>
diff --git a/packages/Keyguard/res/values-in/strings.xml b/packages/Keyguard/res/values-in/strings.xml
index 57ceede..dbe01e7 100644
--- a/packages/Keyguard/res/values-in/strings.xml
+++ b/packages/Keyguard/res/values-in/strings.xml
@@ -31,6 +31,8 @@
<string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"Kode PIN salah."</string>
<string name="keyguard_charged" msgid="3272223906073492454">"Terisi"</string>
<string name="keyguard_plugged_in" msgid="9087497435553252863">"Mengisi daya"</string>
+ <string name="keyguard_plugged_in_charging_fast" msgid="6671162730167305479">"Mengisi daya dengan cepat"</string>
+ <string name="keyguard_plugged_in_charging_slowly" msgid="1964714661071163229">"Mengisi daya dengan lambat"</string>
<string name="keyguard_low_battery" msgid="8143808018719173859">"Hubungkan pengisi daya."</string>
<string name="keyguard_instructions_when_pattern_disabled" msgid="1332288268600329841">"Tekan Menu untuk membuka."</string>
<string name="keyguard_network_locked_message" msgid="9169717779058037168">"Jaringan terkunci"</string>
@@ -111,6 +113,9 @@
<string name="kg_prompt_reason_restart_pattern" msgid="489430505491862444">"Pola diperlukan jika Anda memulai ulang perangkat."</string>
<string name="kg_prompt_reason_restart_pin" msgid="994878216570694974">"PIN diperlukan jika Anda memulai ulang perangkat."</string>
<string name="kg_prompt_reason_restart_password" msgid="2375742919528461664">"Sandi diperlukan jika Anda memulai ulang perangkat."</string>
+ <string name="kg_prompt_reason_timeout_pattern" msgid="8930047492617900785">"Pola diperlukan untuk keamanan tambahan."</string>
+ <string name="kg_prompt_reason_timeout_pin" msgid="7470468607947726377">"PIN diperlukan untuk keamanan tambahan."</string>
+ <string name="kg_prompt_reason_timeout_password" msgid="1177412542773936957">"Sandi diperlukan untuk keamanan tambahan."</string>
<string name="kg_prompt_reason_switch_profiles_pattern" msgid="3802056699323773969">"Pola diperlukan jika Anda beralih profil."</string>
<string name="kg_prompt_reason_switch_profiles_pin" msgid="8108020184731052246">"PIN diperlukan jika Anda beralih profil."</string>
<string name="kg_prompt_reason_switch_profiles_password" msgid="6755997057852042672">"Sandi diperlukan jika Anda beralih profil."</string>
diff --git a/packages/Keyguard/res/values-is-rIS/strings.xml b/packages/Keyguard/res/values-is-rIS/strings.xml
index 56d35fa..23e135b 100644
--- a/packages/Keyguard/res/values-is-rIS/strings.xml
+++ b/packages/Keyguard/res/values-is-rIS/strings.xml
@@ -31,6 +31,8 @@
<string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"Rangt PIN-númer."</string>
<string name="keyguard_charged" msgid="3272223906073492454">"Fullhlaðið"</string>
<string name="keyguard_plugged_in" msgid="9087497435553252863">"Í hleðslu"</string>
+ <string name="keyguard_plugged_in_charging_fast" msgid="6671162730167305479">"Hröð hleðsla"</string>
+ <string name="keyguard_plugged_in_charging_slowly" msgid="1964714661071163229">"Hæg hleðsla"</string>
<string name="keyguard_low_battery" msgid="8143808018719173859">"Tengdu hleðslutækið."</string>
<string name="keyguard_instructions_when_pattern_disabled" msgid="1332288268600329841">"Ýttu á valmyndarhnappinn til að taka úr lás."</string>
<string name="keyguard_network_locked_message" msgid="9169717779058037168">"Símkerfi læst"</string>
@@ -111,6 +113,9 @@
<string name="kg_prompt_reason_restart_pattern" msgid="489430505491862444">"Mynsturs er krafist þegar þú endurræsir tækið."</string>
<string name="kg_prompt_reason_restart_pin" msgid="994878216570694974">"PIN-númers er krafist þegar þú endurræsir tækið."</string>
<string name="kg_prompt_reason_restart_password" msgid="2375742919528461664">"Aðgangsorðs er krafist þegar þú endurræsir tækið."</string>
+ <string name="kg_prompt_reason_timeout_pattern" msgid="8930047492617900785">"Mynsturs er krafist af öryggisástæðum."</string>
+ <string name="kg_prompt_reason_timeout_pin" msgid="7470468607947726377">"PIN-númers er krafist af öryggisástæðum."</string>
+ <string name="kg_prompt_reason_timeout_password" msgid="1177412542773936957">"Aðgangsorðs er krafist af öryggisástæðum."</string>
<string name="kg_prompt_reason_switch_profiles_pattern" msgid="3802056699323773969">"Mynsturs er krafist þegar þú skiptir um snið."</string>
<string name="kg_prompt_reason_switch_profiles_pin" msgid="8108020184731052246">"PIN-númers er krafist þegar þú skiptir um snið."</string>
<string name="kg_prompt_reason_switch_profiles_password" msgid="6755997057852042672">"Aðgangsorðs er krafist þegar þú skiptir um snið."</string>
diff --git a/packages/Keyguard/res/values-it/strings.xml b/packages/Keyguard/res/values-it/strings.xml
index 08a0f8f..98cb0b2 100644
--- a/packages/Keyguard/res/values-it/strings.xml
+++ b/packages/Keyguard/res/values-it/strings.xml
@@ -31,6 +31,8 @@
<string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"Codice PIN errato."</string>
<string name="keyguard_charged" msgid="3272223906073492454">"Carico"</string>
<string name="keyguard_plugged_in" msgid="9087497435553252863">"In carica"</string>
+ <string name="keyguard_plugged_in_charging_fast" msgid="6671162730167305479">"Ricarica veloce"</string>
+ <string name="keyguard_plugged_in_charging_slowly" msgid="1964714661071163229">"Ricarica lenta"</string>
<string name="keyguard_low_battery" msgid="8143808018719173859">"Collega il caricabatterie."</string>
<string name="keyguard_instructions_when_pattern_disabled" msgid="1332288268600329841">"Premi Menu per sbloccare."</string>
<string name="keyguard_network_locked_message" msgid="9169717779058037168">"Rete bloccata"</string>
@@ -111,6 +113,9 @@
<string name="kg_prompt_reason_restart_pattern" msgid="489430505491862444">"Sequenza obbligatoria dopo il riavvio del dispositivo."</string>
<string name="kg_prompt_reason_restart_pin" msgid="994878216570694974">"PIN obbligatorio dopo il riavvio del dispositivo."</string>
<string name="kg_prompt_reason_restart_password" msgid="2375742919528461664">"Password obbligatoria dopo il riavvio del dispositivo."</string>
+ <string name="kg_prompt_reason_timeout_pattern" msgid="8930047492617900785">"Pattern obbligatorio per una maggiore sicurezza."</string>
+ <string name="kg_prompt_reason_timeout_pin" msgid="7470468607947726377">"PIN obbligatorio per una maggiore sicurezza."</string>
+ <string name="kg_prompt_reason_timeout_password" msgid="1177412542773936957">"Password obbligatoria per una maggiore sicurezza."</string>
<string name="kg_prompt_reason_switch_profiles_pattern" msgid="3802056699323773969">"Sequenza obbligatoria dopo aver cambiato profilo."</string>
<string name="kg_prompt_reason_switch_profiles_pin" msgid="8108020184731052246">"PIN obbligatorio dopo aver cambiato profilo."</string>
<string name="kg_prompt_reason_switch_profiles_password" msgid="6755997057852042672">"Password obbligatoria dopo aver cambiato profilo."</string>
diff --git a/packages/Keyguard/res/values-iw/strings.xml b/packages/Keyguard/res/values-iw/strings.xml
index cdafe7f..7ffa676 100644
--- a/packages/Keyguard/res/values-iw/strings.xml
+++ b/packages/Keyguard/res/values-iw/strings.xml
@@ -31,6 +31,8 @@
<string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"קוד PIN שגוי"</string>
<string name="keyguard_charged" msgid="3272223906073492454">"טעון"</string>
<string name="keyguard_plugged_in" msgid="9087497435553252863">"טוען"</string>
+ <string name="keyguard_plugged_in_charging_fast" msgid="6671162730167305479">"טעינה מהירה"</string>
+ <string name="keyguard_plugged_in_charging_slowly" msgid="1964714661071163229">"טעינה איטית"</string>
<string name="keyguard_low_battery" msgid="8143808018719173859">"חבר את המטען."</string>
<string name="keyguard_instructions_when_pattern_disabled" msgid="1332288268600329841">"לחץ על \'תפריט\' כדי לבטל את הנעילה."</string>
<string name="keyguard_network_locked_message" msgid="9169717779058037168">"רשת נעולה"</string>
@@ -115,6 +117,9 @@
<string name="kg_prompt_reason_restart_pattern" msgid="489430505491862444">"יש להזין את קו ביטול הנעילה לאחר אתחול המכשיר."</string>
<string name="kg_prompt_reason_restart_pin" msgid="994878216570694974">"יש להזין את ה-PIN לאחר אתחול המכשיר."</string>
<string name="kg_prompt_reason_restart_password" msgid="2375742919528461664">"יש להזין את הסיסמה לאחר אתחול המכשיר."</string>
+ <string name="kg_prompt_reason_timeout_pattern" msgid="8930047492617900785">"יש להזין את קו ביטול הנעילה על מנת להגביר את רמת האבטחה."</string>
+ <string name="kg_prompt_reason_timeout_pin" msgid="7470468607947726377">"יש להזין PIN על מנת להגביר את רמת האבטחה."</string>
+ <string name="kg_prompt_reason_timeout_password" msgid="1177412542773936957">"יש להזין סיסמה על מנת להגביר את רמת האבטחה."</string>
<string name="kg_prompt_reason_switch_profiles_pattern" msgid="3802056699323773969">"יש להזין את קו ביטול הנעילה בעת מעבר בין פרופילים."</string>
<string name="kg_prompt_reason_switch_profiles_pin" msgid="8108020184731052246">"יש להזין את ה-PIN בעת מעבר בין פרופילים."</string>
<string name="kg_prompt_reason_switch_profiles_password" msgid="6755997057852042672">"יש להזין את הסיסמה בעת מעבר בין פרופילים."</string>
diff --git a/packages/Keyguard/res/values-ja/strings.xml b/packages/Keyguard/res/values-ja/strings.xml
index 6bef3fe..cea4319 100644
--- a/packages/Keyguard/res/values-ja/strings.xml
+++ b/packages/Keyguard/res/values-ja/strings.xml
@@ -31,6 +31,8 @@
<string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"PINコードが正しくありません。"</string>
<string name="keyguard_charged" msgid="3272223906073492454">"充電完了"</string>
<string name="keyguard_plugged_in" msgid="9087497435553252863">"充電中"</string>
+ <string name="keyguard_plugged_in_charging_fast" msgid="6671162730167305479">"急速充電中"</string>
+ <string name="keyguard_plugged_in_charging_slowly" msgid="1964714661071163229">"緩速充電中"</string>
<string name="keyguard_low_battery" msgid="8143808018719173859">"充電してください。"</string>
<string name="keyguard_instructions_when_pattern_disabled" msgid="1332288268600329841">"メニューからロックを解除できます。"</string>
<string name="keyguard_network_locked_message" msgid="9169717779058037168">"ネットワークがロックされました"</string>
@@ -110,7 +112,10 @@
<string name="airplane_mode" msgid="3122107900897202805">"機内モード"</string>
<string name="kg_prompt_reason_restart_pattern" msgid="489430505491862444">"端末を再起動するにはパターンが必要です。"</string>
<string name="kg_prompt_reason_restart_pin" msgid="994878216570694974">"端末を再起動するにはPINが必要です。"</string>
- <string name="kg_prompt_reason_restart_password" msgid="2375742919528461664">"端末を再起動するにはパスワードが必要です。"</string>
+ <string name="kg_prompt_reason_restart_password" msgid="2375742919528461664">"端末を再起動した時にはパスワードが必要です。"</string>
+ <string name="kg_prompt_reason_timeout_pattern" msgid="8930047492617900785">"セキュリティを強化するため、パターンが必要です。"</string>
+ <string name="kg_prompt_reason_timeout_pin" msgid="7470468607947726377">"セキュリティを強化するため、PINが必要です。"</string>
+ <string name="kg_prompt_reason_timeout_password" msgid="1177412542773936957">"セキュリティを強化するため、パスワードが必要です。"</string>
<string name="kg_prompt_reason_switch_profiles_pattern" msgid="3802056699323773969">"プロファイルを切り替えるにはパターンが必要です。"</string>
<string name="kg_prompt_reason_switch_profiles_pin" msgid="8108020184731052246">"プロファイルを切り替えるにはPINが必要です。"</string>
<string name="kg_prompt_reason_switch_profiles_password" msgid="6755997057852042672">"プロファイルを切り替えるにはパスワードが必要です。"</string>
diff --git a/packages/Keyguard/res/values-ka-rGE/strings.xml b/packages/Keyguard/res/values-ka-rGE/strings.xml
index c475a82..c9b31cd 100644
--- a/packages/Keyguard/res/values-ka-rGE/strings.xml
+++ b/packages/Keyguard/res/values-ka-rGE/strings.xml
@@ -31,6 +31,8 @@
<string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"არასწორი PIN კოდი."</string>
<string name="keyguard_charged" msgid="3272223906073492454">"დამუხტულია"</string>
<string name="keyguard_plugged_in" msgid="9087497435553252863">"მიმდინარეობს დატენვა"</string>
+ <string name="keyguard_plugged_in_charging_fast" msgid="6671162730167305479">"იმუხტება სწრაფად"</string>
+ <string name="keyguard_plugged_in_charging_slowly" msgid="1964714661071163229">"იმუხტება ნელა"</string>
<string name="keyguard_low_battery" msgid="8143808018719173859">"შეაერთეთ დამტენი."</string>
<string name="keyguard_instructions_when_pattern_disabled" msgid="1332288268600329841">"განბლოკვისთვის დააჭირეთ მენიუს."</string>
<string name="keyguard_network_locked_message" msgid="9169717779058037168">"ქსელი ჩაკეტილია"</string>
@@ -111,6 +113,9 @@
<string name="kg_prompt_reason_restart_pattern" msgid="489430505491862444">"ნიმუში საჭიროა მოწყობილობის გადატვირთვისას."</string>
<string name="kg_prompt_reason_restart_pin" msgid="994878216570694974">"PIN-კოდი საჭიროა მოწყობილობის გადატვირთვისას."</string>
<string name="kg_prompt_reason_restart_password" msgid="2375742919528461664">"პაროლი საჭიროა მოწყობილობის გადატვირთვისას."</string>
+ <string name="kg_prompt_reason_timeout_pattern" msgid="8930047492617900785">"ნიმუშია საჭირო დამატებითი უსაფრთხოებისთვის."</string>
+ <string name="kg_prompt_reason_timeout_pin" msgid="7470468607947726377">"PIN-კოდია საჭირო დამატებითი უსაფრთხოებისთვის."</string>
+ <string name="kg_prompt_reason_timeout_password" msgid="1177412542773936957">"პაროლია საჭირო დამატებითი უსაფრთხოებისთვის."</string>
<string name="kg_prompt_reason_switch_profiles_pattern" msgid="3802056699323773969">"ნიმუში საჭიროა პროფილების გადართვისას."</string>
<string name="kg_prompt_reason_switch_profiles_pin" msgid="8108020184731052246">"PIN-კოდი საჭიროა პროფილების გადართვისას."</string>
<string name="kg_prompt_reason_switch_profiles_password" msgid="6755997057852042672">"პაროლი საჭიროა პროფილების გადართვისას."</string>
diff --git a/packages/Keyguard/res/values-kk-rKZ/strings.xml b/packages/Keyguard/res/values-kk-rKZ/strings.xml
index bfcbc89..ea3992d 100644
--- a/packages/Keyguard/res/values-kk-rKZ/strings.xml
+++ b/packages/Keyguard/res/values-kk-rKZ/strings.xml
@@ -31,6 +31,8 @@
<string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"Қате PIN код"</string>
<string name="keyguard_charged" msgid="3272223906073492454">"Зарядталған"</string>
<string name="keyguard_plugged_in" msgid="9087497435553252863">"Зарядтауда"</string>
+ <string name="keyguard_plugged_in_charging_fast" msgid="6671162730167305479">"Тез зарядталуда"</string>
+ <string name="keyguard_plugged_in_charging_slowly" msgid="1964714661071163229">"Баяу зарядталуда"</string>
<string name="keyguard_low_battery" msgid="8143808018719173859">"Зарядтау құрылғысын жалғаңыз."</string>
<string name="keyguard_instructions_when_pattern_disabled" msgid="1332288268600329841">"Ашу үшін мәзірді басыңыз."</string>
<string name="keyguard_network_locked_message" msgid="9169717779058037168">"Желі бекітулі."</string>
@@ -111,6 +113,9 @@
<string name="kg_prompt_reason_restart_pattern" msgid="489430505491862444">"Құрылғыны өшіріп, қайта қосқанда, өрнекті енгізу қажет."</string>
<string name="kg_prompt_reason_restart_pin" msgid="994878216570694974">"Құрылғыны өшіріп, қайта қосқанда, PIN кодын енгізу қажет."</string>
<string name="kg_prompt_reason_restart_password" msgid="2375742919528461664">"Құрылғыны өшіріп, қайта қосқанда, құпия сөзді енгізу қажет."</string>
+ <string name="kg_prompt_reason_timeout_pattern" msgid="8930047492617900785">"Қосымша қауіпсіздік үшін өрнек қажет."</string>
+ <string name="kg_prompt_reason_timeout_pin" msgid="7470468607947726377">"Қосымша қауіпсіздік үшін PIN коды қажет."</string>
+ <string name="kg_prompt_reason_timeout_password" msgid="1177412542773936957">"Қосымша қауіпсіздік үшін құпия сөз қажет."</string>
<string name="kg_prompt_reason_switch_profiles_pattern" msgid="3802056699323773969">"Профильдерді ауыстырғанда, өрнекті енгізу қажет."</string>
<string name="kg_prompt_reason_switch_profiles_pin" msgid="8108020184731052246">"Профильдерді ауыстырғанда, PIN кодын енгізу қажет."</string>
<string name="kg_prompt_reason_switch_profiles_password" msgid="6755997057852042672">"Профильдерді ауыстырғанда, құпия сөзді енгізу қажет."</string>
diff --git a/packages/Keyguard/res/values-km-rKH/strings.xml b/packages/Keyguard/res/values-km-rKH/strings.xml
index 95c44cb..3803abf 100644
--- a/packages/Keyguard/res/values-km-rKH/strings.xml
+++ b/packages/Keyguard/res/values-km-rKH/strings.xml
@@ -31,6 +31,8 @@
<string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"កូដ PIN មិនត្រឹមត្រូវ។"</string>
<string name="keyguard_charged" msgid="3272223906073492454">"បានបញ្ចូលពេញ"</string>
<string name="keyguard_plugged_in" msgid="9087497435553252863">"កំពុងបញ្ចូលថ្ម"</string>
+ <string name="keyguard_plugged_in_charging_fast" msgid="6671162730167305479">"សាកយ៉ាងឆាប់រហ័ស"</string>
+ <string name="keyguard_plugged_in_charging_slowly" msgid="1964714661071163229">"សាកយឺត"</string>
<string name="keyguard_low_battery" msgid="8143808018719173859">"ភ្ជាប់ឧបករណ៍បញ្ចូលថ្ម។"</string>
<string name="keyguard_instructions_when_pattern_disabled" msgid="1332288268600329841">"ចុចម៉ឺនុយ ដើម្បីដោះសោ។"</string>
<string name="keyguard_network_locked_message" msgid="9169717779058037168">"បណ្ដាញជាប់សោ"</string>
@@ -111,6 +113,9 @@
<string name="kg_prompt_reason_restart_pattern" msgid="489430505491862444">"តម្រូវឲ្យមានលំនាំនៅពេលដែលអ្នកចាប់ផ្តើមឧបករណ៍ឡើងវិញ។"</string>
<string name="kg_prompt_reason_restart_pin" msgid="994878216570694974">"តម្រូវឲ្យមានកូដ PIN នៅពេលដែលអ្នកចាប់ផ្តើមឧបករណ៍ឡើងវិញ។"</string>
<string name="kg_prompt_reason_restart_password" msgid="2375742919528461664">"តម្រូវឲ្យមានពាក្យសម្ងាត់នៅពេលដែលអ្នកចាប់ផ្តើមឧបករណ៍ឡើងវិញ។"</string>
+ <string name="kg_prompt_reason_timeout_pattern" msgid="8930047492617900785">"តម្រូវឲ្យមានលំនាំសម្រាប់សវុត្ថិភាពបន្ថែម"</string>
+ <string name="kg_prompt_reason_timeout_pin" msgid="7470468607947726377">"តម្រូវឲ្យមានកូដ PIN សម្រាប់សុវត្ថិភាពបន្ថែម"</string>
+ <string name="kg_prompt_reason_timeout_password" msgid="1177412542773936957">"តម្រូវឲ្យមានពាក្យសម្ងាត់សម្រាប់សុវត្ថិភាពបន្ថែម"</string>
<string name="kg_prompt_reason_switch_profiles_pattern" msgid="3802056699323773969">"តម្រូវឲ្យមានលំនាំនៅពេលដែលអ្នកប្តូរប្រវត្តិរូបរបស់អ្នក។"</string>
<string name="kg_prompt_reason_switch_profiles_pin" msgid="8108020184731052246">"តម្រូវឲ្យមានកូដ PIN នៅពេលដែលអ្នកប្តូរប្រវត្តិរូបរបស់អ្នក។"</string>
<string name="kg_prompt_reason_switch_profiles_password" msgid="6755997057852042672">"តម្រូវឲ្យមានពាក្យសម្ងាត់នៅពេលដែលអ្នកប្តូរប្រវត្តិរូបរបស់អ្នក។"</string>
diff --git a/packages/Keyguard/res/values-kn-rIN/strings.xml b/packages/Keyguard/res/values-kn-rIN/strings.xml
index 6f1f7ff..c3d2a61 100644
--- a/packages/Keyguard/res/values-kn-rIN/strings.xml
+++ b/packages/Keyguard/res/values-kn-rIN/strings.xml
@@ -31,6 +31,8 @@
<string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"ತಪ್ಪಾದ ಪಿನ್ ಕೋಡ್."</string>
<string name="keyguard_charged" msgid="3272223906073492454">"ಚಾರ್ಜ್ ಆಗಿದೆ"</string>
<string name="keyguard_plugged_in" msgid="9087497435553252863">"ಚಾರ್ಜ್ ಆಗುತ್ತಿದೆ"</string>
+ <string name="keyguard_plugged_in_charging_fast" msgid="6671162730167305479">"ವೇಗವಾಗಿ ಚಾರ್ಜ್ ಮಾಡಲಾಗುತ್ತಿದೆ"</string>
+ <string name="keyguard_plugged_in_charging_slowly" msgid="1964714661071163229">"ನಿಧಾನವಾಗಿ ಚಾರ್ಜ್ ಮಾಡಲಾಗುತ್ತಿದೆ"</string>
<string name="keyguard_low_battery" msgid="8143808018719173859">"ನಿಮ್ಮ ಚಾರ್ಜರ್ ಸಂಪರ್ಕಗೊಳಿಸಿ."</string>
<string name="keyguard_instructions_when_pattern_disabled" msgid="1332288268600329841">"ಅನ್ಲಾಕ್ ಮಾಡಲು ಮೆನು ಕ್ಲಿಕ್ ಮಾಡಿ."</string>
<string name="keyguard_network_locked_message" msgid="9169717779058037168">"ನೆಟ್ವರ್ಕ್ ಲಾಕ್ ಆಗಿದೆ"</string>
@@ -111,6 +113,9 @@
<string name="kg_prompt_reason_restart_pattern" msgid="489430505491862444">"ನೀವು ಸಾಧನವನ್ನು ಮರುಪ್ರಾರಂಭಿಸಿದಾಗ ಪ್ಯಾಟರ್ನ್ ಅಗತ್ಯವಿರುತ್ತದೆ."</string>
<string name="kg_prompt_reason_restart_pin" msgid="994878216570694974">"ನೀವು ಸಾಧನವನ್ನು ಮರುಪ್ರಾರಂಭಿಸಿದಾಗ ಪಿನ್ ಅಗತ್ಯವಿರುತ್ತದೆ."</string>
<string name="kg_prompt_reason_restart_password" msgid="2375742919528461664">"ನೀವು ಸಾಧನವನ್ನು ಮರುಪ್ರಾರಂಭಿಸಿದಾಗ ಪಾಸ್ವರ್ಡ್ ಅಗತ್ಯವಿರುತ್ತದೆ."</string>
+ <string name="kg_prompt_reason_timeout_pattern" msgid="8930047492617900785">"ಹೆಚ್ಚುವರಿ ಭದ್ರತೆಗೆ ಪ್ಯಾಟರ್ನ್ ಅಗತ್ಯವಿದೆ."</string>
+ <string name="kg_prompt_reason_timeout_pin" msgid="7470468607947726377">"ಹೆಚ್ಚುವರಿ ಭದ್ರತೆಗೆ ಪಿನ್ ಅಗತ್ಯವಿದೆ."</string>
+ <string name="kg_prompt_reason_timeout_password" msgid="1177412542773936957">"ಹೆಚ್ಚುವರಿ ಭದ್ರತೆಗಾಗಿ ಪಾಸ್ವರ್ಡ್ ಅಗತ್ಯವಿದೆ."</string>
<string name="kg_prompt_reason_switch_profiles_pattern" msgid="3802056699323773969">"ನೀವು ಪ್ರೊಫೈಲ್ ಬದಲಾಯಿಸಿದಾಗ ಪ್ಯಾಟರ್ನ್ ಅಗತ್ಯವಿರುತ್ತದೆ."</string>
<string name="kg_prompt_reason_switch_profiles_pin" msgid="8108020184731052246">"ನೀವು ಪ್ರೊಫೈಲ್ ಬದಲಾಯಿಸಿದಾಗ ಪಿನ್ ಅಗತ್ಯವಿರುತ್ತದೆ."</string>
<string name="kg_prompt_reason_switch_profiles_password" msgid="6755997057852042672">"ನೀವು ಪ್ರೊಫೈಲ್ ಬದಲಾಯಿಸಿದಾಗ ಪಾಸ್ವರ್ಡ್ ಅಗತ್ಯವಿರುತ್ತದೆ."</string>
diff --git a/packages/Keyguard/res/values-ko/strings.xml b/packages/Keyguard/res/values-ko/strings.xml
index 88d17fc..691f0a4 100644
--- a/packages/Keyguard/res/values-ko/strings.xml
+++ b/packages/Keyguard/res/values-ko/strings.xml
@@ -31,6 +31,8 @@
<string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"PIN 코드가 잘못되었습니다."</string>
<string name="keyguard_charged" msgid="3272223906073492454">"충전됨"</string>
<string name="keyguard_plugged_in" msgid="9087497435553252863">"충전 중"</string>
+ <string name="keyguard_plugged_in_charging_fast" msgid="6671162730167305479">"고속 충전"</string>
+ <string name="keyguard_plugged_in_charging_slowly" msgid="1964714661071163229">"저속 충전"</string>
<string name="keyguard_low_battery" msgid="8143808018719173859">"충전기를 연결하세요."</string>
<string name="keyguard_instructions_when_pattern_disabled" msgid="1332288268600329841">"잠금해제하려면 메뉴를 누르세요."</string>
<string name="keyguard_network_locked_message" msgid="9169717779058037168">"네트워크 잠김"</string>
@@ -111,6 +113,9 @@
<string name="kg_prompt_reason_restart_pattern" msgid="489430505491862444">"기기를 다시 시작하려면 패턴이 필요합니다."</string>
<string name="kg_prompt_reason_restart_pin" msgid="994878216570694974">"기기를 다시 시작하려면 PIN이 필요합니다."</string>
<string name="kg_prompt_reason_restart_password" msgid="2375742919528461664">"기기를 다시 시작하려면 비밀번호가 필요합니다."</string>
+ <string name="kg_prompt_reason_timeout_pattern" msgid="8930047492617900785">"보안 강화를 위해 패턴이 필요합니다."</string>
+ <string name="kg_prompt_reason_timeout_pin" msgid="7470468607947726377">"보안 강화를 위해 PIN이 필요합니다."</string>
+ <string name="kg_prompt_reason_timeout_password" msgid="1177412542773936957">"보안 강화를 위해 비밀번호가 필요합니다."</string>
<string name="kg_prompt_reason_switch_profiles_pattern" msgid="3802056699323773969">"프로필을 전환하려면 패턴이 필요합니다."</string>
<string name="kg_prompt_reason_switch_profiles_pin" msgid="8108020184731052246">"프로필을 전환하려면 PIN이 필요합니다."</string>
<string name="kg_prompt_reason_switch_profiles_password" msgid="6755997057852042672">"프로필을 전환하려면 비밀번호가 필요합니다."</string>
diff --git a/packages/Keyguard/res/values-ky-rKG/strings.xml b/packages/Keyguard/res/values-ky-rKG/strings.xml
index 2156729..fb5fbae 100644
--- a/packages/Keyguard/res/values-ky-rKG/strings.xml
+++ b/packages/Keyguard/res/values-ky-rKG/strings.xml
@@ -31,6 +31,8 @@
<string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"PIN-код туура эмес."</string>
<string name="keyguard_charged" msgid="3272223906073492454">"Дүрмөттөлдү"</string>
<string name="keyguard_plugged_in" msgid="9087497435553252863">"Кубатталууда"</string>
+ <string name="keyguard_plugged_in_charging_fast" msgid="6671162730167305479">"Ыкчам кубатталууда"</string>
+ <string name="keyguard_plugged_in_charging_slowly" msgid="1964714661071163229">"Жай кубатталууда"</string>
<string name="keyguard_low_battery" msgid="8143808018719173859">"Дүрмөттөөчү түзмөктү туташтырыңыз."</string>
<string name="keyguard_instructions_when_pattern_disabled" msgid="1332288268600329841">"Бөгөттөн чыгаруу үчүн Менюну басыңыз."</string>
<string name="keyguard_network_locked_message" msgid="9169717779058037168">"Тармак бөгөттөлгөн"</string>
@@ -111,6 +113,9 @@
<string name="kg_prompt_reason_restart_pattern" msgid="489430505491862444">"Түзмөктү өчүрүп-күйгүзгөнүңүздө сүрөт үлгүсү керектелет."</string>
<string name="kg_prompt_reason_restart_pin" msgid="994878216570694974">"Түзмөктү өчүрүп-күйгүзгөнүңүздө PIN керектелет."</string>
<string name="kg_prompt_reason_restart_password" msgid="2375742919528461664">"Түзмөктү өчүрүп-күйгүзгөнүңүздө сырсөз керектелет."</string>
+ <string name="kg_prompt_reason_timeout_pattern" msgid="8930047492617900785">"Кошумча коопсуздук үчүн сүрөт үлгүсү керек."</string>
+ <string name="kg_prompt_reason_timeout_pin" msgid="7470468607947726377">"Кошумча коопсуздук үчүн PIN код керек."</string>
+ <string name="kg_prompt_reason_timeout_password" msgid="1177412542773936957">"Кошумча коопсуздук үчүн сырсөз керек."</string>
<string name="kg_prompt_reason_switch_profiles_pattern" msgid="3802056699323773969">"Профилдерди которгонуңузда сүрөт үлгүсү керектелет."</string>
<string name="kg_prompt_reason_switch_profiles_pin" msgid="8108020184731052246">"Профилдерди которгонуңузда PIN керектелет."</string>
<string name="kg_prompt_reason_switch_profiles_password" msgid="6755997057852042672">"Профилдерди которгонуңузда сырсөз керектелет."</string>
diff --git a/packages/Keyguard/res/values-lo-rLA/strings.xml b/packages/Keyguard/res/values-lo-rLA/strings.xml
index ada974f..b9b68692 100644
--- a/packages/Keyguard/res/values-lo-rLA/strings.xml
+++ b/packages/Keyguard/res/values-lo-rLA/strings.xml
@@ -31,6 +31,8 @@
<string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"ລະຫັດ PIN ບໍ່ຖືກຕ້ອງ."</string>
<string name="keyguard_charged" msgid="3272223906073492454">"ສາກເຕັມແລ້ວ"</string>
<string name="keyguard_plugged_in" msgid="9087497435553252863">"ກຳລັງສາກໄຟ"</string>
+ <string name="keyguard_plugged_in_charging_fast" msgid="6671162730167305479">"ກຳລັງສາກດ່ວນ"</string>
+ <string name="keyguard_plugged_in_charging_slowly" msgid="1964714661071163229">"ກຳລັງສາກຊ້າໆ"</string>
<string name="keyguard_low_battery" msgid="8143808018719173859">"ເຊື່ອມຕໍ່ອຸປະກອນສາກຂອງທ່ານ."</string>
<string name="keyguard_instructions_when_pattern_disabled" msgid="1332288268600329841">"ກົດເມນູເພື່ອປົດລັອກ."</string>
<string name="keyguard_network_locked_message" msgid="9169717779058037168">"ເຄືອຂ່າຍຖືກລັອກ"</string>
@@ -111,6 +113,9 @@
<string name="kg_prompt_reason_restart_pattern" msgid="489430505491862444">"ຈຳເປັນຕ້ອງມີແບບຮູບ ເມື່ອທ່ານເລີ່ມລະບົບອຸປະກອນໃໝ່."</string>
<string name="kg_prompt_reason_restart_pin" msgid="994878216570694974">"ຈຳເປັນຕ້ອງມີ PIN ເມື່ອທ່ານເລີ່ມລະບົບອຸປະກອນໃໝ່."</string>
<string name="kg_prompt_reason_restart_password" msgid="2375742919528461664">"ຈຳເປັນຕ້ອງມີລະຫັດຜ່ານ ເມື່ອທ່ານເລີ່ມລະບົບອຸປະກອນໃໝ່."</string>
+ <string name="kg_prompt_reason_timeout_pattern" msgid="8930047492617900785">"ຈຳເປັນຕ້ອງມີຮູບແບບສຳລັບຄວາມປອດໄພເພີ່ມເຕີມ."</string>
+ <string name="kg_prompt_reason_timeout_pin" msgid="7470468607947726377">"ຈຳເປັນຕ້ອງມີ PIN ສຳລັບຄວາມປອດໄພເພີ່ມເຕີມ."</string>
+ <string name="kg_prompt_reason_timeout_password" msgid="1177412542773936957">"ຈຳເປັນຕ້ອງມີລະຫັດຜ່ານສຳລັບຄວາມປອດໄພເພີ່ມເຕີມ."</string>
<string name="kg_prompt_reason_switch_profiles_pattern" msgid="3802056699323773969">"ຈຳເປັນຕ້ອງມີແບບຮູບ ເມື່ອທ່ານປ່ຽນໂປຣໄຟລ໌."</string>
<string name="kg_prompt_reason_switch_profiles_pin" msgid="8108020184731052246">"ຈຳເປັນຕ້ອງມີ PIN ເມື່ອທ່ານປ່ຽນໂປຣໄຟລ໌."</string>
<string name="kg_prompt_reason_switch_profiles_password" msgid="6755997057852042672">"ຈຳເປັນຕ້ອງມີລະຫັດຜ່ານ ເມື່ອທ່ານປ່ຽນໂປຣໄຟລ໌."</string>
diff --git a/packages/Keyguard/res/values-lt/strings.xml b/packages/Keyguard/res/values-lt/strings.xml
index 1983eeb1..d2bed32 100644
--- a/packages/Keyguard/res/values-lt/strings.xml
+++ b/packages/Keyguard/res/values-lt/strings.xml
@@ -31,6 +31,8 @@
<string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"Neteisingas PIN kodas."</string>
<string name="keyguard_charged" msgid="3272223906073492454">"Įkrauta"</string>
<string name="keyguard_plugged_in" msgid="9087497435553252863">"Kraunama"</string>
+ <string name="keyguard_plugged_in_charging_fast" msgid="6671162730167305479">"Greitai kraunama"</string>
+ <string name="keyguard_plugged_in_charging_slowly" msgid="1964714661071163229">"Lėtai kraunama"</string>
<string name="keyguard_low_battery" msgid="8143808018719173859">"Prijunkite įkroviklį."</string>
<string name="keyguard_instructions_when_pattern_disabled" msgid="1332288268600329841">"Jei norite atrakinti, paspauskite „Meniu“."</string>
<string name="keyguard_network_locked_message" msgid="9169717779058037168">"Tinklas užrakintas"</string>
@@ -115,6 +117,9 @@
<string name="kg_prompt_reason_restart_pattern" msgid="489430505491862444">"Iš naujo paleidus įrenginį reikalingas atrakinimo piešinys."</string>
<string name="kg_prompt_reason_restart_pin" msgid="994878216570694974">"Iš naujo paleidus įrenginį reikalingas PIN kodas."</string>
<string name="kg_prompt_reason_restart_password" msgid="2375742919528461664">"Iš naujo paleidus įrenginį reikalingas slaptažodis."</string>
+ <string name="kg_prompt_reason_timeout_pattern" msgid="8930047492617900785">"Norint užtikrinti papildomą saugumą būtinas atrakinimo piešinys."</string>
+ <string name="kg_prompt_reason_timeout_pin" msgid="7470468607947726377">"Norint užtikrinti papildomą saugumą būtinas PIN kodas."</string>
+ <string name="kg_prompt_reason_timeout_password" msgid="1177412542773936957">"Norint užtikrinti papildomą saugumą būtinas slaptažodis."</string>
<string name="kg_prompt_reason_switch_profiles_pattern" msgid="3802056699323773969">"Perjungiant profilius reikalingas atrakinimo piešinys."</string>
<string name="kg_prompt_reason_switch_profiles_pin" msgid="8108020184731052246">"Perjungiant profilius reikalingas PIN kodas."</string>
<string name="kg_prompt_reason_switch_profiles_password" msgid="6755997057852042672">"Perjungiant profilius reikalingas slaptažodis."</string>
diff --git a/packages/Keyguard/res/values-lv/strings.xml b/packages/Keyguard/res/values-lv/strings.xml
index 496a466..20bfc06 100644
--- a/packages/Keyguard/res/values-lv/strings.xml
+++ b/packages/Keyguard/res/values-lv/strings.xml
@@ -31,6 +31,8 @@
<string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"PIN kods nav pareizs."</string>
<string name="keyguard_charged" msgid="3272223906073492454">"Uzlādēts"</string>
<string name="keyguard_plugged_in" msgid="9087497435553252863">"Notiek uzlāde"</string>
+ <string name="keyguard_plugged_in_charging_fast" msgid="6671162730167305479">"Ātrā uzlāde"</string>
+ <string name="keyguard_plugged_in_charging_slowly" msgid="1964714661071163229">"Lēnā uzlāde"</string>
<string name="keyguard_low_battery" msgid="8143808018719173859">"Pievienojiet uzlādes ierīci."</string>
<string name="keyguard_instructions_when_pattern_disabled" msgid="1332288268600329841">"Lai atbloķētu, nospiediet vienumu Izvēlne."</string>
<string name="keyguard_network_locked_message" msgid="9169717779058037168">"Tīkls ir bloķēts."</string>
@@ -113,6 +115,9 @@
<string name="kg_prompt_reason_restart_pattern" msgid="489430505491862444">"Restartējot ierīci, ir jāievada kombinācija."</string>
<string name="kg_prompt_reason_restart_pin" msgid="994878216570694974">"Restartējot ierīci, ir jāievada PIN."</string>
<string name="kg_prompt_reason_restart_password" msgid="2375742919528461664">"Restartējot ierīci, ir jāievada parole."</string>
+ <string name="kg_prompt_reason_timeout_pattern" msgid="8930047492617900785">"Papildu drošībai nepieciešama atbloķēšanas kombinācija."</string>
+ <string name="kg_prompt_reason_timeout_pin" msgid="7470468607947726377">"Papildu drošībai nepieciešams PIN kods."</string>
+ <string name="kg_prompt_reason_timeout_password" msgid="1177412542773936957">"Papildu drošībai nepieciešama parole."</string>
<string name="kg_prompt_reason_switch_profiles_pattern" msgid="3802056699323773969">"Mainot profilu, ir jāievada kombinācija."</string>
<string name="kg_prompt_reason_switch_profiles_pin" msgid="8108020184731052246">"Mainot profilu, ir jāievada PIN."</string>
<string name="kg_prompt_reason_switch_profiles_password" msgid="6755997057852042672">"Mainot profilu, ir jāievada parole."</string>
diff --git a/packages/Keyguard/res/values-mk-rMK/strings.xml b/packages/Keyguard/res/values-mk-rMK/strings.xml
index 9321a99..a06d4e4 100644
--- a/packages/Keyguard/res/values-mk-rMK/strings.xml
+++ b/packages/Keyguard/res/values-mk-rMK/strings.xml
@@ -31,6 +31,8 @@
<string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"Погрешен ПИН код."</string>
<string name="keyguard_charged" msgid="3272223906073492454">"Наполнета"</string>
<string name="keyguard_plugged_in" msgid="9087497435553252863">"Се полни"</string>
+ <string name="keyguard_plugged_in_charging_fast" msgid="6671162730167305479">"Брзо полнење"</string>
+ <string name="keyguard_plugged_in_charging_slowly" msgid="1964714661071163229">"Бавно полнење"</string>
<string name="keyguard_low_battery" msgid="8143808018719173859">"Поврзи го полначот."</string>
<string name="keyguard_instructions_when_pattern_disabled" msgid="1332288268600329841">"Притисни „Мени“ да се отклучи."</string>
<string name="keyguard_network_locked_message" msgid="9169717779058037168">"Мрежата е заклучена"</string>
@@ -111,6 +113,9 @@
<string name="kg_prompt_reason_restart_pattern" msgid="489430505491862444">"Потребна е шема кога го престартувате уредот."</string>
<string name="kg_prompt_reason_restart_pin" msgid="994878216570694974">"Потребен е ПИН кога го престартувате уредот."</string>
<string name="kg_prompt_reason_restart_password" msgid="2375742919528461664">"Потребна е лозинка кога го престартувате уредот."</string>
+ <string name="kg_prompt_reason_timeout_pattern" msgid="8930047492617900785">"Потребна е шема за дополнителна безбедност."</string>
+ <string name="kg_prompt_reason_timeout_pin" msgid="7470468607947726377">"Потребен е ПИН за дополнителна безбедност."</string>
+ <string name="kg_prompt_reason_timeout_password" msgid="1177412542773936957">"Потребна е лозинка за дополнителна безбедност."</string>
<string name="kg_prompt_reason_switch_profiles_pattern" msgid="3802056699323773969">"Потребна е шема кога променувате профили."</string>
<string name="kg_prompt_reason_switch_profiles_pin" msgid="8108020184731052246">"Потребен е ПИН кога променувате профили."</string>
<string name="kg_prompt_reason_switch_profiles_password" msgid="6755997057852042672">"Потребна е лозинка кога променувате профили."</string>
diff --git a/packages/Keyguard/res/values-ml-rIN/strings.xml b/packages/Keyguard/res/values-ml-rIN/strings.xml
index 3e1db03..a7d78f5 100644
--- a/packages/Keyguard/res/values-ml-rIN/strings.xml
+++ b/packages/Keyguard/res/values-ml-rIN/strings.xml
@@ -31,6 +31,8 @@
<string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"പിൻ കോഡ് തെറ്റാണ്."</string>
<string name="keyguard_charged" msgid="3272223906073492454">"ചാർജ്ജുചെയ്തു"</string>
<string name="keyguard_plugged_in" msgid="9087497435553252863">"ചാർജ്ജുചെയ്യുന്നു"</string>
+ <string name="keyguard_plugged_in_charging_fast" msgid="6671162730167305479">"വേഗത്തിൽ ചാർജുചെയ്യുന്നു"</string>
+ <string name="keyguard_plugged_in_charging_slowly" msgid="1964714661071163229">"പതുക്കെ ചാർജുചെയ്യുന്നു"</string>
<string name="keyguard_low_battery" msgid="8143808018719173859">"നിങ്ങളുടെ ചാർജ്ജർ കണക്റ്റുചെയ്യുക."</string>
<string name="keyguard_instructions_when_pattern_disabled" msgid="1332288268600329841">"അൺലോക്കുചെയ്യാൻ മെനു അമർത്തുക"</string>
<string name="keyguard_network_locked_message" msgid="9169717779058037168">"നെറ്റ്വർക്ക് ലോക്കുചെയ്തു"</string>
@@ -111,6 +113,9 @@
<string name="kg_prompt_reason_restart_pattern" msgid="489430505491862444">"ഉപകരണം പുനഃരാരംഭിക്കുമ്പോൾ പാറ്റേൺ ആവശ്യമാണ്."</string>
<string name="kg_prompt_reason_restart_pin" msgid="994878216570694974">"ഉപകരണം പുനഃരാരംഭിക്കുമ്പോൾ PIN ആവശ്യമാണ്."</string>
<string name="kg_prompt_reason_restart_password" msgid="2375742919528461664">"ഉപകരണം പുനഃരാരംഭിക്കുമ്പോൾ പാസ്വേഡ് ആവശ്യമാണ്."</string>
+ <string name="kg_prompt_reason_timeout_pattern" msgid="8930047492617900785">"അധിക സുരക്ഷയ്ക്ക് പാറ്റേൺ ആവശ്യമാണ്."</string>
+ <string name="kg_prompt_reason_timeout_pin" msgid="7470468607947726377">"അധിക സുരക്ഷയ്ക്ക് PIN ആവശ്യമാണ്."</string>
+ <string name="kg_prompt_reason_timeout_password" msgid="1177412542773936957">"അധിക സുരക്ഷയ്ക്ക് പാസ്വേഡ് ആവശ്യമാണ്."</string>
<string name="kg_prompt_reason_switch_profiles_pattern" msgid="3802056699323773969">"പ്രൊഫൈലുകൾ തമ്മിൽ മാറുമ്പോൾ പാറ്റേൺ ആവശ്യമാണ്."</string>
<string name="kg_prompt_reason_switch_profiles_pin" msgid="8108020184731052246">"പ്രൊഫൈലുകൾ തമ്മിൽ മാറുമ്പോൾ PIN ആവശ്യമാണ്."</string>
<string name="kg_prompt_reason_switch_profiles_password" msgid="6755997057852042672">"പ്രൊഫൈലുകൾ തമ്മിൽ മാറുമ്പോൾ പാസ്വേഡ് ആവശ്യമാണ്."</string>
diff --git a/packages/Keyguard/res/values-mn-rMN/strings.xml b/packages/Keyguard/res/values-mn-rMN/strings.xml
index 6c3b076..495076a 100644
--- a/packages/Keyguard/res/values-mn-rMN/strings.xml
+++ b/packages/Keyguard/res/values-mn-rMN/strings.xml
@@ -31,6 +31,8 @@
<string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"Буруу PIN код."</string>
<string name="keyguard_charged" msgid="3272223906073492454">"Цэнэглэгдэв"</string>
<string name="keyguard_plugged_in" msgid="9087497435553252863">"Цэнэглэж байна"</string>
+ <string name="keyguard_plugged_in_charging_fast" msgid="6671162730167305479">"Хурдан цэнэглэх"</string>
+ <string name="keyguard_plugged_in_charging_slowly" msgid="1964714661071163229">"Удаан цэнэглэх"</string>
<string name="keyguard_low_battery" msgid="8143808018719173859">"Цэнэглэгчээ холбоно уу."</string>
<string name="keyguard_instructions_when_pattern_disabled" msgid="1332288268600329841">"Тайлх бол цэсийг дарна уу."</string>
<string name="keyguard_network_locked_message" msgid="9169717779058037168">"Сүлжээ түгжигдсэн"</string>
@@ -111,6 +113,9 @@
<string name="kg_prompt_reason_restart_pattern" msgid="489430505491862444">"Төхөөрөмжийг дахин эхлүүлэхийн тулд зурган хээ шаардлагатай."</string>
<string name="kg_prompt_reason_restart_pin" msgid="994878216570694974">"Төхөөрөмжийг дахин эхлүүлэхийн тулд PIN шаардлагатай."</string>
<string name="kg_prompt_reason_restart_password" msgid="2375742919528461664">"Төхөөрөмжийг дахин эхлүүлэхийн тулд нууц үг шаардлагатай."</string>
+ <string name="kg_prompt_reason_timeout_pattern" msgid="8930047492617900785">"Аюулгүй байдлын үүднээс зурган түгжээ оруулах шаардлагатай."</string>
+ <string name="kg_prompt_reason_timeout_pin" msgid="7470468607947726377">"Аюулгүй байдлын үүднээс PIN оруулах шаардлагатай."</string>
+ <string name="kg_prompt_reason_timeout_password" msgid="1177412542773936957">"Аюулгүй байдлын үүднээс нууц үг оруулах шаардлагатай."</string>
<string name="kg_prompt_reason_switch_profiles_pattern" msgid="3802056699323773969">"Профайлыг солихын тулд зурган хээ шаардлагатай."</string>
<string name="kg_prompt_reason_switch_profiles_pin" msgid="8108020184731052246">"Профайлыг солихын тулд PIN шаардлагатай."</string>
<string name="kg_prompt_reason_switch_profiles_password" msgid="6755997057852042672">"Профайлыг солих үед нууц үг шаардлагатай."</string>
diff --git a/packages/Keyguard/res/values-mr-rIN/strings.xml b/packages/Keyguard/res/values-mr-rIN/strings.xml
index e98c2cb..3d9e901 100644
--- a/packages/Keyguard/res/values-mr-rIN/strings.xml
+++ b/packages/Keyguard/res/values-mr-rIN/strings.xml
@@ -31,6 +31,8 @@
<string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"अयोग्य पिन कोड."</string>
<string name="keyguard_charged" msgid="3272223906073492454">"चार्ज झाली"</string>
<string name="keyguard_plugged_in" msgid="9087497435553252863">"चार्ज होत आहे"</string>
+ <string name="keyguard_plugged_in_charging_fast" msgid="6671162730167305479">"दृतपणे चार्ज होत आहे"</string>
+ <string name="keyguard_plugged_in_charging_slowly" msgid="1964714661071163229">"धीमेपणे चार्ज होत आहे"</string>
<string name="keyguard_low_battery" msgid="8143808018719173859">"आपले चार्जर कनेक्ट करा."</string>
<string name="keyguard_instructions_when_pattern_disabled" msgid="1332288268600329841">"अनलॉक करण्यासाठी मेनू दाबा."</string>
<string name="keyguard_network_locked_message" msgid="9169717779058037168">"नेटवर्क लॉक केले"</string>
@@ -111,6 +113,9 @@
<string name="kg_prompt_reason_restart_pattern" msgid="489430505491862444">"आपण डिव्हाइस रीस्टार्ट करता तेव्हा नुमन्याची आवश्यकता असते."</string>
<string name="kg_prompt_reason_restart_pin" msgid="994878216570694974">"आपण डिव्हाइस रीस्टार्ट करता तेव्हा पिन ची आवश्यकता असते."</string>
<string name="kg_prompt_reason_restart_password" msgid="2375742919528461664">"आपण डिव्हाइस रीस्टार्ट करता तेव्हा संकेतशब्दाची आवश्यकता असते."</string>
+ <string name="kg_prompt_reason_timeout_pattern" msgid="8930047492617900785">"अतिरिक्त सुरक्षिततेसाठी नमुना आवश्यक आहे."</string>
+ <string name="kg_prompt_reason_timeout_pin" msgid="7470468607947726377">"अतिरिक्त सुरक्षिततेसाठी पिन आवश्यक आहे."</string>
+ <string name="kg_prompt_reason_timeout_password" msgid="1177412542773936957">"अतिरिक्त सुरक्षिततेसाठी संकेतशब्द आवश्यक आहे."</string>
<string name="kg_prompt_reason_switch_profiles_pattern" msgid="3802056699323773969">"आपण प्रोफाईल स्विच करता तेव्हा नमुन्याची आवश्यकता असते."</string>
<string name="kg_prompt_reason_switch_profiles_pin" msgid="8108020184731052246">"आपण प्रोफाईल स्विच करता तेव्हा पिन ची आवश्यकता असते."</string>
<string name="kg_prompt_reason_switch_profiles_password" msgid="6755997057852042672">"आपण प्रोफाईल स्विच करता तेव्हा संकेतशब्दाची आवश्यकता असते."</string>
diff --git a/packages/Keyguard/res/values-ms-rMY/strings.xml b/packages/Keyguard/res/values-ms-rMY/strings.xml
index 4a9243b..554aa12 100644
--- a/packages/Keyguard/res/values-ms-rMY/strings.xml
+++ b/packages/Keyguard/res/values-ms-rMY/strings.xml
@@ -31,6 +31,8 @@
<string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"Kod PIN salah."</string>
<string name="keyguard_charged" msgid="3272223906073492454">"Sudah dicas"</string>
<string name="keyguard_plugged_in" msgid="9087497435553252863">"Mengecas"</string>
+ <string name="keyguard_plugged_in_charging_fast" msgid="6671162730167305479">"Mengecas dengan cepat"</string>
+ <string name="keyguard_plugged_in_charging_slowly" msgid="1964714661071163229">"Mengecas dengan perlahan"</string>
<string name="keyguard_low_battery" msgid="8143808018719173859">"Sambungkan pengecas anda."</string>
<string name="keyguard_instructions_when_pattern_disabled" msgid="1332288268600329841">"Tekan Menu untuk membuka kunci."</string>
<string name="keyguard_network_locked_message" msgid="9169717779058037168">"Rangkaian dikunci"</string>
@@ -111,6 +113,9 @@
<string name="kg_prompt_reason_restart_pattern" msgid="489430505491862444">"Corak diperlukan apabila anda memulakan semula peranti."</string>
<string name="kg_prompt_reason_restart_pin" msgid="994878216570694974">"PIN diperlukan apabila anda memulakan semula peranti."</string>
<string name="kg_prompt_reason_restart_password" msgid="2375742919528461664">"Kata laluan diperlukan apabila anda memulakan semula peranti."</string>
+ <string name="kg_prompt_reason_timeout_pattern" msgid="8930047492617900785">"Corak diperlukan untuk keselamatan tambahan."</string>
+ <string name="kg_prompt_reason_timeout_pin" msgid="7470468607947726377">"PIN diperlukan untuk keselamatan tambahan."</string>
+ <string name="kg_prompt_reason_timeout_password" msgid="1177412542773936957">"Kata laluan diperlukan untuk keselamatan tambahan."</string>
<string name="kg_prompt_reason_switch_profiles_pattern" msgid="3802056699323773969">"Corak diperlukan apabila anda menukar profil."</string>
<string name="kg_prompt_reason_switch_profiles_pin" msgid="8108020184731052246">"PIN diperlukan apabila anda menukar profil."</string>
<string name="kg_prompt_reason_switch_profiles_password" msgid="6755997057852042672">"Kata laluan diperlukan apabila anda menukar profil."</string>
diff --git a/packages/Keyguard/res/values-my-rMM/strings.xml b/packages/Keyguard/res/values-my-rMM/strings.xml
index 084a44b..8cb4f32 100644
--- a/packages/Keyguard/res/values-my-rMM/strings.xml
+++ b/packages/Keyguard/res/values-my-rMM/strings.xml
@@ -31,6 +31,8 @@
<string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"ပင်နံပါတ်မှားနေပါသည်"</string>
<string name="keyguard_charged" msgid="3272223906073492454">"အားသွင်းနေပါသည်"</string>
<string name="keyguard_plugged_in" msgid="9087497435553252863">"အားသွင်းနေ"</string>
+ <string name="keyguard_plugged_in_charging_fast" msgid="6671162730167305479">"လျှင်မြန်စွာ အားသွင်းနေသည်"</string>
+ <string name="keyguard_plugged_in_charging_slowly" msgid="1964714661071163229">"နှေးကွေးစွာ အားသွင်းနေသည်"</string>
<string name="keyguard_low_battery" msgid="8143808018719173859">"အားသွင်းကြိုးဖြင့် ဆက်သွယ်ပါ"</string>
<string name="keyguard_instructions_when_pattern_disabled" msgid="1332288268600329841">"မီနူးကို နှိပ်ခြင်းဖြင့် သော့ဖွင့်ပါ"</string>
<string name="keyguard_network_locked_message" msgid="9169717779058037168">"ကွန်ရက် သော့ကျနေခြင်း"</string>
@@ -111,6 +113,9 @@
<string name="kg_prompt_reason_restart_pattern" msgid="489430505491862444">"သင့် စက်ကိရိယာအား ပြန်စဖွင့်လျှင် ပုံစံ လို၏။"</string>
<string name="kg_prompt_reason_restart_pin" msgid="994878216570694974">"သင့် စက်ကိရိယာအား ပြန်စဖွင့်လျှင် PIN လို၏။"</string>
<string name="kg_prompt_reason_restart_password" msgid="2375742919528461664">"သင့် စက်ကိရိယာအား ပြန်စဖွင့်လျှင် စကားဝှက် လို၏။"</string>
+ <string name="kg_prompt_reason_timeout_pattern" msgid="8930047492617900785">"ပိုပြီး လုံခြုံရန် ပုံစံ လိုအပ်တယ်။"</string>
+ <string name="kg_prompt_reason_timeout_pin" msgid="7470468607947726377">"ပိုပြီး လုံခြုံရန် ပင်နံပါတ် လိုအပ်တယ်။"</string>
+ <string name="kg_prompt_reason_timeout_password" msgid="1177412542773936957">"ပိုပြီး လုံခြုံရန် စကားဝှက် လိုအပ်တယ်။"</string>
<string name="kg_prompt_reason_switch_profiles_pattern" msgid="3802056699323773969">"ပရိုဖိုင်းများ သင်ပြောင်းလျှင် ပုံစံ လို၏။"</string>
<string name="kg_prompt_reason_switch_profiles_pin" msgid="8108020184731052246">"ပရိုဖိုင်းများ သင်ပြောင်းလျှင် PIN လို၏။"</string>
<string name="kg_prompt_reason_switch_profiles_password" msgid="6755997057852042672">"ပရိုဖိုင်းများ သင်ပြောင်းလျှင် စကားဝှက် လို၏။"</string>
diff --git a/packages/Keyguard/res/values-nb/strings.xml b/packages/Keyguard/res/values-nb/strings.xml
index d4b5c90..248f65d 100644
--- a/packages/Keyguard/res/values-nb/strings.xml
+++ b/packages/Keyguard/res/values-nb/strings.xml
@@ -31,6 +31,8 @@
<string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"Feil personlig kode."</string>
<string name="keyguard_charged" msgid="3272223906073492454">"Oppladet"</string>
<string name="keyguard_plugged_in" msgid="9087497435553252863">"Lader"</string>
+ <string name="keyguard_plugged_in_charging_fast" msgid="6671162730167305479">"Lader raskt"</string>
+ <string name="keyguard_plugged_in_charging_slowly" msgid="1964714661071163229">"Lader sakte"</string>
<string name="keyguard_low_battery" msgid="8143808018719173859">"Koble til laderen."</string>
<string name="keyguard_instructions_when_pattern_disabled" msgid="1332288268600329841">"Trykk på Meny for å låse opp."</string>
<string name="keyguard_network_locked_message" msgid="9169717779058037168">"Nettverk låst"</string>
@@ -111,6 +113,9 @@
<string name="kg_prompt_reason_restart_pattern" msgid="489430505491862444">"Du må tegne mønsteret ditt når du starter enheten på nytt."</string>
<string name="kg_prompt_reason_restart_pin" msgid="994878216570694974">"Du må skrive inn PIN-koden din når du starter enheten på nytt."</string>
<string name="kg_prompt_reason_restart_password" msgid="2375742919528461664">"Du må skrive inn passordet ditt når du starter enheten på nytt."</string>
+ <string name="kg_prompt_reason_timeout_pattern" msgid="8930047492617900785">"Mønsteret kreves for ekstra sikkerhet."</string>
+ <string name="kg_prompt_reason_timeout_pin" msgid="7470468607947726377">"PIN-koden kreves for ekstra sikkerhet."</string>
+ <string name="kg_prompt_reason_timeout_password" msgid="1177412542773936957">"Passordet kreves for ekstra sikkerhet."</string>
<string name="kg_prompt_reason_switch_profiles_pattern" msgid="3802056699323773969">"Du må tegne mønsteret ditt når du bytter profil."</string>
<string name="kg_prompt_reason_switch_profiles_pin" msgid="8108020184731052246">"Du må skrive inn PIN-koden din når du bytter profil."</string>
<string name="kg_prompt_reason_switch_profiles_password" msgid="6755997057852042672">"Du må skrive inn passordet ditt når du bytter profil."</string>
diff --git a/packages/Keyguard/res/values-ne-rNP/strings.xml b/packages/Keyguard/res/values-ne-rNP/strings.xml
index 9d42493..d18d0f2 100644
--- a/packages/Keyguard/res/values-ne-rNP/strings.xml
+++ b/packages/Keyguard/res/values-ne-rNP/strings.xml
@@ -31,6 +31,8 @@
<string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"गलत PIN कोड।"</string>
<string name="keyguard_charged" msgid="3272223906073492454">"चार्ज भयो"</string>
<string name="keyguard_plugged_in" msgid="9087497435553252863">"चार्ज हुँदै"</string>
+ <string name="keyguard_plugged_in_charging_fast" msgid="6671162730167305479">"छिटो चार्ज हुँदै"</string>
+ <string name="keyguard_plugged_in_charging_slowly" msgid="1964714661071163229">"बिस्तारै चार्ज हुँदै"</string>
<string name="keyguard_low_battery" msgid="8143808018719173859">"तपाईँको चार्जर जोड्नुहोस्।"</string>
<string name="keyguard_instructions_when_pattern_disabled" msgid="1332288268600329841">"अनलक गर्न मेनु थिच्नुहोस्।"</string>
<string name="keyguard_network_locked_message" msgid="9169717779058037168">"नेटवर्क लक गरिएको छ"</string>
@@ -111,6 +113,9 @@
<string name="kg_prompt_reason_restart_pattern" msgid="489430505491862444">"यन्त्र पुन:सुरू गर्न तपाईँलाई ढाँचा चाहिन्छ।"</string>
<string name="kg_prompt_reason_restart_pin" msgid="994878216570694974">"यन्त्र पुन:सुरू गर्न तपाईँलाई PIN चाहिन्छ।"</string>
<string name="kg_prompt_reason_restart_password" msgid="2375742919528461664">"यन्त्र पुन:सुरू गर्न तपाईँलाई पासवर्ड चाहिन्छ।"</string>
+ <string name="kg_prompt_reason_timeout_pattern" msgid="8930047492617900785">"अतिरिक्त सुरक्षाको लागि ढाँचा आवश्यक छ।"</string>
+ <string name="kg_prompt_reason_timeout_pin" msgid="7470468607947726377">"अतिरिक्त सुरक्षाको लागि PIN आवश्यक छ।"</string>
+ <string name="kg_prompt_reason_timeout_password" msgid="1177412542773936957">"अतिरिक्त सुरक्षाको लागि पासवर्ड आवश्यक छ।"</string>
<string name="kg_prompt_reason_switch_profiles_pattern" msgid="3802056699323773969">"प्रोफाइल फेर्न तपाईँलाई ढाँचा चाहिन्छ।"</string>
<string name="kg_prompt_reason_switch_profiles_pin" msgid="8108020184731052246">"प्रोफाइल फेर्न तपाईँलाई PIN चाहिन्छ।"</string>
<string name="kg_prompt_reason_switch_profiles_password" msgid="6755997057852042672">"प्रोफाइल फेर्न तपाईँलाई पासवर्ड चाहिन्छ।"</string>
diff --git a/packages/Keyguard/res/values-nl/strings.xml b/packages/Keyguard/res/values-nl/strings.xml
index b15c08ef..35caf77 100644
--- a/packages/Keyguard/res/values-nl/strings.xml
+++ b/packages/Keyguard/res/values-nl/strings.xml
@@ -31,6 +31,8 @@
<string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"Onjuiste pincode."</string>
<string name="keyguard_charged" msgid="3272223906073492454">"Opgeladen"</string>
<string name="keyguard_plugged_in" msgid="9087497435553252863">"Opladen"</string>
+ <string name="keyguard_plugged_in_charging_fast" msgid="6671162730167305479">"Snel opladen"</string>
+ <string name="keyguard_plugged_in_charging_slowly" msgid="1964714661071163229">"Langzaam opladen"</string>
<string name="keyguard_low_battery" msgid="8143808018719173859">"Sluit de oplader aan."</string>
<string name="keyguard_instructions_when_pattern_disabled" msgid="1332288268600329841">"Druk op \'Menu\' om te ontgrendelen."</string>
<string name="keyguard_network_locked_message" msgid="9169717779058037168">"Netwerk vergrendeld"</string>
@@ -40,7 +42,7 @@
<string name="keyguard_missing_sim_instructions" msgid="5210891509995942250">"Plaats een simkaart."</string>
<string name="keyguard_missing_sim_instructions_long" msgid="5968985489463870358">"De simkaart ontbreekt of kan niet worden gelezen. Plaats een simkaart."</string>
<string name="keyguard_permanent_disabled_sim_message_short" msgid="8340813989586622356">"Onbruikbare simkaart."</string>
- <string name="keyguard_permanent_disabled_sim_instructions" msgid="5892940909699723544">"Uw simkaart is permanent uitgeschakeld.\n Neem contact op met uw mobiele serviceprovider voor een nieuwe simkaart."</string>
+ <string name="keyguard_permanent_disabled_sim_instructions" msgid="5892940909699723544">"Je simkaart is permanent uitgeschakeld.\n Neem contact op met je mobiele serviceprovider voor een nieuwe simkaart."</string>
<string name="keyguard_sim_locked_message" msgid="6875773413306380902">"Simkaart is vergrendeld."</string>
<string name="keyguard_sim_puk_locked_message" msgid="3747232467471801633">"Simkaart is vergrendeld met PUK-code."</string>
<string name="keyguard_sim_unlock_progress_dialog_message" msgid="7975221805033614426">"Simkaart ontgrendelen…"</string>
@@ -60,13 +62,13 @@
<string name="kg_wrong_password" msgid="2333281762128113157">"Onjuist wachtwoord"</string>
<string name="kg_wrong_pin" msgid="1131306510833563801">"Onjuiste pincode"</string>
<string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"Probeer het over <xliff:g id="NUMBER">%d</xliff:g> seconden opnieuw."</string>
- <string name="kg_pattern_instructions" msgid="398978611683075868">"Teken uw patroon"</string>
+ <string name="kg_pattern_instructions" msgid="398978611683075868">"Teken je patroon"</string>
<string name="kg_sim_pin_instructions" msgid="2319508550934557331">"Geef de pincode van de simkaart op"</string>
<string name="kg_sim_pin_instructions_multi" msgid="7818515973197201434">"Voer de pincode in voor de simkaart van \'<xliff:g id="CARRIER">%1$s</xliff:g>\'"</string>
<string name="kg_pin_instructions" msgid="2377242233495111557">"Pincode opgeven"</string>
<string name="kg_password_instructions" msgid="5753646556186936819">"Wachtwoord invoeren"</string>
<string name="kg_puk_enter_puk_hint" msgid="453227143861735537">"De simkaart is nu uitgeschakeld. Geef de PUK-code op om door te gaan. Neem contact op met de provider voor informatie."</string>
- <string name="kg_puk_enter_puk_hint_multi" msgid="363822494559783025">"Simkaart van \'<xliff:g id="CARRIER">%1$s</xliff:g>\' is nu uitgeschakeld. Voer de PUK-code in om door te gaan. Neem contact op met uw provider voor meer informatie."</string>
+ <string name="kg_puk_enter_puk_hint_multi" msgid="363822494559783025">"Simkaart van \'<xliff:g id="CARRIER">%1$s</xliff:g>\' is nu uitgeschakeld. Voer de PUK-code in om door te gaan. Neem contact op met je provider voor meer informatie."</string>
<string name="kg_puk_enter_pin_hint" msgid="7871604527429602024">"Gewenste pincode opgeven"</string>
<string name="kg_enter_confirm_pin_hint" msgid="325676184762529976">"Gewenste pincode bevestigen"</string>
<string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"Simkaart ontgrendelen..."</string>
@@ -75,32 +77,32 @@
<string name="kg_invalid_puk" msgid="3638289409676051243">"Geef de juiste PUK-code opnieuw op. Bij herhaalde pogingen wordt de simkaart permanent uitgeschakeld."</string>
<string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"Pincodes komen niet overeen"</string>
<string name="kg_login_too_many_attempts" msgid="6486842094005698475">"Te veel patroonpogingen"</string>
- <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"U heeft uw pincode <xliff:g id="NUMBER_0">%d</xliff:g> keer onjuist getypt. \n\nProbeer het opnieuw over <xliff:g id="NUMBER_1">%d</xliff:g> seconden."</string>
- <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"U heeft uw wachtwoord <xliff:g id="NUMBER_0">%d</xliff:g> keer onjuist getypt. \n\nProbeer het opnieuw over <xliff:g id="NUMBER_1">%d</xliff:g> seconden."</string>
- <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"U heeft uw ontgrendelingspatroon <xliff:g id="NUMBER_0">%d</xliff:g> keer onjuist getekend. \n\nProbeer het opnieuw over <xliff:g id="NUMBER_1">%d</xliff:g> seconden."</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="8774056606869646621">"U heeft <xliff:g id="NUMBER_0">%d</xliff:g> mislukte pogingen ondernomen om de tablet te ontgrendelen. Na nog eens <xliff:g id="NUMBER_1">%d</xliff:g> mislukte pogingen wordt deze tablet gereset, waardoor alle gegevens worden verwijderd."</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="1843331751334128428">"U heeft <xliff:g id="NUMBER_0">%d</xliff:g> mislukte pogingen ondernomen om de telefoon te ontgrendelen. Na nog eens <xliff:g id="NUMBER_1">%d</xliff:g> mislukte pogingen wordt deze telefoon gereset, waardoor alle gegevens worden verwijderd."</string>
- <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="258925501999698032">"U heeft <xliff:g id="NUMBER">%d</xliff:g> mislukte pogingen ondernomen om de tablet te ontgrendelen. Deze tablet wordt gereset, waardoor alle gegevens worden verwijderd."</string>
- <string name="kg_failed_attempts_now_wiping" product="default" msgid="7154028908459817066">"U heeft <xliff:g id="NUMBER">%d</xliff:g> mislukte pogingen ondernomen om de telefoon te ontgrendelen. Deze telefoon wordt gereset, waardoor alle gegevens worden verwijderd."</string>
- <string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="6159955099372112688">"U heeft <xliff:g id="NUMBER_0">%d</xliff:g> mislukte pogingen ondernomen om de tablet te ontgrendelen. Na nog eens <xliff:g id="NUMBER_1">%d</xliff:g> mislukte pogingen wordt deze gebruiker verwijderd, waardoor alle gebruikersgegevens worden verwijderd."</string>
- <string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="6945823186629369880">"U heeft <xliff:g id="NUMBER_0">%d</xliff:g> mislukte pogingen ondernomen om de telefoon te ontgrendelen. Na nog eens <xliff:g id="NUMBER_1">%d</xliff:g> mislukte pogingen wordt deze gebruiker verwijderd, waardoor alle gebruikersgegevens worden verwijderd."</string>
- <string name="kg_failed_attempts_now_erasing_user" product="tablet" msgid="3963486905355778734">"U heeft <xliff:g id="NUMBER">%d</xliff:g> mislukte pogingen ondernomen om de tablet te ontgrendelen. Deze gebruiker wordt verwijderd, waardoor alle gebruikersgegevens worden verwijderd."</string>
- <string name="kg_failed_attempts_now_erasing_user" product="default" msgid="7729009752252111673">"U heeft <xliff:g id="NUMBER">%d</xliff:g> mislukte pogingen ondernomen om de telefoon te ontgrendelen. Deze gebruiker wordt verwijderd, waardoor alle gebruikersgegevens worden verwijderd."</string>
- <string name="kg_failed_attempts_almost_at_erase_profile" product="tablet" msgid="4621778507387853694">"U heeft <xliff:g id="NUMBER_0">%d</xliff:g> mislukte pogingen ondernomen om de tablet te ontgrendelen. Na nog eens <xliff:g id="NUMBER_1">%d</xliff:g> mislukte pogingen wordt het werkprofiel verwijderd, waardoor alle profielgegevens worden verwijderd."</string>
- <string name="kg_failed_attempts_almost_at_erase_profile" product="default" msgid="6853071165802933545">"U heeft <xliff:g id="NUMBER_0">%d</xliff:g> mislukte pogingen ondernomen om de telefoon te ontgrendelen. Na nog eens <xliff:g id="NUMBER_1">%d</xliff:g> mislukte pogingen wordt het werkprofiel verwijderd, waardoor alle profielgegevens worden verwijderd."</string>
- <string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="4686386497449912146">"U heeft <xliff:g id="NUMBER">%d</xliff:g> mislukte pogingen ondernomen om de tablet te ontgrendelen. Het werkprofiel wordt verwijderd, waardoor alle profielgegevens worden verwijderd."</string>
- <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="4951507352869831265">"U heeft <xliff:g id="NUMBER">%d</xliff:g> mislukte pogingen ondernomen om de telefoon te ontgrendelen. Het werkprofiel wordt verwijderd, waardoor alle profielgegevens worden verwijderd."</string>
- <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"U heeft uw ontgrendelingspatroon <xliff:g id="NUMBER_0">%d</xliff:g> keer onjuist getekend. Na nog eens <xliff:g id="NUMBER_1">%d</xliff:g> mislukte pogingen wordt u gevraagd uw tablet te ontgrendelen via een e-mailaccount.\n\n Probeer het over <xliff:g id="NUMBER_2">%d</xliff:g> seconden opnieuw."</string>
- <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"U heeft uw ontgrendelingspatroon <xliff:g id="NUMBER_0">%d</xliff:g> keer onjuist getekend. Na nog eens <xliff:g id="NUMBER_1">%d</xliff:g> mislukte pogingen wordt u gevraagd uw telefoon te ontgrendelen via een e-mailaccount.\n\n Probeer het over <xliff:g id="NUMBER_2">%d</xliff:g> seconden opnieuw."</string>
- <string name="kg_password_wrong_pin_code_pukked" msgid="30531039455764924">"Onjuiste pincode voor simkaart. U moet nu contact opnemen met uw provider om uw apparaat te ontgrendelen."</string>
+ <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Je hebt je pincode <xliff:g id="NUMBER_0">%d</xliff:g> keer onjuist getypt. \n\nProbeer het opnieuw over <xliff:g id="NUMBER_1">%d</xliff:g> seconden."</string>
+ <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Je hebt je wachtwoord <xliff:g id="NUMBER_0">%d</xliff:g> keer onjuist getypt. \n\nProbeer het opnieuw over <xliff:g id="NUMBER_1">%d</xliff:g> seconden."</string>
+ <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Je hebt je ontgrendelingspatroon <xliff:g id="NUMBER_0">%d</xliff:g> keer onjuist getekend. \n\nProbeer het opnieuw over <xliff:g id="NUMBER_1">%d</xliff:g> seconden."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="8774056606869646621">"Je hebt <xliff:g id="NUMBER_0">%d</xliff:g> mislukte pogingen ondernomen om de tablet te ontgrendelen. Na nog eens <xliff:g id="NUMBER_1">%d</xliff:g> mislukte pogingen wordt deze tablet gereset, waardoor alle gegevens worden verwijderd."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="1843331751334128428">"Je hebt <xliff:g id="NUMBER_0">%d</xliff:g> mislukte pogingen ondernomen om de telefoon te ontgrendelen. Na nog eens <xliff:g id="NUMBER_1">%d</xliff:g> mislukte pogingen wordt deze telefoon gereset, waardoor alle gegevens worden verwijderd."</string>
+ <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="258925501999698032">"Je hebt <xliff:g id="NUMBER">%d</xliff:g> mislukte pogingen ondernomen om de tablet te ontgrendelen. Deze tablet wordt gereset, waardoor alle gegevens worden verwijderd."</string>
+ <string name="kg_failed_attempts_now_wiping" product="default" msgid="7154028908459817066">"Je hebt <xliff:g id="NUMBER">%d</xliff:g> mislukte pogingen ondernomen om de telefoon te ontgrendelen. Deze telefoon wordt gereset, waardoor alle gegevens worden verwijderd."</string>
+ <string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="6159955099372112688">"Je hebt <xliff:g id="NUMBER_0">%d</xliff:g> mislukte pogingen ondernomen om de tablet te ontgrendelen. Na nog eens <xliff:g id="NUMBER_1">%d</xliff:g> mislukte pogingen wordt deze gebruiker verwijderd, waardoor alle gebruikersgegevens worden verwijderd."</string>
+ <string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="6945823186629369880">"Je hebt <xliff:g id="NUMBER_0">%d</xliff:g> mislukte pogingen ondernomen om de telefoon te ontgrendelen. Na nog eens <xliff:g id="NUMBER_1">%d</xliff:g> mislukte pogingen wordt deze gebruiker verwijderd, waardoor alle gebruikersgegevens worden verwijderd."</string>
+ <string name="kg_failed_attempts_now_erasing_user" product="tablet" msgid="3963486905355778734">"Je hebt <xliff:g id="NUMBER">%d</xliff:g> mislukte pogingen ondernomen om de tablet te ontgrendelen. Deze gebruiker wordt verwijderd, waardoor alle gebruikersgegevens worden verwijderd."</string>
+ <string name="kg_failed_attempts_now_erasing_user" product="default" msgid="7729009752252111673">"Je hebt <xliff:g id="NUMBER">%d</xliff:g> mislukte pogingen ondernomen om de telefoon te ontgrendelen. Deze gebruiker wordt verwijderd, waardoor alle gebruikersgegevens worden verwijderd."</string>
+ <string name="kg_failed_attempts_almost_at_erase_profile" product="tablet" msgid="4621778507387853694">"Je hebt <xliff:g id="NUMBER_0">%d</xliff:g> mislukte pogingen ondernomen om de tablet te ontgrendelen. Na nog eens <xliff:g id="NUMBER_1">%d</xliff:g> mislukte pogingen wordt het werkprofiel verwijderd, waardoor alle profielgegevens worden verwijderd."</string>
+ <string name="kg_failed_attempts_almost_at_erase_profile" product="default" msgid="6853071165802933545">"Je hebt <xliff:g id="NUMBER_0">%d</xliff:g> mislukte pogingen ondernomen om de telefoon te ontgrendelen. Na nog eens <xliff:g id="NUMBER_1">%d</xliff:g> mislukte pogingen wordt het werkprofiel verwijderd, waardoor alle profielgegevens worden verwijderd."</string>
+ <string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="4686386497449912146">"Je hebt <xliff:g id="NUMBER">%d</xliff:g> mislukte pogingen ondernomen om de tablet te ontgrendelen. Het werkprofiel wordt verwijderd, waardoor alle profielgegevens worden verwijderd."</string>
+ <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="4951507352869831265">"Je hebt <xliff:g id="NUMBER">%d</xliff:g> mislukte pogingen ondernomen om de telefoon te ontgrendelen. Het werkprofiel wordt verwijderd, waardoor alle profielgegevens worden verwijderd."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Je hebt je ontgrendelingspatroon <xliff:g id="NUMBER_0">%d</xliff:g> keer onjuist getekend. Na nog eens <xliff:g id="NUMBER_1">%d</xliff:g> mislukte pogingen wordt u gevraagd je tablet te ontgrendelen via een e-mailaccount.\n\n Probeer het over <xliff:g id="NUMBER_2">%d</xliff:g> seconden opnieuw."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Je hebt je ontgrendelingspatroon <xliff:g id="NUMBER_0">%d</xliff:g> keer onjuist getekend. Na nog eens <xliff:g id="NUMBER_1">%d</xliff:g> mislukte pogingen wordt u gevraagd je telefoon te ontgrendelen via een e-mailaccount.\n\n Probeer het over <xliff:g id="NUMBER_2">%d</xliff:g> seconden opnieuw."</string>
+ <string name="kg_password_wrong_pin_code_pukked" msgid="30531039455764924">"Onjuiste pincode voor simkaart. U moet nu contact opnemen met je provider om je apparaat te ontgrendelen."</string>
<plurals name="kg_password_wrong_pin_code" formatted="false" msgid="6721575017538162249">
- <item quantity="other">Onjuiste pincode voor simkaart. U heeft nog <xliff:g id="NUMBER_1">%d</xliff:g> pogingen over.</item>
- <item quantity="one">Onjuiste pincode voor simkaart. U heeft nog <xliff:g id="NUMBER_0">%d</xliff:g> poging over voordat u contact met uw provider moet opnemen om uw apparaat te ontgrendelen.</item>
+ <item quantity="other">Onjuiste pincode voor simkaart. Je hebt nog <xliff:g id="NUMBER_1">%d</xliff:g> pogingen over.</item>
+ <item quantity="one">Onjuiste pincode voor simkaart. Je hebt nog <xliff:g id="NUMBER_0">%d</xliff:g> poging over voordat u contact met je provider moet opnemen om je apparaat te ontgrendelen.</item>
</plurals>
- <string name="kg_password_wrong_puk_code_dead" msgid="7077536808291316208">"Simkaart is onbruikbaar. Neem contact op met uw provider."</string>
+ <string name="kg_password_wrong_puk_code_dead" msgid="7077536808291316208">"Simkaart is onbruikbaar. Neem contact op met je provider."</string>
<plurals name="kg_password_wrong_puk_code" formatted="false" msgid="7576227366999858780">
- <item quantity="other">Onjuiste pukcode voor simkaart. U heeft nog <xliff:g id="NUMBER_1">%d</xliff:g> pogingen over voordat de simkaart definitief onbruikbaar wordt.</item>
- <item quantity="one">Onjuiste pukcode voor simkaart. U heeft nog <xliff:g id="NUMBER_0">%d</xliff:g> poging over voordat de simkaart definitief onbruikbaar wordt.</item>
+ <item quantity="other">Onjuiste pukcode voor simkaart. Je hebt nog <xliff:g id="NUMBER_1">%d</xliff:g> pogingen over voordat de simkaart definitief onbruikbaar wordt.</item>
+ <item quantity="one">Onjuiste pukcode voor simkaart. Je hebt nog <xliff:g id="NUMBER_0">%d</xliff:g> poging over voordat de simkaart definitief onbruikbaar wordt.</item>
</plurals>
<string name="kg_password_pin_failed" msgid="6268288093558031564">"Bewerking met pincode voor simkaart mislukt."</string>
<string name="kg_password_puk_failed" msgid="2838824369502455984">"Bewerking met pukcode voor simkaart is mislukt."</string>
@@ -111,6 +113,9 @@
<string name="kg_prompt_reason_restart_pattern" msgid="489430505491862444">"Patroon is vereist wanneer u het apparaat opnieuw opstart."</string>
<string name="kg_prompt_reason_restart_pin" msgid="994878216570694974">"Pincode is vereist wanneer u het apparaat opnieuw opstart."</string>
<string name="kg_prompt_reason_restart_password" msgid="2375742919528461664">"Wachtwoord is vereist wanneer u het apparaat opnieuw opstart."</string>
+ <string name="kg_prompt_reason_timeout_pattern" msgid="8930047492617900785">"Patroon vereist voor extra beveiliging."</string>
+ <string name="kg_prompt_reason_timeout_pin" msgid="7470468607947726377">"Pincode vereist voor extra beveiliging."</string>
+ <string name="kg_prompt_reason_timeout_password" msgid="1177412542773936957">"Wachtwoord vereist voor extra beveiliging."</string>
<string name="kg_prompt_reason_switch_profiles_pattern" msgid="3802056699323773969">"Patroon is vereist wanneer u schakelt tussen profielen."</string>
<string name="kg_prompt_reason_switch_profiles_pin" msgid="8108020184731052246">"Pincode is vereist wanneer u schakelt tussen profielen."</string>
<string name="kg_prompt_reason_switch_profiles_password" msgid="6755997057852042672">"Wachtwoord is vereist wanneer u schakelt tussen profielen."</string>
diff --git a/packages/Keyguard/res/values-pa-rIN/strings.xml b/packages/Keyguard/res/values-pa-rIN/strings.xml
index b2bb788..8486b63 100644
--- a/packages/Keyguard/res/values-pa-rIN/strings.xml
+++ b/packages/Keyguard/res/values-pa-rIN/strings.xml
@@ -31,6 +31,8 @@
<string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"ਗ਼ਲਤ PIN ਕੋਡ।"</string>
<string name="keyguard_charged" msgid="3272223906073492454">"ਚਾਰਜ ਕੀਤਾ"</string>
<string name="keyguard_plugged_in" msgid="9087497435553252863">"ਚਾਰਜਿੰਗ"</string>
+ <string name="keyguard_plugged_in_charging_fast" msgid="6671162730167305479">"ਤੇਜ਼ੀ ਨਾਲ ਚਾਰਜ ਹੋ ਰਿਹਾ ਹੈ"</string>
+ <string name="keyguard_plugged_in_charging_slowly" msgid="1964714661071163229">"ਹੌਲੀ-ਹੌਲੀ ਚਾਰਜ ਹੋ ਰਿਹਾ ਹੈ"</string>
<string name="keyguard_low_battery" msgid="8143808018719173859">"ਆਪਣਾ ਚਾਰਜਰ ਕਨੈਕਟ ਕਰੋ।"</string>
<string name="keyguard_instructions_when_pattern_disabled" msgid="1332288268600329841">"ਅਨਲੌਕ ਕਰਨ ਲਈ ਮੀਨੂ ਦਬਾਓ।"</string>
<string name="keyguard_network_locked_message" msgid="9169717779058037168">"ਨੈਟਵਰਕ ਲੌਕ ਕੀਤਾ"</string>
@@ -111,6 +113,9 @@
<string name="kg_prompt_reason_restart_pattern" msgid="489430505491862444">"ਜਦੋਂ ਤੁਸੀਂ ਡਿਵਾਈਸ ਨੂੰ ਰੀਸਟਾਰਟ ਕਰਦੇ ਹੋ ਤਾਂ ਪੈਟਰਨ ਲੁੜੀਂਦਾ ਹੈ।"</string>
<string name="kg_prompt_reason_restart_pin" msgid="994878216570694974">"ਜਦੋਂ ਤੁਸੀਂ ਡਿਵਾਈਸ ਨੂੰ ਰੀਸਟਾਰਟ ਕਰਦੇ ਹੋ ਤਾਂ PIN ਲੁੜੀਂਦਾ ਹੈ।"</string>
<string name="kg_prompt_reason_restart_password" msgid="2375742919528461664">"ਜਦੋਂ ਤੁਸੀਂ ਡਿਵਾਈਸ ਨੂੰ ਰੀਸਟਾਰਟ ਕਰਦੇ ਹੋ ਤਾਂ ਪਾਸਵਰਡ ਲੁੜੀਂਦਾ ਹੈ।"</string>
+ <string name="kg_prompt_reason_timeout_pattern" msgid="8930047492617900785">"ਵਾਧੂ ਸੁਰੱਖਿਆ ਲਈ ਪੈਟਰਨ ਲੁੜੀਂਦਾ ਹੈ।"</string>
+ <string name="kg_prompt_reason_timeout_pin" msgid="7470468607947726377">"ਵਾਧੂ ਸੁਰੱਖਿਆ ਲਈ PIN ਲੁੜੀਂਦਾ ਹੈ।"</string>
+ <string name="kg_prompt_reason_timeout_password" msgid="1177412542773936957">"ਵਾਧੂ ਸੁਰੱਖਿਆ ਲਈ ਪਾਸਵਰਡ ਲੁੜੀਂਦਾ ਹੈ।"</string>
<string name="kg_prompt_reason_switch_profiles_pattern" msgid="3802056699323773969">"ਜਦੋਂ ਤੁਸੀਂ ਪ੍ਰੋਫਾਈਲਾਂ ਸਵਿਚ ਕਰਦੇ ਹੋ ਤਾਂ ਪੈਟਰਨ ਲੁੜੀਂਦਾ ਹੈ।"</string>
<string name="kg_prompt_reason_switch_profiles_pin" msgid="8108020184731052246">"ਜਦੋਂ ਤੁਸੀਂ ਪ੍ਰੋਫਾਈਲਾਂ ਸਵਿਚ ਕਰਦੇ ਹੋ ਤਾਂ PIN ਲੁੜੀਂਦਾ ਹੈ।"</string>
<string name="kg_prompt_reason_switch_profiles_password" msgid="6755997057852042672">"ਜਦੋਂ ਤੁਸੀਂ ਪ੍ਰੋਫਾਈਲਾਂ ਸਵਿਚ ਕਰਦੇ ਹੋ ਤਾਂ ਪਾਸਵਰਡ ਲੁੜੀਂਦਾ ਹੈ।"</string>
diff --git a/packages/Keyguard/res/values-pl/strings.xml b/packages/Keyguard/res/values-pl/strings.xml
index b552926..04930c5 100644
--- a/packages/Keyguard/res/values-pl/strings.xml
+++ b/packages/Keyguard/res/values-pl/strings.xml
@@ -31,6 +31,8 @@
<string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"Błędny kod PIN"</string>
<string name="keyguard_charged" msgid="3272223906073492454">"Naładowana"</string>
<string name="keyguard_plugged_in" msgid="9087497435553252863">"Ładowanie"</string>
+ <string name="keyguard_plugged_in_charging_fast" msgid="6671162730167305479">"Szybkie ładowanie"</string>
+ <string name="keyguard_plugged_in_charging_slowly" msgid="1964714661071163229">"Wolne ładowanie"</string>
<string name="keyguard_low_battery" msgid="8143808018719173859">"Podłącz ładowarkę."</string>
<string name="keyguard_instructions_when_pattern_disabled" msgid="1332288268600329841">"Naciśnij Menu, by odblokować."</string>
<string name="keyguard_network_locked_message" msgid="9169717779058037168">"Zablokowana sieć"</string>
@@ -115,6 +117,9 @@
<string name="kg_prompt_reason_restart_pattern" msgid="489430505491862444">"Po ponownym uruchomieniu urządzenia wymagany jest wzór."</string>
<string name="kg_prompt_reason_restart_pin" msgid="994878216570694974">"Po ponownym uruchomieniu urządzenia wymagany jest kod PIN."</string>
<string name="kg_prompt_reason_restart_password" msgid="2375742919528461664">"Po ponownym uruchomieniu urządzenia wymagane jest hasło."</string>
+ <string name="kg_prompt_reason_timeout_pattern" msgid="8930047492617900785">"Dla dodatkowego bezpieczeństwa musisz narysować wzór."</string>
+ <string name="kg_prompt_reason_timeout_pin" msgid="7470468607947726377">"Dla dodatkowego bezpieczeństwa musisz podać kod PIN."</string>
+ <string name="kg_prompt_reason_timeout_password" msgid="1177412542773936957">"Dla dodatkowego bezpieczeństwa musisz podać hasło."</string>
<string name="kg_prompt_reason_switch_profiles_pattern" msgid="3802056699323773969">"Po przełączeniu profili wymagany jest wzór."</string>
<string name="kg_prompt_reason_switch_profiles_pin" msgid="8108020184731052246">"Po przełączeniu profili wymagany jest kod PIN."</string>
<string name="kg_prompt_reason_switch_profiles_password" msgid="6755997057852042672">"Po przełączeniu profili wymagane jest hasło."</string>
@@ -136,5 +141,5 @@
<item quantity="other">Urządzenie nie zostało odblokowane od <xliff:g id="NUMBER_1">%d</xliff:g> godziny. Potwierdź hasło.</item>
<item quantity="one">Urządzenie nie zostało odblokowane od <xliff:g id="NUMBER_0">%d</xliff:g> godziny. Potwierdź hasło.</item>
</plurals>
- <string name="fingerprint_not_recognized" msgid="2690661881608146617">"Nie rozpoznano"</string>
+ <string name="fingerprint_not_recognized" msgid="2690661881608146617">"Nie rozpoznano odcisku palca."</string>
</resources>
diff --git a/packages/Keyguard/res/values-pt-rBR/strings.xml b/packages/Keyguard/res/values-pt-rBR/strings.xml
new file mode 100644
index 0000000..0ef07e5
--- /dev/null
+++ b/packages/Keyguard/res/values-pt-rBR/strings.xml
@@ -0,0 +1,135 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, 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.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="719438068451601849">"Bloqueio do teclado"</string>
+ <string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"Insira o código PIN"</string>
+ <string name="keyguard_password_enter_puk_code" msgid="3035856550289724338">"Digite o PUK do SIM e o novo código PIN."</string>
+ <string name="keyguard_password_enter_puk_prompt" msgid="1801941051094974609">"Código PUK do SIM"</string>
+ <string name="keyguard_password_enter_pin_prompt" msgid="3201151840570492538">"Novo código PIN do SIM"</string>
+ <string name="keyguard_password_entry_touch_hint" msgid="7858547464982981384"><font size="17">"Toque para inserir a senha"</font></string>
+ <string name="keyguard_password_enter_password_code" msgid="1054721668279049780">"Digite a senha para desbloquear"</string>
+ <string name="keyguard_password_enter_pin_password_code" msgid="6391755146112503443">"Insira o PIN para desbloquear"</string>
+ <string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"Código PIN incorreto."</string>
+ <string name="keyguard_charged" msgid="3272223906073492454">"Carregado"</string>
+ <string name="keyguard_plugged_in" msgid="9087497435553252863">"Carregando"</string>
+ <string name="keyguard_plugged_in_charging_fast" msgid="6671162730167305479">"Carregando rapidamente"</string>
+ <string name="keyguard_plugged_in_charging_slowly" msgid="1964714661071163229">"Carregando lentamente"</string>
+ <string name="keyguard_low_battery" msgid="8143808018719173859">"Conecte seu carregador."</string>
+ <string name="keyguard_instructions_when_pattern_disabled" msgid="1332288268600329841">"Pressione \"Menu\" para desbloquear."</string>
+ <string name="keyguard_network_locked_message" msgid="9169717779058037168">"Rede bloqueada"</string>
+ <string name="keyguard_missing_sim_message_short" msgid="494980561304211931">"Sem cartão SIM"</string>
+ <string name="keyguard_missing_sim_message" product="tablet" msgid="1445849005909260039">"Não há um cartão SIM no tablet."</string>
+ <string name="keyguard_missing_sim_message" product="default" msgid="3481110395508637643">"Não há um cartão SIM no telefone."</string>
+ <string name="keyguard_missing_sim_instructions" msgid="5210891509995942250">"Insira um cartão SIM."</string>
+ <string name="keyguard_missing_sim_instructions_long" msgid="5968985489463870358">"O cartão SIM não foi inserido ou não é possível lê-lo. Insira um cartão SIM."</string>
+ <string name="keyguard_permanent_disabled_sim_message_short" msgid="8340813989586622356">"Cartão SIM inutilizável."</string>
+ <string name="keyguard_permanent_disabled_sim_instructions" msgid="5892940909699723544">"O cartão SIM foi desativado permanentemente.\nEntre em contato com seu provedor de serviços sem fio para receber outro cartão SIM."</string>
+ <string name="keyguard_sim_locked_message" msgid="6875773413306380902">"O cartão SIM está bloqueado."</string>
+ <string name="keyguard_sim_puk_locked_message" msgid="3747232467471801633">"O cartão SIM está bloqueado pelo PUK."</string>
+ <string name="keyguard_sim_unlock_progress_dialog_message" msgid="7975221805033614426">"Desbloqueando o cartão SIM…"</string>
+ <string name="keyguard_accessibility_pattern_unlock" msgid="1490840706075246612">"Desbloqueio com padrão."</string>
+ <string name="keyguard_accessibility_pin_unlock" msgid="2469687111784035046">"Desbloqueio com PIN."</string>
+ <string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"Desbloqueio com senha."</string>
+ <string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"Área do padrão."</string>
+ <string name="keyguard_accessibility_slide_area" msgid="6736064494019979544">"Área de deslize."</string>
+ <string name="keyguard_accessibility_pin_area" msgid="7903959476607833485">"Área do PIN"</string>
+ <string name="keyguard_accessibility_sim_pin_area" msgid="3887780775111719336">"Área do PIN SIM"</string>
+ <string name="keyguard_accessibility_sim_puk_area" msgid="1880823406954996207">"Área do PUK SIM"</string>
+ <string name="keyguard_accessibility_next_alarm" msgid="7269583073750518672">"Próximo alarme definido para <xliff:g id="ALARM">%1$s</xliff:g>"</string>
+ <string name="keyboardview_keycode_delete" msgid="3337914833206635744">"Excluir"</string>
+ <string name="keyboardview_keycode_enter" msgid="2985864015076059467">"Enter"</string>
+ <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Esqueci o padrão"</string>
+ <string name="kg_wrong_pattern" msgid="1850806070801358830">"Padrão incorreto"</string>
+ <string name="kg_wrong_password" msgid="2333281762128113157">"Senha incorreta"</string>
+ <string name="kg_wrong_pin" msgid="1131306510833563801">"PIN incorreto"</string>
+ <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"Tente novamente em <xliff:g id="NUMBER">%d</xliff:g> segundos."</string>
+ <string name="kg_pattern_instructions" msgid="398978611683075868">"Desenhe seu padrão"</string>
+ <string name="kg_sim_pin_instructions" msgid="2319508550934557331">"Digite o PIN do cartão SIM"</string>
+ <string name="kg_sim_pin_instructions_multi" msgid="7818515973197201434">"Insira o PIN do SIM para \"<xliff:g id="CARRIER">%1$s</xliff:g>\""</string>
+ <string name="kg_pin_instructions" msgid="2377242233495111557">"Digite o PIN"</string>
+ <string name="kg_password_instructions" msgid="5753646556186936819">"Digite a senha"</string>
+ <string name="kg_puk_enter_puk_hint" msgid="453227143861735537">"O SIM foi desativado. Insira o código PUK para continuar. Entre em contato com a operadora para obter mais detalhes."</string>
+ <string name="kg_puk_enter_puk_hint_multi" msgid="363822494559783025">"O SIM \"<xliff:g id="CARRIER">%1$s</xliff:g>\" foi desativado. Insira o código PUK para continuar. Entre em contato com a operadora para saber mais detalhes."</string>
+ <string name="kg_puk_enter_pin_hint" msgid="7871604527429602024">"Digite o código PIN desejado"</string>
+ <string name="kg_enter_confirm_pin_hint" msgid="325676184762529976">"Confirme o código PIN desejado"</string>
+ <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"Desbloqueando o cartão SIM…"</string>
+ <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"Digite um PIN com quatro a oito números."</string>
+ <string name="kg_invalid_sim_puk_hint" msgid="7553388325654369575">"O código PUK deve ter 8 números ou mais."</string>
+ <string name="kg_invalid_puk" msgid="3638289409676051243">"Introduza novamente o código PUK correto. Muitas tentativas malsucedidas desativarão permanentemente o SIM."</string>
+ <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"Os códigos PIN não coincidem"</string>
+ <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"Muitas tentativas de padrão"</string>
+ <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Você digitou seu PIN incorretamente <xliff:g id="NUMBER_0">%d</xliff:g> vezes. \n\nTente novamente em <xliff:g id="NUMBER_1">%d</xliff:g> segundos."</string>
+ <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Você digitou sua senha incorretamente <xliff:g id="NUMBER_0">%d</xliff:g> vezes. \n\nTente novamente em <xliff:g id="NUMBER_1">%d</xliff:g> segundos."</string>
+ <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Você desenhou sua sequência de desbloqueio incorretamente <xliff:g id="NUMBER_0">%d</xliff:g> vezes. \n\nTente novamente em <xliff:g id="NUMBER_1">%d</xliff:g> segundos."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="8774056606869646621">"Você tentou desbloquear o tablet incorretamente <xliff:g id="NUMBER_0">%d</xliff:g> vezes. Após mais <xliff:g id="NUMBER_1">%d</xliff:g> tentativas malsucedidas, este tablet será redefinido, o que excluirá todos os seus dados."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="1843331751334128428">"Você tentou desbloquear o smartphone incorretamente <xliff:g id="NUMBER_0">%d</xliff:g> vezes. Após mais <xliff:g id="NUMBER_1">%d</xliff:g> tentativas malsucedidas, este smartphone será redefinido, o que excluirá todos os seus dados."</string>
+ <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="258925501999698032">"Você tentou desbloquear o tablet incorretamente <xliff:g id="NUMBER">%d</xliff:g> vezes. Este tablet será redefinido, o que excluirá todos os seus dados."</string>
+ <string name="kg_failed_attempts_now_wiping" product="default" msgid="7154028908459817066">"Você tentou desbloquear o smartphone incorretamente <xliff:g id="NUMBER">%d</xliff:g> vezes. Este smartphone será redefinido, o que excluirá todos os seus dados."</string>
+ <string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="6159955099372112688">"Você tentou desbloquear o tablet incorretamente <xliff:g id="NUMBER_0">%d</xliff:g> vezes. Após mais <xliff:g id="NUMBER_1">%d</xliff:g> tentativas malsucedidas, este usuário será removido, o que excluirá todos os dados do usuário."</string>
+ <string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="6945823186629369880">"Você tentou desbloquear o smartphone incorretamente <xliff:g id="NUMBER_0">%d</xliff:g> vezes. Após mais <xliff:g id="NUMBER_1">%d</xliff:g> tentativas malsucedidas, este usuário será removido, o que excluirá todos os dados do usuário."</string>
+ <string name="kg_failed_attempts_now_erasing_user" product="tablet" msgid="3963486905355778734">"Você tentou desbloquear o tablet incorretamente <xliff:g id="NUMBER">%d</xliff:g> vezes. Este usuário será removido, o que excluirá todos os dados do usuário."</string>
+ <string name="kg_failed_attempts_now_erasing_user" product="default" msgid="7729009752252111673">"Você tentou desbloquear o smartphone incorretamente <xliff:g id="NUMBER">%d</xliff:g> vezes. Este usuário será removido, o que excluirá todos os dados do usuário."</string>
+ <string name="kg_failed_attempts_almost_at_erase_profile" product="tablet" msgid="4621778507387853694">"Você tentou desbloquear o tablet incorretamente <xliff:g id="NUMBER_0">%d</xliff:g> vezes. Após mais <xliff:g id="NUMBER_1">%d</xliff:g> tentativas malsucedidas,o perfil de trabalho será removido, o que excluirá todos os dados do perfil."</string>
+ <string name="kg_failed_attempts_almost_at_erase_profile" product="default" msgid="6853071165802933545">"Você tentou desbloquear o smartphone incorretamente <xliff:g id="NUMBER_0">%d</xliff:g> vezes. Após mais <xliff:g id="NUMBER_1">%d</xliff:g> tentativas malsucedidas, o perfil de trabalho será removido, o que excluirá todos os dados do perfil."</string>
+ <string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="4686386497449912146">"Você tentou desbloquear o tablet incorretamente <xliff:g id="NUMBER">%d</xliff:g> vezes. O perfil de trabalho será removido, o que excluirá todos os dados do perfil."</string>
+ <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="4951507352869831265">"Você tentou desbloquear o smartphone incorretamente <xliff:g id="NUMBER">%d</xliff:g> vezes. O perfil de trabalho será removido, o que excluirá todos os dados do perfil."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Você desenhou sua sequência de desbloqueio incorretamente <xliff:g id="NUMBER_0">%d</xliff:g> vezes. Se fizer mais <xliff:g id="NUMBER_1">%d</xliff:g> tentativas incorretas, será solicitado que você use o login do Google para desbloquear seu tablet.\n\n Tente novamente em <xliff:g id="NUMBER_2">%d</xliff:g> segundos."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Você desenhou sua sequência de desbloqueio incorretamente <xliff:g id="NUMBER_0">%d</xliff:g> vezes. Se fizer mais <xliff:g id="NUMBER_1">%d</xliff:g> tentativas incorretas, será solicitado que você use o login do Google para desbloquear.\n\n Tente novamente em <xliff:g id="NUMBER_2">%d</xliff:g> segundos."</string>
+ <string name="kg_password_wrong_pin_code_pukked" msgid="30531039455764924">"Código PIN do SIM incorreto. Entre em contato com a operadora para desbloquear o dispositivo."</string>
+ <plurals name="kg_password_wrong_pin_code" formatted="false" msgid="6721575017538162249">
+ <item quantity="one">Código PIN do SIM incorreto. Tentativas restantes: <xliff:g id="NUMBER_1">%d</xliff:g>.</item>
+ <item quantity="other">Código PIN do SIM incorreto. Tentativas restantes: <xliff:g id="NUMBER_1">%d</xliff:g>.</item>
+ </plurals>
+ <string name="kg_password_wrong_puk_code_dead" msgid="7077536808291316208">"O SIM está inutilizável. Entre em contato com a operadora."</string>
+ <plurals name="kg_password_wrong_puk_code" formatted="false" msgid="7576227366999858780">
+ <item quantity="one">Código PUK do SIM incorreto. Tentativas restantes: <xliff:g id="NUMBER_1">%d</xliff:g>. Caso o código correto não seja digitado, o SIM não poderá mais ser usado.</item>
+ <item quantity="other">Código PUK do SIM incorreto. Tentativas restantes: <xliff:g id="NUMBER_1">%d</xliff:g>. Caso o código correto não seja digitado, o SIM não poderá mais ser usado.</item>
+ </plurals>
+ <string name="kg_password_pin_failed" msgid="6268288093558031564">"Falha na operação de PIN do SIM."</string>
+ <string name="kg_password_puk_failed" msgid="2838824369502455984">"Falha na operação de PUK do SIM."</string>
+ <string name="kg_pin_accepted" msgid="1448241673570020097">"Código aceito."</string>
+ <string name="keyguard_carrier_default" msgid="8700650403054042153">"Sem serviço."</string>
+ <string name="accessibility_ime_switch_button" msgid="5032926134740456424">"Alterar botão do método de entrada."</string>
+ <string name="airplane_mode" msgid="3122107900897202805">"Modo avião"</string>
+ <string name="kg_prompt_reason_restart_pattern" msgid="489430505491862444">"O padrão é exigido quando você reinicia o dispositivo."</string>
+ <string name="kg_prompt_reason_restart_pin" msgid="994878216570694974">"O PIN é exigido quando você reinicia o dispositivo."</string>
+ <string name="kg_prompt_reason_restart_password" msgid="2375742919528461664">"A senha é exigida quando você reinicia o dispositivo."</string>
+ <string name="kg_prompt_reason_timeout_pattern" msgid="8930047492617900785">"O padrão é necessário para aumentar a segurança."</string>
+ <string name="kg_prompt_reason_timeout_pin" msgid="7470468607947726377">"O PIN é necessário para aumentar a segurança."</string>
+ <string name="kg_prompt_reason_timeout_password" msgid="1177412542773936957">"A senha é necessária para aumentar a segurança."</string>
+ <string name="kg_prompt_reason_switch_profiles_pattern" msgid="3802056699323773969">"O padrão é exigido quando você troca de perfil."</string>
+ <string name="kg_prompt_reason_switch_profiles_pin" msgid="8108020184731052246">"O PIN é exigido quando você troca de perfil."</string>
+ <string name="kg_prompt_reason_switch_profiles_password" msgid="6755997057852042672">"A senha é exigida quando você troca de perfil."</string>
+ <plurals name="kg_prompt_reason_time_pattern" formatted="false" msgid="2697444392228541853">
+ <item quantity="one">O dispositivo não foi desbloqueado há <xliff:g id="NUMBER_1">%d</xliff:g> horas. Confirme o padrão.</item>
+ <item quantity="other">O dispositivo não foi desbloqueado há <xliff:g id="NUMBER_1">%d</xliff:g> horas. Confirme o padrão.</item>
+ </plurals>
+ <plurals name="kg_prompt_reason_time_pin" formatted="false" msgid="2118758475374354849">
+ <item quantity="one">O dispositivo não foi desbloqueado há <xliff:g id="NUMBER_1">%d</xliff:g> horas. Confirme o PIN.</item>
+ <item quantity="other">O dispositivo não foi desbloqueado há <xliff:g id="NUMBER_1">%d</xliff:g> horas. Confirme o PIN.</item>
+ </plurals>
+ <plurals name="kg_prompt_reason_time_password" formatted="false" msgid="5132693663364913675">
+ <item quantity="one">O dispositivo não foi desbloqueado há <xliff:g id="NUMBER_1">%d</xliff:g> horas. Confirme a senha.</item>
+ <item quantity="other">O dispositivo não foi desbloqueado há <xliff:g id="NUMBER_1">%d</xliff:g> horas. Confirme a senha.</item>
+ </plurals>
+ <string name="fingerprint_not_recognized" msgid="2690661881608146617">"Não reconhecido"</string>
+</resources>
diff --git a/packages/Keyguard/res/values-pt-rPT/strings.xml b/packages/Keyguard/res/values-pt-rPT/strings.xml
index 3717fc9..dda689c 100644
--- a/packages/Keyguard/res/values-pt-rPT/strings.xml
+++ b/packages/Keyguard/res/values-pt-rPT/strings.xml
@@ -31,6 +31,8 @@
<string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"Código PIN incorreto."</string>
<string name="keyguard_charged" msgid="3272223906073492454">"Carregado"</string>
<string name="keyguard_plugged_in" msgid="9087497435553252863">"A carregar"</string>
+ <string name="keyguard_plugged_in_charging_fast" msgid="6671162730167305479">"A carregar rapidamente"</string>
+ <string name="keyguard_plugged_in_charging_slowly" msgid="1964714661071163229">"A carregar lentamente"</string>
<string name="keyguard_low_battery" msgid="8143808018719173859">"Ligue o carregador."</string>
<string name="keyguard_instructions_when_pattern_disabled" msgid="1332288268600329841">"Prima Menu para desbloquear."</string>
<string name="keyguard_network_locked_message" msgid="9169717779058037168">"Rede bloqueada"</string>
@@ -111,6 +113,9 @@
<string name="kg_prompt_reason_restart_pattern" msgid="489430505491862444">"É necessária a sequência quando reinicia o dispositivo."</string>
<string name="kg_prompt_reason_restart_pin" msgid="994878216570694974">"É necessário o PIN quando reinicia o dispositivo."</string>
<string name="kg_prompt_reason_restart_password" msgid="2375742919528461664">"É necessária a palavra-passe quando reinicia o dispositivo."</string>
+ <string name="kg_prompt_reason_timeout_pattern" msgid="8930047492617900785">"Para uma segurança adicional, é necessária uma sequência."</string>
+ <string name="kg_prompt_reason_timeout_pin" msgid="7470468607947726377">"Para uma segurança adicional, é necessária um PIN."</string>
+ <string name="kg_prompt_reason_timeout_password" msgid="1177412542773936957">"Para uma segurança adicional, é necessária uma palavra-passe."</string>
<string name="kg_prompt_reason_switch_profiles_pattern" msgid="3802056699323773969">"É necessária a sequência quando muda de perfil."</string>
<string name="kg_prompt_reason_switch_profiles_pin" msgid="8108020184731052246">"É necessário o PIN quando muda de perfil."</string>
<string name="kg_prompt_reason_switch_profiles_password" msgid="6755997057852042672">"É necessária a palavra-passe quando muda de perfil."</string>
diff --git a/packages/Keyguard/res/values-pt/strings.xml b/packages/Keyguard/res/values-pt/strings.xml
index d93a5f8..0ef07e5 100644
--- a/packages/Keyguard/res/values-pt/strings.xml
+++ b/packages/Keyguard/res/values-pt/strings.xml
@@ -31,6 +31,8 @@
<string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"Código PIN incorreto."</string>
<string name="keyguard_charged" msgid="3272223906073492454">"Carregado"</string>
<string name="keyguard_plugged_in" msgid="9087497435553252863">"Carregando"</string>
+ <string name="keyguard_plugged_in_charging_fast" msgid="6671162730167305479">"Carregando rapidamente"</string>
+ <string name="keyguard_plugged_in_charging_slowly" msgid="1964714661071163229">"Carregando lentamente"</string>
<string name="keyguard_low_battery" msgid="8143808018719173859">"Conecte seu carregador."</string>
<string name="keyguard_instructions_when_pattern_disabled" msgid="1332288268600329841">"Pressione \"Menu\" para desbloquear."</string>
<string name="keyguard_network_locked_message" msgid="9169717779058037168">"Rede bloqueada"</string>
@@ -111,6 +113,9 @@
<string name="kg_prompt_reason_restart_pattern" msgid="489430505491862444">"O padrão é exigido quando você reinicia o dispositivo."</string>
<string name="kg_prompt_reason_restart_pin" msgid="994878216570694974">"O PIN é exigido quando você reinicia o dispositivo."</string>
<string name="kg_prompt_reason_restart_password" msgid="2375742919528461664">"A senha é exigida quando você reinicia o dispositivo."</string>
+ <string name="kg_prompt_reason_timeout_pattern" msgid="8930047492617900785">"O padrão é necessário para aumentar a segurança."</string>
+ <string name="kg_prompt_reason_timeout_pin" msgid="7470468607947726377">"O PIN é necessário para aumentar a segurança."</string>
+ <string name="kg_prompt_reason_timeout_password" msgid="1177412542773936957">"A senha é necessária para aumentar a segurança."</string>
<string name="kg_prompt_reason_switch_profiles_pattern" msgid="3802056699323773969">"O padrão é exigido quando você troca de perfil."</string>
<string name="kg_prompt_reason_switch_profiles_pin" msgid="8108020184731052246">"O PIN é exigido quando você troca de perfil."</string>
<string name="kg_prompt_reason_switch_profiles_password" msgid="6755997057852042672">"A senha é exigida quando você troca de perfil."</string>
diff --git a/packages/Keyguard/res/values-ro/strings.xml b/packages/Keyguard/res/values-ro/strings.xml
index 39ef0d7..a017564 100644
--- a/packages/Keyguard/res/values-ro/strings.xml
+++ b/packages/Keyguard/res/values-ro/strings.xml
@@ -25,12 +25,14 @@
<string name="keyguard_password_enter_puk_code" msgid="3035856550289724338">"Introduceți codul PUK pentru cardul SIM și codul PIN nou"</string>
<string name="keyguard_password_enter_puk_prompt" msgid="1801941051094974609">"Codul PUK pentru cardul SIM"</string>
<string name="keyguard_password_enter_pin_prompt" msgid="3201151840570492538">"Codul PIN nou pentru cardul SIM"</string>
- <string name="keyguard_password_entry_touch_hint" msgid="7858547464982981384"><font size="17">"Atingeţi și introduceţi parola"</font></string>
+ <string name="keyguard_password_entry_touch_hint" msgid="7858547464982981384"><font size="17">"Atingeți și introduceţi parola"</font></string>
<string name="keyguard_password_enter_password_code" msgid="1054721668279049780">"Introduceţi parola pentru a debloca"</string>
<string name="keyguard_password_enter_pin_password_code" msgid="6391755146112503443">"Introduceţi codul PIN pentru a debloca"</string>
<string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"Cod PIN incorect."</string>
<string name="keyguard_charged" msgid="3272223906073492454">"Încărcată"</string>
<string name="keyguard_plugged_in" msgid="9087497435553252863">"Se încarcă"</string>
+ <string name="keyguard_plugged_in_charging_fast" msgid="6671162730167305479">"Încărcare rapidă"</string>
+ <string name="keyguard_plugged_in_charging_slowly" msgid="1964714661071163229">"Încărcare lentă"</string>
<string name="keyguard_low_battery" msgid="8143808018719173859">"Conectați încărcătorul."</string>
<string name="keyguard_instructions_when_pattern_disabled" msgid="1332288268600329841">"Apăsați pe Meniu pentru a debloca."</string>
<string name="keyguard_network_locked_message" msgid="9169717779058037168">"Rețea blocată"</string>
@@ -53,13 +55,13 @@
<string name="keyguard_accessibility_sim_pin_area" msgid="3887780775111719336">"Zona codului PIN al cardului SIM"</string>
<string name="keyguard_accessibility_sim_puk_area" msgid="1880823406954996207">"Zona codului PUK al cardului SIM"</string>
<string name="keyguard_accessibility_next_alarm" msgid="7269583073750518672">"Următoarea alarmă este setată la <xliff:g id="ALARM">%1$s</xliff:g>"</string>
- <string name="keyboardview_keycode_delete" msgid="3337914833206635744">"Ștergeţi"</string>
+ <string name="keyboardview_keycode_delete" msgid="3337914833206635744">"Ștergeți"</string>
<string name="keyboardview_keycode_enter" msgid="2985864015076059467">"Enter"</string>
<string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Model uitat"</string>
<string name="kg_wrong_pattern" msgid="1850806070801358830">"Model greşit"</string>
<string name="kg_wrong_password" msgid="2333281762128113157">"Parolă greşită"</string>
<string name="kg_wrong_pin" msgid="1131306510833563801">"Cod PIN greşit"</string>
- <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"Încercaţi din nou peste <xliff:g id="NUMBER">%d</xliff:g> (de) secunde."</string>
+ <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"Încercați din nou peste <xliff:g id="NUMBER">%d</xliff:g> (de) secunde."</string>
<string name="kg_pattern_instructions" msgid="398978611683075868">"Desenaţi modelul"</string>
<string name="kg_sim_pin_instructions" msgid="2319508550934557331">"Introduceţi codul PIN al cardului SIM"</string>
<string name="kg_sim_pin_instructions_multi" msgid="7818515973197201434">"Introduceți codul PIN al cardului SIM pentru „<xliff:g id="CARRIER">%1$s</xliff:g>”"</string>
@@ -68,16 +70,16 @@
<string name="kg_puk_enter_puk_hint" msgid="453227143861735537">"Cardul SIM este acum dezactivat. Introduceţi codul PUK pentru a continua. Contactaţi operatorul pentru mai multe detalii."</string>
<string name="kg_puk_enter_puk_hint_multi" msgid="363822494559783025">"Cardul SIM „<xliff:g id="CARRIER">%1$s</xliff:g>” este acum dezactivat. Pentru a continua, introduceți codul PUK. Pentru detalii, contactați operatorul."</string>
<string name="kg_puk_enter_pin_hint" msgid="7871604527429602024">"Introduceţi codul PIN dorit"</string>
- <string name="kg_enter_confirm_pin_hint" msgid="325676184762529976">"Confirmaţi codul PIN dorit"</string>
+ <string name="kg_enter_confirm_pin_hint" msgid="325676184762529976">"Confirmați codul PIN dorit"</string>
<string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"Se deblochează cardul SIM..."</string>
<string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"Introduceţi un cod PIN format din 4 până la 8 cifre."</string>
<string name="kg_invalid_sim_puk_hint" msgid="7553388325654369575">"Codul PUK trebuie să aibă minimum 8 cifre."</string>
<string name="kg_invalid_puk" msgid="3638289409676051243">"Reintroduceţi codul PUK corect. Încercările repetate vor dezactiva definitiv cardul SIM."</string>
<string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"Codurile PIN nu coincid"</string>
<string name="kg_login_too_many_attempts" msgid="6486842094005698475">"Prea multe încercări de desenare a modelului"</string>
- <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Aţi introdus incorect codul PIN de <xliff:g id="NUMBER_0">%d</xliff:g> ori.\n\nÎncercaţi din nou peste <xliff:g id="NUMBER_1">%d</xliff:g> (de) secunde."</string>
- <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Aţi introdus incorect parola de <xliff:g id="NUMBER_0">%d</xliff:g> ori. \n\nÎncercaţi din nou peste <xliff:g id="NUMBER_1">%d</xliff:g> (de) secunde."</string>
- <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Aţi desenat incorect modelul pentru deblocare de <xliff:g id="NUMBER_0">%d</xliff:g> ori. \n\nÎncercaţi din nou peste <xliff:g id="NUMBER_1">%d</xliff:g> (de) secunde."</string>
+ <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Aţi introdus incorect codul PIN de <xliff:g id="NUMBER_0">%d</xliff:g> ori.\n\nÎncercați din nou peste <xliff:g id="NUMBER_1">%d</xliff:g> (de) secunde."</string>
+ <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Aţi introdus incorect parola de <xliff:g id="NUMBER_0">%d</xliff:g> ori. \n\nÎncercați din nou peste <xliff:g id="NUMBER_1">%d</xliff:g> (de) secunde."</string>
+ <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Aţi desenat incorect modelul pentru deblocare de <xliff:g id="NUMBER_0">%d</xliff:g> ori. \n\nÎncercați din nou peste <xliff:g id="NUMBER_1">%d</xliff:g> (de) secunde."</string>
<string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="8774056606869646621">"Ați efectuat <xliff:g id="NUMBER_0">%d</xliff:g> încercări incorecte de deblocare a tabletei. După încă <xliff:g id="NUMBER_1">%d</xliff:g> încercări nereușite, această tabletă va fi resetată, iar toate datele acesteia vor fi șterse."</string>
<string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="1843331751334128428">"Ați efectuat <xliff:g id="NUMBER_0">%d</xliff:g> încercări incorecte de deblocare a telefonului. După încă <xliff:g id="NUMBER_1">%d</xliff:g> încercări nereușite, acest telefon va fi resetat, iar toate datele acestuia vor fi șterse."</string>
<string name="kg_failed_attempts_now_wiping" product="tablet" msgid="258925501999698032">"Ați efectuat <xliff:g id="NUMBER">%d</xliff:g> încercări incorecte de deblocare a tabletei. Această tabletă va fi resetată, iar toate datele acesteia vor fi șterse."</string>
@@ -90,8 +92,8 @@
<string name="kg_failed_attempts_almost_at_erase_profile" product="default" msgid="6853071165802933545">"Ați efectuat <xliff:g id="NUMBER_0">%d</xliff:g> încercări incorecte de deblocare a telefonului. După încă <xliff:g id="NUMBER_1">%d</xliff:g> încercări nereușite, profilul de serviciu va fi eliminat, iar toate datele profilului vor fi șterse."</string>
<string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="4686386497449912146">"Ați efectuat <xliff:g id="NUMBER">%d</xliff:g> încercări incorecte de deblocare a tabletei. Profilul de serviciu va fi eliminat, iar toate datele profilului vor fi șterse."</string>
<string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="4951507352869831265">"Ați efectuat <xliff:g id="NUMBER">%d</xliff:g> încercări incorecte de deblocare a telefonului. Profilul de serviciu va fi eliminat, iar toate datele profilului vor fi șterse."</string>
- <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Aţi desenat incorect modelul pentru deblocare de <xliff:g id="NUMBER_0">%d</xliff:g> ori. După încă <xliff:g id="NUMBER_1">%d</xliff:g> încercări nereuşite, vi se va solicita să deblocaţi tableta cu ajutorul unui cont de e-mail.\n\n Încercaţi din nou peste <xliff:g id="NUMBER_2">%d</xliff:g> (de) secunde."</string>
- <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Aţi desenat incorect modelul pentru deblocare de <xliff:g id="NUMBER_0">%d</xliff:g> ori. După încă <xliff:g id="NUMBER_1">%d</xliff:g> încercări nereuşite, vi se va solicita să deblocaţi telefonul cu ajutorul unui cont de e-mail.\n\n Încercaţi din nou peste <xliff:g id="NUMBER_2">%d</xliff:g> (de) secunde."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Aţi desenat incorect modelul pentru deblocare de <xliff:g id="NUMBER_0">%d</xliff:g> ori. După încă <xliff:g id="NUMBER_1">%d</xliff:g> încercări nereuşite, vi se va solicita să deblocaţi tableta cu ajutorul unui cont de e-mail.\n\n Încercați din nou peste <xliff:g id="NUMBER_2">%d</xliff:g> (de) secunde."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Aţi desenat incorect modelul pentru deblocare de <xliff:g id="NUMBER_0">%d</xliff:g> ori. După încă <xliff:g id="NUMBER_1">%d</xliff:g> încercări nereuşite, vi se va solicita să deblocaţi telefonul cu ajutorul unui cont de e-mail.\n\n Încercați din nou peste <xliff:g id="NUMBER_2">%d</xliff:g> (de) secunde."</string>
<string name="kg_password_wrong_pin_code_pukked" msgid="30531039455764924">"Codul PIN pentru cardul SIM este incorect. Contactați operatorul pentru a vă debloca dispozitivul."</string>
<plurals name="kg_password_wrong_pin_code" formatted="false" msgid="6721575017538162249">
<item quantity="few">Codul PIN pentru cardul SIM este incorect. V-au mai rămas <xliff:g id="NUMBER_1">%d</xliff:g> încercări.</item>
@@ -113,6 +115,9 @@
<string name="kg_prompt_reason_restart_pattern" msgid="489430505491862444">"Când reporniți dispozitivul este necesar să introduceți modelul."</string>
<string name="kg_prompt_reason_restart_pin" msgid="994878216570694974">"Când reporniți dispozitivul este necesar să introduceți codul PIN."</string>
<string name="kg_prompt_reason_restart_password" msgid="2375742919528461664">"Când reporniți dispozitivul este necesar să introduceți parola."</string>
+ <string name="kg_prompt_reason_timeout_pattern" msgid="8930047492617900785">"Pentru securitate suplimentară este necesar un șablon."</string>
+ <string name="kg_prompt_reason_timeout_pin" msgid="7470468607947726377">"Pentru securitate suplimentară este necesar un cod PIN."</string>
+ <string name="kg_prompt_reason_timeout_password" msgid="1177412542773936957">"Pentru securitate suplimentară este necesară o parolă."</string>
<string name="kg_prompt_reason_switch_profiles_pattern" msgid="3802056699323773969">"Când comutați între profiluri este necesar să introduceți modelul."</string>
<string name="kg_prompt_reason_switch_profiles_pin" msgid="8108020184731052246">"Când comutați între profiluri este necesar să introduceți codul PIN."</string>
<string name="kg_prompt_reason_switch_profiles_password" msgid="6755997057852042672">"Când comutați între profiluri este necesar să introduceți parola."</string>
diff --git a/packages/Keyguard/res/values-ru/strings.xml b/packages/Keyguard/res/values-ru/strings.xml
index 39fb2a8..226f566 100644
--- a/packages/Keyguard/res/values-ru/strings.xml
+++ b/packages/Keyguard/res/values-ru/strings.xml
@@ -31,6 +31,8 @@
<string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"Неверный PIN-код."</string>
<string name="keyguard_charged" msgid="3272223906073492454">"Батарея заряжена"</string>
<string name="keyguard_plugged_in" msgid="9087497435553252863">"Зарядка батареи"</string>
+ <string name="keyguard_plugged_in_charging_fast" msgid="6671162730167305479">"Быстрая зарядка"</string>
+ <string name="keyguard_plugged_in_charging_slowly" msgid="1964714661071163229">"Медленная зарядка"</string>
<string name="keyguard_low_battery" msgid="8143808018719173859">"Подключите зарядное устройство."</string>
<string name="keyguard_instructions_when_pattern_disabled" msgid="1332288268600329841">"Для разблокировки нажмите \"Меню\"."</string>
<string name="keyguard_network_locked_message" msgid="9169717779058037168">"Сеть заблокирована"</string>
@@ -115,6 +117,9 @@
<string name="kg_prompt_reason_restart_pattern" msgid="489430505491862444">"После перезапуска устройства нужно ввести графический ключ."</string>
<string name="kg_prompt_reason_restart_pin" msgid="994878216570694974">"После перезапуска устройства нужно ввести PIN-код."</string>
<string name="kg_prompt_reason_restart_password" msgid="2375742919528461664">"После перезапуска устройства нужно ввести пароль."</string>
+ <string name="kg_prompt_reason_timeout_pattern" msgid="8930047492617900785">"В качестве дополнительной меры безопасности введите графический ключ."</string>
+ <string name="kg_prompt_reason_timeout_pin" msgid="7470468607947726377">"В качестве дополнительной меры безопасности введите PIN-код."</string>
+ <string name="kg_prompt_reason_timeout_password" msgid="1177412542773936957">"В качестве дополнительной меры безопасности введите пароль."</string>
<string name="kg_prompt_reason_switch_profiles_pattern" msgid="3802056699323773969">"После смены аккаунта нужно ввести графический ключ."</string>
<string name="kg_prompt_reason_switch_profiles_pin" msgid="8108020184731052246">"После смены аккаунта нужно ввести PIN-код."</string>
<string name="kg_prompt_reason_switch_profiles_password" msgid="6755997057852042672">"После смены аккаунта нужно ввести пароль."</string>
diff --git a/packages/Keyguard/res/values-si-rLK/strings.xml b/packages/Keyguard/res/values-si-rLK/strings.xml
index 484bac9..0afda24 100644
--- a/packages/Keyguard/res/values-si-rLK/strings.xml
+++ b/packages/Keyguard/res/values-si-rLK/strings.xml
@@ -31,6 +31,8 @@
<string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"වැරදි PIN කේතයකි."</string>
<string name="keyguard_charged" msgid="3272223906073492454">"අරෝපිතයි"</string>
<string name="keyguard_plugged_in" msgid="9087497435553252863">"ආරෝපණය වෙමින්"</string>
+ <string name="keyguard_plugged_in_charging_fast" msgid="6671162730167305479">"වේගයෙන් ආරෝපණය"</string>
+ <string name="keyguard_plugged_in_charging_slowly" msgid="1964714661071163229">"සෙමින් ආරෝපණය"</string>
<string name="keyguard_low_battery" msgid="8143808018719173859">"ඔබගේ ආරෝපකයට සම්බන්ධ කරන්න."</string>
<string name="keyguard_instructions_when_pattern_disabled" msgid="1332288268600329841">"අගුළු ඇරීමට මෙනුව ඔබන්න."</string>
<string name="keyguard_network_locked_message" msgid="9169717779058037168">"ජාල අගුළු දමා ඇත"</string>
@@ -111,6 +113,9 @@
<string name="kg_prompt_reason_restart_pattern" msgid="489430505491862444">"ඔබ උපාංගය නැවත ආරම්භ කරන විට රටාව අවශ්යයි."</string>
<string name="kg_prompt_reason_restart_pin" msgid="994878216570694974">"ඔබ උපාංගය නැවත ආරම්භ කරන විට PIN අංකය අවශ්යයි."</string>
<string name="kg_prompt_reason_restart_password" msgid="2375742919528461664">"ඔබ උපාංගය නැවත ආරම්භ කරන විට මුරපදය අවශ්යයි."</string>
+ <string name="kg_prompt_reason_timeout_pattern" msgid="8930047492617900785">"අමතර ආරක්ෂාව සඳහා රටාව අවශ්යයි."</string>
+ <string name="kg_prompt_reason_timeout_pin" msgid="7470468607947726377">"අමතර ආරක්ෂාව සඳහා PIN අංකය අවශ්යයි."</string>
+ <string name="kg_prompt_reason_timeout_password" msgid="1177412542773936957">"අමතර ආරක්ෂාව සඳහා මුරපදය අවශ්යයි."</string>
<string name="kg_prompt_reason_switch_profiles_pattern" msgid="3802056699323773969">"ඔබ පැතිකඩවල් මාරු කරන විට රටාව අවශ්යයි."</string>
<string name="kg_prompt_reason_switch_profiles_pin" msgid="8108020184731052246">"ඔබ පැතිකඩවල් මාරු කරන විට PIN අංකය අවශ්යයි."</string>
<string name="kg_prompt_reason_switch_profiles_password" msgid="6755997057852042672">"ඔබ පැතිකඩවල් මාරු කරන විට මුරපදය අවශ්යයි."</string>
diff --git a/packages/Keyguard/res/values-sk/strings.xml b/packages/Keyguard/res/values-sk/strings.xml
index ffba065..4825e4a 100644
--- a/packages/Keyguard/res/values-sk/strings.xml
+++ b/packages/Keyguard/res/values-sk/strings.xml
@@ -31,6 +31,8 @@
<string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"Nesprávny kód PIN."</string>
<string name="keyguard_charged" msgid="3272223906073492454">"Batéria je nabitá"</string>
<string name="keyguard_plugged_in" msgid="9087497435553252863">"Nabíja sa"</string>
+ <string name="keyguard_plugged_in_charging_fast" msgid="6671162730167305479">"Rýchle nabíjanie"</string>
+ <string name="keyguard_plugged_in_charging_slowly" msgid="1964714661071163229">"Pomalé nabíjanie"</string>
<string name="keyguard_low_battery" msgid="8143808018719173859">"Pripojte nabíjačku."</string>
<string name="keyguard_instructions_when_pattern_disabled" msgid="1332288268600329841">"Telefón odomknete stlačením tlačidla Menu."</string>
<string name="keyguard_network_locked_message" msgid="9169717779058037168">"Sieť je zablokovaná"</string>
@@ -115,6 +117,9 @@
<string name="kg_prompt_reason_restart_pattern" msgid="489430505491862444">"Pri reštartovaní zariadenia sa vyžaduje bezpečnostný vzor."</string>
<string name="kg_prompt_reason_restart_pin" msgid="994878216570694974">"Pri reštartovaní zariadenia sa vyžaduje kód PIN."</string>
<string name="kg_prompt_reason_restart_password" msgid="2375742919528461664">"Pri reštartovaní zariadenia sa vyžaduje heslo."</string>
+ <string name="kg_prompt_reason_timeout_pattern" msgid="8930047492617900785">"Na ďalšie zabezpečenie sa vyžaduje vzor."</string>
+ <string name="kg_prompt_reason_timeout_pin" msgid="7470468607947726377">"Na ďalšie zabezpečenie sa vyžaduje kód PIN."</string>
+ <string name="kg_prompt_reason_timeout_password" msgid="1177412542773936957">"Na ďalšie zabezpečenie sa vyžaduje heslo."</string>
<string name="kg_prompt_reason_switch_profiles_pattern" msgid="3802056699323773969">"Po prepnutí profilov sa vyžaduje bezpečnostný vzor."</string>
<string name="kg_prompt_reason_switch_profiles_pin" msgid="8108020184731052246">"Po prepnutí profilov sa vyžaduje kód PIN."</string>
<string name="kg_prompt_reason_switch_profiles_password" msgid="6755997057852042672">"Po prepnutí profilov sa vyžaduje heslo."</string>
diff --git a/packages/Keyguard/res/values-sl/strings.xml b/packages/Keyguard/res/values-sl/strings.xml
index 4655eb5..41dde2c 100644
--- a/packages/Keyguard/res/values-sl/strings.xml
+++ b/packages/Keyguard/res/values-sl/strings.xml
@@ -31,6 +31,8 @@
<string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"Napačna koda PIN."</string>
<string name="keyguard_charged" msgid="3272223906073492454">"Napolnjeno"</string>
<string name="keyguard_plugged_in" msgid="9087497435553252863">"Polnjenje"</string>
+ <string name="keyguard_plugged_in_charging_fast" msgid="6671162730167305479">"Hitro polnjenje"</string>
+ <string name="keyguard_plugged_in_charging_slowly" msgid="1964714661071163229">"Počasno polnjenje"</string>
<string name="keyguard_low_battery" msgid="8143808018719173859">"Priključite napajalnik."</string>
<string name="keyguard_instructions_when_pattern_disabled" msgid="1332288268600329841">"Če želite odkleniti, pritisnite meni."</string>
<string name="keyguard_network_locked_message" msgid="9169717779058037168">"Omrežje je zaklenjeno"</string>
@@ -115,6 +117,9 @@
<string name="kg_prompt_reason_restart_pattern" msgid="489430505491862444">"Po vnovičnem zagonu je treba vnesti vzorec."</string>
<string name="kg_prompt_reason_restart_pin" msgid="994878216570694974">"Po vnovičnem zagonu je treba vnesti kodo PIN."</string>
<string name="kg_prompt_reason_restart_password" msgid="2375742919528461664">"Po vnovičnem zagonu je treba vnesti geslo."</string>
+ <string name="kg_prompt_reason_timeout_pattern" msgid="8930047492617900785">"Zaradi dodatne varnosti morate vnesti vzorec."</string>
+ <string name="kg_prompt_reason_timeout_pin" msgid="7470468607947726377">"Zaradi dodatne varnosti morate vnesti kodo PIN."</string>
+ <string name="kg_prompt_reason_timeout_password" msgid="1177412542773936957">"Zaradi dodatne varnosti morate vnesti geslo."</string>
<string name="kg_prompt_reason_switch_profiles_pattern" msgid="3802056699323773969">"Po preklopu profilov je treba vnesti vzorec."</string>
<string name="kg_prompt_reason_switch_profiles_pin" msgid="8108020184731052246">"Po preklopu profilov je treba vnesti kodo PIN."</string>
<string name="kg_prompt_reason_switch_profiles_password" msgid="6755997057852042672">"Po preklopu profilov je treba vnesti geslo."</string>
diff --git a/packages/Keyguard/res/values-sq-rAL/strings.xml b/packages/Keyguard/res/values-sq-rAL/strings.xml
index ac4be5c..31ed223 100644
--- a/packages/Keyguard/res/values-sq-rAL/strings.xml
+++ b/packages/Keyguard/res/values-sq-rAL/strings.xml
@@ -31,6 +31,8 @@
<string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"Kodi PIN është i pasaktë."</string>
<string name="keyguard_charged" msgid="3272223906073492454">"I ngarkuar"</string>
<string name="keyguard_plugged_in" msgid="9087497435553252863">"Po ngarkohet"</string>
+ <string name="keyguard_plugged_in_charging_fast" msgid="6671162730167305479">"Po ngarkon me shpejtësi"</string>
+ <string name="keyguard_plugged_in_charging_slowly" msgid="1964714661071163229">"Po ngarkon me ngadalë"</string>
<string name="keyguard_low_battery" msgid="8143808018719173859">"Lidh ngarkuesin."</string>
<string name="keyguard_instructions_when_pattern_disabled" msgid="1332288268600329841">"Shtyp menynë për ta shkyçur."</string>
<string name="keyguard_network_locked_message" msgid="9169717779058037168">"Rrjeti është i kyçur"</string>
@@ -111,6 +113,9 @@
<string name="kg_prompt_reason_restart_pattern" msgid="489430505491862444">"Kërkohet motivi kur rinis pajisjen."</string>
<string name="kg_prompt_reason_restart_pin" msgid="994878216570694974">"Kërkohet kodi PIN kur rinis pajisjen."</string>
<string name="kg_prompt_reason_restart_password" msgid="2375742919528461664">"Kërkohet fjalëkalimi kur rinis pajisjen."</string>
+ <string name="kg_prompt_reason_timeout_pattern" msgid="8930047492617900785">"Kërkohet motivi për më shumë siguri."</string>
+ <string name="kg_prompt_reason_timeout_pin" msgid="7470468607947726377">"Kërkohet kodi PIN për më shumë siguri."</string>
+ <string name="kg_prompt_reason_timeout_password" msgid="1177412542773936957">"Kërkohet fjalëkalimi për më shumë siguri."</string>
<string name="kg_prompt_reason_switch_profiles_pattern" msgid="3802056699323773969">"Kërkohet motivi kur ndryshon profilet."</string>
<string name="kg_prompt_reason_switch_profiles_pin" msgid="8108020184731052246">"Kërkohet kodi PIN kur ndryshon profilet."</string>
<string name="kg_prompt_reason_switch_profiles_password" msgid="6755997057852042672">"Kërkohet fjalëkalimi kur ndryshon profilet."</string>
diff --git a/packages/Keyguard/res/values-sr/strings.xml b/packages/Keyguard/res/values-sr/strings.xml
index 492c9d5..feb18be 100644
--- a/packages/Keyguard/res/values-sr/strings.xml
+++ b/packages/Keyguard/res/values-sr/strings.xml
@@ -31,6 +31,8 @@
<string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"PIN кôд је нетачан."</string>
<string name="keyguard_charged" msgid="3272223906073492454">"Напуњено"</string>
<string name="keyguard_plugged_in" msgid="9087497435553252863">"Пуњење"</string>
+ <string name="keyguard_plugged_in_charging_fast" msgid="6671162730167305479">"Брзо се пуни"</string>
+ <string name="keyguard_plugged_in_charging_slowly" msgid="1964714661071163229">"Споро се пуни"</string>
<string name="keyguard_low_battery" msgid="8143808018719173859">"Повежите пуњач."</string>
<string name="keyguard_instructions_when_pattern_disabled" msgid="1332288268600329841">"Притисните Мени да бисте откључали."</string>
<string name="keyguard_network_locked_message" msgid="9169717779058037168">"Мрежа је закључана"</string>
@@ -113,6 +115,9 @@
<string name="kg_prompt_reason_restart_pattern" msgid="489430505491862444">"Шаблон је обавезан када поново покрећете уређај."</string>
<string name="kg_prompt_reason_restart_pin" msgid="994878216570694974">"PIN је обавезан када поново покрећете уређај."</string>
<string name="kg_prompt_reason_restart_password" msgid="2375742919528461664">"Лозинка је обавезна када поново покрећете уређај."</string>
+ <string name="kg_prompt_reason_timeout_pattern" msgid="8930047492617900785">"Потребан је шаблон ради додатне безбедности."</string>
+ <string name="kg_prompt_reason_timeout_pin" msgid="7470468607947726377">"Потребан је PIN ради додатне безбедности."</string>
+ <string name="kg_prompt_reason_timeout_password" msgid="1177412542773936957">"Потребна је лозинка ради додатне безбедности."</string>
<string name="kg_prompt_reason_switch_profiles_pattern" msgid="3802056699323773969">"Шаблон је обавезан када прелазите са једног профила на други."</string>
<string name="kg_prompt_reason_switch_profiles_pin" msgid="8108020184731052246">"PIN је обавезан када прелазите са једног профила на други."</string>
<string name="kg_prompt_reason_switch_profiles_password" msgid="6755997057852042672">"Лозинка је обавезна када прелазите са једног профила на други."</string>
diff --git a/packages/Keyguard/res/values-sv/strings.xml b/packages/Keyguard/res/values-sv/strings.xml
index c6bb25e..28bcf98 100644
--- a/packages/Keyguard/res/values-sv/strings.xml
+++ b/packages/Keyguard/res/values-sv/strings.xml
@@ -31,6 +31,8 @@
<string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"Fel PIN-kod."</string>
<string name="keyguard_charged" msgid="3272223906073492454">"Batteriet har laddats"</string>
<string name="keyguard_plugged_in" msgid="9087497435553252863">"Laddar"</string>
+ <string name="keyguard_plugged_in_charging_fast" msgid="6671162730167305479">"Laddas snabbt"</string>
+ <string name="keyguard_plugged_in_charging_slowly" msgid="1964714661071163229">"Laddas långsamt"</string>
<string name="keyguard_low_battery" msgid="8143808018719173859">"Anslut din laddare."</string>
<string name="keyguard_instructions_when_pattern_disabled" msgid="1332288268600329841">"Tryck på Meny om du vill låsa upp."</string>
<string name="keyguard_network_locked_message" msgid="9169717779058037168">"Nätverk låst"</string>
@@ -111,6 +113,9 @@
<string name="kg_prompt_reason_restart_pattern" msgid="489430505491862444">"Du måste ange grafiskt lösenord när du startar om enheten."</string>
<string name="kg_prompt_reason_restart_pin" msgid="994878216570694974">"Du måste ange pinkod när du startar om enheten."</string>
<string name="kg_prompt_reason_restart_password" msgid="2375742919528461664">"Du måste ange lösenord när du startar om enheten."</string>
+ <string name="kg_prompt_reason_timeout_pattern" msgid="8930047492617900785">"Mönster krävs för ytterligare säkerhet."</string>
+ <string name="kg_prompt_reason_timeout_pin" msgid="7470468607947726377">"Pinkod krävs för ytterligare säkerhet."</string>
+ <string name="kg_prompt_reason_timeout_password" msgid="1177412542773936957">"Lösenord krävs för ytterligare säkerhet."</string>
<string name="kg_prompt_reason_switch_profiles_pattern" msgid="3802056699323773969">"Du måste ange grafiskt lösenord när du byter profil."</string>
<string name="kg_prompt_reason_switch_profiles_pin" msgid="8108020184731052246">"Du måste ange pinkod när du byter profil."</string>
<string name="kg_prompt_reason_switch_profiles_password" msgid="6755997057852042672">"Du måste ange lösenord när du byter profil."</string>
diff --git a/packages/Keyguard/res/values-sw/strings.xml b/packages/Keyguard/res/values-sw/strings.xml
index 6541b10..bd8c68e 100644
--- a/packages/Keyguard/res/values-sw/strings.xml
+++ b/packages/Keyguard/res/values-sw/strings.xml
@@ -31,6 +31,8 @@
<string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"Msimbo wa PIN usio sahihi."</string>
<string name="keyguard_charged" msgid="3272223906073492454">"Betri imejaa"</string>
<string name="keyguard_plugged_in" msgid="9087497435553252863">"Inachaji"</string>
+ <string name="keyguard_plugged_in_charging_fast" msgid="6671162730167305479">"Inachaji kwa kasi"</string>
+ <string name="keyguard_plugged_in_charging_slowly" msgid="1964714661071163229">"Inachaji pole pole"</string>
<string name="keyguard_low_battery" msgid="8143808018719173859">"Unganisha chaja yako."</string>
<string name="keyguard_instructions_when_pattern_disabled" msgid="1332288268600329841">"Bonyeza Menyu ili kufungua."</string>
<string name="keyguard_network_locked_message" msgid="9169717779058037168">"Mtandao umefungwa"</string>
@@ -111,6 +113,9 @@
<string name="kg_prompt_reason_restart_pattern" msgid="489430505491862444">"Mchoro unahitajika unapoanzisha kifaa upya."</string>
<string name="kg_prompt_reason_restart_pin" msgid="994878216570694974">"PIN inahitajika unapoanzisha kifaa upya."</string>
<string name="kg_prompt_reason_restart_password" msgid="2375742919528461664">"Nenosiri linahitajika unapoanzisha kifaa upya."</string>
+ <string name="kg_prompt_reason_timeout_pattern" msgid="8930047492617900785">"Mchoro unatakikana ili kuongeza usalama."</string>
+ <string name="kg_prompt_reason_timeout_pin" msgid="7470468607947726377">"PIN inatakikana ili kuongeza usalama."</string>
+ <string name="kg_prompt_reason_timeout_password" msgid="1177412542773936957">"Nenosiri linahitajika ili kuongeza usalama."</string>
<string name="kg_prompt_reason_switch_profiles_pattern" msgid="3802056699323773969">"Mchoro unahitajika unapobadili wasifu."</string>
<string name="kg_prompt_reason_switch_profiles_pin" msgid="8108020184731052246">"PIN inahitajika unapobadili wasifu."</string>
<string name="kg_prompt_reason_switch_profiles_password" msgid="6755997057852042672">"Nenosiri linahitajika unapobadili wasifu."</string>
diff --git a/packages/Keyguard/res/values-ta-rIN/strings.xml b/packages/Keyguard/res/values-ta-rIN/strings.xml
index 911611f..32c93b0 100644
--- a/packages/Keyguard/res/values-ta-rIN/strings.xml
+++ b/packages/Keyguard/res/values-ta-rIN/strings.xml
@@ -31,6 +31,8 @@
<string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"தவறான பின் குறியீடு."</string>
<string name="keyguard_charged" msgid="3272223906073492454">"சார்ஜ் செய்யப்பட்டது"</string>
<string name="keyguard_plugged_in" msgid="9087497435553252863">"சார்ஜாகிறது"</string>
+ <string name="keyguard_plugged_in_charging_fast" msgid="6671162730167305479">"வேகமாக சார்ஜாகிறது"</string>
+ <string name="keyguard_plugged_in_charging_slowly" msgid="1964714661071163229">"மெதுவாக சார்ஜாகிறது"</string>
<string name="keyguard_low_battery" msgid="8143808018719173859">"உங்கள் சார்ஜரை இணைக்கவும்."</string>
<string name="keyguard_instructions_when_pattern_disabled" msgid="1332288268600329841">"திறக்க, மெனுவை அழுத்தவும்."</string>
<string name="keyguard_network_locked_message" msgid="9169717779058037168">"பிணையம் பூட்டப்பட்டது"</string>
@@ -111,6 +113,9 @@
<string name="kg_prompt_reason_restart_pattern" msgid="489430505491862444">"சாதனத்தை மீண்டும் தொடங்கும் போது, வடிவம் தேவை."</string>
<string name="kg_prompt_reason_restart_pin" msgid="994878216570694974">"சாதனத்தை மீண்டும் தொடங்கும் போது, பின் தேவை."</string>
<string name="kg_prompt_reason_restart_password" msgid="2375742919528461664">"சாதனத்தை மீண்டும் தொடங்கும் போது, கடவுச்சொல் தேவை."</string>
+ <string name="kg_prompt_reason_timeout_pattern" msgid="8930047492617900785">"கூடுதல் பாதுகாப்பிற்கு வடிவம் தேவை."</string>
+ <string name="kg_prompt_reason_timeout_pin" msgid="7470468607947726377">"கூடுதல் பாதுகாப்பிற்கு PIN தேவை."</string>
+ <string name="kg_prompt_reason_timeout_password" msgid="1177412542773936957">"கூடுதல் பாதுகாப்பிற்குக் கடவுச்சொல் தேவை."</string>
<string name="kg_prompt_reason_switch_profiles_pattern" msgid="3802056699323773969">"சுயவிவரங்களுக்கு இடையே மாறும் போது, வடிவம் தேவை."</string>
<string name="kg_prompt_reason_switch_profiles_pin" msgid="8108020184731052246">"சுயவிவரங்களுக்கு இடையே மாறும் போது, பின் தேவை."</string>
<string name="kg_prompt_reason_switch_profiles_password" msgid="6755997057852042672">"சுயவிவரங்களுக்கு இடையே மாறும் போது, கடவுச்சொல் தேவை."</string>
diff --git a/packages/Keyguard/res/values-te-rIN/strings.xml b/packages/Keyguard/res/values-te-rIN/strings.xml
index 1cba128..e27f5a9 100644
--- a/packages/Keyguard/res/values-te-rIN/strings.xml
+++ b/packages/Keyguard/res/values-te-rIN/strings.xml
@@ -31,6 +31,8 @@
<string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"చెల్లని పిన్ కోడ్."</string>
<string name="keyguard_charged" msgid="3272223906073492454">"ఛార్జ్ అయింది"</string>
<string name="keyguard_plugged_in" msgid="9087497435553252863">"ఛార్జ్ అవుతోంది"</string>
+ <string name="keyguard_plugged_in_charging_fast" msgid="6671162730167305479">"వేగంగా ఛార్జ్ అవుతోంది"</string>
+ <string name="keyguard_plugged_in_charging_slowly" msgid="1964714661071163229">"నెమ్మదిగా ఛార్జ్ అవుతోంది"</string>
<string name="keyguard_low_battery" msgid="8143808018719173859">"మీ ఛార్జర్ను కనెక్ట్ చేయండి."</string>
<string name="keyguard_instructions_when_pattern_disabled" msgid="1332288268600329841">"అన్లాక్ చేయడానికి మెను నొక్కండి."</string>
<string name="keyguard_network_locked_message" msgid="9169717779058037168">"నెట్వర్క్ లాక్ చేయబడింది"</string>
@@ -111,6 +113,9 @@
<string name="kg_prompt_reason_restart_pattern" msgid="489430505491862444">"మీరు పరికరాన్ని పునఃప్రారంభించినప్పుడు నమూనా అవసరం."</string>
<string name="kg_prompt_reason_restart_pin" msgid="994878216570694974">"మీరు పరికరాన్ని పునఃప్రారంభించినప్పుడు PIN అవసరం."</string>
<string name="kg_prompt_reason_restart_password" msgid="2375742919528461664">"మీరు పరికరాన్ని పునఃప్రారంభించినప్పుడు పాస్వర్డ్ అవసరం."</string>
+ <string name="kg_prompt_reason_timeout_pattern" msgid="8930047492617900785">"అదనపు భద్రత కోసం నమూనా అవసరం."</string>
+ <string name="kg_prompt_reason_timeout_pin" msgid="7470468607947726377">"అదనపు భద్రత కోసం PIN అవసరం."</string>
+ <string name="kg_prompt_reason_timeout_password" msgid="1177412542773936957">"అదనపు భద్రత కోసం పాస్వర్డ్ అవసరం."</string>
<string name="kg_prompt_reason_switch_profiles_pattern" msgid="3802056699323773969">"మీరు ప్రొఫైల్లను మార్చినప్పుడు నమూనా అవసరం."</string>
<string name="kg_prompt_reason_switch_profiles_pin" msgid="8108020184731052246">"మీరు ప్రొఫైల్లను మార్చినప్పుడు PIN అవసరం."</string>
<string name="kg_prompt_reason_switch_profiles_password" msgid="6755997057852042672">"మీరు ప్రొఫైల్లను మార్చినప్పుడు పాస్వర్డ్ అవసరం."</string>
diff --git a/packages/Keyguard/res/values-th/strings.xml b/packages/Keyguard/res/values-th/strings.xml
index 7d05487..2629bfd 100644
--- a/packages/Keyguard/res/values-th/strings.xml
+++ b/packages/Keyguard/res/values-th/strings.xml
@@ -31,6 +31,8 @@
<string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"รหัส PIN ไม่ถูกต้อง"</string>
<string name="keyguard_charged" msgid="3272223906073492454">"ชาร์จแล้ว"</string>
<string name="keyguard_plugged_in" msgid="9087497435553252863">"กำลังชาร์จ"</string>
+ <string name="keyguard_plugged_in_charging_fast" msgid="6671162730167305479">"กำลังชาร์จเร็ว"</string>
+ <string name="keyguard_plugged_in_charging_slowly" msgid="1964714661071163229">"กำลังชาร์จช้า"</string>
<string name="keyguard_low_battery" msgid="8143808018719173859">"เสียบที่ชาร์จของคุณ"</string>
<string name="keyguard_instructions_when_pattern_disabled" msgid="1332288268600329841">"กด \"เมนู\" เพื่อปลดล็อก"</string>
<string name="keyguard_network_locked_message" msgid="9169717779058037168">"เครือข่ายล็อก"</string>
@@ -111,6 +113,9 @@
<string name="kg_prompt_reason_restart_pattern" msgid="489430505491862444">"ต้องใช้รูปแบบเมื่อคุณรีสตาร์ทอุปกรณ์"</string>
<string name="kg_prompt_reason_restart_pin" msgid="994878216570694974">"ต้องใช้ PIN เมื่อคุณรีสตาร์ทอุปกรณ์"</string>
<string name="kg_prompt_reason_restart_password" msgid="2375742919528461664">"ต้องใช้รหัสผ่านเมื่อคุณรีสตาร์ทอุปกรณ์"</string>
+ <string name="kg_prompt_reason_timeout_pattern" msgid="8930047492617900785">"ต้องใช้รูปแบบเพื่อความปลอดภัยเพิ่มเติม"</string>
+ <string name="kg_prompt_reason_timeout_pin" msgid="7470468607947726377">"ต้องใช้ PIN เพื่อความปลอดภัยเพิ่มเติม"</string>
+ <string name="kg_prompt_reason_timeout_password" msgid="1177412542773936957">"ต้องใช้รหัสผ่านเพื่อความปลอดภัยเพิ่มเติม"</string>
<string name="kg_prompt_reason_switch_profiles_pattern" msgid="3802056699323773969">"ต้องใช้รูปแบบเมื่อคุณเปลี่ยนโปรไฟล์"</string>
<string name="kg_prompt_reason_switch_profiles_pin" msgid="8108020184731052246">"ต้องใช้ PIN เมื่อคุณเปลี่ยนโปรไฟล์"</string>
<string name="kg_prompt_reason_switch_profiles_password" msgid="6755997057852042672">"ต้องใช้รหัสผ่านเมื่อคุณเปลี่ยนโปรไฟล์"</string>
diff --git a/packages/Keyguard/res/values-tl/strings.xml b/packages/Keyguard/res/values-tl/strings.xml
index cdac6e1..8bfc6a6 100644
--- a/packages/Keyguard/res/values-tl/strings.xml
+++ b/packages/Keyguard/res/values-tl/strings.xml
@@ -31,6 +31,8 @@
<string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"Maling PIN code."</string>
<string name="keyguard_charged" msgid="3272223906073492454">"Na-charge"</string>
<string name="keyguard_plugged_in" msgid="9087497435553252863">"Nagtsa-charge"</string>
+ <string name="keyguard_plugged_in_charging_fast" msgid="6671162730167305479">"Mabilis na nagcha-charge"</string>
+ <string name="keyguard_plugged_in_charging_slowly" msgid="1964714661071163229">"Dahan-dahang nagcha-charge"</string>
<string name="keyguard_low_battery" msgid="8143808018719173859">"Ikonekta ang iyong charger."</string>
<string name="keyguard_instructions_when_pattern_disabled" msgid="1332288268600329841">"Pindutin ang Menu upang i-unlock."</string>
<string name="keyguard_network_locked_message" msgid="9169717779058037168">"Naka-lock ang network"</string>
@@ -111,6 +113,9 @@
<string name="kg_prompt_reason_restart_pattern" msgid="489430505491862444">"Kinakailangan ang pattern kapag ni-restart mo ang device."</string>
<string name="kg_prompt_reason_restart_pin" msgid="994878216570694974">"Kinakailangan ang PIN kapag ni-restart mo ang device."</string>
<string name="kg_prompt_reason_restart_password" msgid="2375742919528461664">"Kinakailangan ang password kapag ni-restart mo ang device."</string>
+ <string name="kg_prompt_reason_timeout_pattern" msgid="8930047492617900785">"Kinakailangan ang pattern para sa karagdagang seguridad."</string>
+ <string name="kg_prompt_reason_timeout_pin" msgid="7470468607947726377">"Kinakailangan ang PIN para sa karagdagang seguridad."</string>
+ <string name="kg_prompt_reason_timeout_password" msgid="1177412542773936957">"Kinakailangan ang password para sa karagdagang seguridad."</string>
<string name="kg_prompt_reason_switch_profiles_pattern" msgid="3802056699323773969">"Kinakailangan ang pattern kapag lumipat ka ng mga profile."</string>
<string name="kg_prompt_reason_switch_profiles_pin" msgid="8108020184731052246">"Kinakailangan ang PIN kapag lumipat ka ng mga profile."</string>
<string name="kg_prompt_reason_switch_profiles_password" msgid="6755997057852042672">"Kinakailangan ang password kapag lumipat ka ng mga profile."</string>
diff --git a/packages/Keyguard/res/values-tr/strings.xml b/packages/Keyguard/res/values-tr/strings.xml
index 2f7fb81..1e8a589a 100644
--- a/packages/Keyguard/res/values-tr/strings.xml
+++ b/packages/Keyguard/res/values-tr/strings.xml
@@ -31,6 +31,8 @@
<string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"Yanlış PIN kodu."</string>
<string name="keyguard_charged" msgid="3272223906073492454">"Şarj oldu"</string>
<string name="keyguard_plugged_in" msgid="9087497435553252863">"Şarj oluyor"</string>
+ <string name="keyguard_plugged_in_charging_fast" msgid="6671162730167305479">"Hızlı şarj oluyor"</string>
+ <string name="keyguard_plugged_in_charging_slowly" msgid="1964714661071163229">"Yavaş şarj oluyor"</string>
<string name="keyguard_low_battery" msgid="8143808018719173859">"Şarj cihazınızı takın."</string>
<string name="keyguard_instructions_when_pattern_disabled" msgid="1332288268600329841">"Kilidi açmak için Menü\'ye basın."</string>
<string name="keyguard_network_locked_message" msgid="9169717779058037168">"Ağ kilitli"</string>
@@ -111,6 +113,9 @@
<string name="kg_prompt_reason_restart_pattern" msgid="489430505491862444">"Cihazı yeniden başlattığınızda desen gerekir."</string>
<string name="kg_prompt_reason_restart_pin" msgid="994878216570694974">"Cihazı yeniden başlattığınızda PIN gerekir."</string>
<string name="kg_prompt_reason_restart_password" msgid="2375742919528461664">"Cihazı yeniden başlattığınızda şifre gerekir."</string>
+ <string name="kg_prompt_reason_timeout_pattern" msgid="8930047492617900785">"Ek güvenlik için desen gerekiyor."</string>
+ <string name="kg_prompt_reason_timeout_pin" msgid="7470468607947726377">"Ek güvenlik için PIN gerekiyor."</string>
+ <string name="kg_prompt_reason_timeout_password" msgid="1177412542773936957">"Ek güvenlik için şifre gerekiyor."</string>
<string name="kg_prompt_reason_switch_profiles_pattern" msgid="3802056699323773969">"Profil değiştirdiğinizde desen gerekir."</string>
<string name="kg_prompt_reason_switch_profiles_pin" msgid="8108020184731052246">"Profil değiştirdiğinizde PIN gerekir."</string>
<string name="kg_prompt_reason_switch_profiles_password" msgid="6755997057852042672">"Profil değiştirdiğinizde şifre gerekir."</string>
diff --git a/packages/Keyguard/res/values-uk/strings.xml b/packages/Keyguard/res/values-uk/strings.xml
index 0b2840c..dba0f6c 100644
--- a/packages/Keyguard/res/values-uk/strings.xml
+++ b/packages/Keyguard/res/values-uk/strings.xml
@@ -31,6 +31,8 @@
<string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"Неправильний PIN-код."</string>
<string name="keyguard_charged" msgid="3272223906073492454">"Заряджено"</string>
<string name="keyguard_plugged_in" msgid="9087497435553252863">"Заряджається"</string>
+ <string name="keyguard_plugged_in_charging_fast" msgid="6671162730167305479">"Швидке заряджання"</string>
+ <string name="keyguard_plugged_in_charging_slowly" msgid="1964714661071163229">"Повільне заряджання"</string>
<string name="keyguard_low_battery" msgid="8143808018719173859">"Підключіть зарядний пристрій."</string>
<string name="keyguard_instructions_when_pattern_disabled" msgid="1332288268600329841">"Натисніть Меню, щоб розблокувати."</string>
<string name="keyguard_network_locked_message" msgid="9169717779058037168">"Мережу заблоковано"</string>
@@ -115,6 +117,9 @@
<string name="kg_prompt_reason_restart_pattern" msgid="489430505491862444">"Після перезавантаження пристрою потрібно ввести ключ."</string>
<string name="kg_prompt_reason_restart_pin" msgid="994878216570694974">"Після перезавантаження пристрою потрібно ввести PIN-код."</string>
<string name="kg_prompt_reason_restart_password" msgid="2375742919528461664">"Після перезавантаження пристрою потрібно ввести пароль."</string>
+ <string name="kg_prompt_reason_timeout_pattern" msgid="8930047492617900785">"Введіть ключ. Це потрібно зробити з міркувань безпеки."</string>
+ <string name="kg_prompt_reason_timeout_pin" msgid="7470468607947726377">"Введіть PIN-код. Це потрібно зробити з міркувань безпеки."</string>
+ <string name="kg_prompt_reason_timeout_password" msgid="1177412542773936957">"Введіть пароль. Це потрібно зробити з міркувань безпеки."</string>
<string name="kg_prompt_reason_switch_profiles_pattern" msgid="3802056699323773969">"Після переходу в інший профіль потрібно ввести ключ."</string>
<string name="kg_prompt_reason_switch_profiles_pin" msgid="8108020184731052246">"Після переходу в інший профіль потрібно ввести PIN-код."</string>
<string name="kg_prompt_reason_switch_profiles_password" msgid="6755997057852042672">"Після переходу в інший профіль потрібно ввести пароль."</string>
diff --git a/packages/Keyguard/res/values-ur-rPK/strings.xml b/packages/Keyguard/res/values-ur-rPK/strings.xml
index 05e68d5..b6a993b 100644
--- a/packages/Keyguard/res/values-ur-rPK/strings.xml
+++ b/packages/Keyguard/res/values-ur-rPK/strings.xml
@@ -31,6 +31,8 @@
<string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"غلط PIN کوڈ۔"</string>
<string name="keyguard_charged" msgid="3272223906073492454">"چارج ہو گیا"</string>
<string name="keyguard_plugged_in" msgid="9087497435553252863">"چارج ہو رہی ہے"</string>
+ <string name="keyguard_plugged_in_charging_fast" msgid="6671162730167305479">"تیزی سے چارج ہو رہا ہے"</string>
+ <string name="keyguard_plugged_in_charging_slowly" msgid="1964714661071163229">"آہستہ چارج ہو رہا ہے"</string>
<string name="keyguard_low_battery" msgid="8143808018719173859">"اپنا چارجر مربوط کریں۔"</string>
<string name="keyguard_instructions_when_pattern_disabled" msgid="1332288268600329841">"غیر مقفل کرنے کیلئے مینو کو دبائیں۔"</string>
<string name="keyguard_network_locked_message" msgid="9169717779058037168">"نیٹ ورک مقفل ہو گیا"</string>
@@ -111,6 +113,9 @@
<string name="kg_prompt_reason_restart_pattern" msgid="489430505491862444">"جب آپ آلہ کو دوبارہ شروع کرتے ہیں تو پیٹرن درکار ہوتا ہے۔"</string>
<string name="kg_prompt_reason_restart_pin" msgid="994878216570694974">"جب آپ آلہ کو دوبارہ شروع کرتے ہیں تو PIN درکار ہوتا ہے۔"</string>
<string name="kg_prompt_reason_restart_password" msgid="2375742919528461664">"جب آپ آلہ کو دوبارہ شروع کرتے ہیں تو پاسورڈ درکار ہوتا ہے۔"</string>
+ <string name="kg_prompt_reason_timeout_pattern" msgid="8930047492617900785">"اضافی سیکیورٹی کیلئے پیٹرن درکار ہے۔"</string>
+ <string name="kg_prompt_reason_timeout_pin" msgid="7470468607947726377">"اضافی سیکیورٹی کیلئے PIN درکار ہے۔"</string>
+ <string name="kg_prompt_reason_timeout_password" msgid="1177412542773936957">"اضافی سیکیورٹی کیلئے پاسورڈ درکار ہے۔"</string>
<string name="kg_prompt_reason_switch_profiles_pattern" msgid="3802056699323773969">"جب آپ پروفائل سوئچ کرتے ہیں تو پیٹرن درکار ہوتا ہے۔"</string>
<string name="kg_prompt_reason_switch_profiles_pin" msgid="8108020184731052246">"جب آپ پروفائل سوئچ کرتے ہیں تو PIN درکار ہوتا ہے۔"</string>
<string name="kg_prompt_reason_switch_profiles_password" msgid="6755997057852042672">"جب آپ پروفائل سوئچ کرتے ہیں تو پاسورڈ درکار ہوتا ہے۔"</string>
diff --git a/packages/Keyguard/res/values-uz-rUZ/strings.xml b/packages/Keyguard/res/values-uz-rUZ/strings.xml
index daf5318..b87298d 100644
--- a/packages/Keyguard/res/values-uz-rUZ/strings.xml
+++ b/packages/Keyguard/res/values-uz-rUZ/strings.xml
@@ -31,6 +31,8 @@
<string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"Noto‘g‘ri PIN-kod."</string>
<string name="keyguard_charged" msgid="3272223906073492454">"Batareya quvvati to‘ldi"</string>
<string name="keyguard_plugged_in" msgid="9087497435553252863">"Quvvat olmoqda"</string>
+ <string name="keyguard_plugged_in_charging_fast" msgid="6671162730167305479">"Tezkor quvvat olmoqda"</string>
+ <string name="keyguard_plugged_in_charging_slowly" msgid="1964714661071163229">"Sekin quvvat olmoqda"</string>
<string name="keyguard_low_battery" msgid="8143808018719173859">"Zaryadlagichni ulang."</string>
<string name="keyguard_instructions_when_pattern_disabled" msgid="1332288268600329841">"Qulfni ochish uchun \"Menyu\"ga bosing."</string>
<string name="keyguard_network_locked_message" msgid="9169717779058037168">"Tarmoq qulflangan"</string>
@@ -111,6 +113,9 @@
<string name="kg_prompt_reason_restart_pattern" msgid="489430505491862444">"Qurilmani o‘chirib yoqishda chizmali kalit talab qilinadi."</string>
<string name="kg_prompt_reason_restart_pin" msgid="994878216570694974">"Qurilmani o‘chirib yoqishda PIN-kod talab qilinadi."</string>
<string name="kg_prompt_reason_restart_password" msgid="2375742919528461664">"Qurilmani o‘chirib yoqishda parol talab qilinadi."</string>
+ <string name="kg_prompt_reason_timeout_pattern" msgid="8930047492617900785">"Qo‘shimcha xavfsizlik chorasi sifatida chizmali kalit talab qilinadi."</string>
+ <string name="kg_prompt_reason_timeout_pin" msgid="7470468607947726377">"Qo‘shimcha xavfsizlik chorasi sifatida PIN-kod talab qilinadi."</string>
+ <string name="kg_prompt_reason_timeout_password" msgid="1177412542773936957">"Qo‘shimcha xavfsizlik chorasi sifatida parol talab qilinadi."</string>
<string name="kg_prompt_reason_switch_profiles_pattern" msgid="3802056699323773969">"Profilni amlashtirishda chizmali kalit talab qilinadi."</string>
<string name="kg_prompt_reason_switch_profiles_pin" msgid="8108020184731052246">"Profilni amlashtirishda PIN-kod talab qilinadi."</string>
<string name="kg_prompt_reason_switch_profiles_password" msgid="6755997057852042672">"Profilni amlashtirishda parol talab qilinadi."</string>
diff --git a/packages/Keyguard/res/values-vi/strings.xml b/packages/Keyguard/res/values-vi/strings.xml
index 37b385c..0568998 100644
--- a/packages/Keyguard/res/values-vi/strings.xml
+++ b/packages/Keyguard/res/values-vi/strings.xml
@@ -31,6 +31,8 @@
<string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"Mã PIN không chính xác."</string>
<string name="keyguard_charged" msgid="3272223906073492454">"Đã sạc đầy"</string>
<string name="keyguard_plugged_in" msgid="9087497435553252863">"Đang sạc"</string>
+ <string name="keyguard_plugged_in_charging_fast" msgid="6671162730167305479">"Đang sạc nhanh"</string>
+ <string name="keyguard_plugged_in_charging_slowly" msgid="1964714661071163229">"Đang sạc chậm"</string>
<string name="keyguard_low_battery" msgid="8143808018719173859">"Kết nối bộ sạc của bạn."</string>
<string name="keyguard_instructions_when_pattern_disabled" msgid="1332288268600329841">"Nhấn vào Menu để mở khóa."</string>
<string name="keyguard_network_locked_message" msgid="9169717779058037168">"Mạng đã bị khóa"</string>
@@ -111,6 +113,9 @@
<string name="kg_prompt_reason_restart_pattern" msgid="489430505491862444">"Yêu cầu hình khi bạn khởi động lại thiết bị."</string>
<string name="kg_prompt_reason_restart_pin" msgid="994878216570694974">"Yêu cầu mã PIN khi bạn khởi động lại thiết bị."</string>
<string name="kg_prompt_reason_restart_password" msgid="2375742919528461664">"Yêu cầu mật khẩu khi bạn khởi động lại thiết bị."</string>
+ <string name="kg_prompt_reason_timeout_pattern" msgid="8930047492617900785">"Cần có mẫu hình để bảo mật thêm."</string>
+ <string name="kg_prompt_reason_timeout_pin" msgid="7470468607947726377">"Cần có mã PIN để bảo mật thêm."</string>
+ <string name="kg_prompt_reason_timeout_password" msgid="1177412542773936957">"Cần có mật khẩu để bảo mật thêm."</string>
<string name="kg_prompt_reason_switch_profiles_pattern" msgid="3802056699323773969">"Yêu cầu hình khi bạn chuyển đổi hồ sơ."</string>
<string name="kg_prompt_reason_switch_profiles_pin" msgid="8108020184731052246">"Yêu cầu mã PIN khi bạn chuyển đổi hồ sơ."</string>
<string name="kg_prompt_reason_switch_profiles_password" msgid="6755997057852042672">"Yêu cầu mật khẩu khi bạn chuyển đổi hồ sơ."</string>
diff --git a/packages/Keyguard/res/values-zh-rCN/strings.xml b/packages/Keyguard/res/values-zh-rCN/strings.xml
index 5afbf4c..5b1e45d 100644
--- a/packages/Keyguard/res/values-zh-rCN/strings.xml
+++ b/packages/Keyguard/res/values-zh-rCN/strings.xml
@@ -31,6 +31,8 @@
<string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"PIN码有误。"</string>
<string name="keyguard_charged" msgid="3272223906073492454">"已充满"</string>
<string name="keyguard_plugged_in" msgid="9087497435553252863">"正在充电"</string>
+ <string name="keyguard_plugged_in_charging_fast" msgid="6671162730167305479">"正在快速充电"</string>
+ <string name="keyguard_plugged_in_charging_slowly" msgid="1964714661071163229">"正在慢速充电"</string>
<string name="keyguard_low_battery" msgid="8143808018719173859">"请连接充电器。"</string>
<string name="keyguard_instructions_when_pattern_disabled" msgid="1332288268600329841">"按“菜单”键解锁。"</string>
<string name="keyguard_network_locked_message" msgid="9169717779058037168">"网络已锁定"</string>
@@ -111,6 +113,9 @@
<string name="kg_prompt_reason_restart_pattern" msgid="489430505491862444">"重启设备后需要绘制图案。"</string>
<string name="kg_prompt_reason_restart_pin" msgid="994878216570694974">"重启设备后需要输入 PIN 码。"</string>
<string name="kg_prompt_reason_restart_password" msgid="2375742919528461664">"重启设备后需要输入密码。"</string>
+ <string name="kg_prompt_reason_timeout_pattern" msgid="8930047492617900785">"需要绘制解锁图案,以进一步确保安全。"</string>
+ <string name="kg_prompt_reason_timeout_pin" msgid="7470468607947726377">"需要输入 PIN 码,以进一步确保安全。"</string>
+ <string name="kg_prompt_reason_timeout_password" msgid="1177412542773936957">"需要输入密码,以进一步确保安全。"</string>
<string name="kg_prompt_reason_switch_profiles_pattern" msgid="3802056699323773969">"切换资料后需要绘制图案。"</string>
<string name="kg_prompt_reason_switch_profiles_pin" msgid="8108020184731052246">"切换资料后需要输入 PIN 码。"</string>
<string name="kg_prompt_reason_switch_profiles_password" msgid="6755997057852042672">"切换资料后需要输入密码。"</string>
diff --git a/packages/Keyguard/res/values-zh-rHK/strings.xml b/packages/Keyguard/res/values-zh-rHK/strings.xml
index 9b5acf6..542e1b8 100644
--- a/packages/Keyguard/res/values-zh-rHK/strings.xml
+++ b/packages/Keyguard/res/values-zh-rHK/strings.xml
@@ -31,6 +31,8 @@
<string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"PIN 碼不正確。"</string>
<string name="keyguard_charged" msgid="3272223906073492454">"充電完成"</string>
<string name="keyguard_plugged_in" msgid="9087497435553252863">"充電中"</string>
+ <string name="keyguard_plugged_in_charging_fast" msgid="6671162730167305479">"正在快速充電"</string>
+ <string name="keyguard_plugged_in_charging_slowly" msgid="1964714661071163229">"正在緩慢充電"</string>
<string name="keyguard_low_battery" msgid="8143808018719173859">"請連接充電器。"</string>
<string name="keyguard_instructions_when_pattern_disabled" msgid="1332288268600329841">"按選單鍵解鎖。"</string>
<string name="keyguard_network_locked_message" msgid="9169717779058037168">"網絡已鎖定"</string>
@@ -111,6 +113,9 @@
<string name="kg_prompt_reason_restart_pattern" msgid="489430505491862444">"需要圖案方可重新啟動裝置。"</string>
<string name="kg_prompt_reason_restart_pin" msgid="994878216570694974">"需要 PIN 方可重新啟動裝置。"</string>
<string name="kg_prompt_reason_restart_password" msgid="2375742919528461664">"需要密碼方可重新啟動裝置。"</string>
+ <string name="kg_prompt_reason_timeout_pattern" msgid="8930047492617900785">"需要使用圖案以提高安全性。"</string>
+ <string name="kg_prompt_reason_timeout_pin" msgid="7470468607947726377">"需要使用 PIN 以提高安全性。"</string>
+ <string name="kg_prompt_reason_timeout_password" msgid="1177412542773936957">"需要使用密碼以提高安全性。"</string>
<string name="kg_prompt_reason_switch_profiles_pattern" msgid="3802056699323773969">"需要圖案方可切換設定檔。"</string>
<string name="kg_prompt_reason_switch_profiles_pin" msgid="8108020184731052246">"需要 PIN 方可切換設定檔。"</string>
<string name="kg_prompt_reason_switch_profiles_password" msgid="6755997057852042672">"需要密碼方可切換設定檔。"</string>
diff --git a/packages/Keyguard/res/values-zh-rTW/strings.xml b/packages/Keyguard/res/values-zh-rTW/strings.xml
index 9491076..56d0573 100644
--- a/packages/Keyguard/res/values-zh-rTW/strings.xml
+++ b/packages/Keyguard/res/values-zh-rTW/strings.xml
@@ -31,6 +31,8 @@
<string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"PIN 碼不正確。"</string>
<string name="keyguard_charged" msgid="3272223906073492454">"充電完成"</string>
<string name="keyguard_plugged_in" msgid="9087497435553252863">"充電中"</string>
+ <string name="keyguard_plugged_in_charging_fast" msgid="6671162730167305479">"快速充電中"</string>
+ <string name="keyguard_plugged_in_charging_slowly" msgid="1964714661071163229">"慢速充電中"</string>
<string name="keyguard_low_battery" msgid="8143808018719173859">"連接充電器。"</string>
<string name="keyguard_instructions_when_pattern_disabled" msgid="1332288268600329841">"按選單鍵解鎖。"</string>
<string name="keyguard_network_locked_message" msgid="9169717779058037168">"網路已鎖定"</string>
@@ -111,6 +113,9 @@
<string name="kg_prompt_reason_restart_pattern" msgid="489430505491862444">"重新啟動裝置時需要確認圖形。"</string>
<string name="kg_prompt_reason_restart_pin" msgid="994878216570694974">"重新啟動裝置時需要確認 PIN 碼。"</string>
<string name="kg_prompt_reason_restart_password" msgid="2375742919528461664">"重新啟動裝置時需要確認密碼。"</string>
+ <string name="kg_prompt_reason_timeout_pattern" msgid="8930047492617900785">"請輸入解鎖圖形,以進一步確保資訊安全。"</string>
+ <string name="kg_prompt_reason_timeout_pin" msgid="7470468607947726377">"請輸入 PIN 碼,以進一步確保資訊安全。"</string>
+ <string name="kg_prompt_reason_timeout_password" msgid="1177412542773936957">"請輸入密碼,以進一步確保資訊安全。"</string>
<string name="kg_prompt_reason_switch_profiles_pattern" msgid="3802056699323773969">"切換設定檔時需要確認圖形。"</string>
<string name="kg_prompt_reason_switch_profiles_pin" msgid="8108020184731052246">"切換設定檔時需要確認 PIN 碼。"</string>
<string name="kg_prompt_reason_switch_profiles_password" msgid="6755997057852042672">"切換設定檔時需要確認密碼。"</string>
diff --git a/packages/Keyguard/res/values-zu/strings.xml b/packages/Keyguard/res/values-zu/strings.xml
index 784dc5c..c29619c 100644
--- a/packages/Keyguard/res/values-zu/strings.xml
+++ b/packages/Keyguard/res/values-zu/strings.xml
@@ -31,6 +31,8 @@
<string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"Ikhodi ye-PIN engalungile!"</string>
<string name="keyguard_charged" msgid="3272223906073492454">"Kushajiwe"</string>
<string name="keyguard_plugged_in" msgid="9087497435553252863">"Iyashaja"</string>
+ <string name="keyguard_plugged_in_charging_fast" msgid="6671162730167305479">"Ishaja ngokushesha"</string>
+ <string name="keyguard_plugged_in_charging_slowly" msgid="1964714661071163229">"Ishaja kancane"</string>
<string name="keyguard_low_battery" msgid="8143808018719173859">"Xhuma ishaja yakho."</string>
<string name="keyguard_instructions_when_pattern_disabled" msgid="1332288268600329841">"Chofoza imenyu ukuze uvule."</string>
<string name="keyguard_network_locked_message" msgid="9169717779058037168">"Inethiwekhi ikhiyiwe"</string>
@@ -111,6 +113,9 @@
<string name="kg_prompt_reason_restart_pattern" msgid="489430505491862444">"Iphethini iyadingeka uma uqalisa kabusha idivayisi."</string>
<string name="kg_prompt_reason_restart_pin" msgid="994878216570694974">"Iphinikhodi iyadingeka uma uqalisa kabusha idivayisi."</string>
<string name="kg_prompt_reason_restart_password" msgid="2375742919528461664">"Iphasiwedi iyadingeka uma uqalisa kabusha idivayisi."</string>
+ <string name="kg_prompt_reason_timeout_pattern" msgid="8930047492617900785">"Iphethini iyadingeka ngokuvikela okungeziwe."</string>
+ <string name="kg_prompt_reason_timeout_pin" msgid="7470468607947726377">"Iphinikhodi iyadingeka ngokuvikela okungeziwe."</string>
+ <string name="kg_prompt_reason_timeout_password" msgid="1177412542773936957">"Iphasiwedi iyadingeka ngokuvikela okungeziwe."</string>
<string name="kg_prompt_reason_switch_profiles_pattern" msgid="3802056699323773969">"Iphethini iyadingeka uma ushintsha amaphrofayela."</string>
<string name="kg_prompt_reason_switch_profiles_pin" msgid="8108020184731052246">"Iphinikhodi iyadingeka uma ushintsha amaphrofayela."</string>
<string name="kg_prompt_reason_switch_profiles_password" msgid="6755997057852042672">"Iphasiwedi iyadingeka uma ushintsha amaphrofayela."</string>
diff --git a/packages/Keyguard/res/values/config.xml b/packages/Keyguard/res/values/config.xml
index 8d9d6ee..b398ab2 100644
--- a/packages/Keyguard/res/values/config.xml
+++ b/packages/Keyguard/res/values/config.xml
@@ -22,4 +22,10 @@
<!-- Allow the menu hard key to be disabled in LockScreen on some devices [DO NOT TRANSLATE] -->
<bool name="config_disableMenuKeyInLockScreen">false</bool>
+
+ <!-- Threshold in micro amperes below which a charger is rated as "slow" -->
+ <integer name="config_chargingSlowlyThreshold">1000000</integer>
+
+ <!-- Threshold in micro amperes above which a charger is rated as "fast" -->
+ <integer name="config_chargingFastThreshold">1500000</integer>
</resources>
diff --git a/packages/Keyguard/res/values/strings.xml b/packages/Keyguard/res/values/strings.xml
index cba122f..d1e84f5 100644
--- a/packages/Keyguard/res/values/strings.xml
+++ b/packages/Keyguard/res/values/strings.xml
@@ -56,6 +56,14 @@
is not fully charged, say that it's charging. -->
<string name="keyguard_plugged_in">Charging</string>
+ <!-- When the lock screen is showing and the phone plugged in, and the battery
+ is not fully charged, and it's plugged into a fast charger, say that it's charging fast. -->
+ <string name="keyguard_plugged_in_charging_fast">Charging rapidly</string>
+
+ <!-- When the lock screen is showing and the phone plugged in, and the battery
+ is not fully charged, and it's plugged into a slow charger, say that it's charging slowly. -->
+ <string name="keyguard_plugged_in_charging_slowly">Charging slowly</string>
+
<!-- When the lock screen is showing and the battery is low, warn user to plug
in the phone soon. -->
<string name="keyguard_low_battery">Connect your charger.</string>
@@ -308,6 +316,15 @@
<!-- An explanation text that the password needs to be entered since the device has just been restarted. [CHAR LIMIT=80] -->
<string name="kg_prompt_reason_restart_password">Password required when you restart device.</string>
+ <!-- An explanation text that the pattern needs to be solved since the user hasn't used strong authentication since quite some time. [CHAR LIMIT=80] -->
+ <string name="kg_prompt_reason_timeout_pattern">Pattern required for additional security.</string>
+
+ <!-- An explanation text that the pin needs to be entered since the user hasn't used strong authentication since quite some time. [CHAR LIMIT=80] -->
+ <string name="kg_prompt_reason_timeout_pin">PIN required for additional security.</string>
+
+ <!-- An explanation text that the password needs to be entered since the user hasn't used strong authentication since quite some time. [CHAR LIMIT=80] -->
+ <string name="kg_prompt_reason_timeout_password">Password required for additional security.</string>
+
<!-- An explanation text that the pattern needs to be solved since profiles have just been switched. [CHAR LIMIT=80] -->
<string name="kg_prompt_reason_switch_profiles_pattern">Pattern required when you switch profiles.</string>
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardAbsKeyInputView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardAbsKeyInputView.java
index 8f792de..b03871a 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardAbsKeyInputView.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardAbsKeyInputView.java
@@ -40,6 +40,7 @@
protected SecurityMessageDisplay mSecurityMessageDisplay;
protected View mEcaView;
protected boolean mEnableHaptics;
+ private boolean mDismissing;
// To avoid accidental lockout due to events while the device in in the pocket, ignore
// any passwords with length less than or equal to this length.
@@ -67,6 +68,7 @@
@Override
public void reset() {
// start fresh
+ mDismissing = false;
resetPasswordText(false /* animate */);
// if the user is currently locked out, enforce it.
long deadline = mLockPatternUtils.getLockoutAttemptDeadline(
@@ -113,6 +115,8 @@
}
protected void verifyPasswordAndUnlock() {
+ if (mDismissing) return; // already verified but haven't been dismissed; don't do it again.
+
final String entry = getPasswordText();
setPasswordEntryInputEnabled(false);
if (mPendingLockCheck != null) {
@@ -143,6 +147,7 @@
private void onPasswordChecked(boolean matched, int timeoutMs, boolean isValidPassword) {
if (matched) {
+ mDismissing = true;
mCallback.reportUnlockAttempt(true, 0);
mCallback.dismiss(true);
} else {
@@ -234,6 +239,12 @@
}
}
+ @Override
+ public void showMessage(String message, int color) {
+ mSecurityMessageDisplay.setNextMessageColor(color);
+ mSecurityMessageDisplay.setMessage(message, true /* important */);
+ }
+
protected abstract int getPromtReasonStringRes(int reason);
// Cause a VIRTUAL_KEY vibration
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardHostView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardHostView.java
index ff4e815..ec2a173 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardHostView.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardHostView.java
@@ -163,13 +163,18 @@
* Show a string explaining why the security view needs to be solved.
*
* @param reason a flag indicating which string should be shown, see
- * {@link KeyguardSecurityView#PROMPT_REASON_NONE}
- * and {@link KeyguardSecurityView#PROMPT_REASON_RESTART}
+ * {@link KeyguardSecurityView#PROMPT_REASON_NONE},
+ * {@link KeyguardSecurityView#PROMPT_REASON_RESTART} and
+ * {@link KeyguardSecurityView#PROMPT_REASON_TIMEOUT}.
*/
public void showPromptReason(int reason) {
mSecurityContainer.showPromptReason(reason);
}
+ public void showMessage(String message, int color) {
+ mSecurityContainer.showMessage(message, color);
+ }
+
/**
* Dismisses the keyguard by going to the next screen or making it gone.
*
@@ -209,9 +214,12 @@
/**
* Authentication has happened and it's time to dismiss keyguard. This function
* should clean up and inform KeyguardViewMediator.
+ *
+ * @param strongAuth whether the user has authenticated with strong authentication like
+ * pattern, password or PIN but not by trust agents or fingerprint
*/
@Override
- public void finish() {
+ public void finish(boolean strongAuth) {
// If there's a pending runnable because the user interacted with a widget
// and we're leaving keyguard, then run it.
boolean deferKeyguardDone = false;
@@ -222,9 +230,9 @@
}
if (mViewMediatorCallback != null) {
if (deferKeyguardDone) {
- mViewMediatorCallback.keyguardDonePending();
+ mViewMediatorCallback.keyguardDonePending(strongAuth);
} else {
- mViewMediatorCallback.keyguardDone(true);
+ mViewMediatorCallback.keyguardDone(strongAuth);
}
}
}
@@ -281,32 +289,6 @@
}
/**
- * Verify that the user can get past the keyguard securely. This is called,
- * for example, when the phone disables the keyguard but then wants to launch
- * something else that requires secure access.
- *
- * The result will be propogated back via {@link KeyguardViewCallback#keyguardDone(boolean)}
- */
- public void verifyUnlock() {
- SecurityMode securityMode = mSecurityContainer.getSecurityMode();
- if (securityMode == KeyguardSecurityModel.SecurityMode.None) {
- if (mViewMediatorCallback != null) {
- mViewMediatorCallback.keyguardDone(true);
- }
- } else if (securityMode != KeyguardSecurityModel.SecurityMode.Pattern
- && securityMode != KeyguardSecurityModel.SecurityMode.PIN
- && securityMode != KeyguardSecurityModel.SecurityMode.Password) {
- // can only verify unlock when in pattern/password mode
- if (mViewMediatorCallback != null) {
- mViewMediatorCallback.keyguardDone(false);
- }
- } else {
- // otherwise, go to the unlock screen, see if they can verify it
- mSecurityContainer.verifyUnlock();
- }
- }
-
- /**
* Called before this view is being removed.
*/
public void cleanUp() {
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardMessageArea.java b/packages/Keyguard/src/com/android/keyguard/KeyguardMessageArea.java
index 2951af9..c8adf64 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardMessageArea.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardMessageArea.java
@@ -39,15 +39,18 @@
* lift-to-type from interrupting itself.
*/
private static final long ANNOUNCEMENT_DELAY = 250;
+ private static final int DEFAULT_COLOR = -1;
private static final int SECURITY_MESSAGE_DURATION = 5000;
private final KeyguardUpdateMonitor mUpdateMonitor;
private final Handler mHandler;
+ private final int mDefaultColor;
// Timeout before we reset the message to show charging/owner info
long mTimeout = SECURITY_MESSAGE_DURATION;
CharSequence mMessage;
+ private int mNextMessageColor = DEFAULT_COLOR;
private final Runnable mClearMessageRunnable = new Runnable() {
@Override
@@ -78,10 +81,16 @@
mUpdateMonitor.registerCallback(mInfoCallback);
mHandler = new Handler(Looper.myLooper());
+ mDefaultColor = getCurrentTextColor();
update();
}
@Override
+ public void setNextMessageColor(int color) {
+ mNextMessageColor = color;
+ }
+
+ @Override
public void setMessage(CharSequence msg, boolean important) {
if (!TextUtils.isEmpty(msg) && important) {
securityMessageChanged(msg);
@@ -151,6 +160,12 @@
CharSequence status = mMessage;
setVisibility(TextUtils.isEmpty(status) ? INVISIBLE : VISIBLE);
setText(status);
+ int color = mDefaultColor;
+ if (mNextMessageColor != DEFAULT_COLOR) {
+ color = mNextMessageColor;
+ mNextMessageColor = DEFAULT_COLOR;
+ }
+ setTextColor(color);
}
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardPasswordView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardPasswordView.java
index 2db87b3..3a7e6d0 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardPasswordView.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardPasswordView.java
@@ -115,6 +115,8 @@
switch (reason) {
case PROMPT_REASON_RESTART:
return R.string.kg_prompt_reason_restart_password;
+ case PROMPT_REASON_TIMEOUT:
+ return R.string.kg_prompt_reason_timeout_password;
default:
return 0;
}
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardPatternView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardPatternView.java
index 4bd1a2e..9a91ca4 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardPatternView.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardPatternView.java
@@ -15,10 +15,6 @@
*/
package com.android.keyguard;
-import android.animation.Animator;
-import android.animation.AnimatorListenerAdapter;
-import android.animation.ObjectAnimator;
-import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.Rect;
import android.os.AsyncTask;
@@ -28,7 +24,6 @@
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
-import android.view.RenderNodeAnimator;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.AnimationUtils;
@@ -337,11 +332,22 @@
mSecurityMessageDisplay.setMessage(R.string.kg_prompt_reason_restart_pattern,
true /* important */);
break;
+ case PROMPT_REASON_TIMEOUT:
+ mSecurityMessageDisplay.setMessage(R.string.kg_prompt_reason_timeout_pattern,
+ true /* important */);
+ break;
default:
+ break;
}
}
@Override
+ public void showMessage(String message, int color) {
+ mSecurityMessageDisplay.setNextMessageColor(color);
+ mSecurityMessageDisplay.setMessage(message, true /* important */);
+ }
+
+ @Override
public void startAppearAnimation() {
enableClipping(false);
setAlpha(1f);
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardPinBasedInputView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardPinBasedInputView.java
index 07947b1..f51e10f 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardPinBasedInputView.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardPinBasedInputView.java
@@ -62,18 +62,21 @@
return mPasswordEntry.requestFocus(direction, previouslyFocusedRect);
}
+ @Override
protected void resetState() {
- mPasswordEntry.setEnabled(true);
+ setPasswordEntryEnabled(true);
}
@Override
protected void setPasswordEntryEnabled(boolean enabled) {
mPasswordEntry.setEnabled(enabled);
+ mOkButton.setEnabled(enabled);
}
@Override
protected void setPasswordEntryInputEnabled(boolean enabled) {
mPasswordEntry.setEnabled(enabled);
+ mOkButton.setEnabled(enabled);
}
@Override
@@ -98,6 +101,8 @@
switch (reason) {
case PROMPT_REASON_RESTART:
return R.string.kg_prompt_reason_restart_pin;
+ case PROMPT_REASON_TIMEOUT:
+ return R.string.kg_prompt_reason_timeout_pin;
default:
return 0;
}
@@ -184,6 +189,7 @@
mDeleteButton = findViewById(R.id.delete_button);
mDeleteButton.setVisibility(View.VISIBLE);
mDeleteButton.setOnClickListener(new OnClickListener() {
+ @Override
public void onClick(View v) {
// check for time-based lockouts
if (mPasswordEntry.isEnabled()) {
@@ -193,6 +199,7 @@
}
});
mDeleteButton.setOnLongClickListener(new View.OnLongClickListener() {
+ @Override
public boolean onLongClick(View v) {
// check for time-based lockouts
if (mPasswordEntry.isEnabled()) {
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityContainer.java b/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityContainer.java
index 85da298..77215a7 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityContainer.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityContainer.java
@@ -54,7 +54,12 @@
public boolean dismiss(boolean authenticated);
public void userActivity();
public void onSecurityModeChanged(SecurityMode securityMode, boolean needsInput);
- public void finish();
+
+ /**
+ * @param strongAuth wheher the user has authenticated with strong authentication like
+ * pattern, password or PIN but not by trust agents or fingerprint
+ */
+ public void finish(boolean strongAuth);
public void reset();
}
@@ -282,7 +287,7 @@
showWipeDialog(failedAttempts, userType);
}
}
- monitor.reportFailedUnlockAttempt();
+ monitor.reportFailedStrongAuthUnlockAttempt();
mLockPatternUtils.reportFailedPasswordAttempt(KeyguardUpdateMonitor.getCurrentUser());
if (timeoutMs > 0) {
showTimeoutDialog(timeoutMs);
@@ -308,6 +313,7 @@
boolean showNextSecurityScreenOrFinish(boolean authenticated) {
if (DEBUG) Log.d(TAG, "showNextSecurityScreenOrFinish(" + authenticated + ")");
boolean finish = false;
+ boolean strongAuth = false;
if (mUpdateMonitor.getUserCanSkipBouncer(
KeyguardUpdateMonitor.getCurrentUser())) {
finish = true;
@@ -323,6 +329,7 @@
case Pattern:
case Password:
case PIN:
+ strongAuth = true;
finish = true;
break;
@@ -346,7 +353,7 @@
}
}
if (finish) {
- mSecurityCallback.finish();
+ mSecurityCallback.finish(strongAuth);
}
return finish;
}
@@ -518,6 +525,13 @@
}
}
+
+ public void showMessage(String message, int color) {
+ if (mCurrentSecuritySelection != SecurityMode.None) {
+ getSecurityView(mCurrentSecuritySelection).showMessage(message, color);
+ }
+ }
+
@Override
public void showUsabilityHint() {
mSecurityViewFlipper.showUsabilityHint();
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityView.java
index 5658a74..38302fb 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityView.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityView.java
@@ -22,9 +22,18 @@
static public final int VIEW_REVEALED = 2;
int PROMPT_REASON_NONE = 0;
+
+ /**
+ * Strong auth is required because the device has just booted.
+ */
int PROMPT_REASON_RESTART = 1;
/**
+ * Strong auth is required because the user hasn't used strong auth since a while.
+ */
+ int PROMPT_REASON_TIMEOUT = 2;
+
+ /**
* Interface back to keyguard to tell it when security
* @param callback
*/
@@ -77,6 +86,14 @@
void showPromptReason(int reason);
/**
+ * Show a message on the security view with a specified color
+ *
+ * @param message the message to show
+ * @param color the color to use
+ */
+ void showMessage(String message, int color);
+
+ /**
* Instruct the view to show usability hints, if any.
*
*/
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityViewFlipper.java b/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityViewFlipper.java
index a0ff21b..6012c45 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityViewFlipper.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityViewFlipper.java
@@ -139,6 +139,14 @@
}
@Override
+ public void showMessage(String message, int color) {
+ KeyguardSecurityView ksv = getSecurityView();
+ if (ksv != null) {
+ ksv.showMessage(message, color);
+ }
+ }
+
+ @Override
public void showUsabilityHint() {
KeyguardSecurityView ksv = getSecurityView();
if (ksv != null) {
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardSimPinView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardSimPinView.java
index aeac912..2033159 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardSimPinView.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardSimPinView.java
@@ -23,6 +23,7 @@
import android.content.Context;
import android.content.res.ColorStateList;
+import android.content.res.Configuration;
import android.content.res.Resources;
import android.app.AlertDialog;
import android.app.AlertDialog.Builder;
@@ -96,6 +97,12 @@
}
@Override
+ protected void onConfigurationChanged(Configuration newConfig) {
+ super.onConfigurationChanged(newConfig);
+ resetState();
+ }
+
+ @Override
protected int getPromtReasonStringRes(int reason) {
// No message on SIM Pin
return 0;
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java
index c7adc98..f31df51 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java
@@ -29,46 +29,38 @@
import android.content.IntentFilter;
import android.database.ContentObserver;
import android.graphics.Bitmap;
-
-import static android.os.BatteryManager.BATTERY_STATUS_FULL;
-import static android.os.BatteryManager.BATTERY_STATUS_UNKNOWN;
-import static android.os.BatteryManager.BATTERY_HEALTH_UNKNOWN;
-import static android.os.BatteryManager.EXTRA_STATUS;
-import static android.os.BatteryManager.EXTRA_PLUGGED;
-import static android.os.BatteryManager.EXTRA_LEVEL;
-import static android.os.BatteryManager.EXTRA_HEALTH;
-
+import android.hardware.fingerprint.Fingerprint;
+import android.hardware.fingerprint.FingerprintManager;
+import android.hardware.fingerprint.FingerprintManager.AuthenticationCallback;
+import android.hardware.fingerprint.FingerprintManager.AuthenticationResult;
import android.media.AudioManager;
import android.os.BatteryManager;
import android.os.CancellationSignal;
import android.os.Handler;
import android.os.IRemoteCallback;
import android.os.Message;
-import android.os.PowerManager;
import android.os.RemoteException;
import android.os.SystemClock;
import android.os.UserHandle;
import android.provider.Settings;
-
-import com.android.internal.telephony.IccCardConstants;
-import com.android.internal.telephony.IccCardConstants.State;
-import com.android.internal.telephony.PhoneConstants;
-import com.android.internal.telephony.TelephonyIntents;
-
-import android.hardware.fingerprint.FingerprintManager;
-import android.hardware.fingerprint.FingerprintManager.AuthenticationCallback;
-import android.hardware.fingerprint.FingerprintManager.AuthenticationResult;
import android.telephony.ServiceState;
import android.telephony.SubscriptionInfo;
import android.telephony.SubscriptionManager;
import android.telephony.SubscriptionManager.OnSubscriptionsChangedListener;
import android.telephony.TelephonyManager;
+import android.util.ArraySet;
import android.util.Log;
import android.util.SparseBooleanArray;
import android.util.SparseIntArray;
import com.google.android.collect.Lists;
+import com.android.internal.telephony.IccCardConstants;
+import com.android.internal.telephony.IccCardConstants.State;
+import com.android.internal.telephony.PhoneConstants;
+import com.android.internal.telephony.TelephonyIntents;
+import com.android.internal.widget.LockPatternUtils;
+
import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.lang.ref.WeakReference;
@@ -77,6 +69,15 @@
import java.util.List;
import java.util.Map.Entry;
+import static android.os.BatteryManager.BATTERY_HEALTH_UNKNOWN;
+import static android.os.BatteryManager.BATTERY_STATUS_FULL;
+import static android.os.BatteryManager.BATTERY_STATUS_UNKNOWN;
+import static android.os.BatteryManager.EXTRA_HEALTH;
+import static android.os.BatteryManager.EXTRA_LEVEL;
+import static android.os.BatteryManager.EXTRA_MAX_CHARGING_CURRENT;
+import static android.os.BatteryManager.EXTRA_PLUGGED;
+import static android.os.BatteryManager.EXTRA_STATUS;
+
/**
* Watches for updates that may be interesting to the keyguard, and provides
* the up to date information as well as a registration for callbacks that care
@@ -92,32 +93,24 @@
private static final String TAG = "KeyguardUpdateMonitor";
private static final boolean DEBUG = KeyguardConstants.DEBUG;
private static final boolean DEBUG_SIM_STATES = KeyguardConstants.DEBUG_SIM_STATES;
- private static final boolean DEBUG_FP_WAKELOCK = KeyguardConstants.DEBUG_FP_WAKELOCK;
private static final int LOW_BATTERY_THRESHOLD = 20;
- private static final long FINGERPRINT_WAKELOCK_TIMEOUT_MS = 15 * 1000;
private static final String ACTION_FACE_UNLOCK_STARTED
= "com.android.facelock.FACE_UNLOCK_STARTED";
private static final String ACTION_FACE_UNLOCK_STOPPED
= "com.android.facelock.FACE_UNLOCK_STOPPED";
- private static final String FINGERPRINT_WAKE_LOCK_NAME = "wake-and-unlock wakelock";
+
+ private static final String ACTION_STRONG_AUTH_TIMEOUT =
+ "com.android.systemui.ACTION_STRONG_AUTH_TIMEOUT";
+ private static final String USER_ID = "com.android.systemui.USER_ID";
+
+ private static final String PERMISSION_SELF = "com.android.systemui.permission.SELF";
/**
- * Mode in which we don't need to wake up the device when we get a fingerprint.
+ * Milliseconds after unlocking with fingerprint times out, i.e. the user has to use a
+ * strong auth method like password, PIN or pattern.
*/
- private static final int FP_WAKE_NONE = 0;
-
- /**
- * Mode in which we wake up the device, and directly dismiss Keyguard. Active when we acquire
- * a fingerprint while the screen is off and the device was sleeping.
- */
- private static final int FP_WAKE_DIRECT_UNLOCK = 1;
-
- /**
- * Mode in which we wake up the device, but play the normal dismiss animation. Active when we
- * acquire a fingerprint pulsing in doze mode.
- * */
- private static final int FP_WAKE_WAKE_TO_BOUNCER = 2;
+ private static final long FINGERPRINT_UNLOCK_TIMEOUT_MS = 72 * 60 * 60 * 1000;
// Callback messages
private static final int MSG_TIME_UPDATE = 301;
@@ -128,7 +121,6 @@
private static final int MSG_DEVICE_PROVISIONED = 308;
private static final int MSG_DPM_STATE_CHANGED = 309;
private static final int MSG_USER_SWITCHING = 310;
- private static final int MSG_KEYGUARD_VISIBILITY_CHANGED = 311;
private static final int MSG_KEYGUARD_RESET = 312;
private static final int MSG_BOOT_COMPLETED = 313;
private static final int MSG_USER_SWITCH_COMPLETE = 314;
@@ -136,11 +128,32 @@
private static final int MSG_REPORT_EMERGENCY_CALL_ACTION = 318;
private static final int MSG_STARTED_WAKING_UP = 319;
private static final int MSG_FINISHED_GOING_TO_SLEEP = 320;
+ private static final int MSG_STARTED_GOING_TO_SLEEP = 321;
private static final int MSG_KEYGUARD_BOUNCER_CHANGED = 322;
private static final int MSG_FACE_UNLOCK_STATE_CHANGED = 327;
private static final int MSG_SIM_SUBSCRIPTION_INFO_CHANGED = 328;
private static final int MSG_AIRPLANE_MODE_CHANGED = 329;
private static final int MSG_SERVICE_STATE_CHANGE = 330;
+ private static final int MSG_SCREEN_TURNED_ON = 331;
+ private static final int MSG_SCREEN_TURNED_OFF = 332;
+
+ /** Fingerprint state: Not listening to fingerprint. */
+ private static final int FINGERPRINT_STATE_STOPPED = 0;
+
+ /** Fingerprint state: Listening. */
+ private static final int FINGERPRINT_STATE_RUNNING = 1;
+
+ /**
+ * Fingerprint state: Cancelling and waiting for the confirmation from FingerprintService to
+ * send us the confirmation that cancellation has happened.
+ */
+ private static final int FINGERPRINT_STATE_CANCELLING = 2;
+
+ /**
+ * Fingerprint state: During cancelling we got another request to start listening, so when we
+ * receive the cancellation done signal, we should start listening again.
+ */
+ private static final int FINGERPRINT_STATE_CANCELLING_RESTARTING = 3;
private static KeyguardUpdateMonitor sInstance;
@@ -151,9 +164,15 @@
private int mRingMode;
private int mPhoneState;
private boolean mKeyguardIsVisible;
+
+ /**
+ * If true, fingerprint was already authenticated and we don't need to start listening again
+ * until the Keyguard has been dismissed.
+ */
+ private boolean mFingerprintAlreadyAuthenticated;
+ private boolean mGoingToSleep;
private boolean mBouncer;
private boolean mBootCompleted;
- private boolean mUserHasAuthenticatedSinceBoot;
// Device provisioning state
private boolean mDeviceProvisioned;
@@ -164,7 +183,9 @@
// Password attempts
private SparseIntArray mFailedAttempts = new SparseIntArray();
- private boolean mClockVisible;
+ /** Tracks whether strong authentication hasn't been used since quite some time per user. */
+ private ArraySet<Integer> mStrongAuthNotTimedOut = new ArraySet<>();
+ private final StrongAuthTracker mStrongAuthTracker = new StrongAuthTracker();
private final ArrayList<WeakReference<KeyguardUpdateMonitorCallback>>
mCallbacks = Lists.newArrayList();
@@ -175,10 +196,10 @@
private boolean mDeviceInteractive;
private boolean mScreenOn;
private SubscriptionManager mSubscriptionManager;
+ private AlarmManager mAlarmManager;
private List<SubscriptionInfo> mSubscriptionInfo;
- private boolean mFingerprintDetectionRunning;
private TrustManager mTrustManager;
- private PowerManager mPowerManager;
+ private int mFingerprintRunningState = FINGERPRINT_STATE_STOPPED;
private final Handler mHandler = new Handler() {
@Override
@@ -211,9 +232,6 @@
case MSG_USER_SWITCH_COMPLETE:
handleUserSwitchComplete(msg.arg1);
break;
- case MSG_KEYGUARD_VISIBILITY_CHANGED:
- handleKeyguardVisibilityChanged(msg.arg1);
- break;
case MSG_KEYGUARD_RESET:
handleKeyguardReset();
break;
@@ -229,6 +247,9 @@
case MSG_REPORT_EMERGENCY_CALL_ACTION:
handleReportEmergencyCallAction();
break;
+ case MSG_STARTED_GOING_TO_SLEEP:
+ handleStartedGoingToSleep(msg.arg1);
+ break;
case MSG_FINISHED_GOING_TO_SLEEP:
handleFinishedGoingToSleep(msg.arg1);
break;
@@ -247,6 +268,12 @@
case MSG_SERVICE_STATE_CHANGE:
handleServiceStateChange(msg.arg1, (ServiceState) msg.obj);
break;
+ case MSG_SCREEN_TURNED_ON:
+ handleScreenTurnedOn();
+ break;
+ case MSG_SCREEN_TURNED_OFF:
+ handleScreenTurnedOff();
+ break;
}
}
};
@@ -266,8 +293,6 @@
private static int sCurrentUser;
- private int mFpWakeMode;
-
public synchronized static void setCurrentUser(int currentUser) {
sCurrentUser = currentUser;
}
@@ -368,18 +393,28 @@
}
}
- private void onFingerprintAuthenticated(int userId, boolean wakeAndUnlocking) {
+ private void onFingerprintAuthenticated(int userId) {
mUserFingerprintAuthenticated.put(userId, true);
+
+ // If fingerprint unlocking is allowed, this event will lead to a Keyguard dismiss or to a
+ // wake-up (if Keyguard is not showing), so we don't need to listen until Keyguard is
+ // fully gone.
+ mFingerprintAlreadyAuthenticated = isUnlockingWithFingerprintAllowed();
for (int i = 0; i < mCallbacks.size(); i++) {
KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
if (cb != null) {
- cb.onFingerprintAuthenticated(userId, wakeAndUnlocking);
+ cb.onFingerprintAuthenticated(userId);
}
}
}
private void handleFingerprintAuthFailed() {
- releaseFingerprintWakeLock();
+ for (int i = 0; i < mCallbacks.size(); i++) {
+ KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
+ if (cb != null) {
+ cb.onFingerprintAuthFailed();
+ }
+ }
handleFingerprintHelp(-1, mContext.getString(R.string.fingerprint_not_recognized));
}
@@ -387,53 +422,16 @@
if (acquireInfo != FingerprintManager.FINGERPRINT_ACQUIRED_GOOD) {
return;
}
- if (!mDeviceInteractive && !mScreenOn) {
- releaseFingerprintWakeLock();
- mWakeLock = mPowerManager.newWakeLock(
- PowerManager.PARTIAL_WAKE_LOCK, FINGERPRINT_WAKE_LOCK_NAME);
- mWakeLock.acquire();
- mFpWakeMode = FP_WAKE_DIRECT_UNLOCK;
- if (DEBUG_FP_WAKELOCK) {
- Log.i(TAG, "fingerprint acquired, grabbing fp wakelock");
+ for (int i = 0; i < mCallbacks.size(); i++) {
+ KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
+ if (cb != null) {
+ cb.onFingerprintAcquired();
}
- mHandler.postDelayed(mReleaseFingerprintWakeLockRunnable,
- FINGERPRINT_WAKELOCK_TIMEOUT_MS);
- } else if (!mDeviceInteractive) {
- mFpWakeMode = FP_WAKE_WAKE_TO_BOUNCER;
- } else {
- mFpWakeMode = FP_WAKE_NONE;
}
}
- private final Runnable mReleaseFingerprintWakeLockRunnable = new Runnable() {
- @Override
- public void run() {
- if (DEBUG_FP_WAKELOCK) {
- Log.i(TAG, "fp wakelock: TIMEOUT!!");
- }
- releaseFingerprintWakeLock();
- }
- };
- private void releaseFingerprintWakeLock() {
- if (mWakeLock != null) {
- mHandler.removeCallbacks(mReleaseFingerprintWakeLockRunnable);
- if (DEBUG_FP_WAKELOCK) {
- Log.i(TAG, "releasing fp wakelock");
- }
- mWakeLock.release();
- mWakeLock = null;
- }
- }
-
- private void handleFingerprintAuthenticated() {
- if (mFpWakeMode == FP_WAKE_WAKE_TO_BOUNCER || mFpWakeMode == FP_WAKE_DIRECT_UNLOCK) {
- if (DEBUG_FP_WAKELOCK) {
- Log.i(TAG, "fp wakelock: Authenticated, waking up...");
- }
- mPowerManager.wakeUp(SystemClock.uptimeMillis());
- }
- releaseFingerprintWakeLock();
+ private void handleFingerprintAuthenticated(int authUserId) {
try {
final int userId;
try {
@@ -442,13 +440,17 @@
Log.e(TAG, "Failed to get current user id: ", e);
return;
}
+ if (userId != authUserId) {
+ Log.d(TAG, "Fingerprint authenticated for wrong user: " + authUserId);
+ return;
+ }
if (isFingerprintDisabled(userId)) {
Log.d(TAG, "Fingerprint disabled by DPM for userId: " + userId);
return;
}
- onFingerprintAuthenticated(userId, mFpWakeMode == FP_WAKE_DIRECT_UNLOCK);
+ onFingerprintAuthenticated(userId);
} finally {
- setFingerprintRunningDetectionRunning(false);
+ setFingerprintRunningState(FINGERPRINT_STATE_STOPPED);
}
}
@@ -462,7 +464,13 @@
}
private void handleFingerprintError(int msgId, String errString) {
- setFingerprintRunningDetectionRunning(false);
+ if (msgId == FingerprintManager.FINGERPRINT_ERROR_CANCELED
+ && mFingerprintRunningState == FINGERPRINT_STATE_CANCELLING_RESTARTING) {
+ setFingerprintRunningState(FINGERPRINT_STATE_STOPPED);
+ startListeningForFingerprint();
+ } else {
+ setFingerprintRunningState(FINGERPRINT_STATE_STOPPED);
+ }
for (int i = 0; i < mCallbacks.size(); i++) {
KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
if (cb != null) {
@@ -471,9 +479,19 @@
}
}
- private void setFingerprintRunningDetectionRunning(boolean running) {
- if (running != mFingerprintDetectionRunning) {
- mFingerprintDetectionRunning = running;
+ private void handleFingerprintLockoutReset() {
+ updateFingerprintListeningState();
+ }
+
+ private void setFingerprintRunningState(int fingerprintRunningState) {
+ boolean wasRunning = mFingerprintRunningState == FINGERPRINT_STATE_RUNNING;
+ boolean isRunning = fingerprintRunningState == FINGERPRINT_STATE_RUNNING;
+ mFingerprintRunningState = fingerprintRunningState;
+
+ // Clients of KeyguardUpdateMonitor don't care about the internal state about the
+ // asynchronousness of the cancel cycle. So only notify them if the actualy running state
+ // has changed.
+ if (wasRunning != isRunning) {
notifyFingerprintRunningStateChanged();
}
}
@@ -482,7 +500,7 @@
for (int i = 0; i < mCallbacks.size(); i++) {
KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
if (cb != null) {
- cb.onFingerprintRunningStateChanged(mFingerprintDetectionRunning);
+ cb.onFingerprintRunningStateChanged(isFingerprintDetectionRunning());
}
}
}
@@ -501,7 +519,7 @@
}
public boolean isFingerprintDetectionRunning() {
- return mFingerprintDetectionRunning;
+ return mFingerprintRunningState == FINGERPRINT_STATE_RUNNING;
}
private boolean isTrustDisabled(int userId) {
@@ -516,7 +534,8 @@
final DevicePolicyManager dpm =
(DevicePolicyManager) mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
return dpm != null && (dpm.getKeyguardDisabledFeatures(null, userId)
- & DevicePolicyManager.KEYGUARD_DISABLE_FINGERPRINT) != 0;
+ & DevicePolicyManager.KEYGUARD_DISABLE_FINGERPRINT) != 0
+ || isSimPinSecure();
}
public boolean getUserCanSkipBouncer(int userId) {
@@ -533,7 +552,48 @@
}
public boolean isUnlockingWithFingerprintAllowed() {
- return mUserHasAuthenticatedSinceBoot;
+ return mStrongAuthTracker.isUnlockingWithFingerprintAllowed()
+ && !hasFingerprintUnlockTimedOut(sCurrentUser);
+ }
+
+ public StrongAuthTracker getStrongAuthTracker() {
+ return mStrongAuthTracker;
+ }
+
+ /**
+ * @return true if the user hasn't use strong authentication (pattern, PIN, password) since a
+ * while and thus can't unlock with fingerprint, false otherwise
+ */
+ public boolean hasFingerprintUnlockTimedOut(int userId) {
+ return !mStrongAuthNotTimedOut.contains(userId);
+ }
+
+ public void reportSuccessfulStrongAuthUnlockAttempt() {
+ mStrongAuthNotTimedOut.add(sCurrentUser);
+ scheduleStrongAuthTimeout();
+ if (mFpm != null) {
+ byte[] token = null; /* TODO: pass real auth token once fp HAL supports it */
+ mFpm.resetTimeout(token);
+ }
+ }
+
+ private void scheduleStrongAuthTimeout() {
+ long when = SystemClock.elapsedRealtime() + FINGERPRINT_UNLOCK_TIMEOUT_MS;
+ Intent intent = new Intent(ACTION_STRONG_AUTH_TIMEOUT);
+ intent.putExtra(USER_ID, sCurrentUser);
+ PendingIntent sender = PendingIntent.getBroadcast(mContext,
+ sCurrentUser, intent, PendingIntent.FLAG_CANCEL_CURRENT);
+ mAlarmManager.set(AlarmManager.ELAPSED_REALTIME, when, sender);
+ notifyStrongAuthStateChanged(sCurrentUser);
+ }
+
+ private void notifyStrongAuthStateChanged(int userId) {
+ for (int i = 0; i < mCallbacks.size(); i++) {
+ KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
+ if (cb != null) {
+ cb.onStrongAuthStateChanged(userId);
+ }
+ }
}
static class DisplayClientState {
@@ -561,8 +621,10 @@
final int plugged = intent.getIntExtra(EXTRA_PLUGGED, 0);
final int level = intent.getIntExtra(EXTRA_LEVEL, 0);
final int health = intent.getIntExtra(EXTRA_HEALTH, BATTERY_HEALTH_UNKNOWN);
+ final int maxChargingCurrent = intent.getIntExtra(EXTRA_MAX_CHARGING_CURRENT, -1);
final Message msg = mHandler.obtainMessage(
- MSG_BATTERY_UPDATE, new BatteryStatus(status, level, plugged, health));
+ MSG_BATTERY_UPDATE, new BatteryStatus(status, level, plugged, health,
+ maxChargingCurrent));
mHandler.sendMessage(msg);
} else if (TelephonyIntents.ACTION_SIM_STATE_CHANGED.equals(action)) {
SimData args = SimData.fromIntent(intent);
@@ -619,6 +681,25 @@
}
};
+ private final BroadcastReceiver mStrongAuthTimeoutReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ if (ACTION_STRONG_AUTH_TIMEOUT.equals(intent.getAction())) {
+ int userId = intent.getIntExtra(USER_ID, -1);
+ mStrongAuthNotTimedOut.remove(userId);
+ notifyStrongAuthStateChanged(userId);
+ }
+ }
+ };
+
+ private final FingerprintManager.LockoutResetCallback mLockoutResetCallback
+ = new FingerprintManager.LockoutResetCallback() {
+ @Override
+ public void onLockoutReset() {
+ handleFingerprintLockoutReset();
+ }
+ };
+
private FingerprintManager.AuthenticationCallback mAuthenticationCallback
= new AuthenticationCallback() {
@@ -629,7 +710,7 @@
@Override
public void onAuthenticationSucceeded(AuthenticationResult result) {
- handleFingerprintAuthenticated();
+ handleFingerprintAuthenticated(result.getUserId());
}
@Override
@@ -649,7 +730,6 @@
};
private CancellationSignal mFingerprintCancelSignal;
private FingerprintManager mFpm;
- private PowerManager.WakeLock mWakeLock;
/**
* When we receive a
@@ -719,15 +799,22 @@
}
public static class BatteryStatus {
+ public static final int CHARGING_UNKNOWN = -1;
+ public static final int CHARGING_SLOWLY = 0;
+ public static final int CHARGING_REGULAR = 1;
+ public static final int CHARGING_FAST = 2;
+
public final int status;
public final int level;
public final int plugged;
public final int health;
- public BatteryStatus(int status, int level, int plugged, int health) {
+ public final int maxChargingCurrent;
+ public BatteryStatus(int status, int level, int plugged, int health, int maxChargingCurrent) {
this.status = status;
this.level = level;
this.plugged = plugged;
this.health = health;
+ this.maxChargingCurrent = maxChargingCurrent;
}
/**
@@ -758,6 +845,31 @@
return level < LOW_BATTERY_THRESHOLD;
}
+ public final int getChargingSpeed(int slowThreshold, int fastThreshold) {
+ return maxChargingCurrent <= 0 ? CHARGING_UNKNOWN :
+ maxChargingCurrent < slowThreshold ? CHARGING_SLOWLY :
+ maxChargingCurrent > fastThreshold ? CHARGING_FAST :
+ CHARGING_REGULAR;
+ }
+ }
+
+ public class StrongAuthTracker extends LockPatternUtils.StrongAuthTracker {
+
+ public boolean isUnlockingWithFingerprintAllowed() {
+ int userId = getCurrentUser();
+ return isFingerprintAllowedForUser(userId);
+ }
+
+ public boolean hasUserAuthenticatedSinceBoot() {
+ int userId = getCurrentUser();
+ return (getStrongAuthForUser(userId)
+ & STRONG_AUTH_REQUIRED_AFTER_BOOT) == 0;
+ }
+
+ @Override
+ public void onStrongAuthRequiredChanged(int userId) {
+ notifyStrongAuthStateChanged(userId);
+ }
}
public static KeyguardUpdateMonitor getInstance(Context context) {
@@ -778,18 +890,52 @@
}
}
- protected void handleFinishedGoingToSleep(int arg1) {
+ protected void handleStartedGoingToSleep(int arg1) {
clearFingerprintRecognized();
final int count = mCallbacks.size();
for (int i = 0; i < count; i++) {
KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
if (cb != null) {
+ cb.onStartedGoingToSleep(arg1);
+ }
+ }
+ mGoingToSleep = true;
+ mFingerprintAlreadyAuthenticated = false;
+ updateFingerprintListeningState();
+ }
+
+ protected void handleFinishedGoingToSleep(int arg1) {
+ mGoingToSleep = false;
+ final int count = mCallbacks.size();
+ for (int i = 0; i < count; i++) {
+ KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
+ if (cb != null) {
cb.onFinishedGoingToSleep(arg1);
}
}
updateFingerprintListeningState();
}
+ private void handleScreenTurnedOn() {
+ final int count = mCallbacks.size();
+ for (int i = 0; i < count; i++) {
+ KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
+ if (cb != null) {
+ cb.onScreenTurnedOn();
+ }
+ }
+ }
+
+ private void handleScreenTurnedOff() {
+ final int count = mCallbacks.size();
+ for (int i = 0; i < count; i++) {
+ KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
+ if (cb != null) {
+ cb.onScreenTurnedOff();
+ }
+ }
+ }
+
/**
* IMPORTANT: Must be called from UI thread.
*/
@@ -816,8 +962,9 @@
private KeyguardUpdateMonitor(Context context) {
mContext = context;
mSubscriptionManager = SubscriptionManager.from(context);
- mPowerManager = context.getSystemService(PowerManager.class);
+ mAlarmManager = context.getSystemService(AlarmManager.class);
mDeviceProvisioned = isDeviceProvisionedInSettingsDb();
+
// Since device can't be un-provisioned, we only need to register a content observer
// to update mDeviceProvisioned when we are...
if (!mDeviceProvisioned) {
@@ -825,7 +972,7 @@
}
// Take a guess at initial SIM state, battery status and PLMN until we get an update
- mBatteryStatus = new BatteryStatus(BATTERY_STATUS_UNKNOWN, 100, 0, 0);
+ mBatteryStatus = new BatteryStatus(BATTERY_STATUS_UNKNOWN, 100, 0, 0, 0);
// Watch for interesting updates
final IntentFilter filter = new IntentFilter();
@@ -878,53 +1025,69 @@
e.printStackTrace();
}
+ IntentFilter strongAuthTimeoutFilter = new IntentFilter();
+ strongAuthTimeoutFilter.addAction(ACTION_STRONG_AUTH_TIMEOUT);
+ context.registerReceiver(mStrongAuthTimeoutReceiver, strongAuthTimeoutFilter,
+ PERMISSION_SELF, null /* handler */);
mTrustManager = (TrustManager) context.getSystemService(Context.TRUST_SERVICE);
mTrustManager.registerTrustListener(this);
+ new LockPatternUtils(context).registerStrongAuthTracker(mStrongAuthTracker);
mFpm = (FingerprintManager) context.getSystemService(Context.FINGERPRINT_SERVICE);
updateFingerprintListeningState();
+ if (mFpm != null) {
+ mFpm.addLockoutResetCallback(mLockoutResetCallback);
+ }
}
private void updateFingerprintListeningState() {
boolean shouldListenForFingerprint = shouldListenForFingerprint();
- if (mFingerprintDetectionRunning && !shouldListenForFingerprint) {
+ if (mFingerprintRunningState == FINGERPRINT_STATE_RUNNING && !shouldListenForFingerprint) {
stopListeningForFingerprint();
- } else if (!mFingerprintDetectionRunning && shouldListenForFingerprint) {
+ } else if (mFingerprintRunningState != FINGERPRINT_STATE_RUNNING
+ && shouldListenForFingerprint) {
startListeningForFingerprint();
}
}
private boolean shouldListenForFingerprint() {
- return mKeyguardIsVisible && !mSwitchingUser;
+ return (mKeyguardIsVisible || !mDeviceInteractive || mBouncer || mGoingToSleep)
+ && !mSwitchingUser && !mFingerprintAlreadyAuthenticated
+ && !isFingerprintDisabled(getCurrentUser());
}
private void startListeningForFingerprint() {
+ if (mFingerprintRunningState == FINGERPRINT_STATE_CANCELLING) {
+ setFingerprintRunningState(FINGERPRINT_STATE_CANCELLING_RESTARTING);
+ return;
+ }
if (DEBUG) Log.v(TAG, "startListeningForFingerprint()");
int userId = ActivityManager.getCurrentUser();
- if (isUnlockWithFingerPrintPossible(userId)) {
- mUserHasAuthenticatedSinceBoot = mTrustManager.hasUserAuthenticatedSinceBoot(
- ActivityManager.getCurrentUser());
+ if (isUnlockWithFingerprintPossible(userId)) {
if (mFingerprintCancelSignal != null) {
mFingerprintCancelSignal.cancel();
}
mFingerprintCancelSignal = new CancellationSignal();
mFpm.authenticate(null, mFingerprintCancelSignal, 0, mAuthenticationCallback, null, userId);
- setFingerprintRunningDetectionRunning(true);
+ setFingerprintRunningState(FINGERPRINT_STATE_RUNNING);
}
}
- public boolean isUnlockWithFingerPrintPossible(int userId) {
+ public boolean isUnlockWithFingerprintPossible(int userId) {
return mFpm != null && mFpm.isHardwareDetected() && !isFingerprintDisabled(userId)
&& mFpm.getEnrolledFingerprints(userId).size() > 0;
}
private void stopListeningForFingerprint() {
if (DEBUG) Log.v(TAG, "stopListeningForFingerprint()");
- if (isFingerprintDetectionRunning()) {
+ if (mFingerprintRunningState == FINGERPRINT_STATE_RUNNING) {
mFingerprintCancelSignal.cancel();
mFingerprintCancelSignal = null;
+ setFingerprintRunningState(FINGERPRINT_STATE_CANCELLING);
}
- setFingerprintRunningDetectionRunning(false);
+ if (mFingerprintRunningState == FINGERPRINT_STATE_CANCELLING_RESTARTING) {
+ setFingerprintRunningState(FINGERPRINT_STATE_CANCELLING);
+ }
}
private boolean isDeviceProvisionedInSettingsDb() {
@@ -964,6 +1127,7 @@
* Handle {@link #MSG_DPM_STATE_CHANGED}
*/
protected void handleDevicePolicyManagerStateChanged() {
+ updateFingerprintListeningState();
for (int i = mCallbacks.size() - 1; i >= 0; i--) {
KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
if (cb != null) {
@@ -1181,18 +1345,22 @@
}
/**
- * Handle {@link #MSG_KEYGUARD_VISIBILITY_CHANGED}
+ * Notifies that the visibility state of Keyguard has changed.
+ *
+ * <p>Needs to be called from the main thread.
*/
- private void handleKeyguardVisibilityChanged(int showing) {
- if (DEBUG) Log.d(TAG, "handleKeyguardVisibilityChanged(" + showing + ")");
- boolean isShowing = (showing == 1);
- mKeyguardIsVisible = isShowing;
+ public void onKeyguardVisibilityChanged(boolean showing) {
+ if (DEBUG) Log.d(TAG, "onKeyguardVisibilityChanged(" + showing + ")");
+ mKeyguardIsVisible = showing;
for (int i = 0; i < mCallbacks.size(); i++) {
KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
if (cb != null) {
- cb.onKeyguardVisibilityChangedRaw(isShowing);
+ cb.onKeyguardVisibilityChangedRaw(showing);
}
}
+ if (!showing) {
+ mFingerprintAlreadyAuthenticated = false;
+ }
updateFingerprintListeningState();
}
@@ -1201,9 +1369,7 @@
*/
private void handleKeyguardReset() {
if (DEBUG) Log.d(TAG, "handleKeyguardReset");
- if (!isUnlockingWithFingerprintAllowed()) {
- updateFingerprintListeningState();
- }
+ updateFingerprintListeningState();
}
/**
@@ -1220,6 +1386,7 @@
cb.onKeyguardBouncerChanged(isBouncer);
}
}
+ updateFingerprintListeningState();
}
/**
@@ -1255,6 +1422,12 @@
if (!nowPluggedIn && current.isBatteryLow() && current.level != old.level) {
return true;
}
+
+ // change in charging current while plugged in
+ if (nowPluggedIn && current.maxChargingCurrent != old.maxChargingCurrent) {
+ return true;
+ }
+
return false;
}
@@ -1306,13 +1479,6 @@
}
}
- public void sendKeyguardVisibilityChanged(boolean showing) {
- if (DEBUG) Log.d(TAG, "sendKeyguardVisibilityChanged(" + showing + ")");
- Message message = mHandler.obtainMessage(MSG_KEYGUARD_VISIBILITY_CHANGED);
- message.arg1 = showing ? 1 : 0;
- message.sendToTarget();
- }
-
public void sendKeyguardReset() {
mHandler.obtainMessage(MSG_KEYGUARD_RESET).sendToTarget();
}
@@ -1373,7 +1539,7 @@
return mFailedAttempts.get(sCurrentUser, 0);
}
- public void reportFailedUnlockAttempt() {
+ public void reportFailedStrongAuthUnlockAttempt() {
mFailedAttempts.put(sCurrentUser, getFailedUnlockAttempts() + 1);
}
@@ -1453,6 +1619,10 @@
mHandler.sendEmptyMessage(MSG_STARTED_WAKING_UP);
}
+ public void dispatchStartedGoingToSleep(int why) {
+ mHandler.sendMessage(mHandler.obtainMessage(MSG_STARTED_GOING_TO_SLEEP, why, 0));
+ }
+
public void dispatchFinishedGoingToSleep(int why) {
synchronized(this) {
mDeviceInteractive = false;
@@ -1464,18 +1634,24 @@
synchronized (this) {
mScreenOn = true;
}
+ mHandler.sendEmptyMessage(MSG_SCREEN_TURNED_ON);
}
public void dispatchScreenTurnedOff() {
synchronized(this) {
mScreenOn = false;
}
+ mHandler.sendEmptyMessage(MSG_SCREEN_TURNED_OFF);
}
public boolean isDeviceInteractive() {
return mDeviceInteractive;
}
+ public boolean isGoingToSleep() {
+ return mGoingToSleep;
+ }
+
/**
* Find the next SubscriptionId for a SIM in the given state, favoring lower slot numbers first.
* @param state
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitorCallback.java b/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitorCallback.java
index 0cdf999..bd6c51c 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitorCallback.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitorCallback.java
@@ -153,6 +153,12 @@
public void onStartedWakingUp() { }
/**
+ * Called when the device has started going to sleep.
+ * @param why see {@link #onFinishedGoingToSleep(int)}
+ */
+ public void onStartedGoingToSleep(int why) { }
+
+ /**
* Called when the device has finished going to sleep.
* @param why either {@link WindowManagerPolicy#OFF_BECAUSE_OF_ADMIN},
* {@link WindowManagerPolicy#OFF_BECAUSE_OF_USER}, or
@@ -161,6 +167,16 @@
public void onFinishedGoingToSleep(int why) { }
/**
+ * Called when the screen has been turned on.
+ */
+ public void onScreenTurnedOn() { }
+
+ /**
+ * Called when the screen has been turned off.
+ */
+ public void onScreenTurnedOff() { }
+
+ /**
* Called when trust changes for a user.
*/
public void onTrustChanged(int userId) { }
@@ -176,12 +192,23 @@
public void onTrustGrantedWithFlags(int flags, int userId) { }
/**
+ * Called when a finger has been acquired.
+ * <p>
+ * It is guaranteed that either {@link #onFingerprintAuthenticated} or
+ * {@link #onFingerprintAuthFailed()} is called after this method eventually.
+ */
+ public void onFingerprintAcquired() { }
+
+ /**
+ * Called when a fingerprint couldn't be authenticated.
+ */
+ public void onFingerprintAuthFailed() { }
+
+ /**
* Called when a fingerprint is recognized.
* @param userId the user id for which the fingerprint was authenticated
- * @param wakeAndUnlocking whether the authentication woke the device up and thus we'd like to
- * dismiss the lockscreen before turning on the screen
*/
- public void onFingerprintAuthenticated(int userId, boolean wakeAndUnlocking) { }
+ public void onFingerprintAuthenticated(int userId) { }
/**
* Called when fingerprint provides help string (e.g. "Try again")
@@ -207,4 +234,10 @@
* Called when the fingerprint running state changed.
*/
public void onFingerprintRunningStateChanged(boolean running) { }
+
+ /**
+ * Called when the state that the user hasn't used strong authentication since quite some time
+ * has changed.
+ */
+ public void onStrongAuthStateChanged(int userId) { }
}
diff --git a/packages/Keyguard/src/com/android/keyguard/SecurityMessageDisplay.java b/packages/Keyguard/src/com/android/keyguard/SecurityMessageDisplay.java
index b38cfd5..ddb1f6e 100644
--- a/packages/Keyguard/src/com/android/keyguard/SecurityMessageDisplay.java
+++ b/packages/Keyguard/src/com/android/keyguard/SecurityMessageDisplay.java
@@ -17,11 +17,14 @@
package com.android.keyguard;
public interface SecurityMessageDisplay {
- public void setMessage(CharSequence msg, boolean important);
- public void setMessage(int resId, boolean important);
+ void setNextMessageColor(int color);
- public void setMessage(int resId, boolean important, Object... formatArgs);
+ void setMessage(CharSequence msg, boolean important);
- public void setTimeout(int timeout_ms);
+ void setMessage(int resId, boolean important);
+
+ void setMessage(int resId, boolean important, Object... formatArgs);
+
+ void setTimeout(int timeout_ms);
}
diff --git a/packages/Keyguard/src/com/android/keyguard/ViewMediatorCallback.java b/packages/Keyguard/src/com/android/keyguard/ViewMediatorCallback.java
index ff463c6..8ab3011 100644
--- a/packages/Keyguard/src/com/android/keyguard/ViewMediatorCallback.java
+++ b/packages/Keyguard/src/com/android/keyguard/ViewMediatorCallback.java
@@ -28,12 +28,11 @@
/**
* Report that the keyguard is done.
- * @param authenticated Whether the user securely got past the keyguard.
- * the only reason for this to be false is if the keyguard was instructed
- * to appear temporarily to verify the user is supposed to get past the
- * keyguard, and the user fails to do so.
+ *
+ * @param strongAuth whether the user has authenticated with strong authentication like
+ * pattern, password or PIN but not by trust agents or fingerprint
*/
- void keyguardDone(boolean authenticated);
+ void keyguardDone(boolean strongAuth);
/**
* Report that the keyguard is done drawing.
@@ -48,8 +47,11 @@
/**
* Report that the keyguard is dismissable, pending the next keyguardDone call.
+ *
+ * @param strongAuth whether the user has authenticated with strong authentication like
+ * pattern, password or PIN but not by trust agents or fingerprint
*/
- void keyguardDonePending();
+ void keyguardDonePending(boolean strongAuth);
/**
* Report when keyguard is actually gone
@@ -85,8 +87,9 @@
/**
* @return one of the reasons why the bouncer needs to be shown right now and the user can't use
* his normal unlock method like fingerprint or trust agents. See
- * {@link KeyguardSecurityView#PROMPT_REASON_NONE}
- * and {@link KeyguardSecurityView#PROMPT_REASON_RESTART}.
+ * {@link KeyguardSecurityView#PROMPT_REASON_NONE},
+ * {@link KeyguardSecurityView#PROMPT_REASON_RESTART} and
+ * {@link KeyguardSecurityView#PROMPT_REASON_TIMEOUT}.
*/
int getBouncerPromptReason();
}
diff --git a/packages/PrintSpooler/res/values-eu-rES/strings.xml b/packages/PrintSpooler/res/values-eu-rES/strings.xml
index 58dfc2a..461a92f 100644
--- a/packages/PrintSpooler/res/values-eu-rES/strings.xml
+++ b/packages/PrintSpooler/res/values-eu-rES/strings.xml
@@ -30,7 +30,7 @@
<string name="template_all_pages" msgid="3322235982020148762">"<xliff:g id="PAGE_COUNT">%1$s</xliff:g> orriak"</string>
<string name="template_page_range" msgid="428638530038286328">"<xliff:g id="PAGE_COUNT">%1$s</xliff:g> orriko tartea"</string>
<string name="pages_range_example" msgid="8558694453556945172">"adib., 1-5, 8,11-13"</string>
- <string name="print_preview" msgid="8010217796057763343">"Inprimatzearen aurrebista"</string>
+ <string name="print_preview" msgid="8010217796057763343">"Inprimatze-aurrebista"</string>
<string name="install_for_print_preview" msgid="6366303997385509332">"Aurrebista ikusteko, instalatu PDF ikustailea"</string>
<string name="printing_app_crashed" msgid="854477616686566398">"Inprimatzeko aplikazioak matxura izan du"</string>
<string name="generating_print_job" msgid="3119608742651698916">"Inprimatze-lana sortzen"</string>
diff --git a/packages/PrintSpooler/res/values-ja/strings.xml b/packages/PrintSpooler/res/values-ja/strings.xml
index 6029425..8ef7517 100644
--- a/packages/PrintSpooler/res/values-ja/strings.xml
+++ b/packages/PrintSpooler/res/values-ja/strings.xml
@@ -53,7 +53,7 @@
<string name="print_search_box_hidden_utterance" msgid="5727755169343113351">"検索ボックスは表示されていません"</string>
<string name="print_add_printer" msgid="1088656468360653455">"プリンタを追加"</string>
<string name="print_select_printer" msgid="7388760939873368698">"プリンタを選択"</string>
- <string name="print_forget_printer" msgid="5035287497291910766">"プリンタを切断"</string>
+ <string name="print_forget_printer" msgid="5035287497291910766">"プリンタを削除"</string>
<plurals name="print_search_result_count_utterance" formatted="false" msgid="6997663738361080868">
<item quantity="other"><xliff:g id="COUNT_1">%1$s</xliff:g>台のプリンタが見つかりました</item>
<item quantity="one"><xliff:g id="COUNT_0">%1$s</xliff:g>台のプリンタが見つかりました</item>
diff --git a/packages/PrintSpooler/res/values-pt-rBR/strings.xml b/packages/PrintSpooler/res/values-pt-rBR/strings.xml
new file mode 100644
index 0000000..9e38506
--- /dev/null
+++ b/packages/PrintSpooler/res/values-pt-rBR/strings.xml
@@ -0,0 +1,95 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2013 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_label" msgid="4469836075319831821">"Sp. de impressão"</string>
+ <string name="more_options_button" msgid="2243228396432556771">"Mais opções"</string>
+ <string name="label_destination" msgid="9132510997381599275">"Destino"</string>
+ <string name="label_copies" msgid="3634531042822968308">"Cópias"</string>
+ <string name="label_copies_summary" msgid="3861966063536529540">"Cópias:"</string>
+ <string name="label_paper_size" msgid="908654383827777759">"Tamanho do papel"</string>
+ <string name="label_paper_size_summary" msgid="5668204981332138168">"Tamanho do papel:"</string>
+ <string name="label_color" msgid="1108690305218188969">"Cor"</string>
+ <string name="label_duplex" msgid="5370037254347072243">"Dois lados"</string>
+ <string name="label_orientation" msgid="2853142581990496477">"Orientação"</string>
+ <string name="label_pages" msgid="7768589729282182230">"Páginas"</string>
+ <string name="template_all_pages" msgid="3322235982020148762">"Todas as <xliff:g id="PAGE_COUNT">%1$s</xliff:g>"</string>
+ <string name="template_page_range" msgid="428638530038286328">"Intervalo de <xliff:g id="PAGE_COUNT">%1$s</xliff:g>"</string>
+ <string name="pages_range_example" msgid="8558694453556945172">"Ex.: 1–5, 8, 11–13"</string>
+ <string name="print_preview" msgid="8010217796057763343">"Visualização de impressão"</string>
+ <string name="install_for_print_preview" msgid="6366303997385509332">"Instalar o visualizador de PDF"</string>
+ <string name="printing_app_crashed" msgid="854477616686566398">"O app de impressão falhou"</string>
+ <string name="generating_print_job" msgid="3119608742651698916">"Gerando trabalho de impressão"</string>
+ <string name="save_as_pdf" msgid="5718454119847596853">"Salvar como PDF"</string>
+ <string name="all_printers" msgid="5018829726861876202">"Todas as impressoras…"</string>
+ <string name="print_dialog" msgid="32628687461331979">"Diálogo de impressão"</string>
+ <string name="current_page_template" msgid="1386638343571771292">"<xliff:g id="CURRENT_PAGE">%1$d</xliff:g> /<xliff:g id="PAGE_COUNT">%2$d</xliff:g>"</string>
+ <string name="page_description_template" msgid="6831239682256197161">"Página <xliff:g id="CURRENT_PAGE">%1$d</xliff:g> de <xliff:g id="PAGE_COUNT">%2$d</xliff:g>"</string>
+ <string name="summary_template" msgid="8899734908625669193">"Resumo, cópias <xliff:g id="COPIES">%1$s</xliff:g>, tamanho do papel <xliff:g id="PAPER_SIZE">%2$s</xliff:g>"</string>
+ <string name="expand_handle" msgid="7282974448109280522">"Expandir alça"</string>
+ <string name="collapse_handle" msgid="6886637989442507451">"Recolher alça"</string>
+ <string name="print_button" msgid="645164566271246268">"Imprimir"</string>
+ <string name="savetopdf_button" msgid="2976186791686924743">"Salvar como PDF"</string>
+ <string name="print_options_expanded" msgid="6944679157471691859">"Opções de impressão expandidas"</string>
+ <string name="print_options_collapsed" msgid="7455930445670414332">"Opções de impressão recolhidas"</string>
+ <string name="search" msgid="5421724265322228497">"Pesquisar"</string>
+ <string name="all_printers_label" msgid="3178848870161526399">"Todas as impressoras"</string>
+ <string name="add_print_service_label" msgid="5356702546188981940">"Adicionar serviço"</string>
+ <string name="print_search_box_shown_utterance" msgid="7967404953901376090">"Caixa de pesquisa exibida"</string>
+ <string name="print_search_box_hidden_utterance" msgid="5727755169343113351">"Caixa de pesquisa oculta"</string>
+ <string name="print_add_printer" msgid="1088656468360653455">"Adicionar impressora"</string>
+ <string name="print_select_printer" msgid="7388760939873368698">"Selecionar impressora"</string>
+ <string name="print_forget_printer" msgid="5035287497291910766">"Esquecer impressora"</string>
+ <plurals name="print_search_result_count_utterance" formatted="false" msgid="6997663738361080868">
+ <item quantity="one"><xliff:g id="COUNT_1">%1$s</xliff:g> impressoras encontradas</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%1$s</xliff:g> impressoras encontradas</item>
+ </plurals>
+ <string name="choose_print_service" msgid="3740309762324459694">"Selecione o serviço de impressão"</string>
+ <string name="print_searching_for_printers" msgid="6550424555079932867">"Procurando impressoras"</string>
+ <string name="print_no_printers" msgid="4869403323900054866">"Nenhuma impressora encontrada"</string>
+ <string name="printing_notification_title_template" msgid="295903957762447362">"Imprimindo <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
+ <string name="cancelling_notification_title_template" msgid="1821759594704703197">"Cancelando <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
+ <string name="failed_notification_title_template" msgid="2256217208186530973">"Erro ao imprimir <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
+ <string name="blocked_notification_title_template" msgid="1175435827331588646">"A impressora bloqueou <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
+ <plurals name="composite_notification_title_template" formatted="false" msgid="6940956968211733780">
+ <item quantity="one">Tarefas de impressão <xliff:g id="PRINT_JOB_NAME_1">%1$d</xliff:g></item>
+ <item quantity="other">Tarefas de impressão <xliff:g id="PRINT_JOB_NAME_1">%1$d</xliff:g></item>
+ </plurals>
+ <string name="cancel" msgid="4373674107267141885">"Cancelar"</string>
+ <string name="restart" msgid="2472034227037808749">"Reiniciar"</string>
+ <string name="no_connection_to_printer" msgid="2159246915977282728">"Sem conexão com a impressora"</string>
+ <string name="reason_unknown" msgid="5507940196503246139">"desconhecido"</string>
+ <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – não disponível"</string>
+ <string-array name="color_mode_labels">
+ <item msgid="7602948745415174937">"Preto e branco"</item>
+ <item msgid="2762241247228983754">"Cor"</item>
+ </string-array>
+ <string-array name="duplex_mode_labels">
+ <item msgid="3882302912790928315">"Nenhum"</item>
+ <item msgid="7296563835355641719">"Borda longa"</item>
+ <item msgid="79513688117503758">"Borda curta"</item>
+ </string-array>
+ <string-array name="orientation_labels">
+ <item msgid="4061931020926489228">"Retrato"</item>
+ <item msgid="3199660090246166812">"Paisagem"</item>
+ </string-array>
+ <string name="print_write_error_message" msgid="5787642615179572543">"Não foi possível gravar no arquivo"</string>
+ <string name="print_error_default_message" msgid="8602678405502922346">"Falhou. Tente novamente."</string>
+ <string name="print_error_retry" msgid="1426421728784259538">"Tentar novamente"</string>
+ <string name="print_error_printer_unavailable" msgid="8985614415253203381">"Esta impressora não está disponível no momento."</string>
+ <string name="print_preparing_preview" msgid="3939930735671364712">"Preparando visualização…"</string>
+</resources>
diff --git a/packages/PrintSpooler/res/values-uz-rUZ/strings.xml b/packages/PrintSpooler/res/values-uz-rUZ/strings.xml
index 8e41a34..f88eca5 100644
--- a/packages/PrintSpooler/res/values-uz-rUZ/strings.xml
+++ b/packages/PrintSpooler/res/values-uz-rUZ/strings.xml
@@ -46,7 +46,7 @@
<string name="savetopdf_button" msgid="2976186791686924743">"PDF sifatida saqlash"</string>
<string name="print_options_expanded" msgid="6944679157471691859">"Chop qilish tanlamalari yoyildi"</string>
<string name="print_options_collapsed" msgid="7455930445670414332">"Chop qilish tanlamalari yig‘ildi"</string>
- <string name="search" msgid="5421724265322228497">"Izlash"</string>
+ <string name="search" msgid="5421724265322228497">"Qidirish"</string>
<string name="all_printers_label" msgid="3178848870161526399">"Barcha printerlar"</string>
<string name="add_print_service_label" msgid="5356702546188981940">"Xizmat qo‘shish"</string>
<string name="print_search_box_shown_utterance" msgid="7967404953901376090">"Izlash oynasi ko‘rsatildi"</string>
diff --git a/packages/SettingsLib/res/values-af/strings.xml b/packages/SettingsLib/res/values-af/strings.xml
index da7e3d3..a4cbcd2 100644
--- a/packages/SettingsLib/res/values-af/strings.xml
+++ b/packages/SettingsLib/res/values-af/strings.xml
@@ -77,16 +77,10 @@
<string name="bluetooth_pairing_pin_error_message" msgid="8337234855188925274">"Kon nie met <xliff:g id="DEVICE_NAME">%1$s</xliff:g> saambind nie weens \'n verkeerde PIN of wagwoordsleutel."</string>
<string name="bluetooth_pairing_device_down_error_message" msgid="7870998403045801381">"Kan nie met <xliff:g id="DEVICE_NAME">%1$s</xliff:g> kommunikeer nie."</string>
<string name="bluetooth_pairing_rejected_error_message" msgid="1648157108520832454">"Saambinding verwerp deur <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
- <!-- no translation found for accessibility_wifi_off (1166761729660614716) -->
- <skip />
- <!-- no translation found for accessibility_no_wifi (8834610636137374508) -->
- <skip />
- <!-- no translation found for accessibility_wifi_one_bar (4869376278894301820) -->
- <skip />
- <!-- no translation found for accessibility_wifi_two_bars (3569851234710034416) -->
- <skip />
- <!-- no translation found for accessibility_wifi_three_bars (8134185644861380311) -->
- <skip />
- <!-- no translation found for accessibility_wifi_signal_full (7061045677694702) -->
- <skip />
+ <string name="accessibility_wifi_off" msgid="1166761729660614716">"Wi-Fi af."</string>
+ <string name="accessibility_no_wifi" msgid="8834610636137374508">"Wi-Fi is ontkoppel."</string>
+ <string name="accessibility_wifi_one_bar" msgid="4869376278894301820">"Wi-Fi een staaf."</string>
+ <string name="accessibility_wifi_two_bars" msgid="3569851234710034416">"Wi-Fi twee stawe."</string>
+ <string name="accessibility_wifi_three_bars" msgid="8134185644861380311">"Wi-Fi drie stawe."</string>
+ <string name="accessibility_wifi_signal_full" msgid="7061045677694702">"Wi-Fi-sein vol."</string>
</resources>
diff --git a/packages/SettingsLib/res/values-am/strings.xml b/packages/SettingsLib/res/values-am/strings.xml
index 77bd2f1..67ab51d 100644
--- a/packages/SettingsLib/res/values-am/strings.xml
+++ b/packages/SettingsLib/res/values-am/strings.xml
@@ -77,16 +77,10 @@
<string name="bluetooth_pairing_pin_error_message" msgid="8337234855188925274">"ከ <xliff:g id="DEVICE_NAME">%1$s</xliff:g> ጋር ትክክለኛ ባልሆነ ፒን ወይም የይለፍቁልፍ ምክንያት ማጣመር አልተቻለም::"</string>
<string name="bluetooth_pairing_device_down_error_message" msgid="7870998403045801381">"ከ<xliff:g id="DEVICE_NAME">%1$s</xliff:g> ጋር ግንኙነት መመስረት አልተቻለም።"</string>
<string name="bluetooth_pairing_rejected_error_message" msgid="1648157108520832454">"ማጣመር በ<xliff:g id="DEVICE_NAME">%1$s</xliff:g> ተገፍቷል።"</string>
- <!-- no translation found for accessibility_wifi_off (1166761729660614716) -->
- <skip />
- <!-- no translation found for accessibility_no_wifi (8834610636137374508) -->
- <skip />
- <!-- no translation found for accessibility_wifi_one_bar (4869376278894301820) -->
- <skip />
- <!-- no translation found for accessibility_wifi_two_bars (3569851234710034416) -->
- <skip />
- <!-- no translation found for accessibility_wifi_three_bars (8134185644861380311) -->
- <skip />
- <!-- no translation found for accessibility_wifi_signal_full (7061045677694702) -->
- <skip />
+ <string name="accessibility_wifi_off" msgid="1166761729660614716">"Wifi ጠፍቷል።"</string>
+ <string name="accessibility_no_wifi" msgid="8834610636137374508">"የWifi ግንኙነት ተቋርጧል።"</string>
+ <string name="accessibility_wifi_one_bar" msgid="4869376278894301820">"አንድ የWiFi አሞሌ።"</string>
+ <string name="accessibility_wifi_two_bars" msgid="3569851234710034416">"ሁለት የWiFi አሞሌዎች።"</string>
+ <string name="accessibility_wifi_three_bars" msgid="8134185644861380311">"ሦስት የWiFi አሞሌዎች።"</string>
+ <string name="accessibility_wifi_signal_full" msgid="7061045677694702">"የWiFi ምልክት ሙሉ ነው።"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-ar/strings.xml b/packages/SettingsLib/res/values-ar/strings.xml
index 363c9cc..ce7c26b 100644
--- a/packages/SettingsLib/res/values-ar/strings.xml
+++ b/packages/SettingsLib/res/values-ar/strings.xml
@@ -77,16 +77,10 @@
<string name="bluetooth_pairing_pin_error_message" msgid="8337234855188925274">"تعذر الإقران مع <xliff:g id="DEVICE_NAME">%1$s</xliff:g> نظرًا لوجود رقم تعريف شخصي أو مفتاح مرور غير صحيح."</string>
<string name="bluetooth_pairing_device_down_error_message" msgid="7870998403045801381">"لا يمكن الاتصال بـ <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
<string name="bluetooth_pairing_rejected_error_message" msgid="1648157108520832454">"تم رفض الاقتران بواسطة <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
- <!-- no translation found for accessibility_wifi_off (1166761729660614716) -->
- <skip />
- <!-- no translation found for accessibility_no_wifi (8834610636137374508) -->
- <skip />
- <!-- no translation found for accessibility_wifi_one_bar (4869376278894301820) -->
- <skip />
- <!-- no translation found for accessibility_wifi_two_bars (3569851234710034416) -->
- <skip />
- <!-- no translation found for accessibility_wifi_three_bars (8134185644861380311) -->
- <skip />
- <!-- no translation found for accessibility_wifi_signal_full (7061045677694702) -->
- <skip />
+ <string name="accessibility_wifi_off" msgid="1166761729660614716">"تم إيقاف Wi-Fi."</string>
+ <string name="accessibility_no_wifi" msgid="8834610636137374508">"تم قطع اتصال Wi-Fi."</string>
+ <string name="accessibility_wifi_one_bar" msgid="4869376278894301820">"إشارة Wi-Fi تتكون من شريط واحد."</string>
+ <string name="accessibility_wifi_two_bars" msgid="3569851234710034416">"إشارة Wi-Fi تتكون من شريطين."</string>
+ <string name="accessibility_wifi_three_bars" msgid="8134185644861380311">"إشارة Wi-Fi تتكون من ثلاثة أشرطة."</string>
+ <string name="accessibility_wifi_signal_full" msgid="7061045677694702">"إشارة Wi-Fi كاملة."</string>
</resources>
diff --git a/packages/SettingsLib/res/values-az-rAZ/strings.xml b/packages/SettingsLib/res/values-az-rAZ/strings.xml
index f9573c4..f479f6f 100644
--- a/packages/SettingsLib/res/values-az-rAZ/strings.xml
+++ b/packages/SettingsLib/res/values-az-rAZ/strings.xml
@@ -77,16 +77,10 @@
<string name="bluetooth_pairing_pin_error_message" msgid="8337234855188925274">"Yanlış PIN və ya parola görə <xliff:g id="DEVICE_NAME">%1$s</xliff:g> ilə cütləşmək alınmadı."</string>
<string name="bluetooth_pairing_device_down_error_message" msgid="7870998403045801381">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> ilə ünsiyyət qurula bilmir."</string>
<string name="bluetooth_pairing_rejected_error_message" msgid="1648157108520832454">"Cütləşdirmə <xliff:g id="DEVICE_NAME">%1$s</xliff:g> tərəfindən rədd edildi."</string>
- <!-- no translation found for accessibility_wifi_off (1166761729660614716) -->
- <skip />
- <!-- no translation found for accessibility_no_wifi (8834610636137374508) -->
- <skip />
- <!-- no translation found for accessibility_wifi_one_bar (4869376278894301820) -->
- <skip />
- <!-- no translation found for accessibility_wifi_two_bars (3569851234710034416) -->
- <skip />
- <!-- no translation found for accessibility_wifi_three_bars (8134185644861380311) -->
- <skip />
- <!-- no translation found for accessibility_wifi_signal_full (7061045677694702) -->
- <skip />
+ <string name="accessibility_wifi_off" msgid="1166761729660614716">"Wifi sönülüdür."</string>
+ <string name="accessibility_no_wifi" msgid="8834610636137374508">"Wifi bağlantı kəsildi."</string>
+ <string name="accessibility_wifi_one_bar" msgid="4869376278894301820">"Wifi bir xətdir."</string>
+ <string name="accessibility_wifi_two_bars" msgid="3569851234710034416">"Wifi iki xətdir."</string>
+ <string name="accessibility_wifi_three_bars" msgid="8134185644861380311">"Wifi üç xətdir."</string>
+ <string name="accessibility_wifi_signal_full" msgid="7061045677694702">"Wifi siqnalı tamdır."</string>
</resources>
diff --git a/packages/SettingsLib/res/values-bg/strings.xml b/packages/SettingsLib/res/values-bg/strings.xml
index 2c9c0a5..1fc7193 100644
--- a/packages/SettingsLib/res/values-bg/strings.xml
+++ b/packages/SettingsLib/res/values-bg/strings.xml
@@ -77,16 +77,10 @@
<string name="bluetooth_pairing_pin_error_message" msgid="8337234855188925274">"Не можа да се сдвои с/ъс <xliff:g id="DEVICE_NAME">%1$s</xliff:g> поради неправилен ПИН или код за достъп."</string>
<string name="bluetooth_pairing_device_down_error_message" msgid="7870998403045801381">"Не може да се свърже с/ъс <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
<string name="bluetooth_pairing_rejected_error_message" msgid="1648157108520832454">"Сдвояването е отхвърлено от <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
- <!-- no translation found for accessibility_wifi_off (1166761729660614716) -->
- <skip />
- <!-- no translation found for accessibility_no_wifi (8834610636137374508) -->
- <skip />
- <!-- no translation found for accessibility_wifi_one_bar (4869376278894301820) -->
- <skip />
- <!-- no translation found for accessibility_wifi_two_bars (3569851234710034416) -->
- <skip />
- <!-- no translation found for accessibility_wifi_three_bars (8134185644861380311) -->
- <skip />
- <!-- no translation found for accessibility_wifi_signal_full (7061045677694702) -->
- <skip />
+ <string name="accessibility_wifi_off" msgid="1166761729660614716">"Wi-Fi е изключен."</string>
+ <string name="accessibility_no_wifi" msgid="8834610636137374508">"Няма връзка с Wi-Fi."</string>
+ <string name="accessibility_wifi_one_bar" msgid="4869376278894301820">"Wi-Fi е с една чертичка."</string>
+ <string name="accessibility_wifi_two_bars" msgid="3569851234710034416">"Wi-Fi е с две чертички."</string>
+ <string name="accessibility_wifi_three_bars" msgid="8134185644861380311">"Wi-Fi е с три чертички."</string>
+ <string name="accessibility_wifi_signal_full" msgid="7061045677694702">"Сигналът за Wi-Fi е пълен."</string>
</resources>
diff --git a/packages/SettingsLib/res/values-bn-rBD/strings.xml b/packages/SettingsLib/res/values-bn-rBD/strings.xml
index 131d555..bdaecb7 100644
--- a/packages/SettingsLib/res/values-bn-rBD/strings.xml
+++ b/packages/SettingsLib/res/values-bn-rBD/strings.xml
@@ -77,16 +77,10 @@
<string name="bluetooth_pairing_pin_error_message" msgid="8337234855188925274">"ভুল পিন বা পাস কী দেওয়ার কারণে <xliff:g id="DEVICE_NAME">%1$s</xliff:g> এর সঙ্গে যুক্ত করা যায়নি।"</string>
<string name="bluetooth_pairing_device_down_error_message" msgid="7870998403045801381">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> এর সঙ্গে যোগাযোগ করতে পারবেন না।"</string>
<string name="bluetooth_pairing_rejected_error_message" msgid="1648157108520832454">"যুক্ত করা <xliff:g id="DEVICE_NAME">%1$s</xliff:g> প্রত্যাখ্যান করেছে।"</string>
- <!-- no translation found for accessibility_wifi_off (1166761729660614716) -->
- <skip />
- <!-- no translation found for accessibility_no_wifi (8834610636137374508) -->
- <skip />
- <!-- no translation found for accessibility_wifi_one_bar (4869376278894301820) -->
- <skip />
- <!-- no translation found for accessibility_wifi_two_bars (3569851234710034416) -->
- <skip />
- <!-- no translation found for accessibility_wifi_three_bars (8134185644861380311) -->
- <skip />
- <!-- no translation found for accessibility_wifi_signal_full (7061045677694702) -->
- <skip />
+ <string name="accessibility_wifi_off" msgid="1166761729660614716">"Wifi বন্ধ৷"</string>
+ <string name="accessibility_no_wifi" msgid="8834610636137374508">"Wifi এর সংযোগ বিচ্ছিন্ন হয়েছে৷"</string>
+ <string name="accessibility_wifi_one_bar" msgid="4869376278894301820">"Wifi এ একটি দণ্ড৷"</string>
+ <string name="accessibility_wifi_two_bars" msgid="3569851234710034416">"Wifi এ দুইটি দণ্ড৷"</string>
+ <string name="accessibility_wifi_three_bars" msgid="8134185644861380311">"Wifi এ তিনটি দণ্ড৷"</string>
+ <string name="accessibility_wifi_signal_full" msgid="7061045677694702">"Wifi এ সম্পূর্ণ সিগন্যাল৷"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-ca/strings.xml b/packages/SettingsLib/res/values-ca/strings.xml
index d6561a4..b23531c 100644
--- a/packages/SettingsLib/res/values-ca/strings.xml
+++ b/packages/SettingsLib/res/values-ca/strings.xml
@@ -77,16 +77,10 @@
<string name="bluetooth_pairing_pin_error_message" msgid="8337234855188925274">"No s\'ha pogut vincular amb <xliff:g id="DEVICE_NAME">%1$s</xliff:g>, perquè el PIN o la contrasenya són incorrectes."</string>
<string name="bluetooth_pairing_device_down_error_message" msgid="7870998403045801381">"No es pot comunicar amb <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
<string name="bluetooth_pairing_rejected_error_message" msgid="1648157108520832454">"Vinculació rebutjada per <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
- <!-- no translation found for accessibility_wifi_off (1166761729660614716) -->
- <skip />
- <!-- no translation found for accessibility_no_wifi (8834610636137374508) -->
- <skip />
- <!-- no translation found for accessibility_wifi_one_bar (4869376278894301820) -->
- <skip />
- <!-- no translation found for accessibility_wifi_two_bars (3569851234710034416) -->
- <skip />
- <!-- no translation found for accessibility_wifi_three_bars (8134185644861380311) -->
- <skip />
- <!-- no translation found for accessibility_wifi_signal_full (7061045677694702) -->
- <skip />
+ <string name="accessibility_wifi_off" msgid="1166761729660614716">"Wi-Fi desactivada."</string>
+ <string name="accessibility_no_wifi" msgid="8834610636137374508">"Wi-Fi desconnectada."</string>
+ <string name="accessibility_wifi_one_bar" msgid="4869376278894301820">"Senyal Wi-Fi: una barra."</string>
+ <string name="accessibility_wifi_two_bars" msgid="3569851234710034416">"Senyal Wi-Fi: dues barres."</string>
+ <string name="accessibility_wifi_three_bars" msgid="8134185644861380311">"Senyal Wi-Fi: tres barres."</string>
+ <string name="accessibility_wifi_signal_full" msgid="7061045677694702">"Senyal Wi-Fi: complet."</string>
</resources>
diff --git a/packages/SettingsLib/res/values-cs/strings.xml b/packages/SettingsLib/res/values-cs/strings.xml
index 508a1c6..79e28fe 100644
--- a/packages/SettingsLib/res/values-cs/strings.xml
+++ b/packages/SettingsLib/res/values-cs/strings.xml
@@ -77,16 +77,10 @@
<string name="bluetooth_pairing_pin_error_message" msgid="8337234855188925274">"Nelze párovat se zařízením <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. Kód PIN nebo přístupový klíč je nesprávný."</string>
<string name="bluetooth_pairing_device_down_error_message" msgid="7870998403045801381">"Se zařízením <xliff:g id="DEVICE_NAME">%1$s</xliff:g> nelze navázat komunikaci."</string>
<string name="bluetooth_pairing_rejected_error_message" msgid="1648157108520832454">"Párování odmítnuto zařízením <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
- <!-- no translation found for accessibility_wifi_off (1166761729660614716) -->
- <skip />
- <!-- no translation found for accessibility_no_wifi (8834610636137374508) -->
- <skip />
- <!-- no translation found for accessibility_wifi_one_bar (4869376278894301820) -->
- <skip />
- <!-- no translation found for accessibility_wifi_two_bars (3569851234710034416) -->
- <skip />
- <!-- no translation found for accessibility_wifi_three_bars (8134185644861380311) -->
- <skip />
- <!-- no translation found for accessibility_wifi_signal_full (7061045677694702) -->
- <skip />
+ <string name="accessibility_wifi_off" msgid="1166761729660614716">"Síť Wi-Fi je vypnuta."</string>
+ <string name="accessibility_no_wifi" msgid="8834610636137374508">"Síť Wi-Fi je odpojena."</string>
+ <string name="accessibility_wifi_one_bar" msgid="4869376278894301820">"Wi-Fi – jedna čárka."</string>
+ <string name="accessibility_wifi_two_bars" msgid="3569851234710034416">"Wi-Fi – dvě čárky."</string>
+ <string name="accessibility_wifi_three_bars" msgid="8134185644861380311">"Wi-Fi – tři čárky."</string>
+ <string name="accessibility_wifi_signal_full" msgid="7061045677694702">"Wi-Fi – plný signál."</string>
</resources>
diff --git a/packages/SettingsLib/res/values-da/strings.xml b/packages/SettingsLib/res/values-da/strings.xml
index dc0d5ec..59cdc904 100644
--- a/packages/SettingsLib/res/values-da/strings.xml
+++ b/packages/SettingsLib/res/values-da/strings.xml
@@ -77,16 +77,10 @@
<string name="bluetooth_pairing_pin_error_message" msgid="8337234855188925274">"Der kunne ikke parres med <xliff:g id="DEVICE_NAME">%1$s</xliff:g> på grund af en forkert pinkode eller adgangsnøgle."</string>
<string name="bluetooth_pairing_device_down_error_message" msgid="7870998403045801381">"Der kan ikke kommunikeres med <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
<string name="bluetooth_pairing_rejected_error_message" msgid="1648157108520832454">"Parring afvist af <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
- <!-- no translation found for accessibility_wifi_off (1166761729660614716) -->
- <skip />
- <!-- no translation found for accessibility_no_wifi (8834610636137374508) -->
- <skip />
- <!-- no translation found for accessibility_wifi_one_bar (4869376278894301820) -->
- <skip />
- <!-- no translation found for accessibility_wifi_two_bars (3569851234710034416) -->
- <skip />
- <!-- no translation found for accessibility_wifi_three_bars (8134185644861380311) -->
- <skip />
- <!-- no translation found for accessibility_wifi_signal_full (7061045677694702) -->
- <skip />
+ <string name="accessibility_wifi_off" msgid="1166761729660614716">"Wi-Fi er slået fra."</string>
+ <string name="accessibility_no_wifi" msgid="8834610636137374508">"Wi-Fi er afbrudt."</string>
+ <string name="accessibility_wifi_one_bar" msgid="4869376278894301820">"Wi-Fi har én bjælke."</string>
+ <string name="accessibility_wifi_two_bars" msgid="3569851234710034416">"Wi-Fi har to bjælker."</string>
+ <string name="accessibility_wifi_three_bars" msgid="8134185644861380311">"Wi-Fi har tre bjælker."</string>
+ <string name="accessibility_wifi_signal_full" msgid="7061045677694702">"Wi-Fi har fuldt signal."</string>
</resources>
diff --git a/packages/SettingsLib/res/values-de/strings.xml b/packages/SettingsLib/res/values-de/strings.xml
index 432e729..424cf83 100644
--- a/packages/SettingsLib/res/values-de/strings.xml
+++ b/packages/SettingsLib/res/values-de/strings.xml
@@ -77,16 +77,10 @@
<string name="bluetooth_pairing_pin_error_message" msgid="8337234855188925274">"Pairing mit <xliff:g id="DEVICE_NAME">%1$s</xliff:g> war nicht möglich, weil die eingegebene PIN oder der Zugangscode falsch ist."</string>
<string name="bluetooth_pairing_device_down_error_message" msgid="7870998403045801381">"Kommunikation mit <xliff:g id="DEVICE_NAME">%1$s</xliff:g> ist nicht möglich."</string>
<string name="bluetooth_pairing_rejected_error_message" msgid="1648157108520832454">"Verbindung wurde von <xliff:g id="DEVICE_NAME">%1$s</xliff:g> abgelehnt."</string>
- <!-- no translation found for accessibility_wifi_off (1166761729660614716) -->
- <skip />
- <!-- no translation found for accessibility_no_wifi (8834610636137374508) -->
- <skip />
- <!-- no translation found for accessibility_wifi_one_bar (4869376278894301820) -->
- <skip />
- <!-- no translation found for accessibility_wifi_two_bars (3569851234710034416) -->
- <skip />
- <!-- no translation found for accessibility_wifi_three_bars (8134185644861380311) -->
- <skip />
- <!-- no translation found for accessibility_wifi_signal_full (7061045677694702) -->
- <skip />
+ <string name="accessibility_wifi_off" msgid="1166761729660614716">"WLAN: aus"</string>
+ <string name="accessibility_no_wifi" msgid="8834610636137374508">"WLAN getrennt"</string>
+ <string name="accessibility_wifi_one_bar" msgid="4869376278894301820">"WLAN: ein Balken"</string>
+ <string name="accessibility_wifi_two_bars" msgid="3569851234710034416">"WLAN: zwei Balken"</string>
+ <string name="accessibility_wifi_three_bars" msgid="8134185644861380311">"WLAN: drei Balken"</string>
+ <string name="accessibility_wifi_signal_full" msgid="7061045677694702">"WLAN: volle Signalstärke"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-el/strings.xml b/packages/SettingsLib/res/values-el/strings.xml
index 390b6bd..48ff636 100644
--- a/packages/SettingsLib/res/values-el/strings.xml
+++ b/packages/SettingsLib/res/values-el/strings.xml
@@ -77,16 +77,10 @@
<string name="bluetooth_pairing_pin_error_message" msgid="8337234855188925274">"Δεν ήταν δυνατή η σύζευξη με τη συσκευή <xliff:g id="DEVICE_NAME">%1$s</xliff:g> λόγω εσφαλμένου αριθμού PIN ή κλειδιού πρόσβασης."</string>
<string name="bluetooth_pairing_device_down_error_message" msgid="7870998403045801381">"Δεν είναι δυνατή η σύνδεση με τη συσκευή <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
<string name="bluetooth_pairing_rejected_error_message" msgid="1648157108520832454">"Η ζεύξη απορρίφθηκε από τη συσκευή <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
- <!-- no translation found for accessibility_wifi_off (1166761729660614716) -->
- <skip />
- <!-- no translation found for accessibility_no_wifi (8834610636137374508) -->
- <skip />
- <!-- no translation found for accessibility_wifi_one_bar (4869376278894301820) -->
- <skip />
- <!-- no translation found for accessibility_wifi_two_bars (3569851234710034416) -->
- <skip />
- <!-- no translation found for accessibility_wifi_three_bars (8134185644861380311) -->
- <skip />
- <!-- no translation found for accessibility_wifi_signal_full (7061045677694702) -->
- <skip />
+ <string name="accessibility_wifi_off" msgid="1166761729660614716">"Wi-Fi ανενεργό."</string>
+ <string name="accessibility_no_wifi" msgid="8834610636137374508">"Το Wi-Fi έχει αποσυνδεθεί."</string>
+ <string name="accessibility_wifi_one_bar" msgid="4869376278894301820">"Μία γραμμή Wi-Fi."</string>
+ <string name="accessibility_wifi_two_bars" msgid="3569851234710034416">"Δύο γραμμές Wi-Fi."</string>
+ <string name="accessibility_wifi_three_bars" msgid="8134185644861380311">"Τρεις γραμμές Wi-Fi."</string>
+ <string name="accessibility_wifi_signal_full" msgid="7061045677694702">"Άριστο σήμα Wi-Fi."</string>
</resources>
diff --git a/packages/SettingsLib/res/values-en-rAU/strings.xml b/packages/SettingsLib/res/values-en-rAU/strings.xml
index 2bca7ce..ccbbdcf 100644
--- a/packages/SettingsLib/res/values-en-rAU/strings.xml
+++ b/packages/SettingsLib/res/values-en-rAU/strings.xml
@@ -77,16 +77,10 @@
<string name="bluetooth_pairing_pin_error_message" msgid="8337234855188925274">"Couldn\'t pair with <xliff:g id="DEVICE_NAME">%1$s</xliff:g> because of an incorrect PIN or passkey."</string>
<string name="bluetooth_pairing_device_down_error_message" msgid="7870998403045801381">"Can\'t communicate with <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
<string name="bluetooth_pairing_rejected_error_message" msgid="1648157108520832454">"Pairing rejected by <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
- <!-- no translation found for accessibility_wifi_off (1166761729660614716) -->
- <skip />
- <!-- no translation found for accessibility_no_wifi (8834610636137374508) -->
- <skip />
- <!-- no translation found for accessibility_wifi_one_bar (4869376278894301820) -->
- <skip />
- <!-- no translation found for accessibility_wifi_two_bars (3569851234710034416) -->
- <skip />
- <!-- no translation found for accessibility_wifi_three_bars (8134185644861380311) -->
- <skip />
- <!-- no translation found for accessibility_wifi_signal_full (7061045677694702) -->
- <skip />
+ <string name="accessibility_wifi_off" msgid="1166761729660614716">"Wi-Fi off."</string>
+ <string name="accessibility_no_wifi" msgid="8834610636137374508">"Wi-Fi disconnected."</string>
+ <string name="accessibility_wifi_one_bar" msgid="4869376278894301820">"Wi-Fi one bar."</string>
+ <string name="accessibility_wifi_two_bars" msgid="3569851234710034416">"Wi-Fi two bars."</string>
+ <string name="accessibility_wifi_three_bars" msgid="8134185644861380311">"Wi-Fi three bars."</string>
+ <string name="accessibility_wifi_signal_full" msgid="7061045677694702">"Wi-Fi signal full."</string>
</resources>
diff --git a/packages/SettingsLib/res/values-en-rGB/strings.xml b/packages/SettingsLib/res/values-en-rGB/strings.xml
index 2bca7ce..ccbbdcf 100644
--- a/packages/SettingsLib/res/values-en-rGB/strings.xml
+++ b/packages/SettingsLib/res/values-en-rGB/strings.xml
@@ -77,16 +77,10 @@
<string name="bluetooth_pairing_pin_error_message" msgid="8337234855188925274">"Couldn\'t pair with <xliff:g id="DEVICE_NAME">%1$s</xliff:g> because of an incorrect PIN or passkey."</string>
<string name="bluetooth_pairing_device_down_error_message" msgid="7870998403045801381">"Can\'t communicate with <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
<string name="bluetooth_pairing_rejected_error_message" msgid="1648157108520832454">"Pairing rejected by <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
- <!-- no translation found for accessibility_wifi_off (1166761729660614716) -->
- <skip />
- <!-- no translation found for accessibility_no_wifi (8834610636137374508) -->
- <skip />
- <!-- no translation found for accessibility_wifi_one_bar (4869376278894301820) -->
- <skip />
- <!-- no translation found for accessibility_wifi_two_bars (3569851234710034416) -->
- <skip />
- <!-- no translation found for accessibility_wifi_three_bars (8134185644861380311) -->
- <skip />
- <!-- no translation found for accessibility_wifi_signal_full (7061045677694702) -->
- <skip />
+ <string name="accessibility_wifi_off" msgid="1166761729660614716">"Wi-Fi off."</string>
+ <string name="accessibility_no_wifi" msgid="8834610636137374508">"Wi-Fi disconnected."</string>
+ <string name="accessibility_wifi_one_bar" msgid="4869376278894301820">"Wi-Fi one bar."</string>
+ <string name="accessibility_wifi_two_bars" msgid="3569851234710034416">"Wi-Fi two bars."</string>
+ <string name="accessibility_wifi_three_bars" msgid="8134185644861380311">"Wi-Fi three bars."</string>
+ <string name="accessibility_wifi_signal_full" msgid="7061045677694702">"Wi-Fi signal full."</string>
</resources>
diff --git a/packages/SettingsLib/res/values-en-rIN/strings.xml b/packages/SettingsLib/res/values-en-rIN/strings.xml
index 2bca7ce..ccbbdcf 100644
--- a/packages/SettingsLib/res/values-en-rIN/strings.xml
+++ b/packages/SettingsLib/res/values-en-rIN/strings.xml
@@ -77,16 +77,10 @@
<string name="bluetooth_pairing_pin_error_message" msgid="8337234855188925274">"Couldn\'t pair with <xliff:g id="DEVICE_NAME">%1$s</xliff:g> because of an incorrect PIN or passkey."</string>
<string name="bluetooth_pairing_device_down_error_message" msgid="7870998403045801381">"Can\'t communicate with <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
<string name="bluetooth_pairing_rejected_error_message" msgid="1648157108520832454">"Pairing rejected by <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
- <!-- no translation found for accessibility_wifi_off (1166761729660614716) -->
- <skip />
- <!-- no translation found for accessibility_no_wifi (8834610636137374508) -->
- <skip />
- <!-- no translation found for accessibility_wifi_one_bar (4869376278894301820) -->
- <skip />
- <!-- no translation found for accessibility_wifi_two_bars (3569851234710034416) -->
- <skip />
- <!-- no translation found for accessibility_wifi_three_bars (8134185644861380311) -->
- <skip />
- <!-- no translation found for accessibility_wifi_signal_full (7061045677694702) -->
- <skip />
+ <string name="accessibility_wifi_off" msgid="1166761729660614716">"Wi-Fi off."</string>
+ <string name="accessibility_no_wifi" msgid="8834610636137374508">"Wi-Fi disconnected."</string>
+ <string name="accessibility_wifi_one_bar" msgid="4869376278894301820">"Wi-Fi one bar."</string>
+ <string name="accessibility_wifi_two_bars" msgid="3569851234710034416">"Wi-Fi two bars."</string>
+ <string name="accessibility_wifi_three_bars" msgid="8134185644861380311">"Wi-Fi three bars."</string>
+ <string name="accessibility_wifi_signal_full" msgid="7061045677694702">"Wi-Fi signal full."</string>
</resources>
diff --git a/packages/SettingsLib/res/values-es-rUS/strings.xml b/packages/SettingsLib/res/values-es-rUS/strings.xml
index c0da188..67e9114 100644
--- a/packages/SettingsLib/res/values-es-rUS/strings.xml
+++ b/packages/SettingsLib/res/values-es-rUS/strings.xml
@@ -77,16 +77,10 @@
<string name="bluetooth_pairing_pin_error_message" msgid="8337234855188925274">"No se pudo sincronizar con <xliff:g id="DEVICE_NAME">%1$s</xliff:g> debido a que el PIN o la clave de acceso son incorrectos."</string>
<string name="bluetooth_pairing_device_down_error_message" msgid="7870998403045801381">"No se puede establecer la comunicación con <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
<string name="bluetooth_pairing_rejected_error_message" msgid="1648157108520832454">"Vínculo rechazado por <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
- <!-- no translation found for accessibility_wifi_off (1166761729660614716) -->
- <skip />
- <!-- no translation found for accessibility_no_wifi (8834610636137374508) -->
- <skip />
- <!-- no translation found for accessibility_wifi_one_bar (4869376278894301820) -->
- <skip />
- <!-- no translation found for accessibility_wifi_two_bars (3569851234710034416) -->
- <skip />
- <!-- no translation found for accessibility_wifi_three_bars (8134185644861380311) -->
- <skip />
- <!-- no translation found for accessibility_wifi_signal_full (7061045677694702) -->
- <skip />
+ <string name="accessibility_wifi_off" msgid="1166761729660614716">"Wi-Fi inhabilitado"</string>
+ <string name="accessibility_no_wifi" msgid="8834610636137374508">"Wi-Fi desconectado"</string>
+ <string name="accessibility_wifi_one_bar" msgid="4869376278894301820">"Una barra de Wi-Fi"</string>
+ <string name="accessibility_wifi_two_bars" msgid="3569851234710034416">"Dos barras de Wi-Fi"</string>
+ <string name="accessibility_wifi_three_bars" msgid="8134185644861380311">"Tres barras de Wi-Fi"</string>
+ <string name="accessibility_wifi_signal_full" msgid="7061045677694702">"Señal de Wi-Fi excelente"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-es/strings.xml b/packages/SettingsLib/res/values-es/strings.xml
index f3b310e..30983dd 100644
--- a/packages/SettingsLib/res/values-es/strings.xml
+++ b/packages/SettingsLib/res/values-es/strings.xml
@@ -77,16 +77,10 @@
<string name="bluetooth_pairing_pin_error_message" msgid="8337234855188925274">"No se ha podido vincular con <xliff:g id="DEVICE_NAME">%1$s</xliff:g> porque la clave de acceso o el PIN son incorrectos."</string>
<string name="bluetooth_pairing_device_down_error_message" msgid="7870998403045801381">"No se puede establecer comunicación con <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
<string name="bluetooth_pairing_rejected_error_message" msgid="1648157108520832454">"Vinculación rechazada por <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
- <!-- no translation found for accessibility_wifi_off (1166761729660614716) -->
- <skip />
- <!-- no translation found for accessibility_no_wifi (8834610636137374508) -->
- <skip />
- <!-- no translation found for accessibility_wifi_one_bar (4869376278894301820) -->
- <skip />
- <!-- no translation found for accessibility_wifi_two_bars (3569851234710034416) -->
- <skip />
- <!-- no translation found for accessibility_wifi_three_bars (8134185644861380311) -->
- <skip />
- <!-- no translation found for accessibility_wifi_signal_full (7061045677694702) -->
- <skip />
+ <string name="accessibility_wifi_off" msgid="1166761729660614716">"Wi-Fi desactivado."</string>
+ <string name="accessibility_no_wifi" msgid="8834610636137374508">"Wi-Fi desconectado."</string>
+ <string name="accessibility_wifi_one_bar" msgid="4869376278894301820">"Una barra de Wi-Fi."</string>
+ <string name="accessibility_wifi_two_bars" msgid="3569851234710034416">"Dos barras de Wi-Fi."</string>
+ <string name="accessibility_wifi_three_bars" msgid="8134185644861380311">"Tres barras de Wi-Fi."</string>
+ <string name="accessibility_wifi_signal_full" msgid="7061045677694702">"Señal de Wi-Fi al máximo."</string>
</resources>
diff --git a/packages/SettingsLib/res/values-et-rEE/strings.xml b/packages/SettingsLib/res/values-et-rEE/strings.xml
index ee8b031..af58a91 100644
--- a/packages/SettingsLib/res/values-et-rEE/strings.xml
+++ b/packages/SettingsLib/res/values-et-rEE/strings.xml
@@ -77,16 +77,10 @@
<string name="bluetooth_pairing_pin_error_message" msgid="8337234855188925274">"Ei saanud seadmega <xliff:g id="DEVICE_NAME">%1$s</xliff:g> siduda vale PIN-koodi või parooli tõttu."</string>
<string name="bluetooth_pairing_device_down_error_message" msgid="7870998403045801381">"Seadmega <xliff:g id="DEVICE_NAME">%1$s</xliff:g> ei saa sidet luua."</string>
<string name="bluetooth_pairing_rejected_error_message" msgid="1648157108520832454">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> hülgas sidumise."</string>
- <!-- no translation found for accessibility_wifi_off (1166761729660614716) -->
- <skip />
- <!-- no translation found for accessibility_no_wifi (8834610636137374508) -->
- <skip />
- <!-- no translation found for accessibility_wifi_one_bar (4869376278894301820) -->
- <skip />
- <!-- no translation found for accessibility_wifi_two_bars (3569851234710034416) -->
- <skip />
- <!-- no translation found for accessibility_wifi_three_bars (8134185644861380311) -->
- <skip />
- <!-- no translation found for accessibility_wifi_signal_full (7061045677694702) -->
- <skip />
+ <string name="accessibility_wifi_off" msgid="1166761729660614716">"WiFi on välja lülitatud."</string>
+ <string name="accessibility_no_wifi" msgid="8834610636137374508">"WiFi-ühendus on katkestatud."</string>
+ <string name="accessibility_wifi_one_bar" msgid="4869376278894301820">"WiFi: üks pulk."</string>
+ <string name="accessibility_wifi_two_bars" msgid="3569851234710034416">"WiFi: kaks pulka."</string>
+ <string name="accessibility_wifi_three_bars" msgid="8134185644861380311">"WiFi: kolm pulka."</string>
+ <string name="accessibility_wifi_signal_full" msgid="7061045677694702">"WiFi-signaal on tugev."</string>
</resources>
diff --git a/packages/SettingsLib/res/values-eu-rES/strings.xml b/packages/SettingsLib/res/values-eu-rES/strings.xml
index 1f86e3b..f500557 100644
--- a/packages/SettingsLib/res/values-eu-rES/strings.xml
+++ b/packages/SettingsLib/res/values-eu-rES/strings.xml
@@ -77,16 +77,10 @@
<string name="bluetooth_pairing_pin_error_message" msgid="8337234855188925274">"Ezin izan da <xliff:g id="DEVICE_NAME">%1$s</xliff:g> gailuarekin parekatu PIN edo pasakode okerra idatzi delako."</string>
<string name="bluetooth_pairing_device_down_error_message" msgid="7870998403045801381">"Ezin da <xliff:g id="DEVICE_NAME">%1$s</xliff:g> gailuarekin komunikatu."</string>
<string name="bluetooth_pairing_rejected_error_message" msgid="1648157108520832454">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> gailuak bikotetzea ukatu du."</string>
- <!-- no translation found for accessibility_wifi_off (1166761729660614716) -->
- <skip />
- <!-- no translation found for accessibility_no_wifi (8834610636137374508) -->
- <skip />
- <!-- no translation found for accessibility_wifi_one_bar (4869376278894301820) -->
- <skip />
- <!-- no translation found for accessibility_wifi_two_bars (3569851234710034416) -->
- <skip />
- <!-- no translation found for accessibility_wifi_three_bars (8134185644861380311) -->
- <skip />
- <!-- no translation found for accessibility_wifi_signal_full (7061045677694702) -->
- <skip />
+ <string name="accessibility_wifi_off" msgid="1166761729660614716">"Desaktibatuta dago Wi-Fi konexioa."</string>
+ <string name="accessibility_no_wifi" msgid="8834610636137374508">"Deskonektatu egin da Wi-Fi konexioa."</string>
+ <string name="accessibility_wifi_one_bar" msgid="4869376278894301820">"Wi-Fi sarearen barra bat."</string>
+ <string name="accessibility_wifi_two_bars" msgid="3569851234710034416">"Wi-Fi sarearen bi barra."</string>
+ <string name="accessibility_wifi_three_bars" msgid="8134185644861380311">"Wi-Fi sarearen hiru barra."</string>
+ <string name="accessibility_wifi_signal_full" msgid="7061045677694702">"Wi-Fi sarearen seinalea osoa."</string>
</resources>
diff --git a/packages/SettingsLib/res/values-fa/strings.xml b/packages/SettingsLib/res/values-fa/strings.xml
index 784d801..2968913 100644
--- a/packages/SettingsLib/res/values-fa/strings.xml
+++ b/packages/SettingsLib/res/values-fa/strings.xml
@@ -69,24 +69,18 @@
<string name="bluetooth_headset_profile_summary_use_for" msgid="8705753622443862627">"استفاده برای تلفن صوتی"</string>
<string name="bluetooth_opp_profile_summary_use_for" msgid="1255674547144769756">"استفاده برای انتقال فایل"</string>
<string name="bluetooth_hid_profile_summary_use_for" msgid="232727040453645139">"استفاده برای چاپ"</string>
- <string name="bluetooth_pairing_accept" msgid="6163520056536604875">"مرتبط سازی"</string>
+ <string name="bluetooth_pairing_accept" msgid="6163520056536604875">"مرتبطسازی"</string>
<string name="bluetooth_pairing_accept_all_caps" msgid="6061699265220789149">"مرتبطسازی"</string>
<string name="bluetooth_pairing_decline" msgid="4185420413578948140">"لغو"</string>
<string name="bluetooth_pairing_will_share_phonebook" msgid="4982239145676394429">"وقتی وصل باشید، مرتبطسازی اجازه دسترسی به مخاطبین و سابقه تماستان را فراهم میکند."</string>
- <string name="bluetooth_pairing_error_message" msgid="3748157733635947087">"جفت کردن با <xliff:g id="DEVICE_NAME">%1$s</xliff:g> امکانپذیر نیست."</string>
+ <string name="bluetooth_pairing_error_message" msgid="3748157733635947087">"با <xliff:g id="DEVICE_NAME">%1$s</xliff:g> مرتبطسازی نشد."</string>
<string name="bluetooth_pairing_pin_error_message" msgid="8337234855188925274">"به خاطر یک پین یا کلیدواژه نادرست، مرتبطسازی با <xliff:g id="DEVICE_NAME">%1$s</xliff:g> انجام نشد."</string>
<string name="bluetooth_pairing_device_down_error_message" msgid="7870998403045801381">"ارتباط با <xliff:g id="DEVICE_NAME">%1$s</xliff:g> امکانپذیر نیست."</string>
<string name="bluetooth_pairing_rejected_error_message" msgid="1648157108520832454">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> مرتبطسازی را رد کرد."</string>
- <!-- no translation found for accessibility_wifi_off (1166761729660614716) -->
- <skip />
- <!-- no translation found for accessibility_no_wifi (8834610636137374508) -->
- <skip />
- <!-- no translation found for accessibility_wifi_one_bar (4869376278894301820) -->
- <skip />
- <!-- no translation found for accessibility_wifi_two_bars (3569851234710034416) -->
- <skip />
- <!-- no translation found for accessibility_wifi_three_bars (8134185644861380311) -->
- <skip />
- <!-- no translation found for accessibility_wifi_signal_full (7061045677694702) -->
- <skip />
+ <string name="accessibility_wifi_off" msgid="1166761729660614716">"Wi‑Fi خاموش است."</string>
+ <string name="accessibility_no_wifi" msgid="8834610636137374508">"Wi-Fi قطع شد."</string>
+ <string name="accessibility_wifi_one_bar" msgid="4869376278894301820">"یک نوار برای Wi‑Fi."</string>
+ <string name="accessibility_wifi_two_bars" msgid="3569851234710034416">"دو نوار برای Wi‑Fi."</string>
+ <string name="accessibility_wifi_three_bars" msgid="8134185644861380311">"سه نوار برای Wi‑Fi."</string>
+ <string name="accessibility_wifi_signal_full" msgid="7061045677694702">"قدرت سیگنال Wi‑Fi کامل است."</string>
</resources>
diff --git a/packages/SettingsLib/res/values-fi/strings.xml b/packages/SettingsLib/res/values-fi/strings.xml
index ede35ad..9ef1087 100644
--- a/packages/SettingsLib/res/values-fi/strings.xml
+++ b/packages/SettingsLib/res/values-fi/strings.xml
@@ -77,16 +77,10 @@
<string name="bluetooth_pairing_pin_error_message" msgid="8337234855188925274">"Laiteparia laitteen <xliff:g id="DEVICE_NAME">%1$s</xliff:g> kanssa ei voitu muodostaa, koska PIN-koodi tai avain oli virheellinen."</string>
<string name="bluetooth_pairing_device_down_error_message" msgid="7870998403045801381">"Ei yhteyttä laitteeseen <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
<string name="bluetooth_pairing_rejected_error_message" msgid="1648157108520832454">"Laite <xliff:g id="DEVICE_NAME">%1$s</xliff:g> torjui laitepariyhteyden."</string>
- <!-- no translation found for accessibility_wifi_off (1166761729660614716) -->
- <skip />
- <!-- no translation found for accessibility_no_wifi (8834610636137374508) -->
- <skip />
- <!-- no translation found for accessibility_wifi_one_bar (4869376278894301820) -->
- <skip />
- <!-- no translation found for accessibility_wifi_two_bars (3569851234710034416) -->
- <skip />
- <!-- no translation found for accessibility_wifi_three_bars (8134185644861380311) -->
- <skip />
- <!-- no translation found for accessibility_wifi_signal_full (7061045677694702) -->
- <skip />
+ <string name="accessibility_wifi_off" msgid="1166761729660614716">"Wi-Fi pois käytöstä"</string>
+ <string name="accessibility_no_wifi" msgid="8834610636137374508">"Ei Wi-Fi-yhteyttä"</string>
+ <string name="accessibility_wifi_one_bar" msgid="4869376278894301820">"Wi-Fi-signaali – yksi palkki"</string>
+ <string name="accessibility_wifi_two_bars" msgid="3569851234710034416">"Wi-Fi-signaali – kaksi palkkia"</string>
+ <string name="accessibility_wifi_three_bars" msgid="8134185644861380311">"Wi-Fi-signaali – kolme palkkia"</string>
+ <string name="accessibility_wifi_signal_full" msgid="7061045677694702">"Vahva Wi-Fi-signaali"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-fr-rCA/strings.xml b/packages/SettingsLib/res/values-fr-rCA/strings.xml
index 66836ef..19eb40b 100644
--- a/packages/SettingsLib/res/values-fr-rCA/strings.xml
+++ b/packages/SettingsLib/res/values-fr-rCA/strings.xml
@@ -77,16 +77,10 @@
<string name="bluetooth_pairing_pin_error_message" msgid="8337234855188925274">"Impossible d\'établir l\'association avec <xliff:g id="DEVICE_NAME">%1$s</xliff:g> en raison d\'un NIP ou d\'une clé d\'accès incorrects."</string>
<string name="bluetooth_pairing_device_down_error_message" msgid="7870998403045801381">"Impossible d\'établir la communication avec <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
<string name="bluetooth_pairing_rejected_error_message" msgid="1648157108520832454">"Association refusée par <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
- <!-- no translation found for accessibility_wifi_off (1166761729660614716) -->
- <skip />
- <!-- no translation found for accessibility_no_wifi (8834610636137374508) -->
- <skip />
- <!-- no translation found for accessibility_wifi_one_bar (4869376278894301820) -->
- <skip />
- <!-- no translation found for accessibility_wifi_two_bars (3569851234710034416) -->
- <skip />
- <!-- no translation found for accessibility_wifi_three_bars (8134185644861380311) -->
- <skip />
- <!-- no translation found for accessibility_wifi_signal_full (7061045677694702) -->
- <skip />
+ <string name="accessibility_wifi_off" msgid="1166761729660614716">"Wi-Fi désactivé."</string>
+ <string name="accessibility_no_wifi" msgid="8834610636137374508">"Wi-Fi déconnecté."</string>
+ <string name="accessibility_wifi_one_bar" msgid="4869376278894301820">"Wi-Fi : une barre."</string>
+ <string name="accessibility_wifi_two_bars" msgid="3569851234710034416">"Wi-Fi : deux barres."</string>
+ <string name="accessibility_wifi_three_bars" msgid="8134185644861380311">"Wi-Fi : trois barres."</string>
+ <string name="accessibility_wifi_signal_full" msgid="7061045677694702">"Wi-Fi : signal complet."</string>
</resources>
diff --git a/packages/SettingsLib/res/values-fr/strings.xml b/packages/SettingsLib/res/values-fr/strings.xml
index 3c0346ee..b184160 100644
--- a/packages/SettingsLib/res/values-fr/strings.xml
+++ b/packages/SettingsLib/res/values-fr/strings.xml
@@ -74,19 +74,13 @@
<string name="bluetooth_pairing_decline" msgid="4185420413578948140">"Annuler"</string>
<string name="bluetooth_pairing_will_share_phonebook" msgid="4982239145676394429">"L\'association vous permet d\'accéder à vos contacts et à l\'historique des appels lorsque vous êtes connecté."</string>
<string name="bluetooth_pairing_error_message" msgid="3748157733635947087">"Impossible d\'associer à <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
- <string name="bluetooth_pairing_pin_error_message" msgid="8337234855188925274">"Impossible d\'établir l\'association avec <xliff:g id="DEVICE_NAME">%1$s</xliff:g> en raison d\'un code PIN ou d\'une clé d\'accès incorrects."</string>
+ <string name="bluetooth_pairing_pin_error_message" msgid="8337234855188925274">"Impossible d\'établir l\'association avec <xliff:g id="DEVICE_NAME">%1$s</xliff:g> en raison d\'un code ou d\'une clé d\'accès incorrects."</string>
<string name="bluetooth_pairing_device_down_error_message" msgid="7870998403045801381">"Impossible d\'établir la communication avec <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
<string name="bluetooth_pairing_rejected_error_message" msgid="1648157108520832454">"Association refusée par <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
- <!-- no translation found for accessibility_wifi_off (1166761729660614716) -->
- <skip />
- <!-- no translation found for accessibility_no_wifi (8834610636137374508) -->
- <skip />
- <!-- no translation found for accessibility_wifi_one_bar (4869376278894301820) -->
- <skip />
- <!-- no translation found for accessibility_wifi_two_bars (3569851234710034416) -->
- <skip />
- <!-- no translation found for accessibility_wifi_three_bars (8134185644861380311) -->
- <skip />
- <!-- no translation found for accessibility_wifi_signal_full (7061045677694702) -->
- <skip />
+ <string name="accessibility_wifi_off" msgid="1166761729660614716">"Wi-Fi désactivé"</string>
+ <string name="accessibility_no_wifi" msgid="8834610636137374508">"Wi-Fi déconnecté"</string>
+ <string name="accessibility_wifi_one_bar" msgid="4869376278894301820">"Signal Wi-Fi faible"</string>
+ <string name="accessibility_wifi_two_bars" msgid="3569851234710034416">"Signal Wi-Fi moyen"</string>
+ <string name="accessibility_wifi_three_bars" msgid="8134185644861380311">"Signal Wi-Fi bon"</string>
+ <string name="accessibility_wifi_signal_full" msgid="7061045677694702">"Signal Wi-Fi excellent"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-gl-rES/strings.xml b/packages/SettingsLib/res/values-gl-rES/strings.xml
index a96eda8..07bde32 100644
--- a/packages/SettingsLib/res/values-gl-rES/strings.xml
+++ b/packages/SettingsLib/res/values-gl-rES/strings.xml
@@ -77,16 +77,10 @@
<string name="bluetooth_pairing_pin_error_message" msgid="8337234855188925274">"Non se puido sincronizar con <xliff:g id="DEVICE_NAME">%1$s</xliff:g> debido a que se introduciu un contrasinal ou PIN incorrecto."</string>
<string name="bluetooth_pairing_device_down_error_message" msgid="7870998403045801381">"Non se pode comunicar con <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
<string name="bluetooth_pairing_rejected_error_message" msgid="1648157108520832454">"Sincronización rexeitada por <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
- <!-- no translation found for accessibility_wifi_off (1166761729660614716) -->
- <skip />
- <!-- no translation found for accessibility_no_wifi (8834610636137374508) -->
- <skip />
- <!-- no translation found for accessibility_wifi_one_bar (4869376278894301820) -->
- <skip />
- <!-- no translation found for accessibility_wifi_two_bars (3569851234710034416) -->
- <skip />
- <!-- no translation found for accessibility_wifi_three_bars (8134185644861380311) -->
- <skip />
- <!-- no translation found for accessibility_wifi_signal_full (7061045677694702) -->
- <skip />
+ <string name="accessibility_wifi_off" msgid="1166761729660614716">"Wifi desactivada."</string>
+ <string name="accessibility_no_wifi" msgid="8834610636137374508">"Wifi desconectada."</string>
+ <string name="accessibility_wifi_one_bar" msgid="4869376278894301820">"Unha barra de wifi."</string>
+ <string name="accessibility_wifi_two_bars" msgid="3569851234710034416">"Dúas barras de wifi."</string>
+ <string name="accessibility_wifi_three_bars" msgid="8134185644861380311">"Tres barras de wifi."</string>
+ <string name="accessibility_wifi_signal_full" msgid="7061045677694702">"Sinal completo de wifi."</string>
</resources>
diff --git a/packages/SettingsLib/res/values-gu-rIN/strings.xml b/packages/SettingsLib/res/values-gu-rIN/strings.xml
index 2b22e61..03bd2d2bf 100644
--- a/packages/SettingsLib/res/values-gu-rIN/strings.xml
+++ b/packages/SettingsLib/res/values-gu-rIN/strings.xml
@@ -77,16 +77,10 @@
<string name="bluetooth_pairing_pin_error_message" msgid="8337234855188925274">"એક ખોટા PIN અથવા પાસકીને કારણે <xliff:g id="DEVICE_NAME">%1$s</xliff:g> સાથે જોડી બનાવી શકાઈ નથી."</string>
<string name="bluetooth_pairing_device_down_error_message" msgid="7870998403045801381">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> સાથે સંચાર કરી શકાતો નથી."</string>
<string name="bluetooth_pairing_rejected_error_message" msgid="1648157108520832454">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> દ્વારા જોડી કરવાનું નકાર્યું."</string>
- <!-- no translation found for accessibility_wifi_off (1166761729660614716) -->
- <skip />
- <!-- no translation found for accessibility_no_wifi (8834610636137374508) -->
- <skip />
- <!-- no translation found for accessibility_wifi_one_bar (4869376278894301820) -->
- <skip />
- <!-- no translation found for accessibility_wifi_two_bars (3569851234710034416) -->
- <skip />
- <!-- no translation found for accessibility_wifi_three_bars (8134185644861380311) -->
- <skip />
- <!-- no translation found for accessibility_wifi_signal_full (7061045677694702) -->
- <skip />
+ <string name="accessibility_wifi_off" msgid="1166761729660614716">"Wifi બંધ."</string>
+ <string name="accessibility_no_wifi" msgid="8834610636137374508">"Wifi ડિસ્કનેક્ટ થયું."</string>
+ <string name="accessibility_wifi_one_bar" msgid="4869376278894301820">"Wifi એક બાર."</string>
+ <string name="accessibility_wifi_two_bars" msgid="3569851234710034416">"Wifi બે બાર."</string>
+ <string name="accessibility_wifi_three_bars" msgid="8134185644861380311">"Wifi ત્રણ બાર."</string>
+ <string name="accessibility_wifi_signal_full" msgid="7061045677694702">"પૂર્ણ Wifi સિગ્નલ."</string>
</resources>
diff --git a/packages/SettingsLib/res/values-hi/strings.xml b/packages/SettingsLib/res/values-hi/strings.xml
index d750a3a..c6edfc8 100644
--- a/packages/SettingsLib/res/values-hi/strings.xml
+++ b/packages/SettingsLib/res/values-hi/strings.xml
@@ -77,16 +77,10 @@
<string name="bluetooth_pairing_pin_error_message" msgid="8337234855188925274">"गलत पिन या पासकी के कारण <xliff:g id="DEVICE_NAME">%1$s</xliff:g> के साथ युग्मित नहीं हो सका."</string>
<string name="bluetooth_pairing_device_down_error_message" msgid="7870998403045801381">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> से संचार नहीं कर सकता."</string>
<string name="bluetooth_pairing_rejected_error_message" msgid="1648157108520832454">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> द्वारा युग्मन अस्वीकृत किया गया."</string>
- <!-- no translation found for accessibility_wifi_off (1166761729660614716) -->
- <skip />
- <!-- no translation found for accessibility_no_wifi (8834610636137374508) -->
- <skip />
- <!-- no translation found for accessibility_wifi_one_bar (4869376278894301820) -->
- <skip />
- <!-- no translation found for accessibility_wifi_two_bars (3569851234710034416) -->
- <skip />
- <!-- no translation found for accessibility_wifi_three_bars (8134185644861380311) -->
- <skip />
- <!-- no translation found for accessibility_wifi_signal_full (7061045677694702) -->
- <skip />
+ <string name="accessibility_wifi_off" msgid="1166761729660614716">"वाई-फ़ाई बंद है."</string>
+ <string name="accessibility_no_wifi" msgid="8834610636137374508">"वाई-फ़ाई डिस्कनेक्ट है."</string>
+ <string name="accessibility_wifi_one_bar" msgid="4869376278894301820">"वाई-फ़ाई का एक बार है."</string>
+ <string name="accessibility_wifi_two_bars" msgid="3569851234710034416">"वाई-फ़ाई की दो पट्टी मिल रही हैं."</string>
+ <string name="accessibility_wifi_three_bars" msgid="8134185644861380311">"वाई-फ़ाई की एक पट्टी मिल रही है."</string>
+ <string name="accessibility_wifi_signal_full" msgid="7061045677694702">"पूरे वाई-फ़ाई सिग्नल मिल रहे हैं."</string>
</resources>
diff --git a/packages/SettingsLib/res/values-hr/strings.xml b/packages/SettingsLib/res/values-hr/strings.xml
index 8ea337d..f8cf53a 100644
--- a/packages/SettingsLib/res/values-hr/strings.xml
+++ b/packages/SettingsLib/res/values-hr/strings.xml
@@ -77,16 +77,10 @@
<string name="bluetooth_pairing_pin_error_message" msgid="8337234855188925274">"Uparivanje s uređajem <xliff:g id="DEVICE_NAME">%1$s</xliff:g> nije bilo moguće zbog netočnog PIN-a ili zaporke."</string>
<string name="bluetooth_pairing_device_down_error_message" msgid="7870998403045801381">"Komunikacija s uređajem <xliff:g id="DEVICE_NAME">%1$s</xliff:g> nije moguća."</string>
<string name="bluetooth_pairing_rejected_error_message" msgid="1648157108520832454">"Uparivanje odbio uređaj <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
- <!-- no translation found for accessibility_wifi_off (1166761729660614716) -->
- <skip />
- <!-- no translation found for accessibility_no_wifi (8834610636137374508) -->
- <skip />
- <!-- no translation found for accessibility_wifi_one_bar (4869376278894301820) -->
- <skip />
- <!-- no translation found for accessibility_wifi_two_bars (3569851234710034416) -->
- <skip />
- <!-- no translation found for accessibility_wifi_three_bars (8134185644861380311) -->
- <skip />
- <!-- no translation found for accessibility_wifi_signal_full (7061045677694702) -->
- <skip />
+ <string name="accessibility_wifi_off" msgid="1166761729660614716">"Wi-Fi je isključen."</string>
+ <string name="accessibility_no_wifi" msgid="8834610636137374508">"Wi-Fi je isključen."</string>
+ <string name="accessibility_wifi_one_bar" msgid="4869376278894301820">"Wi-Fi signal ima jedan stupac."</string>
+ <string name="accessibility_wifi_two_bars" msgid="3569851234710034416">"Wi-Fi signal ima dva stupca."</string>
+ <string name="accessibility_wifi_three_bars" msgid="8134185644861380311">"Wi-Fi signal ima tri stupca."</string>
+ <string name="accessibility_wifi_signal_full" msgid="7061045677694702">"Wi-Fi signal je pun."</string>
</resources>
diff --git a/packages/SettingsLib/res/values-hu/strings.xml b/packages/SettingsLib/res/values-hu/strings.xml
index 5d7c02c..e786e81 100644
--- a/packages/SettingsLib/res/values-hu/strings.xml
+++ b/packages/SettingsLib/res/values-hu/strings.xml
@@ -77,16 +77,10 @@
<string name="bluetooth_pairing_pin_error_message" msgid="8337234855188925274">"A párosítás sikertelen volt a(z) <xliff:g id="DEVICE_NAME">%1$s</xliff:g> eszközzel hibás PIN kód vagy jelszó miatt."</string>
<string name="bluetooth_pairing_device_down_error_message" msgid="7870998403045801381">"Nem lehet kommunikálni a(z) <xliff:g id="DEVICE_NAME">%1$s</xliff:g> eszközzel."</string>
<string name="bluetooth_pairing_rejected_error_message" msgid="1648157108520832454">"A(z) <xliff:g id="DEVICE_NAME">%1$s</xliff:g> eszköz elutasította a párosítást."</string>
- <!-- no translation found for accessibility_wifi_off (1166761729660614716) -->
- <skip />
- <!-- no translation found for accessibility_no_wifi (8834610636137374508) -->
- <skip />
- <!-- no translation found for accessibility_wifi_one_bar (4869376278894301820) -->
- <skip />
- <!-- no translation found for accessibility_wifi_two_bars (3569851234710034416) -->
- <skip />
- <!-- no translation found for accessibility_wifi_three_bars (8134185644861380311) -->
- <skip />
- <!-- no translation found for accessibility_wifi_signal_full (7061045677694702) -->
- <skip />
+ <string name="accessibility_wifi_off" msgid="1166761729660614716">"Wi-Fi kikapcsolva."</string>
+ <string name="accessibility_no_wifi" msgid="8834610636137374508">"Nincs Wi-Fi-kapcsolat."</string>
+ <string name="accessibility_wifi_one_bar" msgid="4869376278894301820">"Wi-Fi-jel: egy sáv."</string>
+ <string name="accessibility_wifi_two_bars" msgid="3569851234710034416">"Wi-Fi-jel: két sáv."</string>
+ <string name="accessibility_wifi_three_bars" msgid="8134185644861380311">"Wi-Fi-jel: három sáv."</string>
+ <string name="accessibility_wifi_signal_full" msgid="7061045677694702">"Wi-Fi-jel: teljes."</string>
</resources>
diff --git a/packages/SettingsLib/res/values-hy-rAM/strings.xml b/packages/SettingsLib/res/values-hy-rAM/strings.xml
index 38f4507..e51435c 100644
--- a/packages/SettingsLib/res/values-hy-rAM/strings.xml
+++ b/packages/SettingsLib/res/values-hy-rAM/strings.xml
@@ -77,16 +77,10 @@
<string name="bluetooth_pairing_pin_error_message" msgid="8337234855188925274">"Հնարավոր չեղավ զուգավորվել <xliff:g id="DEVICE_NAME">%1$s</xliff:g>-ի հետ սխալ PIN-ի կամ անցաբառի պատճառով:."</string>
<string name="bluetooth_pairing_device_down_error_message" msgid="7870998403045801381">"Հնարավոր չէ կապ հաստատել <xliff:g id="DEVICE_NAME">%1$s</xliff:g>-ի հետ:"</string>
<string name="bluetooth_pairing_rejected_error_message" msgid="1648157108520832454">"Զուգավորումը մերժվեց <xliff:g id="DEVICE_NAME">%1$s</xliff:g>-ի կողմից:"</string>
- <!-- no translation found for accessibility_wifi_off (1166761729660614716) -->
- <skip />
- <!-- no translation found for accessibility_no_wifi (8834610636137374508) -->
- <skip />
- <!-- no translation found for accessibility_wifi_one_bar (4869376278894301820) -->
- <skip />
- <!-- no translation found for accessibility_wifi_two_bars (3569851234710034416) -->
- <skip />
- <!-- no translation found for accessibility_wifi_three_bars (8134185644861380311) -->
- <skip />
- <!-- no translation found for accessibility_wifi_signal_full (7061045677694702) -->
- <skip />
+ <string name="accessibility_wifi_off" msgid="1166761729660614716">"Wi-Fi-ն անջատված է:"</string>
+ <string name="accessibility_no_wifi" msgid="8834610636137374508">"Wi-Fi-ը կապակցված չէ:"</string>
+ <string name="accessibility_wifi_one_bar" msgid="4869376278894301820">"Wi-Fi-ի ուժգնությունը՝ մեկ գիծ:"</string>
+ <string name="accessibility_wifi_two_bars" msgid="3569851234710034416">"Wi-Fi-ի ուժգնությունը՝ երկու գիծ:"</string>
+ <string name="accessibility_wifi_three_bars" msgid="8134185644861380311">"Wi-Fi-ի ուժգնությունը՝ երեք գիծ:"</string>
+ <string name="accessibility_wifi_signal_full" msgid="7061045677694702">"Wi-Fi-ի ազդանշանը ուժեղ է:"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-in/strings.xml b/packages/SettingsLib/res/values-in/strings.xml
index 314cacf..1a319e6 100644
--- a/packages/SettingsLib/res/values-in/strings.xml
+++ b/packages/SettingsLib/res/values-in/strings.xml
@@ -77,16 +77,10 @@
<string name="bluetooth_pairing_pin_error_message" msgid="8337234855188925274">"Tidak dapat menyandingkan dengan <xliff:g id="DEVICE_NAME">%1$s</xliff:g> karena PIN atau kode sandi salah."</string>
<string name="bluetooth_pairing_device_down_error_message" msgid="7870998403045801381">"Tidak dapat berkomunikasi dengan <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
<string name="bluetooth_pairing_rejected_error_message" msgid="1648157108520832454">"Penyandingan ditolak oleh <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
- <!-- no translation found for accessibility_wifi_off (1166761729660614716) -->
- <skip />
- <!-- no translation found for accessibility_no_wifi (8834610636137374508) -->
- <skip />
- <!-- no translation found for accessibility_wifi_one_bar (4869376278894301820) -->
- <skip />
- <!-- no translation found for accessibility_wifi_two_bars (3569851234710034416) -->
- <skip />
- <!-- no translation found for accessibility_wifi_three_bars (8134185644861380311) -->
- <skip />
- <!-- no translation found for accessibility_wifi_signal_full (7061045677694702) -->
- <skip />
+ <string name="accessibility_wifi_off" msgid="1166761729660614716">"Wi-Fi tidak aktif."</string>
+ <string name="accessibility_no_wifi" msgid="8834610636137374508">"Wi-Fi tidak tersambung."</string>
+ <string name="accessibility_wifi_one_bar" msgid="4869376278894301820">"Wi-Fi satu baris."</string>
+ <string name="accessibility_wifi_two_bars" msgid="3569851234710034416">"Wi-Fi dua baris"</string>
+ <string name="accessibility_wifi_three_bars" msgid="8134185644861380311">"Wi-Fi tiga baris."</string>
+ <string name="accessibility_wifi_signal_full" msgid="7061045677694702">"Sinyal Wi-Fi penuh."</string>
</resources>
diff --git a/packages/SettingsLib/res/values-is-rIS/strings.xml b/packages/SettingsLib/res/values-is-rIS/strings.xml
index e5e73d7..e5bebbd 100644
--- a/packages/SettingsLib/res/values-is-rIS/strings.xml
+++ b/packages/SettingsLib/res/values-is-rIS/strings.xml
@@ -77,16 +77,10 @@
<string name="bluetooth_pairing_pin_error_message" msgid="8337234855188925274">"Ekki tókst að para við <xliff:g id="DEVICE_NAME">%1$s</xliff:g> þar sem PIN-númer eða aðgangslykill er rangur."</string>
<string name="bluetooth_pairing_device_down_error_message" msgid="7870998403045801381">"Ekki er hægt að eiga samskipti við <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
<string name="bluetooth_pairing_rejected_error_message" msgid="1648157108520832454">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> hafnaði pörun."</string>
- <!-- no translation found for accessibility_wifi_off (1166761729660614716) -->
- <skip />
- <!-- no translation found for accessibility_no_wifi (8834610636137374508) -->
- <skip />
- <!-- no translation found for accessibility_wifi_one_bar (4869376278894301820) -->
- <skip />
- <!-- no translation found for accessibility_wifi_two_bars (3569851234710034416) -->
- <skip />
- <!-- no translation found for accessibility_wifi_three_bars (8134185644861380311) -->
- <skip />
- <!-- no translation found for accessibility_wifi_signal_full (7061045677694702) -->
- <skip />
+ <string name="accessibility_wifi_off" msgid="1166761729660614716">"Slökkt á Wi-Fi."</string>
+ <string name="accessibility_no_wifi" msgid="8834610636137374508">"Wi-Fi ótengt."</string>
+ <string name="accessibility_wifi_one_bar" msgid="4869376278894301820">"Wi-Fi: Eitt strik."</string>
+ <string name="accessibility_wifi_two_bars" msgid="3569851234710034416">"Wi-Fi: Tvö strik."</string>
+ <string name="accessibility_wifi_three_bars" msgid="8134185644861380311">"Wi-Fi: Þrjú strik."</string>
+ <string name="accessibility_wifi_signal_full" msgid="7061045677694702">"Fullur Wi-Fi sendistyrkur."</string>
</resources>
diff --git a/packages/SettingsLib/res/values-it/strings.xml b/packages/SettingsLib/res/values-it/strings.xml
index aae0c98..95fb7ee 100644
--- a/packages/SettingsLib/res/values-it/strings.xml
+++ b/packages/SettingsLib/res/values-it/strings.xml
@@ -77,16 +77,10 @@
<string name="bluetooth_pairing_pin_error_message" msgid="8337234855188925274">"Impossibile eseguire l\'accoppiamento con <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. La passkey o il PIN è errato."</string>
<string name="bluetooth_pairing_device_down_error_message" msgid="7870998403045801381">"Impossibile comunicare con <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
<string name="bluetooth_pairing_rejected_error_message" msgid="1648157108520832454">"Accoppiamento rifiutato da <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
- <!-- no translation found for accessibility_wifi_off (1166761729660614716) -->
- <skip />
- <!-- no translation found for accessibility_no_wifi (8834610636137374508) -->
- <skip />
- <!-- no translation found for accessibility_wifi_one_bar (4869376278894301820) -->
- <skip />
- <!-- no translation found for accessibility_wifi_two_bars (3569851234710034416) -->
- <skip />
- <!-- no translation found for accessibility_wifi_three_bars (8134185644861380311) -->
- <skip />
- <!-- no translation found for accessibility_wifi_signal_full (7061045677694702) -->
- <skip />
+ <string name="accessibility_wifi_off" msgid="1166761729660614716">"Wi-Fi non attivo."</string>
+ <string name="accessibility_no_wifi" msgid="8834610636137374508">"Rete Wi-Fi scollegata."</string>
+ <string name="accessibility_wifi_one_bar" msgid="4869376278894301820">"Wi-Fi: una barra."</string>
+ <string name="accessibility_wifi_two_bars" msgid="3569851234710034416">"Wi-Fi: due barre."</string>
+ <string name="accessibility_wifi_three_bars" msgid="8134185644861380311">"Wi-Fi: tre barre."</string>
+ <string name="accessibility_wifi_signal_full" msgid="7061045677694702">"Segnale Wi-Fi completo."</string>
</resources>
diff --git a/packages/SettingsLib/res/values-iw/strings.xml b/packages/SettingsLib/res/values-iw/strings.xml
index 9e5e81b..ed4a015 100644
--- a/packages/SettingsLib/res/values-iw/strings.xml
+++ b/packages/SettingsLib/res/values-iw/strings.xml
@@ -77,16 +77,10 @@
<string name="bluetooth_pairing_pin_error_message" msgid="8337234855188925274">"לא ניתן להתאים את <xliff:g id="DEVICE_NAME">%1$s</xliff:g> בשל קוד PIN או סיסמה שגויים."</string>
<string name="bluetooth_pairing_device_down_error_message" msgid="7870998403045801381">"לא ניתן לתקשר עם <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
<string name="bluetooth_pairing_rejected_error_message" msgid="1648157108520832454">"ההתאמה נדחתה על ידי <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
- <!-- no translation found for accessibility_wifi_off (1166761729660614716) -->
- <skip />
- <!-- no translation found for accessibility_no_wifi (8834610636137374508) -->
- <skip />
- <!-- no translation found for accessibility_wifi_one_bar (4869376278894301820) -->
- <skip />
- <!-- no translation found for accessibility_wifi_two_bars (3569851234710034416) -->
- <skip />
- <!-- no translation found for accessibility_wifi_three_bars (8134185644861380311) -->
- <skip />
- <!-- no translation found for accessibility_wifi_signal_full (7061045677694702) -->
- <skip />
+ <string name="accessibility_wifi_off" msgid="1166761729660614716">"Wi-Fi כבוי."</string>
+ <string name="accessibility_no_wifi" msgid="8834610636137374508">"Wi-Fi מנותק."</string>
+ <string name="accessibility_wifi_one_bar" msgid="4869376278894301820">"פס אחד של Wi-Fi."</string>
+ <string name="accessibility_wifi_two_bars" msgid="3569851234710034416">"שני פסים של Wi-Fi."</string>
+ <string name="accessibility_wifi_three_bars" msgid="8134185644861380311">"שלושה פסים של Wi-Fi."</string>
+ <string name="accessibility_wifi_signal_full" msgid="7061045677694702">"אות Wi-Fi מלא."</string>
</resources>
diff --git a/packages/SettingsLib/res/values-ja/strings.xml b/packages/SettingsLib/res/values-ja/strings.xml
index f25594e..571a4b2 100644
--- a/packages/SettingsLib/res/values-ja/strings.xml
+++ b/packages/SettingsLib/res/values-ja/strings.xml
@@ -33,7 +33,7 @@
<string name="connected_via_wfa" msgid="3805736726317410714">"Wi‑Fiアシスタント経由で接続"</string>
<string name="connected_via_passpoint" msgid="2826205693803088747">"%1$s経由で接続"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"%1$s経由で使用可能"</string>
- <string name="wifi_connected_no_internet" msgid="3149853966840874992">"接続先はインターネットに接続されていない"</string>
+ <string name="wifi_connected_no_internet" msgid="3149853966840874992">"接続済み、インターネットは利用できません"</string>
<string name="bluetooth_disconnected" msgid="6557104142667339895">"切断"</string>
<string name="bluetooth_disconnecting" msgid="8913264760027764974">"切断中..."</string>
<string name="bluetooth_connecting" msgid="8555009514614320497">"接続中..."</string>
@@ -77,16 +77,10 @@
<string name="bluetooth_pairing_pin_error_message" msgid="8337234855188925274">"PINまたはパスキーが正しくないため、<xliff:g id="DEVICE_NAME">%1$s</xliff:g>をペアに設定できませんでした。"</string>
<string name="bluetooth_pairing_device_down_error_message" msgid="7870998403045801381">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g>と通信できません。"</string>
<string name="bluetooth_pairing_rejected_error_message" msgid="1648157108520832454">"ペア設定が<xliff:g id="DEVICE_NAME">%1$s</xliff:g>に拒否されました。"</string>
- <!-- no translation found for accessibility_wifi_off (1166761729660614716) -->
- <skip />
- <!-- no translation found for accessibility_no_wifi (8834610636137374508) -->
- <skip />
- <!-- no translation found for accessibility_wifi_one_bar (4869376278894301820) -->
- <skip />
- <!-- no translation found for accessibility_wifi_two_bars (3569851234710034416) -->
- <skip />
- <!-- no translation found for accessibility_wifi_three_bars (8134185644861380311) -->
- <skip />
- <!-- no translation found for accessibility_wifi_signal_full (7061045677694702) -->
- <skip />
+ <string name="accessibility_wifi_off" msgid="1166761729660614716">"Wi-FiはOFFです。"</string>
+ <string name="accessibility_no_wifi" msgid="8834610636137374508">"Wi-Fiが切断されました。"</string>
+ <string name="accessibility_wifi_one_bar" msgid="4869376278894301820">"Wi-Fiはレベル1です。"</string>
+ <string name="accessibility_wifi_two_bars" msgid="3569851234710034416">"Wi-Fiはレベル2です。"</string>
+ <string name="accessibility_wifi_three_bars" msgid="8134185644861380311">"Wi-Fiはレベル3です。"</string>
+ <string name="accessibility_wifi_signal_full" msgid="7061045677694702">"Wi-Fiの電波はフルです。"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-ka-rGE/strings.xml b/packages/SettingsLib/res/values-ka-rGE/strings.xml
index 6f91f7a..046a062 100644
--- a/packages/SettingsLib/res/values-ka-rGE/strings.xml
+++ b/packages/SettingsLib/res/values-ka-rGE/strings.xml
@@ -77,16 +77,10 @@
<string name="bluetooth_pairing_pin_error_message" msgid="8337234855188925274">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g>-თან დაწყვილება ვერ მოხერხდა, რადგან PIN ან გასაღები არასწორია."</string>
<string name="bluetooth_pairing_device_down_error_message" msgid="7870998403045801381">"შეუძლებელია <xliff:g id="DEVICE_NAME">%1$s</xliff:g>-თან კომუნიკაცია."</string>
<string name="bluetooth_pairing_rejected_error_message" msgid="1648157108520832454">"დაწყვილება უარყოფილია <xliff:g id="DEVICE_NAME">%1$s</xliff:g>-ის მიერ."</string>
- <!-- no translation found for accessibility_wifi_off (1166761729660614716) -->
- <skip />
- <!-- no translation found for accessibility_no_wifi (8834610636137374508) -->
- <skip />
- <!-- no translation found for accessibility_wifi_one_bar (4869376278894301820) -->
- <skip />
- <!-- no translation found for accessibility_wifi_two_bars (3569851234710034416) -->
- <skip />
- <!-- no translation found for accessibility_wifi_three_bars (8134185644861380311) -->
- <skip />
- <!-- no translation found for accessibility_wifi_signal_full (7061045677694702) -->
- <skip />
+ <string name="accessibility_wifi_off" msgid="1166761729660614716">"WiFi გამორთულია."</string>
+ <string name="accessibility_no_wifi" msgid="8834610636137374508">"WiFi არ არის დაკავშირებული."</string>
+ <string name="accessibility_wifi_one_bar" msgid="4869376278894301820">"WiFi სიგნალი ერთ ზოლზეა."</string>
+ <string name="accessibility_wifi_two_bars" msgid="3569851234710034416">"WiFi სიგნალი ორ ზოლზეა."</string>
+ <string name="accessibility_wifi_three_bars" msgid="8134185644861380311">"WiFi სიგნალი სამ ზოლზეა."</string>
+ <string name="accessibility_wifi_signal_full" msgid="7061045677694702">"WiFi სიგნალი სრულია."</string>
</resources>
diff --git a/packages/SettingsLib/res/values-kk-rKZ/strings.xml b/packages/SettingsLib/res/values-kk-rKZ/strings.xml
index 0ec592d..4403526 100644
--- a/packages/SettingsLib/res/values-kk-rKZ/strings.xml
+++ b/packages/SettingsLib/res/values-kk-rKZ/strings.xml
@@ -77,16 +77,10 @@
<string name="bluetooth_pairing_pin_error_message" msgid="8337234855188925274">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> құрылғысымен жұптала алмады, себебі PIN немесе кілтсөз дұрыс емес."</string>
<string name="bluetooth_pairing_device_down_error_message" msgid="7870998403045801381">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> құрылғысымен қатынаса алмайды"</string>
<string name="bluetooth_pairing_rejected_error_message" msgid="1648157108520832454">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> құрылғысы жұпталудан бас тартты."</string>
- <!-- no translation found for accessibility_wifi_off (1166761729660614716) -->
- <skip />
- <!-- no translation found for accessibility_no_wifi (8834610636137374508) -->
- <skip />
- <!-- no translation found for accessibility_wifi_one_bar (4869376278894301820) -->
- <skip />
- <!-- no translation found for accessibility_wifi_two_bars (3569851234710034416) -->
- <skip />
- <!-- no translation found for accessibility_wifi_three_bars (8134185644861380311) -->
- <skip />
- <!-- no translation found for accessibility_wifi_signal_full (7061045677694702) -->
- <skip />
+ <string name="accessibility_wifi_off" msgid="1166761729660614716">"Wi-Fi өшірулі."</string>
+ <string name="accessibility_no_wifi" msgid="8834610636137374508">"Wi-Fi ажыратылған."</string>
+ <string name="accessibility_wifi_one_bar" msgid="4869376278894301820">"Wi-Fi сигналы — бір жолақ."</string>
+ <string name="accessibility_wifi_two_bars" msgid="3569851234710034416">"Wi-Fi сигналы — екі жолақ."</string>
+ <string name="accessibility_wifi_three_bars" msgid="8134185644861380311">"Wi-Fi сигналы — үш жолақ."</string>
+ <string name="accessibility_wifi_signal_full" msgid="7061045677694702">"Wi-Fi сигналы толық."</string>
</resources>
diff --git a/packages/SettingsLib/res/values-km-rKH/strings.xml b/packages/SettingsLib/res/values-km-rKH/strings.xml
index a7ba884..ed00f87 100644
--- a/packages/SettingsLib/res/values-km-rKH/strings.xml
+++ b/packages/SettingsLib/res/values-km-rKH/strings.xml
@@ -77,16 +77,10 @@
<string name="bluetooth_pairing_pin_error_message" msgid="8337234855188925274">"មិនអាចផ្គូផ្គងជាមួយ <xliff:g id="DEVICE_NAME">%1$s</xliff:g> ព្រោះកូដ PIN ឬលេខកូដមិនត្រឹមត្រូវ។"</string>
<string name="bluetooth_pairing_device_down_error_message" msgid="7870998403045801381">"មិនអាចទាក់ទងជាមួយ <xliff:g id="DEVICE_NAME">%1$s</xliff:g> ។"</string>
<string name="bluetooth_pairing_rejected_error_message" msgid="1648157108520832454">"ការផ្គូផ្គងបានបដិសេធដោយ <xliff:g id="DEVICE_NAME">%1$s</xliff:g> ។"</string>
- <!-- no translation found for accessibility_wifi_off (1166761729660614716) -->
- <skip />
- <!-- no translation found for accessibility_no_wifi (8834610636137374508) -->
- <skip />
- <!-- no translation found for accessibility_wifi_one_bar (4869376278894301820) -->
- <skip />
- <!-- no translation found for accessibility_wifi_two_bars (3569851234710034416) -->
- <skip />
- <!-- no translation found for accessibility_wifi_three_bars (8134185644861380311) -->
- <skip />
- <!-- no translation found for accessibility_wifi_signal_full (7061045677694702) -->
- <skip />
+ <string name="accessibility_wifi_off" msgid="1166761729660614716">"បានបិទ Wifi"</string>
+ <string name="accessibility_no_wifi" msgid="8834610636137374508">"បានផ្តាច់ Wifi"</string>
+ <string name="accessibility_wifi_one_bar" msgid="4869376278894301820">"Wifi មួយកាំ"</string>
+ <string name="accessibility_wifi_two_bars" msgid="3569851234710034416">"Wifi ពីរកាំ"</string>
+ <string name="accessibility_wifi_three_bars" msgid="8134185644861380311">"Wifi បីកាំ"</string>
+ <string name="accessibility_wifi_signal_full" msgid="7061045677694702">"សេវា Wifi ពេញ"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-kn-rIN/strings.xml b/packages/SettingsLib/res/values-kn-rIN/strings.xml
index 45417a7..3e1d94d 100644
--- a/packages/SettingsLib/res/values-kn-rIN/strings.xml
+++ b/packages/SettingsLib/res/values-kn-rIN/strings.xml
@@ -77,16 +77,10 @@
<string name="bluetooth_pairing_pin_error_message" msgid="8337234855188925274">"ತಪ್ಪಾಗಿರುವ ಪಿನ್ ಅಥವಾ ಪಾಸ್ಕೀ ಕಾರಣದಿಂದಾಗಿ <xliff:g id="DEVICE_NAME">%1$s</xliff:g> ಜೊತೆಗೆ ಜೋಡಿಸಲು ಸಾಧ್ಯವಾಗಲಿಲ್ಲ."</string>
<string name="bluetooth_pairing_device_down_error_message" msgid="7870998403045801381">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> ಜೊತೆಗೆ ಸಂವಹನ ನಡೆಸಲು ಸಾಧ್ಯವಿಲ್ಲ"</string>
<string name="bluetooth_pairing_rejected_error_message" msgid="1648157108520832454">"ಜೋಡಿಸುವಿಕೆಯನ್ನು <xliff:g id="DEVICE_NAME">%1$s</xliff:g> ತಿರಸ್ಕರಿಸಿದೆ"</string>
- <!-- no translation found for accessibility_wifi_off (1166761729660614716) -->
- <skip />
- <!-- no translation found for accessibility_no_wifi (8834610636137374508) -->
- <skip />
- <!-- no translation found for accessibility_wifi_one_bar (4869376278894301820) -->
- <skip />
- <!-- no translation found for accessibility_wifi_two_bars (3569851234710034416) -->
- <skip />
- <!-- no translation found for accessibility_wifi_three_bars (8134185644861380311) -->
- <skip />
- <!-- no translation found for accessibility_wifi_signal_full (7061045677694702) -->
- <skip />
+ <string name="accessibility_wifi_off" msgid="1166761729660614716">"ವೈಫೈ ಆಫ್."</string>
+ <string name="accessibility_no_wifi" msgid="8834610636137374508">"ವೈಫೈ ಸಂಪರ್ಕ ಕಡಿತಗೊಂಡಿದೆ."</string>
+ <string name="accessibility_wifi_one_bar" msgid="4869376278894301820">"ವೈಫೈ ಒಂದು ಪಟ್ಟಿ."</string>
+ <string name="accessibility_wifi_two_bars" msgid="3569851234710034416">"ವೈಫೈ ಎರಡು ಪಟ್ಟಿಗಳು."</string>
+ <string name="accessibility_wifi_three_bars" msgid="8134185644861380311">"ವೈಫೈ ಮೂರು ಪಟ್ಟಿಗಳು."</string>
+ <string name="accessibility_wifi_signal_full" msgid="7061045677694702">"ವೈಫೈ ಸಿಗ್ನಲ್ ಪೂರ್ತಿ ಇದೆ."</string>
</resources>
diff --git a/packages/SettingsLib/res/values-ko/strings.xml b/packages/SettingsLib/res/values-ko/strings.xml
index 99413ad..2f78a90 100644
--- a/packages/SettingsLib/res/values-ko/strings.xml
+++ b/packages/SettingsLib/res/values-ko/strings.xml
@@ -77,16 +77,10 @@
<string name="bluetooth_pairing_pin_error_message" msgid="8337234855188925274">"PIN 또는 패스키가 잘못되어 <xliff:g id="DEVICE_NAME">%1$s</xliff:g>와(과) 페어링하지 못했습니다."</string>
<string name="bluetooth_pairing_device_down_error_message" msgid="7870998403045801381">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g>와(과) 통신할 수 없습니다."</string>
<string name="bluetooth_pairing_rejected_error_message" msgid="1648157108520832454">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g>에서 페어링을 거부했습니다."</string>
- <!-- no translation found for accessibility_wifi_off (1166761729660614716) -->
- <skip />
- <!-- no translation found for accessibility_no_wifi (8834610636137374508) -->
- <skip />
- <!-- no translation found for accessibility_wifi_one_bar (4869376278894301820) -->
- <skip />
- <!-- no translation found for accessibility_wifi_two_bars (3569851234710034416) -->
- <skip />
- <!-- no translation found for accessibility_wifi_three_bars (8134185644861380311) -->
- <skip />
- <!-- no translation found for accessibility_wifi_signal_full (7061045677694702) -->
- <skip />
+ <string name="accessibility_wifi_off" msgid="1166761729660614716">"Wi-Fi가 꺼져 있습니다."</string>
+ <string name="accessibility_no_wifi" msgid="8834610636137374508">"Wi-Fi 연결이 끊어졌습니다."</string>
+ <string name="accessibility_wifi_one_bar" msgid="4869376278894301820">"Wi-Fi 신호 막대가 한 개입니다."</string>
+ <string name="accessibility_wifi_two_bars" msgid="3569851234710034416">"Wi-Fi 신호 막대가 두 개입니다."</string>
+ <string name="accessibility_wifi_three_bars" msgid="8134185644861380311">"Wi-Fi 신호 막대가 세 개입니다."</string>
+ <string name="accessibility_wifi_signal_full" msgid="7061045677694702">"Wi-Fi 신호가 강합니다."</string>
</resources>
diff --git a/packages/SettingsLib/res/values-ky-rKG/arrays.xml b/packages/SettingsLib/res/values-ky-rKG/arrays.xml
new file mode 100644
index 0000000..207dea1
--- /dev/null
+++ b/packages/SettingsLib/res/values-ky-rKG/arrays.xml
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/*
+**
+** Copyright 2015 The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="wifi_status">
+ <item msgid="1922181315419294640"></item>
+ <item msgid="8934131797783724664">"Скандалууда…"</item>
+ <item msgid="8513729475867537913">"Туташууда…"</item>
+ <item msgid="515055375277271756">"Аныктыгы текшерилүүдө…"</item>
+ <item msgid="1943354004029184381">"IP дареги алынууда…"</item>
+ <item msgid="4221763391123233270">"Туташып турат"</item>
+ <item msgid="624838831631122137">"Убактылуу токтотулду"</item>
+ <item msgid="7979680559596111948">"Ажыратылууда…"</item>
+ <item msgid="1634960474403853625">"Ажыратылды"</item>
+ <item msgid="746097431216080650">"Ийгиликсиз"</item>
+ <item msgid="6367044185730295334">"Бөгөттөлгөн"</item>
+ <item msgid="503942654197908005">"Начар байланыштан убактылуу баш тартууда"</item>
+ </string-array>
+ <string-array name="wifi_status_with_ssid">
+ <item msgid="7714855332363650812"></item>
+ <item msgid="8878186979715711006">"Скандалууда…"</item>
+ <item msgid="355508996603873860">"<xliff:g id="NETWORK_NAME">%1$s</xliff:g> тармагына туташууда…"</item>
+ <item msgid="554971459996405634">"<xliff:g id="NETWORK_NAME">%1$s</xliff:g> менен аныктыгы текшерилүүдө…"</item>
+ <item msgid="7928343808033020343">"<xliff:g id="NETWORK_NAME">%1$s</xliff:g> тармагынан IP дареги алынууда…"</item>
+ <item msgid="8937994881315223448">"<xliff:g id="NETWORK_NAME">%1$s</xliff:g> тармагына туташты"</item>
+ <item msgid="1330262655415760617">"Убактылуу токтотулду"</item>
+ <item msgid="7698638434317271902">"<xliff:g id="NETWORK_NAME">%1$s</xliff:g> тармагынан ажыратылууда…"</item>
+ <item msgid="197508606402264311">"Ажыратылды"</item>
+ <item msgid="8578370891960825148">"Ийгиликсиз"</item>
+ <item msgid="5660739516542454527">"Бөгөттөлгөн"</item>
+ <item msgid="1805837518286731242">"Начар байланыштан убактылуу баш тартууда"</item>
+ </string-array>
+</resources>
diff --git a/packages/SettingsLib/res/values-ky-rKG/strings.xml b/packages/SettingsLib/res/values-ky-rKG/strings.xml
index 2c22948..cb70c6c 100644
--- a/packages/SettingsLib/res/values-ky-rKG/strings.xml
+++ b/packages/SettingsLib/res/values-ky-rKG/strings.xml
@@ -27,24 +27,18 @@
<string name="wifi_disabled_network_failure" msgid="2364951338436007124">"IP конфигурациясы бузулду"</string>
<string name="wifi_disabled_wifi_failure" msgid="3081668066612876581">"WiFi туташуусу бузулду"</string>
<string name="wifi_disabled_password_failure" msgid="8659805351763133575">"Аутентификация маселеси бар"</string>
- <!-- no translation found for wifi_not_in_range (1136191511238508967) -->
- <skip />
+ <string name="wifi_not_in_range" msgid="1136191511238508967">"Тейлөө аймагында эмес"</string>
<string name="wifi_no_internet" msgid="9151470775868728896">"Интернетке кирүү мүмкүнчүлүгү табылган жок, андыктан автоматтык түрдө кайра туташпайт."</string>
<string name="saved_network" msgid="4352716707126620811">"<xliff:g id="NAME">%1$s</xliff:g> тарабынан сакталды"</string>
<string name="connected_via_wfa" msgid="3805736726317410714">"Wi‑Fi жардамчысы аркылуу туташып турат"</string>
<string name="connected_via_passpoint" msgid="2826205693803088747">"%1$s аркылуу жеткиликтүү"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"%1$s аркылуу жеткиликтүү"</string>
<string name="wifi_connected_no_internet" msgid="3149853966840874992">"Туташып турат, Интернет жок"</string>
- <!-- no translation found for bluetooth_disconnected (6557104142667339895) -->
- <skip />
- <!-- no translation found for bluetooth_disconnecting (8913264760027764974) -->
- <skip />
- <!-- no translation found for bluetooth_connecting (8555009514614320497) -->
- <skip />
- <!-- no translation found for bluetooth_connected (6038755206916626419) -->
- <skip />
- <!-- no translation found for bluetooth_pairing (1426882272690346242) -->
- <skip />
+ <string name="bluetooth_disconnected" msgid="6557104142667339895">"Ажыратылды"</string>
+ <string name="bluetooth_disconnecting" msgid="8913264760027764974">"Ажыратылууда…"</string>
+ <string name="bluetooth_connecting" msgid="8555009514614320497">"Туташууда…"</string>
+ <string name="bluetooth_connected" msgid="6038755206916626419">"Туташып турат"</string>
+ <string name="bluetooth_pairing" msgid="1426882272690346242">"Жупташтырылууда…"</string>
<string name="bluetooth_connected_no_headset" msgid="2866994875046035609">"Туташып турат (телефониясыз)"</string>
<string name="bluetooth_connected_no_a2dp" msgid="4576188601581440337">"Туташып турат (медиасыз)"</string>
<string name="bluetooth_connected_no_map" msgid="6504436917057479986">"Байланышта (билдирүү алмашуу жок)"</string>
@@ -53,61 +47,40 @@
<string name="bluetooth_profile_headset" msgid="8658779596261212609">"Телефон"</string>
<string name="bluetooth_profile_opp" msgid="9168139293654233697">"Файл алмашуу"</string>
<string name="bluetooth_profile_hid" msgid="3680729023366986480">"Киргизүү түзмөгү"</string>
- <!-- no translation found for bluetooth_profile_pan (3391606497945147673) -->
- <skip />
+ <string name="bluetooth_profile_pan" msgid="3391606497945147673">"Интернетке мүмкүнчүлүк алуу"</string>
<string name="bluetooth_profile_pbap" msgid="5372051906968576809">"Байланышты бөлүшүү"</string>
<string name="bluetooth_profile_pbap_summary" msgid="6605229608108852198">"Байланышты бөлүшүү үчүн колдонуу"</string>
<string name="bluetooth_profile_pan_nap" msgid="8429049285027482959">"Интернет байланышын бөлүшүү"</string>
<string name="bluetooth_profile_map" msgid="5465271250454324383">"Билдирүү алмашуу"</string>
<string name="bluetooth_profile_sap" msgid="5764222021851283125">"SIM картаны пайдалануу мүмкүнчүлүгү"</string>
- <!-- no translation found for bluetooth_a2dp_profile_summary_connected (963376081347721598) -->
- <skip />
- <!-- no translation found for bluetooth_headset_profile_summary_connected (7661070206715520671) -->
- <skip />
- <!-- no translation found for bluetooth_opp_profile_summary_connected (2611913495968309066) -->
- <skip />
+ <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"Медиа аудиого туташты"</string>
+ <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"Телефон аудиосуна туташты"</string>
+ <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"Файл өткөрүү серверине туташты"</string>
<string name="bluetooth_map_profile_summary_connected" msgid="8191407438851351713">"MAP\'ка байланышты"</string>
<string name="bluetooth_sap_profile_summary_connected" msgid="8561765057453083838">"SAP\'ка туташып турат"</string>
- <!-- no translation found for bluetooth_opp_profile_summary_not_connected (1267091356089086285) -->
- <skip />
- <!-- no translation found for bluetooth_hid_profile_summary_connected (3381760054215168689) -->
- <skip />
- <!-- no translation found for bluetooth_pan_user_profile_summary_connected (4602294638909590612) -->
- <skip />
- <!-- no translation found for bluetooth_pan_nap_profile_summary_connected (1561383706411975199) -->
- <skip />
- <!-- no translation found for bluetooth_pan_profile_summary_use_for (5664884523822068653) -->
- <skip />
+ <string name="bluetooth_opp_profile_summary_not_connected" msgid="1267091356089086285">"Файл өткөрүү серверине туташкан жок"</string>
+ <string name="bluetooth_hid_profile_summary_connected" msgid="3381760054215168689">"Киргизүү түзмөгүнө туташты"</string>
+ <string name="bluetooth_pan_user_profile_summary_connected" msgid="4602294638909590612">"Интернетке мүмкүнчүлүк алуу үчүн түзмөккө туташты"</string>
+ <string name="bluetooth_pan_nap_profile_summary_connected" msgid="1561383706411975199">"Жергиликтүү Интернет туташуусу түзмөк менен бөлүшүлүүдө"</string>
+ <string name="bluetooth_pan_profile_summary_use_for" msgid="5664884523822068653">"Интернетке мүмкүнчүлүк алуу үчүн колдонулсун"</string>
<string name="bluetooth_map_profile_summary_use_for" msgid="5154200119919927434">"MAP үчүн колдонуу"</string>
<string name="bluetooth_sap_profile_summary_use_for" msgid="7085362712786907993">"SIM картаны пайдалануу үчүн колдонуу"</string>
- <!-- no translation found for bluetooth_a2dp_profile_summary_use_for (4630849022250168427) -->
- <skip />
- <!-- no translation found for bluetooth_headset_profile_summary_use_for (8705753622443862627) -->
- <skip />
- <!-- no translation found for bluetooth_opp_profile_summary_use_for (1255674547144769756) -->
- <skip />
- <!-- no translation found for bluetooth_hid_profile_summary_use_for (232727040453645139) -->
- <skip />
- <!-- no translation found for bluetooth_pairing_accept (6163520056536604875) -->
- <skip />
+ <string name="bluetooth_a2dp_profile_summary_use_for" msgid="4630849022250168427">"Медиа аудио үчүн колдонуу"</string>
+ <string name="bluetooth_headset_profile_summary_use_for" msgid="8705753622443862627">"Телефон аудиосу үчүн колдонулсун"</string>
+ <string name="bluetooth_opp_profile_summary_use_for" msgid="1255674547144769756">"Файл өткөрүү үчүн колдонулсун"</string>
+ <string name="bluetooth_hid_profile_summary_use_for" msgid="232727040453645139">"Киргизүү үчүн колдонулсун"</string>
+ <string name="bluetooth_pairing_accept" msgid="6163520056536604875">"Жупташтыруу"</string>
<string name="bluetooth_pairing_accept_all_caps" msgid="6061699265220789149">"ЖУПТАШТЫРУУ"</string>
<string name="bluetooth_pairing_decline" msgid="4185420413578948140">"Баш тартуу"</string>
<string name="bluetooth_pairing_will_share_phonebook" msgid="4982239145676394429">"Жупташканда байланыштарыңыз менен чалуу таржымалыңызды пайдалана аласыз."</string>
<string name="bluetooth_pairing_error_message" msgid="3748157733635947087">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> менен жупташуу мүмкүн эмес."</string>
<string name="bluetooth_pairing_pin_error_message" msgid="8337234855188925274">"PIN же код туура эмес болгондуктан <xliff:g id="DEVICE_NAME">%1$s</xliff:g> туташуу мүмкүн эмес."</string>
<string name="bluetooth_pairing_device_down_error_message" msgid="7870998403045801381">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> менен байланышуу мүмкүн эмес."</string>
- <!-- no translation found for bluetooth_pairing_rejected_error_message (1648157108520832454) -->
- <skip />
- <!-- no translation found for accessibility_wifi_off (1166761729660614716) -->
- <skip />
- <!-- no translation found for accessibility_no_wifi (8834610636137374508) -->
- <skip />
- <!-- no translation found for accessibility_wifi_one_bar (4869376278894301820) -->
- <skip />
- <!-- no translation found for accessibility_wifi_two_bars (3569851234710034416) -->
- <skip />
- <!-- no translation found for accessibility_wifi_three_bars (8134185644861380311) -->
- <skip />
- <!-- no translation found for accessibility_wifi_signal_full (7061045677694702) -->
- <skip />
+ <string name="bluetooth_pairing_rejected_error_message" msgid="1648157108520832454">"Жупташтырууну <xliff:g id="DEVICE_NAME">%1$s</xliff:g> четке какты."</string>
+ <string name="accessibility_wifi_off" msgid="1166761729660614716">"Wifi өчүк."</string>
+ <string name="accessibility_no_wifi" msgid="8834610636137374508">"Wifi туташуусу жок."</string>
+ <string name="accessibility_wifi_one_bar" msgid="4869376278894301820">"Wifi: бир таякча."</string>
+ <string name="accessibility_wifi_two_bars" msgid="3569851234710034416">"Wifi: эки таякча."</string>
+ <string name="accessibility_wifi_three_bars" msgid="8134185644861380311">"Wifi: үч таякча."</string>
+ <string name="accessibility_wifi_signal_full" msgid="7061045677694702">"Wifi: күчтүү сигнал."</string>
</resources>
diff --git a/packages/SettingsLib/res/values-lo-rLA/strings.xml b/packages/SettingsLib/res/values-lo-rLA/strings.xml
index c77170a..37d7bef 100644
--- a/packages/SettingsLib/res/values-lo-rLA/strings.xml
+++ b/packages/SettingsLib/res/values-lo-rLA/strings.xml
@@ -77,16 +77,10 @@
<string name="bluetooth_pairing_pin_error_message" msgid="8337234855188925274">"ບໍ່ສາມາດຈັບຄູ່ກັບ <xliff:g id="DEVICE_NAME">%1$s</xliff:g> ໄດ້ ເພາະ PIN ຫຼື passkey ບໍ່ຖືກຕ້ອງ."</string>
<string name="bluetooth_pairing_device_down_error_message" msgid="7870998403045801381">"ບໍ່ສາມາດຕິດຕໍ່ສື່ສານກັບ <xliff:g id="DEVICE_NAME">%1$s</xliff:g> ໄດ້."</string>
<string name="bluetooth_pairing_rejected_error_message" msgid="1648157108520832454">"ການຈັບຄູ່ຖືກປະຕິເສດໂດຍ <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
- <!-- no translation found for accessibility_wifi_off (1166761729660614716) -->
- <skip />
- <!-- no translation found for accessibility_no_wifi (8834610636137374508) -->
- <skip />
- <!-- no translation found for accessibility_wifi_one_bar (4869376278894301820) -->
- <skip />
- <!-- no translation found for accessibility_wifi_two_bars (3569851234710034416) -->
- <skip />
- <!-- no translation found for accessibility_wifi_three_bars (8134185644861380311) -->
- <skip />
- <!-- no translation found for accessibility_wifi_signal_full (7061045677694702) -->
- <skip />
+ <string name="accessibility_wifi_off" msgid="1166761729660614716">"WiFi ປິດຢູ່."</string>
+ <string name="accessibility_no_wifi" msgid="8834610636137374508">"ຕັດການເຊື່ອມຕໍ່ Wi-Fi ແລ້ວ."</string>
+ <string name="accessibility_wifi_one_bar" msgid="4869376278894301820">"ສັນຍານ Wi-Fi ນຶ່ງຂີດ."</string>
+ <string name="accessibility_wifi_two_bars" msgid="3569851234710034416">"ສັນຍານ Wi-Fi ສອງຂີດ."</string>
+ <string name="accessibility_wifi_three_bars" msgid="8134185644861380311">"Wifi ສາມຂີດ."</string>
+ <string name="accessibility_wifi_signal_full" msgid="7061045677694702">"ສັນຍານ Wi-Fi ເຕັມ"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-lt/strings.xml b/packages/SettingsLib/res/values-lt/strings.xml
index 850697e..57dd5a6 100644
--- a/packages/SettingsLib/res/values-lt/strings.xml
+++ b/packages/SettingsLib/res/values-lt/strings.xml
@@ -77,16 +77,10 @@
<string name="bluetooth_pairing_pin_error_message" msgid="8337234855188925274">"Nepavyko susieti su „<xliff:g id="DEVICE_NAME">%1$s</xliff:g>“ dėl netinkamo PIN kodo ar prieigos rakto."</string>
<string name="bluetooth_pairing_device_down_error_message" msgid="7870998403045801381">"Nepavyksta užmegzti ryšio su „<xliff:g id="DEVICE_NAME">%1$s</xliff:g>“."</string>
<string name="bluetooth_pairing_rejected_error_message" msgid="1648157108520832454">"Susiejimą atmetė <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
- <!-- no translation found for accessibility_wifi_off (1166761729660614716) -->
- <skip />
- <!-- no translation found for accessibility_no_wifi (8834610636137374508) -->
- <skip />
- <!-- no translation found for accessibility_wifi_one_bar (4869376278894301820) -->
- <skip />
- <!-- no translation found for accessibility_wifi_two_bars (3569851234710034416) -->
- <skip />
- <!-- no translation found for accessibility_wifi_three_bars (8134185644861380311) -->
- <skip />
- <!-- no translation found for accessibility_wifi_signal_full (7061045677694702) -->
- <skip />
+ <string name="accessibility_wifi_off" msgid="1166761729660614716">"„Wi-Fi“ išjungtas."</string>
+ <string name="accessibility_no_wifi" msgid="8834610636137374508">"„Wi-Fi“ atjungtas."</string>
+ <string name="accessibility_wifi_one_bar" msgid="4869376278894301820">"Viena „Wi-Fi“ signalo juosta."</string>
+ <string name="accessibility_wifi_two_bars" msgid="3569851234710034416">"Dvi „Wi-Fi“ signalo juostos."</string>
+ <string name="accessibility_wifi_three_bars" msgid="8134185644861380311">"Trys „Wi-Fi“ signalo juostos."</string>
+ <string name="accessibility_wifi_signal_full" msgid="7061045677694702">"Stiprus „Wi-Fi“ signalas."</string>
</resources>
diff --git a/packages/SettingsLib/res/values-lv/strings.xml b/packages/SettingsLib/res/values-lv/strings.xml
index 4165f485..725da49 100644
--- a/packages/SettingsLib/res/values-lv/strings.xml
+++ b/packages/SettingsLib/res/values-lv/strings.xml
@@ -77,16 +77,10 @@
<string name="bluetooth_pairing_pin_error_message" msgid="8337234855188925274">"Nevarēja savienot pārī ar ierīci <xliff:g id="DEVICE_NAME">%1$s</xliff:g>, jo tika ievadīts nepareizs PIN kods vai nepareiza ieejas atslēga."</string>
<string name="bluetooth_pairing_device_down_error_message" msgid="7870998403045801381">"Nevar sazināties ar ierīci <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
<string name="bluetooth_pairing_rejected_error_message" msgid="1648157108520832454">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> noraidīja pāra izveidi."</string>
- <!-- no translation found for accessibility_wifi_off (1166761729660614716) -->
- <skip />
- <!-- no translation found for accessibility_no_wifi (8834610636137374508) -->
- <skip />
- <!-- no translation found for accessibility_wifi_one_bar (4869376278894301820) -->
- <skip />
- <!-- no translation found for accessibility_wifi_two_bars (3569851234710034416) -->
- <skip />
- <!-- no translation found for accessibility_wifi_three_bars (8134185644861380311) -->
- <skip />
- <!-- no translation found for accessibility_wifi_signal_full (7061045677694702) -->
- <skip />
+ <string name="accessibility_wifi_off" msgid="1166761729660614716">"Wi-Fi savienojums izslēgts"</string>
+ <string name="accessibility_no_wifi" msgid="8834610636137374508">"Wi-Fi savienojums pārtraukts"</string>
+ <string name="accessibility_wifi_one_bar" msgid="4869376278894301820">"Wi-Fi: viena josla"</string>
+ <string name="accessibility_wifi_two_bars" msgid="3569851234710034416">"Wi-Fi: divas joslas"</string>
+ <string name="accessibility_wifi_three_bars" msgid="8134185644861380311">"Wi-Fi: trīs joslas"</string>
+ <string name="accessibility_wifi_signal_full" msgid="7061045677694702">"Pilna piekļuve Wi-Fi signālam"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-mk-rMK/strings.xml b/packages/SettingsLib/res/values-mk-rMK/strings.xml
index b1d9e80..52688e3 100644
--- a/packages/SettingsLib/res/values-mk-rMK/strings.xml
+++ b/packages/SettingsLib/res/values-mk-rMK/strings.xml
@@ -77,16 +77,10 @@
<string name="bluetooth_pairing_pin_error_message" msgid="8337234855188925274">"Не можеше да се спари со <xliff:g id="DEVICE_NAME">%1$s</xliff:g> поради погрешен ПИН или лозинка."</string>
<string name="bluetooth_pairing_device_down_error_message" msgid="7870998403045801381">"Не може да комуницира со <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
<string name="bluetooth_pairing_rejected_error_message" msgid="1648157108520832454">"Спарувањето е одбиено од <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
- <!-- no translation found for accessibility_wifi_off (1166761729660614716) -->
- <skip />
- <!-- no translation found for accessibility_no_wifi (8834610636137374508) -->
- <skip />
- <!-- no translation found for accessibility_wifi_one_bar (4869376278894301820) -->
- <skip />
- <!-- no translation found for accessibility_wifi_two_bars (3569851234710034416) -->
- <skip />
- <!-- no translation found for accessibility_wifi_three_bars (8134185644861380311) -->
- <skip />
- <!-- no translation found for accessibility_wifi_signal_full (7061045677694702) -->
- <skip />
+ <string name="accessibility_wifi_off" msgid="1166761729660614716">"Wi-Fi е исклучено."</string>
+ <string name="accessibility_no_wifi" msgid="8834610636137374508">"Wi-Fi е исклучено."</string>
+ <string name="accessibility_wifi_one_bar" msgid="4869376278894301820">"Една црта на Wi-Fi."</string>
+ <string name="accessibility_wifi_two_bars" msgid="3569851234710034416">"Две црти на Wi-Fi."</string>
+ <string name="accessibility_wifi_three_bars" msgid="8134185644861380311">"Три црти на Wi-Fi."</string>
+ <string name="accessibility_wifi_signal_full" msgid="7061045677694702">"Полн сигнал на Wi-Fi."</string>
</resources>
diff --git a/packages/SettingsLib/res/values-ml-rIN/strings.xml b/packages/SettingsLib/res/values-ml-rIN/strings.xml
index 157755d..44a3501 100644
--- a/packages/SettingsLib/res/values-ml-rIN/strings.xml
+++ b/packages/SettingsLib/res/values-ml-rIN/strings.xml
@@ -77,16 +77,10 @@
<string name="bluetooth_pairing_pin_error_message" msgid="8337234855188925274">"ഒരു തെറ്റായ പിൻ അല്ലെങ്കിൽ പാസ്കീ കാരണം <xliff:g id="DEVICE_NAME">%1$s</xliff:g> എന്നതുമായി ജോടിയാക്കാനായില്ല."</string>
<string name="bluetooth_pairing_device_down_error_message" msgid="7870998403045801381">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> എന്നതുമായി ആശയവിനിമയം നടത്താനായില്ല."</string>
<string name="bluetooth_pairing_rejected_error_message" msgid="1648157108520832454">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g>, ജോടിയാക്കൽ നിരസിച്ചു."</string>
- <!-- no translation found for accessibility_wifi_off (1166761729660614716) -->
- <skip />
- <!-- no translation found for accessibility_no_wifi (8834610636137374508) -->
- <skip />
- <!-- no translation found for accessibility_wifi_one_bar (4869376278894301820) -->
- <skip />
- <!-- no translation found for accessibility_wifi_two_bars (3569851234710034416) -->
- <skip />
- <!-- no translation found for accessibility_wifi_three_bars (8134185644861380311) -->
- <skip />
- <!-- no translation found for accessibility_wifi_signal_full (7061045677694702) -->
- <skip />
+ <string name="accessibility_wifi_off" msgid="1166761729660614716">"വൈഫൈ ഓഫാണ്."</string>
+ <string name="accessibility_no_wifi" msgid="8834610636137374508">"വൈഫൈ വിച്ഛേദിച്ചു."</string>
+ <string name="accessibility_wifi_one_bar" msgid="4869376278894301820">"വൈഫൈ സിഗ്നൽ ഒരു ബാർ."</string>
+ <string name="accessibility_wifi_two_bars" msgid="3569851234710034416">"വൈഫൈ സിഗ്നൽ രണ്ട് ബാറുകൾ."</string>
+ <string name="accessibility_wifi_three_bars" msgid="8134185644861380311">"വൈഫൈ സിഗ്നൽ മൂന്ന് ബാറുകൾ."</string>
+ <string name="accessibility_wifi_signal_full" msgid="7061045677694702">"വൈഫൈ മികച്ച സിഗ്നൽ."</string>
</resources>
diff --git a/packages/SettingsLib/res/values-mn-rMN/strings.xml b/packages/SettingsLib/res/values-mn-rMN/strings.xml
index 8b854de..968ca1c 100644
--- a/packages/SettingsLib/res/values-mn-rMN/strings.xml
+++ b/packages/SettingsLib/res/values-mn-rMN/strings.xml
@@ -77,16 +77,10 @@
<string name="bluetooth_pairing_pin_error_message" msgid="8337234855188925274">"Буруу PIN эсхүл дамжих түлхүүрээс шалтгаалан <xliff:g id="DEVICE_NAME">%1$s</xliff:g>-тай хослуулж чадсангүй."</string>
<string name="bluetooth_pairing_device_down_error_message" msgid="7870998403045801381">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g>-тай холбоо барих боломжгүй."</string>
<string name="bluetooth_pairing_rejected_error_message" msgid="1648157108520832454">"Хослуулахаас <xliff:g id="DEVICE_NAME">%1$s</xliff:g> татгалзсан."</string>
- <!-- no translation found for accessibility_wifi_off (1166761729660614716) -->
- <skip />
- <!-- no translation found for accessibility_no_wifi (8834610636137374508) -->
- <skip />
- <!-- no translation found for accessibility_wifi_one_bar (4869376278894301820) -->
- <skip />
- <!-- no translation found for accessibility_wifi_two_bars (3569851234710034416) -->
- <skip />
- <!-- no translation found for accessibility_wifi_three_bars (8134185644861380311) -->
- <skip />
- <!-- no translation found for accessibility_wifi_signal_full (7061045677694702) -->
- <skip />
+ <string name="accessibility_wifi_off" msgid="1166761729660614716">"Wifi унтраалттай байна."</string>
+ <string name="accessibility_no_wifi" msgid="8834610636137374508">"Wifi холбогдоогүй байна."</string>
+ <string name="accessibility_wifi_one_bar" msgid="4869376278894301820">"Wifi сүлжээний дохио нэг баганатай байна."</string>
+ <string name="accessibility_wifi_two_bars" msgid="3569851234710034416">"Wifi сүлжээний дохио хоёр баганатай байна."</string>
+ <string name="accessibility_wifi_three_bars" msgid="8134185644861380311">"Wifi сүлжээний дохио гурван баганатай байна."</string>
+ <string name="accessibility_wifi_signal_full" msgid="7061045677694702">"Wifi-н дохио дүүрэн байна."</string>
</resources>
diff --git a/packages/SettingsLib/res/values-mr-rIN/strings.xml b/packages/SettingsLib/res/values-mr-rIN/strings.xml
index 86b4c51..e9eb637 100644
--- a/packages/SettingsLib/res/values-mr-rIN/strings.xml
+++ b/packages/SettingsLib/res/values-mr-rIN/strings.xml
@@ -77,16 +77,10 @@
<string name="bluetooth_pairing_pin_error_message" msgid="8337234855188925274">"अयोग्य पिन किंवा पासकीमुळे <xliff:g id="DEVICE_NAME">%1$s</xliff:g> सह जोडू शकलो नाही."</string>
<string name="bluetooth_pairing_device_down_error_message" msgid="7870998403045801381">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> शी संप्रेषण करू शकत नाही."</string>
<string name="bluetooth_pairing_rejected_error_message" msgid="1648157108520832454">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> द्वारे जोडणी नाकारली."</string>
- <!-- no translation found for accessibility_wifi_off (1166761729660614716) -->
- <skip />
- <!-- no translation found for accessibility_no_wifi (8834610636137374508) -->
- <skip />
- <!-- no translation found for accessibility_wifi_one_bar (4869376278894301820) -->
- <skip />
- <!-- no translation found for accessibility_wifi_two_bars (3569851234710034416) -->
- <skip />
- <!-- no translation found for accessibility_wifi_three_bars (8134185644861380311) -->
- <skip />
- <!-- no translation found for accessibility_wifi_signal_full (7061045677694702) -->
- <skip />
+ <string name="accessibility_wifi_off" msgid="1166761729660614716">"वाय फाय बंद."</string>
+ <string name="accessibility_no_wifi" msgid="8834610636137374508">"वाय फाय डिस्कनेक्ट झाले."</string>
+ <string name="accessibility_wifi_one_bar" msgid="4869376278894301820">"वाय फाय एक बार."</string>
+ <string name="accessibility_wifi_two_bars" msgid="3569851234710034416">"वाय फाय दोन बार."</string>
+ <string name="accessibility_wifi_three_bars" msgid="8134185644861380311">"वाय फाय तीन बार."</string>
+ <string name="accessibility_wifi_signal_full" msgid="7061045677694702">"वाय फाय सिग्नल संपूर्ण आहे."</string>
</resources>
diff --git a/packages/SettingsLib/res/values-ms-rMY/strings.xml b/packages/SettingsLib/res/values-ms-rMY/strings.xml
index e6afd7e..af2e234 100644
--- a/packages/SettingsLib/res/values-ms-rMY/strings.xml
+++ b/packages/SettingsLib/res/values-ms-rMY/strings.xml
@@ -77,16 +77,10 @@
<string name="bluetooth_pairing_pin_error_message" msgid="8337234855188925274">"Tidak dapat berpasangan dengan <xliff:g id="DEVICE_NAME">%1$s</xliff:g> kerana PIN atau kunci laluan yang salah."</string>
<string name="bluetooth_pairing_device_down_error_message" msgid="7870998403045801381">"Tidak boleh berkomunikasi dengan <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
<string name="bluetooth_pairing_rejected_error_message" msgid="1648157108520832454">"Pasangan ditolak oleh <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
- <!-- no translation found for accessibility_wifi_off (1166761729660614716) -->
- <skip />
- <!-- no translation found for accessibility_no_wifi (8834610636137374508) -->
- <skip />
- <!-- no translation found for accessibility_wifi_one_bar (4869376278894301820) -->
- <skip />
- <!-- no translation found for accessibility_wifi_two_bars (3569851234710034416) -->
- <skip />
- <!-- no translation found for accessibility_wifi_three_bars (8134185644861380311) -->
- <skip />
- <!-- no translation found for accessibility_wifi_signal_full (7061045677694702) -->
- <skip />
+ <string name="accessibility_wifi_off" msgid="1166761729660614716">"Wi-Fi dimatikan."</string>
+ <string name="accessibility_no_wifi" msgid="8834610636137374508">"Wi-Fi diputuskan sambungannya."</string>
+ <string name="accessibility_wifi_one_bar" msgid="4869376278894301820">"Wi-Fi satu bar."</string>
+ <string name="accessibility_wifi_two_bars" msgid="3569851234710034416">"Wi-Fi dua bar."</string>
+ <string name="accessibility_wifi_three_bars" msgid="8134185644861380311">"Wi-Fi tiga bar."</string>
+ <string name="accessibility_wifi_signal_full" msgid="7061045677694702">"Isyarat Wi-Fi penuh."</string>
</resources>
diff --git a/packages/SettingsLib/res/values-my-rMM/strings.xml b/packages/SettingsLib/res/values-my-rMM/strings.xml
index a5aa3a5..32d31ca 100644
--- a/packages/SettingsLib/res/values-my-rMM/strings.xml
+++ b/packages/SettingsLib/res/values-my-rMM/strings.xml
@@ -77,16 +77,10 @@
<string name="bluetooth_pairing_pin_error_message" msgid="8337234855188925274">"ပင်နံပါတ် သို့မဟုတ် ဖြတ်သန်းခွင့်ကီးမမှန်ကန်သောကြောင့်<xliff:g id="DEVICE_NAME">%1$s</xliff:g>နှင့် တွဲချိတ်မရပါ။"</string>
<string name="bluetooth_pairing_device_down_error_message" msgid="7870998403045801381">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g>နှင့်ဆက်သွယ်မရပါ"</string>
<string name="bluetooth_pairing_rejected_error_message" msgid="1648157108520832454">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g>နှင့်တွဲချိတ်ရန် ပယ်ချခံရသည်"</string>
- <!-- no translation found for accessibility_wifi_off (1166761729660614716) -->
- <skip />
- <!-- no translation found for accessibility_no_wifi (8834610636137374508) -->
- <skip />
- <!-- no translation found for accessibility_wifi_one_bar (4869376278894301820) -->
- <skip />
- <!-- no translation found for accessibility_wifi_two_bars (3569851234710034416) -->
- <skip />
- <!-- no translation found for accessibility_wifi_three_bars (8134185644861380311) -->
- <skip />
- <!-- no translation found for accessibility_wifi_signal_full (7061045677694702) -->
- <skip />
+ <string name="accessibility_wifi_off" msgid="1166761729660614716">"ဝိုင်ဖိုင် မရှိ"</string>
+ <string name="accessibility_no_wifi" msgid="8834610636137374508">"ဝိုင်ဖိုင် ချိတ်ဆက်ထားမှု မရှိပါ"</string>
+ <string name="accessibility_wifi_one_bar" msgid="4869376278894301820">"ဝိုင်ဖိုင် ၁ ဘားရှိ"</string>
+ <string name="accessibility_wifi_two_bars" msgid="3569851234710034416">"ဝိုင်ဖိုင် ၂ ဘား"</string>
+ <string name="accessibility_wifi_three_bars" msgid="8134185644861380311">"ဝိုင်ဖိုင် ၃ ဘား"</string>
+ <string name="accessibility_wifi_signal_full" msgid="7061045677694702">"ဝိုင်ဖိုင် အပြည့်ရှိ"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-nb/strings.xml b/packages/SettingsLib/res/values-nb/strings.xml
index d8622f9..e1ad3a2 100644
--- a/packages/SettingsLib/res/values-nb/strings.xml
+++ b/packages/SettingsLib/res/values-nb/strings.xml
@@ -77,16 +77,10 @@
<string name="bluetooth_pairing_pin_error_message" msgid="8337234855188925274">"Kan ikke koble til <xliff:g id="DEVICE_NAME">%1$s</xliff:g> på grunn av feil personlig kode eller passord."</string>
<string name="bluetooth_pairing_device_down_error_message" msgid="7870998403045801381">"Kan ikke kommunisere med <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
<string name="bluetooth_pairing_rejected_error_message" msgid="1648157108520832454">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> avslo paring."</string>
- <!-- no translation found for accessibility_wifi_off (1166761729660614716) -->
- <skip />
- <!-- no translation found for accessibility_no_wifi (8834610636137374508) -->
- <skip />
- <!-- no translation found for accessibility_wifi_one_bar (4869376278894301820) -->
- <skip />
- <!-- no translation found for accessibility_wifi_two_bars (3569851234710034416) -->
- <skip />
- <!-- no translation found for accessibility_wifi_three_bars (8134185644861380311) -->
- <skip />
- <!-- no translation found for accessibility_wifi_signal_full (7061045677694702) -->
- <skip />
+ <string name="accessibility_wifi_off" msgid="1166761729660614716">"Wi-Fi er av."</string>
+ <string name="accessibility_no_wifi" msgid="8834610636137374508">"Wi-Fi er frakoblet."</string>
+ <string name="accessibility_wifi_one_bar" msgid="4869376278894301820">"Wi-Fi-signal med én stolpe."</string>
+ <string name="accessibility_wifi_two_bars" msgid="3569851234710034416">"Wi-Fi-signal med to stolper."</string>
+ <string name="accessibility_wifi_three_bars" msgid="8134185644861380311">"Wi-Fi-signal med tre stolper."</string>
+ <string name="accessibility_wifi_signal_full" msgid="7061045677694702">"Wi-Fi-signalet er ved full styrke."</string>
</resources>
diff --git a/packages/SettingsLib/res/values-ne-rNP/strings.xml b/packages/SettingsLib/res/values-ne-rNP/strings.xml
index d080e09..6add87d 100644
--- a/packages/SettingsLib/res/values-ne-rNP/strings.xml
+++ b/packages/SettingsLib/res/values-ne-rNP/strings.xml
@@ -77,16 +77,10 @@
<string name="bluetooth_pairing_pin_error_message" msgid="8337234855188925274">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g>गलत PIN वा पासकिका कारण सँग जोडा बाँध्न सक्दैन।"</string>
<string name="bluetooth_pairing_device_down_error_message" msgid="7870998403045801381">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> सँग कुराकानी हुन सक्दैन।"</string>
<string name="bluetooth_pairing_rejected_error_message" msgid="1648157108520832454">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> द्वारा जोडा बाँध्ने कार्य अस्वीकृत"</string>
- <!-- no translation found for accessibility_wifi_off (1166761729660614716) -->
- <skip />
- <!-- no translation found for accessibility_no_wifi (8834610636137374508) -->
- <skip />
- <!-- no translation found for accessibility_wifi_one_bar (4869376278894301820) -->
- <skip />
- <!-- no translation found for accessibility_wifi_two_bars (3569851234710034416) -->
- <skip />
- <!-- no translation found for accessibility_wifi_three_bars (8134185644861380311) -->
- <skip />
- <!-- no translation found for accessibility_wifi_signal_full (7061045677694702) -->
- <skip />
+ <string name="accessibility_wifi_off" msgid="1166761729660614716">"Wi-Fi बन्द।"</string>
+ <string name="accessibility_no_wifi" msgid="8834610636137374508">"Wi-Fi जडान विच्छेद भयो।"</string>
+ <string name="accessibility_wifi_one_bar" msgid="4869376278894301820">"Wi-Fi एक पट्टि।"</string>
+ <string name="accessibility_wifi_two_bars" msgid="3569851234710034416">"Wi-Fi दुई पट्टि।"</string>
+ <string name="accessibility_wifi_three_bars" msgid="8134185644861380311">"Wi-Fi तीन बारहरू।"</string>
+ <string name="accessibility_wifi_signal_full" msgid="7061045677694702">"पूर्ण Wi-Fi सिंग्नल।"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-nl/strings.xml b/packages/SettingsLib/res/values-nl/strings.xml
index 06c4357..3c06985 100644
--- a/packages/SettingsLib/res/values-nl/strings.xml
+++ b/packages/SettingsLib/res/values-nl/strings.xml
@@ -72,21 +72,15 @@
<string name="bluetooth_pairing_accept" msgid="6163520056536604875">"Koppelen"</string>
<string name="bluetooth_pairing_accept_all_caps" msgid="6061699265220789149">"KOPPELEN"</string>
<string name="bluetooth_pairing_decline" msgid="4185420413578948140">"Annuleren"</string>
- <string name="bluetooth_pairing_will_share_phonebook" msgid="4982239145676394429">"Koppelen verleent toegang tot uw contacten en oproepgeschiedenis wanneer de apparaten zijn verbonden."</string>
+ <string name="bluetooth_pairing_will_share_phonebook" msgid="4982239145676394429">"Koppelen verleent toegang tot je contacten en oproepgeschiedenis wanneer de apparaten zijn verbonden."</string>
<string name="bluetooth_pairing_error_message" msgid="3748157733635947087">"Kan niet koppelen aan <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
<string name="bluetooth_pairing_pin_error_message" msgid="8337234855188925274">"Kan niet koppelen aan <xliff:g id="DEVICE_NAME">%1$s</xliff:g> vanwege een onjuiste pincode of toegangscode."</string>
<string name="bluetooth_pairing_device_down_error_message" msgid="7870998403045801381">"Kan niet communiceren met <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
<string name="bluetooth_pairing_rejected_error_message" msgid="1648157108520832454">"Koppeling geweigerd door <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
- <!-- no translation found for accessibility_wifi_off (1166761729660614716) -->
- <skip />
- <!-- no translation found for accessibility_no_wifi (8834610636137374508) -->
- <skip />
- <!-- no translation found for accessibility_wifi_one_bar (4869376278894301820) -->
- <skip />
- <!-- no translation found for accessibility_wifi_two_bars (3569851234710034416) -->
- <skip />
- <!-- no translation found for accessibility_wifi_three_bars (8134185644861380311) -->
- <skip />
- <!-- no translation found for accessibility_wifi_signal_full (7061045677694702) -->
- <skip />
+ <string name="accessibility_wifi_off" msgid="1166761729660614716">"Wifi: uitgeschakeld."</string>
+ <string name="accessibility_no_wifi" msgid="8834610636137374508">"Wifi-verbinding verbroken."</string>
+ <string name="accessibility_wifi_one_bar" msgid="4869376278894301820">"Wifi: één streepje."</string>
+ <string name="accessibility_wifi_two_bars" msgid="3569851234710034416">"Wifi: twee streepjes."</string>
+ <string name="accessibility_wifi_three_bars" msgid="8134185644861380311">"Wifi: drie streepjes."</string>
+ <string name="accessibility_wifi_signal_full" msgid="7061045677694702">"Wifii-signaal is op volledige sterkte."</string>
</resources>
diff --git a/packages/SettingsLib/res/values-pa-rIN/strings.xml b/packages/SettingsLib/res/values-pa-rIN/strings.xml
index 24d5f78..2a6e456 100644
--- a/packages/SettingsLib/res/values-pa-rIN/strings.xml
+++ b/packages/SettingsLib/res/values-pa-rIN/strings.xml
@@ -77,16 +77,10 @@
<string name="bluetooth_pairing_pin_error_message" msgid="8337234855188925274">"ਇੱਕ ਗ਼ਲਤ PIN ਜਾਂ ਪਾਸਕੁੰਜੀ ਦੇ ਕਾਰਨ <xliff:g id="DEVICE_NAME">%1$s</xliff:g> ਨਾਲ ਪੇਅਰ ਨਹੀਂ ਕਰ ਸਕਿਆ।"</string>
<string name="bluetooth_pairing_device_down_error_message" msgid="7870998403045801381">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> ਨਾਲ ਸੰਚਾਰ ਨਹੀਂ ਕਰ ਸਕਦਾ।"</string>
<string name="bluetooth_pairing_rejected_error_message" msgid="1648157108520832454">"ਪੇਅਰਿੰਗ <xliff:g id="DEVICE_NAME">%1$s</xliff:g> ਵੱਲੋਂ ਰੱਦ ਕੀਤੀ ਗਈ।"</string>
- <!-- no translation found for accessibility_wifi_off (1166761729660614716) -->
- <skip />
- <!-- no translation found for accessibility_no_wifi (8834610636137374508) -->
- <skip />
- <!-- no translation found for accessibility_wifi_one_bar (4869376278894301820) -->
- <skip />
- <!-- no translation found for accessibility_wifi_two_bars (3569851234710034416) -->
- <skip />
- <!-- no translation found for accessibility_wifi_three_bars (8134185644861380311) -->
- <skip />
- <!-- no translation found for accessibility_wifi_signal_full (7061045677694702) -->
- <skip />
+ <string name="accessibility_wifi_off" msgid="1166761729660614716">"Wifi ਬੰਦ।"</string>
+ <string name="accessibility_no_wifi" msgid="8834610636137374508">"Wifi ਡਿਸਕਨੈਕਟ ਕੀਤਾ।"</string>
+ <string name="accessibility_wifi_one_bar" msgid="4869376278894301820">"Wifi ਇੱਕ ਬਾਰ।"</string>
+ <string name="accessibility_wifi_two_bars" msgid="3569851234710034416">"Wifi ਦੋ ਬਾਰ।"</string>
+ <string name="accessibility_wifi_three_bars" msgid="8134185644861380311">"Wifi ਤਿੰਨ ਬਾਰ।"</string>
+ <string name="accessibility_wifi_signal_full" msgid="7061045677694702">"Wifi ਸਿਗਨਲ ਪੂਰਾ।"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-pl/strings.xml b/packages/SettingsLib/res/values-pl/strings.xml
index 7731df0..a89e958 100644
--- a/packages/SettingsLib/res/values-pl/strings.xml
+++ b/packages/SettingsLib/res/values-pl/strings.xml
@@ -77,16 +77,10 @@
<string name="bluetooth_pairing_pin_error_message" msgid="8337234855188925274">"Nie można sparować z urządzeniem <xliff:g id="DEVICE_NAME">%1$s</xliff:g> ze względu na błędny kod PIN lub klucz."</string>
<string name="bluetooth_pairing_device_down_error_message" msgid="7870998403045801381">"Nie można skomunikować się z urządzeniem <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
<string name="bluetooth_pairing_rejected_error_message" msgid="1648157108520832454">"Powiązanie odrzucone przez urządzenie <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
- <!-- no translation found for accessibility_wifi_off (1166761729660614716) -->
- <skip />
- <!-- no translation found for accessibility_no_wifi (8834610636137374508) -->
- <skip />
- <!-- no translation found for accessibility_wifi_one_bar (4869376278894301820) -->
- <skip />
- <!-- no translation found for accessibility_wifi_two_bars (3569851234710034416) -->
- <skip />
- <!-- no translation found for accessibility_wifi_three_bars (8134185644861380311) -->
- <skip />
- <!-- no translation found for accessibility_wifi_signal_full (7061045677694702) -->
- <skip />
+ <string name="accessibility_wifi_off" msgid="1166761729660614716">"Wi-Fi wyłączone."</string>
+ <string name="accessibility_no_wifi" msgid="8834610636137374508">"Wi-Fi odłączone."</string>
+ <string name="accessibility_wifi_one_bar" msgid="4869376278894301820">"Wi-Fi: jeden pasek."</string>
+ <string name="accessibility_wifi_two_bars" msgid="3569851234710034416">"Wi-Fi: dwa paski."</string>
+ <string name="accessibility_wifi_three_bars" msgid="8134185644861380311">"Wi-Fi: trzy paski."</string>
+ <string name="accessibility_wifi_signal_full" msgid="7061045677694702">"Wi-Fi: pełna moc sygnału."</string>
</resources>
diff --git a/packages/SettingsLib/res/values-pt-rBR/arrays.xml b/packages/SettingsLib/res/values-pt-rBR/arrays.xml
new file mode 100644
index 0000000..cea70da
--- /dev/null
+++ b/packages/SettingsLib/res/values-pt-rBR/arrays.xml
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/*
+**
+** Copyright 2015 The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="wifi_status">
+ <item msgid="1922181315419294640"></item>
+ <item msgid="8934131797783724664">"Procurando…"</item>
+ <item msgid="8513729475867537913">"Conectando..."</item>
+ <item msgid="515055375277271756">"Autenticando..."</item>
+ <item msgid="1943354004029184381">"Obtendo endereço IP…"</item>
+ <item msgid="4221763391123233270">"Conectado"</item>
+ <item msgid="624838831631122137">"Suspenso"</item>
+ <item msgid="7979680559596111948">"Desconectando…"</item>
+ <item msgid="1634960474403853625">"Desconectado"</item>
+ <item msgid="746097431216080650">"Falha"</item>
+ <item msgid="6367044185730295334">"Bloqueado"</item>
+ <item msgid="503942654197908005">"Temporariamente evitando uma conexão ruim"</item>
+ </string-array>
+ <string-array name="wifi_status_with_ssid">
+ <item msgid="7714855332363650812"></item>
+ <item msgid="8878186979715711006">"Procurando…"</item>
+ <item msgid="355508996603873860">"Conectando-se a <xliff:g id="NETWORK_NAME">%1$s</xliff:g>…"</item>
+ <item msgid="554971459996405634">"Autenticando com a <xliff:g id="NETWORK_NAME">%1$s</xliff:g>…"</item>
+ <item msgid="7928343808033020343">"Obtendo endereço IP da <xliff:g id="NETWORK_NAME">%1$s</xliff:g>…"</item>
+ <item msgid="8937994881315223448">"Conectado a <xliff:g id="NETWORK_NAME">%1$s</xliff:g>"</item>
+ <item msgid="1330262655415760617">"Suspenso"</item>
+ <item msgid="7698638434317271902">"Desconectando da <xliff:g id="NETWORK_NAME">%1$s</xliff:g>…"</item>
+ <item msgid="197508606402264311">"Desconectado"</item>
+ <item msgid="8578370891960825148">"Falha"</item>
+ <item msgid="5660739516542454527">"Bloqueado"</item>
+ <item msgid="1805837518286731242">"Temporariamente evitando uma conexão ruim"</item>
+ </string-array>
+</resources>
diff --git a/packages/SettingsLib/res/values-pt-rBR/strings.xml b/packages/SettingsLib/res/values-pt-rBR/strings.xml
new file mode 100644
index 0000000..480e457
--- /dev/null
+++ b/packages/SettingsLib/res/values-pt-rBR/strings.xml
@@ -0,0 +1,86 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/*
+**
+** Copyright 2015 The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="wifi_fail_to_scan" msgid="1265540342578081461">"Não é possível verificar a existência de redes"</string>
+ <string name="wifi_security_none" msgid="7985461072596594400">"Nenhuma"</string>
+ <string name="wifi_remembered" msgid="4955746899347821096">"Salva"</string>
+ <string name="wifi_disabled_generic" msgid="4259794910584943386">"Desativado"</string>
+ <string name="wifi_disabled_network_failure" msgid="2364951338436007124">"Falha de configuração de IP"</string>
+ <string name="wifi_disabled_wifi_failure" msgid="3081668066612876581">"Falha de conexão Wi-Fi"</string>
+ <string name="wifi_disabled_password_failure" msgid="8659805351763133575">"Problema de autenticação"</string>
+ <string name="wifi_not_in_range" msgid="1136191511238508967">"Fora do alcance"</string>
+ <string name="wifi_no_internet" msgid="9151470775868728896">"Nenhum acesso à Internet detectado. O dispositivo não conectará automaticamente."</string>
+ <string name="saved_network" msgid="4352716707126620811">"Salvas por <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="connected_via_wfa" msgid="3805736726317410714">"Conectado via assistente de Wi‑Fi"</string>
+ <string name="connected_via_passpoint" msgid="2826205693803088747">"Conectado via %1$s"</string>
+ <string name="available_via_passpoint" msgid="1617440946846329613">"Disponível via %1$s"</string>
+ <string name="wifi_connected_no_internet" msgid="3149853966840874992">"Conectada, sem Internet"</string>
+ <string name="bluetooth_disconnected" msgid="6557104142667339895">"Desconectado"</string>
+ <string name="bluetooth_disconnecting" msgid="8913264760027764974">"Desconectando…"</string>
+ <string name="bluetooth_connecting" msgid="8555009514614320497">"Conectando..."</string>
+ <string name="bluetooth_connected" msgid="6038755206916626419">"Conectado"</string>
+ <string name="bluetooth_pairing" msgid="1426882272690346242">"Pareando…"</string>
+ <string name="bluetooth_connected_no_headset" msgid="2866994875046035609">"Conectado (sem telefone)"</string>
+ <string name="bluetooth_connected_no_a2dp" msgid="4576188601581440337">"Conectado (sem mídia)"</string>
+ <string name="bluetooth_connected_no_map" msgid="6504436917057479986">"Conectado (sem acesso a mensagens)"</string>
+ <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"Conectado (sem telefone ou mídia)"</string>
+ <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Áudio da mídia"</string>
+ <string name="bluetooth_profile_headset" msgid="8658779596261212609">"Áudio do telefone"</string>
+ <string name="bluetooth_profile_opp" msgid="9168139293654233697">"Transferência de arquivo"</string>
+ <string name="bluetooth_profile_hid" msgid="3680729023366986480">"Dispositivo de entrada"</string>
+ <string name="bluetooth_profile_pan" msgid="3391606497945147673">"Acesso à Internet"</string>
+ <string name="bluetooth_profile_pbap" msgid="5372051906968576809">"Compartilhamento de contatos"</string>
+ <string name="bluetooth_profile_pbap_summary" msgid="6605229608108852198">"Usar para compartilhamento de contatos"</string>
+ <string name="bluetooth_profile_pan_nap" msgid="8429049285027482959">"Compartilhamento de conexão à Internet"</string>
+ <string name="bluetooth_profile_map" msgid="5465271250454324383">"Acesso a mensagens"</string>
+ <string name="bluetooth_profile_sap" msgid="5764222021851283125">"Acesso SIM"</string>
+ <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"Conectado ao áudio da mídia"</string>
+ <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"Conectado ao áudio do telefone"</string>
+ <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"Conectado ao servidor de transferência de arquivo"</string>
+ <string name="bluetooth_map_profile_summary_connected" msgid="8191407438851351713">"Conectado ao mapa"</string>
+ <string name="bluetooth_sap_profile_summary_connected" msgid="8561765057453083838">"Conectado a SAP"</string>
+ <string name="bluetooth_opp_profile_summary_not_connected" msgid="1267091356089086285">"Não está conectado ao servidor de transferência de arquivo"</string>
+ <string name="bluetooth_hid_profile_summary_connected" msgid="3381760054215168689">"Conectado ao dispositivo de entrada"</string>
+ <string name="bluetooth_pan_user_profile_summary_connected" msgid="4602294638909590612">"Conectado ao dispositivo para acesso à Internet"</string>
+ <string name="bluetooth_pan_nap_profile_summary_connected" msgid="1561383706411975199">"Compart. conexão local de Intern. com disp."</string>
+ <string name="bluetooth_pan_profile_summary_use_for" msgid="5664884523822068653">"Usar para acesso à Internet"</string>
+ <string name="bluetooth_map_profile_summary_use_for" msgid="5154200119919927434">"Usar para mapa"</string>
+ <string name="bluetooth_sap_profile_summary_use_for" msgid="7085362712786907993">"Use para acesso SIM"</string>
+ <string name="bluetooth_a2dp_profile_summary_use_for" msgid="4630849022250168427">"Usar para áudio de mídia"</string>
+ <string name="bluetooth_headset_profile_summary_use_for" msgid="8705753622443862627">"Usar para áudio do telefone"</string>
+ <string name="bluetooth_opp_profile_summary_use_for" msgid="1255674547144769756">"Usado para transferência de arquivo"</string>
+ <string name="bluetooth_hid_profile_summary_use_for" msgid="232727040453645139">"Usar para entrada"</string>
+ <string name="bluetooth_pairing_accept" msgid="6163520056536604875">"Parear"</string>
+ <string name="bluetooth_pairing_accept_all_caps" msgid="6061699265220789149">"PAREAR"</string>
+ <string name="bluetooth_pairing_decline" msgid="4185420413578948140">"Cancelar"</string>
+ <string name="bluetooth_pairing_will_share_phonebook" msgid="4982239145676394429">"O pareamento dá acesso a seus contatos e ao histórico de chamadas quando estiver conectado."</string>
+ <string name="bluetooth_pairing_error_message" msgid="3748157733635947087">"Não foi possível parear com <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
+ <string name="bluetooth_pairing_pin_error_message" msgid="8337234855188925274">"Não foi possível parear com <xliff:g id="DEVICE_NAME">%1$s</xliff:g> por causa de um PIN ou senha incorretos."</string>
+ <string name="bluetooth_pairing_device_down_error_message" msgid="7870998403045801381">"Não é possível se comunicar com <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
+ <string name="bluetooth_pairing_rejected_error_message" msgid="1648157108520832454">"Emparelhamento rejeitado por <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
+ <string name="accessibility_wifi_off" msgid="1166761729660614716">"Wi-Fi desligado."</string>
+ <string name="accessibility_no_wifi" msgid="8834610636137374508">"Wi-Fi desconectado"</string>
+ <string name="accessibility_wifi_one_bar" msgid="4869376278894301820">"Uma barra de Wi-Fi."</string>
+ <string name="accessibility_wifi_two_bars" msgid="3569851234710034416">"Duas barras de Wi-Fi."</string>
+ <string name="accessibility_wifi_three_bars" msgid="8134185644861380311">"Três barras de Wi-Fi."</string>
+ <string name="accessibility_wifi_signal_full" msgid="7061045677694702">"Sinal Wi-Fi cheio."</string>
+</resources>
diff --git a/packages/SettingsLib/res/values-pt-rPT/strings.xml b/packages/SettingsLib/res/values-pt-rPT/strings.xml
index 712654b..85a775c 100644
--- a/packages/SettingsLib/res/values-pt-rPT/strings.xml
+++ b/packages/SettingsLib/res/values-pt-rPT/strings.xml
@@ -77,16 +77,10 @@
<string name="bluetooth_pairing_pin_error_message" msgid="8337234855188925274">"Não foi possível sincronizar com <xliff:g id="DEVICE_NAME">%1$s</xliff:g> devido a PIN ou chave de acesso incorreto."</string>
<string name="bluetooth_pairing_device_down_error_message" msgid="7870998403045801381">"Não é possível comunicar com <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
<string name="bluetooth_pairing_rejected_error_message" msgid="1648157108520832454">"Emparelhamento rejeitado por <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
- <!-- no translation found for accessibility_wifi_off (1166761729660614716) -->
- <skip />
- <!-- no translation found for accessibility_no_wifi (8834610636137374508) -->
- <skip />
- <!-- no translation found for accessibility_wifi_one_bar (4869376278894301820) -->
- <skip />
- <!-- no translation found for accessibility_wifi_two_bars (3569851234710034416) -->
- <skip />
- <!-- no translation found for accessibility_wifi_three_bars (8134185644861380311) -->
- <skip />
- <!-- no translation found for accessibility_wifi_signal_full (7061045677694702) -->
- <skip />
+ <string name="accessibility_wifi_off" msgid="1166761729660614716">"Wi-Fi desativado."</string>
+ <string name="accessibility_no_wifi" msgid="8834610636137374508">"Wi-Fi desligado."</string>
+ <string name="accessibility_wifi_one_bar" msgid="4869376278894301820">"Uma barra de Wi-Fi."</string>
+ <string name="accessibility_wifi_two_bars" msgid="3569851234710034416">"Duas barras de Wi-Fi."</string>
+ <string name="accessibility_wifi_three_bars" msgid="8134185644861380311">"Três barras de Wi-Fi."</string>
+ <string name="accessibility_wifi_signal_full" msgid="7061045677694702">"Sinal de Wi-Fi completo."</string>
</resources>
diff --git a/packages/SettingsLib/res/values-pt/strings.xml b/packages/SettingsLib/res/values-pt/strings.xml
index 4e48b96..480e457 100644
--- a/packages/SettingsLib/res/values-pt/strings.xml
+++ b/packages/SettingsLib/res/values-pt/strings.xml
@@ -77,16 +77,10 @@
<string name="bluetooth_pairing_pin_error_message" msgid="8337234855188925274">"Não foi possível parear com <xliff:g id="DEVICE_NAME">%1$s</xliff:g> por causa de um PIN ou senha incorretos."</string>
<string name="bluetooth_pairing_device_down_error_message" msgid="7870998403045801381">"Não é possível se comunicar com <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
<string name="bluetooth_pairing_rejected_error_message" msgid="1648157108520832454">"Emparelhamento rejeitado por <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
- <!-- no translation found for accessibility_wifi_off (1166761729660614716) -->
- <skip />
- <!-- no translation found for accessibility_no_wifi (8834610636137374508) -->
- <skip />
- <!-- no translation found for accessibility_wifi_one_bar (4869376278894301820) -->
- <skip />
- <!-- no translation found for accessibility_wifi_two_bars (3569851234710034416) -->
- <skip />
- <!-- no translation found for accessibility_wifi_three_bars (8134185644861380311) -->
- <skip />
- <!-- no translation found for accessibility_wifi_signal_full (7061045677694702) -->
- <skip />
+ <string name="accessibility_wifi_off" msgid="1166761729660614716">"Wi-Fi desligado."</string>
+ <string name="accessibility_no_wifi" msgid="8834610636137374508">"Wi-Fi desconectado"</string>
+ <string name="accessibility_wifi_one_bar" msgid="4869376278894301820">"Uma barra de Wi-Fi."</string>
+ <string name="accessibility_wifi_two_bars" msgid="3569851234710034416">"Duas barras de Wi-Fi."</string>
+ <string name="accessibility_wifi_three_bars" msgid="8134185644861380311">"Três barras de Wi-Fi."</string>
+ <string name="accessibility_wifi_signal_full" msgid="7061045677694702">"Sinal Wi-Fi cheio."</string>
</resources>
diff --git a/packages/SettingsLib/res/values-ro/arrays.xml b/packages/SettingsLib/res/values-ro/arrays.xml
index bd0239a..c4b3b34 100644
--- a/packages/SettingsLib/res/values-ro/arrays.xml
+++ b/packages/SettingsLib/res/values-ro/arrays.xml
@@ -25,12 +25,12 @@
<item msgid="8934131797783724664">"În curs de scanare..."</item>
<item msgid="8513729475867537913">"Se conectează..."</item>
<item msgid="515055375277271756">"În curs de autentificare…"</item>
- <item msgid="1943354004029184381">"Se obţine adresa IP..."</item>
+ <item msgid="1943354004029184381">"Se obține adresa IP..."</item>
<item msgid="4221763391123233270">"Conectată"</item>
<item msgid="624838831631122137">"Suspendată"</item>
<item msgid="7979680559596111948">"În curs de deconectare..."</item>
<item msgid="1634960474403853625">"Deconectată"</item>
- <item msgid="746097431216080650">"Nereuşit"</item>
+ <item msgid="746097431216080650">"Nereușit"</item>
<item msgid="6367044185730295334">"Blocat"</item>
<item msgid="503942654197908005">"Evitarea temporară a conexiunii slabe"</item>
</string-array>
@@ -39,12 +39,12 @@
<item msgid="8878186979715711006">"În curs de scanare..."</item>
<item msgid="355508996603873860">"Se conectează la <xliff:g id="NETWORK_NAME">%1$s</xliff:g>..."</item>
<item msgid="554971459996405634">"Se autentifică cu <xliff:g id="NETWORK_NAME">%1$s</xliff:g>…"</item>
- <item msgid="7928343808033020343">"Se obţine adresa IP de la <xliff:g id="NETWORK_NAME">%1$s</xliff:g>…"</item>
+ <item msgid="7928343808033020343">"Se obține adresa IP de la <xliff:g id="NETWORK_NAME">%1$s</xliff:g>…"</item>
<item msgid="8937994881315223448">"Conectat la <xliff:g id="NETWORK_NAME">%1$s</xliff:g>"</item>
<item msgid="1330262655415760617">"Suspendată"</item>
<item msgid="7698638434317271902">"În curs de deconectare de la <xliff:g id="NETWORK_NAME">%1$s</xliff:g>..."</item>
<item msgid="197508606402264311">"Deconectată"</item>
- <item msgid="8578370891960825148">"Nereuşit"</item>
+ <item msgid="8578370891960825148">"Nereușit"</item>
<item msgid="5660739516542454527">"Blocat"</item>
<item msgid="1805837518286731242">"Evitarea temporară a conexiunii slabe"</item>
</string-array>
diff --git a/packages/SettingsLib/res/values-ro/strings.xml b/packages/SettingsLib/res/values-ro/strings.xml
index 527151b..e6f9728 100644
--- a/packages/SettingsLib/res/values-ro/strings.xml
+++ b/packages/SettingsLib/res/values-ro/strings.xml
@@ -20,7 +20,7 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="wifi_fail_to_scan" msgid="1265540342578081461">"Nu se poate scana pentru reţele"</string>
+ <string name="wifi_fail_to_scan" msgid="1265540342578081461">"Nu se poate scana pentru rețele"</string>
<string name="wifi_security_none" msgid="7985461072596594400">"Niciuna"</string>
<string name="wifi_remembered" msgid="4955746899347821096">"Salvată"</string>
<string name="wifi_disabled_generic" msgid="4259794910584943386">"Dezactivată"</string>
@@ -40,12 +40,12 @@
<string name="bluetooth_connected" msgid="6038755206916626419">"Conectat"</string>
<string name="bluetooth_pairing" msgid="1426882272690346242">"Se conectează…"</string>
<string name="bluetooth_connected_no_headset" msgid="2866994875046035609">"Conectat (fără telefon)"</string>
- <string name="bluetooth_connected_no_a2dp" msgid="4576188601581440337">"Conectat (fără conţinut media)"</string>
+ <string name="bluetooth_connected_no_a2dp" msgid="4576188601581440337">"Conectat (fără conținut media)"</string>
<string name="bluetooth_connected_no_map" msgid="6504436917057479986">"Conectat (fără acces la mesaje)"</string>
- <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"Conectat (fără telefon sau conţ. media)"</string>
- <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Conţinut media audio"</string>
+ <string name="bluetooth_connected_no_headset_no_a2dp" msgid="9195757766755553810">"Conectat (fără telefon sau conț. media)"</string>
+ <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Conținut media audio"</string>
<string name="bluetooth_profile_headset" msgid="8658779596261212609">"Componenta audio a telefonului"</string>
- <string name="bluetooth_profile_opp" msgid="9168139293654233697">"Transfer de fişiere"</string>
+ <string name="bluetooth_profile_opp" msgid="9168139293654233697">"Transfer de fișiere"</string>
<string name="bluetooth_profile_hid" msgid="3680729023366986480">"Dispozitiv de intrare"</string>
<string name="bluetooth_profile_pan" msgid="3391606497945147673">"Acces internet"</string>
<string name="bluetooth_profile_pbap" msgid="5372051906968576809">"Acces la Agendă"</string>
@@ -53,23 +53,23 @@
<string name="bluetooth_profile_pan_nap" msgid="8429049285027482959">"Distribuirea conexiunii la internet"</string>
<string name="bluetooth_profile_map" msgid="5465271250454324383">"Acces la mesaje"</string>
<string name="bluetooth_profile_sap" msgid="5764222021851283125">"Acces la SIM"</string>
- <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"Conectat la profilul pentru conţinut media audio"</string>
+ <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"Conectat la profilul pentru conținut media audio"</string>
<string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"Conectat la componenta audio a telefonului"</string>
- <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"Conectat la serverul de transfer de fişiere"</string>
+ <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"Conectat la serverul de transfer de fișiere"</string>
<string name="bluetooth_map_profile_summary_connected" msgid="8191407438851351713">"Conectat la hartă"</string>
<string name="bluetooth_sap_profile_summary_connected" msgid="8561765057453083838">"Conectat la SAP"</string>
- <string name="bluetooth_opp_profile_summary_not_connected" msgid="1267091356089086285">"Neconectat la serverul de transfer de fişiere"</string>
+ <string name="bluetooth_opp_profile_summary_not_connected" msgid="1267091356089086285">"Neconectat la serverul de transfer de fișiere"</string>
<string name="bluetooth_hid_profile_summary_connected" msgid="3381760054215168689">"Conectat la dispozitivul de intrare"</string>
<string name="bluetooth_pan_user_profile_summary_connected" msgid="4602294638909590612">"Conectat la dispoz. pt. acces internet"</string>
<string name="bluetooth_pan_nap_profile_summary_connected" msgid="1561383706411975199">"Se permite dispoz. acces la internet local"</string>
- <string name="bluetooth_pan_profile_summary_use_for" msgid="5664884523822068653">"Utilizaţi pentru acces internet"</string>
+ <string name="bluetooth_pan_profile_summary_use_for" msgid="5664884523822068653">"Utilizați pentru acces internet"</string>
<string name="bluetooth_map_profile_summary_use_for" msgid="5154200119919927434">"Utilizați pentru hartă"</string>
<string name="bluetooth_sap_profile_summary_use_for" msgid="7085362712786907993">"Folosiți pentru acces la SIM"</string>
- <string name="bluetooth_a2dp_profile_summary_use_for" msgid="4630849022250168427">"Utilizaţi pentru profilul pentru conţinut media audio"</string>
- <string name="bluetooth_headset_profile_summary_use_for" msgid="8705753622443862627">"Utilizaţi pentru componenta audio a telefonului"</string>
- <string name="bluetooth_opp_profile_summary_use_for" msgid="1255674547144769756">"Utilizaţi pentru transferul de fişiere"</string>
- <string name="bluetooth_hid_profile_summary_use_for" msgid="232727040453645139">"Utilizaţi pentru introducere date"</string>
- <string name="bluetooth_pairing_accept" msgid="6163520056536604875">"Asociaţi"</string>
+ <string name="bluetooth_a2dp_profile_summary_use_for" msgid="4630849022250168427">"Utilizați pentru profilul pentru conținut media audio"</string>
+ <string name="bluetooth_headset_profile_summary_use_for" msgid="8705753622443862627">"Utilizați pentru componenta audio a telefonului"</string>
+ <string name="bluetooth_opp_profile_summary_use_for" msgid="1255674547144769756">"Utilizați pentru transferul de fișiere"</string>
+ <string name="bluetooth_hid_profile_summary_use_for" msgid="232727040453645139">"Utilizați pentru introducere date"</string>
+ <string name="bluetooth_pairing_accept" msgid="6163520056536604875">"Asociați"</string>
<string name="bluetooth_pairing_accept_all_caps" msgid="6061699265220789149">"CONECTAȚI"</string>
<string name="bluetooth_pairing_decline" msgid="4185420413578948140">"Anulați"</string>
<string name="bluetooth_pairing_will_share_phonebook" msgid="4982239145676394429">"Asocierea dispozitivelor vă permite accesul la persoanele de contact și la istoricul apelurilor când dispozitivul este conectat."</string>
@@ -77,16 +77,10 @@
<string name="bluetooth_pairing_pin_error_message" msgid="8337234855188925274">"Nu s-a putut împerechea cu <xliff:g id="DEVICE_NAME">%1$s</xliff:g> din cauza unui cod PIN sau al unei chei de acces incorecte."</string>
<string name="bluetooth_pairing_device_down_error_message" msgid="7870998403045801381">"Nu se poate comunica cu <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
<string name="bluetooth_pairing_rejected_error_message" msgid="1648157108520832454">"Împerechere respinsă de <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
- <!-- no translation found for accessibility_wifi_off (1166761729660614716) -->
- <skip />
- <!-- no translation found for accessibility_no_wifi (8834610636137374508) -->
- <skip />
- <!-- no translation found for accessibility_wifi_one_bar (4869376278894301820) -->
- <skip />
- <!-- no translation found for accessibility_wifi_two_bars (3569851234710034416) -->
- <skip />
- <!-- no translation found for accessibility_wifi_three_bars (8134185644861380311) -->
- <skip />
- <!-- no translation found for accessibility_wifi_signal_full (7061045677694702) -->
- <skip />
+ <string name="accessibility_wifi_off" msgid="1166761729660614716">"Wi-Fi dezactivat."</string>
+ <string name="accessibility_no_wifi" msgid="8834610636137374508">"Wi-Fi deconectat."</string>
+ <string name="accessibility_wifi_one_bar" msgid="4869376278894301820">"Semnal Wi-Fi: o bară."</string>
+ <string name="accessibility_wifi_two_bars" msgid="3569851234710034416">"Semnal Wi-Fi: două bare."</string>
+ <string name="accessibility_wifi_three_bars" msgid="8134185644861380311">"Semnal Wi-Fi: trei bare."</string>
+ <string name="accessibility_wifi_signal_full" msgid="7061045677694702">"Semnal Wi-Fi: complet."</string>
</resources>
diff --git a/packages/SettingsLib/res/values-ru/strings.xml b/packages/SettingsLib/res/values-ru/strings.xml
index 922e2c5..738c7ca 100644
--- a/packages/SettingsLib/res/values-ru/strings.xml
+++ b/packages/SettingsLib/res/values-ru/strings.xml
@@ -77,16 +77,10 @@
<string name="bluetooth_pairing_pin_error_message" msgid="8337234855188925274">"Не удалось подключиться к устройству \"<xliff:g id="DEVICE_NAME">%1$s</xliff:g>\", так как введен неверный PIN-код или пароль."</string>
<string name="bluetooth_pairing_device_down_error_message" msgid="7870998403045801381">"Не удается установить соединение с устройством \"<xliff:g id="DEVICE_NAME">%1$s</xliff:g>\"."</string>
<string name="bluetooth_pairing_rejected_error_message" msgid="1648157108520832454">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> не разрешает сопряжение."</string>
- <!-- no translation found for accessibility_wifi_off (1166761729660614716) -->
- <skip />
- <!-- no translation found for accessibility_no_wifi (8834610636137374508) -->
- <skip />
- <!-- no translation found for accessibility_wifi_one_bar (4869376278894301820) -->
- <skip />
- <!-- no translation found for accessibility_wifi_two_bars (3569851234710034416) -->
- <skip />
- <!-- no translation found for accessibility_wifi_three_bars (8134185644861380311) -->
- <skip />
- <!-- no translation found for accessibility_wifi_signal_full (7061045677694702) -->
- <skip />
+ <string name="accessibility_wifi_off" msgid="1166761729660614716">"Wi-Fi выключен"</string>
+ <string name="accessibility_no_wifi" msgid="8834610636137374508">"Wi-Fi отключен"</string>
+ <string name="accessibility_wifi_one_bar" msgid="4869376278894301820">"Wi-Fi: одно деление"</string>
+ <string name="accessibility_wifi_two_bars" msgid="3569851234710034416">"Wi-Fi: два деления"</string>
+ <string name="accessibility_wifi_three_bars" msgid="8134185644861380311">"Wi-Fi: три деления"</string>
+ <string name="accessibility_wifi_signal_full" msgid="7061045677694702">"Wi-Fi: надежный сигнал"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-si-rLK/strings.xml b/packages/SettingsLib/res/values-si-rLK/strings.xml
index 907237c..cb4bf86 100644
--- a/packages/SettingsLib/res/values-si-rLK/strings.xml
+++ b/packages/SettingsLib/res/values-si-rLK/strings.xml
@@ -77,16 +77,10 @@
<string name="bluetooth_pairing_pin_error_message" msgid="8337234855188925274">"වැරදි PIN එකක් හෝ පාස් යතුරක් නිසා <xliff:g id="DEVICE_NAME">%1$s</xliff:g> සමඟ යුගල කිරීමට නොහැකිය."</string>
<string name="bluetooth_pairing_device_down_error_message" msgid="7870998403045801381">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> සමඟ සන්නිවේදනය කළ නොහැක."</string>
<string name="bluetooth_pairing_rejected_error_message" msgid="1648157108520832454">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> විසින් යුගල කිරීම ප්රතික්ෂේප කරන ලදි."</string>
- <!-- no translation found for accessibility_wifi_off (1166761729660614716) -->
- <skip />
- <!-- no translation found for accessibility_no_wifi (8834610636137374508) -->
- <skip />
- <!-- no translation found for accessibility_wifi_one_bar (4869376278894301820) -->
- <skip />
- <!-- no translation found for accessibility_wifi_two_bars (3569851234710034416) -->
- <skip />
- <!-- no translation found for accessibility_wifi_three_bars (8134185644861380311) -->
- <skip />
- <!-- no translation found for accessibility_wifi_signal_full (7061045677694702) -->
- <skip />
+ <string name="accessibility_wifi_off" msgid="1166761729660614716">"Wifi අක්රියයි."</string>
+ <string name="accessibility_no_wifi" msgid="8834610636137374508">"Wifi සම්බන්ධ කර නොමැත."</string>
+ <string name="accessibility_wifi_one_bar" msgid="4869376278894301820">"Wifi තීරු එකයි."</string>
+ <string name="accessibility_wifi_two_bars" msgid="3569851234710034416">"Wifi තීරු දෙකයි."</string>
+ <string name="accessibility_wifi_three_bars" msgid="8134185644861380311">"WiFi තීරු තුනයි."</string>
+ <string name="accessibility_wifi_signal_full" msgid="7061045677694702">"Wifi සංඥාව පිරී ඇත."</string>
</resources>
diff --git a/packages/SettingsLib/res/values-sk/strings.xml b/packages/SettingsLib/res/values-sk/strings.xml
index d7fabc0..eec73a1 100644
--- a/packages/SettingsLib/res/values-sk/strings.xml
+++ b/packages/SettingsLib/res/values-sk/strings.xml
@@ -77,16 +77,10 @@
<string name="bluetooth_pairing_pin_error_message" msgid="8337234855188925274">"Nepodarilo sa spárovať so zariadením <xliff:g id="DEVICE_NAME">%1$s</xliff:g>, pretože ste zadali nesprávny kód PIN alebo prístupový kľúč."</string>
<string name="bluetooth_pairing_device_down_error_message" msgid="7870998403045801381">"So zariadením <xliff:g id="DEVICE_NAME">%1$s</xliff:g> nie je možné komunikovať."</string>
<string name="bluetooth_pairing_rejected_error_message" msgid="1648157108520832454">"Párovanie odmietnuté zariadením <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
- <!-- no translation found for accessibility_wifi_off (1166761729660614716) -->
- <skip />
- <!-- no translation found for accessibility_no_wifi (8834610636137374508) -->
- <skip />
- <!-- no translation found for accessibility_wifi_one_bar (4869376278894301820) -->
- <skip />
- <!-- no translation found for accessibility_wifi_two_bars (3569851234710034416) -->
- <skip />
- <!-- no translation found for accessibility_wifi_three_bars (8134185644861380311) -->
- <skip />
- <!-- no translation found for accessibility_wifi_signal_full (7061045677694702) -->
- <skip />
+ <string name="accessibility_wifi_off" msgid="1166761729660614716">"Sieť Wi-Fi je vypnutá."</string>
+ <string name="accessibility_no_wifi" msgid="8834610636137374508">"Sieť Wi-Fi je odpojená."</string>
+ <string name="accessibility_wifi_one_bar" msgid="4869376278894301820">"Jedna čiarka signálu Wi-Fi."</string>
+ <string name="accessibility_wifi_two_bars" msgid="3569851234710034416">"Dve čiarky signálu Wi-Fi."</string>
+ <string name="accessibility_wifi_three_bars" msgid="8134185644861380311">"Tri čiarky signálu Wi-Fi."</string>
+ <string name="accessibility_wifi_signal_full" msgid="7061045677694702">"Plný signál Wi-Fi."</string>
</resources>
diff --git a/packages/SettingsLib/res/values-sl/strings.xml b/packages/SettingsLib/res/values-sl/strings.xml
index 9f074fd1..3b589a5 100644
--- a/packages/SettingsLib/res/values-sl/strings.xml
+++ b/packages/SettingsLib/res/values-sl/strings.xml
@@ -77,16 +77,10 @@
<string name="bluetooth_pairing_pin_error_message" msgid="8337234855188925274">"Zaradi nepravilne kode PIN ali gesla ni mogoče vzpostaviti povezave z napravo <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
<string name="bluetooth_pairing_device_down_error_message" msgid="7870998403045801381">"Z napravo <xliff:g id="DEVICE_NAME">%1$s</xliff:g> ni mogoče vzpostaviti povezave."</string>
<string name="bluetooth_pairing_rejected_error_message" msgid="1648157108520832454">"Naprava <xliff:g id="DEVICE_NAME">%1$s</xliff:g> je zavrnila seznanitev."</string>
- <!-- no translation found for accessibility_wifi_off (1166761729660614716) -->
- <skip />
- <!-- no translation found for accessibility_no_wifi (8834610636137374508) -->
- <skip />
- <!-- no translation found for accessibility_wifi_one_bar (4869376278894301820) -->
- <skip />
- <!-- no translation found for accessibility_wifi_two_bars (3569851234710034416) -->
- <skip />
- <!-- no translation found for accessibility_wifi_three_bars (8134185644861380311) -->
- <skip />
- <!-- no translation found for accessibility_wifi_signal_full (7061045677694702) -->
- <skip />
+ <string name="accessibility_wifi_off" msgid="1166761729660614716">"Wi-Fi je izklopljen."</string>
+ <string name="accessibility_no_wifi" msgid="8834610636137374508">"Povezava Wi-Fi je prekinjena."</string>
+ <string name="accessibility_wifi_one_bar" msgid="4869376278894301820">"Ena črtica signala Wi-Fi."</string>
+ <string name="accessibility_wifi_two_bars" msgid="3569851234710034416">"Dve črtici signala Wi-Fi."</string>
+ <string name="accessibility_wifi_three_bars" msgid="8134185644861380311">"Tri črtice signala Wi-Fi."</string>
+ <string name="accessibility_wifi_signal_full" msgid="7061045677694702">"Poln signal Wi-Fi."</string>
</resources>
diff --git a/packages/SettingsLib/res/values-sq-rAL/strings.xml b/packages/SettingsLib/res/values-sq-rAL/strings.xml
index 7fe42b6..1936f4e 100644
--- a/packages/SettingsLib/res/values-sq-rAL/strings.xml
+++ b/packages/SettingsLib/res/values-sq-rAL/strings.xml
@@ -77,16 +77,10 @@
<string name="bluetooth_pairing_pin_error_message" msgid="8337234855188925274">"Nuk mundi të çiftohej me <xliff:g id="DEVICE_NAME">%1$s</xliff:g> për shkak të një kodi PIN ose një kodi të pasaktë."</string>
<string name="bluetooth_pairing_device_down_error_message" msgid="7870998403045801381">"Nuk mund të komunikohet me <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
<string name="bluetooth_pairing_rejected_error_message" msgid="1648157108520832454">"Çiftimi u refuzua nga <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
- <!-- no translation found for accessibility_wifi_off (1166761729660614716) -->
- <skip />
- <!-- no translation found for accessibility_no_wifi (8834610636137374508) -->
- <skip />
- <!-- no translation found for accessibility_wifi_one_bar (4869376278894301820) -->
- <skip />
- <!-- no translation found for accessibility_wifi_two_bars (3569851234710034416) -->
- <skip />
- <!-- no translation found for accessibility_wifi_three_bars (8134185644861380311) -->
- <skip />
- <!-- no translation found for accessibility_wifi_signal_full (7061045677694702) -->
- <skip />
+ <string name="accessibility_wifi_off" msgid="1166761729660614716">"Wi-Fi është çaktivizuar."</string>
+ <string name="accessibility_no_wifi" msgid="8834610636137374508">"Wi-Fi është i shkëputur."</string>
+ <string name="accessibility_wifi_one_bar" msgid="4869376278894301820">"Wi-Fi ka një vijë."</string>
+ <string name="accessibility_wifi_two_bars" msgid="3569851234710034416">"Wi-Fi ka dy vija."</string>
+ <string name="accessibility_wifi_three_bars" msgid="8134185644861380311">"Wi-Fi: tre vija."</string>
+ <string name="accessibility_wifi_signal_full" msgid="7061045677694702">"Wi-Fi ka sinjal të plotë."</string>
</resources>
diff --git a/packages/SettingsLib/res/values-sr/strings.xml b/packages/SettingsLib/res/values-sr/strings.xml
index f0556f6..3a7adbc 100644
--- a/packages/SettingsLib/res/values-sr/strings.xml
+++ b/packages/SettingsLib/res/values-sr/strings.xml
@@ -77,16 +77,10 @@
<string name="bluetooth_pairing_pin_error_message" msgid="8337234855188925274">"Упаривање са уређајем <xliff:g id="DEVICE_NAME">%1$s</xliff:g> није могуће због нетачног PIN-а или приступног кода."</string>
<string name="bluetooth_pairing_device_down_error_message" msgid="7870998403045801381">"Није могуће комуницирати са уређајем <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
<string name="bluetooth_pairing_rejected_error_message" msgid="1648157108520832454">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> је одбио/ла упаривање"</string>
- <!-- no translation found for accessibility_wifi_off (1166761729660614716) -->
- <skip />
- <!-- no translation found for accessibility_no_wifi (8834610636137374508) -->
- <skip />
- <!-- no translation found for accessibility_wifi_one_bar (4869376278894301820) -->
- <skip />
- <!-- no translation found for accessibility_wifi_two_bars (3569851234710034416) -->
- <skip />
- <!-- no translation found for accessibility_wifi_three_bars (8134185644861380311) -->
- <skip />
- <!-- no translation found for accessibility_wifi_signal_full (7061045677694702) -->
- <skip />
+ <string name="accessibility_wifi_off" msgid="1166761729660614716">"Wi-Fi је искључен."</string>
+ <string name="accessibility_no_wifi" msgid="8834610636137374508">"Wi-Fi веза је прекинута."</string>
+ <string name="accessibility_wifi_one_bar" msgid="4869376278894301820">"Wi-Fi сигнал има једну црту."</string>
+ <string name="accessibility_wifi_two_bars" msgid="3569851234710034416">"Wi-Fi сигнал има две црте."</string>
+ <string name="accessibility_wifi_three_bars" msgid="8134185644861380311">"Wi-Fi сигнал има три црте."</string>
+ <string name="accessibility_wifi_signal_full" msgid="7061045677694702">"Wi-Fi сигнал је најјачи."</string>
</resources>
diff --git a/packages/SettingsLib/res/values-sv/strings.xml b/packages/SettingsLib/res/values-sv/strings.xml
index e11a153..ba07656 100644
--- a/packages/SettingsLib/res/values-sv/strings.xml
+++ b/packages/SettingsLib/res/values-sv/strings.xml
@@ -77,16 +77,10 @@
<string name="bluetooth_pairing_pin_error_message" msgid="8337234855188925274">"Det gick inte att koppla till <xliff:g id="DEVICE_NAME">%1$s</xliff:g> på grund av en felaktig PIN-kod eller nyckel."</string>
<string name="bluetooth_pairing_device_down_error_message" msgid="7870998403045801381">"Det går inte att kommunicera med <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
<string name="bluetooth_pairing_rejected_error_message" msgid="1648157108520832454">"Parkoppling avvisad av <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
- <!-- no translation found for accessibility_wifi_off (1166761729660614716) -->
- <skip />
- <!-- no translation found for accessibility_no_wifi (8834610636137374508) -->
- <skip />
- <!-- no translation found for accessibility_wifi_one_bar (4869376278894301820) -->
- <skip />
- <!-- no translation found for accessibility_wifi_two_bars (3569851234710034416) -->
- <skip />
- <!-- no translation found for accessibility_wifi_three_bars (8134185644861380311) -->
- <skip />
- <!-- no translation found for accessibility_wifi_signal_full (7061045677694702) -->
- <skip />
+ <string name="accessibility_wifi_off" msgid="1166761729660614716">"Wi-Fi är inaktiverat."</string>
+ <string name="accessibility_no_wifi" msgid="8834610636137374508">"Ingen Wi-Fi-anslutning."</string>
+ <string name="accessibility_wifi_one_bar" msgid="4869376278894301820">"Wi-Fi: en stapel."</string>
+ <string name="accessibility_wifi_two_bars" msgid="3569851234710034416">"Wi-Fi: två staplar."</string>
+ <string name="accessibility_wifi_three_bars" msgid="8134185644861380311">"Wi-Fi: tre staplar."</string>
+ <string name="accessibility_wifi_signal_full" msgid="7061045677694702">"Full signalstyrka för Wi-Fi."</string>
</resources>
diff --git a/packages/SettingsLib/res/values-sw/strings.xml b/packages/SettingsLib/res/values-sw/strings.xml
index 0b775e8..5573518 100644
--- a/packages/SettingsLib/res/values-sw/strings.xml
+++ b/packages/SettingsLib/res/values-sw/strings.xml
@@ -77,16 +77,10 @@
<string name="bluetooth_pairing_pin_error_message" msgid="8337234855188925274">"Haikuweza kulingana na <xliff:g id="DEVICE_NAME">%1$s</xliff:g> kwa sababu ya PIN isiyo sahihi au msimbo ya kuingia."</string>
<string name="bluetooth_pairing_device_down_error_message" msgid="7870998403045801381">"Haiwezi kuanzisha mawasiliano na <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
<string name="bluetooth_pairing_rejected_error_message" msgid="1648157108520832454">"Ulinganishaji umekataliwa na <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
- <!-- no translation found for accessibility_wifi_off (1166761729660614716) -->
- <skip />
- <!-- no translation found for accessibility_no_wifi (8834610636137374508) -->
- <skip />
- <!-- no translation found for accessibility_wifi_one_bar (4869376278894301820) -->
- <skip />
- <!-- no translation found for accessibility_wifi_two_bars (3569851234710034416) -->
- <skip />
- <!-- no translation found for accessibility_wifi_three_bars (8134185644861380311) -->
- <skip />
- <!-- no translation found for accessibility_wifi_signal_full (7061045677694702) -->
- <skip />
+ <string name="accessibility_wifi_off" msgid="1166761729660614716">"Wifi imezimwa."</string>
+ <string name="accessibility_no_wifi" msgid="8834610636137374508">"Wifi imeondolewa."</string>
+ <string name="accessibility_wifi_one_bar" msgid="4869376278894301820">"Kipima mtandao kimoja cha Wifi."</string>
+ <string name="accessibility_wifi_two_bars" msgid="3569851234710034416">"Vipima mtandao viwili vya Wifi."</string>
+ <string name="accessibility_wifi_three_bars" msgid="8134185644861380311">"Vipima mtandao vitatu vya Wifi."</string>
+ <string name="accessibility_wifi_signal_full" msgid="7061045677694702">"Nguvu kamili ya mtandao wa Wifi."</string>
</resources>
diff --git a/packages/SettingsLib/res/values-ta-rIN/strings.xml b/packages/SettingsLib/res/values-ta-rIN/strings.xml
index 06bfa96..9b6ea75 100644
--- a/packages/SettingsLib/res/values-ta-rIN/strings.xml
+++ b/packages/SettingsLib/res/values-ta-rIN/strings.xml
@@ -77,16 +77,10 @@
<string name="bluetooth_pairing_pin_error_message" msgid="8337234855188925274">"தவறான பின் அல்லது கடவுச்சொல் காரணமாக <xliff:g id="DEVICE_NAME">%1$s</xliff:g> உடன் இணைக்க முடியவில்லை."</string>
<string name="bluetooth_pairing_device_down_error_message" msgid="7870998403045801381">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> உடன் இணைக்க முடியவில்லை."</string>
<string name="bluetooth_pairing_rejected_error_message" msgid="1648157108520832454">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> இணைப்பதை நிராகரித்தது."</string>
- <!-- no translation found for accessibility_wifi_off (1166761729660614716) -->
- <skip />
- <!-- no translation found for accessibility_no_wifi (8834610636137374508) -->
- <skip />
- <!-- no translation found for accessibility_wifi_one_bar (4869376278894301820) -->
- <skip />
- <!-- no translation found for accessibility_wifi_two_bars (3569851234710034416) -->
- <skip />
- <!-- no translation found for accessibility_wifi_three_bars (8134185644861380311) -->
- <skip />
- <!-- no translation found for accessibility_wifi_signal_full (7061045677694702) -->
- <skip />
+ <string name="accessibility_wifi_off" msgid="1166761729660614716">"வைஃபை முடக்கப்பட்டது."</string>
+ <string name="accessibility_no_wifi" msgid="8834610636137374508">"வைஃபை துண்டிக்கப்பட்டது."</string>
+ <string name="accessibility_wifi_one_bar" msgid="4869376278894301820">"வைஃபை சிக்னல்: ஒரு கோடு."</string>
+ <string name="accessibility_wifi_two_bars" msgid="3569851234710034416">"வைஃபை சிக்னல்: இரண்டு கோடுகள்."</string>
+ <string name="accessibility_wifi_three_bars" msgid="8134185644861380311">"வைஃபை சிக்னல்: மூன்று கோடுகள்."</string>
+ <string name="accessibility_wifi_signal_full" msgid="7061045677694702">"வைஃபை சிக்னல் முழுமையாக உள்ளது."</string>
</resources>
diff --git a/packages/SettingsLib/res/values-te-rIN/strings.xml b/packages/SettingsLib/res/values-te-rIN/strings.xml
index 6bd4f5f..291e7b1 100644
--- a/packages/SettingsLib/res/values-te-rIN/strings.xml
+++ b/packages/SettingsLib/res/values-te-rIN/strings.xml
@@ -77,16 +77,10 @@
<string name="bluetooth_pairing_pin_error_message" msgid="8337234855188925274">"పిన్ లేదా పాస్కీ చెల్లని కారణంగా <xliff:g id="DEVICE_NAME">%1$s</xliff:g>తో జత చేయడం సాధ్యపడలేదు."</string>
<string name="bluetooth_pairing_device_down_error_message" msgid="7870998403045801381">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g>తో కమ్యూనికేట్ చేయడం సాధ్యపడదు."</string>
<string name="bluetooth_pairing_rejected_error_message" msgid="1648157108520832454">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> జత చేయడాన్ని తిరస్కరించింది."</string>
- <!-- no translation found for accessibility_wifi_off (1166761729660614716) -->
- <skip />
- <!-- no translation found for accessibility_no_wifi (8834610636137374508) -->
- <skip />
- <!-- no translation found for accessibility_wifi_one_bar (4869376278894301820) -->
- <skip />
- <!-- no translation found for accessibility_wifi_two_bars (3569851234710034416) -->
- <skip />
- <!-- no translation found for accessibility_wifi_three_bars (8134185644861380311) -->
- <skip />
- <!-- no translation found for accessibility_wifi_signal_full (7061045677694702) -->
- <skip />
+ <string name="accessibility_wifi_off" msgid="1166761729660614716">"Wifi ఆఫ్లో ఉంది."</string>
+ <string name="accessibility_no_wifi" msgid="8834610636137374508">"Wifi డిస్కనెక్ట్ చేయబడింది."</string>
+ <string name="accessibility_wifi_one_bar" msgid="4869376278894301820">"Wifi సిగ్నల్ ఒక బార్ ఉంది."</string>
+ <string name="accessibility_wifi_two_bars" msgid="3569851234710034416">"Wifi సిగ్నల్ రెండు బార్లు ఉంది."</string>
+ <string name="accessibility_wifi_three_bars" msgid="8134185644861380311">"Wifi సిగ్నల్ మూడు బార్లు ఉంది."</string>
+ <string name="accessibility_wifi_signal_full" msgid="7061045677694702">"Wifi సిగ్నల్ పూర్తిగా ఉంది."</string>
</resources>
diff --git a/packages/SettingsLib/res/values-th/strings.xml b/packages/SettingsLib/res/values-th/strings.xml
index 2bb7b34..a8c874c 100644
--- a/packages/SettingsLib/res/values-th/strings.xml
+++ b/packages/SettingsLib/res/values-th/strings.xml
@@ -77,16 +77,10 @@
<string name="bluetooth_pairing_pin_error_message" msgid="8337234855188925274">"ไม่สามารถจับคู่กับ <xliff:g id="DEVICE_NAME">%1$s</xliff:g> ได้เพราะ PIN หรือรหัสผ่านไม่ถูกต้อง"</string>
<string name="bluetooth_pairing_device_down_error_message" msgid="7870998403045801381">"ไม่สามารถเชื่อมต่อกับ <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
<string name="bluetooth_pairing_rejected_error_message" msgid="1648157108520832454">"การกำหนดค่าอุปกรณ์ให้ตรงกันถูกปฏิเสธโดย <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
- <!-- no translation found for accessibility_wifi_off (1166761729660614716) -->
- <skip />
- <!-- no translation found for accessibility_no_wifi (8834610636137374508) -->
- <skip />
- <!-- no translation found for accessibility_wifi_one_bar (4869376278894301820) -->
- <skip />
- <!-- no translation found for accessibility_wifi_two_bars (3569851234710034416) -->
- <skip />
- <!-- no translation found for accessibility_wifi_three_bars (8134185644861380311) -->
- <skip />
- <!-- no translation found for accessibility_wifi_signal_full (7061045677694702) -->
- <skip />
+ <string name="accessibility_wifi_off" msgid="1166761729660614716">"Wi-Fi ปิดอยู่"</string>
+ <string name="accessibility_no_wifi" msgid="8834610636137374508">"ไม่ได้เชื่อมต่อ Wi-Fi"</string>
+ <string name="accessibility_wifi_one_bar" msgid="4869376278894301820">"สัญญาณ Wi-Fi 1 ขีด"</string>
+ <string name="accessibility_wifi_two_bars" msgid="3569851234710034416">"สัญญาณ Wi-Fi 2 ขีด"</string>
+ <string name="accessibility_wifi_three_bars" msgid="8134185644861380311">"สัญญาณ Wi-Fi 3 ขีด"</string>
+ <string name="accessibility_wifi_signal_full" msgid="7061045677694702">"สัญญาณ Wi-Fi เต็ม"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-tl/strings.xml b/packages/SettingsLib/res/values-tl/strings.xml
index 6a94c4c..1ff256d 100644
--- a/packages/SettingsLib/res/values-tl/strings.xml
+++ b/packages/SettingsLib/res/values-tl/strings.xml
@@ -77,16 +77,10 @@
<string name="bluetooth_pairing_pin_error_message" msgid="8337234855188925274">"Hindi maipares sa <xliff:g id="DEVICE_NAME">%1$s</xliff:g> dahil sa maling PIN o passkey."</string>
<string name="bluetooth_pairing_device_down_error_message" msgid="7870998403045801381">"Hindi magawang makipag-ugnay sa <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
<string name="bluetooth_pairing_rejected_error_message" msgid="1648157108520832454">"Tinanggihan ng <xliff:g id="DEVICE_NAME">%1$s</xliff:g> ang pagpapares."</string>
- <!-- no translation found for accessibility_wifi_off (1166761729660614716) -->
- <skip />
- <!-- no translation found for accessibility_no_wifi (8834610636137374508) -->
- <skip />
- <!-- no translation found for accessibility_wifi_one_bar (4869376278894301820) -->
- <skip />
- <!-- no translation found for accessibility_wifi_two_bars (3569851234710034416) -->
- <skip />
- <!-- no translation found for accessibility_wifi_three_bars (8134185644861380311) -->
- <skip />
- <!-- no translation found for accessibility_wifi_signal_full (7061045677694702) -->
- <skip />
+ <string name="accessibility_wifi_off" msgid="1166761729660614716">"Naka-off ang Wifi."</string>
+ <string name="accessibility_no_wifi" msgid="8834610636137374508">"Nakadiskonekta ang Wifi."</string>
+ <string name="accessibility_wifi_one_bar" msgid="4869376278894301820">"May isang bar ang Wifi."</string>
+ <string name="accessibility_wifi_two_bars" msgid="3569851234710034416">"May dalawang bar ang Wifi."</string>
+ <string name="accessibility_wifi_three_bars" msgid="8134185644861380311">"May tatlong bar ang Wifi."</string>
+ <string name="accessibility_wifi_signal_full" msgid="7061045677694702">"Puno ang signal ng Wifi."</string>
</resources>
diff --git a/packages/SettingsLib/res/values-tr/strings.xml b/packages/SettingsLib/res/values-tr/strings.xml
index d89a0f4..258c03c 100644
--- a/packages/SettingsLib/res/values-tr/strings.xml
+++ b/packages/SettingsLib/res/values-tr/strings.xml
@@ -77,16 +77,10 @@
<string name="bluetooth_pairing_pin_error_message" msgid="8337234855188925274">"PIN veya parola yanlış olduğundan <xliff:g id="DEVICE_NAME">%1$s</xliff:g> ile eşleştirilemedi"</string>
<string name="bluetooth_pairing_device_down_error_message" msgid="7870998403045801381">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> ile iletişim kurulamıyor."</string>
<string name="bluetooth_pairing_rejected_error_message" msgid="1648157108520832454">"Eşleştirme <xliff:g id="DEVICE_NAME">%1$s</xliff:g> tarafından reddedildi."</string>
- <!-- no translation found for accessibility_wifi_off (1166761729660614716) -->
- <skip />
- <!-- no translation found for accessibility_no_wifi (8834610636137374508) -->
- <skip />
- <!-- no translation found for accessibility_wifi_one_bar (4869376278894301820) -->
- <skip />
- <!-- no translation found for accessibility_wifi_two_bars (3569851234710034416) -->
- <skip />
- <!-- no translation found for accessibility_wifi_three_bars (8134185644861380311) -->
- <skip />
- <!-- no translation found for accessibility_wifi_signal_full (7061045677694702) -->
- <skip />
+ <string name="accessibility_wifi_off" msgid="1166761729660614716">"Kablosuz kapalı."</string>
+ <string name="accessibility_no_wifi" msgid="8834610636137374508">"Kablosuz bağlantı kesildi."</string>
+ <string name="accessibility_wifi_one_bar" msgid="4869376278894301820">"Kablosuz sinyal gücü tek çubuk."</string>
+ <string name="accessibility_wifi_two_bars" msgid="3569851234710034416">"Kablosuz sinyal gücü iki çubuk."</string>
+ <string name="accessibility_wifi_three_bars" msgid="8134185644861380311">"Kablosuz sinyal gücü üç çubuk."</string>
+ <string name="accessibility_wifi_signal_full" msgid="7061045677694702">"Kablosuz sinyal gücü tam."</string>
</resources>
diff --git a/packages/SettingsLib/res/values-uk/strings.xml b/packages/SettingsLib/res/values-uk/strings.xml
index fc719b8..3559d21 100644
--- a/packages/SettingsLib/res/values-uk/strings.xml
+++ b/packages/SettingsLib/res/values-uk/strings.xml
@@ -77,16 +77,10 @@
<string name="bluetooth_pairing_pin_error_message" msgid="8337234855188925274">"Не вдалося створити пару з пристроєм <xliff:g id="DEVICE_NAME">%1$s</xliff:g> через неправильний PIN-код чи ключ доступу."</string>
<string name="bluetooth_pairing_device_down_error_message" msgid="7870998403045801381">"Неможливо зв’язатися з пристроєм <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
<string name="bluetooth_pairing_rejected_error_message" msgid="1648157108520832454">"Створ. пари відхилено <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
- <!-- no translation found for accessibility_wifi_off (1166761729660614716) -->
- <skip />
- <!-- no translation found for accessibility_no_wifi (8834610636137374508) -->
- <skip />
- <!-- no translation found for accessibility_wifi_one_bar (4869376278894301820) -->
- <skip />
- <!-- no translation found for accessibility_wifi_two_bars (3569851234710034416) -->
- <skip />
- <!-- no translation found for accessibility_wifi_three_bars (8134185644861380311) -->
- <skip />
- <!-- no translation found for accessibility_wifi_signal_full (7061045677694702) -->
- <skip />
+ <string name="accessibility_wifi_off" msgid="1166761729660614716">"Wi-Fi вимкнено."</string>
+ <string name="accessibility_no_wifi" msgid="8834610636137374508">"Wi-Fi від’єднано."</string>
+ <string name="accessibility_wifi_one_bar" msgid="4869376278894301820">"Одна смужка сигналу Wi-Fi."</string>
+ <string name="accessibility_wifi_two_bars" msgid="3569851234710034416">"Дві смужки сигналу Wi-Fi."</string>
+ <string name="accessibility_wifi_three_bars" msgid="8134185644861380311">"Три смужки сигналу Wi-Fi."</string>
+ <string name="accessibility_wifi_signal_full" msgid="7061045677694702">"Максимальний сигнал Wi-Fi."</string>
</resources>
diff --git a/packages/SettingsLib/res/values-ur-rPK/strings.xml b/packages/SettingsLib/res/values-ur-rPK/strings.xml
index ddc9b19..b9e72d2 100644
--- a/packages/SettingsLib/res/values-ur-rPK/strings.xml
+++ b/packages/SettingsLib/res/values-ur-rPK/strings.xml
@@ -77,16 +77,10 @@
<string name="bluetooth_pairing_pin_error_message" msgid="8337234855188925274">"غلط PIN یا پاس کلید کی وجہ سے <xliff:g id="DEVICE_NAME">%1$s</xliff:g> کے ساتھ جوڑا نہیں بنا سکا۔"</string>
<string name="bluetooth_pairing_device_down_error_message" msgid="7870998403045801381">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> کے ساتھ مواصلت نہیں ہو سکتی۔"</string>
<string name="bluetooth_pairing_rejected_error_message" msgid="1648157108520832454">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> نے جوڑا بنانے کو مسترد کر دیا۔"</string>
- <!-- no translation found for accessibility_wifi_off (1166761729660614716) -->
- <skip />
- <!-- no translation found for accessibility_no_wifi (8834610636137374508) -->
- <skip />
- <!-- no translation found for accessibility_wifi_one_bar (4869376278894301820) -->
- <skip />
- <!-- no translation found for accessibility_wifi_two_bars (3569851234710034416) -->
- <skip />
- <!-- no translation found for accessibility_wifi_three_bars (8134185644861380311) -->
- <skip />
- <!-- no translation found for accessibility_wifi_signal_full (7061045677694702) -->
- <skip />
+ <string name="accessibility_wifi_off" msgid="1166761729660614716">"Wifi آف ہے۔"</string>
+ <string name="accessibility_no_wifi" msgid="8834610636137374508">"Wifi غیر منسلک ہو گیا۔"</string>
+ <string name="accessibility_wifi_one_bar" msgid="4869376278894301820">"Wifi ایک بار۔"</string>
+ <string name="accessibility_wifi_two_bars" msgid="3569851234710034416">"Wifi دو بارز۔"</string>
+ <string name="accessibility_wifi_three_bars" msgid="8134185644861380311">"Wifi تین بارز۔"</string>
+ <string name="accessibility_wifi_signal_full" msgid="7061045677694702">"Wifi سگنل پورا ہے۔"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-uz-rUZ/strings.xml b/packages/SettingsLib/res/values-uz-rUZ/strings.xml
index 612c4b3..ba33886 100644
--- a/packages/SettingsLib/res/values-uz-rUZ/strings.xml
+++ b/packages/SettingsLib/res/values-uz-rUZ/strings.xml
@@ -23,7 +23,7 @@
<string name="wifi_fail_to_scan" msgid="1265540342578081461">"Tarmoqlarni tekshirib chiqishni iloji bo‘lmadi"</string>
<string name="wifi_security_none" msgid="7985461072596594400">"Yo‘q"</string>
<string name="wifi_remembered" msgid="4955746899347821096">"Saqlandi"</string>
- <string name="wifi_disabled_generic" msgid="4259794910584943386">"O\'chirilgan"</string>
+ <string name="wifi_disabled_generic" msgid="4259794910584943386">"O‘chiq"</string>
<string name="wifi_disabled_network_failure" msgid="2364951338436007124">"IP manzilini sozlab bo‘lmadi"</string>
<string name="wifi_disabled_wifi_failure" msgid="3081668066612876581">"Wi-Fi ulanishini o‘rnatib bo‘lmadi"</string>
<string name="wifi_disabled_password_failure" msgid="8659805351763133575">"Tasdiqdan o‘tishda muammo"</string>
@@ -77,16 +77,10 @@
<string name="bluetooth_pairing_pin_error_message" msgid="8337234855188925274">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> qurilmasiga ulanib bo‘lmadi, chunki PIN-kod yoki parol noto‘g‘ri kiritildi."</string>
<string name="bluetooth_pairing_device_down_error_message" msgid="7870998403045801381">"Quyidagi qurilma javob bermayapti: <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
<string name="bluetooth_pairing_rejected_error_message" msgid="1648157108520832454">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> biriktirish so‘rovini rad qildi."</string>
- <!-- no translation found for accessibility_wifi_off (1166761729660614716) -->
- <skip />
- <!-- no translation found for accessibility_no_wifi (8834610636137374508) -->
- <skip />
- <!-- no translation found for accessibility_wifi_one_bar (4869376278894301820) -->
- <skip />
- <!-- no translation found for accessibility_wifi_two_bars (3569851234710034416) -->
- <skip />
- <!-- no translation found for accessibility_wifi_three_bars (8134185644861380311) -->
- <skip />
- <!-- no translation found for accessibility_wifi_signal_full (7061045677694702) -->
- <skip />
+ <string name="accessibility_wifi_off" msgid="1166761729660614716">"Wi-Fi o‘chiq."</string>
+ <string name="accessibility_no_wifi" msgid="8834610636137374508">"Wi-Fi o‘chirilgan."</string>
+ <string name="accessibility_wifi_one_bar" msgid="4869376278894301820">"Wi-Fi: bitta ustun"</string>
+ <string name="accessibility_wifi_two_bars" msgid="3569851234710034416">"Wi-Fi: ikkita ustun"</string>
+ <string name="accessibility_wifi_three_bars" msgid="8134185644861380311">"Wi-Fi: uchta ustun"</string>
+ <string name="accessibility_wifi_signal_full" msgid="7061045677694702">"Wi-Fi: signal to‘liq"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-vi/strings.xml b/packages/SettingsLib/res/values-vi/strings.xml
index 1e8326e..01236b0 100644
--- a/packages/SettingsLib/res/values-vi/strings.xml
+++ b/packages/SettingsLib/res/values-vi/strings.xml
@@ -77,16 +77,10 @@
<string name="bluetooth_pairing_pin_error_message" msgid="8337234855188925274">"Không thể ghép nối với <xliff:g id="DEVICE_NAME">%1$s</xliff:g> do mã PIN hoặc mã xác nhận không đúng."</string>
<string name="bluetooth_pairing_device_down_error_message" msgid="7870998403045801381">"Không thể kết nối với <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
<string name="bluetooth_pairing_rejected_error_message" msgid="1648157108520832454">"Ghép nối bị <xliff:g id="DEVICE_NAME">%1$s</xliff:g> từ chối."</string>
- <!-- no translation found for accessibility_wifi_off (1166761729660614716) -->
- <skip />
- <!-- no translation found for accessibility_no_wifi (8834610636137374508) -->
- <skip />
- <!-- no translation found for accessibility_wifi_one_bar (4869376278894301820) -->
- <skip />
- <!-- no translation found for accessibility_wifi_two_bars (3569851234710034416) -->
- <skip />
- <!-- no translation found for accessibility_wifi_three_bars (8134185644861380311) -->
- <skip />
- <!-- no translation found for accessibility_wifi_signal_full (7061045677694702) -->
- <skip />
+ <string name="accessibility_wifi_off" msgid="1166761729660614716">"Đã tắt Wi-Fi."</string>
+ <string name="accessibility_no_wifi" msgid="8834610636137374508">"Đã ngắt kết nối Wi-Fi."</string>
+ <string name="accessibility_wifi_one_bar" msgid="4869376278894301820">"Tín hiệu Wi-Fi một vạch."</string>
+ <string name="accessibility_wifi_two_bars" msgid="3569851234710034416">"Tín hiệu Wi-Fi hai vạch."</string>
+ <string name="accessibility_wifi_three_bars" msgid="8134185644861380311">"Tín hiệu Wi-Fi ba vạch."</string>
+ <string name="accessibility_wifi_signal_full" msgid="7061045677694702">"Tín hiệu Wi-Fi đủ."</string>
</resources>
diff --git a/packages/SettingsLib/res/values-zh-rCN/strings.xml b/packages/SettingsLib/res/values-zh-rCN/strings.xml
index 20b002f..6d1717f 100644
--- a/packages/SettingsLib/res/values-zh-rCN/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rCN/strings.xml
@@ -77,16 +77,10 @@
<string name="bluetooth_pairing_pin_error_message" msgid="8337234855188925274">"PIN码或配对密钥不正确,无法与<xliff:g id="DEVICE_NAME">%1$s</xliff:g>配对。"</string>
<string name="bluetooth_pairing_device_down_error_message" msgid="7870998403045801381">"无法与“<xliff:g id="DEVICE_NAME">%1$s</xliff:g>”进行通信。"</string>
<string name="bluetooth_pairing_rejected_error_message" msgid="1648157108520832454">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> 已拒绝配对。"</string>
- <!-- no translation found for accessibility_wifi_off (1166761729660614716) -->
- <skip />
- <!-- no translation found for accessibility_no_wifi (8834610636137374508) -->
- <skip />
- <!-- no translation found for accessibility_wifi_one_bar (4869376278894301820) -->
- <skip />
- <!-- no translation found for accessibility_wifi_two_bars (3569851234710034416) -->
- <skip />
- <!-- no translation found for accessibility_wifi_three_bars (8134185644861380311) -->
- <skip />
- <!-- no translation found for accessibility_wifi_signal_full (7061045677694702) -->
- <skip />
+ <string name="accessibility_wifi_off" msgid="1166761729660614716">"WLAN 已关闭。"</string>
+ <string name="accessibility_no_wifi" msgid="8834610636137374508">"WLAN 连接已断开。"</string>
+ <string name="accessibility_wifi_one_bar" msgid="4869376278894301820">"WLAN 信号强度为一格。"</string>
+ <string name="accessibility_wifi_two_bars" msgid="3569851234710034416">"WLAN 信号强度为两格。"</string>
+ <string name="accessibility_wifi_three_bars" msgid="8134185644861380311">"WLAN 信号强度为三格。"</string>
+ <string name="accessibility_wifi_signal_full" msgid="7061045677694702">"WLAN 信号满格。"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-zh-rHK/strings.xml b/packages/SettingsLib/res/values-zh-rHK/strings.xml
index bbd288c..bea3e21 100644
--- a/packages/SettingsLib/res/values-zh-rHK/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rHK/strings.xml
@@ -77,16 +77,10 @@
<string name="bluetooth_pairing_pin_error_message" msgid="8337234855188925274">"無法與 <xliff:g id="DEVICE_NAME">%1$s</xliff:g> 配對,因為 PIN 碼或密鑰不正確。"</string>
<string name="bluetooth_pairing_device_down_error_message" msgid="7870998403045801381">"無法與 <xliff:g id="DEVICE_NAME">%1$s</xliff:g> 通訊。"</string>
<string name="bluetooth_pairing_rejected_error_message" msgid="1648157108520832454">"「<xliff:g id="DEVICE_NAME">%1$s</xliff:g>」拒絕配對要求。"</string>
- <!-- no translation found for accessibility_wifi_off (1166761729660614716) -->
- <skip />
- <!-- no translation found for accessibility_no_wifi (8834610636137374508) -->
- <skip />
- <!-- no translation found for accessibility_wifi_one_bar (4869376278894301820) -->
- <skip />
- <!-- no translation found for accessibility_wifi_two_bars (3569851234710034416) -->
- <skip />
- <!-- no translation found for accessibility_wifi_three_bars (8134185644861380311) -->
- <skip />
- <!-- no translation found for accessibility_wifi_signal_full (7061045677694702) -->
- <skip />
+ <string name="accessibility_wifi_off" msgid="1166761729660614716">"Wi-Fi 已關閉。"</string>
+ <string name="accessibility_no_wifi" msgid="8834610636137374508">"Wi-Fi 連線已中斷。"</string>
+ <string name="accessibility_wifi_one_bar" msgid="4869376278894301820">"Wi-Fi 訊號一格。"</string>
+ <string name="accessibility_wifi_two_bars" msgid="3569851234710034416">"Wi-Fi 訊號兩格。"</string>
+ <string name="accessibility_wifi_three_bars" msgid="8134185644861380311">"Wi-Fi 訊號三格。"</string>
+ <string name="accessibility_wifi_signal_full" msgid="7061045677694702">"Wi-Fi 訊號滿格。"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-zh-rTW/strings.xml b/packages/SettingsLib/res/values-zh-rTW/strings.xml
index 5864ec6..f9ed7ac 100644
--- a/packages/SettingsLib/res/values-zh-rTW/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rTW/strings.xml
@@ -77,16 +77,10 @@
<string name="bluetooth_pairing_pin_error_message" msgid="8337234855188925274">"無法與 <xliff:g id="DEVICE_NAME">%1$s</xliff:g> 配對,因為 PIN 或密碼金鑰不正確。"</string>
<string name="bluetooth_pairing_device_down_error_message" msgid="7870998403045801381">"無法與 <xliff:g id="DEVICE_NAME">%1$s</xliff:g> 通訊。"</string>
<string name="bluetooth_pairing_rejected_error_message" msgid="1648157108520832454">"「<xliff:g id="DEVICE_NAME">%1$s</xliff:g>」拒絕配對要求。"</string>
- <!-- no translation found for accessibility_wifi_off (1166761729660614716) -->
- <skip />
- <!-- no translation found for accessibility_no_wifi (8834610636137374508) -->
- <skip />
- <!-- no translation found for accessibility_wifi_one_bar (4869376278894301820) -->
- <skip />
- <!-- no translation found for accessibility_wifi_two_bars (3569851234710034416) -->
- <skip />
- <!-- no translation found for accessibility_wifi_three_bars (8134185644861380311) -->
- <skip />
- <!-- no translation found for accessibility_wifi_signal_full (7061045677694702) -->
- <skip />
+ <string name="accessibility_wifi_off" msgid="1166761729660614716">"已關閉 Wi-Fi。"</string>
+ <string name="accessibility_no_wifi" msgid="8834610636137374508">"Wi-Fi 連線已中斷。"</string>
+ <string name="accessibility_wifi_one_bar" msgid="4869376278894301820">"Wi-Fi 訊號強度一格。"</string>
+ <string name="accessibility_wifi_two_bars" msgid="3569851234710034416">"Wi-Fi 訊號強度兩格。"</string>
+ <string name="accessibility_wifi_three_bars" msgid="8134185644861380311">"Wi-Fi 訊號強度三格。"</string>
+ <string name="accessibility_wifi_signal_full" msgid="7061045677694702">"Wi-Fi 訊號強度滿格。"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-zu/strings.xml b/packages/SettingsLib/res/values-zu/strings.xml
index 328d6eb..08d6506 100644
--- a/packages/SettingsLib/res/values-zu/strings.xml
+++ b/packages/SettingsLib/res/values-zu/strings.xml
@@ -77,16 +77,10 @@
<string name="bluetooth_pairing_pin_error_message" msgid="8337234855188925274">"Ayikwazanga ukumataniswa ne <xliff:g id="DEVICE_NAME">%1$s</xliff:g> ngenxa ye-PIN noma isihluthulelo sokungena okungafanele."</string>
<string name="bluetooth_pairing_device_down_error_message" msgid="7870998403045801381">"Ayaikwazi ukuxhumana ne- <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
<string name="bluetooth_pairing_rejected_error_message" msgid="1648157108520832454">"Ukubhangqa kunqatshelwe i-<xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
- <!-- no translation found for accessibility_wifi_off (1166761729660614716) -->
- <skip />
- <!-- no translation found for accessibility_no_wifi (8834610636137374508) -->
- <skip />
- <!-- no translation found for accessibility_wifi_one_bar (4869376278894301820) -->
- <skip />
- <!-- no translation found for accessibility_wifi_two_bars (3569851234710034416) -->
- <skip />
- <!-- no translation found for accessibility_wifi_three_bars (8134185644861380311) -->
- <skip />
- <!-- no translation found for accessibility_wifi_signal_full (7061045677694702) -->
- <skip />
+ <string name="accessibility_wifi_off" msgid="1166761729660614716">"I-Wifi ivaliwe."</string>
+ <string name="accessibility_no_wifi" msgid="8834610636137374508">"I-Wifi inqanyuliwe."</string>
+ <string name="accessibility_wifi_one_bar" msgid="4869376278894301820">"Ibha elilodwa le-Wifi."</string>
+ <string name="accessibility_wifi_two_bars" msgid="3569851234710034416">"Amabha amabili we-Wifi."</string>
+ <string name="accessibility_wifi_three_bars" msgid="8134185644861380311">"Amabha amathathu we-Wifi."</string>
+ <string name="accessibility_wifi_signal_full" msgid="7061045677694702">"Isiginali ye-Wifi igcwele."</string>
</resources>
diff --git a/packages/SettingsLib/src/com/android/settingslib/TetherUtil.java b/packages/SettingsLib/src/com/android/settingslib/TetherUtil.java
index 58e5e29a..5294199 100644
--- a/packages/SettingsLib/src/com/android/settingslib/TetherUtil.java
+++ b/packages/SettingsLib/src/com/android/settingslib/TetherUtil.java
@@ -25,6 +25,7 @@
import android.os.SystemProperties;
import android.os.UserHandle;
import android.provider.Settings;
+import android.telephony.CarrierConfigManager;
public class TetherUtil {
@@ -54,29 +55,7 @@
public static boolean setWifiTethering(boolean enable, Context context) {
final WifiManager wifiManager =
(WifiManager) context.getSystemService(Context.WIFI_SERVICE);
- final ContentResolver cr = context.getContentResolver();
- /**
- * Disable Wifi if enabling tethering
- */
- int wifiState = wifiManager.getWifiState();
- if (enable && ((wifiState == WifiManager.WIFI_STATE_ENABLING) ||
- (wifiState == WifiManager.WIFI_STATE_ENABLED))) {
- wifiManager.setWifiEnabled(false);
- Settings.Global.putInt(cr, Settings.Global.WIFI_SAVED_STATE, 1);
- }
-
- boolean success = wifiManager.setWifiApEnabled(null, enable);
- /**
- * If needed, restore Wifi on tether disable
- */
- if (!enable) {
- int wifiSavedState = Settings.Global.getInt(cr, Settings.Global.WIFI_SAVED_STATE, 0);
- if (wifiSavedState == 1) {
- wifiManager.setWifiEnabled(true);
- Settings.Global.putInt(cr, Settings.Global.WIFI_SAVED_STATE, 0);
- }
- }
- return success;
+ return wifiManager.setWifiApEnabled(null, enable);
}
public static boolean isWifiTetherEnabled(Context context) {
@@ -84,6 +63,13 @@
return wifiManager.getWifiApState() == WifiManager.WIFI_AP_STATE_ENABLED;
}
+ private static boolean isEntitlementCheckRequired(Context context) {
+ final CarrierConfigManager configManager = (CarrierConfigManager) context
+ .getSystemService(Context.CARRIER_CONFIG_SERVICE);
+ return configManager.getConfig().getBoolean(CarrierConfigManager
+ .KEY_REQUIRE_ENTITLEMENT_CHECKS_BOOL);
+ }
+
public static boolean isProvisioningNeeded(Context context) {
// Keep in sync with other usage of config_mobile_hotspot_provision_app.
// ConnectivityManager#enforceTetherChangePermission
@@ -93,6 +79,10 @@
|| provisionApp == null) {
return false;
}
+ // Check carrier config for entitlement checks
+ if (isEntitlementCheckRequired(context) == false) {
+ return false;
+ }
return (provisionApp.length == 2);
}
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java
index 17fe24a..d994841 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java
@@ -539,10 +539,10 @@
* Otherwise, allow the connect on UUID change.
*/
if (!mProfiles.isEmpty()
- && ((mConnectAttempted + timeout) > SystemClock.elapsedRealtime()
- || (mConnectAttempted == 0))) {
+ && ((mConnectAttempted + timeout) > SystemClock.elapsedRealtime())) {
connectWithoutResettingTimer(false);
}
+
dispatchAttributesChanged();
}
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothAdapter.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothAdapter.java
index 0380e21..f935f31 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothAdapter.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothAdapter.java
@@ -19,6 +19,7 @@
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothProfile;
+import android.bluetooth.le.BluetoothLeScanner;
import android.content.Context;
import android.os.ParcelUuid;
import android.util.Log;
@@ -106,6 +107,10 @@
return mAdapter.getScanMode();
}
+ public BluetoothLeScanner getBluetoothLeScanner() {
+ return mAdapter.getBluetoothLeScanner();
+ }
+
public int getState() {
return mAdapter.getState();
}
diff --git a/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java b/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java
index c28288e..d3236d3 100644
--- a/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java
+++ b/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java
@@ -470,20 +470,7 @@
}
private void updateWifiState(int state) {
- if (state == WifiManager.WIFI_STATE_ENABLED) {
- if (mScanner != null) {
- // We only need to resume if mScanner isn't null because
- // that means we want to be scanning.
- mScanner.resume();
- }
- } else {
- mLastInfo = null;
- mLastNetworkInfo = null;
- if (mScanner != null) {
- mScanner.pause();
- }
- }
- mMainHandler.obtainMessage(MainHandler.MSG_WIFI_STATE_CHANGED, state, 0).sendToTarget();
+ mWorkHandler.obtainMessage(WorkHandler.MSG_UPDATE_WIFI_STATE, state, 0).sendToTarget();
}
public static List<AccessPoint> getCurrentAccessPoints(Context context, boolean includeSaved,
@@ -566,6 +553,7 @@
private static final int MSG_UPDATE_ACCESS_POINTS = 0;
private static final int MSG_UPDATE_NETWORK_INFO = 1;
private static final int MSG_RESUME = 2;
+ private static final int MSG_UPDATE_WIFI_STATE = 3;
public WorkHandler(Looper looper) {
super(looper);
@@ -583,6 +571,23 @@
case MSG_RESUME:
handleResume();
break;
+ case MSG_UPDATE_WIFI_STATE:
+ if (msg.arg1 == WifiManager.WIFI_STATE_ENABLED) {
+ if (mScanner != null) {
+ // We only need to resume if mScanner isn't null because
+ // that means we want to be scanning.
+ mScanner.resume();
+ }
+ } else {
+ mLastInfo = null;
+ mLastNetworkInfo = null;
+ if (mScanner != null) {
+ mScanner.pause();
+ }
+ }
+ mMainHandler.obtainMessage(MainHandler.MSG_WIFI_STATE_CHANGED, msg.arg1, 0)
+ .sendToTarget();
+ break;
}
}
}
diff --git a/packages/SettingsProvider/res/values-af/defaults.xml b/packages/SettingsProvider/res/values-af/defaults.xml
index 22443a5..4a87a12 100644
--- a/packages/SettingsProvider/res/values-af/defaults.xml
+++ b/packages/SettingsProvider/res/values-af/defaults.xml
@@ -21,4 +21,5 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="def_device_name" msgid="6309317409634339402">"%1$s %2$s"</string>
<string name="def_device_name_simple" msgid="9037785625140748221">"%1$s"</string>
+ <string name="def_nfc_payment_component" msgid="5861297439873026958"></string>
</resources>
diff --git a/packages/SettingsProvider/res/values-am/defaults.xml b/packages/SettingsProvider/res/values-am/defaults.xml
index 22443a5..4a87a12 100644
--- a/packages/SettingsProvider/res/values-am/defaults.xml
+++ b/packages/SettingsProvider/res/values-am/defaults.xml
@@ -21,4 +21,5 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="def_device_name" msgid="6309317409634339402">"%1$s %2$s"</string>
<string name="def_device_name_simple" msgid="9037785625140748221">"%1$s"</string>
+ <string name="def_nfc_payment_component" msgid="5861297439873026958"></string>
</resources>
diff --git a/packages/SettingsProvider/res/values-ar/defaults.xml b/packages/SettingsProvider/res/values-ar/defaults.xml
index 22443a5..4a87a12 100644
--- a/packages/SettingsProvider/res/values-ar/defaults.xml
+++ b/packages/SettingsProvider/res/values-ar/defaults.xml
@@ -21,4 +21,5 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="def_device_name" msgid="6309317409634339402">"%1$s %2$s"</string>
<string name="def_device_name_simple" msgid="9037785625140748221">"%1$s"</string>
+ <string name="def_nfc_payment_component" msgid="5861297439873026958"></string>
</resources>
diff --git a/packages/SettingsProvider/res/values-az-rAZ/defaults.xml b/packages/SettingsProvider/res/values-az-rAZ/defaults.xml
index 22443a5..4a87a12 100644
--- a/packages/SettingsProvider/res/values-az-rAZ/defaults.xml
+++ b/packages/SettingsProvider/res/values-az-rAZ/defaults.xml
@@ -21,4 +21,5 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="def_device_name" msgid="6309317409634339402">"%1$s %2$s"</string>
<string name="def_device_name_simple" msgid="9037785625140748221">"%1$s"</string>
+ <string name="def_nfc_payment_component" msgid="5861297439873026958"></string>
</resources>
diff --git a/packages/SettingsProvider/res/values-bg/defaults.xml b/packages/SettingsProvider/res/values-bg/defaults.xml
index aee229e..715e78f 100644
--- a/packages/SettingsProvider/res/values-bg/defaults.xml
+++ b/packages/SettingsProvider/res/values-bg/defaults.xml
@@ -21,4 +21,5 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="def_device_name" msgid="6309317409634339402">"%2$s от %1$s"</string>
<string name="def_device_name_simple" msgid="9037785625140748221">"%1$s"</string>
+ <string name="def_nfc_payment_component" msgid="5861297439873026958"></string>
</resources>
diff --git a/packages/SettingsProvider/res/values-bn-rBD/defaults.xml b/packages/SettingsProvider/res/values-bn-rBD/defaults.xml
index 22443a5..4a87a12 100644
--- a/packages/SettingsProvider/res/values-bn-rBD/defaults.xml
+++ b/packages/SettingsProvider/res/values-bn-rBD/defaults.xml
@@ -21,4 +21,5 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="def_device_name" msgid="6309317409634339402">"%1$s %2$s"</string>
<string name="def_device_name_simple" msgid="9037785625140748221">"%1$s"</string>
+ <string name="def_nfc_payment_component" msgid="5861297439873026958"></string>
</resources>
diff --git a/packages/SettingsProvider/res/values-ca/defaults.xml b/packages/SettingsProvider/res/values-ca/defaults.xml
index 22443a5..4a87a12 100644
--- a/packages/SettingsProvider/res/values-ca/defaults.xml
+++ b/packages/SettingsProvider/res/values-ca/defaults.xml
@@ -21,4 +21,5 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="def_device_name" msgid="6309317409634339402">"%1$s %2$s"</string>
<string name="def_device_name_simple" msgid="9037785625140748221">"%1$s"</string>
+ <string name="def_nfc_payment_component" msgid="5861297439873026958"></string>
</resources>
diff --git a/packages/SettingsProvider/res/values-cs/defaults.xml b/packages/SettingsProvider/res/values-cs/defaults.xml
index 22443a5..4a87a12 100644
--- a/packages/SettingsProvider/res/values-cs/defaults.xml
+++ b/packages/SettingsProvider/res/values-cs/defaults.xml
@@ -21,4 +21,5 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="def_device_name" msgid="6309317409634339402">"%1$s %2$s"</string>
<string name="def_device_name_simple" msgid="9037785625140748221">"%1$s"</string>
+ <string name="def_nfc_payment_component" msgid="5861297439873026958"></string>
</resources>
diff --git a/packages/SettingsProvider/res/values-da/defaults.xml b/packages/SettingsProvider/res/values-da/defaults.xml
index 22443a5..4a87a12 100644
--- a/packages/SettingsProvider/res/values-da/defaults.xml
+++ b/packages/SettingsProvider/res/values-da/defaults.xml
@@ -21,4 +21,5 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="def_device_name" msgid="6309317409634339402">"%1$s %2$s"</string>
<string name="def_device_name_simple" msgid="9037785625140748221">"%1$s"</string>
+ <string name="def_nfc_payment_component" msgid="5861297439873026958"></string>
</resources>
diff --git a/packages/SettingsProvider/res/values-de/defaults.xml b/packages/SettingsProvider/res/values-de/defaults.xml
index 22443a5..4a87a12 100644
--- a/packages/SettingsProvider/res/values-de/defaults.xml
+++ b/packages/SettingsProvider/res/values-de/defaults.xml
@@ -21,4 +21,5 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="def_device_name" msgid="6309317409634339402">"%1$s %2$s"</string>
<string name="def_device_name_simple" msgid="9037785625140748221">"%1$s"</string>
+ <string name="def_nfc_payment_component" msgid="5861297439873026958"></string>
</resources>
diff --git a/packages/SettingsProvider/res/values-el/defaults.xml b/packages/SettingsProvider/res/values-el/defaults.xml
index 22443a5..4a87a12 100644
--- a/packages/SettingsProvider/res/values-el/defaults.xml
+++ b/packages/SettingsProvider/res/values-el/defaults.xml
@@ -21,4 +21,5 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="def_device_name" msgid="6309317409634339402">"%1$s %2$s"</string>
<string name="def_device_name_simple" msgid="9037785625140748221">"%1$s"</string>
+ <string name="def_nfc_payment_component" msgid="5861297439873026958"></string>
</resources>
diff --git a/packages/SettingsProvider/res/values-en-rAU/defaults.xml b/packages/SettingsProvider/res/values-en-rAU/defaults.xml
index 22443a5..4a87a12 100644
--- a/packages/SettingsProvider/res/values-en-rAU/defaults.xml
+++ b/packages/SettingsProvider/res/values-en-rAU/defaults.xml
@@ -21,4 +21,5 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="def_device_name" msgid="6309317409634339402">"%1$s %2$s"</string>
<string name="def_device_name_simple" msgid="9037785625140748221">"%1$s"</string>
+ <string name="def_nfc_payment_component" msgid="5861297439873026958"></string>
</resources>
diff --git a/packages/SettingsProvider/res/values-en-rGB/defaults.xml b/packages/SettingsProvider/res/values-en-rGB/defaults.xml
index 22443a5..4a87a12 100644
--- a/packages/SettingsProvider/res/values-en-rGB/defaults.xml
+++ b/packages/SettingsProvider/res/values-en-rGB/defaults.xml
@@ -21,4 +21,5 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="def_device_name" msgid="6309317409634339402">"%1$s %2$s"</string>
<string name="def_device_name_simple" msgid="9037785625140748221">"%1$s"</string>
+ <string name="def_nfc_payment_component" msgid="5861297439873026958"></string>
</resources>
diff --git a/packages/SettingsProvider/res/values-en-rIN/defaults.xml b/packages/SettingsProvider/res/values-en-rIN/defaults.xml
index 22443a5..4a87a12 100644
--- a/packages/SettingsProvider/res/values-en-rIN/defaults.xml
+++ b/packages/SettingsProvider/res/values-en-rIN/defaults.xml
@@ -21,4 +21,5 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="def_device_name" msgid="6309317409634339402">"%1$s %2$s"</string>
<string name="def_device_name_simple" msgid="9037785625140748221">"%1$s"</string>
+ <string name="def_nfc_payment_component" msgid="5861297439873026958"></string>
</resources>
diff --git a/packages/SettingsProvider/res/values-es-rUS/defaults.xml b/packages/SettingsProvider/res/values-es-rUS/defaults.xml
index 22443a5..4a87a12 100644
--- a/packages/SettingsProvider/res/values-es-rUS/defaults.xml
+++ b/packages/SettingsProvider/res/values-es-rUS/defaults.xml
@@ -21,4 +21,5 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="def_device_name" msgid="6309317409634339402">"%1$s %2$s"</string>
<string name="def_device_name_simple" msgid="9037785625140748221">"%1$s"</string>
+ <string name="def_nfc_payment_component" msgid="5861297439873026958"></string>
</resources>
diff --git a/packages/SettingsProvider/res/values-es/defaults.xml b/packages/SettingsProvider/res/values-es/defaults.xml
index 22443a5..4a87a12 100644
--- a/packages/SettingsProvider/res/values-es/defaults.xml
+++ b/packages/SettingsProvider/res/values-es/defaults.xml
@@ -21,4 +21,5 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="def_device_name" msgid="6309317409634339402">"%1$s %2$s"</string>
<string name="def_device_name_simple" msgid="9037785625140748221">"%1$s"</string>
+ <string name="def_nfc_payment_component" msgid="5861297439873026958"></string>
</resources>
diff --git a/packages/SettingsProvider/res/values-et-rEE/defaults.xml b/packages/SettingsProvider/res/values-et-rEE/defaults.xml
index 71e91ae..5ec05cb 100644
--- a/packages/SettingsProvider/res/values-et-rEE/defaults.xml
+++ b/packages/SettingsProvider/res/values-et-rEE/defaults.xml
@@ -21,4 +21,5 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="def_device_name" msgid="6309317409634339402">"%2$s, %1$s"</string>
<string name="def_device_name_simple" msgid="9037785625140748221">"%1$s"</string>
+ <string name="def_nfc_payment_component" msgid="5861297439873026958"></string>
</resources>
diff --git a/packages/SettingsProvider/res/values-eu-rES/defaults.xml b/packages/SettingsProvider/res/values-eu-rES/defaults.xml
index 22443a5..4a87a12 100644
--- a/packages/SettingsProvider/res/values-eu-rES/defaults.xml
+++ b/packages/SettingsProvider/res/values-eu-rES/defaults.xml
@@ -21,4 +21,5 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="def_device_name" msgid="6309317409634339402">"%1$s %2$s"</string>
<string name="def_device_name_simple" msgid="9037785625140748221">"%1$s"</string>
+ <string name="def_nfc_payment_component" msgid="5861297439873026958"></string>
</resources>
diff --git a/packages/SettingsProvider/res/values-fa/defaults.xml b/packages/SettingsProvider/res/values-fa/defaults.xml
index 22443a5..4a87a12 100644
--- a/packages/SettingsProvider/res/values-fa/defaults.xml
+++ b/packages/SettingsProvider/res/values-fa/defaults.xml
@@ -21,4 +21,5 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="def_device_name" msgid="6309317409634339402">"%1$s %2$s"</string>
<string name="def_device_name_simple" msgid="9037785625140748221">"%1$s"</string>
+ <string name="def_nfc_payment_component" msgid="5861297439873026958"></string>
</resources>
diff --git a/packages/SettingsProvider/res/values-fi/defaults.xml b/packages/SettingsProvider/res/values-fi/defaults.xml
index 22443a5..4a87a12 100644
--- a/packages/SettingsProvider/res/values-fi/defaults.xml
+++ b/packages/SettingsProvider/res/values-fi/defaults.xml
@@ -21,4 +21,5 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="def_device_name" msgid="6309317409634339402">"%1$s %2$s"</string>
<string name="def_device_name_simple" msgid="9037785625140748221">"%1$s"</string>
+ <string name="def_nfc_payment_component" msgid="5861297439873026958"></string>
</resources>
diff --git a/packages/SettingsProvider/res/values-fr-rCA/defaults.xml b/packages/SettingsProvider/res/values-fr-rCA/defaults.xml
index beba56e..b728013 100644
--- a/packages/SettingsProvider/res/values-fr-rCA/defaults.xml
+++ b/packages/SettingsProvider/res/values-fr-rCA/defaults.xml
@@ -21,4 +21,5 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="def_device_name" msgid="6309317409634339402">"%2$s de %1$s"</string>
<string name="def_device_name_simple" msgid="9037785625140748221">"%1$s"</string>
+ <string name="def_nfc_payment_component" msgid="5861297439873026958"></string>
</resources>
diff --git a/packages/SettingsProvider/res/values-fr/defaults.xml b/packages/SettingsProvider/res/values-fr/defaults.xml
index 22443a5..4a87a12 100644
--- a/packages/SettingsProvider/res/values-fr/defaults.xml
+++ b/packages/SettingsProvider/res/values-fr/defaults.xml
@@ -21,4 +21,5 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="def_device_name" msgid="6309317409634339402">"%1$s %2$s"</string>
<string name="def_device_name_simple" msgid="9037785625140748221">"%1$s"</string>
+ <string name="def_nfc_payment_component" msgid="5861297439873026958"></string>
</resources>
diff --git a/packages/SettingsProvider/res/values-gl-rES/defaults.xml b/packages/SettingsProvider/res/values-gl-rES/defaults.xml
index 22443a5..4a87a12 100644
--- a/packages/SettingsProvider/res/values-gl-rES/defaults.xml
+++ b/packages/SettingsProvider/res/values-gl-rES/defaults.xml
@@ -21,4 +21,5 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="def_device_name" msgid="6309317409634339402">"%1$s %2$s"</string>
<string name="def_device_name_simple" msgid="9037785625140748221">"%1$s"</string>
+ <string name="def_nfc_payment_component" msgid="5861297439873026958"></string>
</resources>
diff --git a/packages/SettingsProvider/res/values-gu-rIN/defaults.xml b/packages/SettingsProvider/res/values-gu-rIN/defaults.xml
index 22443a5..4a87a12 100644
--- a/packages/SettingsProvider/res/values-gu-rIN/defaults.xml
+++ b/packages/SettingsProvider/res/values-gu-rIN/defaults.xml
@@ -21,4 +21,5 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="def_device_name" msgid="6309317409634339402">"%1$s %2$s"</string>
<string name="def_device_name_simple" msgid="9037785625140748221">"%1$s"</string>
+ <string name="def_nfc_payment_component" msgid="5861297439873026958"></string>
</resources>
diff --git a/packages/SettingsProvider/res/values-hi/defaults.xml b/packages/SettingsProvider/res/values-hi/defaults.xml
index 22443a5..4a87a12 100644
--- a/packages/SettingsProvider/res/values-hi/defaults.xml
+++ b/packages/SettingsProvider/res/values-hi/defaults.xml
@@ -21,4 +21,5 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="def_device_name" msgid="6309317409634339402">"%1$s %2$s"</string>
<string name="def_device_name_simple" msgid="9037785625140748221">"%1$s"</string>
+ <string name="def_nfc_payment_component" msgid="5861297439873026958"></string>
</resources>
diff --git a/packages/SettingsProvider/res/values-hr/defaults.xml b/packages/SettingsProvider/res/values-hr/defaults.xml
index 22443a5..4a87a12 100644
--- a/packages/SettingsProvider/res/values-hr/defaults.xml
+++ b/packages/SettingsProvider/res/values-hr/defaults.xml
@@ -21,4 +21,5 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="def_device_name" msgid="6309317409634339402">"%1$s %2$s"</string>
<string name="def_device_name_simple" msgid="9037785625140748221">"%1$s"</string>
+ <string name="def_nfc_payment_component" msgid="5861297439873026958"></string>
</resources>
diff --git a/packages/SettingsProvider/res/values-hu/defaults.xml b/packages/SettingsProvider/res/values-hu/defaults.xml
index 22443a5..4a87a12 100644
--- a/packages/SettingsProvider/res/values-hu/defaults.xml
+++ b/packages/SettingsProvider/res/values-hu/defaults.xml
@@ -21,4 +21,5 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="def_device_name" msgid="6309317409634339402">"%1$s %2$s"</string>
<string name="def_device_name_simple" msgid="9037785625140748221">"%1$s"</string>
+ <string name="def_nfc_payment_component" msgid="5861297439873026958"></string>
</resources>
diff --git a/packages/SettingsProvider/res/values-hy-rAM/defaults.xml b/packages/SettingsProvider/res/values-hy-rAM/defaults.xml
index 22443a5..4a87a12 100644
--- a/packages/SettingsProvider/res/values-hy-rAM/defaults.xml
+++ b/packages/SettingsProvider/res/values-hy-rAM/defaults.xml
@@ -21,4 +21,5 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="def_device_name" msgid="6309317409634339402">"%1$s %2$s"</string>
<string name="def_device_name_simple" msgid="9037785625140748221">"%1$s"</string>
+ <string name="def_nfc_payment_component" msgid="5861297439873026958"></string>
</resources>
diff --git a/packages/SettingsProvider/res/values-in/defaults.xml b/packages/SettingsProvider/res/values-in/defaults.xml
index 012a65f..71f1d3b 100644
--- a/packages/SettingsProvider/res/values-in/defaults.xml
+++ b/packages/SettingsProvider/res/values-in/defaults.xml
@@ -23,4 +23,5 @@
<!-- String.format failed for translation -->
<!-- no translation found for def_device_name_simple (9037785625140748221) -->
<skip />
+ <string name="def_nfc_payment_component" msgid="5861297439873026958"></string>
</resources>
diff --git a/packages/SettingsProvider/res/values-is-rIS/defaults.xml b/packages/SettingsProvider/res/values-is-rIS/defaults.xml
index 22443a5..4a87a12 100644
--- a/packages/SettingsProvider/res/values-is-rIS/defaults.xml
+++ b/packages/SettingsProvider/res/values-is-rIS/defaults.xml
@@ -21,4 +21,5 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="def_device_name" msgid="6309317409634339402">"%1$s %2$s"</string>
<string name="def_device_name_simple" msgid="9037785625140748221">"%1$s"</string>
+ <string name="def_nfc_payment_component" msgid="5861297439873026958"></string>
</resources>
diff --git a/packages/SettingsProvider/res/values-it/defaults.xml b/packages/SettingsProvider/res/values-it/defaults.xml
index 3ea32a1..524132e 100644
--- a/packages/SettingsProvider/res/values-it/defaults.xml
+++ b/packages/SettingsProvider/res/values-it/defaults.xml
@@ -21,4 +21,5 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="def_device_name" msgid="6309317409634339402">"%2$s %1$s"</string>
<string name="def_device_name_simple" msgid="9037785625140748221">"%1$s"</string>
+ <string name="def_nfc_payment_component" msgid="5861297439873026958"></string>
</resources>
diff --git a/packages/SettingsProvider/res/values-iw/defaults.xml b/packages/SettingsProvider/res/values-iw/defaults.xml
index 22443a5..4a87a12 100644
--- a/packages/SettingsProvider/res/values-iw/defaults.xml
+++ b/packages/SettingsProvider/res/values-iw/defaults.xml
@@ -21,4 +21,5 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="def_device_name" msgid="6309317409634339402">"%1$s %2$s"</string>
<string name="def_device_name_simple" msgid="9037785625140748221">"%1$s"</string>
+ <string name="def_nfc_payment_component" msgid="5861297439873026958"></string>
</resources>
diff --git a/packages/SettingsProvider/res/values-ja/defaults.xml b/packages/SettingsProvider/res/values-ja/defaults.xml
index 3ea32a1..524132e 100644
--- a/packages/SettingsProvider/res/values-ja/defaults.xml
+++ b/packages/SettingsProvider/res/values-ja/defaults.xml
@@ -21,4 +21,5 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="def_device_name" msgid="6309317409634339402">"%2$s %1$s"</string>
<string name="def_device_name_simple" msgid="9037785625140748221">"%1$s"</string>
+ <string name="def_nfc_payment_component" msgid="5861297439873026958"></string>
</resources>
diff --git a/packages/SettingsProvider/res/values-ka-rGE/defaults.xml b/packages/SettingsProvider/res/values-ka-rGE/defaults.xml
index 22443a5..4a87a12 100644
--- a/packages/SettingsProvider/res/values-ka-rGE/defaults.xml
+++ b/packages/SettingsProvider/res/values-ka-rGE/defaults.xml
@@ -21,4 +21,5 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="def_device_name" msgid="6309317409634339402">"%1$s %2$s"</string>
<string name="def_device_name_simple" msgid="9037785625140748221">"%1$s"</string>
+ <string name="def_nfc_payment_component" msgid="5861297439873026958"></string>
</resources>
diff --git a/packages/SettingsProvider/res/values-kk-rKZ/defaults.xml b/packages/SettingsProvider/res/values-kk-rKZ/defaults.xml
index 22443a5..4a87a12 100644
--- a/packages/SettingsProvider/res/values-kk-rKZ/defaults.xml
+++ b/packages/SettingsProvider/res/values-kk-rKZ/defaults.xml
@@ -21,4 +21,5 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="def_device_name" msgid="6309317409634339402">"%1$s %2$s"</string>
<string name="def_device_name_simple" msgid="9037785625140748221">"%1$s"</string>
+ <string name="def_nfc_payment_component" msgid="5861297439873026958"></string>
</resources>
diff --git a/packages/SettingsProvider/res/values-km-rKH/defaults.xml b/packages/SettingsProvider/res/values-km-rKH/defaults.xml
index 22443a5..4a87a12 100644
--- a/packages/SettingsProvider/res/values-km-rKH/defaults.xml
+++ b/packages/SettingsProvider/res/values-km-rKH/defaults.xml
@@ -21,4 +21,5 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="def_device_name" msgid="6309317409634339402">"%1$s %2$s"</string>
<string name="def_device_name_simple" msgid="9037785625140748221">"%1$s"</string>
+ <string name="def_nfc_payment_component" msgid="5861297439873026958"></string>
</resources>
diff --git a/packages/SettingsProvider/res/values-kn-rIN/defaults.xml b/packages/SettingsProvider/res/values-kn-rIN/defaults.xml
index 22443a5..4a87a12 100644
--- a/packages/SettingsProvider/res/values-kn-rIN/defaults.xml
+++ b/packages/SettingsProvider/res/values-kn-rIN/defaults.xml
@@ -21,4 +21,5 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="def_device_name" msgid="6309317409634339402">"%1$s %2$s"</string>
<string name="def_device_name_simple" msgid="9037785625140748221">"%1$s"</string>
+ <string name="def_nfc_payment_component" msgid="5861297439873026958"></string>
</resources>
diff --git a/packages/SettingsProvider/res/values-ko/defaults.xml b/packages/SettingsProvider/res/values-ko/defaults.xml
index 22443a5..4a87a12 100644
--- a/packages/SettingsProvider/res/values-ko/defaults.xml
+++ b/packages/SettingsProvider/res/values-ko/defaults.xml
@@ -21,4 +21,5 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="def_device_name" msgid="6309317409634339402">"%1$s %2$s"</string>
<string name="def_device_name_simple" msgid="9037785625140748221">"%1$s"</string>
+ <string name="def_nfc_payment_component" msgid="5861297439873026958"></string>
</resources>
diff --git a/packages/SettingsProvider/res/values-ky-rKG/defaults.xml b/packages/SettingsProvider/res/values-ky-rKG/defaults.xml
index 22443a5..4a87a12 100644
--- a/packages/SettingsProvider/res/values-ky-rKG/defaults.xml
+++ b/packages/SettingsProvider/res/values-ky-rKG/defaults.xml
@@ -21,4 +21,5 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="def_device_name" msgid="6309317409634339402">"%1$s %2$s"</string>
<string name="def_device_name_simple" msgid="9037785625140748221">"%1$s"</string>
+ <string name="def_nfc_payment_component" msgid="5861297439873026958"></string>
</resources>
diff --git a/packages/SettingsProvider/res/values-lo-rLA/defaults.xml b/packages/SettingsProvider/res/values-lo-rLA/defaults.xml
index 22443a5..4a87a12 100644
--- a/packages/SettingsProvider/res/values-lo-rLA/defaults.xml
+++ b/packages/SettingsProvider/res/values-lo-rLA/defaults.xml
@@ -21,4 +21,5 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="def_device_name" msgid="6309317409634339402">"%1$s %2$s"</string>
<string name="def_device_name_simple" msgid="9037785625140748221">"%1$s"</string>
+ <string name="def_nfc_payment_component" msgid="5861297439873026958"></string>
</resources>
diff --git a/packages/SettingsProvider/res/values-lt/defaults.xml b/packages/SettingsProvider/res/values-lt/defaults.xml
index 22443a5..4a87a12 100644
--- a/packages/SettingsProvider/res/values-lt/defaults.xml
+++ b/packages/SettingsProvider/res/values-lt/defaults.xml
@@ -21,4 +21,5 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="def_device_name" msgid="6309317409634339402">"%1$s %2$s"</string>
<string name="def_device_name_simple" msgid="9037785625140748221">"%1$s"</string>
+ <string name="def_nfc_payment_component" msgid="5861297439873026958"></string>
</resources>
diff --git a/packages/SettingsProvider/res/values-lv/defaults.xml b/packages/SettingsProvider/res/values-lv/defaults.xml
index 22443a5..4a87a12 100644
--- a/packages/SettingsProvider/res/values-lv/defaults.xml
+++ b/packages/SettingsProvider/res/values-lv/defaults.xml
@@ -21,4 +21,5 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="def_device_name" msgid="6309317409634339402">"%1$s %2$s"</string>
<string name="def_device_name_simple" msgid="9037785625140748221">"%1$s"</string>
+ <string name="def_nfc_payment_component" msgid="5861297439873026958"></string>
</resources>
diff --git a/packages/SettingsProvider/res/values-mk-rMK/defaults.xml b/packages/SettingsProvider/res/values-mk-rMK/defaults.xml
index 22443a5..4a87a12 100644
--- a/packages/SettingsProvider/res/values-mk-rMK/defaults.xml
+++ b/packages/SettingsProvider/res/values-mk-rMK/defaults.xml
@@ -21,4 +21,5 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="def_device_name" msgid="6309317409634339402">"%1$s %2$s"</string>
<string name="def_device_name_simple" msgid="9037785625140748221">"%1$s"</string>
+ <string name="def_nfc_payment_component" msgid="5861297439873026958"></string>
</resources>
diff --git a/packages/SettingsProvider/res/values-ml-rIN/defaults.xml b/packages/SettingsProvider/res/values-ml-rIN/defaults.xml
index 22443a5..4a87a12 100644
--- a/packages/SettingsProvider/res/values-ml-rIN/defaults.xml
+++ b/packages/SettingsProvider/res/values-ml-rIN/defaults.xml
@@ -21,4 +21,5 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="def_device_name" msgid="6309317409634339402">"%1$s %2$s"</string>
<string name="def_device_name_simple" msgid="9037785625140748221">"%1$s"</string>
+ <string name="def_nfc_payment_component" msgid="5861297439873026958"></string>
</resources>
diff --git a/packages/SettingsProvider/res/values-mn-rMN/defaults.xml b/packages/SettingsProvider/res/values-mn-rMN/defaults.xml
index 22443a5..4a87a12 100644
--- a/packages/SettingsProvider/res/values-mn-rMN/defaults.xml
+++ b/packages/SettingsProvider/res/values-mn-rMN/defaults.xml
@@ -21,4 +21,5 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="def_device_name" msgid="6309317409634339402">"%1$s %2$s"</string>
<string name="def_device_name_simple" msgid="9037785625140748221">"%1$s"</string>
+ <string name="def_nfc_payment_component" msgid="5861297439873026958"></string>
</resources>
diff --git a/packages/SettingsProvider/res/values-mr-rIN/defaults.xml b/packages/SettingsProvider/res/values-mr-rIN/defaults.xml
index 22443a5..4a87a12 100644
--- a/packages/SettingsProvider/res/values-mr-rIN/defaults.xml
+++ b/packages/SettingsProvider/res/values-mr-rIN/defaults.xml
@@ -21,4 +21,5 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="def_device_name" msgid="6309317409634339402">"%1$s %2$s"</string>
<string name="def_device_name_simple" msgid="9037785625140748221">"%1$s"</string>
+ <string name="def_nfc_payment_component" msgid="5861297439873026958"></string>
</resources>
diff --git a/packages/SettingsProvider/res/values-ms-rMY/defaults.xml b/packages/SettingsProvider/res/values-ms-rMY/defaults.xml
index 22443a5..4a87a12 100644
--- a/packages/SettingsProvider/res/values-ms-rMY/defaults.xml
+++ b/packages/SettingsProvider/res/values-ms-rMY/defaults.xml
@@ -21,4 +21,5 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="def_device_name" msgid="6309317409634339402">"%1$s %2$s"</string>
<string name="def_device_name_simple" msgid="9037785625140748221">"%1$s"</string>
+ <string name="def_nfc_payment_component" msgid="5861297439873026958"></string>
</resources>
diff --git a/packages/SettingsProvider/res/values-my-rMM/defaults.xml b/packages/SettingsProvider/res/values-my-rMM/defaults.xml
index 22443a5..4a87a12 100644
--- a/packages/SettingsProvider/res/values-my-rMM/defaults.xml
+++ b/packages/SettingsProvider/res/values-my-rMM/defaults.xml
@@ -21,4 +21,5 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="def_device_name" msgid="6309317409634339402">"%1$s %2$s"</string>
<string name="def_device_name_simple" msgid="9037785625140748221">"%1$s"</string>
+ <string name="def_nfc_payment_component" msgid="5861297439873026958"></string>
</resources>
diff --git a/packages/SettingsProvider/res/values-nb/defaults.xml b/packages/SettingsProvider/res/values-nb/defaults.xml
index 22443a5..4a87a12 100644
--- a/packages/SettingsProvider/res/values-nb/defaults.xml
+++ b/packages/SettingsProvider/res/values-nb/defaults.xml
@@ -21,4 +21,5 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="def_device_name" msgid="6309317409634339402">"%1$s %2$s"</string>
<string name="def_device_name_simple" msgid="9037785625140748221">"%1$s"</string>
+ <string name="def_nfc_payment_component" msgid="5861297439873026958"></string>
</resources>
diff --git a/packages/SettingsProvider/res/values-ne-rNP/defaults.xml b/packages/SettingsProvider/res/values-ne-rNP/defaults.xml
index 012a65f..71f1d3b 100644
--- a/packages/SettingsProvider/res/values-ne-rNP/defaults.xml
+++ b/packages/SettingsProvider/res/values-ne-rNP/defaults.xml
@@ -23,4 +23,5 @@
<!-- String.format failed for translation -->
<!-- no translation found for def_device_name_simple (9037785625140748221) -->
<skip />
+ <string name="def_nfc_payment_component" msgid="5861297439873026958"></string>
</resources>
diff --git a/packages/SettingsProvider/res/values-nl/defaults.xml b/packages/SettingsProvider/res/values-nl/defaults.xml
index 22443a5..4a87a12 100644
--- a/packages/SettingsProvider/res/values-nl/defaults.xml
+++ b/packages/SettingsProvider/res/values-nl/defaults.xml
@@ -21,4 +21,5 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="def_device_name" msgid="6309317409634339402">"%1$s %2$s"</string>
<string name="def_device_name_simple" msgid="9037785625140748221">"%1$s"</string>
+ <string name="def_nfc_payment_component" msgid="5861297439873026958"></string>
</resources>
diff --git a/packages/SettingsProvider/res/values-pa-rIN/defaults.xml b/packages/SettingsProvider/res/values-pa-rIN/defaults.xml
index 22443a5..4a87a12 100644
--- a/packages/SettingsProvider/res/values-pa-rIN/defaults.xml
+++ b/packages/SettingsProvider/res/values-pa-rIN/defaults.xml
@@ -21,4 +21,5 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="def_device_name" msgid="6309317409634339402">"%1$s %2$s"</string>
<string name="def_device_name_simple" msgid="9037785625140748221">"%1$s"</string>
+ <string name="def_nfc_payment_component" msgid="5861297439873026958"></string>
</resources>
diff --git a/packages/SettingsProvider/res/values-pl/defaults.xml b/packages/SettingsProvider/res/values-pl/defaults.xml
index 22443a5..4a87a12 100644
--- a/packages/SettingsProvider/res/values-pl/defaults.xml
+++ b/packages/SettingsProvider/res/values-pl/defaults.xml
@@ -21,4 +21,5 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="def_device_name" msgid="6309317409634339402">"%1$s %2$s"</string>
<string name="def_device_name_simple" msgid="9037785625140748221">"%1$s"</string>
+ <string name="def_nfc_payment_component" msgid="5861297439873026958"></string>
</resources>
diff --git a/packages/SettingsProvider/res/values-pt-rBR/defaults.xml b/packages/SettingsProvider/res/values-pt-rBR/defaults.xml
new file mode 100644
index 0000000..4a87a12
--- /dev/null
+++ b/packages/SettingsProvider/res/values-pt-rBR/defaults.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (c) 2009, 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.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="def_device_name" msgid="6309317409634339402">"%1$s %2$s"</string>
+ <string name="def_device_name_simple" msgid="9037785625140748221">"%1$s"</string>
+ <string name="def_nfc_payment_component" msgid="5861297439873026958"></string>
+</resources>
diff --git a/packages/SettingsProvider/res/values-pt-rBR/strings.xml b/packages/SettingsProvider/res/values-pt-rBR/strings.xml
new file mode 100644
index 0000000..ade1746
--- /dev/null
+++ b/packages/SettingsProvider/res/values-pt-rBR/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (c) 2007, 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.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_label" msgid="4567566098528588863">"Armazenamento de configurações"</string>
+</resources>
diff --git a/packages/SettingsProvider/res/values-pt-rPT/defaults.xml b/packages/SettingsProvider/res/values-pt-rPT/defaults.xml
index 22443a5..4a87a12 100644
--- a/packages/SettingsProvider/res/values-pt-rPT/defaults.xml
+++ b/packages/SettingsProvider/res/values-pt-rPT/defaults.xml
@@ -21,4 +21,5 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="def_device_name" msgid="6309317409634339402">"%1$s %2$s"</string>
<string name="def_device_name_simple" msgid="9037785625140748221">"%1$s"</string>
+ <string name="def_nfc_payment_component" msgid="5861297439873026958"></string>
</resources>
diff --git a/packages/SettingsProvider/res/values-pt/defaults.xml b/packages/SettingsProvider/res/values-pt/defaults.xml
index 22443a5..4a87a12 100644
--- a/packages/SettingsProvider/res/values-pt/defaults.xml
+++ b/packages/SettingsProvider/res/values-pt/defaults.xml
@@ -21,4 +21,5 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="def_device_name" msgid="6309317409634339402">"%1$s %2$s"</string>
<string name="def_device_name_simple" msgid="9037785625140748221">"%1$s"</string>
+ <string name="def_nfc_payment_component" msgid="5861297439873026958"></string>
</resources>
diff --git a/packages/SettingsProvider/res/values-ro/defaults.xml b/packages/SettingsProvider/res/values-ro/defaults.xml
index 22443a5..4a87a12 100644
--- a/packages/SettingsProvider/res/values-ro/defaults.xml
+++ b/packages/SettingsProvider/res/values-ro/defaults.xml
@@ -21,4 +21,5 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="def_device_name" msgid="6309317409634339402">"%1$s %2$s"</string>
<string name="def_device_name_simple" msgid="9037785625140748221">"%1$s"</string>
+ <string name="def_nfc_payment_component" msgid="5861297439873026958"></string>
</resources>
diff --git a/packages/SettingsProvider/res/values-ru/defaults.xml b/packages/SettingsProvider/res/values-ru/defaults.xml
index 3ea32a1..524132e 100644
--- a/packages/SettingsProvider/res/values-ru/defaults.xml
+++ b/packages/SettingsProvider/res/values-ru/defaults.xml
@@ -21,4 +21,5 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="def_device_name" msgid="6309317409634339402">"%2$s %1$s"</string>
<string name="def_device_name_simple" msgid="9037785625140748221">"%1$s"</string>
+ <string name="def_nfc_payment_component" msgid="5861297439873026958"></string>
</resources>
diff --git a/packages/SettingsProvider/res/values-si-rLK/defaults.xml b/packages/SettingsProvider/res/values-si-rLK/defaults.xml
index 22443a5..4a87a12 100644
--- a/packages/SettingsProvider/res/values-si-rLK/defaults.xml
+++ b/packages/SettingsProvider/res/values-si-rLK/defaults.xml
@@ -21,4 +21,5 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="def_device_name" msgid="6309317409634339402">"%1$s %2$s"</string>
<string name="def_device_name_simple" msgid="9037785625140748221">"%1$s"</string>
+ <string name="def_nfc_payment_component" msgid="5861297439873026958"></string>
</resources>
diff --git a/packages/SettingsProvider/res/values-sk/defaults.xml b/packages/SettingsProvider/res/values-sk/defaults.xml
index 22443a5..4a87a12 100644
--- a/packages/SettingsProvider/res/values-sk/defaults.xml
+++ b/packages/SettingsProvider/res/values-sk/defaults.xml
@@ -21,4 +21,5 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="def_device_name" msgid="6309317409634339402">"%1$s %2$s"</string>
<string name="def_device_name_simple" msgid="9037785625140748221">"%1$s"</string>
+ <string name="def_nfc_payment_component" msgid="5861297439873026958"></string>
</resources>
diff --git a/packages/SettingsProvider/res/values-sl/defaults.xml b/packages/SettingsProvider/res/values-sl/defaults.xml
index 22443a5..4a87a12 100644
--- a/packages/SettingsProvider/res/values-sl/defaults.xml
+++ b/packages/SettingsProvider/res/values-sl/defaults.xml
@@ -21,4 +21,5 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="def_device_name" msgid="6309317409634339402">"%1$s %2$s"</string>
<string name="def_device_name_simple" msgid="9037785625140748221">"%1$s"</string>
+ <string name="def_nfc_payment_component" msgid="5861297439873026958"></string>
</resources>
diff --git a/packages/SettingsProvider/res/values-sq-rAL/defaults.xml b/packages/SettingsProvider/res/values-sq-rAL/defaults.xml
index 22443a5..4a87a12 100644
--- a/packages/SettingsProvider/res/values-sq-rAL/defaults.xml
+++ b/packages/SettingsProvider/res/values-sq-rAL/defaults.xml
@@ -21,4 +21,5 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="def_device_name" msgid="6309317409634339402">"%1$s %2$s"</string>
<string name="def_device_name_simple" msgid="9037785625140748221">"%1$s"</string>
+ <string name="def_nfc_payment_component" msgid="5861297439873026958"></string>
</resources>
diff --git a/packages/SettingsProvider/res/values-sr/defaults.xml b/packages/SettingsProvider/res/values-sr/defaults.xml
index 3ea32a1..524132e 100644
--- a/packages/SettingsProvider/res/values-sr/defaults.xml
+++ b/packages/SettingsProvider/res/values-sr/defaults.xml
@@ -21,4 +21,5 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="def_device_name" msgid="6309317409634339402">"%2$s %1$s"</string>
<string name="def_device_name_simple" msgid="9037785625140748221">"%1$s"</string>
+ <string name="def_nfc_payment_component" msgid="5861297439873026958"></string>
</resources>
diff --git a/packages/SettingsProvider/res/values-sv/defaults.xml b/packages/SettingsProvider/res/values-sv/defaults.xml
index 22443a5..4a87a12 100644
--- a/packages/SettingsProvider/res/values-sv/defaults.xml
+++ b/packages/SettingsProvider/res/values-sv/defaults.xml
@@ -21,4 +21,5 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="def_device_name" msgid="6309317409634339402">"%1$s %2$s"</string>
<string name="def_device_name_simple" msgid="9037785625140748221">"%1$s"</string>
+ <string name="def_nfc_payment_component" msgid="5861297439873026958"></string>
</resources>
diff --git a/packages/SettingsProvider/res/values-sw/defaults.xml b/packages/SettingsProvider/res/values-sw/defaults.xml
index 22443a5..4a87a12 100644
--- a/packages/SettingsProvider/res/values-sw/defaults.xml
+++ b/packages/SettingsProvider/res/values-sw/defaults.xml
@@ -21,4 +21,5 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="def_device_name" msgid="6309317409634339402">"%1$s %2$s"</string>
<string name="def_device_name_simple" msgid="9037785625140748221">"%1$s"</string>
+ <string name="def_nfc_payment_component" msgid="5861297439873026958"></string>
</resources>
diff --git a/packages/SettingsProvider/res/values-ta-rIN/defaults.xml b/packages/SettingsProvider/res/values-ta-rIN/defaults.xml
index 22443a5..4a87a12 100644
--- a/packages/SettingsProvider/res/values-ta-rIN/defaults.xml
+++ b/packages/SettingsProvider/res/values-ta-rIN/defaults.xml
@@ -21,4 +21,5 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="def_device_name" msgid="6309317409634339402">"%1$s %2$s"</string>
<string name="def_device_name_simple" msgid="9037785625140748221">"%1$s"</string>
+ <string name="def_nfc_payment_component" msgid="5861297439873026958"></string>
</resources>
diff --git a/packages/SettingsProvider/res/values-te-rIN/defaults.xml b/packages/SettingsProvider/res/values-te-rIN/defaults.xml
index 22443a5..4a87a12 100644
--- a/packages/SettingsProvider/res/values-te-rIN/defaults.xml
+++ b/packages/SettingsProvider/res/values-te-rIN/defaults.xml
@@ -21,4 +21,5 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="def_device_name" msgid="6309317409634339402">"%1$s %2$s"</string>
<string name="def_device_name_simple" msgid="9037785625140748221">"%1$s"</string>
+ <string name="def_nfc_payment_component" msgid="5861297439873026958"></string>
</resources>
diff --git a/packages/SettingsProvider/res/values-th/defaults.xml b/packages/SettingsProvider/res/values-th/defaults.xml
index 22443a5..4a87a12 100644
--- a/packages/SettingsProvider/res/values-th/defaults.xml
+++ b/packages/SettingsProvider/res/values-th/defaults.xml
@@ -21,4 +21,5 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="def_device_name" msgid="6309317409634339402">"%1$s %2$s"</string>
<string name="def_device_name_simple" msgid="9037785625140748221">"%1$s"</string>
+ <string name="def_nfc_payment_component" msgid="5861297439873026958"></string>
</resources>
diff --git a/packages/SettingsProvider/res/values-tl/defaults.xml b/packages/SettingsProvider/res/values-tl/defaults.xml
index 22443a5..4a87a12 100644
--- a/packages/SettingsProvider/res/values-tl/defaults.xml
+++ b/packages/SettingsProvider/res/values-tl/defaults.xml
@@ -21,4 +21,5 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="def_device_name" msgid="6309317409634339402">"%1$s %2$s"</string>
<string name="def_device_name_simple" msgid="9037785625140748221">"%1$s"</string>
+ <string name="def_nfc_payment_component" msgid="5861297439873026958"></string>
</resources>
diff --git a/packages/SettingsProvider/res/values-tr/defaults.xml b/packages/SettingsProvider/res/values-tr/defaults.xml
index 22443a5..4a87a12 100644
--- a/packages/SettingsProvider/res/values-tr/defaults.xml
+++ b/packages/SettingsProvider/res/values-tr/defaults.xml
@@ -21,4 +21,5 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="def_device_name" msgid="6309317409634339402">"%1$s %2$s"</string>
<string name="def_device_name_simple" msgid="9037785625140748221">"%1$s"</string>
+ <string name="def_nfc_payment_component" msgid="5861297439873026958"></string>
</resources>
diff --git a/packages/SettingsProvider/res/values-uk/defaults.xml b/packages/SettingsProvider/res/values-uk/defaults.xml
index 7655a19..a8e1fe8 100644
--- a/packages/SettingsProvider/res/values-uk/defaults.xml
+++ b/packages/SettingsProvider/res/values-uk/defaults.xml
@@ -21,4 +21,5 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="def_device_name" msgid="6309317409634339402">"%2$s о %1$s"</string>
<string name="def_device_name_simple" msgid="9037785625140748221">"%1$s"</string>
+ <string name="def_nfc_payment_component" msgid="5861297439873026958"></string>
</resources>
diff --git a/packages/SettingsProvider/res/values-ur-rPK/defaults.xml b/packages/SettingsProvider/res/values-ur-rPK/defaults.xml
index 22443a5..4a87a12 100644
--- a/packages/SettingsProvider/res/values-ur-rPK/defaults.xml
+++ b/packages/SettingsProvider/res/values-ur-rPK/defaults.xml
@@ -21,4 +21,5 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="def_device_name" msgid="6309317409634339402">"%1$s %2$s"</string>
<string name="def_device_name_simple" msgid="9037785625140748221">"%1$s"</string>
+ <string name="def_nfc_payment_component" msgid="5861297439873026958"></string>
</resources>
diff --git a/packages/SettingsProvider/res/values-uz-rUZ/defaults.xml b/packages/SettingsProvider/res/values-uz-rUZ/defaults.xml
index 22443a5..4a87a12 100644
--- a/packages/SettingsProvider/res/values-uz-rUZ/defaults.xml
+++ b/packages/SettingsProvider/res/values-uz-rUZ/defaults.xml
@@ -21,4 +21,5 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="def_device_name" msgid="6309317409634339402">"%1$s %2$s"</string>
<string name="def_device_name_simple" msgid="9037785625140748221">"%1$s"</string>
+ <string name="def_nfc_payment_component" msgid="5861297439873026958"></string>
</resources>
diff --git a/packages/SettingsProvider/res/values-vi/defaults.xml b/packages/SettingsProvider/res/values-vi/defaults.xml
index 22443a5..4a87a12 100644
--- a/packages/SettingsProvider/res/values-vi/defaults.xml
+++ b/packages/SettingsProvider/res/values-vi/defaults.xml
@@ -21,4 +21,5 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="def_device_name" msgid="6309317409634339402">"%1$s %2$s"</string>
<string name="def_device_name_simple" msgid="9037785625140748221">"%1$s"</string>
+ <string name="def_nfc_payment_component" msgid="5861297439873026958"></string>
</resources>
diff --git a/packages/SettingsProvider/res/values-zh-rCN/defaults.xml b/packages/SettingsProvider/res/values-zh-rCN/defaults.xml
index 22443a5..4a87a12 100644
--- a/packages/SettingsProvider/res/values-zh-rCN/defaults.xml
+++ b/packages/SettingsProvider/res/values-zh-rCN/defaults.xml
@@ -21,4 +21,5 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="def_device_name" msgid="6309317409634339402">"%1$s %2$s"</string>
<string name="def_device_name_simple" msgid="9037785625140748221">"%1$s"</string>
+ <string name="def_nfc_payment_component" msgid="5861297439873026958"></string>
</resources>
diff --git a/packages/SettingsProvider/res/values-zh-rHK/defaults.xml b/packages/SettingsProvider/res/values-zh-rHK/defaults.xml
index 22443a5..4a87a12 100644
--- a/packages/SettingsProvider/res/values-zh-rHK/defaults.xml
+++ b/packages/SettingsProvider/res/values-zh-rHK/defaults.xml
@@ -21,4 +21,5 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="def_device_name" msgid="6309317409634339402">"%1$s %2$s"</string>
<string name="def_device_name_simple" msgid="9037785625140748221">"%1$s"</string>
+ <string name="def_nfc_payment_component" msgid="5861297439873026958"></string>
</resources>
diff --git a/packages/SettingsProvider/res/values-zh-rTW/defaults.xml b/packages/SettingsProvider/res/values-zh-rTW/defaults.xml
index 22443a5..4a87a12 100644
--- a/packages/SettingsProvider/res/values-zh-rTW/defaults.xml
+++ b/packages/SettingsProvider/res/values-zh-rTW/defaults.xml
@@ -21,4 +21,5 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="def_device_name" msgid="6309317409634339402">"%1$s %2$s"</string>
<string name="def_device_name_simple" msgid="9037785625140748221">"%1$s"</string>
+ <string name="def_nfc_payment_component" msgid="5861297439873026958"></string>
</resources>
diff --git a/packages/SettingsProvider/res/values-zu/defaults.xml b/packages/SettingsProvider/res/values-zu/defaults.xml
index 22443a5..4a87a12 100644
--- a/packages/SettingsProvider/res/values-zu/defaults.xml
+++ b/packages/SettingsProvider/res/values-zu/defaults.xml
@@ -21,4 +21,5 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="def_device_name" msgid="6309317409634339402">"%1$s %2$s"</string>
<string name="def_device_name_simple" msgid="9037785625140748221">"%1$s"</string>
+ <string name="def_nfc_payment_component" msgid="5861297439873026958"></string>
</resources>
diff --git a/packages/Shell/res/values-nl/strings.xml b/packages/Shell/res/values-nl/strings.xml
index 2936387..b0dba4d 100644
--- a/packages/Shell/res/values-nl/strings.xml
+++ b/packages/Shell/res/values-nl/strings.xml
@@ -18,8 +18,8 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="3701846017049540910">"Shell"</string>
<string name="bugreport_finished_title" msgid="2293711546892863898">"Foutenrapport vastgelegd"</string>
- <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"Veeg naar links om uw bugmelding te delen"</string>
- <string name="bugreport_finished_text" product="default" msgid="3559904746859400732">"Raak aan om uw foutenrapport te delen"</string>
+ <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"Veeg naar links om je bugmelding te delen"</string>
+ <string name="bugreport_finished_text" product="default" msgid="3559904746859400732">"Raak aan om je foutenrapport te delen"</string>
<string name="bugreport_confirm" msgid="5130698467795669780">"Foutenrapporten bevatten gegevens uit de verschillende logbestanden van het systeem, waaronder persoonlijke en privégegevens. Deel foutenrapporten alleen met apps en mensen die u vertrouwt."</string>
<string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Dit bericht de volgende keer weergeven"</string>
<string name="bugreport_storage_title" msgid="5332488144740527109">"Foutenrapporten"</string>
diff --git a/packages/Shell/res/values-pt-rBR/strings.xml b/packages/Shell/res/values-pt-rBR/strings.xml
new file mode 100644
index 0000000..e04d600
--- /dev/null
+++ b/packages/Shell/res/values-pt-rBR/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2013 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_label" msgid="3701846017049540910">"Shell"</string>
+ <string name="bugreport_finished_title" msgid="2293711546892863898">"Relatório de bugs capturado"</string>
+ <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"Deslize para a esquerda para compartilhar seu relatório de bugs"</string>
+ <string name="bugreport_finished_text" product="default" msgid="3559904746859400732">"Toque para compartilhar seu relatório de bugs"</string>
+ <string name="bugreport_confirm" msgid="5130698467795669780">"Os relatórios de bugs contêm dados de diversos arquivos de registro do sistema, inclusive informações pessoais e particulares. Compartilhe relatórios de bugs somente com apps e pessoas nos quais você confia."</string>
+ <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Mostrar esta mensagem da próxima vez"</string>
+ <string name="bugreport_storage_title" msgid="5332488144740527109">"Relatórios de bugs"</string>
+</resources>
diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml
index 677ab91..80f4d4c 100644
--- a/packages/SystemUI/AndroidManifest.xml
+++ b/packages/SystemUI/AndroidManifest.xml
@@ -108,6 +108,7 @@
<uses-permission android:name="android.permission.ACCESS_KEYGUARD_SECURE_STORAGE" />
<uses-permission android:name="android.permission.TRUST_LISTENER" />
<uses-permission android:name="android.permission.USE_FINGERPRINT" />
+ <uses-permission android:name="android.permission.RESET_FINGERPRINT_LOCKOUT" />
<!-- Needed for WallpaperManager.clear in ImageWallpaper.updateWallpaperLocked -->
<uses-permission android:name="android.permission.SET_WALLPAPER"/>
@@ -126,6 +127,9 @@
<!-- Assist -->
<uses-permission android:name="android.permission.ACCESS_VOICE_INTERACTION_SERVICE" />
+ <!-- Listen for keyboard attachment / detachment -->
+ <uses-permission android:name="android.permission.TABLET_MODE" />
+
<!-- Self permission for internal broadcasts. -->
<permission android:name="com.android.systemui.permission.SELF"
android:protectionLevel="signature" />
diff --git a/packages/SystemUI/res/anim/error_to_trustedstate_ellipse_path_1_animation.xml b/packages/SystemUI/res/anim/error_to_trustedstate_ellipse_path_1_animation.xml
new file mode 100755
index 0000000..1c50165
--- /dev/null
+++ b/packages/SystemUI/res/anim/error_to_trustedstate_ellipse_path_1_animation.xml
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<set
+ xmlns:android="http://schemas.android.com/apk/res/android" >
+ <objectAnimator
+ android:duration="600"
+ android:propertyName="strokeColor"
+ android:valueFrom="#FFF3511E"
+ android:valueTo="#FFFFFFFF"
+ android:interpolator="@android:interpolator/fast_out_slow_in" />
+ <objectAnimator
+ android:duration="600"
+ android:propertyName="strokeAlpha"
+ android:valueFrom="1.0"
+ android:valueTo="0.5"
+ android:valueType="floatType"
+ android:interpolator="@android:interpolator/fast_out_slow_in" />
+ <objectAnimator
+ android:duration="383"
+ android:propertyName="trimPathStart"
+ android:valueFrom="0.5001"
+ android:valueTo="0.0"
+ android:valueType="floatType"
+ android:interpolator="@interpolator/error_to_trustedstate_animation_interpolator_3" />
+ <objectAnimator
+ android:duration="383"
+ android:propertyName="trimPathEnd"
+ android:valueFrom="1.5"
+ android:valueTo="0.0"
+ android:valueType="floatType"
+ android:interpolator="@interpolator/error_to_trustedstate_animation_interpolator_1" />
+</set>
diff --git a/packages/SystemUI/res/anim/error_to_trustedstate_ellipse_path_2_animation.xml b/packages/SystemUI/res/anim/error_to_trustedstate_ellipse_path_2_animation.xml
new file mode 100755
index 0000000..598255c
--- /dev/null
+++ b/packages/SystemUI/res/anim/error_to_trustedstate_ellipse_path_2_animation.xml
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<set
+ xmlns:android="http://schemas.android.com/apk/res/android" >
+ <set
+ android:ordering="sequentially" >
+ <objectAnimator
+ android:duration="316"
+ android:propertyName="pathData"
+ android:valueFrom="M 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 Z"
+ android:valueTo="M 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 Z"
+ android:valueType="pathType"
+ android:interpolator="@android:interpolator/linear" />
+ <objectAnimator
+ android:duration="233"
+ android:propertyName="pathData"
+ android:valueFrom="M 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 Z"
+ android:valueTo="M 0.0,-1.988645 c 1.09829830627,0.0 1.988645,0.890346693734 1.988645,1.988645 c 0.0,1.09829830627 -0.890346693734,1.988645 -1.988645,1.988645 c -1.09829830627,0.0 -1.988645,-0.890346693734 -1.988645,-1.988645 c 0.0,-1.09829830627 0.890346693734,-1.988645 1.988645,-1.988645 Z"
+ android:valueType="pathType"
+ android:interpolator="@interpolator/error_to_trustedstate_animation_interpolator_1" />
+ </set>
+ <objectAnimator
+ android:duration="600"
+ android:propertyName="fillColor"
+ android:valueFrom="#FFF3511E"
+ android:valueTo="#FFFFFFFF"
+ android:interpolator="@android:interpolator/fast_out_slow_in" />
+ <objectAnimator
+ android:duration="600"
+ android:propertyName="fillAlpha"
+ android:valueFrom="1.0"
+ android:valueTo="0.5"
+ android:valueType="floatType"
+ android:interpolator="@android:interpolator/fast_out_slow_in" />
+</set>
diff --git a/packages/SystemUI/res/anim/error_to_trustedstate_exclamation_dot_animation.xml b/packages/SystemUI/res/anim/error_to_trustedstate_exclamation_dot_animation.xml
new file mode 100755
index 0000000..7e0fa43
--- /dev/null
+++ b/packages/SystemUI/res/anim/error_to_trustedstate_exclamation_dot_animation.xml
@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<set
+ xmlns:android="http://schemas.android.com/apk/res/android" >
+ <objectAnimator
+ android:duration="133"
+ android:propertyXName="translateX"
+ android:propertyYName="translateY"
+ android:pathData="M -0.00391,5.333 c 0.00065,-0.22217 0.00326,-1.11083 0.00391,-1.333"
+ android:interpolator="@interpolator/error_to_trustedstate_animation_interpolator_0" />
+ <set
+ android:ordering="sequentially" >
+ <objectAnimator
+ android:duration="83"
+ android:propertyName="scaleX"
+ android:valueFrom="1.0"
+ android:valueTo="1.0"
+ android:valueType="floatType"
+ android:interpolator="@android:interpolator/linear" />
+ <objectAnimator
+ android:duration="16"
+ android:propertyName="scaleX"
+ android:valueFrom="1.0"
+ android:valueTo="0.0"
+ android:valueType="floatType"
+ android:interpolator="@android:interpolator/linear" />
+ </set>
+ <set
+ android:ordering="sequentially" >
+ <objectAnimator
+ android:duration="83"
+ android:propertyName="scaleY"
+ android:valueFrom="1.0"
+ android:valueTo="1.0"
+ android:valueType="floatType"
+ android:interpolator="@android:interpolator/linear" />
+ <objectAnimator
+ android:duration="16"
+ android:propertyName="scaleY"
+ android:valueFrom="1.0"
+ android:valueTo="0.0"
+ android:valueType="floatType"
+ android:interpolator="@android:interpolator/linear" />
+ </set>
+</set>
diff --git a/packages/SystemUI/res/anim/error_to_trustedstate_lock_left_side_animation.xml b/packages/SystemUI/res/anim/error_to_trustedstate_lock_left_side_animation.xml
new file mode 100755
index 0000000..f413cbf
--- /dev/null
+++ b/packages/SystemUI/res/anim/error_to_trustedstate_lock_left_side_animation.xml
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<set
+ xmlns:android="http://schemas.android.com/apk/res/android" >
+ <set
+ android:ordering="sequentially" >
+ <objectAnimator
+ android:duration="33"
+ android:propertyName="scaleX"
+ android:valueFrom="1.33333"
+ android:valueTo="1.33333"
+ android:valueType="floatType"
+ android:interpolator="@android:interpolator/linear" />
+ <objectAnimator
+ android:duration="183"
+ android:propertyName="scaleX"
+ android:valueFrom="1.33333"
+ android:valueTo="1.0"
+ android:valueType="floatType"
+ android:interpolator="@android:interpolator/fast_out_slow_in" />
+ </set>
+ <set
+ android:ordering="sequentially" >
+ <objectAnimator
+ android:duration="33"
+ android:propertyName="scaleY"
+ android:valueFrom="1.33333"
+ android:valueTo="1.33333"
+ android:valueType="floatType"
+ android:interpolator="@android:interpolator/linear" />
+ <objectAnimator
+ android:duration="183"
+ android:propertyName="scaleY"
+ android:valueFrom="1.33333"
+ android:valueTo="1.0"
+ android:valueType="floatType"
+ android:interpolator="@android:interpolator/fast_out_slow_in" />
+ </set>
+</set>
diff --git a/packages/SystemUI/res/anim/error_to_trustedstate_lock_right_side_animation.xml b/packages/SystemUI/res/anim/error_to_trustedstate_lock_right_side_animation.xml
new file mode 100755
index 0000000..f413cbf
--- /dev/null
+++ b/packages/SystemUI/res/anim/error_to_trustedstate_lock_right_side_animation.xml
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<set
+ xmlns:android="http://schemas.android.com/apk/res/android" >
+ <set
+ android:ordering="sequentially" >
+ <objectAnimator
+ android:duration="33"
+ android:propertyName="scaleX"
+ android:valueFrom="1.33333"
+ android:valueTo="1.33333"
+ android:valueType="floatType"
+ android:interpolator="@android:interpolator/linear" />
+ <objectAnimator
+ android:duration="183"
+ android:propertyName="scaleX"
+ android:valueFrom="1.33333"
+ android:valueTo="1.0"
+ android:valueType="floatType"
+ android:interpolator="@android:interpolator/fast_out_slow_in" />
+ </set>
+ <set
+ android:ordering="sequentially" >
+ <objectAnimator
+ android:duration="33"
+ android:propertyName="scaleY"
+ android:valueFrom="1.33333"
+ android:valueTo="1.33333"
+ android:valueType="floatType"
+ android:interpolator="@android:interpolator/linear" />
+ <objectAnimator
+ android:duration="183"
+ android:propertyName="scaleY"
+ android:valueFrom="1.33333"
+ android:valueTo="1.0"
+ android:valueType="floatType"
+ android:interpolator="@android:interpolator/fast_out_slow_in" />
+ </set>
+</set>
diff --git a/packages/SystemUI/res/anim/error_to_trustedstate_lock_top_animation.xml b/packages/SystemUI/res/anim/error_to_trustedstate_lock_top_animation.xml
new file mode 100755
index 0000000..2518041
--- /dev/null
+++ b/packages/SystemUI/res/anim/error_to_trustedstate_lock_top_animation.xml
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<set
+ xmlns:android="http://schemas.android.com/apk/res/android" >
+ <set
+ android:ordering="sequentially" >
+ <objectAnimator
+ android:duration="333"
+ android:propertyName="scaleX"
+ android:valueFrom="0.0"
+ android:valueTo="0.0"
+ android:valueType="floatType"
+ android:interpolator="@android:interpolator/linear" />
+ <objectAnimator
+ android:duration="16"
+ android:propertyName="scaleX"
+ android:valueFrom="0.0"
+ android:valueTo="1.0"
+ android:valueType="floatType"
+ android:interpolator="@android:interpolator/linear" />
+ </set>
+ <set
+ android:ordering="sequentially" >
+ <objectAnimator
+ android:duration="333"
+ android:propertyName="scaleY"
+ android:valueFrom="0.0"
+ android:valueTo="0.0"
+ android:valueType="floatType"
+ android:interpolator="@android:interpolator/linear" />
+ <objectAnimator
+ android:duration="16"
+ android:propertyName="scaleY"
+ android:valueFrom="0.0"
+ android:valueTo="1.0"
+ android:valueType="floatType"
+ android:interpolator="@android:interpolator/linear" />
+ </set>
+</set>
diff --git a/packages/SystemUI/res/anim/error_to_trustedstate_path_1_animation.xml b/packages/SystemUI/res/anim/error_to_trustedstate_path_1_animation.xml
new file mode 100755
index 0000000..15f8d2e
--- /dev/null
+++ b/packages/SystemUI/res/anim/error_to_trustedstate_path_1_animation.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<set
+ xmlns:android="http://schemas.android.com/apk/res/android" >
+ <set
+ android:ordering="sequentially" >
+ <objectAnimator
+ android:duration="33"
+ android:propertyName="pathData"
+ android:valueFrom="M 0.02685546875,-4.96875 c 0.0,0.0 -0.005615234375,0.015625 -0.005615234375,0.015625 c 0.0,0.0 0.0,2.0 0.0,2.0 c 0.0,0.0 0.00375366210938,-0.015625 0.00375366210938,-0.015625 c 0.0,0.0 -0.00936889648438,3.9296875 -0.00936889648438,3.9296875 c 0.0,0.0 -0.0040283203125,0.015625 -0.0040283203125,0.015625 c 0.0,0.0 -0.0028076171875,0.0234375 -0.0028076171875,0.0234375 c 0.0,0.0 0.010498046875,-0.015625 0.010498046875,-0.015625 c 0.0,0.0 0.985595703125,0.0078125 0.985595703125,0.0078125 c 0.0,0.0 0.017578125,-6.015625 0.017578125,-6.015625 c 0.0,0.0 0.104400634766,0.0546875 -0.99560546875,0.0546875 Z"
+ android:valueTo="M 0.02685546875,-4.96875 c 0.0,0.0 -0.005615234375,0.015625 -0.005615234375,0.015625 c 0.0,0.0 0.0,2.0 0.0,2.0 c 0.0,0.0 0.00375366210938,-0.015625 0.00375366210938,-0.015625 c 0.0,0.0 -0.00936889648438,3.9296875 -0.00936889648438,3.9296875 c 0.0,0.0 -0.0040283203125,0.015625 -0.0040283203125,0.015625 c 0.0,0.0 -0.0028076171875,0.0234375 -0.0028076171875,0.0234375 c 0.0,0.0 0.010498046875,-0.015625 0.010498046875,-0.015625 c 0.0,0.0 0.985595703125,0.0078125 0.985595703125,0.0078125 c 0.0,0.0 0.017578125,-6.015625 0.017578125,-6.015625 c 0.0,0.0 0.104400634766,0.0546875 -0.99560546875,0.0546875 Z"
+ android:valueType="pathType"
+ android:interpolator="@android:interpolator/linear" />
+ <objectAnimator
+ android:duration="183"
+ android:propertyName="pathData"
+ android:valueFrom="M 0.02685546875,-4.96875 c 0.0,0.0 -0.005615234375,0.015625 -0.005615234375,0.015625 c 0.0,0.0 0.0,2.0 0.0,2.0 c 0.0,0.0 0.00375366210938,-0.015625 0.00375366210938,-0.015625 c 0.0,0.0 -0.00936889648438,3.9296875 -0.00936889648438,3.9296875 c 0.0,0.0 -0.0040283203125,0.015625 -0.0040283203125,0.015625 c 0.0,0.0 -0.0028076171875,0.0234375 -0.0028076171875,0.0234375 c 0.0,0.0 0.010498046875,-0.015625 0.010498046875,-0.015625 c 0.0,0.0 0.985595703125,0.0078125 0.985595703125,0.0078125 c 0.0,0.0 0.017578125,-6.015625 0.017578125,-6.015625 c 0.0,0.0 0.104400634766,0.0546875 -0.99560546875,0.0546875 Z"
+ android:valueTo="M 1.63623046875,-4.953125 c 0.0,0.0 -1.61499023438,0.0 -1.61499023438,0.0 c 0.0,0.0 0.0,2.0 0.0,2.0 c 0.0,0.0 0.00375366210938,-0.015625 0.00375366210938,-0.015625 c 0.0,0.0 0.0118713378906,7.9296875 0.0118713378906,7.9296875 c 0.0,0.0 -0.0040283203125,0.015625 -0.0040283203125,0.015625 c 0.0,0.0 -0.0052490234375,2.0 -0.0052490234375,2.0 c 0.0,0.0 1.61987304688,0.0 1.61987304688,0.0 c 1.10000610352,0.0 2.0,-0.900024414062 2.0,-2.0 c 0.0,0.0 -0.01123046875,-7.9296875 -0.01123046875,-7.9296875 c 0.0,-1.09997558594 -0.899993896484,-2.0 -2.0,-2.0 Z"
+ android:valueType="pathType"
+ android:interpolator="@android:interpolator/fast_out_slow_in" />
+ <objectAnimator
+ android:duration="316"
+ android:propertyName="pathData"
+ android:valueFrom="M 1.63623046875,-4.953125 c 0.0,0.0 -1.61499023438,0.0 -1.61499023438,0.0 c 0.0,0.0 0.0,2.0 0.0,2.0 c 0.0,0.0 0.00375366210938,-0.015625 0.00375366210938,-0.015625 c 0.0,0.0 0.0118713378906,7.9296875 0.0118713378906,7.9296875 c 0.0,0.0 -0.0040283203125,0.015625 -0.0040283203125,0.015625 c 0.0,0.0 -0.0052490234375,2.0 -0.0052490234375,2.0 c 0.0,0.0 1.61987304688,0.0 1.61987304688,0.0 c 1.10000610352,0.0 2.0,-0.900024414062 2.0,-2.0 c 0.0,0.0 -0.01123046875,-7.9296875 -0.01123046875,-7.9296875 c 0.0,-1.09997558594 -0.899993896484,-2.0 -2.0,-2.0 Z"
+ android:valueTo="M 6.00561523438,-4.046875 c 0.0,0.0 -5.98999023438,0.0 -5.98999023438,0.0 c 0.0,0.0 0.0,2.0 0.0,2.0 c 0.0,0.0 5.98812866211,0.0 5.98812866211,0.0 c 0.0,0.0 0.00064086914062,10.0 0.00064086914062,10.0 c 0.0,0.0 -5.98840332031,0.0 -5.98840332031,0.0 c 0.0,0.0 -0.0052490234375,2.0 -0.0052490234375,2.0 c 0.0,0.0 5.99487304688,0.0 5.99487304688,0.0 c 1.10000610352,0.0 2.0,-0.900024414062 2.0,-2.0 c 0.0,0.0 0.0,-10.0 0.0,-10.0 c 0.0,-1.09997558594 -0.899993896484,-2.0 -2.0,-2.0 Z"
+ android:valueType="pathType"
+ android:interpolator="@interpolator/error_to_trustedstate_animation_interpolator_4" />
+ </set>
+ <objectAnimator
+ android:duration="600"
+ android:propertyName="fillColor"
+ android:valueFrom="#FFF3511E"
+ android:valueTo="#FFFFFFFF"
+ android:interpolator="@android:interpolator/fast_out_slow_in" />
+ <objectAnimator
+ android:duration="600"
+ android:propertyName="fillAlpha"
+ android:valueFrom="1.0"
+ android:valueTo="0.5"
+ android:valueType="floatType"
+ android:interpolator="@android:interpolator/fast_out_slow_in" />
+</set>
diff --git a/packages/SystemUI/res/anim/error_to_trustedstate_path_2_animation.xml b/packages/SystemUI/res/anim/error_to_trustedstate_path_2_animation.xml
new file mode 100755
index 0000000..aa81fcf
--- /dev/null
+++ b/packages/SystemUI/res/anim/error_to_trustedstate_path_2_animation.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<set
+ xmlns:android="http://schemas.android.com/apk/res/android" >
+ <set
+ android:ordering="sequentially" >
+ <objectAnimator
+ android:duration="33"
+ android:propertyName="pathData"
+ android:valueFrom="M 0.0252990722656,-2.96914672852 c 0.0,0.0 -0.00390625,0.0160217285156 -0.00390625,0.0160217285156 c 0.0,0.0 -0.00015258789062,-2.0 -0.00015258789062,-2.0 c 0.0,0.0 0.005615234375,-0.015625 0.005615234375,-0.015625 c -1.10000610352,0.0 -1.01220703125,-0.0546875 -1.01220703125,-0.0546875 c 0.0,0.0 -0.017578125,6.015625 -0.017578125,6.015625 c 0.0,0.0 -0.0777893066406,-0.0078125 1.02221679688,-0.0078125 c 0.0,0.0 -0.005615234375,0.015625 -0.005615234375,0.015625 c 0.0,0.0 -0.002685546875,-0.0244140625 -0.002685546875,-0.0244140625 c 0.0,0.0 0.00390625,-0.0152587890625 0.00390625,-0.0152587890625 c 0.0,0.0 0.0104064941406,-3.92947387695 0.0104064941406,-3.92947387695 Z"
+ android:valueTo="M 0.0252990722656,-2.96914672852 c 0.0,0.0 -0.00390625,0.0160217285156 -0.00390625,0.0160217285156 c 0.0,0.0 -0.00015258789062,-2.0 -0.00015258789062,-2.0 c 0.0,0.0 0.005615234375,-0.015625 0.005615234375,-0.015625 c -1.10000610352,0.0 -1.01220703125,-0.0546875 -1.01220703125,-0.0546875 c 0.0,0.0 -0.017578125,6.015625 -0.017578125,6.015625 c 0.0,0.0 -0.0777893066406,-0.0078125 1.02221679688,-0.0078125 c 0.0,0.0 -0.005615234375,0.015625 -0.005615234375,0.015625 c 0.0,0.0 -0.002685546875,-0.0244140625 -0.002685546875,-0.0244140625 c 0.0,0.0 0.00390625,-0.0152587890625 0.00390625,-0.0152587890625 c 0.0,0.0 0.0104064941406,-3.92947387695 0.0104064941406,-3.92947387695 Z"
+ android:valueType="pathType"
+ android:interpolator="@android:interpolator/linear" />
+ <objectAnimator
+ android:duration="183"
+ android:propertyName="pathData"
+ android:valueFrom="M 0.0252990722656,-2.96914672852 c 0.0,0.0 -0.00390625,0.0160217285156 -0.00390625,0.0160217285156 c 0.0,0.0 -0.00015258789062,-2.0 -0.00015258789062,-2.0 c 0.0,0.0 0.005615234375,-0.015625 0.005615234375,-0.015625 c -1.10000610352,0.0 -1.01220703125,-0.0546875 -1.01220703125,-0.0546875 c 0.0,0.0 -0.017578125,6.015625 -0.017578125,6.015625 c 0.0,0.0 -0.0777893066406,-0.0078125 1.02221679688,-0.0078125 c 0.0,0.0 -0.005615234375,0.015625 -0.005615234375,0.015625 c 0.0,0.0 -0.002685546875,-0.0244140625 -0.002685546875,-0.0244140625 c 0.0,0.0 0.00390625,-0.0152587890625 0.00390625,-0.0152587890625 c 0.0,0.0 0.0104064941406,-3.92947387695 0.0104064941406,-3.92947387695 Z"
+ android:valueTo="M 0.0252990722656,-2.96975708008 c 0.0,0.0 -0.00390625,0.0166320800781 -0.00390625,0.0166320800781 c 0.0,0.0 -0.00015258789062,-2.0 -0.00015258789062,-2.0 c 0.0,0.0 -1.63500976562,0.0 -1.63500976562,0.0 c -1.10000610352,0.0 -2.0,0.900024414062 -2.0,2.0 c 0.0,0.0 0.01123046875,7.9296875 0.01123046875,7.9296875 c 0.0,1.09997558594 0.899993896484,2.0 2.0,2.0 c 0.0,0.0 1.63500976562,0.0 1.63500976562,0.0 c 0.0,0.0 -0.000244140625,-2.0009765625 -0.000244140625,-2.0009765625 c 0.0,0.0 0.00390625,-0.015869140625 0.00390625,-0.015869140625 c 0.0,0.0 -0.0108337402344,-7.92947387695 -0.0108337402344,-7.92947387695 Z"
+ android:valueType="pathType"
+ android:interpolator="@android:interpolator/fast_out_slow_in" />
+ <objectAnimator
+ android:duration="316"
+ android:propertyName="pathData"
+ android:valueFrom="M 0.0252990722656,-2.96975708008 c 0.0,0.0 -0.00390625,0.0166320800781 -0.00390625,0.0166320800781 c 0.0,0.0 -0.00015258789062,-2.0 -0.00015258789062,-2.0 c 0.0,0.0 -1.63500976562,0.0 -1.63500976562,0.0 c -1.10000610352,0.0 -2.0,0.900024414062 -2.0,2.0 c 0.0,0.0 0.01123046875,7.9296875 0.01123046875,7.9296875 c 0.0,1.09997558594 0.899993896484,2.0 2.0,2.0 c 0.0,0.0 1.63500976562,0.0 1.63500976562,0.0 c 0.0,0.0 -0.000244140625,-2.0009765625 -0.000244140625,-2.0009765625 c 0.0,0.0 0.00390625,-0.015869140625 0.00390625,-0.015869140625 c 0.0,0.0 -0.0108337402344,-7.92947387695 -0.0108337402344,-7.92947387695 Z"
+ android:valueTo="M -5.9959564209,-2.04727172852 c 0.0,0.0 6.01173400879,0.00039672851562 6.01173400879,0.00039672851562 c 0.0,0.0 -0.00015258789062,-2.0 -0.00015258789062,-2.0 c 0.0,0.0 -6.01000976562,0.0 -6.01000976562,0.0 c -1.10000610352,0.0 -2.0,0.900024414062 -2.0,2.0 c 0.0,0.0 0.0,10.0 0.0,10.0 c 0.0,1.09997558594 0.899993896484,2.0 2.0,2.0 c 0.0,0.0 6.01000976562,0.0 6.01000976562,0.0 c 0.0,0.0 -0.000244140625,-2.0009765625 -0.000244140625,-2.0009765625 c 0.0,0.0 -6.01171875,0.0003662109375 -6.01171875,0.0003662109375 c 0.0,0.0 0.00038146972656,-9.99978637695 0.00038146972656,-9.99978637695 Z"
+ android:valueType="pathType"
+ android:interpolator="@interpolator/error_to_trustedstate_animation_interpolator_4" />
+ </set>
+ <objectAnimator
+ android:duration="600"
+ android:propertyName="fillColor"
+ android:valueFrom="#FFF3511E"
+ android:valueTo="#FFFFFFFF"
+ android:interpolator="@android:interpolator/fast_out_slow_in" />
+ <objectAnimator
+ android:duration="600"
+ android:propertyName="fillAlpha"
+ android:valueFrom="1.0"
+ android:valueTo="0.5"
+ android:valueType="floatType"
+ android:interpolator="@android:interpolator/fast_out_slow_in" />
+</set>
diff --git a/packages/SystemUI/res/anim/error_to_trustedstate_path_3_animation.xml b/packages/SystemUI/res/anim/error_to_trustedstate_path_3_animation.xml
new file mode 100755
index 0000000..f94fe0a
--- /dev/null
+++ b/packages/SystemUI/res/anim/error_to_trustedstate_path_3_animation.xml
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<set
+ xmlns:android="http://schemas.android.com/apk/res/android" >
+ <set
+ android:ordering="sequentially" >
+ <objectAnimator
+ android:duration="233"
+ android:propertyName="pathData"
+ android:valueFrom="M 5.01239013672,3.390625 c 0.0,-2.76000976562 -2.23999023438,-5.0 -5.0,-5.0 c -2.76000976562,0.0 -5.0,2.23999023438 -5.0,5.0 c 0.0,0.0 1.89999389648,0.0 1.89999389648,0.0 c 0.0,-1.71002197266 1.38999938965,-3.09997558594 3.10000610352,-3.09997558594 c 1.71000671387,0.0 3.10000610352,1.38995361328 3.10000610352,3.09997558594 c 0.0,0.0 0.0,2.0 0.0,2.0 c 0.0,0.0 1.89999389648,0.0 1.89999389648,0.0 c 0.0,0.0 0.0,-2.0 0.0,-2.0 Z"
+ android:valueTo="M 5.01239013672,3.390625 c 0.0,-2.76000976562 -2.23999023438,-5.0 -5.0,-5.0 c -2.76000976562,0.0 -5.0,2.23999023438 -5.0,5.0 c 0.0,0.0 1.89999389648,0.0 1.89999389648,0.0 c 0.0,-1.71002197266 1.38999938965,-3.09997558594 3.10000610352,-3.09997558594 c 1.71000671387,0.0 3.10000610352,1.38995361328 3.10000610352,3.09997558594 c 0.0,0.0 0.0,2.0 0.0,2.0 c 0.0,0.0 1.89999389648,0.0 1.89999389648,0.0 c 0.0,0.0 0.0,-2.0 0.0,-2.0 Z"
+ android:valueType="pathType"
+ android:interpolator="@android:interpolator/linear" />
+ <objectAnimator
+ android:duration="366"
+ android:propertyName="pathData"
+ android:valueFrom="M 5.01239013672,3.390625 c 0.0,-2.76000976562 -2.23999023438,-5.0 -5.0,-5.0 c -2.76000976562,0.0 -5.0,2.23999023438 -5.0,5.0 c 0.0,0.0 1.89999389648,0.0 1.89999389648,0.0 c 0.0,-1.71002197266 1.38999938965,-3.09997558594 3.10000610352,-3.09997558594 c 1.71000671387,0.0 3.10000610352,1.38995361328 3.10000610352,3.09997558594 c 0.0,0.0 0.0,2.0 0.0,2.0 c 0.0,0.0 1.89999389648,0.0 1.89999389648,0.0 c 0.0,0.0 0.0,-2.0 0.0,-2.0 Z"
+ android:valueTo="M 5.00619506836,-6.046875 c 0.0,-2.76000976562 -2.23999023438,-5.0 -5.0,-5.0 c -2.76000976562,0.0 -5.0,2.23999023438 -5.0,5.0 c 0.0,0.0 1.89999389648,0.0 1.89999389648,0.0 c 0.0,-1.71002197266 1.38999938965,-3.09997558594 3.10000610352,-3.09997558594 c 1.71000671387,0.0 3.10000610352,1.38995361328 3.10000610352,3.09997558594 c 0.0,0.0 0.0,2.0 0.0,2.0 c 0.0,0.0 1.89999389648,0.0 1.89999389648,0.0 c 0.0,0.0 0.0,-2.0 0.0,-2.0 Z"
+ android:valueType="pathType"
+ android:interpolator="@interpolator/error_to_trustedstate_animation_interpolator_2" />
+ </set>
+ <objectAnimator
+ android:duration="600"
+ android:propertyName="fillColor"
+ android:valueFrom="#FFF3511E"
+ android:valueTo="#FFFFFFFF"
+ android:interpolator="@android:interpolator/fast_out_slow_in" />
+ <objectAnimator
+ android:duration="600"
+ android:propertyName="fillAlpha"
+ android:valueFrom="1.0"
+ android:valueTo="0.5"
+ android:valueType="floatType"
+ android:interpolator="@android:interpolator/fast_out_slow_in" />
+</set>
diff --git a/packages/SystemUI/res/anim/error_to_trustedstate_rectangle_path_1_animation.xml b/packages/SystemUI/res/anim/error_to_trustedstate_rectangle_path_1_animation.xml
new file mode 100755
index 0000000..bcc8c41
--- /dev/null
+++ b/packages/SystemUI/res/anim/error_to_trustedstate_rectangle_path_1_animation.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<set
+ xmlns:android="http://schemas.android.com/apk/res/android" >
+ <objectAnimator
+ android:duration="600"
+ android:propertyName="fillColor"
+ android:valueFrom="#FFF3511E"
+ android:valueTo="#FFFFFFFF"
+ android:interpolator="@android:interpolator/fast_out_slow_in" />
+ <objectAnimator
+ android:duration="600"
+ android:propertyName="fillAlpha"
+ android:valueFrom="1.0"
+ android:valueTo="0.5"
+ android:valueType="floatType"
+ android:interpolator="@android:interpolator/fast_out_slow_in" />
+</set>
diff --git a/packages/SystemUI/res/anim/navbar_fade_in.xml b/packages/SystemUI/res/anim/navbar_fade_in.xml
index e3429e6..7051730 100644
--- a/packages/SystemUI/res/anim/navbar_fade_in.xml
+++ b/packages/SystemUI/res/anim/navbar_fade_in.xml
@@ -19,4 +19,5 @@
android:fromAlpha="0.0"
android:toAlpha="1.0"
android:interpolator="@android:interpolator/linear_out_slow_in"
+ android:startDelay="32"
android:duration="200"/>
diff --git a/packages/SystemUI/res/anim/trusted_state_to_error_ellipse_path_1_animation.xml b/packages/SystemUI/res/anim/trusted_state_to_error_ellipse_path_1_animation.xml
new file mode 100755
index 0000000..5cf4809
--- /dev/null
+++ b/packages/SystemUI/res/anim/trusted_state_to_error_ellipse_path_1_animation.xml
@@ -0,0 +1,66 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<set
+ xmlns:android="http://schemas.android.com/apk/res/android" >
+ <objectAnimator
+ android:duration="600"
+ android:propertyName="strokeColor"
+ android:valueFrom="#FFFFFFFF"
+ android:valueTo="#FFF3511E"
+ android:interpolator="@android:interpolator/fast_out_slow_in" />
+ <objectAnimator
+ android:duration="600"
+ android:propertyName="strokeAlpha"
+ android:valueFrom="0.5"
+ android:valueTo="1.0"
+ android:valueType="floatType"
+ android:interpolator="@android:interpolator/fast_out_slow_in" />
+ <set
+ android:ordering="sequentially" >
+ <objectAnimator
+ android:duration="166"
+ android:propertyName="trimPathOffset"
+ android:valueFrom="1.0"
+ android:valueTo="1.0"
+ android:valueType="floatType"
+ android:interpolator="@android:interpolator/linear" />
+ <objectAnimator
+ android:duration="433"
+ android:propertyName="trimPathOffset"
+ android:valueFrom="1.0"
+ android:valueTo="0.5"
+ android:valueType="floatType"
+ android:interpolator="@interpolator/trusted_state_to_error_animation_interpolator_2" />
+ </set>
+ <set
+ android:ordering="sequentially" >
+ <objectAnimator
+ android:duration="166"
+ android:propertyName="trimPathStart"
+ android:valueFrom="1.0"
+ android:valueTo="1.0"
+ android:valueType="floatType"
+ android:interpolator="@android:interpolator/linear" />
+ <objectAnimator
+ android:duration="433"
+ android:propertyName="trimPathStart"
+ android:valueFrom="1.0"
+ android:valueTo="0.0"
+ android:valueType="floatType"
+ android:interpolator="@interpolator/trusted_state_to_error_animation_interpolator_0" />
+ </set>
+</set>
diff --git a/packages/SystemUI/res/anim/trusted_state_to_error_ellipse_path_2_animation.xml b/packages/SystemUI/res/anim/trusted_state_to_error_ellipse_path_2_animation.xml
new file mode 100755
index 0000000..a387f97
--- /dev/null
+++ b/packages/SystemUI/res/anim/trusted_state_to_error_ellipse_path_2_animation.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<set
+ xmlns:android="http://schemas.android.com/apk/res/android" >
+ <objectAnimator
+ android:duration="200"
+ android:propertyName="pathData"
+ android:valueFrom="M 0.0,-1.988645 c 1.09829830627,0.0 1.988645,0.890346693734 1.988645,1.988645 c 0.0,1.09829830627 -0.890346693734,1.988645 -1.988645,1.988645 c -1.09829830627,0.0 -1.988645,-0.890346693734 -1.988645,-1.988645 c 0.0,-1.09829830627 0.890346693734,-1.988645 1.988645,-1.988645 Z"
+ android:valueTo="M 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 Z"
+ android:valueType="pathType"
+ android:interpolator="@android:interpolator/fast_out_slow_in" />
+ <objectAnimator
+ android:duration="600"
+ android:propertyName="fillColor"
+ android:valueFrom="#FFFFFFFF"
+ android:valueTo="#FFF3511E"
+ android:interpolator="@android:interpolator/fast_out_slow_in" />
+ <objectAnimator
+ android:duration="600"
+ android:propertyName="fillAlpha"
+ android:valueFrom="0.5"
+ android:valueTo="1.0"
+ android:valueType="floatType"
+ android:interpolator="@android:interpolator/fast_out_slow_in" />
+</set>
diff --git a/packages/SystemUI/res/anim/trusted_state_to_error_exclamation_dot_animation.xml b/packages/SystemUI/res/anim/trusted_state_to_error_exclamation_dot_animation.xml
new file mode 100755
index 0000000..7a9fb3b
--- /dev/null
+++ b/packages/SystemUI/res/anim/trusted_state_to_error_exclamation_dot_animation.xml
@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<set
+ xmlns:android="http://schemas.android.com/apk/res/android" >
+ <objectAnimator
+ android:duration="566"
+ android:propertyXName="translateX"
+ android:propertyYName="translateY"
+ android:pathData="M 0.0,4.0 c -0.00065,0.22217 -0.00326,1.11083 -0.00391,1.333"
+ android:interpolator="@interpolator/trusted_state_to_error_animation_interpolator_1" />
+ <set
+ android:ordering="sequentially" >
+ <objectAnimator
+ android:duration="300"
+ android:propertyName="scaleX"
+ android:valueFrom="0.0"
+ android:valueTo="0.0"
+ android:valueType="floatType"
+ android:interpolator="@android:interpolator/linear" />
+ <objectAnimator
+ android:duration="16"
+ android:propertyName="scaleX"
+ android:valueFrom="0.0"
+ android:valueTo="1.0"
+ android:valueType="floatType"
+ android:interpolator="@android:interpolator/linear" />
+ </set>
+ <set
+ android:ordering="sequentially" >
+ <objectAnimator
+ android:duration="300"
+ android:propertyName="scaleY"
+ android:valueFrom="0.0"
+ android:valueTo="0.0"
+ android:valueType="floatType"
+ android:interpolator="@android:interpolator/linear" />
+ <objectAnimator
+ android:duration="16"
+ android:propertyName="scaleY"
+ android:valueFrom="0.0"
+ android:valueTo="1.0"
+ android:valueType="floatType"
+ android:interpolator="@android:interpolator/linear" />
+ </set>
+</set>
diff --git a/packages/SystemUI/res/anim/trusted_state_to_error_lock_left_side_animation.xml b/packages/SystemUI/res/anim/trusted_state_to_error_lock_left_side_animation.xml
new file mode 100755
index 0000000..2a4753a
--- /dev/null
+++ b/packages/SystemUI/res/anim/trusted_state_to_error_lock_left_side_animation.xml
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<set
+ xmlns:android="http://schemas.android.com/apk/res/android" >
+ <set
+ android:ordering="sequentially" >
+ <objectAnimator
+ android:duration="200"
+ android:propertyName="scaleX"
+ android:valueFrom="1.0"
+ android:valueTo="1.0"
+ android:valueType="floatType"
+ android:interpolator="@android:interpolator/linear" />
+ <objectAnimator
+ android:duration="200"
+ android:propertyName="scaleX"
+ android:valueFrom="1.0"
+ android:valueTo="1.33333"
+ android:valueType="floatType"
+ android:interpolator="@android:interpolator/fast_out_slow_in" />
+ </set>
+ <set
+ android:ordering="sequentially" >
+ <objectAnimator
+ android:duration="200"
+ android:propertyName="scaleY"
+ android:valueFrom="1.0"
+ android:valueTo="1.0"
+ android:valueType="floatType"
+ android:interpolator="@android:interpolator/linear" />
+ <objectAnimator
+ android:duration="200"
+ android:propertyName="scaleY"
+ android:valueFrom="1.0"
+ android:valueTo="1.33333"
+ android:valueType="floatType"
+ android:interpolator="@android:interpolator/fast_out_slow_in" />
+ </set>
+</set>
diff --git a/packages/SystemUI/res/anim/trusted_state_to_error_lock_right_side_animation.xml b/packages/SystemUI/res/anim/trusted_state_to_error_lock_right_side_animation.xml
new file mode 100755
index 0000000..2a4753a
--- /dev/null
+++ b/packages/SystemUI/res/anim/trusted_state_to_error_lock_right_side_animation.xml
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<set
+ xmlns:android="http://schemas.android.com/apk/res/android" >
+ <set
+ android:ordering="sequentially" >
+ <objectAnimator
+ android:duration="200"
+ android:propertyName="scaleX"
+ android:valueFrom="1.0"
+ android:valueTo="1.0"
+ android:valueType="floatType"
+ android:interpolator="@android:interpolator/linear" />
+ <objectAnimator
+ android:duration="200"
+ android:propertyName="scaleX"
+ android:valueFrom="1.0"
+ android:valueTo="1.33333"
+ android:valueType="floatType"
+ android:interpolator="@android:interpolator/fast_out_slow_in" />
+ </set>
+ <set
+ android:ordering="sequentially" >
+ <objectAnimator
+ android:duration="200"
+ android:propertyName="scaleY"
+ android:valueFrom="1.0"
+ android:valueTo="1.0"
+ android:valueType="floatType"
+ android:interpolator="@android:interpolator/linear" />
+ <objectAnimator
+ android:duration="200"
+ android:propertyName="scaleY"
+ android:valueFrom="1.0"
+ android:valueTo="1.33333"
+ android:valueType="floatType"
+ android:interpolator="@android:interpolator/fast_out_slow_in" />
+ </set>
+</set>
diff --git a/packages/SystemUI/res/anim/trusted_state_to_error_lock_top_animation.xml b/packages/SystemUI/res/anim/trusted_state_to_error_lock_top_animation.xml
new file mode 100755
index 0000000..1f601d3
--- /dev/null
+++ b/packages/SystemUI/res/anim/trusted_state_to_error_lock_top_animation.xml
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<set
+ xmlns:android="http://schemas.android.com/apk/res/android" >
+ <set
+ android:ordering="sequentially" >
+ <objectAnimator
+ android:duration="116"
+ android:propertyName="scaleX"
+ android:valueFrom="1.0"
+ android:valueTo="1.0"
+ android:valueType="floatType"
+ android:interpolator="@android:interpolator/linear" />
+ <objectAnimator
+ android:duration="16"
+ android:propertyName="scaleX"
+ android:valueFrom="1.0"
+ android:valueTo="0.0"
+ android:valueType="floatType"
+ android:interpolator="@android:interpolator/linear" />
+ </set>
+ <set
+ android:ordering="sequentially" >
+ <objectAnimator
+ android:duration="116"
+ android:propertyName="scaleY"
+ android:valueFrom="1.0"
+ android:valueTo="1.0"
+ android:valueType="floatType"
+ android:interpolator="@android:interpolator/linear" />
+ <objectAnimator
+ android:duration="16"
+ android:propertyName="scaleY"
+ android:valueFrom="1.0"
+ android:valueTo="0.0"
+ android:valueType="floatType"
+ android:interpolator="@android:interpolator/linear" />
+ </set>
+</set>
diff --git a/packages/SystemUI/res/anim/trusted_state_to_error_path_1_animation.xml b/packages/SystemUI/res/anim/trusted_state_to_error_path_1_animation.xml
new file mode 100755
index 0000000..7b9be5c
--- /dev/null
+++ b/packages/SystemUI/res/anim/trusted_state_to_error_path_1_animation.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<set
+ xmlns:android="http://schemas.android.com/apk/res/android" >
+ <set
+ android:ordering="sequentially" >
+ <objectAnimator
+ android:duration="33"
+ android:propertyName="pathData"
+ android:valueFrom="M 6.00561523438,-4.046875 c 0.0,0.0 -5.98999023438,0.0 -5.98999023438,0.0 c 0.0,0.0 0.0,2.0 0.0,2.0 c 0.0,0.0 5.98812866211,0.0 5.98812866211,0.0 c 0.0,0.0 0.00064086914062,10.0 0.00064086914062,10.0 c 0.0,0.0 -5.98840332031,0.0 -5.98840332031,0.0 c 0.0,0.0 -0.0052490234375,2.0 -0.0052490234375,2.0 c 0.0,0.0 5.99487304688,0.0 5.99487304688,0.0 c 1.10000610352,0.0 2.0,-0.900024414062 2.0,-2.0 c 0.0,0.0 0.0,-10.0 0.0,-10.0 c 0.0,-1.09997558594 -0.899993896484,-2.0 -2.0,-2.0 Z"
+ android:valueTo="M 6.00561523438,-4.046875 c 0.0,0.0 -5.98999023438,0.0 -5.98999023438,0.0 c 0.0,0.0 0.0,2.0 0.0,2.0 c 0.0,0.0 5.98812866211,0.0 5.98812866211,0.0 c 0.0,0.0 0.00064086914062,10.0 0.00064086914062,10.0 c 0.0,0.0 -5.98840332031,0.0 -5.98840332031,0.0 c 0.0,0.0 -0.0052490234375,2.0 -0.0052490234375,2.0 c 0.0,0.0 5.99487304688,0.0 5.99487304688,0.0 c 1.10000610352,0.0 2.0,-0.900024414062 2.0,-2.0 c 0.0,0.0 0.0,-10.0 0.0,-10.0 c 0.0,-1.09997558594 -0.899993896484,-2.0 -2.0,-2.0 Z"
+ android:valueType="pathType"
+ android:interpolator="@android:interpolator/linear" />
+ <objectAnimator
+ android:duration="166"
+ android:propertyName="pathData"
+ android:valueFrom="M 6.00561523438,-4.046875 c 0.0,0.0 -5.98999023438,0.0 -5.98999023438,0.0 c 0.0,0.0 0.0,2.0 0.0,2.0 c 0.0,0.0 5.98812866211,0.0 5.98812866211,0.0 c 0.0,0.0 0.00064086914062,10.0 0.00064086914062,10.0 c 0.0,0.0 -5.98840332031,0.0 -5.98840332031,0.0 c 0.0,0.0 -0.0052490234375,2.0 -0.0052490234375,2.0 c 0.0,0.0 5.99487304688,0.0 5.99487304688,0.0 c 1.10000610352,0.0 2.0,-0.900024414062 2.0,-2.0 c 0.0,0.0 0.0,-10.0 0.0,-10.0 c 0.0,-1.09997558594 -0.899993896484,-2.0 -2.0,-2.0 Z"
+ android:valueTo="M 1.63623046875,-4.953125 c 0.0,0.0 -1.61499023438,0.0 -1.61499023438,0.0 c 0.0,0.0 0.0,2.0 0.0,2.0 c 0.0,0.0 0.00375366210938,-0.015625 0.00375366210938,-0.015625 c 0.0,0.0 0.00064086914062,10.625 0.00064086914062,10.625 c 0.0,0.0 -0.0040283203125,0.015625 -0.0040283203125,0.015625 c 0.0,0.0 -0.0052490234375,2.0 -0.0052490234375,2.0 c 0.0,0.0 1.61987304688,0.0 1.61987304688,0.0 c 1.10000610352,0.0 2.0,-0.900024414062 2.0,-2.0 c 0.0,0.0 0.0,-10.625 0.0,-10.625 c 0.0,-1.09997558594 -0.899993896484,-2.0 -2.0,-2.0 Z"
+ android:valueType="pathType"
+ android:interpolator="@android:interpolator/fast_out_slow_in" />
+ <objectAnimator
+ android:duration="200"
+ android:propertyName="pathData"
+ android:valueFrom="M 1.63623046875,-4.953125 c 0.0,0.0 -1.61499023438,0.0 -1.61499023438,0.0 c 0.0,0.0 0.0,2.0 0.0,2.0 c 0.0,0.0 0.00375366210938,-0.015625 0.00375366210938,-0.015625 c 0.0,0.0 0.00064086914062,10.625 0.00064086914062,10.625 c 0.0,0.0 -0.0040283203125,0.015625 -0.0040283203125,0.015625 c 0.0,0.0 -0.0052490234375,2.0 -0.0052490234375,2.0 c 0.0,0.0 1.61987304688,0.0 1.61987304688,0.0 c 1.10000610352,0.0 2.0,-0.900024414062 2.0,-2.0 c 0.0,0.0 0.0,-10.625 0.0,-10.625 c 0.0,-1.09997558594 -0.899993896484,-2.0 -2.0,-2.0 Z"
+ android:valueTo="M 0.02685546875,-4.96875 c 0.0,0.0 -0.005615234375,0.015625 -0.005615234375,0.015625 c 0.0,0.0 0.0,2.0 0.0,2.0 c 0.0,0.0 0.00375366210938,-0.015625 0.00375366210938,-0.015625 c 0.0,0.0 -0.00936889648438,3.9296875 -0.00936889648438,3.9296875 c 0.0,0.0 -0.0040283203125,0.015625 -0.0040283203125,0.015625 c 0.0,0.0 -0.0028076171875,0.0234375 -0.0028076171875,0.0234375 c 0.0,0.0 0.010498046875,-0.015625 0.010498046875,-0.015625 c 0.0,0.0 0.985595703125,0.0078125 0.985595703125,0.0078125 c 0.0,0.0 0.017578125,-6.015625 0.017578125,-6.015625 c 0.0,0.0 0.104400634766,0.0546875 -0.99560546875,0.0546875 Z"
+ android:valueType="pathType"
+ android:interpolator="@android:interpolator/fast_out_slow_in" />
+ </set>
+ <objectAnimator
+ android:duration="600"
+ android:propertyName="fillColor"
+ android:valueFrom="#FFFFFFFF"
+ android:valueTo="#FFF3511E"
+ android:interpolator="@android:interpolator/fast_out_slow_in" />
+ <objectAnimator
+ android:duration="600"
+ android:propertyName="fillAlpha"
+ android:valueFrom="0.5"
+ android:valueTo="1.0"
+ android:valueType="floatType"
+ android:interpolator="@android:interpolator/fast_out_slow_in" />
+</set>
diff --git a/packages/SystemUI/res/anim/trusted_state_to_error_path_2_animation.xml b/packages/SystemUI/res/anim/trusted_state_to_error_path_2_animation.xml
new file mode 100755
index 0000000..8eb0c62
--- /dev/null
+++ b/packages/SystemUI/res/anim/trusted_state_to_error_path_2_animation.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<set
+ xmlns:android="http://schemas.android.com/apk/res/android" >
+ <set
+ android:ordering="sequentially" >
+ <objectAnimator
+ android:duration="33"
+ android:propertyName="pathData"
+ android:valueFrom="M -5.9959564209,-2.04727172852 c 0.0,0.0 6.01173400879,0.00039672851562 6.01173400879,0.00039672851562 c 0.0,0.0 -0.00015258789062,-2.0 -0.00015258789062,-2.0 c 0.0,0.0 -6.01000976562,0.0 -6.01000976562,0.0 c -1.10000610352,0.0 -2.0,0.900024414062 -2.0,2.0 c 0.0,0.0 0.0,10.0 0.0,10.0 c 0.0,1.09997558594 0.899993896484,2.0 2.0,2.0 c 0.0,0.0 6.01000976562,0.0 6.01000976562,0.0 c 0.0,0.0 -0.000244140625,-2.0009765625 -0.000244140625,-2.0009765625 c 0.0,0.0 -6.01171875,0.0003662109375 -6.01171875,0.0003662109375 c 0.0,0.0 0.00038146972656,-9.99978637695 0.00038146972656,-9.99978637695 Z"
+ android:valueTo="M -5.9959564209,-2.04727172852 c 0.0,0.0 6.01173400879,0.00039672851562 6.01173400879,0.00039672851562 c 0.0,0.0 -0.00015258789062,-2.0 -0.00015258789062,-2.0 c 0.0,0.0 -6.01000976562,0.0 -6.01000976562,0.0 c -1.10000610352,0.0 -2.0,0.900024414062 -2.0,2.0 c 0.0,0.0 0.0,10.0 0.0,10.0 c 0.0,1.09997558594 0.899993896484,2.0 2.0,2.0 c 0.0,0.0 6.01000976562,0.0 6.01000976562,0.0 c 0.0,0.0 -0.000244140625,-2.0009765625 -0.000244140625,-2.0009765625 c 0.0,0.0 -6.01171875,0.0003662109375 -6.01171875,0.0003662109375 c 0.0,0.0 0.00038146972656,-9.99978637695 0.00038146972656,-9.99978637695 Z"
+ android:valueType="pathType"
+ android:interpolator="@android:interpolator/linear" />
+ <objectAnimator
+ android:duration="166"
+ android:propertyName="pathData"
+ android:valueFrom="M -5.9959564209,-2.04727172852 c 0.0,0.0 6.01173400879,0.00039672851562 6.01173400879,0.00039672851562 c 0.0,0.0 -0.00015258789062,-2.0 -0.00015258789062,-2.0 c 0.0,0.0 -6.01000976562,0.0 -6.01000976562,0.0 c -1.10000610352,0.0 -2.0,0.900024414062 -2.0,2.0 c 0.0,0.0 0.0,10.0 0.0,10.0 c 0.0,1.09997558594 0.899993896484,2.0 2.0,2.0 c 0.0,0.0 6.01000976562,0.0 6.01000976562,0.0 c 0.0,0.0 -0.000244140625,-2.0009765625 -0.000244140625,-2.0009765625 c 0.0,0.0 -6.01171875,0.0003662109375 -6.01171875,0.0003662109375 c 0.0,0.0 0.00038146972656,-9.99978637695 0.00038146972656,-9.99978637695 Z"
+ android:valueTo="M 0.0252990722656,-2.96975708008 c 0.0,0.0 -0.00390625,0.0166320800781 -0.00390625,0.0166320800781 c 0.0,0.0 -0.00015258789062,-2.0 -0.00015258789062,-2.0 c 0.0,0.0 -1.63500976562,0.0 -1.63500976562,0.0 c -1.10000610352,0.0 -2.0,0.900024414062 -2.0,2.0 c 0.0,0.0 0.0,10.625 0.0,10.625 c 0.0,1.09997558594 0.899993896484,2.0 2.0,2.0 c 0.0,0.0 1.63500976562,0.0 1.63500976562,0.0 c 0.0,0.0 -0.000244140625,-2.0009765625 -0.000244140625,-2.0009765625 c 0.0,0.0 0.00390625,-0.015869140625 0.00390625,-0.015869140625 c 0.0,0.0 0.00039672851562,-10.624786377 0.00039672851562,-10.624786377 Z"
+ android:valueType="pathType"
+ android:interpolator="@android:interpolator/fast_out_slow_in" />
+ <objectAnimator
+ android:duration="200"
+ android:propertyName="pathData"
+ android:valueFrom="M 0.0252990722656,-2.96975708008 c 0.0,0.0 -0.00390625,0.0166320800781 -0.00390625,0.0166320800781 c 0.0,0.0 -0.00015258789062,-2.0 -0.00015258789062,-2.0 c 0.0,0.0 -1.63500976562,0.0 -1.63500976562,0.0 c -1.10000610352,0.0 -2.0,0.900024414062 -2.0,2.0 c 0.0,0.0 0.0,10.625 0.0,10.625 c 0.0,1.09997558594 0.899993896484,2.0 2.0,2.0 c 0.0,0.0 1.63500976562,0.0 1.63500976562,0.0 c 0.0,0.0 -0.000244140625,-2.0009765625 -0.000244140625,-2.0009765625 c 0.0,0.0 0.00390625,-0.015869140625 0.00390625,-0.015869140625 c 0.0,0.0 0.00039672851562,-10.624786377 0.00039672851562,-10.624786377 Z"
+ android:valueTo="M 0.0252990722656,-2.96914672852 c 0.0,0.0 -0.00390625,0.0160217285156 -0.00390625,0.0160217285156 c 0.0,0.0 -0.00015258789062,-2.0 -0.00015258789062,-2.0 c 0.0,0.0 0.005615234375,-0.015625 0.005615234375,-0.015625 c -1.10000610352,0.0 -1.01220703125,-0.0546875 -1.01220703125,-0.0546875 c 0.0,0.0 -0.017578125,6.015625 -0.017578125,6.015625 c 0.0,0.0 -0.0777893066406,-0.0078125 1.02221679688,-0.0078125 c 0.0,0.0 -0.005615234375,0.015625 -0.005615234375,0.015625 c 0.0,0.0 -0.002685546875,-0.0244140625 -0.002685546875,-0.0244140625 c 0.0,0.0 0.00390625,-0.0152587890625 0.00390625,-0.0152587890625 c 0.0,0.0 0.0104064941406,-3.92947387695 0.0104064941406,-3.92947387695 Z"
+ android:valueType="pathType"
+ android:interpolator="@android:interpolator/fast_out_slow_in" />
+ </set>
+ <objectAnimator
+ android:duration="600"
+ android:propertyName="fillColor"
+ android:valueFrom="#FFFFFFFF"
+ android:valueTo="#FFF3511E"
+ android:interpolator="@android:interpolator/fast_out_slow_in" />
+ <objectAnimator
+ android:duration="600"
+ android:propertyName="fillAlpha"
+ android:valueFrom="0.5"
+ android:valueTo="1.0"
+ android:valueType="floatType"
+ android:interpolator="@android:interpolator/fast_out_slow_in" />
+</set>
diff --git a/packages/SystemUI/res/anim/trusted_state_to_error_path_3_animation.xml b/packages/SystemUI/res/anim/trusted_state_to_error_path_3_animation.xml
new file mode 100755
index 0000000..2e86744
--- /dev/null
+++ b/packages/SystemUI/res/anim/trusted_state_to_error_path_3_animation.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<set
+ xmlns:android="http://schemas.android.com/apk/res/android" >
+ <objectAnimator
+ android:duration="200"
+ android:propertyName="pathData"
+ android:valueFrom="M 5.00619506836,-6.046875 c 0.0,-2.76000976562 -2.23999023438,-5.0 -5.0,-5.0 c -2.76000976562,0.0 -5.0,2.23999023438 -5.0,5.0 c 0.0,0.0 1.89999389648,0.0 1.89999389648,0.0 c 0.0,-1.71002197266 1.38999938965,-3.09997558594 3.10000610352,-3.09997558594 c 1.71000671387,0.0 3.10000610352,1.38995361328 3.10000610352,3.09997558594 c 0.0,0.0 0.0,2.0 0.0,2.0 c 0.0,0.0 1.89999389648,0.0 1.89999389648,0.0 c 0.0,0.0 0.0,-2.0 0.0,-2.0 Z"
+ android:valueTo="M 5.01239013672,3.390625 c 0.0,-2.76000976562 -2.23999023438,-5.0 -5.0,-5.0 c -2.76000976562,0.0 -5.0,2.23999023438 -5.0,5.0 c 0.0,0.0 1.89999389648,0.0 1.89999389648,0.0 c 0.0,-1.71002197266 1.38999938965,-3.09997558594 3.10000610352,-3.09997558594 c 1.71000671387,0.0 3.10000610352,1.38995361328 3.10000610352,3.09997558594 c 0.0,0.0 0.0,2.0 0.0,2.0 c 0.0,0.0 1.89999389648,0.0 1.89999389648,0.0 c 0.0,0.0 0.0,-2.0 0.0,-2.0 Z"
+ android:valueType="pathType"
+ android:interpolator="@interpolator/trusted_state_to_error_animation_interpolator_3" />
+ <objectAnimator
+ android:duration="600"
+ android:propertyName="fillColor"
+ android:valueFrom="#FFFFFFFF"
+ android:valueTo="#FFF3511E"
+ android:interpolator="@android:interpolator/fast_out_slow_in" />
+ <objectAnimator
+ android:duration="600"
+ android:propertyName="fillAlpha"
+ android:valueFrom="0.5"
+ android:valueTo="1.0"
+ android:valueType="floatType"
+ android:interpolator="@android:interpolator/fast_out_slow_in" />
+</set>
diff --git a/packages/SystemUI/res/anim/trusted_state_to_error_rectangle_path_1_animation.xml b/packages/SystemUI/res/anim/trusted_state_to_error_rectangle_path_1_animation.xml
new file mode 100755
index 0000000..46d571c
--- /dev/null
+++ b/packages/SystemUI/res/anim/trusted_state_to_error_rectangle_path_1_animation.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<set
+ xmlns:android="http://schemas.android.com/apk/res/android" >
+ <objectAnimator
+ android:duration="600"
+ android:propertyName="fillColor"
+ android:valueFrom="#FFFFFFFF"
+ android:valueTo="#FFF3511E"
+ android:interpolator="@android:interpolator/fast_out_slow_in" />
+ <objectAnimator
+ android:duration="600"
+ android:propertyName="fillAlpha"
+ android:valueFrom="0.5"
+ android:valueTo="1.0"
+ android:valueType="floatType"
+ android:interpolator="@android:interpolator/fast_out_slow_in" />
+</set>
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back_ime_land.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back_ime_land.png
deleted file mode 100644
index 165ef4f..0000000
--- a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back_ime_land.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back_land.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back_land.png
deleted file mode 100644
index f95f09f..0000000
--- a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back_land.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_home_land.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_home_land.png
deleted file mode 100644
index 860a906..0000000
--- a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_home_land.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_menu_land.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_menu_land.png
deleted file mode 100644
index bcb203e..0000000
--- a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_menu_land.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_recent_land.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_recent_land.png
deleted file mode 100644
index bab268e..0000000
--- a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_recent_land.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_sysbar_back_land.png b/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_sysbar_back_land.png
deleted file mode 100644
index 2f4dbbe..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_sysbar_back_land.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_sysbar_back_land.png b/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_sysbar_back_land.png
deleted file mode 100644
index d04d84f..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_sysbar_back_land.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_sysbar_back_land.png b/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_sysbar_back_land.png
deleted file mode 100644
index 1500ae5..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_sysbar_back_land.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_sysbar_back_land.png b/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_sysbar_back_land.png
deleted file mode 100644
index a7fec49..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_sysbar_back_land.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back_ime_land.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back_ime_land.png
deleted file mode 100644
index 0feb405..0000000
--- a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back_ime_land.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back_land.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back_land.png
deleted file mode 100644
index cabab0d..0000000
--- a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back_land.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_home_land.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_home_land.png
deleted file mode 100644
index 16e1bf5..0000000
--- a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_home_land.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_menu_land.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_menu_land.png
deleted file mode 100644
index 94c9743..0000000
--- a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_menu_land.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_recent_land.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_recent_land.png
deleted file mode 100644
index 40375de..0000000
--- a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_recent_land.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_back_ime_land.png b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_back_ime_land.png
deleted file mode 100644
index b7b8f98..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_back_ime_land.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_back_land.png b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_back_land.png
deleted file mode 100644
index 69b7449..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_back_land.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_home_land.png b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_home_land.png
deleted file mode 100644
index 57d243c..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_home_land.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_menu_land.png b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_menu_land.png
deleted file mode 100644
index 8a7ac4f..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_menu_land.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_recent_land.png b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_recent_land.png
deleted file mode 100644
index e53eaff..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_recent_land.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_back_ime_land.png b/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_back_ime_land.png
deleted file mode 100644
index 695e7a4..0000000
--- a/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_back_ime_land.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_back_land.png b/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_back_land.png
deleted file mode 100644
index 88294c0..0000000
--- a/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_back_land.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_home_land.png b/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_home_land.png
deleted file mode 100644
index 09d684a..0000000
--- a/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_home_land.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_menu_land.png b/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_menu_land.png
deleted file mode 100644
index 62f44e8..0000000
--- a/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_menu_land.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_recent_land.png b/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_recent_land.png
deleted file mode 100644
index e31ea32..0000000
--- a/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_recent_land.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxxhdpi/ic_sysbar_back_ime_land.png b/packages/SystemUI/res/drawable-xxxhdpi/ic_sysbar_back_ime_land.png
deleted file mode 100644
index 24f12d7..0000000
--- a/packages/SystemUI/res/drawable-xxxhdpi/ic_sysbar_back_ime_land.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxxhdpi/ic_sysbar_back_land.png b/packages/SystemUI/res/drawable-xxxhdpi/ic_sysbar_back_land.png
deleted file mode 100644
index 51482f5..0000000
--- a/packages/SystemUI/res/drawable-xxxhdpi/ic_sysbar_back_land.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxxhdpi/ic_sysbar_home_land.png b/packages/SystemUI/res/drawable-xxxhdpi/ic_sysbar_home_land.png
deleted file mode 100644
index 46c7b18..0000000
--- a/packages/SystemUI/res/drawable-xxxhdpi/ic_sysbar_home_land.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxxhdpi/ic_sysbar_recent_land.png b/packages/SystemUI/res/drawable-xxxhdpi/ic_sysbar_recent_land.png
deleted file mode 100644
index 396ad7d..0000000
--- a/packages/SystemUI/res/drawable-xxxhdpi/ic_sysbar_recent_land.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable/error_to_trustedstate.xml b/packages/SystemUI/res/drawable/error_to_trustedstate.xml
new file mode 100755
index 0000000..6211edf
--- /dev/null
+++ b/packages/SystemUI/res/drawable/error_to_trustedstate.xml
@@ -0,0 +1,84 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<vector
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:name="error_to_trustedstate"
+ android:width="32dp"
+ android:viewportWidth="32"
+ android:height="32dp"
+ android:viewportHeight="32" >
+ <group
+ android:name="error_to_trusted_state"
+ android:translateX="16"
+ android:translateY="16" >
+ <group
+ android:name="error_circle" >
+ <path
+ android:name="ellipse_path_1"
+ android:trimPathStart="0"
+ android:trimPathEnd="1"
+ android:trimPathOffset="0.0"
+ android:strokeColor="#FFF3511E"
+ android:strokeWidth="2"
+ android:pathData="M 0.0,-12.0 c 6.6274169976,0.0 12.0,5.3725830024 12.0,12.0 c 0.0,6.6274169976 -5.3725830024,12.0 -12.0,12.0 c -6.6274169976,0.0 -12.0,-5.3725830024 -12.0,-12.0 c 0.0,-6.6274169976 5.3725830024,-12.0 12.0,-12.0 Z" />
+ </group>
+ <group
+ android:name="middle_ellipse"
+ android:translateY="2.9375" >
+ <path
+ android:name="ellipse_path_2"
+ android:fillColor="#FFF3511E"
+ android:pathData="M 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 Z" />
+ </group>
+ <group
+ android:name="lock_right_side"
+ android:scaleX="1.33333"
+ android:scaleY="1.33333" >
+ <path
+ android:name="path_1"
+ android:pathData="M 0.02685546875,-4.96875 c 0.0,0.0 -0.005615234375,0.015625 -0.005615234375,0.015625 c 0.0,0.0 0.0,2.0 0.0,2.0 c 0.0,0.0 0.00375366210938,-0.015625 0.00375366210938,-0.015625 c 0.0,0.0 -0.00936889648438,3.9296875 -0.00936889648438,3.9296875 c 0.0,0.0 -0.0040283203125,0.015625 -0.0040283203125,0.015625 c 0.0,0.0 -0.0028076171875,0.0234375 -0.0028076171875,0.0234375 c 0.0,0.0 0.010498046875,-0.015625 0.010498046875,-0.015625 c 0.0,0.0 0.985595703125,0.0078125 0.985595703125,0.0078125 c 0.0,0.0 0.017578125,-6.015625 0.017578125,-6.015625 c 0.0,0.0 0.104400634766,0.0546875 -0.99560546875,0.0546875 Z"
+ android:fillColor="#FFF3511E" />
+ </group>
+ <group
+ android:name="lock_left_side"
+ android:scaleX="1.33333"
+ android:scaleY="1.33333" >
+ <path
+ android:name="path_2"
+ android:pathData="M 0.0252990722656,-2.96914672852 c 0.0,0.0 -0.00390625,0.0160217285156 -0.00390625,0.0160217285156 c 0.0,0.0 -0.00015258789062,-2.0 -0.00015258789062,-2.0 c 0.0,0.0 0.005615234375,-0.015625 0.005615234375,-0.015625 c -1.10000610352,0.0 -1.01220703125,-0.0546875 -1.01220703125,-0.0546875 c 0.0,0.0 -0.017578125,6.015625 -0.017578125,6.015625 c 0.0,0.0 -0.0777893066406,-0.0078125 1.02221679688,-0.0078125 c 0.0,0.0 -0.005615234375,0.015625 -0.005615234375,0.015625 c 0.0,0.0 -0.002685546875,-0.0244140625 -0.002685546875,-0.0244140625 c 0.0,0.0 0.00390625,-0.0152587890625 0.00390625,-0.0152587890625 c 0.0,0.0 0.0104064941406,-3.92947387695 0.0104064941406,-3.92947387695 Z"
+ android:fillColor="#FFF3511E" />
+ </group>
+ <group
+ android:name="lock_top"
+ android:scaleX="0"
+ android:scaleY="0" >
+ <path
+ android:name="path_3"
+ android:pathData="M 5.01239013672,3.390625 c 0.0,-2.76000976562 -2.23999023438,-5.0 -5.0,-5.0 c -2.76000976562,0.0 -5.0,2.23999023438 -5.0,5.0 c 0.0,0.0 1.89999389648,0.0 1.89999389648,0.0 c 0.0,-1.71002197266 1.38999938965,-3.09997558594 3.10000610352,-3.09997558594 c 1.71000671387,0.0 3.10000610352,1.38995361328 3.10000610352,3.09997558594 c 0.0,0.0 0.0,2.0 0.0,2.0 c 0.0,0.0 1.89999389648,0.0 1.89999389648,0.0 c 0.0,0.0 0.0,-2.0 0.0,-2.0 Z"
+ android:fillColor="#FFF3511E" />
+ </group>
+ <group
+ android:name="exclamation_dot"
+ android:translateX="-0.00391"
+ android:translateY="5.333" >
+ <path
+ android:name="rectangle_path_1"
+ android:fillColor="#FFF3511E"
+ android:pathData="M -1.33871,-1.3335 l 2.67742,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l 0.0,2.667 c 0.0,0.0 0.0,0.0 0.0,0.0 l -2.67742,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l 0.0,-2.667 c 0.0,0.0 0.0,0.0 0.0,0.0 Z" />
+ </group>
+ </group>
+</vector>
diff --git a/packages/SystemUI/res/drawable/error_to_trustedstate_animation.xml b/packages/SystemUI/res/drawable/error_to_trustedstate_animation.xml
new file mode 100755
index 0000000..6befe13
--- /dev/null
+++ b/packages/SystemUI/res/drawable/error_to_trustedstate_animation.xml
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<animated-vector
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:drawable="@drawable/error_to_trustedstate" >
+ <target
+ android:name="ellipse_path_1"
+ android:animation="@anim/error_to_trustedstate_ellipse_path_1_animation" />
+ <target
+ android:name="ellipse_path_2"
+ android:animation="@anim/error_to_trustedstate_ellipse_path_2_animation" />
+ <target
+ android:name="lock_right_side"
+ android:animation="@anim/error_to_trustedstate_lock_right_side_animation" />
+ <target
+ android:name="path_1"
+ android:animation="@anim/error_to_trustedstate_path_1_animation" />
+ <target
+ android:name="lock_left_side"
+ android:animation="@anim/error_to_trustedstate_lock_left_side_animation" />
+ <target
+ android:name="path_2"
+ android:animation="@anim/error_to_trustedstate_path_2_animation" />
+ <target
+ android:name="lock_top"
+ android:animation="@anim/error_to_trustedstate_lock_top_animation" />
+ <target
+ android:name="path_3"
+ android:animation="@anim/error_to_trustedstate_path_3_animation" />
+ <target
+ android:name="exclamation_dot"
+ android:animation="@anim/error_to_trustedstate_exclamation_dot_animation" />
+ <target
+ android:name="rectangle_path_1"
+ android:animation="@anim/error_to_trustedstate_rectangle_path_1_animation" />
+</animated-vector>
diff --git a/packages/SystemUI/res/drawable/trusted_state_to_error.xml b/packages/SystemUI/res/drawable/trusted_state_to_error.xml
new file mode 100755
index 0000000..534a9a5
--- /dev/null
+++ b/packages/SystemUI/res/drawable/trusted_state_to_error.xml
@@ -0,0 +1,84 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<vector
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:name="trusted_state_to_error"
+ android:width="32dp"
+ android:viewportWidth="32"
+ android:height="32dp"
+ android:viewportHeight="32" >
+ <group
+ android:name="trusted_state_to_error_0"
+ android:translateX="16"
+ android:translateY="16" >
+ <group
+ android:name="error_circle" >
+ <path
+ android:name="ellipse_path_1"
+ android:trimPathStart="1"
+ android:trimPathOffset="1"
+ android:strokeColor="#FFFFFFFF"
+ android:strokeAlpha="0.5"
+ android:strokeWidth="2"
+ android:pathData="M 0.0,-12.0 c 6.6274169976,0.0 12.0,5.3725830024 12.0,12.0 c 0.0,6.6274169976 -5.3725830024,12.0 -12.0,12.0 c -6.6274169976,0.0 -12.0,-5.3725830024 -12.0,-12.0 c 0.0,-6.6274169976 5.3725830024,-12.0 12.0,-12.0 Z" />
+ </group>
+ <group
+ android:name="middle_ellipse"
+ android:translateY="2.9375" >
+ <path
+ android:name="ellipse_path_2"
+ android:fillColor="#FFFFFFFF"
+ android:fillAlpha="0.5"
+ android:pathData="M 0.0,-1.988645 c 1.09829830627,0.0 1.988645,0.890346693734 1.988645,1.988645 c 0.0,1.09829830627 -0.890346693734,1.988645 -1.988645,1.988645 c -1.09829830627,0.0 -1.988645,-0.890346693734 -1.988645,-1.988645 c 0.0,-1.09829830627 0.890346693734,-1.988645 1.988645,-1.988645 Z" />
+ </group>
+ <group
+ android:name="lock_right_side" >
+ <path
+ android:name="path_1"
+ android:pathData="M 6.00561523438,-4.046875 c 0.0,0.0 -5.98999023438,0.0 -5.98999023438,0.0 c 0.0,0.0 0.0,2.0 0.0,2.0 c 0.0,0.0 5.98812866211,0.0 5.98812866211,0.0 c 0.0,0.0 0.00064086914062,10.0 0.00064086914062,10.0 c 0.0,0.0 -5.98840332031,0.0 -5.98840332031,0.0 c 0.0,0.0 -0.0052490234375,2.0 -0.0052490234375,2.0 c 0.0,0.0 5.99487304688,0.0 5.99487304688,0.0 c 1.10000610352,0.0 2.0,-0.900024414062 2.0,-2.0 c 0.0,0.0 0.0,-10.0 0.0,-10.0 c 0.0,-1.09997558594 -0.899993896484,-2.0 -2.0,-2.0 Z"
+ android:fillColor="#FFFFFFFF"
+ android:fillAlpha="0.5" />
+ </group>
+ <group
+ android:name="lock_left_side" >
+ <path
+ android:name="path_2"
+ android:pathData="M -5.9959564209,-2.04727172852 c 0.0,0.0 6.01173400879,0.00039672851562 6.01173400879,0.00039672851562 c 0.0,0.0 -0.00015258789062,-2.0 -0.00015258789062,-2.0 c 0.0,0.0 -6.01000976562,0.0 -6.01000976562,0.0 c -1.10000610352,0.0 -2.0,0.900024414062 -2.0,2.0 c 0.0,0.0 0.0,10.0 0.0,10.0 c 0.0,1.09997558594 0.899993896484,2.0 2.0,2.0 c 0.0,0.0 6.01000976562,0.0 6.01000976562,0.0 c 0.0,0.0 -0.000244140625,-2.0009765625 -0.000244140625,-2.0009765625 c 0.0,0.0 -6.01171875,0.0003662109375 -6.01171875,0.0003662109375 c 0.0,0.0 0.00038146972656,-9.99978637695 0.00038146972656,-9.99978637695 Z"
+ android:fillColor="#FFFFFFFF"
+ android:fillAlpha="0.5" />
+ </group>
+ <group
+ android:name="lock_top" >
+ <path
+ android:name="path_3"
+ android:pathData="M 5.00619506836,-6.046875 c 0.0,-2.76000976562 -2.23999023438,-5.0 -5.0,-5.0 c -2.76000976562,0.0 -5.0,2.23999023438 -5.0,5.0 c 0.0,0.0 1.89999389648,0.0 1.89999389648,0.0 c 0.0,-1.71002197266 1.38999938965,-3.09997558594 3.10000610352,-3.09997558594 c 1.71000671387,0.0 3.10000610352,1.38995361328 3.10000610352,3.09997558594 c 0.0,0.0 0.0,2.0 0.0,2.0 c 0.0,0.0 1.89999389648,0.0 1.89999389648,0.0 c 0.0,0.0 0.0,-2.0 0.0,-2.0 Z"
+ android:fillColor="#FFFFFFFF"
+ android:fillAlpha="0.5" />
+ </group>
+ <group
+ android:name="exclamation_dot"
+ android:translateY="4"
+ android:scaleX="0"
+ android:scaleY="0" >
+ <path
+ android:name="rectangle_path_1"
+ android:fillColor="#FFFFFFFF"
+ android:fillAlpha="0.5"
+ android:pathData="M -1.33871,-1.3335 l 2.67742,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l 0.0,2.667 c 0.0,0.0 0.0,0.0 0.0,0.0 l -2.67742,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l 0.0,-2.667 c 0.0,0.0 0.0,0.0 0.0,0.0 Z" />
+ </group>
+ </group>
+</vector>
diff --git a/packages/SystemUI/res/drawable/trusted_state_to_error_animation.xml b/packages/SystemUI/res/drawable/trusted_state_to_error_animation.xml
new file mode 100755
index 0000000..5686d54
--- /dev/null
+++ b/packages/SystemUI/res/drawable/trusted_state_to_error_animation.xml
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<animated-vector
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:drawable="@drawable/trusted_state_to_error" >
+ <target
+ android:name="ellipse_path_1"
+ android:animation="@anim/trusted_state_to_error_ellipse_path_1_animation" />
+ <target
+ android:name="ellipse_path_2"
+ android:animation="@anim/trusted_state_to_error_ellipse_path_2_animation" />
+ <target
+ android:name="lock_right_side"
+ android:animation="@anim/trusted_state_to_error_lock_right_side_animation" />
+ <target
+ android:name="path_1"
+ android:animation="@anim/trusted_state_to_error_path_1_animation" />
+ <target
+ android:name="lock_left_side"
+ android:animation="@anim/trusted_state_to_error_lock_left_side_animation" />
+ <target
+ android:name="path_2"
+ android:animation="@anim/trusted_state_to_error_path_2_animation" />
+ <target
+ android:name="lock_top"
+ android:animation="@anim/trusted_state_to_error_lock_top_animation" />
+ <target
+ android:name="path_3"
+ android:animation="@anim/trusted_state_to_error_path_3_animation" />
+ <target
+ android:name="exclamation_dot"
+ android:animation="@anim/trusted_state_to_error_exclamation_dot_animation" />
+ <target
+ android:name="rectangle_path_1"
+ android:animation="@anim/trusted_state_to_error_rectangle_path_1_animation" />
+</animated-vector>
diff --git a/packages/SystemUI/res/interpolator/error_to_trustedstate_animation_interpolator_0.xml b/packages/SystemUI/res/interpolator/error_to_trustedstate_animation_interpolator_0.xml
new file mode 100755
index 0000000..262cb88
--- /dev/null
+++ b/packages/SystemUI/res/interpolator/error_to_trustedstate_animation_interpolator_0.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<pathInterpolator
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:pathData="M 0.0,0.0 l 0.254777070064,0.0 c 0.00007,0.0 0.447133757962,1.0 0.745222929936,1.0 L 1.0,1.0" />
diff --git a/packages/SystemUI/res/interpolator/error_to_trustedstate_animation_interpolator_1.xml b/packages/SystemUI/res/interpolator/error_to_trustedstate_animation_interpolator_1.xml
new file mode 100755
index 0000000..9ecee94
--- /dev/null
+++ b/packages/SystemUI/res/interpolator/error_to_trustedstate_animation_interpolator_1.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<pathInterpolator
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:pathData="M 0.0,0.0 c 0.00010,0.0 0.6,1.0 1.0,1.0" />
diff --git a/packages/SystemUI/res/interpolator/error_to_trustedstate_animation_interpolator_2.xml b/packages/SystemUI/res/interpolator/error_to_trustedstate_animation_interpolator_2.xml
new file mode 100755
index 0000000..ae0b2d7
--- /dev/null
+++ b/packages/SystemUI/res/interpolator/error_to_trustedstate_animation_interpolator_2.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<pathInterpolator
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:pathData="M 0.0,0.0 c 0.000100000000009,0.0 0.6,1.0 1.0,1.0" />
diff --git a/packages/SystemUI/res/interpolator/error_to_trustedstate_animation_interpolator_3.xml b/packages/SystemUI/res/interpolator/error_to_trustedstate_animation_interpolator_3.xml
new file mode 100755
index 0000000..be7cc69
--- /dev/null
+++ b/packages/SystemUI/res/interpolator/error_to_trustedstate_animation_interpolator_3.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<pathInterpolator
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:pathData="M 0.0,0.0 c 0.00010,0.0 0.2,1.0 1.0,1.0" />
diff --git a/packages/SystemUI/res/interpolator/error_to_trustedstate_animation_interpolator_4.xml b/packages/SystemUI/res/interpolator/error_to_trustedstate_animation_interpolator_4.xml
new file mode 100755
index 0000000..f8f978d
--- /dev/null
+++ b/packages/SystemUI/res/interpolator/error_to_trustedstate_animation_interpolator_4.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<pathInterpolator
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:pathData="M 0.0,0.0 c 0.4,0.0 0.6,1.0 1.0,1.0" />
diff --git a/packages/SystemUI/res/interpolator/trusted_state_to_error_animation_interpolator_0.xml b/packages/SystemUI/res/interpolator/trusted_state_to_error_animation_interpolator_0.xml
new file mode 100755
index 0000000..9ecee94
--- /dev/null
+++ b/packages/SystemUI/res/interpolator/trusted_state_to_error_animation_interpolator_0.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<pathInterpolator
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:pathData="M 0.0,0.0 c 0.00010,0.0 0.6,1.0 1.0,1.0" />
diff --git a/packages/SystemUI/res/interpolator/trusted_state_to_error_animation_interpolator_1.xml b/packages/SystemUI/res/interpolator/trusted_state_to_error_animation_interpolator_1.xml
new file mode 100755
index 0000000..87ef1d4
--- /dev/null
+++ b/packages/SystemUI/res/interpolator/trusted_state_to_error_animation_interpolator_1.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<pathInterpolator
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:pathData="M 0.0,0.0 l 0.412907702984,0.0 c 0.00006,0.0 0.35225537821,1.0 0.587092297016,1.0 L 1.0,1.0" />
diff --git a/packages/SystemUI/res/interpolator/trusted_state_to_error_animation_interpolator_2.xml b/packages/SystemUI/res/interpolator/trusted_state_to_error_animation_interpolator_2.xml
new file mode 100755
index 0000000..be7cc69
--- /dev/null
+++ b/packages/SystemUI/res/interpolator/trusted_state_to_error_animation_interpolator_2.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<pathInterpolator
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:pathData="M 0.0,0.0 c 0.00010,0.0 0.2,1.0 1.0,1.0" />
diff --git a/packages/SystemUI/res/interpolator/trusted_state_to_error_animation_interpolator_3.xml b/packages/SystemUI/res/interpolator/trusted_state_to_error_animation_interpolator_3.xml
new file mode 100755
index 0000000..83af65a
--- /dev/null
+++ b/packages/SystemUI/res/interpolator/trusted_state_to_error_animation_interpolator_3.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<pathInterpolator
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:pathData="M 0.0,0.0 c 0.4,0.0 0.9999,1.0 1.0,1.0" />
diff --git a/packages/SystemUI/res/layout/navigation_bar.xml b/packages/SystemUI/res/layout/navigation_bar.xml
index c92ba45..d58664f 100644
--- a/packages/SystemUI/res/layout/navigation_bar.xml
+++ b/packages/SystemUI/res/layout/navigation_bar.xml
@@ -213,7 +213,7 @@
android:layout_width="match_parent"
android:layout_height="40dp"
android:contentDescription="@string/accessibility_menu"
- android:src="@drawable/ic_sysbar_menu_land"
+ android:src="@drawable/ic_sysbar_menu"
android:scaleType="centerInside"
android:layout_gravity="top"
android:visibility="invisible"
@@ -223,7 +223,7 @@
<com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/recent_apps"
android:layout_height="@dimen/navigation_key_width"
android:layout_width="match_parent"
- android:src="@drawable/ic_sysbar_recent_land"
+ android:src="@drawable/ic_sysbar_recent"
android:scaleType="center"
android:layout_weight="0"
android:contentDescription="@string/accessibility_recent"
@@ -237,7 +237,7 @@
<com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/home"
android:layout_height="@dimen/navigation_key_width"
android:layout_width="match_parent"
- android:src="@drawable/ic_sysbar_home_land"
+ android:src="@drawable/ic_sysbar_home"
android:scaleType="center"
systemui:keyCode="3"
systemui:keyRepeat="false"
@@ -253,7 +253,7 @@
<com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/back"
android:layout_height="@dimen/navigation_key_width"
android:layout_width="match_parent"
- android:src="@drawable/ic_sysbar_back_land"
+ android:src="@drawable/ic_sysbar_back"
android:scaleType="center"
systemui:keyCode="4"
android:layout_weight="0"
diff --git a/packages/SystemUI/res/values-af/strings.xml b/packages/SystemUI/res/values-af/strings.xml
index f58ae73..f797e04 100644
--- a/packages/SystemUI/res/values-af/strings.xml
+++ b/packages/SystemUI/res/values-af/strings.xml
@@ -325,6 +325,8 @@
<string name="interruption_level_priority_twoline" msgid="1564715335217164124">"Net\nprioriteit"</string>
<string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"Net\nwekkers"</string>
<string name="keyguard_indication_charging_time" msgid="1757251776872835768">"Laai tans (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> tot vol)"</string>
+ <string name="keyguard_indication_charging_time_fast" msgid="9018981952053914986">"Laai tans vinnig (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> tot vol)"</string>
+ <string name="keyguard_indication_charging_time_slowly" msgid="955252797961724952">"Laai tans stadig (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> tot vol)"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="7305948938141024937">"Wissel gebruiker"</string>
<string name="accessibility_multi_user_switch_switcher_with_current" msgid="8434880595284601601">"Wissel gebruiker, huidige gebruiker <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_inactive" msgid="1424081831468083402">"Huidige gebruiker <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
@@ -426,4 +428,7 @@
<string name="tuner_toast" msgid="603429811084428439">"Geluk! Stelsel-UI-ontvanger is by Instellings gevoeg"</string>
<string name="remove_from_settings" msgid="8389591916603406378">"Verwyder uit Instellings"</string>
<string name="remove_from_settings_prompt" msgid="6069085993355887748">"Verwyder Stelsel-UI-ontvanger uit Instellings en staak die gebruik van al sy kenmerke?"</string>
+ <string name="enable_bluetooth_title" msgid="5027037706500635269">"Skakel Bluetooth aan?"</string>
+ <string name="enable_bluetooth_message" msgid="9106595990708985385">"Jy moet Bluetooth aanskakel om jou sleutelbord aan jou tablet te koppel."</string>
+ <string name="enable_bluetooth_confirmation_ok" msgid="6258074250948309715">"Skakel aan"</string>
</resources>
diff --git a/packages/SystemUI/res/values-am/strings.xml b/packages/SystemUI/res/values-am/strings.xml
index 07c780b2..e4d04ad 100644
--- a/packages/SystemUI/res/values-am/strings.xml
+++ b/packages/SystemUI/res/values-am/strings.xml
@@ -325,6 +325,8 @@
<string name="interruption_level_priority_twoline" msgid="1564715335217164124">"ቅድሚያ ተሰጪ\nብቻ"</string>
<string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"ማንቂያዎች\nብቻ"</string>
<string name="keyguard_indication_charging_time" msgid="1757251776872835768">"ሃይል በመሙላት ላይ (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> እስከሚሞላ ድረስ)"</string>
+ <string name="keyguard_indication_charging_time_fast" msgid="9018981952053914986">"ኃይል በፍጥነት በመሙላት ላይ (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> እስከሚሞላ ድረስ)"</string>
+ <string name="keyguard_indication_charging_time_slowly" msgid="955252797961724952">"ኃይል በዝግታ በመሙላት ላይ (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> እስከሚሞላ ድረስ)"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="7305948938141024937">"ተጠቃሚ ቀይር"</string>
<string name="accessibility_multi_user_switch_switcher_with_current" msgid="8434880595284601601">"ተጠቃሚ ይለውጡ፣ የአሁን ተጠቃሚ <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_inactive" msgid="1424081831468083402">"የአሁን ተጠቃሚ <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
@@ -426,4 +428,7 @@
<string name="tuner_toast" msgid="603429811084428439">"እንኳን ደስ ያለዎት! የስርዓት በይነገጽ መቃኛ ወደ ቅንብሮች ታክሏል"</string>
<string name="remove_from_settings" msgid="8389591916603406378">"ከቅንብሮች አስወግድ"</string>
<string name="remove_from_settings_prompt" msgid="6069085993355887748">"ከቅንብሮች ላይ የስርዓት በይነገጽ መቃኛ ተወግዶ ሁሉም ባህሪዎቹን መጠቀም ይቁም?"</string>
+ <string name="enable_bluetooth_title" msgid="5027037706500635269">"ብሉቱዝ ይብራ?"</string>
+ <string name="enable_bluetooth_message" msgid="9106595990708985385">"የቁልፍ ሰሌዳዎን ከእርስዎ ጡባዊ ጋር ለማገናኘት በመጀመሪያ ብሉቱዝን ማብራት አለብዎት።"</string>
+ <string name="enable_bluetooth_confirmation_ok" msgid="6258074250948309715">"አብራ"</string>
</resources>
diff --git a/packages/SystemUI/res/values-ar/strings.xml b/packages/SystemUI/res/values-ar/strings.xml
index dac9b01..2a0d053 100644
--- a/packages/SystemUI/res/values-ar/strings.xml
+++ b/packages/SystemUI/res/values-ar/strings.xml
@@ -329,6 +329,8 @@
<string name="interruption_level_priority_twoline" msgid="1564715335217164124">"الأولوية \nفقط"</string>
<string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"التنبيهات\nفقط"</string>
<string name="keyguard_indication_charging_time" msgid="1757251776872835768">"جارٍ الشحن (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> حتى الامتلاء)"</string>
+ <string name="keyguard_indication_charging_time_fast" msgid="9018981952053914986">"جارٍ الشحن سريعًا (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> حتى الاكتمال)"</string>
+ <string name="keyguard_indication_charging_time_slowly" msgid="955252797961724952">"جارٍ الشحن ببطء (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> حتى الاكتمال)"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="7305948938141024937">"تبديل المستخدم"</string>
<string name="accessibility_multi_user_switch_switcher_with_current" msgid="8434880595284601601">"تبديل المستخدم، المستخدم الحالي <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_inactive" msgid="1424081831468083402">"المستخدم الحالي <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
@@ -430,4 +432,7 @@
<string name="tuner_toast" msgid="603429811084428439">"تهانينا! تمت إضافة أداة ضبط واجهة مستخدم النظام إلى الإعدادات"</string>
<string name="remove_from_settings" msgid="8389591916603406378">"إزالة من الإعدادات"</string>
<string name="remove_from_settings_prompt" msgid="6069085993355887748">"هل تريد إزالة أداة ضبط واجهة مستخدم النظام من الإعدادات وإيقاف استخدام كل ميزاتها؟"</string>
+ <string name="enable_bluetooth_title" msgid="5027037706500635269">"تشغيل البلوتوث؟"</string>
+ <string name="enable_bluetooth_message" msgid="9106595990708985385">"لتوصيل لوحة المفاتيح بالجهاز اللوحي، يلزمك تشغيل بلوتوث أولاً."</string>
+ <string name="enable_bluetooth_confirmation_ok" msgid="6258074250948309715">"تشغيل"</string>
</resources>
diff --git a/packages/SystemUI/res/values-az-rAZ/strings.xml b/packages/SystemUI/res/values-az-rAZ/strings.xml
index 41a6e26..65c196b 100644
--- a/packages/SystemUI/res/values-az-rAZ/strings.xml
+++ b/packages/SystemUI/res/values-az-rAZ/strings.xml
@@ -325,6 +325,8 @@
<string name="interruption_level_priority_twoline" msgid="1564715335217164124">"Yalnız\nprioritet"</string>
<string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"Yalnız\nalarmlar"</string>
<string name="keyguard_indication_charging_time" msgid="1757251776872835768">"Qidalanır (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> dolana kimi)"</string>
+ <string name="keyguard_indication_charging_time_fast" msgid="9018981952053914986">"Sürətli qidalanır (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> dolana kimi)"</string>
+ <string name="keyguard_indication_charging_time_slowly" msgid="955252797961724952">"Ləng qidalanır (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> dolana kimi)"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="7305948938141024937">"Switch user"</string>
<string name="accessibility_multi_user_switch_switcher_with_current" msgid="8434880595284601601">"İstifadəçiləri dəyişin, indiki istifadəçi: <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_inactive" msgid="1424081831468083402">"Cari istifadəçi <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
@@ -426,4 +428,7 @@
<string name="tuner_toast" msgid="603429811084428439">"Təbriklər! System UI Tuner Ayarlara əlavə edildi"</string>
<string name="remove_from_settings" msgid="8389591916603406378">"Ayarlardan Silin"</string>
<string name="remove_from_settings_prompt" msgid="6069085993355887748">"System UI Tuner Ayarlardan silinsin və onun bütün funksiyalarından istifadə dayandırılsın?"</string>
+ <string name="enable_bluetooth_title" msgid="5027037706500635269">"Bluetooth aktivləşsin?"</string>
+ <string name="enable_bluetooth_message" msgid="9106595990708985385">"Tabletinizlə klaviaturaya bağlanmaq üçün ilk olaraq Bluetooth\'u aktivləşdirməlisiniz."</string>
+ <string name="enable_bluetooth_confirmation_ok" msgid="6258074250948309715">"Aktivləşdirin"</string>
</resources>
diff --git a/packages/SystemUI/res/values-bg/strings.xml b/packages/SystemUI/res/values-bg/strings.xml
index f3d93fc..c9dc33d 100644
--- a/packages/SystemUI/res/values-bg/strings.xml
+++ b/packages/SystemUI/res/values-bg/strings.xml
@@ -325,6 +325,8 @@
<string name="interruption_level_priority_twoline" msgid="1564715335217164124">"Само\nс приоритет"</string>
<string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"Само\nбудилници"</string>
<string name="keyguard_indication_charging_time" msgid="1757251776872835768">"Зарежда се (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> до пълно зареждане)"</string>
+ <string name="keyguard_indication_charging_time_fast" msgid="9018981952053914986">"Зарежда се бързо (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> до пълно зареждане)"</string>
+ <string name="keyguard_indication_charging_time_slowly" msgid="955252797961724952">"Зарежда се бавно (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> до пълно зареждане)"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="7305948938141024937">"Превключване между потребителите"</string>
<string name="accessibility_multi_user_switch_switcher_with_current" msgid="8434880595284601601">"Превключване на потребителя – текущият е <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_inactive" msgid="1424081831468083402">"Текущ потребител – <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
@@ -426,4 +428,7 @@
<string name="tuner_toast" msgid="603429811084428439">"Поздравления! Тунерът на системния потребителски интерфейс е добавен към „Настройки“"</string>
<string name="remove_from_settings" msgid="8389591916603406378">"Премахване от „Настройки“"</string>
<string name="remove_from_settings_prompt" msgid="6069085993355887748">"Да се премахне ли от „Настройки“ тунерът на системния потребителски интерфейс и да се спре ли използването на всичките му функции?"</string>
+ <string name="enable_bluetooth_title" msgid="5027037706500635269">"Да се включи ли Bluetooth?"</string>
+ <string name="enable_bluetooth_message" msgid="9106595990708985385">"За да свържете клавиатурата с таблета си, първо трябва да включите Bluetooth."</string>
+ <string name="enable_bluetooth_confirmation_ok" msgid="6258074250948309715">"Включване"</string>
</resources>
diff --git a/packages/SystemUI/res/values-bn-rBD/strings.xml b/packages/SystemUI/res/values-bn-rBD/strings.xml
index 0c18479..c900656 100644
--- a/packages/SystemUI/res/values-bn-rBD/strings.xml
+++ b/packages/SystemUI/res/values-bn-rBD/strings.xml
@@ -325,6 +325,8 @@
<string name="interruption_level_priority_twoline" msgid="1564715335217164124">"শুধুমাত্র\nঅগ্রাধিকার"</string>
<string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"শুধুমাত্র\nঅ্যালার্মগুলি"</string>
<string name="keyguard_indication_charging_time" msgid="1757251776872835768">"চার্জ হচ্ছে (পূর্ণ হতে <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> সময় বাকি)"</string>
+ <string name="keyguard_indication_charging_time_fast" msgid="9018981952053914986">"দ্রুত চার্জ হচ্ছে (পূর্ণ হতে <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> সময় বাকি)"</string>
+ <string name="keyguard_indication_charging_time_slowly" msgid="955252797961724952">"ধীরে ধীরে চার্জ হচ্ছে (পূর্ণ হতে <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> সময় বাকি)"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="7305948938141024937">"ব্যবহারকারী পাল্টে দিন"</string>
<string name="accessibility_multi_user_switch_switcher_with_current" msgid="8434880595284601601">"ব্যবহারকারী পাল্টান, বর্তমান ব্যবহারকারী <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_inactive" msgid="1424081831468083402">"<xliff:g id="CURRENT_USER_NAME">%s</xliff:g> হল বর্তমান ব্যবহারকারী"</string>
@@ -426,4 +428,7 @@
<string name="tuner_toast" msgid="603429811084428439">"অভিনন্দন! সেটিংস -এ সিস্টেম UI টিউনার যোগ করা হয়েছে"</string>
<string name="remove_from_settings" msgid="8389591916603406378">"সেটিংস থেকে সরান"</string>
<string name="remove_from_settings_prompt" msgid="6069085993355887748">"সেটিংস থেকে সিস্টেম UI টিউনার সরাতে এবং এটির সমস্ত বৈশিষ্ট্য ব্যবহার করা বন্ধ করতে চান?"</string>
+ <string name="enable_bluetooth_title" msgid="5027037706500635269">"Bluetooth চালু করবেন?"</string>
+ <string name="enable_bluetooth_message" msgid="9106595990708985385">"আপনার ট্যাবলেটের সাথে আপনার কীবোর্ড সংযুক্ত করতে, আপনাকে প্রথমে Bluetooth চালু করতে হবে।"</string>
+ <string name="enable_bluetooth_confirmation_ok" msgid="6258074250948309715">"চালু করুন"</string>
</resources>
diff --git a/packages/SystemUI/res/values-ca/strings.xml b/packages/SystemUI/res/values-ca/strings.xml
index d534ab9..b5000b0 100644
--- a/packages/SystemUI/res/values-ca/strings.xml
+++ b/packages/SystemUI/res/values-ca/strings.xml
@@ -150,9 +150,7 @@
<string name="accessibility_airplane_mode" msgid="834748999790763092">"Mode d\'avió."</string>
<string name="accessibility_no_sims" msgid="3957997018324995781">"No hi ha cap targeta SIM."</string>
<string name="accessibility_carrier_network_change_mode" msgid="4017301580441304305">"S\'està canviant la xarxa de l\'operador de telefonia mòbil."</string>
- <!-- String.format failed for translation -->
- <!-- no translation found for accessibility_battery_level (7451474187113371965) -->
- <skip />
+ <string name="accessibility_battery_level" msgid="7451474187113371965">"<xliff:g id="NUMBER">%d</xliff:g> per cent de bateria."</string>
<string name="accessibility_settings_button" msgid="799583911231893380">"Configuració del sistema."</string>
<string name="accessibility_notifications_button" msgid="4498000369779421892">"Notificacions."</string>
<string name="accessibility_remove_notification" msgid="3603099514902182350">"Esborra la notificació."</string>
@@ -170,7 +168,7 @@
<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">"Notificació omesa."</string>
<string name="accessibility_desc_notification_shade" msgid="4690274844447504208">"Àrea de notificacions"</string>
- <string name="accessibility_desc_quick_settings" msgid="6186378411582437046">"Configuració ràpida."</string>
+ <string name="accessibility_desc_quick_settings" msgid="6186378411582437046">"Configuració ràpida"</string>
<string name="accessibility_desc_lock_screen" msgid="5625143713611759164">"Pantalla de bloqueig"</string>
<string name="accessibility_desc_settings" msgid="3417884241751434521">"Configuració"</string>
<string name="accessibility_desc_recent_apps" msgid="4876900986661819788">"Visió general"</string>
@@ -270,7 +268,7 @@
<string name="quick_settings_cast_title" msgid="7709016546426454729">"Emet"</string>
<string name="quick_settings_casting" msgid="6601710681033353316">"En emissió"</string>
<string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"Dispositiu sense nom"</string>
- <string name="quick_settings_cast_device_default_description" msgid="2484573682378634413">"A punt per a l\'emissió"</string>
+ <string name="quick_settings_cast_device_default_description" msgid="2484573682378634413">"A punt per emetre"</string>
<string name="quick_settings_cast_detail_empty_text" msgid="311785821261640623">"No hi ha cap dispositiu disponible."</string>
<string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Brillantor"</string>
<string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"AUTOMÀTICA"</string>
@@ -327,6 +325,8 @@
<string name="interruption_level_priority_twoline" msgid="1564715335217164124">"Només\ninterr. prior."</string>
<string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"Només\nalarmes"</string>
<string name="keyguard_indication_charging_time" msgid="1757251776872835768">"Carregant (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> per completar la càrrega)"</string>
+ <string name="keyguard_indication_charging_time_fast" msgid="9018981952053914986">"Càrrega ràpida (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> per completar-se)"</string>
+ <string name="keyguard_indication_charging_time_slowly" msgid="955252797961724952">"Càrrega lenta (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> per completar-se)"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="7305948938141024937">"Canvia d\'usuari"</string>
<string name="accessibility_multi_user_switch_switcher_with_current" msgid="8434880595284601601">"Canvia l\'usuari. Usuari actual: <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_inactive" msgid="1424081831468083402">"Usuari actual: <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
@@ -335,7 +335,7 @@
<string name="user_new_user_name" msgid="426540612051178753">"Usuari nou"</string>
<string name="guest_nickname" msgid="8059989128963789678">"Convidat"</string>
<string name="guest_new_guest" msgid="600537543078847803">"Afegeix un convidat"</string>
- <string name="guest_exit_guest" msgid="7187359342030096885">"Suprimeix l\'usuari"</string>
+ <string name="guest_exit_guest" msgid="7187359342030096885">"Suprimeix el convidat"</string>
<string name="guest_exit_guest_dialog_title" msgid="8480693520521766688">"Vols suprimir el convidat?"</string>
<string name="guest_exit_guest_dialog_message" msgid="4155503224769676625">"Totes les aplicacions i les dades d\'aquesta sessió se suprimiran."</string>
<string name="guest_exit_guest_dialog_remove" msgid="7402231963862520531">"Suprimeix"</string>
@@ -348,7 +348,7 @@
<string name="guest_notification_remove_action" msgid="8820670703892101990">"SUPRIMEIX EL CONVIDAT"</string>
<string name="user_add_user_title" msgid="4553596395824132638">"Vols afegir un usuari nou?"</string>
<string name="user_add_user_message_short" msgid="2161624834066214559">"Quan s\'afegeix un usuari nou, aquest usuari ha de configurar-se l\'espai.\n\nQualsevol usuari pot actualitzar les aplicacions de la resta d\'usuaris."</string>
- <string name="battery_saver_notification_title" msgid="237918726750955859">"Estalvi de bateria activada"</string>
+ <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="notification_hidden_text" msgid="1135169301897151909">"Contingut amagat"</string>
@@ -400,7 +400,7 @@
<string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> és el diàleg de volum"</string>
<string name="volumeui_notification_text" msgid="1826889705095768656">"Toca per restaurar l\'original."</string>
<string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Estàs utilitzant el perfil professional"</string>
- <string name="system_ui_tuner" msgid="708224127392452018">"Configurador de la IU del sistema"</string>
+ <string name="system_ui_tuner" msgid="708224127392452018">"Personalitzador d\'interfície d\'usuari"</string>
<string name="show_battery_percentage" msgid="5444136600512968798">"Mostra el percentatge de la bateria inserit"</string>
<string name="show_battery_percentage_summary" msgid="3215025775576786037">"Mostra el percentatge del nivell de bateria dins de la icona de la barra d\'estat quan no s\'estigui carregant"</string>
<string name="quick_settings" msgid="10042998191725428">"Configuració ràpida"</string>
@@ -422,10 +422,13 @@
<string name="accessibility_status_bar_hotspot" msgid="4099381329956402865">"Zona Wi-Fi"</string>
<string name="accessibility_managed_profile" msgid="6613641363112584120">"Perfil professional"</string>
<string name="tuner_warning_title" msgid="7094689930793031682">"Diversió per a uns quants, però no per a tothom"</string>
- <string name="tuner_warning" msgid="8730648121973575701">"El Configurador de la IU del sistema presenta opcions addicionals per canviar i personalitzar la interfície d\'usuari d\'Android. És possible que aquestes funcions experimentals canviïn, deixin de funcionar o desapareguin en versions futures. Continua amb precaució."</string>
+ <string name="tuner_warning" msgid="8730648121973575701">"El Personalitzador d\'interfície d\'usuari presenta opcions addicionals per canviar i personalitzar la interfície d\'usuari d\'Android. És possible que aquestes funcions experimentals canviïn, deixin de funcionar o desapareguin en versions futures. Continua amb precaució."</string>
<string name="tuner_persistent_warning" msgid="8597333795565621795">"És possible que aquestes funcions experimentals canviïn, deixin de funcionar o desapareguin en versions futures. Continua amb precaució."</string>
<string name="got_it" msgid="2239653834387972602">"D\'acord"</string>
- <string name="tuner_toast" msgid="603429811084428439">"Enhorabona! El Configurador de la IU del sistema s\'ha afegit a Configuració."</string>
+ <string name="tuner_toast" msgid="603429811084428439">"Enhorabona! El Personalitzador d\'interfície d\'usuari s\'ha afegit a Configuració."</string>
<string name="remove_from_settings" msgid="8389591916603406378">"Treu de Configuració"</string>
- <string name="remove_from_settings_prompt" msgid="6069085993355887748">"Vols treure el Configurador de la UI del sistema de Configuració i deixar d\'utilitzar-ne totes les funcions?"</string>
+ <string name="remove_from_settings_prompt" msgid="6069085993355887748">"Vols suprimir el Personalitzador d\'interfície d\'usuari de Configuració i deixar d\'utilitzar-ne totes les funcions?"</string>
+ <string name="enable_bluetooth_title" msgid="5027037706500635269">"Vols activar el Bluetooth?"</string>
+ <string name="enable_bluetooth_message" msgid="9106595990708985385">"Per connectar el teclat amb la tauleta, primer has d\'activar el Bluetooth."</string>
+ <string name="enable_bluetooth_confirmation_ok" msgid="6258074250948309715">"Activa"</string>
</resources>
diff --git a/packages/SystemUI/res/values-cs/strings.xml b/packages/SystemUI/res/values-cs/strings.xml
index 3330500..ab5caa5 100644
--- a/packages/SystemUI/res/values-cs/strings.xml
+++ b/packages/SystemUI/res/values-cs/strings.xml
@@ -152,9 +152,7 @@
<string name="accessibility_airplane_mode" msgid="834748999790763092">"Režim Letadlo."</string>
<string name="accessibility_no_sims" msgid="3957997018324995781">"Není vložena SIM karta"</string>
<string name="accessibility_carrier_network_change_mode" msgid="4017301580441304305">"Probíhá změna sítě operátora."</string>
- <!-- String.format failed for translation -->
- <!-- no translation found for accessibility_battery_level (7451474187113371965) -->
- <skip />
+ <string name="accessibility_battery_level" msgid="7451474187113371965">"Stav baterie: <xliff:g id="NUMBER">%d</xliff:g> procent."</string>
<string name="accessibility_settings_button" msgid="799583911231893380">"Systémová nastavení."</string>
<string name="accessibility_notifications_button" msgid="4498000369779421892">"Oznámení."</string>
<string name="accessibility_remove_notification" msgid="3603099514902182350">"Vymazat oznámení."</string>
@@ -329,6 +327,8 @@
<string name="interruption_level_priority_twoline" msgid="1564715335217164124">"Pouze\nprioritní"</string>
<string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"Pouze\nbudíky"</string>
<string name="keyguard_indication_charging_time" msgid="1757251776872835768">"Nabíjení (plně nabito za <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>)"</string>
+ <string name="keyguard_indication_charging_time_fast" msgid="9018981952053914986">"Rychlé nabíjení (plně nabito za <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>)"</string>
+ <string name="keyguard_indication_charging_time_slowly" msgid="955252797961724952">"Pomalé nabíjení (plně nabito za <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>)"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="7305948938141024937">"Přepnout uživatele"</string>
<string name="accessibility_multi_user_switch_switcher_with_current" msgid="8434880595284601601">"Přepnout uživatele, aktuální uživatel: <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_inactive" msgid="1424081831468083402">"Aktuální uživatel <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
@@ -430,4 +430,7 @@
<string name="tuner_toast" msgid="603429811084428439">"Úspěch! Do Nastavení byl přidán nástroj na ladění uživatelského rozhraní systému."</string>
<string name="remove_from_settings" msgid="8389591916603406378">"Odstranit z Nastavení"</string>
<string name="remove_from_settings_prompt" msgid="6069085993355887748">"Chcete nástroj na ladění uživatelského rozhraní systému odstranit z Nastavení a přestat používat všechny jeho funkce?"</string>
+ <string name="enable_bluetooth_title" msgid="5027037706500635269">"Zapnout Bluetooth?"</string>
+ <string name="enable_bluetooth_message" msgid="9106595990708985385">"Chcete-li klávesnici připojit k tabletu, nejdříve musíte zapnout Bluetooth."</string>
+ <string name="enable_bluetooth_confirmation_ok" msgid="6258074250948309715">"Zapnout"</string>
</resources>
diff --git a/packages/SystemUI/res/values-da/strings.xml b/packages/SystemUI/res/values-da/strings.xml
index 3c0c0b2..28e7a487 100644
--- a/packages/SystemUI/res/values-da/strings.xml
+++ b/packages/SystemUI/res/values-da/strings.xml
@@ -85,13 +85,13 @@
<string name="accessibility_search_light" msgid="1103867596330271848">"Søg"</string>
<string name="accessibility_camera_button" msgid="8064671582820358152">"Kamera"</string>
<string name="accessibility_phone_button" msgid="6738112589538563574">"Telefon"</string>
- <string name="accessibility_voice_assist_button" msgid="487611083884852965">"Voice Assist"</string>
+ <string name="accessibility_voice_assist_button" msgid="487611083884852965">"Taleassistent"</string>
<string name="accessibility_unlock_button" msgid="128158454631118828">"Lås op"</string>
<string name="accessibility_unlock_button_fingerprint" msgid="8214125623493923751">"Knap til oplåsning. Venter på fingeraftryk"</string>
<string name="accessibility_unlock_without_fingerprint" msgid="7541705575183694446">"Lås op uden at bruge dit fingeraftryk"</string>
<string name="unlock_label" msgid="8779712358041029439">"lås op"</string>
<string name="phone_label" msgid="2320074140205331708">"åbn telefon"</string>
- <string name="voice_assist_label" msgid="3956854378310019854">"åbn voice assist"</string>
+ <string name="voice_assist_label" msgid="3956854378310019854">"åbn taleassistent"</string>
<string name="camera_label" msgid="7261107956054836961">"åbn kamera"</string>
<string name="recents_caption_resize" msgid="3517056471774958200">"Vælg nyt opgavelayout"</string>
<string name="cancel" msgid="6442560571259935130">"Annuller"</string>
@@ -183,12 +183,12 @@
<string name="accessibility_quick_settings_airplane_on" msgid="6406141469157599296">"Flytilstand er slået til."</string>
<string name="accessibility_quick_settings_airplane_changed_off" msgid="66846307818850664">"Flytilstand er slået fra."</string>
<string name="accessibility_quick_settings_airplane_changed_on" msgid="8983005603505087728">"Flytilstand er slået til."</string>
- <string name="accessibility_quick_settings_dnd_priority_on" msgid="1448402297221249355">"\"Vil ikke forstyrres\" er slået til, kun prioritet."</string>
- <string name="accessibility_quick_settings_dnd_none_on" msgid="6882582132662613537">"\"Vil ikke forstyrres\" er slået til, total stilhed."</string>
- <string name="accessibility_quick_settings_dnd_alarms_on" msgid="9152834845587554157">"\"Vil ikke forstyrres\" er slået til, kun alarmer."</string>
- <string name="accessibility_quick_settings_dnd_off" msgid="2371832603753738581">"\"Vil ikke forstyrres\" er slået fra."</string>
- <string name="accessibility_quick_settings_dnd_changed_off" msgid="898107593453022935">"\"Vil ikke forstyrres\" er slået fra."</string>
- <string name="accessibility_quick_settings_dnd_changed_on" msgid="4483780856613561039">"\"Vil ikke forstyrres\" er slået til."</string>
+ <string name="accessibility_quick_settings_dnd_priority_on" msgid="1448402297221249355">"\"Forstyr ikke\" er slået til, kun prioritet."</string>
+ <string name="accessibility_quick_settings_dnd_none_on" msgid="6882582132662613537">"\"Forstyr ikke\" er slået til, total stilhed."</string>
+ <string name="accessibility_quick_settings_dnd_alarms_on" msgid="9152834845587554157">"\"Forstyr ikke\" er slået til, kun alarmer."</string>
+ <string name="accessibility_quick_settings_dnd_off" msgid="2371832603753738581">"\"Forstyr ikke\" er slået fra."</string>
+ <string name="accessibility_quick_settings_dnd_changed_off" msgid="898107593453022935">"\"Forstyr ikke\" er slået fra."</string>
+ <string name="accessibility_quick_settings_dnd_changed_on" msgid="4483780856613561039">"\"Forstyr ikke\" er slået til."</string>
<string name="accessibility_quick_settings_bluetooth_off" msgid="2133631372372064339">"Bluetooth er slået fra."</string>
<string name="accessibility_quick_settings_bluetooth_on" msgid="7681999166216621838">"Bluetooth er slået til."</string>
<string name="accessibility_quick_settings_bluetooth_connecting" msgid="6953242966685343855">"Opretter forbindelse til Bluetooth."</string>
@@ -236,7 +236,7 @@
<string name="dessert_case" msgid="1295161776223959221">"Dessertcase"</string>
<string name="start_dreams" msgid="7219575858348719790">"Dagdrøm"</string>
<string name="ethernet_label" msgid="7967563676324087464">"Ethernet"</string>
- <string name="quick_settings_dnd_label" msgid="8735855737575028208">"Vil ikke forstyrres"</string>
+ <string name="quick_settings_dnd_label" msgid="8735855737575028208">"Forstyr ikke"</string>
<string name="quick_settings_dnd_priority_label" msgid="483232950670692036">"Kun prioritet"</string>
<string name="quick_settings_dnd_alarms_label" msgid="2559229444312445858">"Kun Alarmer"</string>
<string name="quick_settings_dnd_none_label" msgid="5025477807123029478">"Total stilhed"</string>
@@ -315,7 +315,7 @@
<string name="notification_tap_again" msgid="8524949573675922138">"Tryk igen for at åbne"</string>
<string name="keyguard_unlock" msgid="8043466894212841998">"Stryg opad for at låse op"</string>
<string name="phone_hint" msgid="4872890986869209950">"Stryg fra telefonikonet"</string>
- <string name="voice_hint" msgid="8939888732119726665">"Stryg fra ikonet for voice assist"</string>
+ <string name="voice_hint" msgid="8939888732119726665">"Stryg fra mikrofonikonet"</string>
<string name="camera_hint" msgid="7939688436797157483">"Stryg fra kameraikonet"</string>
<string name="interruption_level_none_with_warning" msgid="5114872171614161084">"Helt lydløs. Denne handling slukker også skærmlæsere."</string>
<string name="interruption_level_none" msgid="6000083681244492992">"Total stilhed"</string>
@@ -325,6 +325,8 @@
<string name="interruption_level_priority_twoline" msgid="1564715335217164124">"Kun\nprioritet"</string>
<string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"Kun\nalarmer"</string>
<string name="keyguard_indication_charging_time" msgid="1757251776872835768">"Oplader (fuldt opladet om <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>)"</string>
+ <string name="keyguard_indication_charging_time_fast" msgid="9018981952053914986">"Hurtig opladning (fuldt opladet om <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>)"</string>
+ <string name="keyguard_indication_charging_time_slowly" msgid="955252797961724952">"Langsom opladning (fuldt opladet om <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>)"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="7305948938141024937">"Skift bruger"</string>
<string name="accessibility_multi_user_switch_switcher_with_current" msgid="8434880595284601601">"Skift bruger. Nuværende bruger er <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_inactive" msgid="1424081831468083402">"Nuværende bruger: <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
@@ -426,4 +428,7 @@
<string name="tuner_toast" msgid="603429811084428439">"System UI Tuner blev føjet til Indstillinger"</string>
<string name="remove_from_settings" msgid="8389591916603406378">"Fjern fra Indstillinger"</string>
<string name="remove_from_settings_prompt" msgid="6069085993355887748">"Vil du fjerne System UI Tuner fra Indstillinger og stoppe med at bruge alle dens funktioner?"</string>
+ <string name="enable_bluetooth_title" msgid="5027037706500635269">"Vil du slå Bluetooth til?"</string>
+ <string name="enable_bluetooth_message" msgid="9106595990708985385">"Bluetooth skal være slået til, før du kan knytte dit tastatur til din tablet."</string>
+ <string name="enable_bluetooth_confirmation_ok" msgid="6258074250948309715">"Slå til"</string>
</resources>
diff --git a/packages/SystemUI/res/values-de/strings.xml b/packages/SystemUI/res/values-de/strings.xml
index 310436a..82d067e 100644
--- a/packages/SystemUI/res/values-de/strings.xml
+++ b/packages/SystemUI/res/values-de/strings.xml
@@ -23,7 +23,7 @@
<string name="status_bar_clear_all_button" msgid="7774721344716731603">"Löschen"</string>
<string name="status_bar_recent_remove_item_title" msgid="6026395868129852968">"Aus Liste entfernen"</string>
<string name="status_bar_recent_inspect_item_title" msgid="7793624864528818569">"App-Info"</string>
- <string name="status_bar_no_recent_apps" msgid="7374907845131203189">"Hier sehen Sie Ihre zuletzt geöffneten Apps."</string>
+ <string name="status_bar_no_recent_apps" msgid="7374907845131203189">"Hier siehst du deine zuletzt geöffneten Apps."</string>
<string name="status_bar_accessibility_dismiss_recents" msgid="4576076075226540105">"Kürzlich geöffnete Apps schließen"</string>
<plurals name="status_bar_accessibility_recent_apps" formatted="false" msgid="9138535907802238759">
<item quantity="other">%d Bildschirme in der Übersicht</item>
@@ -35,9 +35,9 @@
<string name="battery_low_title" msgid="6456385927409742437">"Akku ist schwach"</string>
<string name="battery_low_percent_format" msgid="2900940511201380775">"<xliff:g id="PERCENTAGE">%s</xliff:g> verbleibend"</string>
<string name="battery_low_percent_format_saver_started" msgid="6859235584035338833">"<xliff:g id="PERCENTAGE">%s</xliff:g> verbleibend. Der Energiesparmodus ist aktiviert."</string>
- <string name="invalid_charger" msgid="4549105996740522523">"USB-Aufladung wird nicht unterstützt.\nVerwenden Sie das mitgelieferte Aufladegerät."</string>
+ <string name="invalid_charger" msgid="4549105996740522523">"USB-Aufladung wird nicht unterstützt.\nVerwende das mitgelieferte Aufladegerät."</string>
<string name="invalid_charger_title" msgid="3515740382572798460">"Laden per USB wird nicht unterstützt."</string>
- <string name="invalid_charger_text" msgid="5474997287953892710">"Verwenden Sie nur das im Lieferumfang enthaltene Ladegerät."</string>
+ <string name="invalid_charger_text" msgid="5474997287953892710">"Verwende nur das im Lieferumfang enthaltene Ladegerät."</string>
<string name="battery_low_why" msgid="4553600287639198111">"Einstellungen"</string>
<string name="battery_saver_confirmation_title" msgid="5299585433050361634">"Energiesparmodus aktivieren?"</string>
<string name="battery_saver_confirmation_ok" msgid="7507968430447930257">"Aktivieren"</string>
@@ -64,7 +64,7 @@
<string name="usb_debugging_message" msgid="2220143855912376496">"Der Fingerabdruck des RSA-Schlüssels für diesen Computer lautet: \n<xliff:g id="FINGERPRINT">%1$s</xliff:g>"</string>
<string name="usb_debugging_always" msgid="303335496705863070">"Von diesem Computer immer zulassen"</string>
<string name="usb_debugging_secondary_user_title" msgid="6353808721761220421">"USB-Debugging nicht zulässig"</string>
- <string name="usb_debugging_secondary_user_message" msgid="6011931347142270156">"Der momentan auf diesem Gerät angemeldete Nutzer kann das USB-Debugging nicht aktivieren. Um diese Funktion zu aktivieren, wechseln Sie zum primären Nutzer \"<xliff:g id="NAME">%s</xliff:g>\"."</string>
+ <string name="usb_debugging_secondary_user_message" msgid="6011931347142270156">"Der momentan auf diesem Gerät angemeldete Nutzer kann das USB-Debugging nicht aktivieren. Um diese Funktion zu aktivieren, wechsle zum primären Nutzer \"<xliff:g id="NAME">%s</xliff:g>\"."</string>
<string name="compat_mode_on" msgid="6623839244840638213">"Zoom auf Bildschirmgröße"</string>
<string name="compat_mode_off" msgid="4434467572461327898">"Auf Bildschirmgröße anpassen"</string>
<string name="screenshot_saving_ticker" msgid="7403652894056693515">"Screenshot wird gespeichert..."</string>
@@ -73,7 +73,7 @@
<string name="screenshot_saved_title" msgid="6461865960961414961">"Screenshot aufgenommen"</string>
<string name="screenshot_saved_text" msgid="1152839647677558815">"Zum Ansehen berühren"</string>
<string name="screenshot_failed_title" msgid="705781116746922771">"Screenshot konnte nicht aufgenommen werden."</string>
- <string name="screenshot_failed_text" msgid="1260203058661337274">"Screenshot nicht möglich. Entweder zu wenig Speicher oder die App/Ihr Unternehmen lässt dies nicht zu."</string>
+ <string name="screenshot_failed_text" msgid="1260203058661337274">"Screenshot nicht möglich. Entweder zu wenig Speicher oder die App/dein Unternehmen lässt dies nicht zu."</string>
<string name="usb_preference_title" msgid="6551050377388882787">"USB-Dateiübertragungsoptionen"</string>
<string name="use_mtp_button_title" msgid="4333504413563023626">"Als Medienplayer (MTP) bereitstellen"</string>
<string name="use_ptp_button_title" msgid="7517127540301625751">"Als Kamera (PTP) bereitstellen"</string>
@@ -150,9 +150,7 @@
<string name="accessibility_airplane_mode" msgid="834748999790763092">"Flugmodus"</string>
<string name="accessibility_no_sims" msgid="3957997018324995781">"Keine SIM-Karte"</string>
<string name="accessibility_carrier_network_change_mode" msgid="4017301580441304305">"Netzwerk des Mobilfunkanbieters wird gewechselt"</string>
- <!-- String.format failed for translation -->
- <!-- no translation found for accessibility_battery_level (7451474187113371965) -->
- <skip />
+ <string name="accessibility_battery_level" msgid="7451474187113371965">"Akku bei <xliff:g id="NUMBER">%d</xliff:g> Prozent."</string>
<string name="accessibility_settings_button" msgid="799583911231893380">"Systemeinstellungen"</string>
<string name="accessibility_notifications_button" msgid="4498000369779421892">"Benachrichtigungen"</string>
<string name="accessibility_remove_notification" msgid="3603099514902182350">"Benachrichtigung löschen"</string>
@@ -219,7 +217,7 @@
<string name="data_usage_disabled_dialog_4g_title" msgid="1601769736881078016">"4G-Daten pausiert"</string>
<string name="data_usage_disabled_dialog_mobile_title" msgid="4651001290947318931">"Mobilfunkdaten pausiert"</string>
<string name="data_usage_disabled_dialog_title" msgid="3932437232199671967">"Daten pausiert"</string>
- <string name="data_usage_disabled_dialog" msgid="8453242888903772524">"Da Ihr festgelegtes Datenlimit erreicht wurde, hat das Gerät die Datennutzung für den Rest dieses Zeitraums pausiert.\n\nWenn Sie diese fortsetzen, können möglicherweise Kosten bei Ihrem Mobilfunkanbieter entstehen."</string>
+ <string name="data_usage_disabled_dialog" msgid="8453242888903772524">"Da dein festgelegtes Datenlimit erreicht wurde, hat das Gerät die Datennutzung für den Rest dieses Zeitraums pausiert.\n\nWenn du die Nutzung fortsetzt, entstehen möglicherweise Kosten bei deinem Mobilfunkanbieter."</string>
<string name="data_usage_disabled_dialog_enable" msgid="1412395410306390593">"Fortsetzen"</string>
<string name="status_bar_settings_signal_meter_disconnected" msgid="1940231521274147771">"Keine Internetverbindung"</string>
<string name="status_bar_settings_signal_meter_wifi_nossid" msgid="6557486452774597820">"WLAN verbunden"</string>
@@ -291,7 +289,7 @@
<string name="quick_settings_cellular_detail_data_used" msgid="1476810587475761478">"<xliff:g id="DATA_USED">%s</xliff:g> verwendet"</string>
<string name="quick_settings_cellular_detail_data_limit" msgid="56011158504994128">"<xliff:g id="DATA_LIMIT">%s</xliff:g> Datenlimit"</string>
<string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"Warnung für <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string>
- <string name="recents_empty_message" msgid="8682129509540827999">"Hier sehen Sie Ihre zuletzt geöffneten Apps."</string>
+ <string name="recents_empty_message" msgid="8682129509540827999">"Hier siehst du deine zuletzt geöffneten Apps."</string>
<string name="recents_app_info_button_label" msgid="2890317189376000030">"App-Info"</string>
<string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"Bildschirmfixierung"</string>
<string name="recents_search_bar_label" msgid="8074997400187836677">"Suche"</string>
@@ -308,9 +306,9 @@
<string name="description_target_search" msgid="3091587249776033139">"Suche"</string>
<string name="description_direction_up" msgid="7169032478259485180">"Zum <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> nach oben schieben"</string>
<string name="description_direction_left" msgid="7207478719805562165">"Zum <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> nach links schieben"</string>
- <string name="zen_priority_introduction" msgid="3070506961866919502">"Klingeltöne und die Vibration werden deaktiviert, außer für Weckrufe, Erinnerungen, Termine sowie Anrufe von zuvor von Ihnen festgelegten Personen."</string>
+ <string name="zen_priority_introduction" msgid="3070506961866919502">"Klingeltöne und die Vibration werden deaktiviert, außer für Weckrufe, Erinnerungen, Termine sowie Anrufe von zuvor von dir festgelegten Personen."</string>
<string name="zen_priority_customize_button" msgid="7948043278226955063">"Anpassen"</string>
- <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"Hierdurch werden alle Klingeltöne und Vibrationsalarme stummgeschaltet, auch für Weckrufe, Musik, Videos und Spiele. Anrufe können Sie jedoch weiterhin tätigen."</string>
+ <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"Hierdurch werden alle Klingeltöne und Vibrationsalarme stummgeschaltet, auch für Weckrufe, Musik, Videos und Spiele. Anrufe kannst du jedoch weiterhin tätigen."</string>
<string name="zen_silence_introduction" msgid="3137882381093271568">"Hierdurch werden alle Klingeltöne und Vibrationsalarme stummgeschaltet, auch für Weckrufe, Musik, Videos und Spiele."</string>
<string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
<string name="speed_bump_explanation" msgid="1288875699658819755">"Weniger dringende Benachrichtigungen unten"</string>
@@ -327,6 +325,8 @@
<string name="interruption_level_priority_twoline" msgid="1564715335217164124">"Nur\nwichtige"</string>
<string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"Nur\nWecker"</string>
<string name="keyguard_indication_charging_time" msgid="1757251776872835768">"Wird aufgeladen (voll in <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>)"</string>
+ <string name="keyguard_indication_charging_time_fast" msgid="9018981952053914986">"Wird schnell aufgeladen (voll in <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>)"</string>
+ <string name="keyguard_indication_charging_time_slowly" msgid="955252797961724952">"Wird langsam aufgeladen (voll in <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>)"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="7305948938141024937">"Nutzer wechseln"</string>
<string name="accessibility_multi_user_switch_switcher_with_current" msgid="8434880595284601601">"Nutzer wechseln. Aktueller Nutzer: <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_inactive" msgid="1424081831468083402">"Aktueller Nutzer <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
@@ -340,19 +340,19 @@
<string name="guest_exit_guest_dialog_message" msgid="4155503224769676625">"Alle Apps und Daten in dieser Sitzung werden gelöscht."</string>
<string name="guest_exit_guest_dialog_remove" msgid="7402231963862520531">"Entfernen"</string>
<string name="guest_wipe_session_title" msgid="6419439912885956132">"Willkommen zurück im Gastmodus"</string>
- <string name="guest_wipe_session_message" msgid="8476238178270112811">"Möchten Sie Ihre Sitzung fortsetzen?"</string>
+ <string name="guest_wipe_session_message" msgid="8476238178270112811">"Möchtest du deine Sitzung fortsetzen?"</string>
<string name="guest_wipe_session_wipe" msgid="5065558566939858884">"Von vorn"</string>
<string name="guest_wipe_session_dontwipe" msgid="1401113462524894716">"Ja, weiter"</string>
<string name="guest_notification_title" msgid="1585278533840603063">"Gastnutzer"</string>
<string name="guest_notification_text" msgid="335747957734796689">"Zum Löschen von Apps und Daten Gastnutzer entfernen"</string>
<string name="guest_notification_remove_action" msgid="8820670703892101990">"Gast entfernen"</string>
<string name="user_add_user_title" msgid="4553596395824132638">"Neuen Nutzer hinzufügen?"</string>
- <string name="user_add_user_message_short" msgid="2161624834066214559">"Wenn Sie einen neuen Nutzer hinzufügen, muss dieser seinen Bereich einrichten.\n\nJeder Nutzer kann Apps für alle anderen Nutzer aktualisieren."</string>
+ <string name="user_add_user_message_short" msgid="2161624834066214559">"Wenn du einen neuen Nutzer hinzufügst, muss dieser seinen Bereich einrichten.\n\nJeder Nutzer kann Apps für alle anderen Nutzer aktualisieren."</string>
<string name="battery_saver_notification_title" msgid="237918726750955859">"Energiesparmodus ist aktiviert"</string>
<string name="battery_saver_notification_text" msgid="820318788126672692">"Reduzierung der Leistung und Hintergrunddaten"</string>
<string name="battery_saver_notification_action_text" msgid="109158658238110382">"Energiesparmodus deaktivieren"</string>
<string name="notification_hidden_text" msgid="1135169301897151909">"Inhalte ausgeblendet"</string>
- <string name="media_projection_dialog_text" msgid="3071431025448218928">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> nimmt alle auf Ihrem Bildschirm angezeigten Aktivitäten auf."</string>
+ <string name="media_projection_dialog_text" msgid="3071431025448218928">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> nimmt alle auf deinem Bildschirm angezeigten Aktivitäten auf."</string>
<string name="media_projection_remember_text" msgid="3103510882172746752">"Nicht erneut anzeigen"</string>
<string name="clear_all_notifications_text" msgid="814192889771462828">"Alle löschen"</string>
<string name="media_projection_action_text" msgid="8470872969457985954">"Jetzt starten"</string>
@@ -365,17 +365,17 @@
<string name="monitoring_title" msgid="169206259253048106">"Netzwerküberwachung"</string>
<string name="disable_vpn" msgid="4435534311510272506">"VPN deaktivieren"</string>
<string name="disconnect_vpn" msgid="1324915059568548655">"VPN-Verbindung trennen"</string>
- <string name="monitoring_description_device_owned" msgid="5780988291898461883">"Ihr Gerät wird verwaltet von <xliff:g id="ORGANIZATION">%1$s</xliff:g>.\n\nIhr Administrator kann die zu Ihrem Gerät gehörigen Einstellungen, Unternehmenszugriffsrechte, Apps und Daten überwachen und verwalten, einschließlich der Standortinformationen Ihres Geräts. Weitere Informationen erhalten Sie bei Ihrem Administrator."</string>
- <string name="monitoring_description_vpn" msgid="4445150119515393526">"Sie haben einer App gestattet, eine VPN-Verbindung einzurichten.\n\nDiese App kann Ihr Gerät und Ihre Netzwerkaktivitäten überwachen, einschließlich E-Mails, Apps und Websites."</string>
- <string name="monitoring_description_vpn_device_owned" msgid="3090670777499161246">"Ihr Gerät wird von <xliff:g id="ORGANIZATION">%1$s</xliff:g> verwaltet.\n\nIhr Administrator kann die zu Ihrem Gerät gehörigen Einstellungen, Unternehmenszugriffsrechte, Apps und Daten überwachen und verwalten, einschließlich der Standortinformationen Ihres Geräts.\n\nSie sind zudem mit einem VPN verbunden, das Ihre persönliche Netzwerkaktivität überwachen kann, einschließlich E-Mails, Apps und Websites.\n\nWeitere Informationen erhalten Sie bei Ihrem Administrator."</string>
- <string name="monitoring_description_vpn_profile_owned" msgid="2054949132145039290">"Ihr Arbeitsprofil wird von <xliff:g id="ORGANIZATION">%1$s</xliff:g> verwaltet.\n\nIhr Administrator kann Ihre Netzwerkaktivität überwachen, einschließlich E-Mails, Apps und Websites.\n\nWeitere Informationen erhalten Sie bei Ihrem Administrator.\n\nSie sind zudem mit einem VPN verbunden, das Ihre persönliche Netzwerkaktivität überwachen kann."</string>
+ <string name="monitoring_description_device_owned" msgid="5780988291898461883">"Dein Gerät wird verwaltet von <xliff:g id="ORGANIZATION">%1$s</xliff:g>.\n\nDein Administrator kann die zu deinem Gerät gehörigen Einstellungen, Unternehmenszugriffsrechte, Apps und Daten überwachen und verwalten, einschließlich der Standortinformationen deines Geräts. Weitere Informationen erhältst du bei deinem Administrator."</string>
+ <string name="monitoring_description_vpn" msgid="4445150119515393526">"Du hast einer App gestattet, eine VPN-Verbindung einzurichten.\n\nDiese App kann dein Gerät und deine Netzwerkaktivitäten überwachen, einschließlich E-Mails, Apps und Websites."</string>
+ <string name="monitoring_description_vpn_device_owned" msgid="3090670777499161246">"Dein Gerät wird von <xliff:g id="ORGANIZATION">%1$s</xliff:g> verwaltet.\n\nDein Administrator kann die zu deinem Gerät gehörigen Einstellungen, Unternehmenszugriffsrechte, Apps und Daten überwachen und verwalten, einschließlich der Standortinformationen deines Geräts.\n\nDu bist außerdem mit einem VPN verbunden, das deine persönliche Netzwerkaktivität überwachen kann, einschließlich E-Mails, Apps und Websites.\n\nWeitere Informationen erhältst du bei deinem Administrator."</string>
+ <string name="monitoring_description_vpn_profile_owned" msgid="2054949132145039290">"Dein Arbeitsprofil wird von <xliff:g id="ORGANIZATION">%1$s</xliff:g> verwaltet.\n\nDein Administrator kann deine Netzwerkaktivität überwachen, einschließlich E-Mails, Apps und Websites.\n\nWeitere Informationen erhältst du bei deinem Administrator.\n\nDu bist außerdem mit einem VPN verbunden, das deine persönliche Netzwerkaktivität überwachen kann."</string>
<string name="legacy_vpn_name" msgid="6604123105765737830">"VPN"</string>
- <string name="monitoring_description_app" msgid="6259179342284742878">"Sie sind mit der App <xliff:g id="APPLICATION">%1$s</xliff:g> verbunden, die Ihre Netzwerkaktivität überwachen kann, einschließlich E-Mails, Apps und Websites."</string>
- <string name="monitoring_description_app_personal" msgid="484599052118316268">"Sie sind mit der App <xliff:g id="APPLICATION">%1$s</xliff:g> verbunden, die Ihre persönliche Netzwerkaktivität überwachen kann, einschließlich E-Mails, Apps und Websites."</string>
- <string name="monitoring_description_app_work" msgid="1754325860918060897">"Ihr Arbeitsprofil wird von <xliff:g id="ORGANIZATION">%1$s</xliff:g> verwaltet. Das Profil ist mit der App <xliff:g id="APPLICATION">%2$s</xliff:g> verbunden, die Ihre geschäftlichen Netzwerkaktivitäten überwachen kann, einschließlich E-Mails, Apps und Websites.\n\nWeitere Informationen erhalten Sie von Ihrem Administrator."</string>
- <string name="monitoring_description_app_personal_work" msgid="4946600443852045903">"Ihr Arbeitsprofil wird von <xliff:g id="ORGANIZATION">%1$s</xliff:g> verwaltet. Das Profil ist mit der App <xliff:g id="APPLICATION_WORK">%2$s</xliff:g> verbunden, die Ihre geschäftliche Netzwerkaktivität überwachen kann, einschließlich E-Mails, Apps und Websites.\n\nSie sind außerdem mit der App <xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g> verbunden, die Ihre persönliche Netzwerkaktivität überwachen kann."</string>
- <string name="monitoring_description_vpn_app_device_owned" msgid="4970443827043261703">"Ihr Gerät wird von <xliff:g id="ORGANIZATION">%1$s</xliff:g> verwaltet.\n\nIhr Administrator kann die zu Ihrem Gerät gehörigen Einstellungen, Unternehmenszugriffsrechte, Apps und Daten überwachen und verwalten, einschließlich der Standortinformationen Ihres Geräts.\n\nSie sind mit der App <xliff:g id="APPLICATION">%2$s</xliff:g> verbunden, die Ihre persönlichen Netzwerkaktivität überwachen kann, einschließlich E-Mails, Apps und Websites.\n\nWeitere Informationen erhalten Sie bei Ihrem Administrator."</string>
- <string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"Das Gerät bleibt gesperrt, bis Sie es manuell entsperren."</string>
+ <string name="monitoring_description_app" msgid="6259179342284742878">"Du bist mit der App <xliff:g id="APPLICATION">%1$s</xliff:g> verbunden, die deine Netzwerkaktivität überwachen kann, einschließlich E-Mails, Apps und Websites."</string>
+ <string name="monitoring_description_app_personal" msgid="484599052118316268">"Du bist mit der App <xliff:g id="APPLICATION">%1$s</xliff:g> verbunden, die deine persönliche Netzwerkaktivität überwachen kann, einschließlich E-Mails, Apps und Websites."</string>
+ <string name="monitoring_description_app_work" msgid="1754325860918060897">"Dein Arbeitsprofil wird von <xliff:g id="ORGANIZATION">%1$s</xliff:g> verwaltet. Das Profil ist mit der App <xliff:g id="APPLICATION">%2$s</xliff:g> verbunden, die deine geschäftlichen Netzwerkaktivitäten überwachen kann, einschließlich E-Mails, Apps und Websites.\n\nWeitere Informationen erhältst du von deinem Administrator."</string>
+ <string name="monitoring_description_app_personal_work" msgid="4946600443852045903">"Dein Arbeitsprofil wird von <xliff:g id="ORGANIZATION">%1$s</xliff:g> verwaltet. Das Profil ist mit der App <xliff:g id="APPLICATION_WORK">%2$s</xliff:g> verbunden, die deine geschäftliche Netzwerkaktivität überwachen kann, einschließlich E-Mails, Apps und Websites.\n\nDu bist außerdem mit der App <xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g> verbunden, die deine persönliche Netzwerkaktivität überwachen kann."</string>
+ <string name="monitoring_description_vpn_app_device_owned" msgid="4970443827043261703">"Dein Gerät wird von <xliff:g id="ORGANIZATION">%1$s</xliff:g> verwaltet.\n\nDein Administrator kann die zu deinem Gerät gehörigen Einstellungen, Unternehmenszugriffsrechte, Apps und Daten überwachen und verwalten, einschließlich der Standortinformationen deines Geräts.\n\nDu bist außerdem mit der App <xliff:g id="APPLICATION">%2$s</xliff:g> verbunden, die deine persönliche Netzwerkaktivität überwachen kann, einschließlich E-Mails, Apps und Websites.\n\nWeitere Informationen erhältst du bei deinem Administrator."</string>
+ <string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"Das Gerät bleibt gesperrt, bis du es manuell entsperrst."</string>
<string name="hidden_notifications_title" msgid="7139628534207443290">"Benachrichtigungen schneller erhalten"</string>
<string name="hidden_notifications_text" msgid="2326409389088668981">"Vor dem Entsperren anzeigen"</string>
<string name="hidden_notifications_cancel" msgid="3690709735122344913">"Nein danke"</string>
@@ -387,19 +387,19 @@
<string name="accessibility_volume_expand" msgid="5946812790999244205">"Maximieren"</string>
<string name="accessibility_volume_collapse" msgid="3609549593031810875">"Minimieren"</string>
<string name="screen_pinning_title" msgid="3273740381976175811">"Bildschirm ist fixiert"</string>
- <string name="screen_pinning_description" msgid="1346522416878235405">"Der Bildschirm wird solange angezeigt, bis Sie die Fixierung aufheben. Berühren und halten Sie \"Zurück\" und \"Übersicht\" gleichzeitig, um die Fixierung aufzuheben."</string>
- <string name="screen_pinning_description_accessible" msgid="8518446209564202557">"Der Bildschirm wird solange angezeigt, bis Sie die Fixierung aufheben. Berühren und halten Sie \"Übersicht\", wenn Sie die Fixierung aufheben möchten."</string>
+ <string name="screen_pinning_description" msgid="1346522416878235405">"Der Bildschirm wird so lange angezeigt, bis du die Fixierung aufhebst. Berühre und halte \"Zurück\" und \"Übersicht\" gleichzeitig, um die Fixierung aufzuheben."</string>
+ <string name="screen_pinning_description_accessible" msgid="8518446209564202557">"Der Bildschirm wird so lange angezeigt, bis du die Fixierung aufhebst. Berühre und halte \"Übersicht\", wenn du die Fixierung aufheben möchtest."</string>
<string name="screen_pinning_positive" msgid="3783985798366751226">"OK"</string>
<string name="screen_pinning_negative" msgid="3741602308343880268">"Nein danke"</string>
<string name="quick_settings_reset_confirmation_title" msgid="748792586749897883">"<xliff:g id="TILE_LABEL">%1$s</xliff:g> ausblenden?"</string>
- <string name="quick_settings_reset_confirmation_message" msgid="2235970126803317374">"Sie wird wieder eingeblendet, wenn Sie sie in den Einstellungen erneut aktivieren."</string>
+ <string name="quick_settings_reset_confirmation_message" msgid="2235970126803317374">"Sie wird wieder eingeblendet, wenn du sie in den Einstellungen erneut aktivierst."</string>
<string name="quick_settings_reset_confirmation_button" msgid="2660339101868367515">"Ausblenden"</string>
<string name="volumeui_prompt_message" msgid="918680947433389110">"<xliff:g id="APP_NAME">%1$s</xliff:g> will die Lautstärke regeln."</string>
<string name="volumeui_prompt_allow" msgid="7954396902482228786">"Zulassen"</string>
<string name="volumeui_prompt_deny" msgid="5720663643411696731">"Ablehnen"</string>
<string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> regelt die Lautstärke."</string>
<string name="volumeui_notification_text" msgid="1826889705095768656">"Zum Wiederherstellen des Originals hier tippen"</string>
- <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Sie verwenden Ihr Arbeitsprofil."</string>
+ <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Du verwendest dein Arbeitsprofil."</string>
<string name="system_ui_tuner" msgid="708224127392452018">"System UI Tuner"</string>
<string name="show_battery_percentage" msgid="5444136600512968798">"Eingebettete Akku-Prozentzahl anzeigen"</string>
<string name="show_battery_percentage_summary" msgid="3215025775576786037">"Prozentzahl für Akkustand in Statusleistensymbol anzeigen, wenn das Gerät nicht geladen wird"</string>
@@ -414,7 +414,7 @@
<string name="status_bar_airplane" msgid="7057575501472249002">"Flugmodus"</string>
<string name="add_tile" msgid="2995389510240786221">"Kachel hinzufügen"</string>
<string name="broadcast_tile" msgid="3894036511763289383">"Broadcast-Kachel"</string>
- <string name="zen_alarm_warning_indef" msgid="3482966345578319605">"Sie erhalten einen lautlosen Weckruf <xliff:g id="WHEN">%1$s</xliff:g>, wenn Sie ihn nicht vorher ausschalten."</string>
+ <string name="zen_alarm_warning_indef" msgid="3482966345578319605">"Du erhältst einen lautlosen Weckruf <xliff:g id="WHEN">%1$s</xliff:g>, wenn du ihn nicht vorher ausschaltest."</string>
<string name="zen_alarm_warning" msgid="444533119582244293">"Lautloser Weckruf <xliff:g id="WHEN">%1$s</xliff:g>"</string>
<string name="alarm_template" msgid="3980063409350522735">"um <xliff:g id="WHEN">%1$s</xliff:g>"</string>
<string name="alarm_template_far" msgid="4242179982586714810">"am <xliff:g id="WHEN">%1$s</xliff:g>"</string>
@@ -422,10 +422,13 @@
<string name="accessibility_status_bar_hotspot" msgid="4099381329956402865">"Hotspot"</string>
<string name="accessibility_managed_profile" msgid="6613641363112584120">"Arbeitsprofil"</string>
<string name="tuner_warning_title" msgid="7094689930793031682">"Für einige ein Vergnügen, aber nicht für alle"</string>
- <string name="tuner_warning" msgid="8730648121973575701">"Mit System UI Tuner erhalten Sie zusätzliche Möglichkeiten, die Android-Benutzeroberfläche anzupassen. Achtung: Diese Testfunktionen können sich ändern, abstürzen oder in zukünftigen Versionen verschwinden."</string>
+ <string name="tuner_warning" msgid="8730648121973575701">"Mit System UI Tuner erhältst du zusätzliche Möglichkeiten, die Android-Benutzeroberfläche anzupassen. Achtung: Diese Testfunktionen können sich ändern, abstürzen oder in zukünftigen Versionen verschwinden."</string>
<string name="tuner_persistent_warning" msgid="8597333795565621795">"Achtung: Diese Testfunktionen können sich ändern, abstürzen oder in zukünftigen Versionen verschwinden."</string>
<string name="got_it" msgid="2239653834387972602">"OK"</string>
<string name="tuner_toast" msgid="603429811084428439">"Herzlichen Glückwunsch! System UI Tuner wurde \"Einstellungen\" hinzugefügt."</string>
<string name="remove_from_settings" msgid="8389591916603406378">"Aus \"Einstellungen\" entfernen"</string>
<string name="remove_from_settings_prompt" msgid="6069085993355887748">"System UI Tuner aus \"Einstellungen\" entfernen und die Verwendung von allen zugehörigen Funktionen beenden?"</string>
+ <string name="enable_bluetooth_title" msgid="5027037706500635269">"Bluetooth aktivieren?"</string>
+ <string name="enable_bluetooth_message" msgid="9106595990708985385">"Zum Verbinden von Tastatur und Tablet muss Bluetooth aktiviert sein."</string>
+ <string name="enable_bluetooth_confirmation_ok" msgid="6258074250948309715">"Aktivieren"</string>
</resources>
diff --git a/packages/SystemUI/res/values-el/strings.xml b/packages/SystemUI/res/values-el/strings.xml
index 5efe87b..51bcb81 100644
--- a/packages/SystemUI/res/values-el/strings.xml
+++ b/packages/SystemUI/res/values-el/strings.xml
@@ -150,9 +150,7 @@
<string name="accessibility_airplane_mode" msgid="834748999790763092">"Λειτουργία πτήσης."</string>
<string name="accessibility_no_sims" msgid="3957997018324995781">"Δεν υπάρχει κάρτα SIM."</string>
<string name="accessibility_carrier_network_change_mode" msgid="4017301580441304305">"Αλλαγή δικτύου εταιρείας κινητής τηλεφωνίας."</string>
- <!-- String.format failed for translation -->
- <!-- no translation found for accessibility_battery_level (7451474187113371965) -->
- <skip />
+ <string name="accessibility_battery_level" msgid="7451474187113371965">"Μπαταρία <xliff:g id="NUMBER">%d</xliff:g> τοις εκατό."</string>
<string name="accessibility_settings_button" msgid="799583911231893380">"Ρυθμίσεις συστήματος."</string>
<string name="accessibility_notifications_button" msgid="4498000369779421892">"Ειδοποιήσεις."</string>
<string name="accessibility_remove_notification" msgid="3603099514902182350">"Εκκαθάριση ειδοποίησης."</string>
@@ -327,6 +325,8 @@
<string name="interruption_level_priority_twoline" msgid="1564715335217164124">"Μόνο\nπροτεραιότητας"</string>
<string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"Μόνο\nειδοποιήσεις"</string>
<string name="keyguard_indication_charging_time" msgid="1757251776872835768">"Φόρτιση (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> για πλήρη φόρτιση)"</string>
+ <string name="keyguard_indication_charging_time_fast" msgid="9018981952053914986">"Γρήγορη φόρτιση (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> για πλήρη φόρτιση)"</string>
+ <string name="keyguard_indication_charging_time_slowly" msgid="955252797961724952">"Αργή φόρτιση (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> για πλήρη φόρτιση)"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="7305948938141024937">"Εναλλαγή χρήστη"</string>
<string name="accessibility_multi_user_switch_switcher_with_current" msgid="8434880595284601601">"Εναλλαγή χρήστη, τρέχων χρήστης <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_inactive" msgid="1424081831468083402">"Τρέχων χρήστης <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
@@ -428,4 +428,7 @@
<string name="tuner_toast" msgid="603429811084428439">"Συγχαρητήρια! Το System UI Tuner προστέθηκε στις Ρυθμίσεις"</string>
<string name="remove_from_settings" msgid="8389591916603406378">"Κατάργηση από τις Ρυθμίσεις"</string>
<string name="remove_from_settings_prompt" msgid="6069085993355887748">"Κατάργηση System UI Tuner από τις Ρυθμίσεις και διακοπή χρήσης όλων των λειτουργιών του;"</string>
+ <string name="enable_bluetooth_title" msgid="5027037706500635269">"Ενεργοποίηση Bluetooth;"</string>
+ <string name="enable_bluetooth_message" msgid="9106595990708985385">"Για να συνδέσετε το πληκτρολόγιο με το tablet σας, θα πρέπει πρώτα να ενεργοποιήσετε το Bluetooth."</string>
+ <string name="enable_bluetooth_confirmation_ok" msgid="6258074250948309715">"Ενεργοποίηση"</string>
</resources>
diff --git a/packages/SystemUI/res/values-en-rAU/strings.xml b/packages/SystemUI/res/values-en-rAU/strings.xml
index d630e44..5a9fc16 100644
--- a/packages/SystemUI/res/values-en-rAU/strings.xml
+++ b/packages/SystemUI/res/values-en-rAU/strings.xml
@@ -325,6 +325,8 @@
<string name="interruption_level_priority_twoline" msgid="1564715335217164124">"Priority\nonly"</string>
<string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"Alarms\nonly"</string>
<string name="keyguard_indication_charging_time" msgid="1757251776872835768">"Charging (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> until full)"</string>
+ <string name="keyguard_indication_charging_time_fast" msgid="9018981952053914986">"Charging rapidly (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> until full)"</string>
+ <string name="keyguard_indication_charging_time_slowly" msgid="955252797961724952">"Charging slowly (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> until full)"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="7305948938141024937">"Switch user"</string>
<string name="accessibility_multi_user_switch_switcher_with_current" msgid="8434880595284601601">"Switch user, current user <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_inactive" msgid="1424081831468083402">"Current user <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
@@ -426,4 +428,7 @@
<string name="tuner_toast" msgid="603429811084428439">"Congrats! System UI Tuner has been added to Settings"</string>
<string name="remove_from_settings" msgid="8389591916603406378">"Remove from settings"</string>
<string name="remove_from_settings_prompt" msgid="6069085993355887748">"Remove System UI Tuner from Settings and stop using all of its features?"</string>
+ <string name="enable_bluetooth_title" msgid="5027037706500635269">"Turn on Bluetooth?"</string>
+ <string name="enable_bluetooth_message" msgid="9106595990708985385">"To connect your keyboard with your tablet, you first have to turn on Bluetooth."</string>
+ <string name="enable_bluetooth_confirmation_ok" msgid="6258074250948309715">"Turn on"</string>
</resources>
diff --git a/packages/SystemUI/res/values-en-rGB/strings.xml b/packages/SystemUI/res/values-en-rGB/strings.xml
index d630e44..5a9fc16 100644
--- a/packages/SystemUI/res/values-en-rGB/strings.xml
+++ b/packages/SystemUI/res/values-en-rGB/strings.xml
@@ -325,6 +325,8 @@
<string name="interruption_level_priority_twoline" msgid="1564715335217164124">"Priority\nonly"</string>
<string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"Alarms\nonly"</string>
<string name="keyguard_indication_charging_time" msgid="1757251776872835768">"Charging (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> until full)"</string>
+ <string name="keyguard_indication_charging_time_fast" msgid="9018981952053914986">"Charging rapidly (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> until full)"</string>
+ <string name="keyguard_indication_charging_time_slowly" msgid="955252797961724952">"Charging slowly (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> until full)"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="7305948938141024937">"Switch user"</string>
<string name="accessibility_multi_user_switch_switcher_with_current" msgid="8434880595284601601">"Switch user, current user <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_inactive" msgid="1424081831468083402">"Current user <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
@@ -426,4 +428,7 @@
<string name="tuner_toast" msgid="603429811084428439">"Congrats! System UI Tuner has been added to Settings"</string>
<string name="remove_from_settings" msgid="8389591916603406378">"Remove from settings"</string>
<string name="remove_from_settings_prompt" msgid="6069085993355887748">"Remove System UI Tuner from Settings and stop using all of its features?"</string>
+ <string name="enable_bluetooth_title" msgid="5027037706500635269">"Turn on Bluetooth?"</string>
+ <string name="enable_bluetooth_message" msgid="9106595990708985385">"To connect your keyboard with your tablet, you first have to turn on Bluetooth."</string>
+ <string name="enable_bluetooth_confirmation_ok" msgid="6258074250948309715">"Turn on"</string>
</resources>
diff --git a/packages/SystemUI/res/values-en-rIN/strings.xml b/packages/SystemUI/res/values-en-rIN/strings.xml
index d630e44..5a9fc16 100644
--- a/packages/SystemUI/res/values-en-rIN/strings.xml
+++ b/packages/SystemUI/res/values-en-rIN/strings.xml
@@ -325,6 +325,8 @@
<string name="interruption_level_priority_twoline" msgid="1564715335217164124">"Priority\nonly"</string>
<string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"Alarms\nonly"</string>
<string name="keyguard_indication_charging_time" msgid="1757251776872835768">"Charging (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> until full)"</string>
+ <string name="keyguard_indication_charging_time_fast" msgid="9018981952053914986">"Charging rapidly (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> until full)"</string>
+ <string name="keyguard_indication_charging_time_slowly" msgid="955252797961724952">"Charging slowly (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> until full)"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="7305948938141024937">"Switch user"</string>
<string name="accessibility_multi_user_switch_switcher_with_current" msgid="8434880595284601601">"Switch user, current user <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_inactive" msgid="1424081831468083402">"Current user <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
@@ -426,4 +428,7 @@
<string name="tuner_toast" msgid="603429811084428439">"Congrats! System UI Tuner has been added to Settings"</string>
<string name="remove_from_settings" msgid="8389591916603406378">"Remove from settings"</string>
<string name="remove_from_settings_prompt" msgid="6069085993355887748">"Remove System UI Tuner from Settings and stop using all of its features?"</string>
+ <string name="enable_bluetooth_title" msgid="5027037706500635269">"Turn on Bluetooth?"</string>
+ <string name="enable_bluetooth_message" msgid="9106595990708985385">"To connect your keyboard with your tablet, you first have to turn on Bluetooth."</string>
+ <string name="enable_bluetooth_confirmation_ok" msgid="6258074250948309715">"Turn on"</string>
</resources>
diff --git a/packages/SystemUI/res/values-es-rUS/strings.xml b/packages/SystemUI/res/values-es-rUS/strings.xml
index 4a56237..b58d4db 100644
--- a/packages/SystemUI/res/values-es-rUS/strings.xml
+++ b/packages/SystemUI/res/values-es-rUS/strings.xml
@@ -150,9 +150,7 @@
<string name="accessibility_airplane_mode" msgid="834748999790763092">"Modo avión"</string>
<string name="accessibility_no_sims" msgid="3957997018324995781">"Sin tarjeta SIM"</string>
<string name="accessibility_carrier_network_change_mode" msgid="4017301580441304305">"Cambio de proveedor de red"</string>
- <!-- String.format failed for translation -->
- <!-- no translation found for accessibility_battery_level (7451474187113371965) -->
- <skip />
+ <string name="accessibility_battery_level" msgid="7451474187113371965">"Batería <xliff:g id="NUMBER">%d</xliff:g> por ciento"</string>
<string name="accessibility_settings_button" msgid="799583911231893380">"Configuración del sistema"</string>
<string name="accessibility_notifications_button" msgid="4498000369779421892">"Notificaciones"</string>
<string name="accessibility_remove_notification" msgid="3603099514902182350">"Eliminar notificación"</string>
@@ -327,6 +325,8 @@
<string name="interruption_level_priority_twoline" msgid="1564715335217164124">"Solo\nprioridad"</string>
<string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"Solo\nalarmas"</string>
<string name="keyguard_indication_charging_time" msgid="1757251776872835768">"Cargando (faltan <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> para completar)"</string>
+ <string name="keyguard_indication_charging_time_fast" msgid="9018981952053914986">"Carga rápida (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> para completar la carga)"</string>
+ <string name="keyguard_indication_charging_time_slowly" msgid="955252797961724952">"Carga lenta (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> para completar la carga)"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="7305948938141024937">"Cambiar usuario"</string>
<string name="accessibility_multi_user_switch_switcher_with_current" msgid="8434880595284601601">"Cambiar de usuario (usuario actual: <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>)"</string>
<string name="accessibility_multi_user_switch_inactive" msgid="1424081831468083402">"El usuario actual es <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
@@ -428,4 +428,7 @@
<string name="tuner_toast" msgid="603429811084428439">"Se agregó el sintonizador de IU del sistema a Configuración"</string>
<string name="remove_from_settings" msgid="8389591916603406378">"Quitar de Configuración"</string>
<string name="remove_from_settings_prompt" msgid="6069085993355887748">"¿Quieres quitar el sintonizador de IU del sistema de Configuración y dejar de utilizar todas sus funciones?"</string>
+ <string name="enable_bluetooth_title" msgid="5027037706500635269">"¿Activar Bluetooth?"</string>
+ <string name="enable_bluetooth_message" msgid="9106595990708985385">"Para conectar el teclado con la tablet, primero debes activar Bluetooth."</string>
+ <string name="enable_bluetooth_confirmation_ok" msgid="6258074250948309715">"Activar"</string>
</resources>
diff --git a/packages/SystemUI/res/values-es/strings.xml b/packages/SystemUI/res/values-es/strings.xml
index 7a80715..c8323ad 100644
--- a/packages/SystemUI/res/values-es/strings.xml
+++ b/packages/SystemUI/res/values-es/strings.xml
@@ -325,6 +325,8 @@
<string name="interruption_level_priority_twoline" msgid="1564715335217164124">"Solo\ncon prioridad"</string>
<string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"Solo\nalarmas"</string>
<string name="keyguard_indication_charging_time" msgid="1757251776872835768">"Cargando (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> para completar)"</string>
+ <string name="keyguard_indication_charging_time_fast" msgid="9018981952053914986">"Cargando rápidamente (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> hasta completar)"</string>
+ <string name="keyguard_indication_charging_time_slowly" msgid="955252797961724952">"Cargando lentamente (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> hasta completar)"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="7305948938141024937">"Cambiar de usuario"</string>
<string name="accessibility_multi_user_switch_switcher_with_current" msgid="8434880595284601601">"Cambiar de usuario (usuario actual <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>)"</string>
<string name="accessibility_multi_user_switch_inactive" msgid="1424081831468083402">"Usuario actual: <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
@@ -426,4 +428,7 @@
<string name="tuner_toast" msgid="603429811084428439">"¡Enhorabuena! El configurador de IU del sistema se ha añadido a Ajustes"</string>
<string name="remove_from_settings" msgid="8389591916603406378">"Eliminar de Ajustes"</string>
<string name="remove_from_settings_prompt" msgid="6069085993355887748">"¿Eliminar el configurador de IU del sistema de Ajustes y dejar de utilizar sus funciones?"</string>
+ <string name="enable_bluetooth_title" msgid="5027037706500635269">"¿Activar Bluetooth?"</string>
+ <string name="enable_bluetooth_message" msgid="9106595990708985385">"Para poder conectar tu teclado a tu tablet, debes activar el Bluetooth."</string>
+ <string name="enable_bluetooth_confirmation_ok" msgid="6258074250948309715">"Activar"</string>
</resources>
diff --git a/packages/SystemUI/res/values-et-rEE/strings.xml b/packages/SystemUI/res/values-et-rEE/strings.xml
index aec4906..9877b8f 100644
--- a/packages/SystemUI/res/values-et-rEE/strings.xml
+++ b/packages/SystemUI/res/values-et-rEE/strings.xml
@@ -325,6 +325,8 @@
<string name="interruption_level_priority_twoline" msgid="1564715335217164124">"Ainult\nprioriteetsed"</string>
<string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"Ainult\nalarmid"</string>
<string name="keyguard_indication_charging_time" msgid="1757251776872835768">"Laadimine (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>, kuni seade on täis)"</string>
+ <string name="keyguard_indication_charging_time_fast" msgid="9018981952053914986">"Kiirlaadimine (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>, kuni seade on täis)"</string>
+ <string name="keyguard_indication_charging_time_slowly" msgid="955252797961724952">"Aeglane laadimine (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>, kuni seade on täis)"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="7305948938141024937">"Kasutaja vahetamine"</string>
<string name="accessibility_multi_user_switch_switcher_with_current" msgid="8434880595284601601">"Kasutaja vahetamine, praegune kasutaja: <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_inactive" msgid="1424081831468083402">"Praegune kasutaja <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
@@ -426,4 +428,7 @@
<string name="tuner_toast" msgid="603429811084428439">"Õnnitleme! Süsteemi kasutajaliidese tuuner lisati seadetesse"</string>
<string name="remove_from_settings" msgid="8389591916603406378">"Eemalda seadetest"</string>
<string name="remove_from_settings_prompt" msgid="6069085993355887748">"Kas eemaldada seadetest süsteemi kasutajaliidese tuuner ja lõpetada kõikide selle funktsioonide kasutamine?"</string>
+ <string name="enable_bluetooth_title" msgid="5027037706500635269">"Kas lülitada Bluetooth sisse?"</string>
+ <string name="enable_bluetooth_message" msgid="9106595990708985385">"Klaviatuuri ühendamiseks tahvelarvutiga peate esmalt Bluetoothi sisse lülitama."</string>
+ <string name="enable_bluetooth_confirmation_ok" msgid="6258074250948309715">"Lülita sisse"</string>
</resources>
diff --git a/packages/SystemUI/res/values-eu-rES/strings.xml b/packages/SystemUI/res/values-eu-rES/strings.xml
index c1967a3..adeda31 100644
--- a/packages/SystemUI/res/values-eu-rES/strings.xml
+++ b/packages/SystemUI/res/values-eu-rES/strings.xml
@@ -325,6 +325,8 @@
<string name="interruption_level_priority_twoline" msgid="1564715335217164124">"Lehentasunezkoak\nsoilik"</string>
<string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"Alarmak\nsoilik"</string>
<string name="keyguard_indication_charging_time" msgid="1757251776872835768">"Kargatzen (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> guztiz kargatu arte)"</string>
+ <string name="keyguard_indication_charging_time_fast" msgid="9018981952053914986">"Bizkor kargatzen (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> guztiz kargatu arte)"</string>
+ <string name="keyguard_indication_charging_time_slowly" msgid="955252797961724952">"Mantso kargatzen (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> guztiz kargatu arte)"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="7305948938141024937">"Aldatu erabiltzailea"</string>
<string name="accessibility_multi_user_switch_switcher_with_current" msgid="8434880595284601601">"Aldatu erabiltzailez. <xliff:g id="CURRENT_USER_NAME">%s</xliff:g> da saioa hasita duena."</string>
<string name="accessibility_multi_user_switch_inactive" msgid="1424081831468083402">"Uneko erabiltzailea: <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
@@ -426,4 +428,7 @@
<string name="tuner_toast" msgid="603429811084428439">"Zorionak! Sistemako erabiltzaile-interfazearen konfiguratzailea Ezarpenak atalean gehitu da"</string>
<string name="remove_from_settings" msgid="8389591916603406378">"Kendu Ezarpenak ataletik"</string>
<string name="remove_from_settings_prompt" msgid="6069085993355887748">"Sistemako erabiltzaile-interfazearen konfiguratzailea ezarpenetatik kendu nahi duzu, eta haren eginbide guztiak erabiltzeari utzi nahi diozu?"</string>
+ <string name="enable_bluetooth_title" msgid="5027037706500635269">"Bluetooth eginbidea aktibatu nahi duzu?"</string>
+ <string name="enable_bluetooth_message" msgid="9106595990708985385">"Teklatua tabletara konektatzeko, Bluetooth eginbidea aktibatu behar duzu."</string>
+ <string name="enable_bluetooth_confirmation_ok" msgid="6258074250948309715">"Aktibatu"</string>
</resources>
diff --git a/packages/SystemUI/res/values-fa/strings.xml b/packages/SystemUI/res/values-fa/strings.xml
index b5bd423..e308aab 100644
--- a/packages/SystemUI/res/values-fa/strings.xml
+++ b/packages/SystemUI/res/values-fa/strings.xml
@@ -34,14 +34,14 @@
<string name="status_bar_latest_events_title" msgid="6594767438577593172">"اعلانها"</string>
<string name="battery_low_title" msgid="6456385927409742437">"شارژ باتری کم است"</string>
<string name="battery_low_percent_format" msgid="2900940511201380775">"<xliff:g id="PERCENTAGE">%s</xliff:g> باقی مانده است"</string>
- <string name="battery_low_percent_format_saver_started" msgid="6859235584035338833">"<xliff:g id="PERCENTAGE">%s</xliff:g> باقی مانده است. ذخیره کننده باتری روشن است."</string>
+ <string name="battery_low_percent_format_saver_started" msgid="6859235584035338833">"<xliff:g id="PERCENTAGE">%s</xliff:g> باقی مانده است. بهینهسازی باتری روشن است."</string>
<string name="invalid_charger" msgid="4549105996740522523">"شارژ USB پشتیبانی نمیشود.\nفقط از شارژر ارائه شده استفاده کنید."</string>
<string name="invalid_charger_title" msgid="3515740382572798460">"شارژ با USB پشتیبانی نمیشود."</string>
<string name="invalid_charger_text" msgid="5474997287953892710">"فقط از شارژر ارائه شده استفاده کنید."</string>
<string name="battery_low_why" msgid="4553600287639198111">"تنظیمات"</string>
- <string name="battery_saver_confirmation_title" msgid="5299585433050361634">"ذخیرهکننده باتری روشن شود؟"</string>
+ <string name="battery_saver_confirmation_title" msgid="5299585433050361634">"بهینهسازی باتری روشن شود؟"</string>
<string name="battery_saver_confirmation_ok" msgid="7507968430447930257">"روشن کردن"</string>
- <string name="battery_saver_start_action" msgid="5576697451677486320">"ذخیرهکننده باتری را روشن کنید"</string>
+ <string name="battery_saver_start_action" msgid="5576697451677486320">"بهینهسازی باتری را روشن کنید"</string>
<string name="status_bar_settings_settings_button" msgid="3023889916699270224">"تنظیمات"</string>
<string name="status_bar_settings_wifi_button" msgid="1733928151698311923">"Wi-Fi"</string>
<string name="status_bar_settings_auto_rotation" msgid="3790482541357798421">"چرخش خودکار صفحه"</string>
@@ -65,14 +65,14 @@
<string name="usb_debugging_always" msgid="303335496705863070">"همیشه از این رایانه انجام شود"</string>
<string name="usb_debugging_secondary_user_title" msgid="6353808721761220421">"اشکالزدایی USB مجاز نیست"</string>
<string name="usb_debugging_secondary_user_message" msgid="6011931347142270156">"کاربری که درحال حاضر در این دستگاه وارد سیستم شده نمیتواند اشکالزدایی USB را روشن کند. برای استفاده از این ویژگی، به کاربر اصلی «<xliff:g id="NAME">%s</xliff:g>» تغییر حالت دهید."</string>
- <string name="compat_mode_on" msgid="6623839244840638213">"بزرگنمایی برای پر کردن صفحه"</string>
+ <string name="compat_mode_on" msgid="6623839244840638213">"بزرگنمایی برای پر کردن صفحه"</string>
<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_saved_title" msgid="6461865960961414961">"تصویر صفحه گرفته شد."</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_saved_title" msgid="6461865960961414961">"عکس صفحهنمایش گرفته شد."</string>
<string name="screenshot_saved_text" msgid="1152839647677558815">"برای مشاهده عکس صفحهنمایشتان، لمس کنید."</string>
- <string name="screenshot_failed_title" msgid="705781116746922771">"تصویر صفحه گرفته نشد."</string>
+ <string name="screenshot_failed_title" msgid="705781116746922771">"عکس صفحهنمایش گرفته نشد."</string>
<string name="screenshot_failed_text" msgid="1260203058661337274">"به دلیل فضای ذخیرهسازی کم یا عدم اجازه برنامه یا سازمانتان، نمیتوان از صفحه عکس گرفت."</string>
<string name="usb_preference_title" msgid="6551050377388882787">"گزینههای انتقال فایل USB"</string>
<string name="use_mtp_button_title" msgid="4333504413563023626">"نصب بهعنوان دستگاه پخش رسانه (MTP)"</string>
@@ -95,8 +95,8 @@
<string name="camera_label" msgid="7261107956054836961">"باز کردن دوربین"</string>
<string name="recents_caption_resize" msgid="3517056471774958200">"انتخاب طرحبندی جدید کار"</string>
<string name="cancel" msgid="6442560571259935130">"لغو"</string>
- <string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"دکمه بزرگنمایی سازگار."</string>
- <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"بزرگنمایی از صفحههای کوچک تا بزرگ."</string>
+ <string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"دکمه بزرگنمایی سازگار."</string>
+ <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"بزرگنمایی از صفحههای کوچک تا بزرگ."</string>
<string name="accessibility_bluetooth_connected" msgid="2707027633242983370">"بلوتوث متصل است."</string>
<string name="accessibility_bluetooth_disconnected" msgid="7416648669976870175">"بلوتوث قطع شده است."</string>
<string name="accessibility_no_battery" msgid="358343022352820946">"باتری موجود نیست."</string>
@@ -219,7 +219,7 @@
<string name="data_usage_disabled_dialog_title" msgid="3932437232199671967">"داده موقتاً متوقف شده است"</string>
<string name="data_usage_disabled_dialog" msgid="8453242888903772524">"چون به محدودیت داده تنظیم شده رسیدهاید، دستگاه مصرف داده را برای باقیمانده این دوره موقتاً متوقف کرده است.\n\nاگر ادامه دهید شاید موجب کسر هزینه از طرف شرکت مخابراتی شما شود."</string>
<string name="data_usage_disabled_dialog_enable" msgid="1412395410306390593">"از سرگیری"</string>
- <string name="status_bar_settings_signal_meter_disconnected" msgid="1940231521274147771">"اتصال اینترنتی وجود ندارد"</string>
+ <string name="status_bar_settings_signal_meter_disconnected" msgid="1940231521274147771">"اتصال اینترنتی ندارید"</string>
<string name="status_bar_settings_signal_meter_wifi_nossid" msgid="6557486452774597820">"Wi-Fi متصل شد"</string>
<string name="gps_notification_searching_text" msgid="8574247005642736060">"جستجو برای GPS"</string>
<string name="gps_notification_found_text" msgid="4619274244146446464">"مکان تنظیم شده توسط GPS"</string>
@@ -275,7 +275,7 @@
<string name="quick_settings_inversion_label" msgid="8790919884718619648">"برگردان رنگها"</string>
<string name="quick_settings_color_space_label" msgid="853443689745584770">"حالت تصحیح رنگ"</string>
<string name="quick_settings_more_settings" msgid="326112621462813682">"تنظیمات بیشتر"</string>
- <string name="quick_settings_done" msgid="3402999958839153376">"انجام شد"</string>
+ <string name="quick_settings_done" msgid="3402999958839153376">"تمام"</string>
<string name="quick_settings_connected" msgid="1722253542984847487">"متصل"</string>
<string name="quick_settings_connecting" msgid="47623027419264404">"در حال اتصال..."</string>
<string name="quick_settings_tethering_label" msgid="7153452060448575549">"اتصال به اینترنت با تلفن همراه"</string>
@@ -325,6 +325,8 @@
<string name="interruption_level_priority_twoline" msgid="1564715335217164124">"فقط\nاولویتدار"</string>
<string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"فقط\nهشدارها"</string>
<string name="keyguard_indication_charging_time" msgid="1757251776872835768">"در حال شارژ (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> تا شارژ کامل)"</string>
+ <string name="keyguard_indication_charging_time_fast" msgid="9018981952053914986">"در حال شارژ سریع (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> تا شارژ کامل)"</string>
+ <string name="keyguard_indication_charging_time_slowly" msgid="955252797961724952">"در حال شارژ آهسته (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> تا شارژ کامل)"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="7305948938141024937">"تغییر کاربر"</string>
<string name="accessibility_multi_user_switch_switcher_with_current" msgid="8434880595284601601">"تعویض کاربر، کاربر کنونی <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_inactive" msgid="1424081831468083402">"کاربر کنونی <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
@@ -346,9 +348,9 @@
<string name="guest_notification_remove_action" msgid="8820670703892101990">"حذف مهمان"</string>
<string name="user_add_user_title" msgid="4553596395824132638">"کاربر جدیدی اضافه میکنید؟"</string>
<string name="user_add_user_message_short" msgid="2161624834066214559">"وقتی کاربر جدیدی را اضافه میکنید آن فرد باید فضای خودش را تنظیم کند.\n\nهر کاربری میتواند برنامهها را برای همه کاربران دیگر بهروزرسانی کند."</string>
- <string name="battery_saver_notification_title" msgid="237918726750955859">"ذخیره کننده باتری روشن است."</string>
+ <string name="battery_saver_notification_title" msgid="237918726750955859">"بهینهسازی باتری روشن است."</string>
<string name="battery_saver_notification_text" msgid="820318788126672692">"عملکرد و اطلاعات پسزمینه را کاهش میدهد"</string>
- <string name="battery_saver_notification_action_text" msgid="109158658238110382">"خاموش کردن ذخیرهکننده باتری"</string>
+ <string name="battery_saver_notification_action_text" msgid="109158658238110382">"بهینهسازی باتری را خاموش کنید"</string>
<string name="notification_hidden_text" msgid="1135169301897151909">"محتواها پنهان هستند"</string>
<string name="media_projection_dialog_text" msgid="3071431025448218928">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> شروع به ضبط هر چیزی میکند که در صفحهنمایش شما نمایش داده میشود."</string>
<string name="media_projection_remember_text" msgid="3103510882172746752">"دوباره نشان داده نشود"</string>
@@ -376,7 +378,7 @@
<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_cancel" msgid="3690709735122344913">"خیر، سپاسگزارم"</string>
+ <string name="hidden_notifications_cancel" msgid="3690709735122344913">"نه سپاسگزارم"</string>
<string name="hidden_notifications_setup" msgid="41079514801976810">"راهاندازی"</string>
<string name="notification_expand_button_text" msgid="1037425494153780718">"مشاهده همه"</string>
<string name="notification_collapse_button_text" msgid="6883253262134328057">"پنهان کردن همه"</string>
@@ -388,7 +390,7 @@
<string name="screen_pinning_description" msgid="1346522416878235405">"تا زمانی که پین را بردارید، در نما نگهداشته میشود. برای برداشتن پین، برگشت و نمای کلی را به صورت همزمان لمس کنید و نگهدارید."</string>
<string name="screen_pinning_description_accessible" msgid="8518446209564202557">"تا زمانی که پین را بردارید، در نما نگهداشته میشود. برای برداشتن پین، نمای کلی را لمس کنید و نگهدارید."</string>
<string name="screen_pinning_positive" msgid="3783985798366751226">"متوجه شدم"</string>
- <string name="screen_pinning_negative" msgid="3741602308343880268">"خیر متشکرم"</string>
+ <string name="screen_pinning_negative" msgid="3741602308343880268">"نه سپاسگزارم"</string>
<string name="quick_settings_reset_confirmation_title" msgid="748792586749897883">"<xliff:g id="TILE_LABEL">%1$s</xliff:g> مخفی شود؟"</string>
<string name="quick_settings_reset_confirmation_message" msgid="2235970126803317374">"دفعه بعد که آن را روشن کنید، در تنظیمات نشان داده میشود."</string>
<string name="quick_settings_reset_confirmation_button" msgid="2660339101868367515">"پنهان کردن"</string>
@@ -426,4 +428,7 @@
<string name="tuner_toast" msgid="603429811084428439">"تبریک میگوییم! «تنظیمکننده واسط کاربری سیستم» به «تنظیمات» اضافه شد"</string>
<string name="remove_from_settings" msgid="8389591916603406378">"حذف از تنظیمات"</string>
<string name="remove_from_settings_prompt" msgid="6069085993355887748">"«تنظیمکننده واسط کاربری سیستم» از تنظیمات حذف شود و همه ویژگیهای آن متوقف شوند؟"</string>
+ <string name="enable_bluetooth_title" msgid="5027037706500635269">"بلوتوث روشن شود؟"</string>
+ <string name="enable_bluetooth_message" msgid="9106595990708985385">"برای مرتبط کردن صفحهکلید با رایانه لوحی، ابتدا باید بلوتوث را روشن کنید."</string>
+ <string name="enable_bluetooth_confirmation_ok" msgid="6258074250948309715">"روشن کردن"</string>
</resources>
diff --git a/packages/SystemUI/res/values-fi/strings.xml b/packages/SystemUI/res/values-fi/strings.xml
index 5a540bc..2dbd5be 100644
--- a/packages/SystemUI/res/values-fi/strings.xml
+++ b/packages/SystemUI/res/values-fi/strings.xml
@@ -325,6 +325,8 @@
<string name="interruption_level_priority_twoline" msgid="1564715335217164124">"Vain\ntärkeät"</string>
<string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"Vain\nherätykset"</string>
<string name="keyguard_indication_charging_time" msgid="1757251776872835768">"Ladataan (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> kunnes täynnä)"</string>
+ <string name="keyguard_indication_charging_time_fast" msgid="9018981952053914986">"Nopea lataus (latausaikaa jäljellä <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>)"</string>
+ <string name="keyguard_indication_charging_time_slowly" msgid="955252797961724952">"Hidas lataus (latausaikaa jäljellä <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>)"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="7305948938141024937">"Vaihda käyttäjää"</string>
<string name="accessibility_multi_user_switch_switcher_with_current" msgid="8434880595284601601">"Vaihda käyttäjä (nyt <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>)"</string>
<string name="accessibility_multi_user_switch_inactive" msgid="1424081831468083402">"Nykyinen käyttäjä: <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
@@ -426,4 +428,7 @@
<string name="tuner_toast" msgid="603429811084428439">"Hienoa! System UI Tuner on nyt lisätty Asetuksiin."</string>
<string name="remove_from_settings" msgid="8389591916603406378">"Poista Asetuksista"</string>
<string name="remove_from_settings_prompt" msgid="6069085993355887748">"Haluatko poistaa System UI Tunerin Asetuksista ja lopettaa sen ominaisuuksien käytön?"</string>
+ <string name="enable_bluetooth_title" msgid="5027037706500635269">"Otetaanko Bluetooth käyttöön?"</string>
+ <string name="enable_bluetooth_message" msgid="9106595990708985385">"Jotta voit yhdistää näppäimistön tablettiisi, sinun on ensin otettava Bluetooth käyttöön."</string>
+ <string name="enable_bluetooth_confirmation_ok" msgid="6258074250948309715">"Ota käyttöön"</string>
</resources>
diff --git a/packages/SystemUI/res/values-fr-rCA/strings.xml b/packages/SystemUI/res/values-fr-rCA/strings.xml
index 5a46b10..d132e00 100644
--- a/packages/SystemUI/res/values-fr-rCA/strings.xml
+++ b/packages/SystemUI/res/values-fr-rCA/strings.xml
@@ -150,9 +150,7 @@
<string name="accessibility_airplane_mode" msgid="834748999790763092">"Mode Avion"</string>
<string name="accessibility_no_sims" msgid="3957997018324995781">"Aucune carte SIM."</string>
<string name="accessibility_carrier_network_change_mode" msgid="4017301580441304305">"Modification du réseau du fournisseur de services"</string>
- <!-- String.format failed for translation -->
- <!-- no translation found for accessibility_battery_level (7451474187113371965) -->
- <skip />
+ <string name="accessibility_battery_level" msgid="7451474187113371965">"Pile : <xliff:g id="NUMBER">%d</xliff:g> pour cent"</string>
<string name="accessibility_settings_button" msgid="799583911231893380">"Paramètres système"</string>
<string name="accessibility_notifications_button" msgid="4498000369779421892">"Notifications"</string>
<string name="accessibility_remove_notification" msgid="3603099514902182350">"Supprimer la notification"</string>
@@ -327,6 +325,8 @@
<string name="interruption_level_priority_twoline" msgid="1564715335217164124">"Priorités\nuniquement"</string>
<string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"Alarmes\nuniquement"</string>
<string name="keyguard_indication_charging_time" msgid="1757251776872835768">"Charge en cours... (chargée à 100 %% dans <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>)"</string>
+ <string name="keyguard_indication_charging_time_fast" msgid="9018981952053914986">"Charge rapide en cours... (chargé dans <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>)"</string>
+ <string name="keyguard_indication_charging_time_slowly" msgid="955252797961724952">"Charge lente en cours... (chargé dans <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>)"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="7305948938141024937">"Changer d\'utilisateur"</string>
<string name="accessibility_multi_user_switch_switcher_with_current" msgid="8434880595284601601">"Changer d\'utilisateur (utilisateur actuel <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>)"</string>
<string name="accessibility_multi_user_switch_inactive" msgid="1424081831468083402">"Utilisateur actuel : <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
@@ -428,4 +428,7 @@
<string name="tuner_toast" msgid="603429811084428439">"Félicitations! System UI Tuner a bien été ajouté aux paramètres."</string>
<string name="remove_from_settings" msgid="8389591916603406378">"Supprimer des paramètres"</string>
<string name="remove_from_settings_prompt" msgid="6069085993355887748">"Supprimer « System UI Tuner » des paramètres et arrêter d\'utiliser toutes ses fonctionnalités?"</string>
+ <string name="enable_bluetooth_title" msgid="5027037706500635269">"Activer Bluetooth?"</string>
+ <string name="enable_bluetooth_message" msgid="9106595990708985385">"Pour connecter votre clavier à votre tablette, vous devez d\'abord activer la connectivité Bluetooth."</string>
+ <string name="enable_bluetooth_confirmation_ok" msgid="6258074250948309715">"Activer"</string>
</resources>
diff --git a/packages/SystemUI/res/values-fr/strings.xml b/packages/SystemUI/res/values-fr/strings.xml
index 6b81bde..eccc910 100644
--- a/packages/SystemUI/res/values-fr/strings.xml
+++ b/packages/SystemUI/res/values-fr/strings.xml
@@ -150,9 +150,7 @@
<string name="accessibility_airplane_mode" msgid="834748999790763092">"Mode Avion"</string>
<string name="accessibility_no_sims" msgid="3957997018324995781">"Aucune carte SIM"</string>
<string name="accessibility_carrier_network_change_mode" msgid="4017301580441304305">"Modification du réseau de l\'opérateur"</string>
- <!-- String.format failed for translation -->
- <!-- no translation found for accessibility_battery_level (7451474187113371965) -->
- <skip />
+ <string name="accessibility_battery_level" msgid="7451474187113371965">"Batterie : <xliff:g id="NUMBER">%d</xliff:g> pour cent"</string>
<string name="accessibility_settings_button" msgid="799583911231893380">"Paramètres système"</string>
<string name="accessibility_notifications_button" msgid="4498000369779421892">"Notifications"</string>
<string name="accessibility_remove_notification" msgid="3603099514902182350">"Supprimer la notification"</string>
@@ -327,6 +325,8 @@
<string name="interruption_level_priority_twoline" msgid="1564715335217164124">"Priorité\nuniquement"</string>
<string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"Alarmes\nuniquement"</string>
<string name="keyguard_indication_charging_time" msgid="1757251776872835768">"Charge en cours… (chargé à 100 %% dans <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>)"</string>
+ <string name="keyguard_indication_charging_time_fast" msgid="9018981952053914986">"Charge rapide… (chargé à 100 %% dans <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>)"</string>
+ <string name="keyguard_indication_charging_time_slowly" msgid="955252797961724952">"Charge lente… (chargé à 100 %% dans <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>)"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="7305948938141024937">"Changer d\'utilisateur"</string>
<string name="accessibility_multi_user_switch_switcher_with_current" msgid="8434880595284601601">"Changer d\'utilisateur (utilisateur actuel : <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>)"</string>
<string name="accessibility_multi_user_switch_inactive" msgid="1424081831468083402">"Utilisateur actuel : <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
@@ -428,4 +428,7 @@
<string name="tuner_toast" msgid="603429811084428439">"Félicitations ! System UI Tuner a bien été ajouté aux paramètres."</string>
<string name="remove_from_settings" msgid="8389591916603406378">"Supprimer l\'outil des paramètres"</string>
<string name="remove_from_settings_prompt" msgid="6069085993355887748">"Supprimer System UI Tuner des paramètres et arrêter d\'utiliser toutes ses fonctionnalités ?"</string>
+ <string name="enable_bluetooth_title" msgid="5027037706500635269">"Activer le Bluetooth ?"</string>
+ <string name="enable_bluetooth_message" msgid="9106595990708985385">"Pour connecter un clavier à votre tablette, vous devez avoir activé le Bluetooth."</string>
+ <string name="enable_bluetooth_confirmation_ok" msgid="6258074250948309715">"Activer"</string>
</resources>
diff --git a/packages/SystemUI/res/values-gl-rES/strings.xml b/packages/SystemUI/res/values-gl-rES/strings.xml
index a67f5a7..140f4a7 100644
--- a/packages/SystemUI/res/values-gl-rES/strings.xml
+++ b/packages/SystemUI/res/values-gl-rES/strings.xml
@@ -150,9 +150,7 @@
<string name="accessibility_airplane_mode" msgid="834748999790763092">"Modo avión"</string>
<string name="accessibility_no_sims" msgid="3957997018324995781">"Non hai tarxeta SIM"</string>
<string name="accessibility_carrier_network_change_mode" msgid="4017301580441304305">"Cambio de rede do operador."</string>
- <!-- String.format failed for translation -->
- <!-- no translation found for accessibility_battery_level (7451474187113371965) -->
- <skip />
+ <string name="accessibility_battery_level" msgid="7451474187113371965">"Carga da batería: <xliff:g id="NUMBER">%d</xliff:g> por cento."</string>
<string name="accessibility_settings_button" msgid="799583911231893380">"Configuración do sistema"</string>
<string name="accessibility_notifications_button" msgid="4498000369779421892">"Notificacións"</string>
<string name="accessibility_remove_notification" msgid="3603099514902182350">"Eliminar notificación."</string>
@@ -327,6 +325,8 @@
<string name="interruption_level_priority_twoline" msgid="1564715335217164124">"Só\nprioridade"</string>
<string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"Só\nalarmas"</string>
<string name="keyguard_indication_charging_time" msgid="1757251776872835768">"Cargando (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> para finalizar a carga)"</string>
+ <string name="keyguard_indication_charging_time_fast" msgid="9018981952053914986">"Cargando rápido (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> para rematar a carga)"</string>
+ <string name="keyguard_indication_charging_time_slowly" msgid="955252797961724952">"Cargando lento (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> para rematar a carga)"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="7305948938141024937">"Cambiar usuario"</string>
<string name="accessibility_multi_user_switch_switcher_with_current" msgid="8434880595284601601">"Cambiar usuario, usuario actual: <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_inactive" msgid="1424081831468083402">"Usuario actual <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
@@ -428,4 +428,7 @@
<string name="tuner_toast" msgid="603429811084428439">"Parabéns! O configurador da IU do sistema engadiuse a Configuración"</string>
<string name="remove_from_settings" msgid="8389591916603406378">"Eliminar da Configuración"</string>
<string name="remove_from_settings_prompt" msgid="6069085993355887748">"Queres eliminar o configurador da IU do sistema da Configuración e deixar de usar todas as súas funcións?"</string>
+ <string name="enable_bluetooth_title" msgid="5027037706500635269">"Queres activar o Bluetooth?"</string>
+ <string name="enable_bluetooth_message" msgid="9106595990708985385">"Para conectar o teu teclado co tablet, primeiro tes que activar o Bluetooth."</string>
+ <string name="enable_bluetooth_confirmation_ok" msgid="6258074250948309715">"Activar"</string>
</resources>
diff --git a/packages/SystemUI/res/values-gu-rIN/strings.xml b/packages/SystemUI/res/values-gu-rIN/strings.xml
index fb71e6e..0c43a10 100644
--- a/packages/SystemUI/res/values-gu-rIN/strings.xml
+++ b/packages/SystemUI/res/values-gu-rIN/strings.xml
@@ -325,6 +325,8 @@
<string name="interruption_level_priority_twoline" msgid="1564715335217164124">"ફક્ત\nપ્રાધાન્યતા"</string>
<string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"ફક્ત\nએલાર્મ્સ"</string>
<string name="keyguard_indication_charging_time" msgid="1757251776872835768">"ચાર્જ થઈ રહ્યું છે (પૂર્ણ થવામાં <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> બાકી)"</string>
+ <string name="keyguard_indication_charging_time_fast" msgid="9018981952053914986">"ઝડપથી ચાર્જિંગ થઇ રહી છે (પૂર્ણ થવામાં <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> બાકી)"</string>
+ <string name="keyguard_indication_charging_time_slowly" msgid="955252797961724952">"ધીમેથી ચાર્જિંગ થઇ રહી છે (પૂર્ણ થવામાં <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> બાકી)"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="7305948938141024937">"વપરાશકર્તા સ્વિચ કરો"</string>
<string name="accessibility_multi_user_switch_switcher_with_current" msgid="8434880595284601601">"વપરાશકર્તાને સ્વિચ કરો, વર્તમાન વપરાશકર્તા <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_inactive" msgid="1424081831468083402">"વર્તમાન વપરાશકર્તા <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
@@ -426,4 +428,7 @@
<string name="tuner_toast" msgid="603429811084428439">"અભિનંદન! સિસ્ટમ UI ટ્યૂનરને સેટિંગ્સમાં ઉમેરવામાં આવ્યું છે"</string>
<string name="remove_from_settings" msgid="8389591916603406378">"સેટિંગ્સમાંથી દૂર કરો"</string>
<string name="remove_from_settings_prompt" msgid="6069085993355887748">"સેટિંગ્સમાંથી સિસ્ટમ UI ટ્યૂનર દૂર કરી અને તેની તમામ સુવિધાઓનો ઉપયોગ કરવાનું બંધ કરીએ?"</string>
+ <string name="enable_bluetooth_title" msgid="5027037706500635269">"Bluetooth ચાલુ કરવુ છે?"</string>
+ <string name="enable_bluetooth_message" msgid="9106595990708985385">"તમારા ટેબ્લેટ સાથે કીબોર્ડ કનેક્ટ કરવા માટે, તમારે પહેલાં Bluetooth ચાલુ કરવાની જરૂર પડશે."</string>
+ <string name="enable_bluetooth_confirmation_ok" msgid="6258074250948309715">"ચાલુ કરો"</string>
</resources>
diff --git a/packages/SystemUI/res/values-hi/strings.xml b/packages/SystemUI/res/values-hi/strings.xml
index aac1725..2cebebb 100644
--- a/packages/SystemUI/res/values-hi/strings.xml
+++ b/packages/SystemUI/res/values-hi/strings.xml
@@ -325,6 +325,8 @@
<string name="interruption_level_priority_twoline" msgid="1564715335217164124">"केवल\nप्राथमिकता"</string>
<string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"केवल\nअलार्म"</string>
<string name="keyguard_indication_charging_time" msgid="1757251776872835768">"चार्ज हो रहा है (पूरा होने में <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> बाकी)"</string>
+ <string name="keyguard_indication_charging_time_fast" msgid="9018981952053914986">"तेज़ी से चार्ज हो रहा है (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> में हो जाएगा)"</string>
+ <string name="keyguard_indication_charging_time_slowly" msgid="955252797961724952">"धीरे चार्ज हो रहा है (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> में पूरा हो जाएगा)"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="7305948938141024937">"उपयोगकर्ता स्विच करें"</string>
<string name="accessibility_multi_user_switch_switcher_with_current" msgid="8434880595284601601">"उपयोगकर्ता स्विच करें, वर्तमान उपयोगकर्ता <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_inactive" msgid="1424081831468083402">"वर्तमान उपयोगकर्ता <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
@@ -426,4 +428,7 @@
<string name="tuner_toast" msgid="603429811084428439">"बधाई हो! सिस्टम UI ट्यूनर को सेटिंग में जोड़ दिया गया है"</string>
<string name="remove_from_settings" msgid="8389591916603406378">"सेटिंग से निकालें"</string>
<string name="remove_from_settings_prompt" msgid="6069085993355887748">"सेटिंग से सिस्टम UI ट्यूनर निकालें और इसकी सभी सुविधाओं का उपयोग रोक दें?"</string>
+ <string name="enable_bluetooth_title" msgid="5027037706500635269">"ब्लूटूथ चालू करें?"</string>
+ <string name="enable_bluetooth_message" msgid="9106595990708985385">"अपने कीबोर्ड को अपने टैबलेट से कनेक्ट करने के लिए, आपको पहले ब्लूटूथ चालू करना होगा."</string>
+ <string name="enable_bluetooth_confirmation_ok" msgid="6258074250948309715">"चालू करें"</string>
</resources>
diff --git a/packages/SystemUI/res/values-hr/strings.xml b/packages/SystemUI/res/values-hr/strings.xml
index 85e9eff..f228385 100644
--- a/packages/SystemUI/res/values-hr/strings.xml
+++ b/packages/SystemUI/res/values-hr/strings.xml
@@ -326,6 +326,8 @@
<string name="interruption_level_priority_twoline" msgid="1564715335217164124">"Samo\nprioritetno"</string>
<string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"Samo\nalarmi"</string>
<string name="keyguard_indication_charging_time" msgid="1757251776872835768">"Punjenje (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> do napunjenosti)"</string>
+ <string name="keyguard_indication_charging_time_fast" msgid="9018981952053914986">"Brzo punjenje (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> do napunjenosti)"</string>
+ <string name="keyguard_indication_charging_time_slowly" msgid="955252797961724952">"Sporo punjenje (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> do napunjenosti)"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="7305948938141024937">"Promjena korisnika"</string>
<string name="accessibility_multi_user_switch_switcher_with_current" msgid="8434880595284601601">"Promjena korisnika, trenutačni korisnik <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_inactive" msgid="1424081831468083402">"Trenutačan korisnik <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
@@ -427,4 +429,7 @@
<string name="tuner_toast" msgid="603429811084428439">"Čestitamo! Ugađanje korisničkog sučelja sustava dodano je u Postavke"</string>
<string name="remove_from_settings" msgid="8389591916603406378">"Ukloni iz Postavki"</string>
<string name="remove_from_settings_prompt" msgid="6069085993355887748">"Želite li ukloniti Ugađanje korisničkog sučelja sustava iz Postavki i prestati upotrebljavati njegove značajke?"</string>
+ <string name="enable_bluetooth_title" msgid="5027037706500635269">"Želite li uključiti Bluetooth?"</string>
+ <string name="enable_bluetooth_message" msgid="9106595990708985385">"Da biste povezali tipkovnicu s tabletom, morate uključiti Bluetooth."</string>
+ <string name="enable_bluetooth_confirmation_ok" msgid="6258074250948309715">"Uključi"</string>
</resources>
diff --git a/packages/SystemUI/res/values-hu/strings.xml b/packages/SystemUI/res/values-hu/strings.xml
index 3b34d19..5f0ed21 100644
--- a/packages/SystemUI/res/values-hu/strings.xml
+++ b/packages/SystemUI/res/values-hu/strings.xml
@@ -325,6 +325,8 @@
<string name="interruption_level_priority_twoline" msgid="1564715335217164124">"Csak\nprioritás"</string>
<string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"Csak\nriasztások"</string>
<string name="keyguard_indication_charging_time" msgid="1757251776872835768">"Töltés (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> a teljes töltöttségig)"</string>
+ <string name="keyguard_indication_charging_time_fast" msgid="9018981952053914986">"Gyors töltés (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> a teljes töltöttségig)"</string>
+ <string name="keyguard_indication_charging_time_slowly" msgid="955252797961724952">"Lassú töltés (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> a teljes töltöttségig)"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="7305948938141024937">"Felhasználóváltás"</string>
<string name="accessibility_multi_user_switch_switcher_with_current" msgid="8434880595284601601">"Felhasználóváltás (a jelenlegi felhasználó: <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>)"</string>
<string name="accessibility_multi_user_switch_inactive" msgid="1424081831468083402">"Jelenlegi felhasználó (<xliff:g id="CURRENT_USER_NAME">%s</xliff:g>)"</string>
@@ -426,4 +428,7 @@
<string name="tuner_toast" msgid="603429811084428439">"Gratulálunk! A Kezelőfelület-hangolót hozzáadtuk a Beállításokhoz"</string>
<string name="remove_from_settings" msgid="8389591916603406378">"Eltávolítás a Beállítások közül"</string>
<string name="remove_from_settings_prompt" msgid="6069085993355887748">"Eltávolítja a Kezelőfelület-hangolót a Beállításokból, és nem használja tovább egyik funkcióját sem?"</string>
+ <string name="enable_bluetooth_title" msgid="5027037706500635269">"Engedélyezi a Bluetooth-kapcsolatot?"</string>
+ <string name="enable_bluetooth_message" msgid="9106595990708985385">"Ha a billentyűzetet csatlakoztatni szeretné táblagépéhez, először engedélyeznie kell a Bluetooth-kapcsolatot."</string>
+ <string name="enable_bluetooth_confirmation_ok" msgid="6258074250948309715">"Bekapcsolás"</string>
</resources>
diff --git a/packages/SystemUI/res/values-hy-rAM/strings.xml b/packages/SystemUI/res/values-hy-rAM/strings.xml
index beefa8e..b7ab2b5 100644
--- a/packages/SystemUI/res/values-hy-rAM/strings.xml
+++ b/packages/SystemUI/res/values-hy-rAM/strings.xml
@@ -325,6 +325,8 @@
<string name="interruption_level_priority_twoline" msgid="1564715335217164124">"Միայն\nկարևորները"</string>
<string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"Միայն\nզարթուցիչ"</string>
<string name="keyguard_indication_charging_time" msgid="1757251776872835768">"Լիցքավորում (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> մինչև լրիվ լիցքավորումը)"</string>
+ <string name="keyguard_indication_charging_time_fast" msgid="9018981952053914986">"Արագ լիցքավորում (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>՝ մինչև ավարտ)"</string>
+ <string name="keyguard_indication_charging_time_slowly" msgid="955252797961724952">"Դանդաղ լիցքավորում (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>՝ մինչև ավարտ)"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="7305948938141024937">"Անջատել օգտվողին"</string>
<string name="accessibility_multi_user_switch_switcher_with_current" msgid="8434880595284601601">"Փոխել օգտվողին. ներկայիս օգտվողն է՝ <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_inactive" msgid="1424081831468083402">"Ընթացիկ օգտվողը՝ <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
@@ -420,10 +422,13 @@
<string name="accessibility_status_bar_hotspot" msgid="4099381329956402865">"Թեժ կետ"</string>
<string name="accessibility_managed_profile" msgid="6613641363112584120">"Աշխատանքային պրոֆիլ"</string>
<string name="tuner_warning_title" msgid="7094689930793031682">"Զվարճանք մեկ՝ որոշակի մարդու համար"</string>
- <string name="tuner_warning" msgid="8730648121973575701">"Համակարգի ՕՄ-ի կարգավորիչը հնարավորություն է տալիս հարմարեցնել Android-ի օգտվողի միջերեսը: Այս փորձնական գործառույթները կարող են հետագա թողարկումների մեջ փոփոխվել, խափանվել կամ ընդհանրապես չհայտնվել: Եթե շարունակում եք, զգուշացեք:"</string>
+ <string name="tuner_warning" msgid="8730648121973575701">"Համակարգի ՕՄ-ի ընդունիչը հնարավորություն է տալիս հարմարեցնել Android-ի օգտվողի միջերեսը: Այս փորձնական գործառույթները կարող են հետագա թողարկումների մեջ փոփոխվել, խափանվել կամ ընդհանրապես չհայտնվել: Եթե շարունակում եք, զգուշացեք:"</string>
<string name="tuner_persistent_warning" msgid="8597333795565621795">"Այս փորձնական գործառույթները կարող են հետագա թողարկումների մեջ փոփոխվել, խափանվել կամ ընդհանրապես չհայտնվել: Եթե շարունակում եք, զգուշացեք:"</string>
<string name="got_it" msgid="2239653834387972602">"Հասկանալի է"</string>
- <string name="tuner_toast" msgid="603429811084428439">"Համակարգի ՕՄ-ի կարգավորիչը ավելացվել է կարգավորումներին"</string>
+ <string name="tuner_toast" msgid="603429811084428439">"Համակարգի ՕՄ-ի ընդունիչը ավելացվել է կարգավորումներին"</string>
<string name="remove_from_settings" msgid="8389591916603406378">"Հեռացնել կարգավորումներից"</string>
- <string name="remove_from_settings_prompt" msgid="6069085993355887748">"Հեռացնե՞լ Համակարգի ՕՄ-ի կարգավորիչը կարգավորումներից և չօգտվել այլևս նրա գործառույթներից:"</string>
+ <string name="remove_from_settings_prompt" msgid="6069085993355887748">"Հեռացնե՞լ Համակարգի ՕՄ-ի ընդունիչը կարգավորումներից և չօգտվել այլևս նրա գործառույթներից:"</string>
+ <string name="enable_bluetooth_title" msgid="5027037706500635269">"Միացնե՞լ Bluetooth-ը:"</string>
+ <string name="enable_bluetooth_message" msgid="9106595990708985385">"Ստեղնաշարը ձեր պլանշետին միացնելու համար նախ անհրաժեշտ է միացնել Bluetooth-ը:"</string>
+ <string name="enable_bluetooth_confirmation_ok" msgid="6258074250948309715">"Միացնել"</string>
</resources>
diff --git a/packages/SystemUI/res/values-in/strings.xml b/packages/SystemUI/res/values-in/strings.xml
index f1d2907..a4a6c46 100644
--- a/packages/SystemUI/res/values-in/strings.xml
+++ b/packages/SystemUI/res/values-in/strings.xml
@@ -325,6 +325,8 @@
<string name="interruption_level_priority_twoline" msgid="1564715335217164124">"Hanya\nprioritas"</string>
<string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"Hanya\nalarm"</string>
<string name="keyguard_indication_charging_time" msgid="1757251776872835768">"Mengisi daya (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> hingga penuh)"</string>
+ <string name="keyguard_indication_charging_time_fast" msgid="9018981952053914986">"Mengisi daya dengan cepat (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> hingga penuh)"</string>
+ <string name="keyguard_indication_charging_time_slowly" msgid="955252797961724952">"Mengisi daya dengan lambat (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> hingga penuh)"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="7305948938141024937">"Beralih pengguna"</string>
<string name="accessibility_multi_user_switch_switcher_with_current" msgid="8434880595284601601">"Ganti pengguna, pengguna saat ini <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_inactive" msgid="1424081831468083402">"Pengguna saat ini <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
@@ -426,4 +428,7 @@
<string name="tuner_toast" msgid="603429811084428439">"Selamat! Penyetel Antarmuka Pengguna Sistem telah ditambahkan ke Setelan"</string>
<string name="remove_from_settings" msgid="8389591916603406378">"Hapus dari Setelan"</string>
<string name="remove_from_settings_prompt" msgid="6069085993355887748">"Hapus Penyetel Antarmuka Pengguna Sistem dari Setelan dan berhenti menggunakan semua fiturnya?"</string>
+ <string name="enable_bluetooth_title" msgid="5027037706500635269">"Aktifkan Bluetooth?"</string>
+ <string name="enable_bluetooth_message" msgid="9106595990708985385">"Untuk menghubungkan keyboard dengan tablet, terlebih dahulu aktifkan Bluetooth."</string>
+ <string name="enable_bluetooth_confirmation_ok" msgid="6258074250948309715">"Aktifkan"</string>
</resources>
diff --git a/packages/SystemUI/res/values-is-rIS/strings.xml b/packages/SystemUI/res/values-is-rIS/strings.xml
index b986783..3d93814 100644
--- a/packages/SystemUI/res/values-is-rIS/strings.xml
+++ b/packages/SystemUI/res/values-is-rIS/strings.xml
@@ -325,6 +325,8 @@
<string name="interruption_level_priority_twoline" msgid="1564715335217164124">"Aðeins\nforgangur"</string>
<string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"Aðeins\nvekjarar"</string>
<string name="keyguard_indication_charging_time" msgid="1757251776872835768">"Í hleðslu (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> fram að fullri hleðslu)"</string>
+ <string name="keyguard_indication_charging_time_fast" msgid="9018981952053914986">"Í hraðri hleðslu (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> fram að fullri hleðslu)"</string>
+ <string name="keyguard_indication_charging_time_slowly" msgid="955252797961724952">"Í hægri hleðslu (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> fram að fullri hleðslu)"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="7305948938141024937">"Skipta um notanda"</string>
<string name="accessibility_multi_user_switch_switcher_with_current" msgid="8434880595284601601">"Skipta um notanda; núverandi notandi er <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_inactive" msgid="1424081831468083402">"Núverandi notandi er <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
@@ -426,4 +428,7 @@
<string name="tuner_toast" msgid="603429811084428439">"Til hamingju! Fínstillingum kerfisviðmóts hefur verið bætt við stillingar"</string>
<string name="remove_from_settings" msgid="8389591916603406378">"Fjarlægja úr stillingum"</string>
<string name="remove_from_settings_prompt" msgid="6069085993355887748">"Viltu fjarlægja fínstillingar kerfisviðmóts úr stillingum og hætta að nota eiginleika þeirra?"</string>
+ <string name="enable_bluetooth_title" msgid="5027037706500635269">"Kveikja á Bluetooth?"</string>
+ <string name="enable_bluetooth_message" msgid="9106595990708985385">"Til að geta tengt lyklaborðið við spjaldtölvuna þarftu fyrst að kveikja á Bluetooth."</string>
+ <string name="enable_bluetooth_confirmation_ok" msgid="6258074250948309715">"Kveikja"</string>
</resources>
diff --git a/packages/SystemUI/res/values-it/strings.xml b/packages/SystemUI/res/values-it/strings.xml
index 461db53..5ba6eca 100644
--- a/packages/SystemUI/res/values-it/strings.xml
+++ b/packages/SystemUI/res/values-it/strings.xml
@@ -150,9 +150,7 @@
<string name="accessibility_airplane_mode" msgid="834748999790763092">"Modalità aereo."</string>
<string name="accessibility_no_sims" msgid="3957997018324995781">"Nessuna SIM presente."</string>
<string name="accessibility_carrier_network_change_mode" msgid="4017301580441304305">"Cambio rete operatore."</string>
- <!-- String.format failed for translation -->
- <!-- no translation found for accessibility_battery_level (7451474187113371965) -->
- <skip />
+ <string name="accessibility_battery_level" msgid="7451474187113371965">"Batteria: <xliff:g id="NUMBER">%d</xliff:g> percento."</string>
<string name="accessibility_settings_button" msgid="799583911231893380">"Impostazioni di sistema."</string>
<string name="accessibility_notifications_button" msgid="4498000369779421892">"Notifiche."</string>
<string name="accessibility_remove_notification" msgid="3603099514902182350">"Cancella notifica."</string>
@@ -327,6 +325,8 @@
<string name="interruption_level_priority_twoline" msgid="1564715335217164124">"Solo con\npriorità"</string>
<string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"Solo\nsveglie"</string>
<string name="keyguard_indication_charging_time" msgid="1757251776872835768">"In carica (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> al termine)"</string>
+ <string name="keyguard_indication_charging_time_fast" msgid="9018981952053914986">"Ricarica veloce (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> al termine)"</string>
+ <string name="keyguard_indication_charging_time_slowly" msgid="955252797961724952">"Ricarica lenta (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> al termine)"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="7305948938141024937">"Cambio utente"</string>
<string name="accessibility_multi_user_switch_switcher_with_current" msgid="8434880595284601601">"Cambia utente, utente corrente <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_inactive" msgid="1424081831468083402">"Utente corrente <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
@@ -348,7 +348,7 @@
<string name="guest_notification_remove_action" msgid="8820670703892101990">"RIMUOVI OSPITE"</string>
<string name="user_add_user_title" msgid="4553596395824132638">"Aggiungere un nuovo utente?"</string>
<string name="user_add_user_message_short" msgid="2161624834066214559">"Il nuovo utente, una volta aggiunto, deve impostare il proprio spazio.\n\nQualsiasi utente può aggiornare le app per tutti gli altri."</string>
- <string name="battery_saver_notification_title" msgid="237918726750955859">"Risparmio batteria attivo"</string>
+ <string name="battery_saver_notification_title" msgid="237918726750955859">"Risparmio energetico attivo"</string>
<string name="battery_saver_notification_text" msgid="820318788126672692">"Riduce le prestazioni e i dati in background"</string>
<string name="battery_saver_notification_action_text" msgid="109158658238110382">"Disattiva risparmio energetico"</string>
<string name="notification_hidden_text" msgid="1135169301897151909">"Contenuti nascosti"</string>
@@ -428,4 +428,7 @@
<string name="tuner_toast" msgid="603429811084428439">"Complimenti! Il sintetizzatore interfaccia utente di sistema è stato aggiunto alle impostazioni."</string>
<string name="remove_from_settings" msgid="8389591916603406378">"Rimuovi dalle impostazioni"</string>
<string name="remove_from_settings_prompt" msgid="6069085993355887748">"Vuoi rimuovere il sintetizzatore interfaccia utente di sistema dalle impostazioni e smettere di utilizzare tutte le sue funzioni?"</string>
+ <string name="enable_bluetooth_title" msgid="5027037706500635269">"Attivare il Bluetooth?"</string>
+ <string name="enable_bluetooth_message" msgid="9106595990708985385">"Per connettere la tastiera al tablet, devi prima attivare il Bluetooth."</string>
+ <string name="enable_bluetooth_confirmation_ok" msgid="6258074250948309715">"Attiva"</string>
</resources>
diff --git a/packages/SystemUI/res/values-iw/strings.xml b/packages/SystemUI/res/values-iw/strings.xml
index 8893bec..0a01c16 100644
--- a/packages/SystemUI/res/values-iw/strings.xml
+++ b/packages/SystemUI/res/values-iw/strings.xml
@@ -62,11 +62,11 @@
<string name="label_view" msgid="6304565553218192990">"הצג"</string>
<string name="always_use_device" msgid="1450287437017315906">"השתמש כברירת מחדל עבור מכשיר USB זה"</string>
<string name="always_use_accessory" msgid="1210954576979621596">"השתמש כברירת מחדל עבור אביזר USB זה"</string>
- <string name="usb_debugging_title" msgid="4513918393387141949">"האם לאפשר ניקוי באגים ב-USB?"</string>
+ <string name="usb_debugging_title" msgid="4513918393387141949">"האם לאפשר ניפוי באגים ב-USB?"</string>
<string name="usb_debugging_message" msgid="2220143855912376496">"טביעת האצבע של מפתח ה-RSA של המחשב היא:\n<xliff:g id="FINGERPRINT">%1$s</xliff:g>"</string>
<string name="usb_debugging_always" msgid="303335496705863070">"אפשר תמיד ממחשב זה"</string>
- <string name="usb_debugging_secondary_user_title" msgid="6353808721761220421">"לא ניתן לבצע ניקוי באגים ב-USB"</string>
- <string name="usb_debugging_secondary_user_message" msgid="6011931347142270156">"המכשיר המחובר כעת אל המכשיר הזה אינו יכול להפעיל ניקוי באגים ב-USB. כדי להשתמש בתכונה הזו יש לעבור אל המשתמש הראשי, “<xliff:g id="NAME">%s</xliff:g>”."</string>
+ <string name="usb_debugging_secondary_user_title" msgid="6353808721761220421">"לא ניתן לבצע ניפוי באגים ב-USB"</string>
+ <string name="usb_debugging_secondary_user_message" msgid="6011931347142270156">"המכשיר המחובר כעת אל המכשיר הזה אינו יכול להפעיל ניפוי באגים ב-USB. כדי להשתמש בתכונה הזו יש לעבור אל המשתמש הראשי, “<xliff:g id="NAME">%s</xliff:g>”."</string>
<string name="compat_mode_on" msgid="6623839244840638213">"הגדל תצוגה כדי למלא את המסך"</string>
<string name="compat_mode_off" msgid="4434467572461327898">"מתח כדי למלא את המסך"</string>
<string name="screenshot_saving_ticker" msgid="7403652894056693515">"שומר צילום מסך..."</string>
@@ -327,6 +327,8 @@
<string name="interruption_level_priority_twoline" msgid="1564715335217164124">"התראות בעדיפות\nבלבד"</string>
<string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"התראות\nבלבד"</string>
<string name="keyguard_indication_charging_time" msgid="1757251776872835768">"טוען (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> עד לסיום)"</string>
+ <string name="keyguard_indication_charging_time_fast" msgid="9018981952053914986">"בטעינה מהירה (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> עד למילוי)"</string>
+ <string name="keyguard_indication_charging_time_slowly" msgid="955252797961724952">"בטעינה איטית (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> עד למילוי)"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="7305948938141024937">"החלפת משתמש"</string>
<string name="accessibility_multi_user_switch_switcher_with_current" msgid="8434880595284601601">"החלף משתמש. המשתמש הנוכחי הוא <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_inactive" msgid="1424081831468083402">"משתמש נוכחי <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
@@ -428,4 +430,7 @@
<string name="tuner_toast" msgid="603429811084428439">"מזל טוב! System UI Tuner נוסף ל\'הגדרות\'"</string>
<string name="remove_from_settings" msgid="8389591916603406378">"הסר מההגדרות"</string>
<string name="remove_from_settings_prompt" msgid="6069085993355887748">"האם להסיר את System UI Tuner ולהפסיק להשתמש בכל התכונות שלו?"</string>
+ <string name="enable_bluetooth_title" msgid="5027037706500635269">"האם להפעיל את ה-Bluetooth?"</string>
+ <string name="enable_bluetooth_message" msgid="9106595990708985385">"כדי לחבר את המקלדת לטאבלט, תחילה עליך להפעיל את ה-Bluetooth."</string>
+ <string name="enable_bluetooth_confirmation_ok" msgid="6258074250948309715">"הפעל"</string>
</resources>
diff --git a/packages/SystemUI/res/values-ja/strings.xml b/packages/SystemUI/res/values-ja/strings.xml
index 260a92b..12185d9 100644
--- a/packages/SystemUI/res/values-ja/strings.xml
+++ b/packages/SystemUI/res/values-ja/strings.xml
@@ -88,7 +88,7 @@
<string name="accessibility_voice_assist_button" msgid="487611083884852965">"音声アシスト"</string>
<string name="accessibility_unlock_button" msgid="128158454631118828">"ロック解除"</string>
<string name="accessibility_unlock_button_fingerprint" msgid="8214125623493923751">"ロック解除ボタン、指紋を待っています"</string>
- <string name="accessibility_unlock_without_fingerprint" msgid="7541705575183694446">"指紋を使用せずにロック解除"</string>
+ <string name="accessibility_unlock_without_fingerprint" msgid="7541705575183694446">"指紋認証を使用せずにロック解除"</string>
<string name="unlock_label" msgid="8779712358041029439">"ロック解除"</string>
<string name="phone_label" msgid="2320074140205331708">"電話を起動"</string>
<string name="voice_assist_label" msgid="3956854378310019854">"音声アシストを開く"</string>
@@ -150,9 +150,7 @@
<string name="accessibility_airplane_mode" msgid="834748999790763092">"機内モード。"</string>
<string name="accessibility_no_sims" msgid="3957997018324995781">"SIMカードが挿入されていません。"</string>
<string name="accessibility_carrier_network_change_mode" msgid="4017301580441304305">"携帯通信会社のネットワークを変更します。"</string>
- <!-- String.format failed for translation -->
- <!-- no translation found for accessibility_battery_level (7451474187113371965) -->
- <skip />
+ <string name="accessibility_battery_level" msgid="7451474187113371965">"電池残量: <xliff:g id="NUMBER">%d</xliff:g>パーセント"</string>
<string name="accessibility_settings_button" msgid="799583911231893380">"システム設定。"</string>
<string name="accessibility_notifications_button" msgid="4498000369779421892">"通知。"</string>
<string name="accessibility_remove_notification" msgid="3603099514902182350">"通知を消去。"</string>
@@ -327,10 +325,12 @@
<string name="interruption_level_priority_twoline" msgid="1564715335217164124">"重要な\n通知のみ"</string>
<string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"アラーム\nのみ"</string>
<string name="keyguard_indication_charging_time" msgid="1757251776872835768">"充電中(フル充電まで<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>)"</string>
+ <string name="keyguard_indication_charging_time_fast" msgid="9018981952053914986">"急速充電中(完了まで<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>)"</string>
+ <string name="keyguard_indication_charging_time_slowly" msgid="955252797961724952">"低速充電中(完了まで<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>)"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="7305948938141024937">"ユーザーを切り替える"</string>
<string name="accessibility_multi_user_switch_switcher_with_current" msgid="8434880595284601601">"ユーザーを切り替える、現在のユーザーは<xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_inactive" msgid="1424081831468083402">"現在のユーザー: <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
- <string name="accessibility_multi_user_switch_quick_contact" msgid="3020367729287990475">"プロフィールを表示"</string>
+ <string name="accessibility_multi_user_switch_quick_contact" msgid="3020367729287990475">"プロファイルを表示"</string>
<string name="user_add_user" msgid="5110251524486079492">"ユーザーを追加"</string>
<string name="user_new_user_name" msgid="426540612051178753">"新しいユーザー"</string>
<string name="guest_nickname" msgid="8059989128963789678">"ゲスト"</string>
@@ -358,10 +358,10 @@
<string name="media_projection_action_text" msgid="8470872969457985954">"今すぐ開始"</string>
<string name="empty_shade_text" msgid="708135716272867002">"通知はありません"</string>
<string name="device_owned_footer" msgid="3802752663326030053">"端末が監視されている可能性があります"</string>
- <string name="profile_owned_footer" msgid="8021888108553696069">"プロフィールが監視されている可能性があります"</string>
+ <string name="profile_owned_footer" msgid="8021888108553696069">"プロファイルが監視されている可能性があります"</string>
<string name="vpn_footer" msgid="2388611096129106812">"ネットワークが監視されている可能性があります"</string>
<string name="monitoring_title_device_owned" msgid="7121079311903859610">"端末の監視"</string>
- <string name="monitoring_title_profile_owned" msgid="6790109874733501487">"プロフィールの監視"</string>
+ <string name="monitoring_title_profile_owned" msgid="6790109874733501487">"プロファイルの監視"</string>
<string name="monitoring_title" msgid="169206259253048106">"ネットワーク監視"</string>
<string name="disable_vpn" msgid="4435534311510272506">"VPNを無効にする"</string>
<string name="disconnect_vpn" msgid="1324915059568548655">"VPNを切断"</string>
@@ -428,4 +428,7 @@
<string name="tuner_toast" msgid="603429811084428439">"システムUI調整ツールを設定に追加しました"</string>
<string name="remove_from_settings" msgid="8389591916603406378">"設定から削除"</string>
<string name="remove_from_settings_prompt" msgid="6069085993355887748">"設定からシステムUI調整ツールを削除して、全機能の使用を停止しますか?"</string>
+ <string name="enable_bluetooth_title" msgid="5027037706500635269">"BluetoothをONにしますか?"</string>
+ <string name="enable_bluetooth_message" msgid="9106595990708985385">"タブレットでキーボードに接続するには、最初にBluetoothをONにする必要があります。"</string>
+ <string name="enable_bluetooth_confirmation_ok" msgid="6258074250948309715">"ONにする"</string>
</resources>
diff --git a/packages/SystemUI/res/values-ka-rGE/strings.xml b/packages/SystemUI/res/values-ka-rGE/strings.xml
index 54f545d..8e04d53 100644
--- a/packages/SystemUI/res/values-ka-rGE/strings.xml
+++ b/packages/SystemUI/res/values-ka-rGE/strings.xml
@@ -325,6 +325,8 @@
<string name="interruption_level_priority_twoline" msgid="1564715335217164124">"მხოლოდ\nპრიორიტეტულები"</string>
<string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"მხოლოდ\nგაფრთხილებები"</string>
<string name="keyguard_indication_charging_time" msgid="1757251776872835768">"(<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>-ის შეცვლა დასრულებამდე)"</string>
+ <string name="keyguard_indication_charging_time_fast" msgid="9018981952053914986">"იტენება სწრაფად (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> სრულ დატენვამდე)"</string>
+ <string name="keyguard_indication_charging_time_slowly" msgid="955252797961724952">"იტენება ნელა (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> სრულ დატენვამდე)"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="7305948938141024937">"მომხმარებლის გადართვა"</string>
<string name="accessibility_multi_user_switch_switcher_with_current" msgid="8434880595284601601">"მომხმარებლის გდართვა. ამჟამინდელი მომხმარებელი <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_inactive" msgid="1424081831468083402">"ამჟამინდელი მომხმარებელი <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
@@ -426,4 +428,7 @@
<string name="tuner_toast" msgid="603429811084428439">"გილოცავთ! სისტემის UI ტუნერი დაემატა პარამეტრებს"</string>
<string name="remove_from_settings" msgid="8389591916603406378">"პარამეტრებიდან წაშლა"</string>
<string name="remove_from_settings_prompt" msgid="6069085993355887748">"გსურთ სისტემის UI ტუნერის პარამეტრებიდან წაშლა და მისი ყველა ფუნქციის გამოყენების შეწყვეტა?"</string>
+ <string name="enable_bluetooth_title" msgid="5027037706500635269">"გსურთ Bluetooth-ის ჩართვა?"</string>
+ <string name="enable_bluetooth_message" msgid="9106595990708985385">"კლავიატურის ტაბლეტთან დასაკავშირებლად, ჯერ უნდა ჩართოთ Bluetooth."</string>
+ <string name="enable_bluetooth_confirmation_ok" msgid="6258074250948309715">"ჩართვა"</string>
</resources>
diff --git a/packages/SystemUI/res/values-kk-rKZ/strings.xml b/packages/SystemUI/res/values-kk-rKZ/strings.xml
index e80c03a..d3465ce 100644
--- a/packages/SystemUI/res/values-kk-rKZ/strings.xml
+++ b/packages/SystemUI/res/values-kk-rKZ/strings.xml
@@ -325,6 +325,8 @@
<string name="interruption_level_priority_twoline" msgid="1564715335217164124">"Тек\nбасымдық"</string>
<string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"Тек\nдабылдар"</string>
<string name="keyguard_indication_charging_time" msgid="1757251776872835768">"Зарядталуда (толғанша <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>)"</string>
+ <string name="keyguard_indication_charging_time_fast" msgid="9018981952053914986">"Жылдам зарядталуда (толғанша <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>)"</string>
+ <string name="keyguard_indication_charging_time_slowly" msgid="955252797961724952">"Баяу зарядталуда (толғанша <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>)"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="7305948938141024937">"Пайдаланушыны ауыстыру"</string>
<string name="accessibility_multi_user_switch_switcher_with_current" msgid="8434880595284601601">"Пайдаланушыны ауыстыру, ағымдағы пайдаланушы <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_inactive" msgid="1424081831468083402">"Ағымдағы пайдаланушы: <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
@@ -426,4 +428,7 @@
<string name="tuner_toast" msgid="603429811084428439">"Құттықтаймыз! Жүйелік пайдаланушылық интерфейс тюнері \"Параметрлер\" тармағына қосылды"</string>
<string name="remove_from_settings" msgid="8389591916603406378">"Параметрлерден жою"</string>
<string name="remove_from_settings_prompt" msgid="6069085993355887748">"Жүйелік пайдаланушылық интерфейс тюнерін \"Параметрлер\" тармағынан жойып, оның барлық мүмкіндіктерін пайдалануды тоқтату керек пе?"</string>
+ <string name="enable_bluetooth_title" msgid="5027037706500635269">"Bluetooth функциясын қосу керек пе?"</string>
+ <string name="enable_bluetooth_message" msgid="9106595990708985385">"Пернетақтаны планшетке қосу үшін алдымен Bluetooth функциясын қосу керек."</string>
+ <string name="enable_bluetooth_confirmation_ok" msgid="6258074250948309715">"Қосу"</string>
</resources>
diff --git a/packages/SystemUI/res/values-km-rKH/strings.xml b/packages/SystemUI/res/values-km-rKH/strings.xml
index df3dfb7..94b62bf 100644
--- a/packages/SystemUI/res/values-km-rKH/strings.xml
+++ b/packages/SystemUI/res/values-km-rKH/strings.xml
@@ -325,6 +325,8 @@
<string name="interruption_level_priority_twoline" msgid="1564715335217164124">"អាទិភាព\nប៉ុណ្ណោះ"</string>
<string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"សំឡេងរោទ៍\nប៉ុណ្ណោះ"</string>
<string name="keyguard_indication_charging_time" msgid="1757251776872835768">"កំពុងបញ្ចូលថ្ម (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> ទើបពេញ)"</string>
+ <string name="keyguard_indication_charging_time_fast" msgid="9018981952053914986">"ថ្មកំពុងសាកលឿន (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> ទើបពេញ)"</string>
+ <string name="keyguard_indication_charging_time_slowly" msgid="955252797961724952">"ថ្មកំពុងសាកយឺតៗ (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> ទើបពេញ)"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="7305948938141024937">"ប្ដូរអ្នកប្រើ"</string>
<string name="accessibility_multi_user_switch_switcher_with_current" msgid="8434880595284601601">"ប្ដូរអ្នកប្រើ អ្នកប្រើបច្ចុប្បន្ន <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_inactive" msgid="1424081831468083402">"អ្នកប្រើបច្ចុប្បន្ន <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
@@ -426,4 +428,7 @@
<string name="tuner_toast" msgid="603429811084428439">"សូមអបអរសាទរ! កម្មវិធីសម្រួល UI ប្រព័ន្ធត្រូវបានបន្ថែមទៅការកំណត់ហើយ"</string>
<string name="remove_from_settings" msgid="8389591916603406378">"យកចេញពីការកំណត់"</string>
<string name="remove_from_settings_prompt" msgid="6069085993355887748">"យកកម្មវិធីសម្រួល UI ប្រព័ន្ធចេញពីការកំណត់ ហើយឈប់ប្រើលក្ខណៈពិសេសរបស់វាទាំងអស់?"</string>
+ <string name="enable_bluetooth_title" msgid="5027037706500635269">"បើកប៊្លូធូសឬ?"</string>
+ <string name="enable_bluetooth_message" msgid="9106595990708985385">"ដើម្បីភ្ជាប់ក្តារចុចរបស់អ្នកជាមួយនឹងថេប្លេតរបស់អ្នក អ្នកត្រូវតែបើកប៊្លូធូសជាមុនសិន។"</string>
+ <string name="enable_bluetooth_confirmation_ok" msgid="6258074250948309715">"បើក"</string>
</resources>
diff --git a/packages/SystemUI/res/values-kn-rIN/strings.xml b/packages/SystemUI/res/values-kn-rIN/strings.xml
index 6033303..bf00716 100644
--- a/packages/SystemUI/res/values-kn-rIN/strings.xml
+++ b/packages/SystemUI/res/values-kn-rIN/strings.xml
@@ -325,6 +325,8 @@
<string name="interruption_level_priority_twoline" msgid="1564715335217164124">"ಆದ್ಯತೆ\nಮಾತ್ರ"</string>
<string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"ಅಲಾರಮ್ಗಳು\nಮಾತ್ರ"</string>
<string name="keyguard_indication_charging_time" msgid="1757251776872835768">"ಚಾರ್ಜ್ ಆಗುತ್ತಿದೆ ( ಪೂರ್ತಿ ಆಗುವವರೆಗೆ <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>)"</string>
+ <string name="keyguard_indication_charging_time_fast" msgid="9018981952053914986">"ವೇಗವಾಗಿ ಚಾರ್ಜ್ ಆಗುತ್ತಿದೆ (ಪೂರ್ಣಗೊಳ್ಳಲು <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>)"</string>
+ <string name="keyguard_indication_charging_time_slowly" msgid="955252797961724952">"ನಿಧಾನ ಚಾರ್ಜ್ ಆಗುತ್ತಿದೆ (ಪೂರ್ಣಗೊಳ್ಳಲು <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>)"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="7305948938141024937">"ಬಳಕೆದಾರರನ್ನು ಬದಲಿಸಿ"</string>
<string name="accessibility_multi_user_switch_switcher_with_current" msgid="8434880595284601601">"ಬಳಕೆದಾರರನ್ನು ಬದಲಿಸಿ, ಪ್ರಸ್ತುತ ಬಳಕೆದಾರ <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_inactive" msgid="1424081831468083402">"<xliff:g id="CURRENT_USER_NAME">%s</xliff:g> ಪ್ರಸ್ತುತ ಬಳಕೆದಾರ"</string>
@@ -426,4 +428,7 @@
<string name="tuner_toast" msgid="603429811084428439">"ಅಭಿನಂದನೆಗಳು! ಸಿಸ್ಟಮ್ UI ಟ್ಯೂನರ್ ಅನ್ನು ಸೆಟ್ಟಿಂಗ್ಗಳಿಗೆ ಸೇರಿಸಲಾಗಿದೆ"</string>
<string name="remove_from_settings" msgid="8389591916603406378">"ಸೆಟ್ಟಿಂಗ್ಗಳಿಂದ ತೆಗೆದುಹಾಕಿ"</string>
<string name="remove_from_settings_prompt" msgid="6069085993355887748">"ಸೆಟ್ಟಿಂಗ್ಗಳಿಂದ ಸಿಸ್ಟಮ್ UI ಟ್ಯೂನರ್ ತೆಗೆದುಹಾಕುವುದೇ ಮತ್ತು ಅದರ ಎಲ್ಲಾ ವೈಶಿಷ್ಟ್ಯಗಳನ್ನು ಬಳಸುವುದನ್ನು ನಿಲ್ಲಿಸುವುದೇ?"</string>
+ <string name="enable_bluetooth_title" msgid="5027037706500635269">"ಬ್ಲೂಟೂತ್ ಆನ್ ಮಾಡುವುದೇ?"</string>
+ <string name="enable_bluetooth_message" msgid="9106595990708985385">"ನಿಮ್ಮ ಕೀಬೋರ್ಡ್ ಅನ್ನು ಟ್ಯಾಬ್ಲೆಟ್ಗೆ ಸಂಪರ್ಕಿಸಲು, ನೀವು ಮೊದಲು ಬ್ಲೂಟೂತ್ ಆನ್ ಮಾಡಬೇಕಾಗುತ್ತದೆ."</string>
+ <string name="enable_bluetooth_confirmation_ok" msgid="6258074250948309715">"ಆನ್ ಮಾಡು"</string>
</resources>
diff --git a/packages/SystemUI/res/values-ko/strings.xml b/packages/SystemUI/res/values-ko/strings.xml
index 21796d0..5c49e51 100644
--- a/packages/SystemUI/res/values-ko/strings.xml
+++ b/packages/SystemUI/res/values-ko/strings.xml
@@ -325,6 +325,8 @@
<string name="interruption_level_priority_twoline" msgid="1564715335217164124">"중요 알림만\n허용"</string>
<string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"알람만\n"</string>
<string name="keyguard_indication_charging_time" msgid="1757251776872835768">"충전 중(<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> 후 충전 완료)"</string>
+ <string name="keyguard_indication_charging_time_fast" msgid="9018981952053914986">"고속 충전 중(<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> 후 충전 완료)"</string>
+ <string name="keyguard_indication_charging_time_slowly" msgid="955252797961724952">"저속 충전 중(<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> 후 충전 완료)"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="7305948938141024937">"사용자 전환"</string>
<string name="accessibility_multi_user_switch_switcher_with_current" msgid="8434880595284601601">"사용자 전환, 현재 사용자 <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_inactive" msgid="1424081831468083402">"현재 사용자: <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
@@ -426,4 +428,7 @@
<string name="tuner_toast" msgid="603429811084428439">"축하합니다. 시스템 UI 튜너가 설정에 추가되었습니다."</string>
<string name="remove_from_settings" msgid="8389591916603406378">"설정에서 삭제"</string>
<string name="remove_from_settings_prompt" msgid="6069085993355887748">"시스템 UI 튜너를 설정에서 삭제하고 모든 관련 기능의 사용을 중지하시겠습니까?"</string>
+ <string name="enable_bluetooth_title" msgid="5027037706500635269">"블루투스를 켜시겠습니까?"</string>
+ <string name="enable_bluetooth_message" msgid="9106595990708985385">"키보드를 태블릿에 연결하려면 먼저 블루투스를 켜야 합니다."</string>
+ <string name="enable_bluetooth_confirmation_ok" msgid="6258074250948309715">"사용"</string>
</resources>
diff --git a/packages/SystemUI/res/values-ky-rKG/strings.xml b/packages/SystemUI/res/values-ky-rKG/strings.xml
index 44ccbac..faad243 100644
--- a/packages/SystemUI/res/values-ky-rKG/strings.xml
+++ b/packages/SystemUI/res/values-ky-rKG/strings.xml
@@ -19,10 +19,8 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <!-- no translation found for app_label (7164937344850004466) -->
- <skip />
- <!-- no translation found for status_bar_clear_all_button (7774721344716731603) -->
- <skip />
+ <string name="app_label" msgid="7164937344850004466">"Тутум UI"</string>
+ <string name="status_bar_clear_all_button" msgid="7774721344716731603">"Тазалоо"</string>
<string name="status_bar_recent_remove_item_title" msgid="6026395868129852968">"Тизмеден алып салуу"</string>
<string name="status_bar_recent_inspect_item_title" msgid="7793624864528818569">"Колдонмо тууралуу"</string>
<string name="status_bar_no_recent_apps" msgid="7374907845131203189">"Акыркы экрандарыңыз бул жерден көрүнөт"</string>
@@ -31,63 +29,44 @@
<item quantity="other">%d экран Көз жүгүртүүдө</item>
<item quantity="one">1 экран Көз жүгүртүүдө</item>
</plurals>
- <!-- no translation found for status_bar_no_notifications_title (4755261167193833213) -->
- <skip />
- <!-- no translation found for status_bar_ongoing_events_title (1682504513316879202) -->
- <skip />
- <!-- no translation found for status_bar_latest_events_title (6594767438577593172) -->
- <skip />
+ <string name="status_bar_no_notifications_title" msgid="4755261167193833213">"Эскертмелер жок"</string>
+ <string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"Учурдагы"</string>
+ <string name="status_bar_latest_events_title" msgid="6594767438577593172">"Эскертмелер"</string>
<string name="battery_low_title" msgid="6456385927409742437">"Батареянын кубаты аз"</string>
<string name="battery_low_percent_format" msgid="2900940511201380775">"<xliff:g id="PERCENTAGE">%s</xliff:g> калды"</string>
<string name="battery_low_percent_format_saver_started" msgid="6859235584035338833">"<xliff:g id="PERCENTAGE">%s</xliff:g> калды. Батареянын кубатын үнөмдөгүч күйүк."</string>
- <!-- no translation found for invalid_charger (4549105996740522523) -->
- <skip />
+ <string name="invalid_charger" msgid="4549105996740522523">"USB менен кубаттоо колдоого алынбайт.\nБерилген заряддагычты гана колдонуңуз."</string>
<string name="invalid_charger_title" msgid="3515740382572798460">"USB аркылуу кубаттоого болбойт."</string>
<string name="invalid_charger_text" msgid="5474997287953892710">"Коштолгон кубаттагычты гана колдонуңуз."</string>
<string name="battery_low_why" msgid="4553600287639198111">"Жөндөөлөр"</string>
<string name="battery_saver_confirmation_title" msgid="5299585433050361634">"Батареянын кубатын үнөмдөгүч күйгүзүлсүнбү?"</string>
<string name="battery_saver_confirmation_ok" msgid="7507968430447930257">"Күйгүзүү"</string>
<string name="battery_saver_start_action" msgid="5576697451677486320">"Батареянын кубатын үнөмдөгүчтү иштетүү"</string>
- <!-- no translation found for status_bar_settings_settings_button (3023889916699270224) -->
- <skip />
- <!-- no translation found for status_bar_settings_wifi_button (1733928151698311923) -->
- <skip />
- <!-- no translation found for status_bar_settings_auto_rotation (3790482541357798421) -->
- <skip />
- <!-- no translation found for status_bar_settings_mute_label (554682549917429396) -->
- <skip />
- <!-- no translation found for status_bar_settings_auto_brightness_label (511453614962324674) -->
- <skip />
- <!-- no translation found for status_bar_settings_notifications (397146176280905137) -->
- <skip />
- <!-- no translation found for bluetooth_tethered (7094101612161133267) -->
- <skip />
+ <string name="status_bar_settings_settings_button" msgid="3023889916699270224">"Жөндөөлөр"</string>
+ <string name="status_bar_settings_wifi_button" msgid="1733928151698311923">"Wi‑Fi"</string>
+ <string name="status_bar_settings_auto_rotation" msgid="3790482541357798421">"Экранды авто-тегеретүү"</string>
+ <string name="status_bar_settings_mute_label" msgid="554682549917429396">"ҮНСҮЗ"</string>
+ <string name="status_bar_settings_auto_brightness_label" msgid="511453614962324674">"АВТО"</string>
+ <string name="status_bar_settings_notifications" msgid="397146176280905137">"Эскертмелер"</string>
+ <string name="bluetooth_tethered" msgid="7094101612161133267">"Bluetooth жалгашты"</string>
<string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"Киргизүү ыкмасын тууралоо"</string>
<string name="status_bar_use_physical_keyboard" msgid="7551903084416057810">"Аппараттык тергич"</string>
<string name="usb_device_permission_prompt" msgid="834698001271562057">"<xliff:g id="APPLICATION">%1$s</xliff:g> колдонмосуна USB түзмөккө жеткенге уруксат берилсинби?"</string>
<string name="usb_accessory_permission_prompt" msgid="5171775411178865750">"<xliff:g id="APPLICATION">%1$s</xliff:g> колдонмосуна USB аксессуарына жеткенге уруксат берилсинби?"</string>
- <!-- no translation found for usb_device_confirm_prompt (5161205258635253206) -->
- <skip />
- <!-- no translation found for usb_accessory_confirm_prompt (3808984931830229888) -->
- <skip />
+ <string name="usb_device_confirm_prompt" msgid="5161205258635253206">"USB түзмөк туташканда <xliff:g id="ACTIVITY">%1$s</xliff:g> ачылсынбы?"</string>
+ <string name="usb_accessory_confirm_prompt" msgid="3808984931830229888">"USB шайманы туташканда <xliff:g id="ACTIVITY">%1$s</xliff:g> ачылсынбы?"</string>
<string name="usb_accessory_uri_prompt" msgid="513450621413733343">"Эч бир орнотулган колдонмо USB аксессуар м-н иштебейт. Кенен маалыматтар: <xliff:g id="URL">%1$s</xliff:g>"</string>
- <!-- no translation found for title_usb_accessory (4966265263465181372) -->
- <skip />
- <!-- no translation found for label_view (6304565553218192990) -->
- <skip />
- <!-- no translation found for always_use_device (1450287437017315906) -->
- <skip />
- <!-- no translation found for always_use_accessory (1210954576979621596) -->
- <skip />
+ <string name="title_usb_accessory" msgid="4966265263465181372">"USB шайманы"</string>
+ <string name="label_view" msgid="6304565553218192990">"Карап көрүү"</string>
+ <string name="always_use_device" msgid="1450287437017315906">"USB түзмөгү үчүн демейки боюнча колдонулсун"</string>
+ <string name="always_use_accessory" msgid="1210954576979621596">"Бул USB шайманы үчүн демейки боюнча колдонулсун"</string>
<string name="usb_debugging_title" msgid="4513918393387141949">"USB аркылуу жөндөөгө уруксат берилсинби?"</string>
<string name="usb_debugging_message" msgid="2220143855912376496">"Компүтердин RSA ачкычынын контролдук суммасы:\n<xliff:g id="FINGERPRINT">%1$s</xliff:g>"</string>
<string name="usb_debugging_always" msgid="303335496705863070">"Бул компүтерден дайыма уруксат берилсин"</string>
<string name="usb_debugging_secondary_user_title" msgid="6353808721761220421">"USB мүчүлүштүктөрүн оңдоого уруксат жок"</string>
<string name="usb_debugging_secondary_user_message" msgid="6011931347142270156">"Учурда ушул түзмөккө кирген колдонуучу USB мүчүлүштүктөрүн оңдоо функциясын күйгүзө албайт. Бул функцияны урунуу үчүн, негизги колдонуучунун каттоо эсебине которулуңуз “<xliff:g id="NAME">%s</xliff:g>”."</string>
- <!-- no translation found for compat_mode_on (6623839244840638213) -->
- <skip />
- <!-- no translation found for compat_mode_off (4434467572461327898) -->
- <skip />
+ <string name="compat_mode_on" msgid="6623839244840638213">"Экрнд тлтр ү. чен өлч өзг"</string>
+ <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>
@@ -95,12 +74,9 @@
<string name="screenshot_saved_text" msgid="1152839647677558815">"Тийип, скриншотту көрүңүз."</string>
<string name="screenshot_failed_title" msgid="705781116746922771">"Скриншот кылынбай жатат."</string>
<string name="screenshot_failed_text" msgid="1260203058661337274">"Сактагыч орду чектелүү болгондуктан скриншот тарта албайт, же буга колдонмо же ишканаңыз тарабынан уруксат жок."</string>
- <!-- no translation found for usb_preference_title (6551050377388882787) -->
- <skip />
- <!-- no translation found for use_mtp_button_title (4333504413563023626) -->
- <skip />
- <!-- no translation found for use_ptp_button_title (7517127540301625751) -->
- <skip />
+ <string name="usb_preference_title" msgid="6551050377388882787">"USB менен файл өткөрүү мүмкүнчүлүктөрү"</string>
+ <string name="use_mtp_button_title" msgid="4333504413563023626">"Медиа ойноткуч катары кошуу (MTP)"</string>
+ <string name="use_ptp_button_title" msgid="7517127540301625751">"Камера катары кошуу (PTP)"</string>
<string name="installer_cd_button_title" msgid="2312667578562201583">"MacOS үчүн Android File Transfer колдонмосун орнотуу"</string>
<string name="accessibility_back" msgid="567011538994429120">"Артка"</string>
<string name="accessibility_home" msgid="8217216074895377641">"Үйгө"</string>
@@ -118,8 +94,7 @@
<string name="voice_assist_label" msgid="3956854378310019854">"үн жардамчысысын ачуу"</string>
<string name="camera_label" msgid="7261107956054836961">"камераны ачуу"</string>
<string name="recents_caption_resize" msgid="3517056471774958200">"Жаңы тапшырманын планын тандаңыз"</string>
- <!-- no translation found for cancel (6442560571259935130) -->
- <skip />
+ <string name="cancel" msgid="6442560571259935130">"Жокко чыгаруу"</string>
<string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"Масштабды сыйыштыруу баскычы."</string>
<string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"Кичинекейди чоң экранга масштабдоо."</string>
<string name="accessibility_bluetooth_connected" msgid="2707027633242983370">"Bluetooth байланышта"</string>
@@ -350,6 +325,8 @@
<string name="interruption_level_priority_twoline" msgid="1564715335217164124">"Артыкчылыктуу\nгана"</string>
<string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"Ойготкучтар\nгана"</string>
<string name="keyguard_indication_charging_time" msgid="1757251776872835768">"Кубатталууда (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> толгонго чейин)"</string>
+ <string name="keyguard_indication_charging_time_fast" msgid="9018981952053914986">"Тез кубатталууда (толгонго чейин <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> калды)"</string>
+ <string name="keyguard_indication_charging_time_slowly" msgid="955252797961724952">"Жай кубатталууда (толгонго чейин <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> калды)"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="7305948938141024937">"Колдонуучуну которуу"</string>
<string name="accessibility_multi_user_switch_switcher_with_current" msgid="8434880595284601601">"Колдонуучуну күйгүзүү, учурдагы колдонуучу <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_inactive" msgid="1424081831468083402">"Учурдагы колдонуучу <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
@@ -451,4 +428,7 @@
<string name="tuner_toast" msgid="603429811084428439">"Куттуктайбыз! Жөндөөлөргө System UI Tuner кошулду"</string>
<string name="remove_from_settings" msgid="8389591916603406378">"Жөндөөлөрдөн алып салуу"</string>
<string name="remove_from_settings_prompt" msgid="6069085993355887748">"System UI Tuner Жөндөөлөрдөн алынып салынып, анын бардык функциялары токтотулсунбу?"</string>
+ <string name="enable_bluetooth_title" msgid="5027037706500635269">"Bluetooth күйгүзүлсүнбү?"</string>
+ <string name="enable_bluetooth_message" msgid="9106595990708985385">"Баскычтобуңузду планшетиңизге туташтыруу үчүн, адегенде Bluetooth\'ту күйгүзүшүңүз керек."</string>
+ <string name="enable_bluetooth_confirmation_ok" msgid="6258074250948309715">"Күйгүзүү"</string>
</resources>
diff --git a/packages/SystemUI/res/values-lo-rLA/strings.xml b/packages/SystemUI/res/values-lo-rLA/strings.xml
index 0d33dcb..fba46b2 100644
--- a/packages/SystemUI/res/values-lo-rLA/strings.xml
+++ b/packages/SystemUI/res/values-lo-rLA/strings.xml
@@ -265,7 +265,7 @@
<string name="quick_settings_wifi_no_network" msgid="2221993077220856376">"ບໍ່ມີເຄືອຂ່າຍ"</string>
<string name="quick_settings_wifi_off_label" msgid="7558778100843885864">"Wi-Fi ປິດ"</string>
<string name="quick_settings_wifi_detail_empty_text" msgid="269990350383909226">"ບໍ່ມີເຄືອຂ່າຍ Wi-Fi ຢູ່"</string>
- <string name="quick_settings_cast_title" msgid="7709016546426454729">"ຄາສທ໌"</string>
+ <string name="quick_settings_cast_title" msgid="7709016546426454729">"ການສົ່ງສັນຍານ"</string>
<string name="quick_settings_casting" msgid="6601710681033353316">"ກຳລັງສົ່ງສັນຍານ"</string>
<string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"ອຸປະກອນບໍ່ມີຊື່"</string>
<string name="quick_settings_cast_device_default_description" msgid="2484573682378634413">"ພ້ອມສົ່ງສັນຍານແລ້ວ"</string>
@@ -325,6 +325,8 @@
<string name="interruption_level_priority_twoline" msgid="1564715335217164124">"ບຸລິມະສິດ\nເທົ່ານັ້ນ"</string>
<string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"ໂມງປຸກ\nເທົ່ານັ້ນ"</string>
<string name="keyguard_indication_charging_time" msgid="1757251776872835768">"ກຳລັງສາກໄຟ (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> ກວ່າຈະເຕັມ)"</string>
+ <string name="keyguard_indication_charging_time_fast" msgid="9018981952053914986">"ກຳລັງສາກໄຟ (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> ກວ່າຈະເຕັມ)"</string>
+ <string name="keyguard_indication_charging_time_slowly" msgid="955252797961724952">"ກຳລັງສາກໄຟ (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> ກວ່າຈະເຕັມ)"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="7305948938141024937">"ສະລັບຜູ່ໃຊ້"</string>
<string name="accessibility_multi_user_switch_switcher_with_current" msgid="8434880595284601601">"ປ່ຽນຜູ່ໃຊ້, ຜູ່ໃຊ້ປະຈຸບັນ <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_inactive" msgid="1424081831468083402">"ຜູ້ໃຊ້ປະຈຸບັນ <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
@@ -426,4 +428,7 @@
<string name="tuner_toast" msgid="603429811084428439">"ຍິນດີດ້ວຍ! System UI Tuner ໄດ້ຖືກເພີ່ມໃສ່ການຕັ້ງຄ່າແລ້ວ"</string>
<string name="remove_from_settings" msgid="8389591916603406378">"ເອົາອອກຈາກການຕັ້ງຄ່າ"</string>
<string name="remove_from_settings_prompt" msgid="6069085993355887748">"ເອົາ System UI Tuner ອອກຈາກການຕັ້ງຄ່າ ແລະຢຸດການໃຊ້ທຸກຄຸນສົມບັດໃຊ້ງານຂອງມັນ?"</string>
+ <string name="enable_bluetooth_title" msgid="5027037706500635269">"ເປີດໃຊ້ Bluetooth ບໍ່?"</string>
+ <string name="enable_bluetooth_message" msgid="9106595990708985385">"ເພື່ອເຊື່ອມຕໍ່ແປ້ນພິມຂອງທ່ານກັບແທັບເລັດຂອງທ່ານ, ກ່ອນອື່ນໝົດທ່ານຕ້ອງເປີດ Bluetooth."</string>
+ <string name="enable_bluetooth_confirmation_ok" msgid="6258074250948309715">"ເປີດ"</string>
</resources>
diff --git a/packages/SystemUI/res/values-lt/strings.xml b/packages/SystemUI/res/values-lt/strings.xml
index 54ee52c..96038c0 100644
--- a/packages/SystemUI/res/values-lt/strings.xml
+++ b/packages/SystemUI/res/values-lt/strings.xml
@@ -327,6 +327,8 @@
<string name="interruption_level_priority_twoline" msgid="1564715335217164124">"Tik\nprioritetiniai"</string>
<string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"Tik\nsignalai"</string>
<string name="keyguard_indication_charging_time" msgid="1757251776872835768">"Kraunama (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> iki visiško įkrovimo)"</string>
+ <string name="keyguard_indication_charging_time_fast" msgid="9018981952053914986">"Greitai kraunama (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> iki visiško įkrovimo)"</string>
+ <string name="keyguard_indication_charging_time_slowly" msgid="955252797961724952">"Lėtai kraunama (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> iki visiško įkrovimo)"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="7305948938141024937">"Perjungti naudotoją"</string>
<string name="accessibility_multi_user_switch_switcher_with_current" msgid="8434880595284601601">"Perjungti naudotoją, dabartinis naudotojas <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_inactive" msgid="1424081831468083402">"Dabartinis naudotojas <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
@@ -428,4 +430,7 @@
<string name="tuner_toast" msgid="603429811084428439">"Sveikiname! Sistemos naudotojo sąsajos derinimo priemonė pridėta prie nustatymų"</string>
<string name="remove_from_settings" msgid="8389591916603406378">"Pašalinti iš nustatymų"</string>
<string name="remove_from_settings_prompt" msgid="6069085993355887748">"Ar norite pašalinti sistemos naudotojo sąsajos derinimo priemonę iš nustatymų ir nebenaudoti jokių jos funkcijų?"</string>
+ <string name="enable_bluetooth_title" msgid="5027037706500635269">"Įjungti „Bluetooth“?"</string>
+ <string name="enable_bluetooth_message" msgid="9106595990708985385">"Kad galėtumėte prijungti klaviatūrą prie planšetinio kompiuterio, pirmiausia turite įjungti „Bluetooth“."</string>
+ <string name="enable_bluetooth_confirmation_ok" msgid="6258074250948309715">"Įjungti"</string>
</resources>
diff --git a/packages/SystemUI/res/values-lv/strings.xml b/packages/SystemUI/res/values-lv/strings.xml
index 4e699e3..f2d5eb1 100644
--- a/packages/SystemUI/res/values-lv/strings.xml
+++ b/packages/SystemUI/res/values-lv/strings.xml
@@ -326,6 +326,8 @@
<string name="interruption_level_priority_twoline" msgid="1564715335217164124">"Tikai\nprioritārie"</string>
<string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"Tikai\nsignāli"</string>
<string name="keyguard_indication_charging_time" msgid="1757251776872835768">"Notiek uzlāde (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> līdz pilnīgai uzlādei)"</string>
+ <string name="keyguard_indication_charging_time_fast" msgid="9018981952053914986">"Ātra uzlāde (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> līdz pilnīgai uzlādei)"</string>
+ <string name="keyguard_indication_charging_time_slowly" msgid="955252797961724952">"Lēna uzlāde (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> līdz pilnīgai uzlādei)"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="7305948938141024937">"Mainīt lietotāju"</string>
<string name="accessibility_multi_user_switch_switcher_with_current" msgid="8434880595284601601">"Pārslēgt lietotāju; pašreizējais lietotājs: <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_inactive" msgid="1424081831468083402">"Pašreizējais lietotājs: <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
@@ -427,4 +429,7 @@
<string name="tuner_toast" msgid="603429811084428439">"Apsveicam! Sistēmas saskarnes regulators ir pievienots iestatījumiem."</string>
<string name="remove_from_settings" msgid="8389591916603406378">"Noņemt no iestatījumiem"</string>
<string name="remove_from_settings_prompt" msgid="6069085993355887748">"Vai noņemt sistēmas saskarnes regulatoru no iestatījumiem un pārtraukt izmantot visas tā funkcijas?"</string>
+ <string name="enable_bluetooth_title" msgid="5027037706500635269">"Vai ieslēgt Bluetooth savienojumu?"</string>
+ <string name="enable_bluetooth_message" msgid="9106595990708985385">"Lai pievienotu tastatūru planšetdatoram, vispirms ir jāieslēdz Bluetooth savienojums."</string>
+ <string name="enable_bluetooth_confirmation_ok" msgid="6258074250948309715">"Ieslēgt"</string>
</resources>
diff --git a/packages/SystemUI/res/values-mk-rMK/strings.xml b/packages/SystemUI/res/values-mk-rMK/strings.xml
index 6a85590..47912b9 100644
--- a/packages/SystemUI/res/values-mk-rMK/strings.xml
+++ b/packages/SystemUI/res/values-mk-rMK/strings.xml
@@ -42,7 +42,7 @@
<string name="battery_saver_confirmation_title" msgid="5299585433050361634">"Дали да се вклучи штедачот на батерија?"</string>
<string name="battery_saver_confirmation_ok" msgid="7507968430447930257">"Вклучи"</string>
<string name="battery_saver_start_action" msgid="5576697451677486320">"Вклучете го штедачот на батерија"</string>
- <string name="status_bar_settings_settings_button" msgid="3023889916699270224">"Подесувања"</string>
+ <string name="status_bar_settings_settings_button" msgid="3023889916699270224">"Поставки"</string>
<string name="status_bar_settings_wifi_button" msgid="1733928151698311923">"Wi-Fi"</string>
<string name="status_bar_settings_auto_rotation" msgid="3790482541357798421">"Автоматско ротирање на екранот"</string>
<string name="status_bar_settings_mute_label" msgid="554682549917429396">"ИСКЛ."</string>
@@ -150,10 +150,8 @@
<string name="accessibility_airplane_mode" msgid="834748999790763092">"Режим на работа во авион."</string>
<string name="accessibility_no_sims" msgid="3957997018324995781">"Нема СИМ-картичка"</string>
<string name="accessibility_carrier_network_change_mode" msgid="4017301580441304305">"Променување на мрежата на операторот."</string>
- <!-- String.format failed for translation -->
- <!-- no translation found for accessibility_battery_level (7451474187113371965) -->
- <skip />
- <string name="accessibility_settings_button" msgid="799583911231893380">"Подесувања на систем."</string>
+ <string name="accessibility_battery_level" msgid="7451474187113371965">"Батерија <xliff:g id="NUMBER">%d</xliff:g> проценти."</string>
+ <string name="accessibility_settings_button" msgid="799583911231893380">"Поставки на систем."</string>
<string name="accessibility_notifications_button" msgid="4498000369779421892">"Известувања"</string>
<string name="accessibility_remove_notification" msgid="3603099514902182350">"Избриши известување."</string>
<string name="accessibility_gps_enabled" msgid="3511469499240123019">"ГПС е овозможен."</string>
@@ -257,7 +255,7 @@
<string name="quick_settings_media_device_label" msgid="1302906836372603762">"Медиумски уред"</string>
<string name="quick_settings_rssi_label" msgid="7725671335550695589">"RSSI"</string>
<string name="quick_settings_rssi_emergency_only" msgid="2713774041672886750">"Само итни повици"</string>
- <string name="quick_settings_settings_label" msgid="5326556592578065401">"Подесувања"</string>
+ <string name="quick_settings_settings_label" msgid="5326556592578065401">"Поставки"</string>
<string name="quick_settings_time_label" msgid="4635969182239736408">"Време"</string>
<string name="quick_settings_user_label" msgid="5238995632130897840">"Јас"</string>
<string name="quick_settings_user_title" msgid="4467690427642392403">"Корисник"</string>
@@ -327,6 +325,8 @@
<string name="interruption_level_priority_twoline" msgid="1564715335217164124">"Само\nприоритетни"</string>
<string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"Само\nаларми"</string>
<string name="keyguard_indication_charging_time" msgid="1757251776872835768">"Се полни (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> додека не се наполни)"</string>
+ <string name="keyguard_indication_charging_time_fast" msgid="9018981952053914986">"Брзо полнење (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> додека не се наполни)"</string>
+ <string name="keyguard_indication_charging_time_slowly" msgid="955252797961724952">"Бавно полнење (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> додека не се наполни)"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="7305948938141024937">"Промени го корисникот"</string>
<string name="accessibility_multi_user_switch_switcher_with_current" msgid="8434880595284601601">"Промени го корисникот, тековен корисник <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_inactive" msgid="1424081831468083402">"Тековен корисник <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
@@ -428,4 +428,7 @@
<string name="tuner_toast" msgid="603429811084428439">"Честито! Го додадовте Адаптерот на УИ на системот на Поставки"</string>
<string name="remove_from_settings" msgid="8389591916603406378">"Отстрани од поставки"</string>
<string name="remove_from_settings_prompt" msgid="6069085993355887748">"Да се отстрани Адаптерот на УИ на системот од Поставки и да престанат да се користат сите негови функции?"</string>
+ <string name="enable_bluetooth_title" msgid="5027037706500635269">"Да се вклучи Bluetooth?"</string>
+ <string name="enable_bluetooth_message" msgid="9106595990708985385">"За да ја поврзете тастатурата со таблетот, најпрво треба да вклучите Bluetooth."</string>
+ <string name="enable_bluetooth_confirmation_ok" msgid="6258074250948309715">"Вклучи"</string>
</resources>
diff --git a/packages/SystemUI/res/values-ml-rIN/strings.xml b/packages/SystemUI/res/values-ml-rIN/strings.xml
index eeb0106..4731ba1 100644
--- a/packages/SystemUI/res/values-ml-rIN/strings.xml
+++ b/packages/SystemUI/res/values-ml-rIN/strings.xml
@@ -32,7 +32,7 @@
<string name="status_bar_no_notifications_title" msgid="4755261167193833213">"അറിയിപ്പുകൾ ഒന്നുമില്ല"</string>
<string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"നടന്നുകൊണ്ടിരിക്കുന്നവ"</string>
<string name="status_bar_latest_events_title" msgid="6594767438577593172">"അറിയിപ്പുകൾ"</string>
- <string name="battery_low_title" msgid="6456385927409742437">"ബാറ്ററി നില കുറവാണ്"</string>
+ <string name="battery_low_title" msgid="6456385927409742437">"ബാറ്ററി കുറവാണ്"</string>
<string name="battery_low_percent_format" msgid="2900940511201380775">"<xliff:g id="PERCENTAGE">%s</xliff:g> ശേഷിക്കുന്നു"</string>
<string name="battery_low_percent_format_saver_started" msgid="6859235584035338833">"<xliff:g id="PERCENTAGE">%s</xliff:g> ശേഷിക്കുന്നു. ബാറ്ററി സേവർ ഓണാണ്."</string>
<string name="invalid_charger" msgid="4549105996740522523">"USB ചാർജ്ജുചെയ്യൽ പിന്തുണയ്ക്കുന്നില്ല.\nഅതിന്റെ അനുബന്ധ ചാർജ്ജർ മാത്രം ഉപയോഗിക്കുക."</string>
@@ -325,6 +325,8 @@
<string name="interruption_level_priority_twoline" msgid="1564715335217164124">"മുൻഗണന\nമാത്രം"</string>
<string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"അലാറങ്ങൾ\nമാത്രം"</string>
<string name="keyguard_indication_charging_time" msgid="1757251776872835768">"ചാർജ്ജുചെയ്യുന്നു (പൂർണ്ണമാകുന്നതിന്, <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>)"</string>
+ <string name="keyguard_indication_charging_time_fast" msgid="9018981952053914986">"വേഗത്തിൽ ചാർജുചെയ്യുന്നു (പൂർണ്ണമാകാൻ <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>)"</string>
+ <string name="keyguard_indication_charging_time_slowly" msgid="955252797961724952">"പതുക്കെ ചാർജുചെയ്യുന്നു (പൂർണ്ണമാകാൻ <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>)"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="7305948938141024937">"ഉപയോക്താവ് മാറുക"</string>
<string name="accessibility_multi_user_switch_switcher_with_current" msgid="8434880595284601601">"ഉപയോക്താവിനെ മാറ്റുക, <xliff:g id="CURRENT_USER_NAME">%s</xliff:g> എന്നയാളാണ് നിലവിലുള്ള ഉപയോക്താവ്"</string>
<string name="accessibility_multi_user_switch_inactive" msgid="1424081831468083402">"നിലവിലെ ഉപയോക്താവ് <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
@@ -426,4 +428,7 @@
<string name="tuner_toast" msgid="603429811084428439">"അഭിനന്ദനങ്ങൾ! ക്രമീകരണത്തിലേക്ക് സിസ്റ്റം UI ട്യൂണർ ചേർത്തിരിക്കുന്നു"</string>
<string name="remove_from_settings" msgid="8389591916603406378">"ക്രമീകരണത്തിൽ നിന്ന് നീക്കംചെയ്യുക"</string>
<string name="remove_from_settings_prompt" msgid="6069085993355887748">"ക്രമീകരണത്തിൽ നിന്ന് സിസ്റ്റം UI ട്യൂണർ നീക്കംചെയ്യുകയും അതിന്റെ ഫീച്ചറുകളെല്ലാം ഉപയോഗിക്കുന്നത് നിർത്തുകയും ചെയ്യണോ?"</string>
+ <string name="enable_bluetooth_title" msgid="5027037706500635269">"Bluetooth ഓണാക്കണോ?"</string>
+ <string name="enable_bluetooth_message" msgid="9106595990708985385">"നിങ്ങളുടെ ടാബ്ലെറ്റുമായി കീബോർഡ് കണക്റ്റുചെയ്യുന്നതിന്, ആദ്യം Bluetooth ഓണാക്കേണ്ടതുണ്ട്."</string>
+ <string name="enable_bluetooth_confirmation_ok" msgid="6258074250948309715">"ഓണാക്കുക"</string>
</resources>
diff --git a/packages/SystemUI/res/values-mn-rMN/strings.xml b/packages/SystemUI/res/values-mn-rMN/strings.xml
index 5ac85ed..723cb26 100644
--- a/packages/SystemUI/res/values-mn-rMN/strings.xml
+++ b/packages/SystemUI/res/values-mn-rMN/strings.xml
@@ -323,6 +323,8 @@
<string name="interruption_level_priority_twoline" msgid="1564715335217164124">"Зөвхөн\nхамгийн чухлыг"</string>
<string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"Зөвхөн\nсэрүүлэг"</string>
<string name="keyguard_indication_charging_time" msgid="1757251776872835768">"Цэнэглэж байна (дүүргэхэд <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>)"</string>
+ <string name="keyguard_indication_charging_time_fast" msgid="9018981952053914986">"Цэнэглэж байна (дүүргэхэд <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> шаардлагатай)"</string>
+ <string name="keyguard_indication_charging_time_slowly" msgid="955252797961724952">"Цэнэглэж байна (дүүргэхэд <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> шаардлагатай)"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="7305948938141024937">"Хэрэглэгчийг сэлгэх"</string>
<string name="accessibility_multi_user_switch_switcher_with_current" msgid="8434880595284601601">"Хэрэглэгчийг сэлгэх, одоогийн хэрэглэгч <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_inactive" msgid="1424081831468083402">"Одоогийн хэрэглэгч <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
@@ -424,4 +426,7 @@
<string name="tuner_toast" msgid="603429811084428439">"Баяр хүргэе! Системийн UI Tохируулагчийг тохиргоонд нэмлээ"</string>
<string name="remove_from_settings" msgid="8389591916603406378">"Тохиргооноос устгах"</string>
<string name="remove_from_settings_prompt" msgid="6069085993355887748">"Системийн UI Тохируулагчийг тохиргооноос устгаж, үүнтэй холбоотой бүх тохиргоог ашиглахаа болих уу?"</string>
+ <string name="enable_bluetooth_title" msgid="5027037706500635269">"Bluetooth-г асаах уу?"</string>
+ <string name="enable_bluetooth_message" msgid="9106595990708985385">"Компьютерийн гараа таблетад холбохын тулд эхлээд Bluetooth-г асаана уу."</string>
+ <string name="enable_bluetooth_confirmation_ok" msgid="6258074250948309715">"Асаах"</string>
</resources>
diff --git a/packages/SystemUI/res/values-mr-rIN/strings.xml b/packages/SystemUI/res/values-mr-rIN/strings.xml
index eb726ed..857f83d 100644
--- a/packages/SystemUI/res/values-mr-rIN/strings.xml
+++ b/packages/SystemUI/res/values-mr-rIN/strings.xml
@@ -325,6 +325,8 @@
<string name="interruption_level_priority_twoline" msgid="1564715335217164124">"केवळ\nप्राधान्य"</string>
<string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"केवळ\nअलार्म"</string>
<string name="keyguard_indication_charging_time" msgid="1757251776872835768">"(<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> पूर्ण होईपर्यंत) चार्ज होत आहे"</string>
+ <string name="keyguard_indication_charging_time_fast" msgid="9018981952053914986">"(<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> पूर्ण होईपर्यंत) वेगाने चार्ज होत आहे"</string>
+ <string name="keyguard_indication_charging_time_slowly" msgid="955252797961724952">"(<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> पूर्ण होईपर्यंत) हळूहळू चार्ज होत आहे"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="7305948938141024937">"वापरकर्ता स्विच करा"</string>
<string name="accessibility_multi_user_switch_switcher_with_current" msgid="8434880595284601601">"वापरकर्ता स्विच करा, वर्तमान वापरकर्ता <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_inactive" msgid="1424081831468083402">"वर्तमान वापरकर्ता <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
@@ -401,7 +403,7 @@
<string name="system_ui_tuner" msgid="708224127392452018">"सिस्टीम UI ट्यूनर"</string>
<string name="show_battery_percentage" msgid="5444136600512968798">"एम्बेडेड बॅटरी टक्केवारी दर्शवा"</string>
<string name="show_battery_percentage_summary" msgid="3215025775576786037">"चार्ज होत नसताना स्टेटस बार चिन्हामध्ये बॅटरी पातळी टक्केवारी दर्शवा"</string>
- <string name="quick_settings" msgid="10042998191725428">"दृत सेटिंग्ज"</string>
+ <string name="quick_settings" msgid="10042998191725428">"द्रुत सेटिंग्ज"</string>
<string name="status_bar" msgid="4877645476959324760">"स्टेटस बार"</string>
<string name="demo_mode" msgid="2389163018533514619">"डेमो मोड"</string>
<string name="enable_demo_mode" msgid="4844205668718636518">"डेमो मोड सक्षम करा"</string>
@@ -426,4 +428,7 @@
<string name="tuner_toast" msgid="603429811084428439">"अभिनंदन! सिस्टीम UI ट्यूनर सेटिंग्जमध्ये जोडले गेले आहे"</string>
<string name="remove_from_settings" msgid="8389591916603406378">"सेटिंग्ज मधून काढा"</string>
<string name="remove_from_settings_prompt" msgid="6069085993355887748">"सेटिंग्ज मधून सिस्टीम UI ट्यूनर काढून त्याची सर्व वैशिष्ट्ये वापरणे थांबवायचे?"</string>
+ <string name="enable_bluetooth_title" msgid="5027037706500635269">"ब्लूटुथ सुरू करायचे?"</string>
+ <string name="enable_bluetooth_message" msgid="9106595990708985385">"आपला कीबोर्ड आपल्या टॅब्लेटसह कनेक्ट करण्यासाठी, आपल्याला प्रथम ब्लूटुथ चालू करणे आवश्यक आहे."</string>
+ <string name="enable_bluetooth_confirmation_ok" msgid="6258074250948309715">"चालू करा"</string>
</resources>
diff --git a/packages/SystemUI/res/values-ms-rMY/strings.xml b/packages/SystemUI/res/values-ms-rMY/strings.xml
index 9caa935..471bf68 100644
--- a/packages/SystemUI/res/values-ms-rMY/strings.xml
+++ b/packages/SystemUI/res/values-ms-rMY/strings.xml
@@ -325,6 +325,8 @@
<string name="interruption_level_priority_twoline" msgid="1564715335217164124">"Keutamaan\nsahaja"</string>
<string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"Penggera\nsahaja"</string>
<string name="keyguard_indication_charging_time" msgid="1757251776872835768">"Mengecas (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> sehingga penuh)"</string>
+ <string name="keyguard_indication_charging_time_fast" msgid="9018981952053914986">"Mengecas cepat (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> sehingga penuh)"</string>
+ <string name="keyguard_indication_charging_time_slowly" msgid="955252797961724952">"Mengecas perlahan (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> sehingga penuh)"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="7305948938141024937">"Tukar pengguna"</string>
<string name="accessibility_multi_user_switch_switcher_with_current" msgid="8434880595284601601">"Tukar pengguna, pengguna semasa <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_inactive" msgid="1424081831468083402">"Pengguna semasa <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
@@ -426,4 +428,7 @@
<string name="tuner_toast" msgid="603429811084428439">"Tahniah! Penala UI Sistem telah ditambahkan pada Tetapan"</string>
<string name="remove_from_settings" msgid="8389591916603406378">"Alih keluar daripada Tetapan"</string>
<string name="remove_from_settings_prompt" msgid="6069085993355887748">"Alih keluar Penala UI Sistem daripada Tetapan dan berhenti menggunakan semua cirinya?"</string>
+ <string name="enable_bluetooth_title" msgid="5027037706500635269">"Hidupkan Bluetooth?"</string>
+ <string name="enable_bluetooth_message" msgid="9106595990708985385">"Untuk menyambungkan papan kekunci anda dengan tablet, anda perlu menghidupkan Bluetooth terlebih dahulu."</string>
+ <string name="enable_bluetooth_confirmation_ok" msgid="6258074250948309715">"Hidupkan"</string>
</resources>
diff --git a/packages/SystemUI/res/values-my-rMM/strings.xml b/packages/SystemUI/res/values-my-rMM/strings.xml
index 0e5622e..1f7ff95 100644
--- a/packages/SystemUI/res/values-my-rMM/strings.xml
+++ b/packages/SystemUI/res/values-my-rMM/strings.xml
@@ -325,6 +325,8 @@
<string name="interruption_level_priority_twoline" msgid="1564715335217164124">"ဦးစားပေးမှု\nသာ"</string>
<string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"နှိုးစက်များ\nသာ"</string>
<string name="keyguard_indication_charging_time" msgid="1757251776872835768">"(<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> အပြည့် အထိ) အားသွင်းနေ"</string>
+ <string name="keyguard_indication_charging_time_fast" msgid="9018981952053914986">"လျှင်မြန်စွာအားသွင်းခြင်း (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> ပြည့်သည်အထိ)"</string>
+ <string name="keyguard_indication_charging_time_slowly" msgid="955252797961724952">"နှေးကွေးစွာ အားသွင်းခြင်း (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> ပြည့်သည်အထိ)"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="7305948938141024937">"အသုံးပြုသူကို ပြောင်းလဲရန်"</string>
<string name="accessibility_multi_user_switch_switcher_with_current" msgid="8434880595284601601">"အသုံးပြုသူကို ပြောင်းရန်၊ လက်ရှိ အသုံးပြုသူ <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_inactive" msgid="1424081831468083402">"လတ်တလော သုံးစွဲသူ <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
@@ -426,4 +428,7 @@
<string name="tuner_toast" msgid="603429811084428439">"ဂုဏ်ပြုပါရစေ! စနစ် UI ဖမ်းစက်ကို ဆက်တင်ထဲသို့ ထည့်ပြီးပြီ။"</string>
<string name="remove_from_settings" msgid="8389591916603406378">"ဆက်တင် အထဲမှ ဖယ်ရှားရန်"</string>
<string name="remove_from_settings_prompt" msgid="6069085993355887748">"ဆက်တင် အထဲမှ စနစ် UI ဖမ်းစက်ကို ဖယ်ရှားလျက် ၎င်း၏ အင်္ဂါရပ်များ အားလုံး အသုံးပြုမှု ရပ်တန့်ရမလား?"</string>
+ <string name="enable_bluetooth_title" msgid="5027037706500635269">"ဘလူးတုသ် ဖွင့်ရမလား။"</string>
+ <string name="enable_bluetooth_message" msgid="9106595990708985385">"ကီးဘုတ်ကို တပ်ဘလက်နှင့် ချိတ်ဆက်ရန်၊ ပမထဦးစွာ ဘလူးတုသ်ကို ဖွင့်ပါ။"</string>
+ <string name="enable_bluetooth_confirmation_ok" msgid="6258074250948309715">"ဖွင့်ပါ"</string>
</resources>
diff --git a/packages/SystemUI/res/values-nb/strings.xml b/packages/SystemUI/res/values-nb/strings.xml
index 4c55a98..e259d69 100644
--- a/packages/SystemUI/res/values-nb/strings.xml
+++ b/packages/SystemUI/res/values-nb/strings.xml
@@ -325,6 +325,8 @@
<string name="interruption_level_priority_twoline" msgid="1564715335217164124">"Bare\nPrioritet"</string>
<string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"Bare\nalarmer"</string>
<string name="keyguard_indication_charging_time" msgid="1757251776872835768">"Lader (fulladet om <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>)"</string>
+ <string name="keyguard_indication_charging_time_fast" msgid="9018981952053914986">"Lader raskt (fulladet om <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>)"</string>
+ <string name="keyguard_indication_charging_time_slowly" msgid="955252797961724952">"Lader sakte (fulladet om <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>)"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="7305948938141024937">"Bytt bruker"</string>
<string name="accessibility_multi_user_switch_switcher_with_current" msgid="8434880595284601601">"Bytt bruker, gjeldende bruker er <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_inactive" msgid="1424081831468083402">"Gjeldende bruker: <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
@@ -376,7 +378,7 @@
<string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"Enheten forblir låst til du låser den opp manuelt"</string>
<string name="hidden_notifications_title" msgid="7139628534207443290">"Motta varsler raskere"</string>
<string name="hidden_notifications_text" msgid="2326409389088668981">"Se dem før du låser opp"</string>
- <string name="hidden_notifications_cancel" msgid="3690709735122344913">"Nei takk"</string>
+ <string name="hidden_notifications_cancel" msgid="3690709735122344913">"Nei, takk"</string>
<string name="hidden_notifications_setup" msgid="41079514801976810">"Konfigurer"</string>
<string name="notification_expand_button_text" msgid="1037425494153780718">"Se alle"</string>
<string name="notification_collapse_button_text" msgid="6883253262134328057">"Skjul alle"</string>
@@ -388,7 +390,7 @@
<string name="screen_pinning_description" msgid="1346522416878235405">"På denne måten blir skjermen synlig frem til du låser den opp. Trykk på og hold inne Tilbake og Oversikt samtidig for å låse opp."</string>
<string name="screen_pinning_description_accessible" msgid="8518446209564202557">"På denne måten blir skjermen synlig frem til du låser den opp. Trykk på og hold inne Tilbake og Oversikt for å låse opp."</string>
<string name="screen_pinning_positive" msgid="3783985798366751226">"Skjønner"</string>
- <string name="screen_pinning_negative" msgid="3741602308343880268">"Nei takk"</string>
+ <string name="screen_pinning_negative" msgid="3741602308343880268">"Nei, takk"</string>
<string name="quick_settings_reset_confirmation_title" msgid="748792586749897883">"Vil du skjule <xliff:g id="TILE_LABEL">%1$s</xliff:g>?"</string>
<string name="quick_settings_reset_confirmation_message" msgid="2235970126803317374">"Den vises igjen neste gang du slår den på i innstillingene."</string>
<string name="quick_settings_reset_confirmation_button" msgid="2660339101868367515">"Skjul"</string>
@@ -426,4 +428,7 @@
<string name="tuner_toast" msgid="603429811084428439">"Gratulerer! System UI Tuner er lagt til i Innstillinger"</string>
<string name="remove_from_settings" msgid="8389591916603406378">"Fjern fra Innstillinger"</string>
<string name="remove_from_settings_prompt" msgid="6069085993355887748">"Vil du fjerne System UI Tuner fra Innstillinger og slutte å bruke alle de tilknyttede funksjonene?"</string>
+ <string name="enable_bluetooth_title" msgid="5027037706500635269">"Vil du slå på Bluetooth?"</string>
+ <string name="enable_bluetooth_message" msgid="9106595990708985385">"For å koble tastaturet til nettbrettet ditt må du først slå på Bluetooth."</string>
+ <string name="enable_bluetooth_confirmation_ok" msgid="6258074250948309715">"Slå på"</string>
</resources>
diff --git a/packages/SystemUI/res/values-ne-rNP/strings.xml b/packages/SystemUI/res/values-ne-rNP/strings.xml
index 9d5a679..05a9205 100644
--- a/packages/SystemUI/res/values-ne-rNP/strings.xml
+++ b/packages/SystemUI/res/values-ne-rNP/strings.xml
@@ -325,6 +325,8 @@
<string name="interruption_level_priority_twoline" msgid="1564715335217164124">"प्राथमिकता \nमात्र"</string>
<string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"अलार्महरू \nमात्र"</string>
<string name="keyguard_indication_charging_time" msgid="1757251776872835768">"चार्ज हुँदै (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> पूर्ण भएसम्म)"</string>
+ <string name="keyguard_indication_charging_time_fast" msgid="9018981952053914986">"छिटो चार्ज हुँदै (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> पूर्ण नभएसम्म)"</string>
+ <string name="keyguard_indication_charging_time_slowly" msgid="955252797961724952">"बिस्तारै चार्ज हुँदै (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> पूर्ण नभएसम्म)"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="7305948938141024937">"प्रयोगकर्ता फेर्नुहोस्"</string>
<string name="accessibility_multi_user_switch_switcher_with_current" msgid="8434880595284601601">"प्रयोगकर्ता, हालको प्रयोगकर्ता <xliff:g id="CURRENT_USER_NAME">%s</xliff:g> मा स्विच गर्नुहोस्"</string>
<string name="accessibility_multi_user_switch_inactive" msgid="1424081831468083402">"हालको प्रयोगकर्ता <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
@@ -372,7 +374,7 @@
<string name="monitoring_description_app_personal" msgid="484599052118316268">"तपाईँ <xliff:g id="APPLICATION">%1$s</xliff:g> सँग जडित हुनुहुन्छ जसले इ-मेल, अनुप्रयोगहरू र वेबसाइट लगायतका तपाईँको निजी नेटवर्क गतिविधिका अनुगमन गर्न सक्छ।"</string>
<string name="monitoring_description_app_work" msgid="1754325860918060897">"तपाईँको कार्य प्रोफाइल <xliff:g id="ORGANIZATION">%1$s</xliff:g> द्वारा व्यवस्थापन गरिन्छ। यो <xliff:g id="APPLICATION">%2$s</xliff:g> सँग जोडिएको छ जसले इमेल, अनुप्रयोगहरू, र वेबसाइटहरू लगायतका तपाईँका नेटवर्क गतिविधि अनुगमन गर्न सक्छ।\n\nथप जानकारीको लागि, आफ्नो प्रशासकलाई सम्पर्क गर्नुहोस्।"</string>
<string name="monitoring_description_app_personal_work" msgid="4946600443852045903">"तपाईँको कार्य प्रोफाइल <xliff:g id="ORGANIZATION">%1$s</xliff:g> द्वारा व्यवस्थापन गरिन्छ। यो <xliff:g id="APPLICATION_WORK">%2$s</xliff:g> सँग जोडिएको छ जसले इमेल, अनुप्रयोगहरू, र वेबसाइटहरू लगायतका तपाईँका नेटवर्क गतिविधि अनुगमन गर्न सक्छ।\n\nतपाईँ <xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g> सँग पनि जडित हुनुहुन्छ, जसले तपाईँको व्यक्तिगत नेटवर्क गतिविधि अनुगमन गर्न सक्छ।"</string>
- <string name="monitoring_description_vpn_app_device_owned" msgid="4970443827043261703">"तपाईंको उपकरण <xliff:g id="ORGANIZATION">%1$s</xliff:g> द्वारा व्यवस्थित गरिन्छ।\n\nतपाईंको प्रशासकले तपाईँको यन्त्र र त्यसको स्थान जानकारीमार्फत सेटिङहरू, कर्पोरेट पहुँच, अनुप्रयोगहरू, तपाईँको यन्त्रसँग सम्बद्ध डेटा र तपाईँको यन्त्रको स्थान जानकारीको अनुगमन र व्यवस्थापन गर्न सक्छ।\n\nतपाईं <xliff:g id="APPLICATION">%2$s</xliff:g> सँग जडित हुनुहुन्छ जसले इमेल, अनुप्रयोगहरू, र वेबसाइटहरू लगायतका तपाईँका नेटवर्क गतिविधिका अनुगमन गर्न सक्छ।\n\nथप जानकारीको लागि तपाईको प्रशासकलाई सम्पर्क गर्नुहोस्।"</string>
+ <string name="monitoring_description_vpn_app_device_owned" msgid="4970443827043261703">"तपाईँको उपकरण <xliff:g id="ORGANIZATION">%1$s</xliff:g> द्वारा व्यवस्थित गरिन्छ।\n\nतपाईँको प्रशासकले तपाईँको यन्त्र र त्यसको स्थान जानकारीमार्फत सेटिङहरू, कर्पोरेट पहुँच, अनुप्रयोगहरू, तपाईँको यन्त्रसँग सम्बद्ध डेटा र तपाईँको यन्त्रको स्थान जानकारीको अनुगमन र व्यवस्थापन गर्न सक्छ।\n\nतपाईँ <xliff:g id="APPLICATION">%2$s</xliff:g> सँग जडित हुनुहुन्छ जसले इमेल, अनुप्रयोगहरू, र वेबसाइटहरू लगायतका तपाईँका नेटवर्क गतिविधिका अनुगमन गर्न सक्छ।\n\nथप जानकारीको लागि तपाईको प्रशासकलाई सम्पर्क गर्नुहोस्।"</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>
@@ -385,12 +387,12 @@
<string name="accessibility_volume_expand" msgid="5946812790999244205">"विस्तार गर्नुहोस्"</string>
<string name="accessibility_volume_collapse" msgid="3609549593031810875">"संक्षिप्त पार्नुहोस्"</string>
<string name="screen_pinning_title" msgid="3273740381976175811">"पर्दा राखेका छ"</string>
- <string name="screen_pinning_description" msgid="1346522416878235405">"तपाईं अनपिन सम्म यो दृश्य मा राख्छ। छुनुहोस् र अनपिन फिर्ता र सिंहावलोकन नै समय मा पकड।"</string>
- <string name="screen_pinning_description_accessible" msgid="8518446209564202557">"तपाईं अनपिन सम्म यो दृश्य मा राख्छ। छुनुहोस् र अनपिन गर्न सिंहावलोकन पकड।"</string>
+ <string name="screen_pinning_description" msgid="1346522416878235405">"तपाईँ अनपिन सम्म यो दृश्य मा राख्छ। छुनुहोस् र अनपिन फिर्ता र सिंहावलोकन नै समय मा पकड।"</string>
+ <string name="screen_pinning_description_accessible" msgid="8518446209564202557">"तपाईँ अनपिन सम्म यो दृश्य मा राख्छ। छुनुहोस् र अनपिन गर्न सिंहावलोकन पकड।"</string>
<string name="screen_pinning_positive" msgid="3783985798366751226">"बुझेँ"</string>
<string name="screen_pinning_negative" msgid="3741602308343880268">"धन्यवाद पर्दैन"</string>
<string name="quick_settings_reset_confirmation_title" msgid="748792586749897883">"लुकाउनुहुन्छ <xliff:g id="TILE_LABEL">%1$s</xliff:g>?"</string>
- <string name="quick_settings_reset_confirmation_message" msgid="2235970126803317374">"यो तपाईं सेटिङ् मा यो बारी अर्को समय देखापर्नेछ।"</string>
+ <string name="quick_settings_reset_confirmation_message" msgid="2235970126803317374">"यो तपाईँ सेटिङ् मा यो बारी अर्को समय देखापर्नेछ।"</string>
<string name="quick_settings_reset_confirmation_button" msgid="2660339101868367515">"लुकाउनुहोस्"</string>
<string name="volumeui_prompt_message" msgid="918680947433389110">"<xliff:g id="APP_NAME">%1$s</xliff:g> भोल्यूम संवाद बन्न चाहन्छ।"</string>
<string name="volumeui_prompt_allow" msgid="7954396902482228786">"अनुमति दिनुहोस्"</string>
@@ -426,4 +428,7 @@
<string name="tuner_toast" msgid="603429811084428439">"बधाईँ छ! सेटिङहरूमा प्रणाली UI ट्युनर थप गरिएको छ"</string>
<string name="remove_from_settings" msgid="8389591916603406378">"सेटिङहरूबाट हटाउनुहोस्"</string>
<string name="remove_from_settings_prompt" msgid="6069085993355887748">"प्रणाली UI ट्युनर सेटिङहरूबाट हटाउने र यसका सबै सुविधाहरू प्रयोग गर्न रोक्ने हो?"</string>
+ <string name="enable_bluetooth_title" msgid="5027037706500635269">"ब्लुटुथ सक्रिय पार्ने हो?"</string>
+ <string name="enable_bluetooth_message" msgid="9106595990708985385">"आफ्नो ट्याब्लेटसँग किबोर्ड जोड्न, पहिले तपाईँले ब्लुटुथ सक्रिय गर्नुपर्छ।"</string>
+ <string name="enable_bluetooth_confirmation_ok" msgid="6258074250948309715">"सक्रिय पार्नुहोस्"</string>
</resources>
diff --git a/packages/SystemUI/res/values-nl/strings.xml b/packages/SystemUI/res/values-nl/strings.xml
index 33a8bdf..f19368d 100644
--- a/packages/SystemUI/res/values-nl/strings.xml
+++ b/packages/SystemUI/res/values-nl/strings.xml
@@ -23,7 +23,7 @@
<string name="status_bar_clear_all_button" msgid="7774721344716731603">"Wissen"</string>
<string name="status_bar_recent_remove_item_title" msgid="6026395868129852968">"Verwijderen uit lijst"</string>
<string name="status_bar_recent_inspect_item_title" msgid="7793624864528818569">"App-info"</string>
- <string name="status_bar_no_recent_apps" msgid="7374907845131203189">"Uw recente schermen worden hier weergegeven"</string>
+ <string name="status_bar_no_recent_apps" msgid="7374907845131203189">"Je recente schermen worden hier weergegeven"</string>
<string name="status_bar_accessibility_dismiss_recents" msgid="4576076075226540105">"Recente apps negeren"</string>
<plurals name="status_bar_accessibility_recent_apps" formatted="false" msgid="9138535907802238759">
<item quantity="other">%d schermen in Overzicht</item>
@@ -71,9 +71,9 @@
<string name="screenshot_saving_title" msgid="8242282144535555697">"Screenshot opslaan..."</string>
<string name="screenshot_saving_text" msgid="2419718443411738818">"Screenshot wordt opgeslagen."</string>
<string name="screenshot_saved_title" msgid="6461865960961414961">"Screenshot gemaakt."</string>
- <string name="screenshot_saved_text" msgid="1152839647677558815">"Raak aan om uw screenshot te bekijken."</string>
+ <string name="screenshot_saved_text" msgid="1152839647677558815">"Raak aan om je screenshot te bekijken."</string>
<string name="screenshot_failed_title" msgid="705781116746922771">"Screenshot is niet gemaakt."</string>
- <string name="screenshot_failed_text" msgid="1260203058661337274">"Kan geen screenshot maken wegens beperkte opslagruimte of omdat de app of uw organisatie dit niet toestaat."</string>
+ <string name="screenshot_failed_text" msgid="1260203058661337274">"Kan geen screenshot maken wegens beperkte opslagruimte of omdat de app of je organisatie dit niet toestaat."</string>
<string name="usb_preference_title" msgid="6551050377388882787">"Opties voor USB-bestandsoverdracht"</string>
<string name="use_mtp_button_title" msgid="4333504413563023626">"Koppelen als mediaspeler (MTP)"</string>
<string name="use_ptp_button_title" msgid="7517127540301625751">"Koppelen als camera (PTP)"</string>
@@ -88,7 +88,7 @@
<string name="accessibility_voice_assist_button" msgid="487611083884852965">"Spraakassistent"</string>
<string name="accessibility_unlock_button" msgid="128158454631118828">"Ontgrendelen"</string>
<string name="accessibility_unlock_button_fingerprint" msgid="8214125623493923751">"Knop Ontgrendelen, wacht op vingerafdruk"</string>
- <string name="accessibility_unlock_without_fingerprint" msgid="7541705575183694446">"Ontgrendelen zonder uw vingerafdruk te gebruiken"</string>
+ <string name="accessibility_unlock_without_fingerprint" msgid="7541705575183694446">"Ontgrendelen zonder je vingerafdruk te gebruiken"</string>
<string name="unlock_label" msgid="8779712358041029439">"ontgrendelen"</string>
<string name="phone_label" msgid="2320074140205331708">"telefoon openen"</string>
<string name="voice_assist_label" msgid="3956854378310019854">"spraakassistent openen"</string>
@@ -217,7 +217,7 @@
<string name="data_usage_disabled_dialog_4g_title" msgid="1601769736881078016">"4G-data zijn onderbroken"</string>
<string name="data_usage_disabled_dialog_mobile_title" msgid="4651001290947318931">"Mobiele gegevens zijn onderbroken"</string>
<string name="data_usage_disabled_dialog_title" msgid="3932437232199671967">"Gegevens zijn onderbroken"</string>
- <string name="data_usage_disabled_dialog" msgid="8453242888903772524">"Omdat de ingestelde gegevenslimiet is bereikt, heeft het apparaat het gegevensverbruik onderbroken voor de rest van deze cyclus.\n\nAls u het gegevensverbruik hervat, kan uw provider kosten in rekening brengen."</string>
+ <string name="data_usage_disabled_dialog" msgid="8453242888903772524">"Omdat de ingestelde gegevenslimiet is bereikt, heeft het apparaat het gegevensverbruik onderbroken voor de rest van deze cyclus.\n\nAls u het gegevensverbruik hervat, kan je provider kosten in rekening brengen."</string>
<string name="data_usage_disabled_dialog_enable" msgid="1412395410306390593">"Hervatten"</string>
<string name="status_bar_settings_signal_meter_disconnected" msgid="1940231521274147771">"Geen internetverbinding"</string>
<string name="status_bar_settings_signal_meter_wifi_nossid" msgid="6557486452774597820">"Verbonden via wifi"</string>
@@ -283,13 +283,13 @@
<string name="quick_settings_notifications_label" msgid="4818156442169154523">"Meldingen"</string>
<string name="quick_settings_flashlight_label" msgid="2133093497691661546">"Zaklamp"</string>
<string name="quick_settings_cellular_detail_title" msgid="8575062783675171695">"Mobiele gegevens"</string>
- <string name="quick_settings_cellular_detail_data_usage" msgid="1964260360259312002">"Gegevensgebruik"</string>
+ <string name="quick_settings_cellular_detail_data_usage" msgid="1964260360259312002">"Datagebruik"</string>
<string name="quick_settings_cellular_detail_remaining_data" msgid="722715415543541249">"Resterende gegevens"</string>
<string name="quick_settings_cellular_detail_over_limit" msgid="967669665390990427">"Limiet overschreden"</string>
<string name="quick_settings_cellular_detail_data_used" msgid="1476810587475761478">"<xliff:g id="DATA_USED">%s</xliff:g> gebruikt"</string>
<string name="quick_settings_cellular_detail_data_limit" msgid="56011158504994128">"Limiet van <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string>
<string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"Waarschuwing voor <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string>
- <string name="recents_empty_message" msgid="8682129509540827999">"Uw recente schermen worden hier weergegeven"</string>
+ <string name="recents_empty_message" msgid="8682129509540827999">"Je recente schermen worden hier weergegeven"</string>
<string name="recents_app_info_button_label" msgid="2890317189376000030">"App-informatie"</string>
<string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"scherm vastzetten"</string>
<string name="recents_search_bar_label" msgid="8074997400187836677">"zoeken"</string>
@@ -325,6 +325,8 @@
<string name="interruption_level_priority_twoline" msgid="1564715335217164124">"Alleen\nprioriteit"</string>
<string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"Alleen\nalarmen"</string>
<string name="keyguard_indication_charging_time" msgid="1757251776872835768">"Opladen (vol over <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>)"</string>
+ <string name="keyguard_indication_charging_time_fast" msgid="9018981952053914986">"Snel opladen (vol over <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>)"</string>
+ <string name="keyguard_indication_charging_time_slowly" msgid="955252797961724952">"Langzaam opladen (vol over <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>)"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="7305948938141024937">"Gebruiker wijzigen"</string>
<string name="accessibility_multi_user_switch_switcher_with_current" msgid="8434880595284601601">"Schakelen tussen gebruikers, huidige gebruiker <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_inactive" msgid="1424081831468083402">"Huidige gebruiker <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
@@ -338,7 +340,7 @@
<string name="guest_exit_guest_dialog_message" msgid="4155503224769676625">"Alle apps en gegevens in deze sessie worden verwijderd."</string>
<string name="guest_exit_guest_dialog_remove" msgid="7402231963862520531">"Verwijderen"</string>
<string name="guest_wipe_session_title" msgid="6419439912885956132">"Welkom terug, gast!"</string>
- <string name="guest_wipe_session_message" msgid="8476238178270112811">"Wilt u doorgaan met uw sessie?"</string>
+ <string name="guest_wipe_session_message" msgid="8476238178270112811">"Wilt u doorgaan met je sessie?"</string>
<string name="guest_wipe_session_wipe" msgid="5065558566939858884">"Opnieuw starten"</string>
<string name="guest_wipe_session_dontwipe" msgid="1401113462524894716">"Ja, doorgaan"</string>
<string name="guest_notification_title" msgid="1585278533840603063">"Gastgebruiker"</string>
@@ -350,7 +352,7 @@
<string name="battery_saver_notification_text" msgid="820318788126672692">"Vermindert de prestaties en achtergrondgegevens"</string>
<string name="battery_saver_notification_action_text" msgid="109158658238110382">"Accubesparing uitschakelen"</string>
<string name="notification_hidden_text" msgid="1135169301897151909">"Inhoud verborgen"</string>
- <string name="media_projection_dialog_text" msgid="3071431025448218928">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> gaat alles vastleggen dat wordt weergegeven op uw scherm."</string>
+ <string name="media_projection_dialog_text" msgid="3071431025448218928">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> gaat alles vastleggen dat wordt weergegeven op je scherm."</string>
<string name="media_projection_remember_text" msgid="3103510882172746752">"Niet opnieuw weergeven"</string>
<string name="clear_all_notifications_text" msgid="814192889771462828">"Alles wissen"</string>
<string name="media_projection_action_text" msgid="8470872969457985954">"Nu starten"</string>
@@ -363,16 +365,16 @@
<string name="monitoring_title" msgid="169206259253048106">"Netwerkcontrole"</string>
<string name="disable_vpn" msgid="4435534311510272506">"VPN uitschakelen"</string>
<string name="disconnect_vpn" msgid="1324915059568548655">"Verbinding met VPN verbreken"</string>
- <string name="monitoring_description_device_owned" msgid="5780988291898461883">"Uw apparaat wordt beheerd door <xliff:g id="ORGANIZATION">%1$s</xliff:g>.\n\nUw beheerder kan instellingen, bedrijfstoegang, apps, gegevens voor uw apparaat en locatiegegevens voor uw apparaat controleren en beheren. Neem voor meer informatie contact op met uw beheerder."</string>
- <string name="monitoring_description_vpn" msgid="4445150119515393526">"U heeft een app toestemming gegeven voor het instellen van een VPN-verbinding.\n\nMet deze app kan uw apparaat- en netwerkactiviteit worden gecontroleerd, inclusief e-mails, apps en websites."</string>
- <string name="monitoring_description_vpn_device_owned" msgid="3090670777499161246">"Uw apparaat wordt beheerd door <xliff:g id="ORGANIZATION">%1$s</xliff:g>.\n\nUw beheerder kan instellingen, bedrijfstoegang, apps, gegevens voor uw apparaat en locatiegegevens voor uw apparaat controleren en beheren.\n\nU bent verbonden met een VPN, die uw netwerkactiviteit kan controleren, waaronder e-mails, apps en websites.\n\nNeem voor meer informatie contact op met uw beheerder."</string>
- <string name="monitoring_description_vpn_profile_owned" msgid="2054949132145039290">"Uw werkprofiel wordt beheerd door <xliff:g id="ORGANIZATION">%1$s</xliff:g>.\n\nUw beheerder kan uw netwerkactiviteit controleren, inclusief e-mails, apps en websites.\n\nNeem contact op met uw beheerder voor meer informatie.\n\nU bent ook verbonden met een VPN waarmee uw netwerkactiviteit kan worden gecontroleerd."</string>
+ <string name="monitoring_description_device_owned" msgid="5780988291898461883">"Je apparaat wordt beheerd door <xliff:g id="ORGANIZATION">%1$s</xliff:g>.\n\nJe beheerder kan instellingen, bedrijfstoegang, apps, gegevens voor je apparaat en locatiegegevens voor je apparaat controleren en beheren. Neem voor meer informatie contact op met je beheerder."</string>
+ <string name="monitoring_description_vpn" msgid="4445150119515393526">"Je hebt een app toestemming gegeven voor het instellen van een VPN-verbinding.\n\nMet deze app kan je apparaat- en netwerkactiviteit worden gecontroleerd, inclusief e-mails, apps en websites."</string>
+ <string name="monitoring_description_vpn_device_owned" msgid="3090670777499161246">"Je apparaat wordt beheerd door <xliff:g id="ORGANIZATION">%1$s</xliff:g>.\n\nJe beheerder kan instellingen, bedrijfstoegang, apps, gegevens voor je apparaat en locatiegegevens voor je apparaat controleren en beheren.\n\nU bent verbonden met een VPN, die je netwerkactiviteit kan controleren, waaronder e-mails, apps en websites.\n\nNeem voor meer informatie contact op met je beheerder."</string>
+ <string name="monitoring_description_vpn_profile_owned" msgid="2054949132145039290">"Je werkprofiel wordt beheerd door <xliff:g id="ORGANIZATION">%1$s</xliff:g>.\n\nJe beheerder kan je netwerkactiviteit controleren, inclusief e-mails, apps en websites.\n\nNeem contact op met je beheerder voor meer informatie.\n\nU bent ook verbonden met een VPN waarmee je netwerkactiviteit kan worden gecontroleerd."</string>
<string name="legacy_vpn_name" msgid="6604123105765737830">"VPN"</string>
- <string name="monitoring_description_app" msgid="6259179342284742878">"U bent verbonden met <xliff:g id="APPLICATION">%1$s</xliff:g>, waarmee uw netwerkactiviteit kan worden gecontroleerd, inclusief e-mails, apps en websites."</string>
- <string name="monitoring_description_app_personal" msgid="484599052118316268">"U bent verbonden met <xliff:g id="APPLICATION">%1$s</xliff:g>, waarmee uw persoonlijke netwerkactiviteit kan worden gecontroleerd, inclusief e-mails, apps en websites."</string>
- <string name="monitoring_description_app_work" msgid="1754325860918060897">"Uw werkprofiel wordt beheerd door <xliff:g id="ORGANIZATION">%1$s</xliff:g>. Deze is verbonden met <xliff:g id="APPLICATION">%2$s</xliff:g>, waarmee uw werkgerelateerde netwerkactiviteit kan worden gecontroleerd, inclusief e-mails, apps en websites.\n\nNeem contact op met uw beheerder voor meer informatie."</string>
- <string name="monitoring_description_app_personal_work" msgid="4946600443852045903">"Uw werkprofiel wordt beheerd door <xliff:g id="ORGANIZATION">%1$s</xliff:g>. Deze is verbonden met <xliff:g id="APPLICATION_WORK">%2$s</xliff:g>, waarmee uw werkgerelateerde netwerkactiviteit kan worden gecontroleerd, inclusief e-mails, apps en websites.\n\nU bent ook verbonden met <xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g>, waarmee uw persoonlijke netwerkactiviteit kan worden gecontroleerd."</string>
- <string name="monitoring_description_vpn_app_device_owned" msgid="4970443827043261703">"Uw apparaat wordt beheerd door <xliff:g id="ORGANIZATION">%1$s</xliff:g>.\n\nUw beheerder kan instellingen, zakelijke toegang, apps, gekoppelde apparaatgegevens en locatiegegevens voor uw apparaat controleren en beheren.\n\nU bent verbonden met <xliff:g id="APPLICATION">%2$s</xliff:g> waarmee uw netwerkactiviteit kan worden gecontroleerd, inclusief e-mails, apps en websites.\n\nNeem contact op met uw beheerder voor meer informatie."</string>
+ <string name="monitoring_description_app" msgid="6259179342284742878">"U bent verbonden met <xliff:g id="APPLICATION">%1$s</xliff:g>, waarmee je netwerkactiviteit kan worden gecontroleerd, inclusief e-mails, apps en websites."</string>
+ <string name="monitoring_description_app_personal" msgid="484599052118316268">"U bent verbonden met <xliff:g id="APPLICATION">%1$s</xliff:g>, waarmee je persoonlijke netwerkactiviteit kan worden gecontroleerd, inclusief e-mails, apps en websites."</string>
+ <string name="monitoring_description_app_work" msgid="1754325860918060897">"Je werkprofiel wordt beheerd door <xliff:g id="ORGANIZATION">%1$s</xliff:g>. Deze is verbonden met <xliff:g id="APPLICATION">%2$s</xliff:g>, waarmee je werkgerelateerde netwerkactiviteit kan worden gecontroleerd, inclusief e-mails, apps en websites.\n\nNeem contact op met je beheerder voor meer informatie."</string>
+ <string name="monitoring_description_app_personal_work" msgid="4946600443852045903">"Je werkprofiel wordt beheerd door <xliff:g id="ORGANIZATION">%1$s</xliff:g>. Deze is verbonden met <xliff:g id="APPLICATION_WORK">%2$s</xliff:g>, waarmee je werkgerelateerde netwerkactiviteit kan worden gecontroleerd, inclusief e-mails, apps en websites.\n\nU bent ook verbonden met <xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g>, waarmee je persoonlijke netwerkactiviteit kan worden gecontroleerd."</string>
+ <string name="monitoring_description_vpn_app_device_owned" msgid="4970443827043261703">"Je apparaat wordt beheerd door <xliff:g id="ORGANIZATION">%1$s</xliff:g>.\n\nJe beheerder kan instellingen, zakelijke toegang, apps, gekoppelde apparaatgegevens en locatiegegevens voor je apparaat controleren en beheren.\n\nU bent verbonden met <xliff:g id="APPLICATION">%2$s</xliff:g> waarmee je netwerkactiviteit kan worden gecontroleerd, inclusief e-mails, apps en websites.\n\nNeem contact op met je beheerder voor meer informatie."</string>
<string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"Het apparaat blijft vergrendeld totdat u het handmatig ontgrendelt"</string>
<string name="hidden_notifications_title" msgid="7139628534207443290">"Sneller meldingen ontvangen"</string>
<string name="hidden_notifications_text" msgid="2326409389088668981">"Weergeven voordat u ontgrendelt"</string>
@@ -394,10 +396,10 @@
<string name="quick_settings_reset_confirmation_button" msgid="2660339101868367515">"Verbergen"</string>
<string name="volumeui_prompt_message" msgid="918680947433389110">"<xliff:g id="APP_NAME">%1$s</xliff:g> wil het volumedialoogvenster zijn."</string>
<string name="volumeui_prompt_allow" msgid="7954396902482228786">"Toestaan"</string>
- <string name="volumeui_prompt_deny" msgid="5720663643411696731">"Afwijzen"</string>
+ <string name="volumeui_prompt_deny" msgid="5720663643411696731">"Weigeren"</string>
<string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> is het volumedialoogvenster"</string>
<string name="volumeui_notification_text" msgid="1826889705095768656">"Tik hierop om het origineel te herstellen."</string>
- <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"U gebruikt uw werkprofiel"</string>
+ <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"U gebruikt je werkprofiel"</string>
<string name="system_ui_tuner" msgid="708224127392452018">"Systeem-UI-tuner"</string>
<string name="show_battery_percentage" msgid="5444136600512968798">"Percentage ingebouwde accu weergeven"</string>
<string name="show_battery_percentage_summary" msgid="3215025775576786037">"Accupercentage weergeven in het pictogram op de statusbalk wanneer er niet wordt opgeladen"</string>
@@ -412,8 +414,8 @@
<string name="status_bar_airplane" msgid="7057575501472249002">"Vliegtuigmodus"</string>
<string name="add_tile" msgid="2995389510240786221">"Tegel toevoegen"</string>
<string name="broadcast_tile" msgid="3894036511763289383">"Tegel \'Uitzenden\'"</string>
- <string name="zen_alarm_warning_indef" msgid="3482966345578319605">"U hoort uw volgende alarm niet <xliff:g id="WHEN">%1$s</xliff:g> tenzij u dit voor die tijd uitschakelt"</string>
- <string name="zen_alarm_warning" msgid="444533119582244293">"U hoort uw volgende alarm niet <xliff:g id="WHEN">%1$s</xliff:g>"</string>
+ <string name="zen_alarm_warning_indef" msgid="3482966345578319605">"U hoort je volgende alarm niet <xliff:g id="WHEN">%1$s</xliff:g> tenzij u dit voor die tijd uitschakelt"</string>
+ <string name="zen_alarm_warning" msgid="444533119582244293">"U hoort je volgende alarm niet <xliff:g id="WHEN">%1$s</xliff:g>"</string>
<string name="alarm_template" msgid="3980063409350522735">"om <xliff:g id="WHEN">%1$s</xliff:g>"</string>
<string name="alarm_template_far" msgid="4242179982586714810">"op <xliff:g id="WHEN">%1$s</xliff:g>"</string>
<string name="accessibility_quick_settings_detail" msgid="2579369091672902101">"Snelle instellingen, <xliff:g id="TITLE">%s</xliff:g>."</string>
@@ -426,4 +428,7 @@
<string name="tuner_toast" msgid="603429811084428439">"Systeem-UI-tuner is toegevoegd aan Instellingen"</string>
<string name="remove_from_settings" msgid="8389591916603406378">"Verwijderen uit Instellingen"</string>
<string name="remove_from_settings_prompt" msgid="6069085993355887748">"Systeem-UI-tuner uit Instellingen verwijderen en het gebruik van alle functies daarvan stopzetten?"</string>
+ <string name="enable_bluetooth_title" msgid="5027037706500635269">"Bluetooth inschakelen?"</string>
+ <string name="enable_bluetooth_message" msgid="9106595990708985385">"Als je je toetsenbord wilt verbinden met je tablet, moet je eerst Bluetooth inschakelen."</string>
+ <string name="enable_bluetooth_confirmation_ok" msgid="6258074250948309715">"Inschakelen"</string>
</resources>
diff --git a/packages/SystemUI/res/values-pa-rIN/strings.xml b/packages/SystemUI/res/values-pa-rIN/strings.xml
index f33b441..323292e 100644
--- a/packages/SystemUI/res/values-pa-rIN/strings.xml
+++ b/packages/SystemUI/res/values-pa-rIN/strings.xml
@@ -325,6 +325,8 @@
<string name="interruption_level_priority_twoline" msgid="1564715335217164124">"ਕੇਵਲ\nਤਰਜੀਹੀ"</string>
<string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"ਕੇਵਲ\nਅਲਾਰਮ"</string>
<string name="keyguard_indication_charging_time" msgid="1757251776872835768">"ਚਾਰਜਿੰਗ (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> ਪੂਰਾ ਹੋਣ ਤੱਕ)"</string>
+ <string name="keyguard_indication_charging_time_fast" msgid="9018981952053914986">"ਤੇਜ਼ੀ ਨਾਲ ਚਾਰਜ ਹੋ ਰਹੀ ਹੈ (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> ਪੂਰੀ ਹੋਣ ਤੱਕ)"</string>
+ <string name="keyguard_indication_charging_time_slowly" msgid="955252797961724952">"ਹੌਲੀ-ਹੌਲੀ ਚਾਰਜ ਹੋ ਰਹੀ ਹੈ (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> ਪੂਰੀ ਹੋਣ ਤੱਕ)"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="7305948938141024937">"ਉਪਭੋਗਤਾ ਸਵਿਚ ਕਰੋ"</string>
<string name="accessibility_multi_user_switch_switcher_with_current" msgid="8434880595284601601">"ਉਪਭੋਗਤਾ, ਵਰਤਮਾਨ ਉਪਭੋਗਤਾ ਸਵਿਚ ਕਰੋ<xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_inactive" msgid="1424081831468083402">"ਮੌਜੂਦਾ ਉਪਭੋਗਤਾ <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
@@ -426,4 +428,7 @@
<string name="tuner_toast" msgid="603429811084428439">"ਵਧਾਈਆਂ! ਸਿਸਟਮ UI ਟਿਊਨਰ ਨੂੰ ਸੈਟਿੰਗਜ਼ ਵਿੱਚ ਜੋੜਿਆ ਗਿਆ ਹੈ"</string>
<string name="remove_from_settings" msgid="8389591916603406378">"ਸੈਟਿੰਗਜ਼ ਤੋਂ ਹਟਾਓ"</string>
<string name="remove_from_settings_prompt" msgid="6069085993355887748">"ਕੀ ਸੈਟਿੰਗਜ਼ ਤੋਂ ਸਿਸਟਮ UI ਟਿਊਨਰ ਨੂੰ ਹਟਾਉਣਾ ਹੈ ਅਤੇ ਇਸਦੀਆਂ ਸਾਰੀਆਂ ਵਿਸ਼ੇਸ਼ਤਾਵਾਂ ਨੂੰ ਉਪਯੋਗ ਕਰਨ ਤੋਂ ਰੋਕਣਾ ਹੈ?"</string>
+ <string name="enable_bluetooth_title" msgid="5027037706500635269">"Bluetooth ਚਾਲੂ ਕਰੋ?"</string>
+ <string name="enable_bluetooth_message" msgid="9106595990708985385">"ਆਪਣੇ ਟੈਬਲੇਟ ਨਾਲ ਆਪਣਾ ਕੀ-ਬੋਰਡ ਕਨੈਕਟ ਕਰਨ ਲਈ, ਤੁਹਾਨੂੰ ਪਹਿਲਾਂ Bluetooth ਚਾਲੂ ਕਰਨ ਦੀ ਜ਼ਰੂਰਤ ਹੈ।"</string>
+ <string name="enable_bluetooth_confirmation_ok" msgid="6258074250948309715">"ਚਾਲੂ ਕਰੋ"</string>
</resources>
diff --git a/packages/SystemUI/res/values-pl/strings.xml b/packages/SystemUI/res/values-pl/strings.xml
index 7314c42..77ed1b8 100644
--- a/packages/SystemUI/res/values-pl/strings.xml
+++ b/packages/SystemUI/res/values-pl/strings.xml
@@ -327,6 +327,8 @@
<string name="interruption_level_priority_twoline" msgid="1564715335217164124">"Tylko\npriorytetowe"</string>
<string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"Tylko\nalarmy"</string>
<string name="keyguard_indication_charging_time" msgid="1757251776872835768">"Ładuje się (pełne naładowanie za <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>)"</string>
+ <string name="keyguard_indication_charging_time_fast" msgid="9018981952053914986">"Szybkie ładowanie (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> do końca)"</string>
+ <string name="keyguard_indication_charging_time_slowly" msgid="955252797961724952">"Wolne ładowanie (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> do końca)"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="7305948938141024937">"Przełącz użytkownika"</string>
<string name="accessibility_multi_user_switch_switcher_with_current" msgid="8434880595284601601">"Przełącz użytkownika. Bieżący użytkownik: <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_inactive" msgid="1424081831468083402">"Bieżący użytkownik: <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
@@ -428,4 +430,7 @@
<string name="tuner_toast" msgid="603429811084428439">"Gratulujemy, Kalibrator System UI został dodany do Ustawień"</string>
<string name="remove_from_settings" msgid="8389591916603406378">"Usuń z Ustawień"</string>
<string name="remove_from_settings_prompt" msgid="6069085993355887748">"Usunąć Kalibrator System UI z Ustawień i przestać używać wszystkich jego funkcji?"</string>
+ <string name="enable_bluetooth_title" msgid="5027037706500635269">"Włączyć Bluetooth?"</string>
+ <string name="enable_bluetooth_message" msgid="9106595990708985385">"Aby połączyć klawiaturę z tabletem, musisz najpierw włączyć Bluetooth."</string>
+ <string name="enable_bluetooth_confirmation_ok" msgid="6258074250948309715">"Włącz"</string>
</resources>
diff --git a/packages/SystemUI/res/values-pt-rBR-land/strings.xml b/packages/SystemUI/res/values-pt-rBR-land/strings.xml
new file mode 100644
index 0000000..7b04e7e
--- /dev/null
+++ b/packages/SystemUI/res/values-pt-rBR-land/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (c) 2010, 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.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="toast_rotation_locked" msgid="7609673011431556092">"A tela está bloqueada na orientação cenário."</string>
+</resources>
diff --git a/packages/SystemUI/res/values-pt-rBR/strings.xml b/packages/SystemUI/res/values-pt-rBR/strings.xml
index 68f87e51..ab60bd4 100644
--- a/packages/SystemUI/res/values-pt-rBR/strings.xml
+++ b/packages/SystemUI/res/values-pt-rBR/strings.xml
@@ -150,9 +150,7 @@
<string name="accessibility_airplane_mode" msgid="834748999790763092">"Modo avião."</string>
<string name="accessibility_no_sims" msgid="3957997018324995781">"Sem cartão SIM."</string>
<string name="accessibility_carrier_network_change_mode" msgid="4017301580441304305">"Alteração de rede de operadora."</string>
- <!-- String.format failed for translation -->
- <!-- no translation found for accessibility_battery_level (7451474187113371965) -->
- <skip />
+ <string name="accessibility_battery_level" msgid="7451474187113371965">"Bateria em <xliff:g id="NUMBER">%d</xliff:g> por cento."</string>
<string name="accessibility_settings_button" msgid="799583911231893380">"Configurações do sistema"</string>
<string name="accessibility_notifications_button" msgid="4498000369779421892">"Notificações."</string>
<string name="accessibility_remove_notification" msgid="3603099514902182350">"Limpar notificação."</string>
@@ -327,6 +325,8 @@
<string name="interruption_level_priority_twoline" msgid="1564715335217164124">"Somente\nprioridade"</string>
<string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"Somente\nalarmes"</string>
<string name="keyguard_indication_charging_time" msgid="1757251776872835768">"Carregando (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> até concluir)"</string>
+ <string name="keyguard_indication_charging_time_fast" msgid="9018981952053914986">"Carregando rapidamente (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> para conclusão)"</string>
+ <string name="keyguard_indication_charging_time_slowly" msgid="955252797961724952">"Carregando lentamente (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> para conclusão)"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="7305948938141024937">"Trocar usuário"</string>
<string name="accessibility_multi_user_switch_switcher_with_current" msgid="8434880595284601601">"Alternar usuário. Usuário atual <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_inactive" msgid="1424081831468083402">"Usuário atual <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
@@ -428,4 +428,7 @@
<string name="tuner_toast" msgid="603429811084428439">"Parabéns! O sintonizador System UI foi adicionado às configurações"</string>
<string name="remove_from_settings" msgid="8389591916603406378">"Remover das configurações"</string>
<string name="remove_from_settings_prompt" msgid="6069085993355887748">"Remover sintonizador System UI das configurações e parar de usar todos os seus recursos?"</string>
+ <string name="enable_bluetooth_title" msgid="5027037706500635269">"Ativar o Bluetooth?"</string>
+ <string name="enable_bluetooth_message" msgid="9106595990708985385">"Para conectar o teclado ao tablet, é preciso primeiro ativar o Bluetooth."</string>
+ <string name="enable_bluetooth_confirmation_ok" msgid="6258074250948309715">"Ativar"</string>
</resources>
diff --git a/packages/SystemUI/res/values-pt-rPT/strings.xml b/packages/SystemUI/res/values-pt-rPT/strings.xml
index a4016a5..9e6c15f 100644
--- a/packages/SystemUI/res/values-pt-rPT/strings.xml
+++ b/packages/SystemUI/res/values-pt-rPT/strings.xml
@@ -325,6 +325,8 @@
<string name="interruption_level_priority_twoline" msgid="1564715335217164124">"Apenas\nprioridade"</string>
<string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"Apenas\nalarmes"</string>
<string name="keyguard_indication_charging_time" msgid="1757251776872835768">"A carregar (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> até à carga máxima)"</string>
+ <string name="keyguard_indication_charging_time_fast" msgid="9018981952053914986">"A carregar rapid. (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> até à carga máxima)"</string>
+ <string name="keyguard_indication_charging_time_slowly" msgid="955252797961724952">"A carregar lentam. (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> até à carga máxima)"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="7305948938141024937">"Mudar utilizador"</string>
<string name="accessibility_multi_user_switch_switcher_with_current" msgid="8434880595284601601">"Mudar de utilizador; o utilizador atual é <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_inactive" msgid="1424081831468083402">"Utilizador atual: <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
@@ -412,7 +414,7 @@
<string name="status_bar_airplane" msgid="7057575501472249002">"Modo de avião"</string>
<string name="add_tile" msgid="2995389510240786221">"Adicionar mosaico"</string>
<string name="broadcast_tile" msgid="3894036511763289383">"Mosaico de transmissão"</string>
- <string name="zen_alarm_warning_indef" msgid="3482966345578319605">"Só vai ouvir o próximo alarme às <xliff:g id="WHEN">%1$s</xliff:g> se desativar esta funcionalidade antes dessa hora"</string>
+ <string name="zen_alarm_warning_indef" msgid="3482966345578319605">"Só vai ouvir o próximo alarme (<xliff:g id="WHEN">%1$s</xliff:g>) se desativar esta funcionalidade antes dessa hora"</string>
<string name="zen_alarm_warning" msgid="444533119582244293">"Não vai ouvir o próximo alarme às <xliff:g id="WHEN">%1$s</xliff:g>"</string>
<string name="alarm_template" msgid="3980063409350522735">"às <xliff:g id="WHEN">%1$s</xliff:g>"</string>
<string name="alarm_template_far" msgid="4242179982586714810">"em <xliff:g id="WHEN">%1$s</xliff:g>"</string>
@@ -426,4 +428,7 @@
<string name="tuner_toast" msgid="603429811084428439">"Parabéns! O Sintonizador da interface do sistema foi adicionado às Definições"</string>
<string name="remove_from_settings" msgid="8389591916603406378">"Remover das Definições"</string>
<string name="remove_from_settings_prompt" msgid="6069085993355887748">"Pretende remover o Sintonizador da interface do sistema das Definições e deixar de utilizar todas as respetivas funcionalidades?"</string>
+ <string name="enable_bluetooth_title" msgid="5027037706500635269">"Pretende ativar o Bluetooth?"</string>
+ <string name="enable_bluetooth_message" msgid="9106595990708985385">"Para ligar o teclado ao tablet, tem de ativar primeiro o Bluetooth."</string>
+ <string name="enable_bluetooth_confirmation_ok" msgid="6258074250948309715">"Ativar"</string>
</resources>
diff --git a/packages/SystemUI/res/values-pt/strings.xml b/packages/SystemUI/res/values-pt/strings.xml
index 68f87e51..ab60bd4 100644
--- a/packages/SystemUI/res/values-pt/strings.xml
+++ b/packages/SystemUI/res/values-pt/strings.xml
@@ -150,9 +150,7 @@
<string name="accessibility_airplane_mode" msgid="834748999790763092">"Modo avião."</string>
<string name="accessibility_no_sims" msgid="3957997018324995781">"Sem cartão SIM."</string>
<string name="accessibility_carrier_network_change_mode" msgid="4017301580441304305">"Alteração de rede de operadora."</string>
- <!-- String.format failed for translation -->
- <!-- no translation found for accessibility_battery_level (7451474187113371965) -->
- <skip />
+ <string name="accessibility_battery_level" msgid="7451474187113371965">"Bateria em <xliff:g id="NUMBER">%d</xliff:g> por cento."</string>
<string name="accessibility_settings_button" msgid="799583911231893380">"Configurações do sistema"</string>
<string name="accessibility_notifications_button" msgid="4498000369779421892">"Notificações."</string>
<string name="accessibility_remove_notification" msgid="3603099514902182350">"Limpar notificação."</string>
@@ -327,6 +325,8 @@
<string name="interruption_level_priority_twoline" msgid="1564715335217164124">"Somente\nprioridade"</string>
<string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"Somente\nalarmes"</string>
<string name="keyguard_indication_charging_time" msgid="1757251776872835768">"Carregando (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> até concluir)"</string>
+ <string name="keyguard_indication_charging_time_fast" msgid="9018981952053914986">"Carregando rapidamente (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> para conclusão)"</string>
+ <string name="keyguard_indication_charging_time_slowly" msgid="955252797961724952">"Carregando lentamente (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> para conclusão)"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="7305948938141024937">"Trocar usuário"</string>
<string name="accessibility_multi_user_switch_switcher_with_current" msgid="8434880595284601601">"Alternar usuário. Usuário atual <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_inactive" msgid="1424081831468083402">"Usuário atual <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
@@ -428,4 +428,7 @@
<string name="tuner_toast" msgid="603429811084428439">"Parabéns! O sintonizador System UI foi adicionado às configurações"</string>
<string name="remove_from_settings" msgid="8389591916603406378">"Remover das configurações"</string>
<string name="remove_from_settings_prompt" msgid="6069085993355887748">"Remover sintonizador System UI das configurações e parar de usar todos os seus recursos?"</string>
+ <string name="enable_bluetooth_title" msgid="5027037706500635269">"Ativar o Bluetooth?"</string>
+ <string name="enable_bluetooth_message" msgid="9106595990708985385">"Para conectar o teclado ao tablet, é preciso primeiro ativar o Bluetooth."</string>
+ <string name="enable_bluetooth_confirmation_ok" msgid="6258074250948309715">"Ativar"</string>
</resources>
diff --git a/packages/SystemUI/res/values-ro/strings.xml b/packages/SystemUI/res/values-ro/strings.xml
index 874f51a..122bb01 100644
--- a/packages/SystemUI/res/values-ro/strings.xml
+++ b/packages/SystemUI/res/values-ro/strings.xml
@@ -20,9 +20,9 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="7164937344850004466">"UI sistem"</string>
- <string name="status_bar_clear_all_button" msgid="7774721344716731603">"Ștergeţi"</string>
+ <string name="status_bar_clear_all_button" msgid="7774721344716731603">"Ștergeți"</string>
<string name="status_bar_recent_remove_item_title" msgid="6026395868129852968">"Eliminaţi din listă"</string>
- <string name="status_bar_recent_inspect_item_title" msgid="7793624864528818569">"Informaţii despre aplicație"</string>
+ <string name="status_bar_recent_inspect_item_title" msgid="7793624864528818569">"Informații despre aplicație"</string>
<string name="status_bar_no_recent_apps" msgid="7374907845131203189">"Ecranele dvs. recente apar aici"</string>
<string name="status_bar_accessibility_dismiss_recents" msgid="4576076075226540105">"Renunţaţi la aplicațiile recente"</string>
<plurals name="status_bar_accessibility_recent_apps" formatted="false" msgid="9138535907802238759">
@@ -52,18 +52,18 @@
<string name="bluetooth_tethered" msgid="7094101612161133267">"Conectat prin tethering prin Bluetooth"</string>
<string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"Setaţi metode introducere text"</string>
<string name="status_bar_use_physical_keyboard" msgid="7551903084416057810">"Tastatură fizică"</string>
- <string name="usb_device_permission_prompt" msgid="834698001271562057">"Permiteţi aplicației <xliff:g id="APPLICATION">%1$s</xliff:g> să acceseze dispozitivul USB?"</string>
- <string name="usb_accessory_permission_prompt" msgid="5171775411178865750">"Permiteţi aplicației <xliff:g id="APPLICATION">%1$s</xliff:g> să acceseze accesoriul USB?"</string>
+ <string name="usb_device_permission_prompt" msgid="834698001271562057">"Permiteți aplicației <xliff:g id="APPLICATION">%1$s</xliff:g> să acceseze dispozitivul USB?"</string>
+ <string name="usb_accessory_permission_prompt" msgid="5171775411178865750">"Permiteți aplicației <xliff:g id="APPLICATION">%1$s</xliff:g> să acceseze accesoriul USB?"</string>
<string name="usb_device_confirm_prompt" msgid="5161205258635253206">"Deschideţi <xliff:g id="ACTIVITY">%1$s</xliff:g> la conectarea acestui dispozitiv USB?"</string>
<string name="usb_accessory_confirm_prompt" msgid="3808984931830229888">"Deschideţi <xliff:g id="ACTIVITY">%1$s</xliff:g> la conectarea acestui accesoriu USB?"</string>
- <string name="usb_accessory_uri_prompt" msgid="513450621413733343">"Aplic. instal. nu funcţ. cu acest acces. USB. Aflaţi despre acest accesoriu la <xliff:g id="URL">%1$s</xliff:g>"</string>
+ <string name="usb_accessory_uri_prompt" msgid="513450621413733343">"Aplic. instal. nu funcţ. cu acest acces. USB. Aflați despre acest accesoriu la <xliff:g id="URL">%1$s</xliff:g>"</string>
<string name="title_usb_accessory" msgid="4966265263465181372">"Accesoriu USB"</string>
<string name="label_view" msgid="6304565553218192990">"Afişaţi"</string>
<string name="always_use_device" msgid="1450287437017315906">"Utilizaţi în mod prestabilit pt. acest dispoz. USB"</string>
<string name="always_use_accessory" msgid="1210954576979621596">"Utiliz. în mod prestabilit pt. acest accesoriu USB"</string>
- <string name="usb_debugging_title" msgid="4513918393387141949">"Permiteţi depanarea USB?"</string>
+ <string name="usb_debugging_title" msgid="4513918393387141949">"Permiteți depanarea USB?"</string>
<string name="usb_debugging_message" msgid="2220143855912376496">"Amprenta digitală din cheia RSA a computerului este:\n<xliff:g id="FINGERPRINT">%1$s</xliff:g>"</string>
- <string name="usb_debugging_always" msgid="303335496705863070">"Permiteţi întotdeauna de pe acest computer"</string>
+ <string name="usb_debugging_always" msgid="303335496705863070">"Permiteți întotdeauna de pe acest computer"</string>
<string name="usb_debugging_secondary_user_title" msgid="6353808721761220421">"Remedierea erorilor prin USB nu este permisă"</string>
<string name="usb_debugging_secondary_user_message" msgid="6011931347142270156">"Utilizatorul conectat momentan pe acest dispozitiv nu poate activa remedierea erorilor prin USB. Pentru a folosi această funcție, comutați la utilizatorul principal „<xliff:g id="NAME">%s</xliff:g>”."</string>
<string name="compat_mode_on" msgid="6623839244840638213">"Zoom pt. a umple ecranul"</string>
@@ -72,13 +72,13 @@
<string name="screenshot_saving_title" msgid="8242282144535555697">"Se salvează captura de ecran..."</string>
<string name="screenshot_saving_text" msgid="2419718443411738818">"Captura de ecran este salvată."</string>
<string name="screenshot_saved_title" msgid="6461865960961414961">"Captură de ecran realizată."</string>
- <string name="screenshot_saved_text" msgid="1152839647677558815">"Atingeţi pentru a vedea captura de ecran."</string>
+ <string name="screenshot_saved_text" msgid="1152839647677558815">"Atingeți pentru a vedea captura de ecran."</string>
<string name="screenshot_failed_title" msgid="705781116746922771">"Captura de ecran nu a putut fi realizată."</string>
<string name="screenshot_failed_text" msgid="1260203058661337274">"Captură de ecran impos. de realizat: spațiu de stoc. limitat sau nu este permisă de apl. sau de organiz."</string>
- <string name="usb_preference_title" msgid="6551050377388882787">"Opţiuni pentru transferul de fişiere prin USB"</string>
+ <string name="usb_preference_title" msgid="6551050377388882787">"Opţiuni pentru transferul de fișiere prin USB"</string>
<string name="use_mtp_button_title" msgid="4333504413563023626">"Montaţi ca player media (MTP)"</string>
<string name="use_ptp_button_title" msgid="7517127540301625751">"Montaţi drept cameră foto (PTP)"</string>
- <string name="installer_cd_button_title" msgid="2312667578562201583">"Instal. aplic. Transfer de fişiere Android pt. Mac"</string>
+ <string name="installer_cd_button_title" msgid="2312667578562201583">"Instal. aplic. Transfer de fișiere Android pt. Mac"</string>
<string name="accessibility_back" msgid="567011538994429120">"Înapoi"</string>
<string name="accessibility_home" msgid="8217216074895377641">"Ecranul de pornire"</string>
<string name="accessibility_menu" msgid="316839303324695949">"Meniu"</string>
@@ -151,15 +151,15 @@
<string name="accessibility_airplane_mode" msgid="834748999790763092">"Mod Avion."</string>
<string name="accessibility_no_sims" msgid="3957997018324995781">"Niciun card SIM."</string>
<string name="accessibility_carrier_network_change_mode" msgid="4017301580441304305">"Se schimbă rețeaua operatorului."</string>
- <string name="accessibility_battery_level" msgid="7451474187113371965">"Baterie: <xliff:g id="NUMBER">%d</xliff:g> procente."</string>
+ <string name="accessibility_battery_level" msgid="7451474187113371965">"Baterie: <xliff:g id="NUMBER">%d</xliff:g> la sută."</string>
<string name="accessibility_settings_button" msgid="799583911231893380">"Setări de sistem."</string>
<string name="accessibility_notifications_button" msgid="4498000369779421892">"Notificări."</string>
- <string name="accessibility_remove_notification" msgid="3603099514902182350">"Ștergeţi notificarea."</string>
+ <string name="accessibility_remove_notification" msgid="3603099514902182350">"Ștergeți notificarea."</string>
<string name="accessibility_gps_enabled" msgid="3511469499240123019">"GPS activat."</string>
<string name="accessibility_gps_acquiring" msgid="8959333351058967158">"Se obţine GPS."</string>
<string name="accessibility_tty_enabled" msgid="4613200365379426561">"TeleTypewriter activat."</string>
<string name="accessibility_ringer_vibrate" msgid="666585363364155055">"Vibrare sonerie."</string>
- <string name="accessibility_ringer_silent" msgid="9061243307939135383">"Sonerie silenţioasă."</string>
+ <string name="accessibility_ringer_silent" msgid="9061243307939135383">"Sonerie silențioasă."</string>
<!-- no translation found for accessibility_casting (6887382141726543668) -->
<skip />
<string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"Închideți <xliff:g id="APP">%s</xliff:g>."</string>
@@ -223,9 +223,9 @@
<string name="status_bar_settings_signal_meter_disconnected" msgid="1940231521274147771">"Fără conex. internet"</string>
<string name="status_bar_settings_signal_meter_wifi_nossid" msgid="6557486452774597820">"Wi-Fi conectat"</string>
<string name="gps_notification_searching_text" msgid="8574247005642736060">"Se caută GPS"</string>
- <string name="gps_notification_found_text" msgid="4619274244146446464">"Locaţie setată prin GPS"</string>
+ <string name="gps_notification_found_text" msgid="4619274244146446464">"Locație setată prin GPS"</string>
<string name="accessibility_location_active" msgid="2427290146138169014">"Solicitări locație active"</string>
- <string name="accessibility_clear_all" msgid="5235938559247164925">"Ștergeţi toate notificările."</string>
+ <string name="accessibility_clear_all" msgid="5235938559247164925">"Ștergeți toate notificările."</string>
<string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"Setări pentru notificări"</string>
<string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"Setări <xliff:g id="APP_NAME">%s</xliff:g>"</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Ecranul se va roti în mod automat."</string>
@@ -255,7 +255,7 @@
<string name="quick_settings_location_off_label" msgid="7464544086507331459">"Localizarea este dezactivată"</string>
<string name="quick_settings_media_device_label" msgid="1302906836372603762">"Dispozitiv media"</string>
<string name="quick_settings_rssi_label" msgid="7725671335550695589">"RSSI"</string>
- <string name="quick_settings_rssi_emergency_only" msgid="2713774041672886750">"Numai apeluri de urgenţă"</string>
+ <string name="quick_settings_rssi_emergency_only" msgid="2713774041672886750">"Numai apeluri de urgență"</string>
<string name="quick_settings_settings_label" msgid="5326556592578065401">"Setări"</string>
<string name="quick_settings_time_label" msgid="4635969182239736408">"Ora"</string>
<string name="quick_settings_user_label" msgid="5238995632130897840">"Eu"</string>
@@ -263,7 +263,7 @@
<string name="quick_settings_user_new_user" msgid="9030521362023479778">"Utilizator nou"</string>
<string name="quick_settings_wifi_label" msgid="9135344704899546041">"Wi-Fi"</string>
<string name="quick_settings_wifi_not_connected" msgid="7171904845345573431">"Neconectat"</string>
- <string name="quick_settings_wifi_no_network" msgid="2221993077220856376">"Nicio reţea"</string>
+ <string name="quick_settings_wifi_no_network" msgid="2221993077220856376">"Nicio rețea"</string>
<string name="quick_settings_wifi_off_label" msgid="7558778100843885864">"Wi-Fi deconectat"</string>
<string name="quick_settings_wifi_detail_empty_text" msgid="269990350383909226">"Nicio rețea Wi-Fi disponibilă"</string>
<string name="quick_settings_cast_title" msgid="7709016546426454729">"Proiectați"</string>
@@ -304,7 +304,7 @@
<string name="expanded_header_battery_charging_with_time" msgid="457559884275395376">"<xliff:g id="CHARGING_TIME">%s</xliff:g> până la încărcare completă"</string>
<string name="expanded_header_battery_not_charging" msgid="4798147152367049732">"Nu se încarcă"</string>
<string name="ssl_ca_cert_warning" msgid="9005954106902053641">"Rețeaua poate\nfi monitorizată"</string>
- <string name="description_target_search" msgid="3091587249776033139">"Căutaţi"</string>
+ <string name="description_target_search" msgid="3091587249776033139">"Căutați"</string>
<string name="description_direction_up" msgid="7169032478259485180">"Glisaţi în sus pentru <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
<string name="description_direction_left" msgid="7207478719805562165">"Glisaţi spre stânga pentru <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
<string name="zen_priority_introduction" msgid="3070506961866919502">"Nu veți fi deranjat(ă) de sunete și vibrații, exceptând alarmele, mementourile, evenimentele și apelanții pe care îi menționați."</string>
@@ -326,6 +326,8 @@
<string name="interruption_level_priority_twoline" msgid="1564715335217164124">"Numai\ncu prioritate"</string>
<string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"Numai\nalarme"</string>
<string name="keyguard_indication_charging_time" msgid="1757251776872835768">"Se încarcă (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> până la finalizare)"</string>
+ <string name="keyguard_indication_charging_time_fast" msgid="9018981952053914986">"Se încarcă rapid (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> până la finalizare)"</string>
+ <string name="keyguard_indication_charging_time_slowly" msgid="955252797961724952">"Se încarcă lent (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> până la finalizare)"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="7305948938141024937">"Comutați între utilizatori"</string>
<string name="accessibility_multi_user_switch_switcher_with_current" msgid="8434880595284601601">"Schimbați utilizatorul (utilizator actual <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>)"</string>
<string name="accessibility_multi_user_switch_inactive" msgid="1424081831468083402">"Utilizator actual <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
@@ -427,4 +429,7 @@
<string name="tuner_toast" msgid="603429811084428439">"Felicitări! System UI Tuner a fost adăugat în Setări"</string>
<string name="remove_from_settings" msgid="8389591916603406378">"Eliminați din Setări"</string>
<string name="remove_from_settings_prompt" msgid="6069085993355887748">"Eliminați System UI Tuner din Setări și încetați utilizarea tuturor funcțiilor sale?"</string>
+ <string name="enable_bluetooth_title" msgid="5027037706500635269">"Activați Bluetooth?"</string>
+ <string name="enable_bluetooth_message" msgid="9106595990708985385">"Pentru a conecta tastatura la tabletă, mai întâi trebuie să activați Bluetooth."</string>
+ <string name="enable_bluetooth_confirmation_ok" msgid="6258074250948309715">"Activați"</string>
</resources>
diff --git a/packages/SystemUI/res/values-ru/strings.xml b/packages/SystemUI/res/values-ru/strings.xml
index 49228d1..2197355 100644
--- a/packages/SystemUI/res/values-ru/strings.xml
+++ b/packages/SystemUI/res/values-ru/strings.xml
@@ -152,9 +152,7 @@
<string name="accessibility_airplane_mode" msgid="834748999790763092">"Режим полета."</string>
<string name="accessibility_no_sims" msgid="3957997018324995781">"Нет SIM-карты."</string>
<string name="accessibility_carrier_network_change_mode" msgid="4017301580441304305">"Сменить сеть"</string>
- <!-- String.format failed for translation -->
- <!-- no translation found for accessibility_battery_level (7451474187113371965) -->
- <skip />
+ <string name="accessibility_battery_level" msgid="7451474187113371965">"Заряд батареи в процентах: <xliff:g id="NUMBER">%d</xliff:g>."</string>
<string name="accessibility_settings_button" msgid="799583911231893380">"Настройки"</string>
<string name="accessibility_notifications_button" msgid="4498000369779421892">"Уведомления"</string>
<string name="accessibility_remove_notification" msgid="3603099514902182350">"Удалить уведомление"</string>
@@ -269,7 +267,7 @@
<string name="quick_settings_wifi_no_network" msgid="2221993077220856376">"Нет сети"</string>
<string name="quick_settings_wifi_off_label" msgid="7558778100843885864">"Wi-Fi выкл."</string>
<string name="quick_settings_wifi_detail_empty_text" msgid="269990350383909226">"Не удалось найти доступные сети Wi-Fi"</string>
- <string name="quick_settings_cast_title" msgid="7709016546426454729">"Wi-Fi-монитор"</string>
+ <string name="quick_settings_cast_title" msgid="7709016546426454729">"Трансляция"</string>
<string name="quick_settings_casting" msgid="6601710681033353316">"Передача изображения"</string>
<string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"Безымянное устройство"</string>
<string name="quick_settings_cast_device_default_description" msgid="2484573682378634413">"Готово к передаче"</string>
@@ -329,6 +327,8 @@
<string name="interruption_level_priority_twoline" msgid="1564715335217164124">"Только\nважные"</string>
<string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"Только\nбудильник"</string>
<string name="keyguard_indication_charging_time" msgid="1757251776872835768">"Зарядка батареи (осталось <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>)"</string>
+ <string name="keyguard_indication_charging_time_fast" msgid="9018981952053914986">"Быстрая зарядка (осталось <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>)"</string>
+ <string name="keyguard_indication_charging_time_slowly" msgid="955252797961724952">"Медленная зарядка (осталось <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>)"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="7305948938141024937">"Сменить пользователя."</string>
<string name="accessibility_multi_user_switch_switcher_with_current" msgid="8434880595284601601">"Сменить аккаунт. Вход выполнен под именем <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>."</string>
<string name="accessibility_multi_user_switch_inactive" msgid="1424081831468083402">"Выбран аккаунт пользователя <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
@@ -430,4 +430,7 @@
<string name="tuner_toast" msgid="603429811084428439">"Функция System UI Tuner добавлена в меню настроек"</string>
<string name="remove_from_settings" msgid="8389591916603406378">"Удалить из настроек"</string>
<string name="remove_from_settings_prompt" msgid="6069085993355887748">"Убрать функцию System UI Tuner из меню настроек и прекратить ее работу?"</string>
+ <string name="enable_bluetooth_title" msgid="5027037706500635269">"Подключение по Bluetooth"</string>
+ <string name="enable_bluetooth_message" msgid="9106595990708985385">"Чтобы подключить клавиатуру к планшету, включите Bluetooth."</string>
+ <string name="enable_bluetooth_confirmation_ok" msgid="6258074250948309715">"Включить"</string>
</resources>
diff --git a/packages/SystemUI/res/values-si-rLK/strings.xml b/packages/SystemUI/res/values-si-rLK/strings.xml
index eb6d981..a687379 100644
--- a/packages/SystemUI/res/values-si-rLK/strings.xml
+++ b/packages/SystemUI/res/values-si-rLK/strings.xml
@@ -325,6 +325,8 @@
<string name="interruption_level_priority_twoline" msgid="1564715335217164124">"ප්රමුඛතා\nපමණි"</string>
<string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"ඇඟවීම්\nපමණි"</string>
<string name="keyguard_indication_charging_time" msgid="1757251776872835768">"ආරෝපණය වෙමින් (සම්පුර්ණ වන තෙක් <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>)"</string>
+ <string name="keyguard_indication_charging_time_fast" msgid="9018981952053914986">"ඉක්මනින් ආරෝපණය වෙමින් (සම්පුර්ණ වන තෙක් <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>)"</string>
+ <string name="keyguard_indication_charging_time_slowly" msgid="955252797961724952">"සෙමින් ආරෝපණය වෙමින් (සම්පුර්ණ වන තෙක් <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>)"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="7305948938141024937">"පරිශීලක මාරුව"</string>
<string name="accessibility_multi_user_switch_switcher_with_current" msgid="8434880595284601601">"පරිශීලකයා මාරු කරන්න,දැන් සිටින පරිශීලකයා <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_inactive" msgid="1424081831468083402">"වත්මන් පරිශීලක <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
@@ -426,4 +428,7 @@
<string name="tuner_toast" msgid="603429811084428439">"සුබ පැතුම්! පද්ධති UI සුසරකය සැකසීම් වෙත එක් කර ඇත"</string>
<string name="remove_from_settings" msgid="8389591916603406378">"සැකසීම් වෙතින් ඉවත් කරන්න"</string>
<string name="remove_from_settings_prompt" msgid="6069085993355887748">"සැකසීම් වෙතින් පද්ධති UI සුසරකය ඉවත් කර සහ එහි සියලු අංග භාවිතය නවත් වන්නද?"</string>
+ <string name="enable_bluetooth_title" msgid="5027037706500635269">"බ්ලූටූත් ක්රියාත්මක කරන්නද?"</string>
+ <string name="enable_bluetooth_message" msgid="9106595990708985385">"ඔබේ යතුරු පුවරුව ඔබේ ටැබ්ලට් පරිගණකයට සම්බන්ධ කිරීමට, ඔබ පළමුව බ්ලූටූත් ක්රියාත්මක කළ යුතුය."</string>
+ <string name="enable_bluetooth_confirmation_ok" msgid="6258074250948309715">"ක්රියාත්මක කරන්න"</string>
</resources>
diff --git a/packages/SystemUI/res/values-sk/strings.xml b/packages/SystemUI/res/values-sk/strings.xml
index 1eb5901..e37247e 100644
--- a/packages/SystemUI/res/values-sk/strings.xml
+++ b/packages/SystemUI/res/values-sk/strings.xml
@@ -36,7 +36,7 @@
<string name="status_bar_latest_events_title" msgid="6594767438577593172">"Upozornenia"</string>
<string name="battery_low_title" msgid="6456385927409742437">"Batéria je takmer vybitá"</string>
<string name="battery_low_percent_format" msgid="2900940511201380775">"Zostáva <xliff:g id="PERCENTAGE">%s</xliff:g>"</string>
- <string name="battery_low_percent_format_saver_started" msgid="6859235584035338833">"Zostáva <xliff:g id="PERCENTAGE">%s</xliff:g>. Úspora batérie je zapnutá."</string>
+ <string name="battery_low_percent_format_saver_started" msgid="6859235584035338833">"Zostáva <xliff:g id="PERCENTAGE">%s</xliff:g>. Šetrič batérie je zapnutý."</string>
<string name="invalid_charger" msgid="4549105996740522523">"Nabíjanie pomocou rozhrania USB nie je podporované.\nPoužívajte iba nabíjačku, ktorá bola dodaná spolu so zariadením."</string>
<string name="invalid_charger_title" msgid="3515740382572798460">"Nabíjanie prostredníctvom USB nie je podporované."</string>
<string name="invalid_charger_text" msgid="5474997287953892710">"Používajte iba originálnu nabíjačku."</string>
@@ -152,9 +152,7 @@
<string name="accessibility_airplane_mode" msgid="834748999790763092">"Režim v lietadle."</string>
<string name="accessibility_no_sims" msgid="3957997018324995781">"Žiadna SIM karta."</string>
<string name="accessibility_carrier_network_change_mode" msgid="4017301580441304305">"Zmena siete operátora"</string>
- <!-- String.format failed for translation -->
- <!-- no translation found for accessibility_battery_level (7451474187113371965) -->
- <skip />
+ <string name="accessibility_battery_level" msgid="7451474187113371965">"Batéria <xliff:g id="NUMBER">%d</xliff:g> percent."</string>
<string name="accessibility_settings_button" msgid="799583911231893380">"Nastavenia systému."</string>
<string name="accessibility_notifications_button" msgid="4498000369779421892">"Upozornenia."</string>
<string name="accessibility_remove_notification" msgid="3603099514902182350">"Vymazať upozornenie."</string>
@@ -329,6 +327,8 @@
<string name="interruption_level_priority_twoline" msgid="1564715335217164124">"Iba\nprioritné"</string>
<string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"Iba\nbudíky"</string>
<string name="keyguard_indication_charging_time" msgid="1757251776872835768">"Nabíja sa (úplné nabitie o <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>)"</string>
+ <string name="keyguard_indication_charging_time_fast" msgid="9018981952053914986">"Nabíja sa rýchlo (úplné nabitie o <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>)"</string>
+ <string name="keyguard_indication_charging_time_slowly" msgid="955252797961724952">"Nabíja sa pomaly (úplné nabitie o <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>)"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="7305948938141024937">"Prepnutie používateľa"</string>
<string name="accessibility_multi_user_switch_switcher_with_current" msgid="8434880595284601601">"Prepnúť používateľa (súčasný používateľ: <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>)"</string>
<string name="accessibility_multi_user_switch_inactive" msgid="1424081831468083402">"Aktuálny používateľ <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
@@ -430,4 +430,7 @@
<string name="tuner_toast" msgid="603429811084428439">"Výborne, tuner používateľského rozhrania systému bol pridaný do Nastavení"</string>
<string name="remove_from_settings" msgid="8389591916603406378">"Odstrániť z Nastavení"</string>
<string name="remove_from_settings_prompt" msgid="6069085993355887748">"Chcete odstrániť tuner používateľského rozhrania systému z Nastavení a prestať používať všetky jeho funkcie?"</string>
+ <string name="enable_bluetooth_title" msgid="5027037706500635269">"Zapnúť Bluetooth?"</string>
+ <string name="enable_bluetooth_message" msgid="9106595990708985385">"Ak chcete klávesnicu pripojiť k tabletu, najprv musíte zapnúť Bluetooth."</string>
+ <string name="enable_bluetooth_confirmation_ok" msgid="6258074250948309715">"Zapnúť"</string>
</resources>
diff --git a/packages/SystemUI/res/values-sl/strings.xml b/packages/SystemUI/res/values-sl/strings.xml
index d9102a2..2273758 100644
--- a/packages/SystemUI/res/values-sl/strings.xml
+++ b/packages/SystemUI/res/values-sl/strings.xml
@@ -327,6 +327,8 @@
<string name="interruption_level_priority_twoline" msgid="1564715335217164124">"Samo\nprednostno"</string>
<string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"Samo\nalarmi"</string>
<string name="keyguard_indication_charging_time" msgid="1757251776872835768">"Polnjenje (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> do napolnjenosti)"</string>
+ <string name="keyguard_indication_charging_time_fast" msgid="9018981952053914986">"Hitro polnjenje (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> do napolnjenosti)"</string>
+ <string name="keyguard_indication_charging_time_slowly" msgid="955252797961724952">"Počasno polnjenje (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> do napolnjenosti)"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="7305948938141024937">"Preklop med uporabniki"</string>
<string name="accessibility_multi_user_switch_switcher_with_current" msgid="8434880595284601601">"Preklop med uporabniki, trenutni uporabnik <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_inactive" msgid="1424081831468083402">"Trenutni uporabnik: <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
@@ -428,4 +430,7 @@
<string name="tuner_toast" msgid="603429811084428439">"Čestitke! Uglaševalnik uporabniškega vmesnika sistema je bil dodan v nastavitve."</string>
<string name="remove_from_settings" msgid="8389591916603406378">"Odstrani iz nastavitev"</string>
<string name="remove_from_settings_prompt" msgid="6069085993355887748">"Ali želite odstraniti Uglaševalnik uporabniškega vmesnika sistema iz nastavitev in prenehati uporabljati vse njegove funkcije?"</string>
+ <string name="enable_bluetooth_title" msgid="5027037706500635269">"Želite vklopiti Bluetooth?"</string>
+ <string name="enable_bluetooth_message" msgid="9106595990708985385">"Če želite povezati tipkovnico in tablični računalnik, vklopite Bluetooth."</string>
+ <string name="enable_bluetooth_confirmation_ok" msgid="6258074250948309715">"Vklop"</string>
</resources>
diff --git a/packages/SystemUI/res/values-sq-rAL/strings.xml b/packages/SystemUI/res/values-sq-rAL/strings.xml
index cb8a50c..8d6962e 100644
--- a/packages/SystemUI/res/values-sq-rAL/strings.xml
+++ b/packages/SystemUI/res/values-sq-rAL/strings.xml
@@ -325,6 +325,8 @@
<string name="interruption_level_priority_twoline" msgid="1564715335217164124">"Vetëm\nme prioritet"</string>
<string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"Vetëm\nalarmet"</string>
<string name="keyguard_indication_charging_time" msgid="1757251776872835768">"Po ngarkohet (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> deri sa të mbushet)"</string>
+ <string name="keyguard_indication_charging_time_fast" msgid="9018981952053914986">"Po ngarkon me shpejtësi (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> derisa të mbushet)"</string>
+ <string name="keyguard_indication_charging_time_slowly" msgid="955252797961724952">"Po ngarkon me ngadalë (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> derisa të mbushet)"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="7305948938141024937">"Ndërro përdorues"</string>
<string name="accessibility_multi_user_switch_switcher_with_current" msgid="8434880595284601601">"Ndërro përdoruesin. Përdoruesi aktual është <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_inactive" msgid="1424081831468083402">"Përdoruesi aktual <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
@@ -426,4 +428,7 @@
<string name="tuner_toast" msgid="603429811084428439">"Urime! Sintonizuesi i Sistemit të Ndërfaqes së Përdoruesit u shtua te Cilësimet"</string>
<string name="remove_from_settings" msgid="8389591916603406378">"Hiqe nga Cilësimet"</string>
<string name="remove_from_settings_prompt" msgid="6069085993355887748">"Të hiqet Sintonizuesi i Sistemit të Ndërfaqes së Përdoruesit nga Cilësimet dhe të ndërpritet përdorimi i të gjitha funksioneve të tij?"</string>
+ <string name="enable_bluetooth_title" msgid="5027037706500635269">"Të aktivizohet \"bluetooth-i\"?"</string>
+ <string name="enable_bluetooth_message" msgid="9106595990708985385">"Për të lidhur tastierën me tabletin, në fillim duhet të aktivizosh \"bluetooth-in\"."</string>
+ <string name="enable_bluetooth_confirmation_ok" msgid="6258074250948309715">"Aktivizo"</string>
</resources>
diff --git a/packages/SystemUI/res/values-sr/strings.xml b/packages/SystemUI/res/values-sr/strings.xml
index 181c136..3c8aeb5 100644
--- a/packages/SystemUI/res/values-sr/strings.xml
+++ b/packages/SystemUI/res/values-sr/strings.xml
@@ -326,6 +326,8 @@
<string name="interruption_level_priority_twoline" msgid="1564715335217164124">"Само\nприорит. прекиди"</string>
<string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"Само\nаларми"</string>
<string name="keyguard_indication_charging_time" msgid="1757251776872835768">"Пуњење (пун је за <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>)"</string>
+ <string name="keyguard_indication_charging_time_fast" msgid="9018981952053914986">"Брзо се пуни (напуниће се за <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>)"</string>
+ <string name="keyguard_indication_charging_time_slowly" msgid="955252797961724952">"Споро се пуни (напуниће се за <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>)"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="7305948938141024937">"Замени корисника"</string>
<string name="accessibility_multi_user_switch_switcher_with_current" msgid="8434880595284601601">"Промените корисника, актуелни корисник је <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_inactive" msgid="1424081831468083402">"Актуелни корисник <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
@@ -427,4 +429,7 @@
<string name="tuner_toast" msgid="603429811084428439">"Честитамо! Тјунер за кориснички интерфејс система је додат у Подешавања"</string>
<string name="remove_from_settings" msgid="8389591916603406378">"Уклони из Подешавања"</string>
<string name="remove_from_settings_prompt" msgid="6069085993355887748">"Желите ли да уклоните Тјунер за кориснички интерфејс система из Подешавања и да престанете да користите све његове функције?"</string>
+ <string name="enable_bluetooth_title" msgid="5027037706500635269">"Желите ли да укључите Bluetooth?"</string>
+ <string name="enable_bluetooth_message" msgid="9106595990708985385">"Да бисте повезали тастатуру са таблетом, прво морате да укључите Bluetooth."</string>
+ <string name="enable_bluetooth_confirmation_ok" msgid="6258074250948309715">"Укључи"</string>
</resources>
diff --git a/packages/SystemUI/res/values-sv/strings.xml b/packages/SystemUI/res/values-sv/strings.xml
index 61b3344..76ebef2 100644
--- a/packages/SystemUI/res/values-sv/strings.xml
+++ b/packages/SystemUI/res/values-sv/strings.xml
@@ -313,10 +313,10 @@
<string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
<string name="speed_bump_explanation" msgid="1288875699658819755">"Mindre brådskande aviseringar nedan"</string>
<string name="notification_tap_again" msgid="8524949573675922138">"Tryck igen för att öppna"</string>
- <string name="keyguard_unlock" msgid="8043466894212841998">"Dra uppåt om du vill låsa upp"</string>
- <string name="phone_hint" msgid="4872890986869209950">"Dra från ikonen och öppna telefonen"</string>
- <string name="voice_hint" msgid="8939888732119726665">"Dra från ikonen och öppna röstassistenten"</string>
- <string name="camera_hint" msgid="7939688436797157483">"Dra från ikonen och öppna kameran"</string>
+ <string name="keyguard_unlock" msgid="8043466894212841998">"Svep uppåt om du vill låsa upp"</string>
+ <string name="phone_hint" msgid="4872890986869209950">"Svep från ikonen och öppna telefonen"</string>
+ <string name="voice_hint" msgid="8939888732119726665">"Svep från ikonen och öppna röstassistenten"</string>
+ <string name="camera_hint" msgid="7939688436797157483">"Svep från ikonen och öppna kameran"</string>
<string name="interruption_level_none_with_warning" msgid="5114872171614161084">"Total tystnad. Även skärmläsningsprogram tystas."</string>
<string name="interruption_level_none" msgid="6000083681244492992">"Helt tyst"</string>
<string name="interruption_level_priority" msgid="6426766465363855505">"Bara prioriterade"</string>
@@ -325,6 +325,8 @@
<string name="interruption_level_priority_twoline" msgid="1564715335217164124">"Endast\nprioriterade"</string>
<string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"Endast\nalarm"</string>
<string name="keyguard_indication_charging_time" msgid="1757251776872835768">"Laddar (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> tills batteriet är fulladdat)"</string>
+ <string name="keyguard_indication_charging_time_fast" msgid="9018981952053914986">"Laddas snabbt (batteriet fulladdat om <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>)"</string>
+ <string name="keyguard_indication_charging_time_slowly" msgid="955252797961724952">"Laddas sakta (batteriet fulladdat om <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>)"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="7305948938141024937">"Byt användare"</string>
<string name="accessibility_multi_user_switch_switcher_with_current" msgid="8434880595284601601">"Byt användare. Aktuell användare: <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_inactive" msgid="1424081831468083402">"Aktuell användare <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
@@ -385,7 +387,7 @@
<string name="accessibility_volume_expand" msgid="5946812790999244205">"Utöka"</string>
<string name="accessibility_volume_collapse" msgid="3609549593031810875">"Komprimera"</string>
<string name="screen_pinning_title" msgid="3273740381976175811">"Skärmen har fästs"</string>
- <string name="screen_pinning_description" msgid="1346522416878235405">"Detta visar skärmen tills du lossar den. Tryck länge på bakåtknappen och Översikt samtidigt om du vill lossa skärmen."</string>
+ <string name="screen_pinning_description" msgid="1346522416878235405">"Med den här funktionen är skärmen synlig tills du lossar den. Tryck länge på Tillbaka och Översikt samtidigt om du vill lossa skärmen."</string>
<string name="screen_pinning_description_accessible" msgid="8518446209564202557">"Detta visar skärmen tills du lossar den. Tryck länge på Översikt om du vill lossa skärmen."</string>
<string name="screen_pinning_positive" msgid="3783985798366751226">"OK"</string>
<string name="screen_pinning_negative" msgid="3741602308343880268">"Nej tack"</string>
@@ -426,4 +428,7 @@
<string name="tuner_toast" msgid="603429811084428439">"Grattis! Inställningar för systemgränssnitt har lagts till i inställningarna."</string>
<string name="remove_from_settings" msgid="8389591916603406378">"Ta bort från inställningarna"</string>
<string name="remove_from_settings_prompt" msgid="6069085993355887748">"Vill du ta bort inställningar för systemgränssnitt från inställningarna och sluta använda alla tillhörande funktioner?"</string>
+ <string name="enable_bluetooth_title" msgid="5027037706500635269">"Vill du aktivera Bluetooth?"</string>
+ <string name="enable_bluetooth_message" msgid="9106595990708985385">"Om du vill ansluta tangentbordet till surfplattan måste du först aktivera Bluetooth."</string>
+ <string name="enable_bluetooth_confirmation_ok" msgid="6258074250948309715">"Aktivera"</string>
</resources>
diff --git a/packages/SystemUI/res/values-sw/strings.xml b/packages/SystemUI/res/values-sw/strings.xml
index 2e15c61..d63e135 100644
--- a/packages/SystemUI/res/values-sw/strings.xml
+++ b/packages/SystemUI/res/values-sw/strings.xml
@@ -325,6 +325,8 @@
<string name="interruption_level_priority_twoline" msgid="1564715335217164124">"Kipaumbele\npekee"</string>
<string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"Kengele\npekee"</string>
<string name="keyguard_indication_charging_time" msgid="1757251776872835768">"Inachaji (Imebakisha <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> ijae)"</string>
+ <string name="keyguard_indication_charging_time_fast" msgid="9018981952053914986">"Inachaji kwa kasi (itajaa baada ya <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>)"</string>
+ <string name="keyguard_indication_charging_time_slowly" msgid="955252797961724952">"Inachaji pole pole (itajaa baada ya <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>)"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="7305948938141024937">"Badili mtumiaji"</string>
<string name="accessibility_multi_user_switch_switcher_with_current" msgid="8434880595284601601">"Badili mtumiaji, mtumiaji wa sasa <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_inactive" msgid="1424081831468083402">"Mtumiaji wa sasa <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
@@ -426,4 +428,7 @@
<string name="tuner_toast" msgid="603429811084428439">"Hongera! Kipokea Ishara cha System UI kimeongezwa kwenye Mipangilio"</string>
<string name="remove_from_settings" msgid="8389591916603406378">"Ondoa kwenye Mipangilio"</string>
<string name="remove_from_settings_prompt" msgid="6069085993355887748">"Je, ungependa kuondoa Kipokea ishara cha SystemUI kwenye Mipangilio na uache kutumia vipengele vyake vyote?"</string>
+ <string name="enable_bluetooth_title" msgid="5027037706500635269">"Je, ungependa kuwasha Bluetooth?"</string>
+ <string name="enable_bluetooth_message" msgid="9106595990708985385">"Ili uunganishe Kibodi yako kwenye kompyuta yako kibao, lazima kwanza uwashe Bluetooth."</string>
+ <string name="enable_bluetooth_confirmation_ok" msgid="6258074250948309715">"Washa"</string>
</resources>
diff --git a/packages/SystemUI/res/values-ta-rIN/strings.xml b/packages/SystemUI/res/values-ta-rIN/strings.xml
index 4ed5e02..3e1df8c 100644
--- a/packages/SystemUI/res/values-ta-rIN/strings.xml
+++ b/packages/SystemUI/res/values-ta-rIN/strings.xml
@@ -325,6 +325,8 @@
<string name="interruption_level_priority_twoline" msgid="1564715335217164124">"முன்னுரிமைகள்\nமட்டும்"</string>
<string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"அலாரங்கள்\nமட்டும்"</string>
<string name="keyguard_indication_charging_time" msgid="1757251776872835768">"சார்ஜாகிறது (முழு சார்ஜிற்கு <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> ஆகும்)"</string>
+ <string name="keyguard_indication_charging_time_fast" msgid="9018981952053914986">"வேகமாக சார்ஜாகிறது (முழு சார்ஜிற்கு: <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>)"</string>
+ <string name="keyguard_indication_charging_time_slowly" msgid="955252797961724952">"மெதுவாக சார்ஜாகிறது (முழு சார்ஜிற்கு: <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>)"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="7305948938141024937">"பயனரை மாற்று"</string>
<string name="accessibility_multi_user_switch_switcher_with_current" msgid="8434880595284601601">"பயனரை மாற்று, தற்போதைய பயனர் <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_inactive" msgid="1424081831468083402">"தற்போதைய பயனர்: <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
@@ -426,4 +428,7 @@
<string name="tuner_toast" msgid="603429811084428439">"வாழ்த்துகள்! அமைப்புகளில் System UI Tuner சேர்க்கப்பட்டது"</string>
<string name="remove_from_settings" msgid="8389591916603406378">"அமைப்புகளிலிருந்து அகற்று"</string>
<string name="remove_from_settings_prompt" msgid="6069085993355887748">"அமைப்புகளிலிருந்து System UI Tunerஐ அகற்றிவிட்டு, அதன் எல்லா அம்சங்களையும் பயன்படுத்துவதை நிறுத்தவா?"</string>
+ <string name="enable_bluetooth_title" msgid="5027037706500635269">"புளூடூத்தை இயக்கவா?"</string>
+ <string name="enable_bluetooth_message" msgid="9106595990708985385">"உங்கள் டேப்லெட்டுடன் விசைப்பலகையை இணைக்க, முதலில் புளூடூத்தை இயக்க வேண்டும்."</string>
+ <string name="enable_bluetooth_confirmation_ok" msgid="6258074250948309715">"இயக்கு"</string>
</resources>
diff --git a/packages/SystemUI/res/values-te-rIN/strings.xml b/packages/SystemUI/res/values-te-rIN/strings.xml
index 6b1c762..ca3011a 100644
--- a/packages/SystemUI/res/values-te-rIN/strings.xml
+++ b/packages/SystemUI/res/values-te-rIN/strings.xml
@@ -325,6 +325,8 @@
<string name="interruption_level_priority_twoline" msgid="1564715335217164124">"ప్రాధాన్యమైనవి\nమాత్రమే"</string>
<string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"అలారాలు\nమాత్రమే"</string>
<string name="keyguard_indication_charging_time" msgid="1757251776872835768">"ఛార్జ్ అవుతోంది (పూర్తిగా నిండటానికి <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>)"</string>
+ <string name="keyguard_indication_charging_time_fast" msgid="9018981952053914986">"వేగంగా ఛార్జ్ అవుతోంది (నిండటానికి <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>)"</string>
+ <string name="keyguard_indication_charging_time_slowly" msgid="955252797961724952">"నెమ్మదిగా ఛార్జ్ అవుతోంది (నిండటానికి <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>)"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="7305948938141024937">"వినియోగదారుని మార్చు"</string>
<string name="accessibility_multi_user_switch_switcher_with_current" msgid="8434880595284601601">"వినియోగదారుని మార్చు, ప్రస్తుత వినియోగదారు <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_inactive" msgid="1424081831468083402">"ప్రస్తుత వినియోగదారు <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
@@ -426,4 +428,7 @@
<string name="tuner_toast" msgid="603429811084428439">"అభినందనలు! సెట్టింగ్లకు సిస్టమ్ UI ట్యూనర్ జోడించబడింది"</string>
<string name="remove_from_settings" msgid="8389591916603406378">"సెట్టింగ్ల నుండి తీసివేయి"</string>
<string name="remove_from_settings_prompt" msgid="6069085993355887748">"సిస్టమ్ UI ట్యూనర్ను సెట్టింగ్ల నుండి తీసివేసి, దాని అన్ని లక్షణాలను ఉపయోగించడం ఆపివేయాలా?"</string>
+ <string name="enable_bluetooth_title" msgid="5027037706500635269">"బ్లూటూత్ ఆన్ చేయాలా?"</string>
+ <string name="enable_bluetooth_message" msgid="9106595990708985385">"మీ కీబోర్డ్ను మీ టాబ్లెట్తో కనెక్ట్ చేయడానికి, మీరు ముందుగా బ్లూటూత్ ఆన్ చేయాలి."</string>
+ <string name="enable_bluetooth_confirmation_ok" msgid="6258074250948309715">"ఆన్ చేయి"</string>
</resources>
diff --git a/packages/SystemUI/res/values-th/strings.xml b/packages/SystemUI/res/values-th/strings.xml
index 29437c5..2b56af6 100644
--- a/packages/SystemUI/res/values-th/strings.xml
+++ b/packages/SystemUI/res/values-th/strings.xml
@@ -325,6 +325,8 @@
<string name="interruption_level_priority_twoline" msgid="1564715335217164124">"เฉพาะเรื่อง\nสำคัญ"</string>
<string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"เฉพาะปลุก\nเท่านั้น"</string>
<string name="keyguard_indication_charging_time" msgid="1757251776872835768">"กำลังชาร์จ (อีก <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> เต็ม)"</string>
+ <string name="keyguard_indication_charging_time_fast" msgid="9018981952053914986">"กำลังชาร์จอย่างรวดเร็ว (อีก <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> จะเต็ม)"</string>
+ <string name="keyguard_indication_charging_time_slowly" msgid="955252797961724952">"กำลังชาร์จอย่างช้าๆ (อีก <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> จะเต็ม)"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="7305948938141024937">"สลับผู้ใช้"</string>
<string name="accessibility_multi_user_switch_switcher_with_current" msgid="8434880595284601601">"เปลี่ยนผู้ใช้จากผู้ใช้ปัจจุบัน <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_inactive" msgid="1424081831468083402">"ผู้ใช้ปัจจุบัน <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
@@ -426,4 +428,7 @@
<string name="tuner_toast" msgid="603429811084428439">"ยินดีด้วย! เพิ่มตัวรับสัญญาณ UI ระบบไปยังการตั้งค่าแล้ว"</string>
<string name="remove_from_settings" msgid="8389591916603406378">"นำออกจากการตั้งค่า"</string>
<string name="remove_from_settings_prompt" msgid="6069085993355887748">"นำตัวรับสัญญาณ UI ระบบออกจากการตั้งค่าและหยุดใช้คุณลักษณะทั้งหมดของตัวรับสัญญาณใช่ไหม"</string>
+ <string name="enable_bluetooth_title" msgid="5027037706500635269">"เปิดบลูทูธไหม"</string>
+ <string name="enable_bluetooth_message" msgid="9106595990708985385">"หากต้องการเชื่อมต่อแป้นพิมพ์กับแท็บเล็ต คุณต้องเปิดบลูทูธก่อน"</string>
+ <string name="enable_bluetooth_confirmation_ok" msgid="6258074250948309715">"เปิด"</string>
</resources>
diff --git a/packages/SystemUI/res/values-tl/strings.xml b/packages/SystemUI/res/values-tl/strings.xml
index cde538c..ebcfda7 100644
--- a/packages/SystemUI/res/values-tl/strings.xml
+++ b/packages/SystemUI/res/values-tl/strings.xml
@@ -325,6 +325,8 @@
<string name="interruption_level_priority_twoline" msgid="1564715335217164124">"Priyoridad\nlang"</string>
<string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"Mga alarm\nlang"</string>
<string name="keyguard_indication_charging_time" msgid="1757251776872835768">"Nagtsa-charge (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> hanggang mapuno)"</string>
+ <string name="keyguard_indication_charging_time_fast" msgid="9018981952053914986">"Mabilis mag-charge (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> hanggang sa mapuno)"</string>
+ <string name="keyguard_indication_charging_time_slowly" msgid="955252797961724952">"Mabagal mag-charge (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> hanggang sa mapuno)"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="7305948938141024937">"Magpalit ng user"</string>
<string name="accessibility_multi_user_switch_switcher_with_current" msgid="8434880595284601601">"Magpalit ng user, kasalukuyang user <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_inactive" msgid="1424081831468083402">"Kasalukuyang user <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
@@ -426,4 +428,7 @@
<string name="tuner_toast" msgid="603429811084428439">"Binabati kita! Naidagdag na ang Tuner ng System UI sa Mga Setting"</string>
<string name="remove_from_settings" msgid="8389591916603406378">"Alisin sa Mga Setting"</string>
<string name="remove_from_settings_prompt" msgid="6069085993355887748">"Alisin ang Tuner ng System UI sa Mga Setting at ihinto ang paggamit ng lahat ng feature nito?"</string>
+ <string name="enable_bluetooth_title" msgid="5027037706500635269">"I-on ang Bluetooth?"</string>
+ <string name="enable_bluetooth_message" msgid="9106595990708985385">"Upang ikonekta ang iyong keyboard sa iyong tablet, kailangan mo munang i-on ang Bluetooth."</string>
+ <string name="enable_bluetooth_confirmation_ok" msgid="6258074250948309715">"I-on"</string>
</resources>
diff --git a/packages/SystemUI/res/values-tr/strings.xml b/packages/SystemUI/res/values-tr/strings.xml
index 544a28d..f213b50 100644
--- a/packages/SystemUI/res/values-tr/strings.xml
+++ b/packages/SystemUI/res/values-tr/strings.xml
@@ -203,10 +203,10 @@
<string name="accessibility_quick_settings_close" msgid="3115847794692516306">"Paneli kapat."</string>
<string name="accessibility_quick_settings_more_time" msgid="3659274935356197708">"Daha uzun süre."</string>
<string name="accessibility_quick_settings_less_time" msgid="2404728746293515623">"Daha kısa süre."</string>
- <string name="accessibility_quick_settings_flashlight_off" msgid="4936432000069786988">"Flaş ışığı kapalı."</string>
- <string name="accessibility_quick_settings_flashlight_on" msgid="2003479320007841077">"Flaş ışığı açık."</string>
- <string name="accessibility_quick_settings_flashlight_changed_off" msgid="3303701786768224304">"Flaş ışığı kapatıldı."</string>
- <string name="accessibility_quick_settings_flashlight_changed_on" msgid="6531793301533894686">"Flaş ışığı açıldı."</string>
+ <string name="accessibility_quick_settings_flashlight_off" msgid="4936432000069786988">"El feneri kapalı."</string>
+ <string name="accessibility_quick_settings_flashlight_on" msgid="2003479320007841077">"El feneri açık."</string>
+ <string name="accessibility_quick_settings_flashlight_changed_off" msgid="3303701786768224304">"El feneri kapatıldı."</string>
+ <string name="accessibility_quick_settings_flashlight_changed_on" msgid="6531793301533894686">"El feneri açıldı."</string>
<string name="accessibility_quick_settings_color_inversion_changed_off" msgid="4406577213290173911">"Renkleri ters çevirme işlevi kapatıldı."</string>
<string name="accessibility_quick_settings_color_inversion_changed_on" msgid="6897462320184911126">"Renkleri ters çevirme işlevi açıldı."</string>
<string name="accessibility_quick_settings_hotspot_changed_off" msgid="5004708003447561394">"Mobil hotspot kapatıldı."</string>
@@ -325,6 +325,8 @@
<string name="interruption_level_priority_twoline" msgid="1564715335217164124">"Yalnızca\nöncelik"</string>
<string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"Yalnızca\nalarmlar"</string>
<string name="keyguard_indication_charging_time" msgid="1757251776872835768">"Şarj oluyor (tamamen dolmasına <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> kaldı)"</string>
+ <string name="keyguard_indication_charging_time_fast" msgid="9018981952053914986">"Hızlı şarj oluyor (tam dolmasına <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> kaldı)"</string>
+ <string name="keyguard_indication_charging_time_slowly" msgid="955252797961724952">"Yavaş şarj oluyor (tam dolmasına <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> kaldı)"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="7305948938141024937">"Kullanıcı değiştirme"</string>
<string name="accessibility_multi_user_switch_switcher_with_current" msgid="8434880595284601601">"Kullanıcı değiştir. Geçerli kullanıcı: <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_inactive" msgid="1424081831468083402">"Geçerli kullanıcı: <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
@@ -426,4 +428,7 @@
<string name="tuner_toast" msgid="603429811084428439">"Tebrikler! Sistem Kullanıcı Arayüzü Ayarlayıcı Ayarlar\'a eklendi"</string>
<string name="remove_from_settings" msgid="8389591916603406378">"Ayarlar\'dan kaldır"</string>
<string name="remove_from_settings_prompt" msgid="6069085993355887748">"Sistem Kullanıcı Arayüzü Ayarlayıcısı Ayarlar\'dan kaldırılsın ve tüm özelliklerinin kullanılması durdurulsun mu?"</string>
+ <string name="enable_bluetooth_title" msgid="5027037706500635269">"Bluetooth açılsın mı?"</string>
+ <string name="enable_bluetooth_message" msgid="9106595990708985385">"Klavyenizi tabletinize bağlamak için önce Bluetooth\'u açmanız gerekir."</string>
+ <string name="enable_bluetooth_confirmation_ok" msgid="6258074250948309715">"Aç"</string>
</resources>
diff --git a/packages/SystemUI/res/values-uk/strings.xml b/packages/SystemUI/res/values-uk/strings.xml
index 4f50787..1ac0ce1 100644
--- a/packages/SystemUI/res/values-uk/strings.xml
+++ b/packages/SystemUI/res/values-uk/strings.xml
@@ -152,7 +152,7 @@
<string name="accessibility_airplane_mode" msgid="834748999790763092">"Режим польоту."</string>
<string name="accessibility_no_sims" msgid="3957997018324995781">"Немає SIM-карти."</string>
<string name="accessibility_carrier_network_change_mode" msgid="4017301580441304305">"Змінення мережі оператора."</string>
- <string name="accessibility_battery_level" msgid="7451474187113371965">"Заряд акумулятора: <xliff:g id="NUMBER">%d</xliff:g>."</string>
+ <string name="accessibility_battery_level" msgid="7451474187113371965">"Заряд акумулятора у відсотках: <xliff:g id="NUMBER">%d</xliff:g>."</string>
<string name="accessibility_settings_button" msgid="799583911231893380">"Налаштування системи."</string>
<string name="accessibility_notifications_button" msgid="4498000369779421892">"Сповіщення."</string>
<string name="accessibility_remove_notification" msgid="3603099514902182350">"Очистити сповіщення."</string>
@@ -270,7 +270,7 @@
<string name="quick_settings_cast_title" msgid="7709016546426454729">"Трансляція"</string>
<string name="quick_settings_casting" msgid="6601710681033353316">"Трансляція"</string>
<string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"Пристрій без назви"</string>
- <string name="quick_settings_cast_device_default_description" msgid="2484573682378634413">"Можна транслювати"</string>
+ <string name="quick_settings_cast_device_default_description" msgid="2484573682378634413">"Готово до трансляції"</string>
<string name="quick_settings_cast_detail_empty_text" msgid="311785821261640623">"Немає пристроїв"</string>
<string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Яскравість"</string>
<string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"АВТО"</string>
@@ -327,6 +327,8 @@
<string name="interruption_level_priority_twoline" msgid="1564715335217164124">"Лише\nприорітетні"</string>
<string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"Лише\nсигнали"</string>
<string name="keyguard_indication_charging_time" msgid="1757251776872835768">"Заряджання (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> до повного зарядження)"</string>
+ <string name="keyguard_indication_charging_time_fast" msgid="9018981952053914986">"Швидке заряджання (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> до повного заряду)"</string>
+ <string name="keyguard_indication_charging_time_slowly" msgid="955252797961724952">"Повільне заряджання (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> до повного заряду)"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="7305948938141024937">"Змінити користувача"</string>
<string name="accessibility_multi_user_switch_switcher_with_current" msgid="8434880595284601601">"Змінити користувача, поточний користувач – <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_inactive" msgid="1424081831468083402">"Поточний користувач: <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
@@ -428,4 +430,7 @@
<string name="tuner_toast" msgid="603429811084428439">"Вітаємо! System UI Tuner установлено в додатку Налаштування"</string>
<string name="remove_from_settings" msgid="8389591916603406378">"Видалити з додатка Налаштування"</string>
<string name="remove_from_settings_prompt" msgid="6069085993355887748">"Видалити інструмент System UI Tuner із додатка Налаштування та припинити користуватися всіма його функціями?"</string>
+ <string name="enable_bluetooth_title" msgid="5027037706500635269">"Увімкнути Bluetooth?"</string>
+ <string name="enable_bluetooth_message" msgid="9106595990708985385">"Щоб під’єднати клавіатуру до планшета, спершу потрібно ввімкнути Bluetooth."</string>
+ <string name="enable_bluetooth_confirmation_ok" msgid="6258074250948309715">"Увімкнути"</string>
</resources>
diff --git a/packages/SystemUI/res/values-ur-rPK/strings.xml b/packages/SystemUI/res/values-ur-rPK/strings.xml
index 269bb1f..2c34cfd 100644
--- a/packages/SystemUI/res/values-ur-rPK/strings.xml
+++ b/packages/SystemUI/res/values-ur-rPK/strings.xml
@@ -325,6 +325,8 @@
<string name="interruption_level_priority_twoline" msgid="1564715335217164124">"صرف\nترجیحی"</string>
<string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"صرف\nالارمز"</string>
<string name="keyguard_indication_charging_time" msgid="1757251776872835768">"چارج ہو رہا ہے (مکمل ہونے تک <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> باقی ہیں)"</string>
+ <string name="keyguard_indication_charging_time_fast" msgid="9018981952053914986">"تیزی سے چارج ہو رہا ہے (مکمل ہونے میں <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>)"</string>
+ <string name="keyguard_indication_charging_time_slowly" msgid="955252797961724952">"آہستہ چارج ہو رہا ہے (مکمل ہونے میں <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>)"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="7305948938141024937">"صارف سوئچ کریں"</string>
<string name="accessibility_multi_user_switch_switcher_with_current" msgid="8434880595284601601">"صارف سوئچ کریں، موجودہ صارف <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_inactive" msgid="1424081831468083402">"موجودہ صارف <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
@@ -426,4 +428,7 @@
<string name="tuner_toast" msgid="603429811084428439">"مبارک ہو! سسٹم UI ٹیونر کو ترتیبات میں شامل کر دیا گیا ہے"</string>
<string name="remove_from_settings" msgid="8389591916603406378">"ترتیبات سے ہٹائیں"</string>
<string name="remove_from_settings_prompt" msgid="6069085993355887748">"ترتیبات سے سسٹم UI ٹیونر کو ہٹائیں اور اس کی سبھی خصوصیات کا استعمال بند کریں؟"</string>
+ <string name="enable_bluetooth_title" msgid="5027037706500635269">"بلوٹوتھ آن کریں؟"</string>
+ <string name="enable_bluetooth_message" msgid="9106595990708985385">"اپنے کی بورڈ کو اپنے ٹیبلٹ کے ساتھ منسلک کرنے کیلئے پہلے آپ کو اپنا بلو ٹوتھ آن کرنا ہو گا۔"</string>
+ <string name="enable_bluetooth_confirmation_ok" msgid="6258074250948309715">"آن کریں"</string>
</resources>
diff --git a/packages/SystemUI/res/values-uz-rUZ/strings.xml b/packages/SystemUI/res/values-uz-rUZ/strings.xml
index 63248c3..f39c64f 100644
--- a/packages/SystemUI/res/values-uz-rUZ/strings.xml
+++ b/packages/SystemUI/res/values-uz-rUZ/strings.xml
@@ -29,7 +29,7 @@
<item quantity="other">Umumiy ma’lumot bo‘limida %d ta ekran bor</item>
<item quantity="one">Umumiy ma’lumot bo‘limida 1 ta ekran bor</item>
</plurals>
- <string name="status_bar_no_notifications_title" msgid="4755261167193833213">"Eslatmalar - yo‘q"</string>
+ <string name="status_bar_no_notifications_title" msgid="4755261167193833213">"Bildirishnomalar yo‘q"</string>
<string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"Joriy"</string>
<string name="status_bar_latest_events_title" msgid="6594767438577593172">"Eslatmalar"</string>
<string name="battery_low_title" msgid="6456385927409742437">"Batareya quvvati kam"</string>
@@ -82,7 +82,7 @@
<string name="accessibility_home" msgid="8217216074895377641">"Uyga"</string>
<string name="accessibility_menu" msgid="316839303324695949">"Menyu"</string>
<string name="accessibility_recent" msgid="5208608566793607626">"Umumiy nazar"</string>
- <string name="accessibility_search_light" msgid="1103867596330271848">"Izlash"</string>
+ <string name="accessibility_search_light" msgid="1103867596330271848">"Qidirish"</string>
<string name="accessibility_camera_button" msgid="8064671582820358152">"Kamera"</string>
<string name="accessibility_phone_button" msgid="6738112589538563574">"Telefon"</string>
<string name="accessibility_voice_assist_button" msgid="487611083884852965">"Ovozli yordam"</string>
@@ -145,10 +145,10 @@
<string name="accessibility_data_connection_roaming" msgid="5977362333466556094">"Rouming"</string>
<string name="accessibility_data_connection_edge" msgid="4477457051631979278">"Edge"</string>
<string name="accessibility_data_connection_wifi" msgid="2324496756590645221">"Wi-Fi"</string>
- <string name="accessibility_no_sim" msgid="8274017118472455155">"SIM-karta yo‘q."</string>
+ <string name="accessibility_no_sim" msgid="8274017118472455155">"SIM karta yo‘q."</string>
<string name="accessibility_bluetooth_tether" msgid="4102784498140271969">"Bluetooth modem"</string>
<string name="accessibility_airplane_mode" msgid="834748999790763092">"Parvoz rejimi"</string>
- <string name="accessibility_no_sims" msgid="3957997018324995781">"Hech qanday SIM-karta yo‘q."</string>
+ <string name="accessibility_no_sims" msgid="3957997018324995781">"Hech qanday SIM karta yo‘q."</string>
<string name="accessibility_carrier_network_change_mode" msgid="4017301580441304305">"Mobil tarmoqni o‘zgartirish"</string>
<string name="accessibility_battery_level" msgid="7451474187113371965">"Batareya <xliff:g id="NUMBER">%d</xliff:g> foiz."</string>
<string name="accessibility_settings_button" msgid="799583911231893380">"Tizim sozlamalari."</string>
@@ -227,10 +227,10 @@
<string name="accessibility_clear_all" msgid="5235938559247164925">"Barcha eslatmalarni tozalash."</string>
<string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"Bildirishnoma sozlamalari"</string>
<string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"<xliff:g id="APP_NAME">%s</xliff:g> sozlamalari"</string>
- <string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Ekran avtomatik ravishda aylanadi."</string>
+ <string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Ekran avtomatik buriladi."</string>
<string name="accessibility_rotation_lock_on_landscape" msgid="6731197337665366273">"Ekran eniga holatida qulflandi."</string>
<string name="accessibility_rotation_lock_on_portrait" msgid="5809367521644012115">"Ekran bo‘yiga holatida qulflandi."</string>
- <string name="accessibility_rotation_lock_off_changed" msgid="8134601071026305153">"Ekran endi avtomatik ravishda aylanadi."</string>
+ <string name="accessibility_rotation_lock_off_changed" msgid="8134601071026305153">"Ekran endi avtomatik buriladi."</string>
<string name="accessibility_rotation_lock_on_landscape_changed" msgid="3135965553707519743">"Ekran yotiq holatda aylanmaydigan qilindi."</string>
<string name="accessibility_rotation_lock_on_portrait_changed" msgid="8922481981834012126">"Ekran tik holatda aylanmaydigan qilindi."</string>
<string name="dessert_case" msgid="1295161776223959221">"Dessert Case"</string>
@@ -245,7 +245,7 @@
<string name="quick_settings_bluetooth_off_label" msgid="8159652146149219937">"Bluetooth o‘chirilgan"</string>
<string name="quick_settings_bluetooth_detail_empty_text" msgid="4910015762433302860">"Ulangan qurilmalar topilmadi"</string>
<string name="quick_settings_brightness_label" msgid="6968372297018755815">"Yorqinlik"</string>
- <string name="quick_settings_rotation_unlocked_label" msgid="7305323031808150099">"Auto-aylantirish"</string>
+ <string name="quick_settings_rotation_unlocked_label" msgid="7305323031808150099">"Avtomatik burish"</string>
<string name="quick_settings_rotation_locked_label" msgid="6359205706154282377">"Aylanmaydigan qilingan"</string>
<string name="quick_settings_rotation_locked_portrait_label" msgid="5102691921442135053">"Bo‘yiga"</string>
<string name="quick_settings_rotation_locked_landscape_label" msgid="8553157770061178719">"Eniga"</string>
@@ -303,7 +303,7 @@
<string name="expanded_header_battery_charging_with_time" msgid="457559884275395376">"<xliff:g id="CHARGING_TIME">%s</xliff:g>da to‘ladi"</string>
<string name="expanded_header_battery_not_charging" msgid="4798147152367049732">"Quvvat olmayapti"</string>
<string name="ssl_ca_cert_warning" msgid="9005954106902053641">"Tarmoq nazorat\nostida bo‘lishi mumkin"</string>
- <string name="description_target_search" msgid="3091587249776033139">"Izlash"</string>
+ <string name="description_target_search" msgid="3091587249776033139">"Qidirish"</string>
<string name="description_direction_up" msgid="7169032478259485180">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> uchun yuqoriga suring."</string>
<string name="description_direction_left" msgid="7207478719805562165">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> uchun chapga suring."</string>
<string name="zen_priority_introduction" msgid="3070506961866919502">"Turli ovoz va tebranishlar endi sizni bezovta qilmaydi. Biroq uyg‘otkich signallari, eslatmalar, tadbirlar haqidagi bildirishnomalar va siz tanlagan abonentlardan kelgan qo‘ng‘iroqlar bundan mustasno."</string>
@@ -325,6 +325,8 @@
<string name="interruption_level_priority_twoline" msgid="1564715335217164124">"Faqat\nmuhimlar"</string>
<string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"Faqat\nsignallar"</string>
<string name="keyguard_indication_charging_time" msgid="1757251776872835768">"Quvvat olmoqda (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>da to‘ladi)"</string>
+ <string name="keyguard_indication_charging_time_fast" msgid="9018981952053914986">"Tez quvvat olmoqda (to‘lishiga <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> qoldi)"</string>
+ <string name="keyguard_indication_charging_time_slowly" msgid="955252797961724952">"Sekin quvvat olmoqda (to‘lishiga <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> qoldi)"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="7305948938141024937">"Foydalanuvchini almashtirish"</string>
<string name="accessibility_multi_user_switch_switcher_with_current" msgid="8434880595284601601">"Foydalanuvchini o‘zgartirish. Joriy foydalanuvchi – <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_inactive" msgid="1424081831468083402">"Joriy foydalanuvchi <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
@@ -426,4 +428,7 @@
<string name="tuner_toast" msgid="603429811084428439">"Tabriklaymiz! System UI Tuner Sozlamalarga qo‘shildi."</string>
<string name="remove_from_settings" msgid="8389591916603406378">"Sozlamalardan olib tashlash"</string>
<string name="remove_from_settings_prompt" msgid="6069085993355887748">"System UI Tuner Sozlamalardan olib tashlanib, uning barcha funksiyalaridan foydalanish to‘xtatilsinmi?"</string>
+ <string name="enable_bluetooth_title" msgid="5027037706500635269">"Bluetooth yoqilsinmi?"</string>
+ <string name="enable_bluetooth_message" msgid="9106595990708985385">"Klaviaturani planshetingizga ulash uchun Bluetooth xizmatini yoqishingiz kerak."</string>
+ <string name="enable_bluetooth_confirmation_ok" msgid="6258074250948309715">"Yoqish"</string>
</resources>
diff --git a/packages/SystemUI/res/values-vi/strings.xml b/packages/SystemUI/res/values-vi/strings.xml
index 158d2a6..547925e 100644
--- a/packages/SystemUI/res/values-vi/strings.xml
+++ b/packages/SystemUI/res/values-vi/strings.xml
@@ -325,6 +325,8 @@
<string name="interruption_level_priority_twoline" msgid="1564715335217164124">"Chỉ\nưu tiên"</string>
<string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"Chỉ\nbáo thức"</string>
<string name="keyguard_indication_charging_time" msgid="1757251776872835768">"Đang sạc (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> cho đến khi đầy)"</string>
+ <string name="keyguard_indication_charging_time_fast" msgid="9018981952053914986">"Sạc nhanh (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> cho tới khi đầy)"</string>
+ <string name="keyguard_indication_charging_time_slowly" msgid="955252797961724952">"Sạc chậm (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> cho tới khi đầy)"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="7305948938141024937">"Chuyển đổi người dùng"</string>
<string name="accessibility_multi_user_switch_switcher_with_current" msgid="8434880595284601601">"Chuyển người dùng, người dùng hiện tại <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_inactive" msgid="1424081831468083402">"Người dùng hiện tại <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
@@ -426,4 +428,7 @@
<string name="tuner_toast" msgid="603429811084428439">"Xin chúc mừng! Bộ điều hướng giao diện người dùng hệ thống đã được thêm vào Cài đặt"</string>
<string name="remove_from_settings" msgid="8389591916603406378">"Xóa khỏi Cài đặt"</string>
<string name="remove_from_settings_prompt" msgid="6069085993355887748">"Xóa Bộ điều hướng giao diện người dùng hệ thống khỏi Cài đặt và ngừng sử dụng tất cả tính năng của ứng dụng này?"</string>
+ <string name="enable_bluetooth_title" msgid="5027037706500635269">"Bật Bluetooth?"</string>
+ <string name="enable_bluetooth_message" msgid="9106595990708985385">"Để kết nối bàn phím với máy tính bảng, trước tiên, bạn phải bật Bluetooth."</string>
+ <string name="enable_bluetooth_confirmation_ok" msgid="6258074250948309715">"Bật"</string>
</resources>
diff --git a/packages/SystemUI/res/values-zh-rCN/strings.xml b/packages/SystemUI/res/values-zh-rCN/strings.xml
index 84e0eea..980da9d 100644
--- a/packages/SystemUI/res/values-zh-rCN/strings.xml
+++ b/packages/SystemUI/res/values-zh-rCN/strings.xml
@@ -64,7 +64,7 @@
<string name="usb_debugging_message" msgid="2220143855912376496">"这台计算机的 RSA 密钥指纹如下:\n<xliff:g id="FINGERPRINT">%1$s</xliff:g>"</string>
<string name="usb_debugging_always" msgid="303335496705863070">"一律允许使用这台计算机进行调试"</string>
<string name="usb_debugging_secondary_user_title" msgid="6353808721761220421">"不允许使用 USB 调试功能"</string>
- <string name="usb_debugging_secondary_user_message" msgid="6011931347142270156">"目前已登录此设备的用户无法开启 USB 调试功能。要使用此功能,请切换为主要用户“<xliff:g id="NAME">%s</xliff:g>”的帐户。"</string>
+ <string name="usb_debugging_secondary_user_message" msgid="6011931347142270156">"目前已登录此设备的用户无法开启 USB 调试功能。要使用此功能,请切换为主要用户“<xliff:g id="NAME">%s</xliff:g>”的帐号。"</string>
<string name="compat_mode_on" msgid="6623839244840638213">"缩放以填满屏幕"</string>
<string name="compat_mode_off" msgid="4434467572461327898">"拉伸以填满屏幕"</string>
<string name="screenshot_saving_ticker" msgid="7403652894056693515">"正在保存屏幕截图..."</string>
@@ -77,7 +77,7 @@
<string name="usb_preference_title" msgid="6551050377388882787">"USB文件传输选项"</string>
<string name="use_mtp_button_title" msgid="4333504413563023626">"作为媒体播放器(MTP)装载"</string>
<string name="use_ptp_button_title" msgid="7517127540301625751">"作为相机(PTP)装载"</string>
- <string name="installer_cd_button_title" msgid="2312667578562201583">"安装适用于Mac的Android文件传输应用"</string>
+ <string name="installer_cd_button_title" msgid="2312667578562201583">"安装适用于 Mac 的 Android 文件传输应用"</string>
<string name="accessibility_back" msgid="567011538994429120">"返回"</string>
<string name="accessibility_home" msgid="8217216074895377641">"主屏幕"</string>
<string name="accessibility_menu" msgid="316839303324695949">"菜单"</string>
@@ -150,9 +150,7 @@
<string name="accessibility_airplane_mode" msgid="834748999790763092">"飞行模式。"</string>
<string name="accessibility_no_sims" msgid="3957997018324995781">"没有 SIM 卡。"</string>
<string name="accessibility_carrier_network_change_mode" msgid="4017301580441304305">"运营商网络正在更改。"</string>
- <!-- String.format failed for translation -->
- <!-- no translation found for accessibility_battery_level (7451474187113371965) -->
- <skip />
+ <string name="accessibility_battery_level" msgid="7451474187113371965">"电池电量为百分之 <xliff:g id="NUMBER">%d</xliff:g>。"</string>
<string name="accessibility_settings_button" msgid="799583911231893380">"系统设置。"</string>
<string name="accessibility_notifications_button" msgid="4498000369779421892">"通知。"</string>
<string name="accessibility_remove_notification" msgid="3603099514902182350">"清除通知。"</string>
@@ -327,6 +325,8 @@
<string name="interruption_level_priority_twoline" msgid="1564715335217164124">"仅限\n优先打扰"</string>
<string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"仅限\n闹钟"</string>
<string name="keyguard_indication_charging_time" msgid="1757251776872835768">"正在充电(还需<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>充满)"</string>
+ <string name="keyguard_indication_charging_time_fast" msgid="9018981952053914986">"正在快速充电(还需<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>充满)"</string>
+ <string name="keyguard_indication_charging_time_slowly" msgid="955252797961724952">"正在慢速充电(还需<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>充满)"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="7305948938141024937">"切换用户"</string>
<string name="accessibility_multi_user_switch_switcher_with_current" msgid="8434880595284601601">"切换用户,当前用户为<xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_inactive" msgid="1424081831468083402">"当前用户为<xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
@@ -403,7 +403,7 @@
<string name="system_ui_tuner" msgid="708224127392452018">"系统界面调谐器"</string>
<string name="show_battery_percentage" msgid="5444136600512968798">"嵌入式显示电池电量百分比 显示嵌入的电池电量百分比"</string>
<string name="show_battery_percentage_summary" msgid="3215025775576786037">"未充电时在状态栏图标内显示电池电量百分比"</string>
- <string name="quick_settings" msgid="10042998191725428">"快速设置"</string>
+ <string name="quick_settings" msgid="10042998191725428">"快捷设置"</string>
<string name="status_bar" msgid="4877645476959324760">"状态栏"</string>
<string name="demo_mode" msgid="2389163018533514619">"演示模式"</string>
<string name="enable_demo_mode" msgid="4844205668718636518">"启用演示模式"</string>
@@ -418,7 +418,7 @@
<string name="zen_alarm_warning" msgid="444533119582244293">"您在<xliff:g id="WHEN">%1$s</xliff:g>将不会听到下次闹钟响铃"</string>
<string name="alarm_template" msgid="3980063409350522735">"<xliff:g id="WHEN">%1$s</xliff:g>"</string>
<string name="alarm_template_far" msgid="4242179982586714810">"<xliff:g id="WHEN">%1$s</xliff:g>"</string>
- <string name="accessibility_quick_settings_detail" msgid="2579369091672902101">"快速设置,<xliff:g id="TITLE">%s</xliff:g>。"</string>
+ <string name="accessibility_quick_settings_detail" msgid="2579369091672902101">"快捷设置,<xliff:g id="TITLE">%s</xliff:g>。"</string>
<string name="accessibility_status_bar_hotspot" msgid="4099381329956402865">"热点"</string>
<string name="accessibility_managed_profile" msgid="6613641363112584120">"工作资料"</string>
<string name="tuner_warning_title" msgid="7094689930793031682">"是否有趣完全取决于个人感觉"</string>
@@ -428,4 +428,7 @@
<string name="tuner_toast" msgid="603429811084428439">"恭喜!系统界面调谐器已添加到“设置”中"</string>
<string name="remove_from_settings" msgid="8389591916603406378">"从“设置”中移除"</string>
<string name="remove_from_settings_prompt" msgid="6069085993355887748">"要将系统界面调谐器从“设置”中移除,并停止使用所有相关功能吗?"</string>
+ <string name="enable_bluetooth_title" msgid="5027037706500635269">"要开启蓝牙吗?"</string>
+ <string name="enable_bluetooth_message" msgid="9106595990708985385">"要将您的键盘连接到平板电脑,您必须先开启蓝牙。"</string>
+ <string name="enable_bluetooth_confirmation_ok" msgid="6258074250948309715">"开启"</string>
</resources>
diff --git a/packages/SystemUI/res/values-zh-rHK/strings.xml b/packages/SystemUI/res/values-zh-rHK/strings.xml
index aacdd0e..a1b7191 100644
--- a/packages/SystemUI/res/values-zh-rHK/strings.xml
+++ b/packages/SystemUI/res/values-zh-rHK/strings.xml
@@ -150,9 +150,7 @@
<string name="accessibility_airplane_mode" msgid="834748999790763092">"飛航模式。"</string>
<string name="accessibility_no_sims" msgid="3957997018324995781">"沒有 SIM 卡。"</string>
<string name="accessibility_carrier_network_change_mode" msgid="4017301580441304305">"流動網絡供應商網絡正在變更。"</string>
- <!-- String.format failed for translation -->
- <!-- no translation found for accessibility_battery_level (7451474187113371965) -->
- <skip />
+ <string name="accessibility_battery_level" msgid="7451474187113371965">"電池電量為百分之 <xliff:g id="NUMBER">%d</xliff:g>。"</string>
<string name="accessibility_settings_button" msgid="799583911231893380">"系統設定"</string>
<string name="accessibility_notifications_button" msgid="4498000369779421892">"通知。"</string>
<string name="accessibility_remove_notification" msgid="3603099514902182350">"清除通知。"</string>
@@ -327,6 +325,8 @@
<string name="interruption_level_priority_twoline" msgid="1564715335217164124">"僅限\n優先"</string>
<string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"僅限\n鬧鐘"</string>
<string name="keyguard_indication_charging_time" msgid="1757251776872835768">"充電中 (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>後完成充電)"</string>
+ <string name="keyguard_indication_charging_time_fast" msgid="9018981952053914986">"正在快速充電 (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>後完成充電)"</string>
+ <string name="keyguard_indication_charging_time_slowly" msgid="955252797961724952">"正在緩慢充電 (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>後完成充電)"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="7305948938141024937">"切換使用者"</string>
<string name="accessibility_multi_user_switch_switcher_with_current" msgid="8434880595284601601">"切換使用者,目前使用者是<xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_inactive" msgid="1424081831468083402">"目前的使用者是 <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
@@ -428,4 +428,7 @@
<string name="tuner_toast" msgid="603429811084428439">"恭喜您!系統使用者介面調諧器已新增至「設定」中"</string>
<string name="remove_from_settings" msgid="8389591916603406378">"從「設定」移除"</string>
<string name="remove_from_settings_prompt" msgid="6069085993355887748">"要從「設定」移除系統使用者介面調諧器,並停止其所有功能嗎?"</string>
+ <string name="enable_bluetooth_title" msgid="5027037706500635269">"要開啟藍牙嗎?"</string>
+ <string name="enable_bluetooth_message" msgid="9106595990708985385">"如要將鍵盤連接至平板電腦,請先開啟藍牙。"</string>
+ <string name="enable_bluetooth_confirmation_ok" msgid="6258074250948309715">"開啟"</string>
</resources>
diff --git a/packages/SystemUI/res/values-zh-rTW/strings.xml b/packages/SystemUI/res/values-zh-rTW/strings.xml
index e0464b7..46bf52d 100644
--- a/packages/SystemUI/res/values-zh-rTW/strings.xml
+++ b/packages/SystemUI/res/values-zh-rTW/strings.xml
@@ -150,9 +150,7 @@
<string name="accessibility_airplane_mode" msgid="834748999790763092">"飛行模式。"</string>
<string name="accessibility_no_sims" msgid="3957997018324995781">"沒有 SIM 卡。"</string>
<string name="accessibility_carrier_network_change_mode" msgid="4017301580441304305">"行動通訊業者網路正在變更。"</string>
- <!-- String.format failed for translation -->
- <!-- no translation found for accessibility_battery_level (7451474187113371965) -->
- <skip />
+ <string name="accessibility_battery_level" msgid="7451474187113371965">"電池電量為百分之 <xliff:g id="NUMBER">%d</xliff:g>。"</string>
<string name="accessibility_settings_button" msgid="799583911231893380">"系統設定"</string>
<string name="accessibility_notifications_button" msgid="4498000369779421892">"通知。"</string>
<string name="accessibility_remove_notification" msgid="3603099514902182350">"清除通知。"</string>
@@ -327,6 +325,8 @@
<string name="interruption_level_priority_twoline" msgid="1564715335217164124">"僅允許\n優先通知"</string>
<string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"僅允許\n鬧鐘"</string>
<string name="keyguard_indication_charging_time" msgid="1757251776872835768">"充電中 (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>後充飽)"</string>
+ <string name="keyguard_indication_charging_time_fast" msgid="9018981952053914986">"快速充電中 (充飽需要 <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>)"</string>
+ <string name="keyguard_indication_charging_time_slowly" msgid="955252797961724952">"慢速充電中 (充飽需要 <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>)"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="7305948938141024937">"切換使用者"</string>
<string name="accessibility_multi_user_switch_switcher_with_current" msgid="8434880595284601601">"切換使用者,目前使用者是<xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_inactive" msgid="1424081831468083402">"目前使用者是「<xliff:g id="CURRENT_USER_NAME">%s</xliff:g>」"</string>
@@ -428,4 +428,7 @@
<string name="tuner_toast" msgid="603429811084428439">"恭喜!系統使用者介面調整精靈已新增到設定中"</string>
<string name="remove_from_settings" msgid="8389591916603406378">"從設定中移除"</string>
<string name="remove_from_settings_prompt" msgid="6069085993355887748">"要將系統使用者介面調整精靈從設定中移除,並停止使用所有相關功能嗎?"</string>
+ <string name="enable_bluetooth_title" msgid="5027037706500635269">"要開啟藍牙功能嗎?"</string>
+ <string name="enable_bluetooth_message" msgid="9106595990708985385">"如要將鍵盤連線到平板電腦,您必須先開啟藍牙。"</string>
+ <string name="enable_bluetooth_confirmation_ok" msgid="6258074250948309715">"開啟"</string>
</resources>
diff --git a/packages/SystemUI/res/values-zu/strings.xml b/packages/SystemUI/res/values-zu/strings.xml
index 9b491ba..67a49d4 100644
--- a/packages/SystemUI/res/values-zu/strings.xml
+++ b/packages/SystemUI/res/values-zu/strings.xml
@@ -325,6 +325,8 @@
<string name="interruption_level_priority_twoline" msgid="1564715335217164124">"Okubalulekile\nkuphela"</string>
<string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"Ama-alamu\nkuphela"</string>
<string name="keyguard_indication_charging_time" msgid="1757251776872835768">"Iyashaja (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> ize igcwale)"</string>
+ <string name="keyguard_indication_charging_time_fast" msgid="9018981952053914986">"Iyashaja ngokushesha (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> ize igcwale)"</string>
+ <string name="keyguard_indication_charging_time_slowly" msgid="955252797961724952">"Iyashaja kancane (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> ize igcwale)"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="7305948938141024937">"Shintsha umsebenzisi"</string>
<string name="accessibility_multi_user_switch_switcher_with_current" msgid="8434880595284601601">"Shintsha umsebenzisi, umsebenzisi wamanje ngu-<xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_inactive" msgid="1424081831468083402">"Umsebenzisi wamanje <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
@@ -426,4 +428,7 @@
<string name="tuner_toast" msgid="603429811084428439">"Siyakuhalalisela! Isishuni se-UI sesistimu singeziwe kuzilungiselelo"</string>
<string name="remove_from_settings" msgid="8389591916603406378">"Susa kusuka kuzilungiselelo"</string>
<string name="remove_from_settings_prompt" msgid="6069085993355887748">"Susa isishuni se-UI yesistimu kusuka kuzilungiselelo futhi uyeke ukusebenzisa zonke izici zakhona?"</string>
+ <string name="enable_bluetooth_title" msgid="5027037706500635269">"Vula i-Bluetooth?"</string>
+ <string name="enable_bluetooth_message" msgid="9106595990708985385">"Ukuze uxhume ikhibhodi yakho nethebhulethi yakho, kufanele uqale ngokuvula i-Bluetooth."</string>
+ <string name="enable_bluetooth_confirmation_ok" msgid="6258074250948309715">"Vula"</string>
</resources>
diff --git a/packages/SystemUI/res/values/attrs.xml b/packages/SystemUI/res/values/attrs.xml
index 527248c..49f7bdb 100644
--- a/packages/SystemUI/res/values/attrs.xml
+++ b/packages/SystemUI/res/values/attrs.xml
@@ -20,6 +20,7 @@
<attr name="keyCode" format="integer" />
<!-- does this button generate longpress / repeat events? -->
<attr name="keyRepeat" format="boolean" />
+ <attr name="android:contentDescription" />
</declare-styleable>
<declare-styleable name="ToggleSlider">
<attr name="text" format="string" />
diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml
index 260d81b..5d06768 100644
--- a/packages/SystemUI/res/values/config.xml
+++ b/packages/SystemUI/res/values/config.xml
@@ -243,7 +243,7 @@
<bool name="doze_pulse_on_notifications">true</bool>
<!-- Doze: when to pulse after a buzzworthy notification arrives -->
- <string name="doze_pulse_schedule" translatable="false">1s,10s,30s,60s</string>
+ <string name="doze_pulse_schedule" translatable="false">10s,30s,60s</string>
<!-- Doze: maximum number of times the notification pulse schedule can be reset -->
<integer name="doze_pulse_schedule_resets">2</integer>
@@ -260,12 +260,6 @@
<!-- Doze: pulse parameter - how long does it take to fade in after a pickup? -->
<integer name="doze_pulse_duration_in_pickup">300</integer>
- <!-- Doze: pulse parameter - delay to wait for the screen to wake up -->
- <integer name="doze_pulse_delay_in">200</integer>
-
- <!-- Doze: pulse parameter - delay to wait for the screen to wake up after a pickup -->
- <integer name="doze_pulse_delay_in_pickup">200</integer>
-
<!-- Doze: pulse parameter - once faded in, how long does it stay visible? -->
<integer name="doze_pulse_duration_visible">3000</integer>
diff --git a/packages/SystemUI/res/values/ids.xml b/packages/SystemUI/res/values/ids.xml
index 8eef23e..13128b7 100644
--- a/packages/SystemUI/res/values/ids.xml
+++ b/packages/SystemUI/res/values/ids.xml
@@ -37,6 +37,7 @@
<item type="id" name="doze_saved_filter_tag"/>
<item type="id" name="qs_icon_tag"/>
<item type="id" name="scrim"/>
+ <item type="id" name="scrim_target"/>
<item type="id" name="hun_scrim_alpha_start"/>
<item type="id" name="hun_scrim_alpha_end"/>
<item type="id" name="notification_power"/>
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index 3eac84f..dc9c9fd 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -793,6 +793,12 @@
<!-- Indication on the keyguard that is shown when the device is charging. [CHAR LIMIT=40]-->
<string name="keyguard_indication_charging_time">Charging (<xliff:g id="charging_time_left" example="4 hours and 2 minutes">%s</xliff:g> until full)</string>
+ <!-- Indication on the keyguard that is shown when the device is charging rapidly. Should match keyguard_plugged_in_charging_fast [CHAR LIMIT=40]-->
+ <string name="keyguard_indication_charging_time_fast">Charging rapidly (<xliff:g id="charging_time_left" example="4 hours and 2 minutes">%s</xliff:g> until full)</string>
+
+ <!-- Indication on the keyguard that is shown when the device is charging slowly. Should match keyguard_plugged_in_charging_slowly [CHAR LIMIT=40]-->
+ <string name="keyguard_indication_charging_time_slowly">Charging slowly (<xliff:g id="charging_time_left" example="4 hours and 2 minutes">%s</xliff:g> until full)</string>
+
<!-- Related to user switcher --><skip/>
<!-- Accessibility label for the button that opens the user switcher. -->
@@ -1120,4 +1126,14 @@
<!-- Dialog asking if the tuner should really be removed from settings [CHAR LIMIT=NONE]-->
<string name="remove_from_settings_prompt">Remove System UI Tuner from Settings and stop using all of its features?"</string>
+ <!-- Dialog title asking if Bluetooth should be enabled [CHAR LIMIT=NONE] -->
+ <string name="enable_bluetooth_title">Turn on Bluetooth?</string>
+
+ <!-- Dialog message explaining why Bluetooth should be enabled when a packaged keyboard is
+ conncted to the device [CHAR LIMIT=NONE] -->
+ <string name="enable_bluetooth_message">To connect your keyboard with your tablet, you first have to turn on Bluetooth.</string>
+
+ <!-- Bluetooth enablement ok text [CHAR LIMIT=40] -->
+ <string name="enable_bluetooth_confirmation_ok">Turn on</string>
+
</resources>
diff --git a/packages/SystemUI/src/com/android/systemui/ExpandHelper.java b/packages/SystemUI/src/com/android/systemui/ExpandHelper.java
index b0e2afa..1dca149 100644
--- a/packages/SystemUI/src/com/android/systemui/ExpandHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/ExpandHelper.java
@@ -112,7 +112,9 @@
public boolean onScaleBegin(ScaleGestureDetector detector) {
if (DEBUG_SCALE) Log.v(TAG, "onscalebegin()");
- startExpanding(mResizedView, STRETCH);
+ if (!mOnlyMovements) {
+ startExpanding(mResizedView, STRETCH);
+ }
return mExpanding;
}
diff --git a/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java b/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java
index 33bd726..0b066af 100644
--- a/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java
+++ b/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java
@@ -48,6 +48,7 @@
com.android.systemui.usb.StorageNotification.class,
com.android.systemui.power.PowerUI.class,
com.android.systemui.media.RingtonePlayer.class,
+ com.android.systemui.keyboard.KeyboardUI.class,
};
/**
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeHost.java b/packages/SystemUI/src/com/android/systemui/doze/DozeHost.java
index 89a2c74..82a1bfe 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeHost.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeHost.java
@@ -29,6 +29,7 @@
void stopDozing();
boolean isPowerSaveActive();
boolean isNotificationLightOn();
+ boolean isPulsingBlocked();
public interface Callback {
void onNewNotifications();
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeService.java b/packages/SystemUI/src/com/android/systemui/doze/DozeService.java
index 887391c..39423f2 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeService.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeService.java
@@ -88,6 +88,7 @@
private boolean mPowerSaveActive;
private boolean mCarMode;
private long mNotificationPulseTime;
+ private long mLastScheduleResetTime;
private long mEarliestPulseDueToLight;
private int mScheduleResetsRemaining;
@@ -255,6 +256,11 @@
}
private void continuePulsing(int reason) {
+ if (mHost.isPulsingBlocked()) {
+ mPulsing = false;
+ mWakeLock.release();
+ return;
+ }
mHost.pulseWhileDozing(new DozeHost.PulseCallback() {
@Override
public void onPulseStarted() {
@@ -351,13 +357,21 @@
return;
}
final long pulseDuration = mDozeParameters.getPulseDuration(false /*pickup*/);
- if ((notificationTimeMs - mNotificationPulseTime) < pulseDuration) {
+ boolean pulseImmediately = System.currentTimeMillis() >= notificationTimeMs;
+ if ((notificationTimeMs - mLastScheduleResetTime) >= pulseDuration) {
+ mScheduleResetsRemaining--;
+ mLastScheduleResetTime = notificationTimeMs;
+ } else if (!pulseImmediately){
if (DEBUG) Log.d(mTag, "Recently updated, not resetting schedule");
return;
}
- mScheduleResetsRemaining--;
if (DEBUG) Log.d(mTag, "mScheduleResetsRemaining = " + mScheduleResetsRemaining);
mNotificationPulseTime = notificationTimeMs;
+ if (pulseImmediately) {
+ DozeLog.traceNotificationPulse(0);
+ requestPulse(DozeLog.PULSE_REASON_NOTIFICATION);
+ }
+ // schedule the rest of the pulses
rescheduleNotificationPulse(true /*predicate*/);
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/BluetoothDialog.java b/packages/SystemUI/src/com/android/systemui/keyboard/BluetoothDialog.java
new file mode 100644
index 0000000..64f3e13f
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/BluetoothDialog.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.keyboard;
+
+import android.app.AlertDialog;
+import android.content.Context;
+import android.view.WindowManager;
+
+import com.android.systemui.R;
+import com.android.systemui.statusbar.phone.SystemUIDialog;
+
+public class BluetoothDialog extends SystemUIDialog {
+
+ public BluetoothDialog(Context context) {
+ super(context);
+
+ getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_DIALOG);
+ setShowForAllUsers(true);
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/KeyboardUI.java b/packages/SystemUI/src/com/android/systemui/keyboard/KeyboardUI.java
new file mode 100644
index 0000000..96ee397
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/KeyboardUI.java
@@ -0,0 +1,573 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.keyboard;
+
+import android.app.AlertDialog;
+import android.bluetooth.BluetoothAdapter;
+import android.bluetooth.BluetoothDevice;
+import android.bluetooth.BluetoothManager;
+import android.bluetooth.le.BluetoothLeScanner;
+import android.bluetooth.le.ScanCallback;
+import android.bluetooth.le.ScanFilter;
+import android.bluetooth.le.ScanRecord;
+import android.bluetooth.le.ScanResult;
+import android.bluetooth.le.ScanSettings;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.content.res.Configuration;
+import android.hardware.input.InputManager;
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.os.Looper;
+import android.os.Message;
+import android.os.Process;
+import android.os.SystemClock;
+import android.os.UserHandle;
+import android.provider.Settings.Secure;
+import android.text.TextUtils;
+import android.util.Slog;
+import android.view.WindowManager;
+
+import com.android.settingslib.bluetooth.BluetoothCallback;
+import com.android.settingslib.bluetooth.CachedBluetoothDevice;
+import com.android.settingslib.bluetooth.CachedBluetoothDeviceManager;
+import com.android.settingslib.bluetooth.LocalBluetoothAdapter;
+import com.android.settingslib.bluetooth.LocalBluetoothManager;
+import com.android.settingslib.bluetooth.LocalBluetoothProfileManager;
+import com.android.systemui.R;
+import com.android.systemui.SystemUI;
+
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+public class KeyboardUI extends SystemUI implements InputManager.OnTabletModeChangedListener {
+ private static final String TAG = "KeyboardUI";
+ private static final boolean DEBUG = false;
+
+ // Give BT some time to start after SyUI comes up. This avoids flashing a dialog in the user's
+ // face because BT starts a little bit later in the boot process than SysUI and it takes some
+ // time for us to receive the signal that it's starting.
+ private static final long BLUETOOTH_START_DELAY_MILLIS = 10 * 1000;
+
+ private static final int STATE_NOT_ENABLED = -1;
+ private static final int STATE_UNKNOWN = 0;
+ private static final int STATE_WAITING_FOR_BOOT_COMPLETED = 1;
+ private static final int STATE_WAITING_FOR_TABLET_MODE_EXIT = 2;
+ private static final int STATE_WAITING_FOR_DEVICE_DISCOVERY = 3;
+ private static final int STATE_WAITING_FOR_BLUETOOTH = 4;
+ private static final int STATE_WAITING_FOR_STATE_PAIRED = 5;
+ private static final int STATE_PAIRING = 6;
+ private static final int STATE_PAIRED = 7;
+ private static final int STATE_USER_CANCELLED = 8;
+ private static final int STATE_DEVICE_NOT_FOUND = 9;
+
+ private static final int MSG_INIT = 0;
+ private static final int MSG_ON_BOOT_COMPLETED = 1;
+ private static final int MSG_PROCESS_KEYBOARD_STATE = 2;
+ private static final int MSG_ENABLE_BLUETOOTH = 3;
+ private static final int MSG_ON_BLUETOOTH_STATE_CHANGED = 4;
+ private static final int MSG_ON_DEVICE_BOND_STATE_CHANGED = 5;
+ private static final int MSG_ON_BLUETOOTH_DEVICE_ADDED = 6;
+ private static final int MSG_ON_BLE_SCAN_FAILED = 7;
+ private static final int MSG_SHOW_BLUETOOTH_DIALOG = 8;
+ private static final int MSG_DISMISS_BLUETOOTH_DIALOG = 9;
+
+ private volatile KeyboardHandler mHandler;
+ private volatile KeyboardUIHandler mUIHandler;
+
+ protected volatile Context mContext;
+
+ private boolean mEnabled;
+ private String mKeyboardName;
+ private CachedBluetoothDeviceManager mCachedDeviceManager;
+ private LocalBluetoothAdapter mLocalBluetoothAdapter;
+ private LocalBluetoothProfileManager mProfileManager;
+ private boolean mBootCompleted;
+ private long mBootCompletedTime;
+
+ private int mInTabletMode = InputManager.SWITCH_STATE_UNKNOWN;
+ private ScanCallback mScanCallback;
+ private BluetoothDialog mDialog;
+
+ private int mState;
+
+ @Override
+ public void start() {
+ mContext = super.mContext;
+ HandlerThread thread = new HandlerThread("Keyboard", Process.THREAD_PRIORITY_BACKGROUND);
+ thread.start();
+ mHandler = new KeyboardHandler(thread.getLooper());
+ mHandler.sendEmptyMessage(MSG_INIT);
+ }
+
+ @Override
+ protected void onConfigurationChanged(Configuration newConfig) {
+ }
+
+ @Override
+ public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+ pw.println("KeyboardUI:");
+ pw.println(" mEnabled=" + mEnabled);
+ pw.println(" mBootCompleted=" + mEnabled);
+ pw.println(" mBootCompletedTime=" + mBootCompletedTime);
+ pw.println(" mKeyboardName=" + mKeyboardName);
+ pw.println(" mInTabletMode=" + mInTabletMode);
+ pw.println(" mState=" + stateToString(mState));
+ }
+
+ @Override
+ protected void onBootCompleted() {
+ mHandler.sendEmptyMessage(MSG_ON_BOOT_COMPLETED);
+ }
+
+ @Override
+ public void onTabletModeChanged(long whenNanos, boolean inTabletMode) {
+ if (DEBUG) {
+ Slog.d(TAG, "onTabletModeChanged(" + whenNanos + ", " + inTabletMode + ")");
+ }
+
+ if (inTabletMode && mInTabletMode != InputManager.SWITCH_STATE_ON
+ || !inTabletMode && mInTabletMode != InputManager.SWITCH_STATE_OFF) {
+ mInTabletMode = inTabletMode ?
+ InputManager.SWITCH_STATE_ON : InputManager.SWITCH_STATE_OFF;
+ processKeyboardState();
+ }
+ }
+
+ // Shoud only be called on the handler thread
+ private void init() {
+ Context context = mContext;
+ mKeyboardName =
+ context.getString(com.android.internal.R.string.config_packagedKeyboardName);
+ if (TextUtils.isEmpty(mKeyboardName)) {
+ if (DEBUG) {
+ Slog.d(TAG, "No packaged keyboard name given.");
+ }
+ return;
+ }
+
+ LocalBluetoothManager bluetoothManager = LocalBluetoothManager.getInstance(context, null);
+ if (bluetoothManager == null) {
+ if (DEBUG) {
+ Slog.e(TAG, "Failed to retrieve LocalBluetoothManager instance");
+ }
+ return;
+ }
+ mEnabled = true;
+ mCachedDeviceManager = bluetoothManager.getCachedDeviceManager();
+ mLocalBluetoothAdapter = bluetoothManager.getBluetoothAdapter();
+ mProfileManager = bluetoothManager.getProfileManager();
+ bluetoothManager.getEventManager().registerCallback(new BluetoothCallbackHandler());
+
+ InputManager im = (InputManager) context.getSystemService(Context.INPUT_SERVICE);
+ im.registerOnTabletModeChangedListener(this, mHandler);
+ mInTabletMode = im.isInTabletMode();
+
+ processKeyboardState();
+ mUIHandler = new KeyboardUIHandler();
+ }
+
+ // Should only be called on the handler thread
+ private void processKeyboardState() {
+ mHandler.removeMessages(MSG_PROCESS_KEYBOARD_STATE);
+
+ if (!mEnabled) {
+ mState = STATE_NOT_ENABLED;
+ return;
+ }
+
+ if (!mBootCompleted) {
+ mState = STATE_WAITING_FOR_BOOT_COMPLETED;
+ return;
+ }
+
+ if (mInTabletMode != InputManager.SWITCH_STATE_OFF) {
+ if (mState == STATE_WAITING_FOR_DEVICE_DISCOVERY) {
+ stopScanning();
+ }
+ mState = STATE_WAITING_FOR_TABLET_MODE_EXIT;
+ return;
+ }
+
+ final int btState = mLocalBluetoothAdapter.getState();
+ if (btState == BluetoothAdapter.STATE_TURNING_ON || btState == BluetoothAdapter.STATE_ON
+ && mState == STATE_WAITING_FOR_BLUETOOTH) {
+ // If we're waiting for bluetooth but it has come on in the meantime, or is coming
+ // on, just dismiss the dialog. This frequently happens during device startup.
+ mUIHandler.sendEmptyMessage(MSG_DISMISS_BLUETOOTH_DIALOG);
+ }
+
+ if (btState == BluetoothAdapter.STATE_TURNING_ON) {
+ mState = STATE_WAITING_FOR_BLUETOOTH;
+ // Wait for bluetooth to fully come on.
+ return;
+ }
+
+ if (btState != BluetoothAdapter.STATE_ON) {
+ mState = STATE_WAITING_FOR_BLUETOOTH;
+ showBluetoothDialog();
+ return;
+ }
+
+ CachedBluetoothDevice device = getPairedKeyboard();
+ if (mState == STATE_WAITING_FOR_TABLET_MODE_EXIT || mState == STATE_WAITING_FOR_BLUETOOTH) {
+ if (device != null) {
+ // If we're just coming out of tablet mode or BT just turned on,
+ // then we want to go ahead and automatically connect to the
+ // keyboard. We want to avoid this in other cases because we might
+ // be spuriously called after the user has manually disconnected
+ // the keyboard, meaning we shouldn't try to automtically connect
+ // it again.
+ mState = STATE_PAIRED;
+ device.connect(false);
+ return;
+ }
+ mCachedDeviceManager.clearNonBondedDevices();
+ }
+
+ device = getDiscoveredKeyboard();
+ if (device != null) {
+ mState = STATE_PAIRING;
+ device.startPairing();
+ } else {
+ mState = STATE_WAITING_FOR_DEVICE_DISCOVERY;
+ startScanning();
+ }
+ }
+
+ // Should only be called on the handler thread
+ public void onBootCompletedInternal() {
+ mBootCompleted = true;
+ mBootCompletedTime = SystemClock.uptimeMillis();
+ if (mState == STATE_WAITING_FOR_BOOT_COMPLETED) {
+ processKeyboardState();
+ }
+ }
+
+ // Should only be called on the handler thread
+ private void showBluetoothDialog() {
+ if (isUserSetupComplete()) {
+ long now = SystemClock.uptimeMillis();
+ long earliestDialogTime = mBootCompletedTime + BLUETOOTH_START_DELAY_MILLIS;
+ if (earliestDialogTime < now) {
+ mUIHandler.sendEmptyMessage(MSG_SHOW_BLUETOOTH_DIALOG);
+ } else {
+ mHandler.sendEmptyMessageAtTime(MSG_PROCESS_KEYBOARD_STATE, earliestDialogTime);
+ }
+ } else {
+ // If we're in setup wizard and the keyboard is docked, just automatically enable BT.
+ mLocalBluetoothAdapter.enable();
+ }
+ }
+
+ private boolean isUserSetupComplete() {
+ ContentResolver resolver = mContext.getContentResolver();
+ return Secure.getIntForUser(
+ resolver, Secure.USER_SETUP_COMPLETE, 0, UserHandle.USER_CURRENT) != 0;
+ }
+
+ private CachedBluetoothDevice getPairedKeyboard() {
+ Set<BluetoothDevice> devices = mLocalBluetoothAdapter.getBondedDevices();
+ for (BluetoothDevice d : devices) {
+ if (mKeyboardName.equals(d.getName())) {
+ return getCachedBluetoothDevice(d);
+ }
+ }
+ return null;
+ }
+
+ private CachedBluetoothDevice getDiscoveredKeyboard() {
+ Collection<CachedBluetoothDevice> devices = mCachedDeviceManager.getCachedDevicesCopy();
+ for (CachedBluetoothDevice d : devices) {
+ if (d.getName().equals(mKeyboardName)) {
+ return d;
+ }
+ }
+ return null;
+ }
+
+
+ private CachedBluetoothDevice getCachedBluetoothDevice(BluetoothDevice d) {
+ CachedBluetoothDevice cachedDevice = mCachedDeviceManager.findDevice(d);
+ if (cachedDevice == null) {
+ cachedDevice = mCachedDeviceManager.addDevice(
+ mLocalBluetoothAdapter, mProfileManager, d);
+ }
+ return cachedDevice;
+ }
+
+ private void startScanning() {
+ BluetoothLeScanner scanner = mLocalBluetoothAdapter.getBluetoothLeScanner();
+ ScanFilter filter = (new ScanFilter.Builder()).setDeviceName(mKeyboardName).build();
+ ScanSettings settings = (new ScanSettings.Builder())
+ .setCallbackType(ScanSettings.CALLBACK_TYPE_ALL_MATCHES)
+ .setNumOfMatches(ScanSettings.MATCH_NUM_ONE_ADVERTISEMENT)
+ .setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY)
+ .setReportDelay(0)
+ .build();
+ mScanCallback = new KeyboardScanCallback();
+ scanner.startScan(Arrays.asList(filter), settings, mScanCallback);
+ }
+
+ private void stopScanning() {
+ if (mScanCallback != null) {
+ mLocalBluetoothAdapter.getBluetoothLeScanner().stopScan(mScanCallback);
+ mScanCallback = null;
+ }
+ }
+
+ // Should only be called on the handler thread
+ private void onDeviceAddedInternal(CachedBluetoothDevice d) {
+ if (mState == STATE_WAITING_FOR_DEVICE_DISCOVERY && d.getName().equals(mKeyboardName)) {
+ stopScanning();
+ d.startPairing();
+ mState = STATE_PAIRING;
+ }
+ }
+
+ // Should only be called on the handler thread
+ private void onBluetoothStateChangedInternal(int bluetoothState) {
+ if (bluetoothState == BluetoothAdapter.STATE_ON && mState == STATE_WAITING_FOR_BLUETOOTH) {
+ processKeyboardState();
+ }
+ }
+
+ // Should only be called on the handler thread
+ private void onDeviceBondStateChangedInternal(CachedBluetoothDevice d, int bondState) {
+ if (d.getName().equals(mKeyboardName) && bondState == BluetoothDevice.BOND_BONDED) {
+ // We don't need to manually connect to the device here because it will automatically
+ // try to connect after it has been paired.
+ mState = STATE_PAIRED;
+ }
+ }
+
+ // Should only be called on the handler thread
+ private void onBleScanFailedInternal() {
+ mScanCallback = null;
+ if (mState == STATE_WAITING_FOR_DEVICE_DISCOVERY) {
+ mState = STATE_DEVICE_NOT_FOUND;
+ }
+ }
+
+ private final class KeyboardUIHandler extends Handler {
+ public KeyboardUIHandler() {
+ super(Looper.getMainLooper(), null, true /*async*/);
+ }
+ @Override
+ public void handleMessage(Message msg) {
+ switch(msg.what) {
+ case MSG_SHOW_BLUETOOTH_DIALOG: {
+ DialogInterface.OnClickListener listener = new BluetoothDialogClickListener();
+ mDialog = new BluetoothDialog(mContext);
+ mDialog.setTitle(R.string.enable_bluetooth_title);
+ mDialog.setMessage(R.string.enable_bluetooth_message);
+ mDialog.setPositiveButton(R.string.enable_bluetooth_confirmation_ok, listener);
+ mDialog.setNegativeButton(android.R.string.cancel, listener);
+ mDialog.show();
+ break;
+ }
+ case MSG_DISMISS_BLUETOOTH_DIALOG: {
+ if (mDialog != null) {
+ mDialog.dismiss();
+ mDialog = null;
+ }
+ break;
+ }
+ }
+ }
+ }
+
+ private final class KeyboardHandler extends Handler {
+ public KeyboardHandler(Looper looper) {
+ super(looper, null, true /*async*/);
+ }
+
+ @Override
+ public void handleMessage(Message msg) {
+ switch(msg.what) {
+ case MSG_INIT: {
+ init();
+ break;
+ }
+ case MSG_ON_BOOT_COMPLETED: {
+ onBootCompletedInternal();
+ break;
+ }
+ case MSG_PROCESS_KEYBOARD_STATE: {
+ processKeyboardState();
+ break;
+ }
+ case MSG_ENABLE_BLUETOOTH: {
+ boolean enable = msg.arg1 == 1;
+ if (enable) {
+ mLocalBluetoothAdapter.enable();
+ } else {
+ mState = STATE_USER_CANCELLED;
+ }
+ }
+ case MSG_ON_BLUETOOTH_STATE_CHANGED: {
+ int bluetoothState = msg.arg1;
+ onBluetoothStateChangedInternal(bluetoothState);
+ break;
+ }
+ case MSG_ON_DEVICE_BOND_STATE_CHANGED: {
+ CachedBluetoothDevice d = (CachedBluetoothDevice)msg.obj;
+ int bondState = msg.arg1;
+ onDeviceBondStateChangedInternal(d, bondState);
+ break;
+ }
+ case MSG_ON_BLUETOOTH_DEVICE_ADDED: {
+ BluetoothDevice d = (BluetoothDevice)msg.obj;
+ CachedBluetoothDevice cachedDevice = getCachedBluetoothDevice(d);
+ onDeviceAddedInternal(cachedDevice);
+ break;
+
+ }
+ case MSG_ON_BLE_SCAN_FAILED: {
+ onBleScanFailedInternal();
+ break;
+ }
+ }
+ }
+ }
+
+ private final class BluetoothDialogClickListener implements DialogInterface.OnClickListener {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ int enable = DialogInterface.BUTTON_POSITIVE == which ? 1 : 0;
+ mHandler.obtainMessage(MSG_ENABLE_BLUETOOTH, enable, 0).sendToTarget();
+ mDialog = null;
+ }
+ }
+
+ private final class KeyboardScanCallback extends ScanCallback {
+
+ private boolean isDeviceDiscoverable(ScanResult result) {
+ final ScanRecord scanRecord = result.getScanRecord();
+ final int flags = scanRecord.getAdvertiseFlags();
+ final int BT_DISCOVERABLE_MASK = 0x03;
+
+ return (flags & BT_DISCOVERABLE_MASK) != 0;
+ }
+
+ @Override
+ public void onBatchScanResults(List<ScanResult> results) {
+ if (DEBUG) {
+ Slog.d(TAG, "onBatchScanResults(" + results.size() + ")");
+ }
+
+ BluetoothDevice bestDevice = null;
+ int bestRssi = Integer.MIN_VALUE;
+
+ for (ScanResult result : results) {
+ if (DEBUG) {
+ Slog.d(TAG, "onBatchScanResults: considering " + result);
+ }
+
+ if (isDeviceDiscoverable(result) && result.getRssi() > bestRssi) {
+ bestDevice = result.getDevice();
+ bestRssi = result.getRssi();
+ }
+ }
+
+ if (bestDevice != null) {
+ mHandler.obtainMessage(MSG_ON_BLUETOOTH_DEVICE_ADDED, bestDevice).sendToTarget();
+ }
+ }
+
+ @Override
+ public void onScanFailed(int errorCode) {
+ if (DEBUG) {
+ Slog.d(TAG, "onScanFailed(" + errorCode + ")");
+ }
+ mHandler.obtainMessage(MSG_ON_BLE_SCAN_FAILED).sendToTarget();
+ }
+
+ @Override
+ public void onScanResult(int callbackType, ScanResult result) {
+ if (DEBUG) {
+ Slog.d(TAG, "onScanResult(" + callbackType + ", " + result + ")");
+ }
+
+ if (isDeviceDiscoverable(result)) {
+ mHandler.obtainMessage(MSG_ON_BLUETOOTH_DEVICE_ADDED,
+ result.getDevice()).sendToTarget();
+ } else if (DEBUG) {
+ Slog.d(TAG, "onScanResult: device " + result.getDevice() +
+ " is not discoverable, ignoring");
+ }
+ }
+ }
+
+ private final class BluetoothCallbackHandler implements BluetoothCallback {
+ @Override
+ public void onBluetoothStateChanged(int bluetoothState) {
+ mHandler.obtainMessage(MSG_ON_BLUETOOTH_STATE_CHANGED,
+ bluetoothState, 0).sendToTarget();
+ }
+
+ @Override
+ public void onDeviceBondStateChanged(CachedBluetoothDevice cachedDevice, int bondState) {
+ mHandler.obtainMessage(MSG_ON_DEVICE_BOND_STATE_CHANGED,
+ bondState, 0, cachedDevice).sendToTarget();
+ }
+
+ @Override
+ public void onDeviceAdded(CachedBluetoothDevice cachedDevice) { }
+ @Override
+ public void onDeviceDeleted(CachedBluetoothDevice cachedDevice) { }
+ @Override
+ public void onScanningStateChanged(boolean started) { }
+ @Override
+ public void onConnectionStateChanged(CachedBluetoothDevice cachedDevice, int state) { }
+ }
+
+ private static String stateToString(int state) {
+ switch (state) {
+ case STATE_NOT_ENABLED:
+ return "STATE_NOT_ENABLED";
+ case STATE_WAITING_FOR_BOOT_COMPLETED:
+ return "STATE_WAITING_FOR_BOOT_COMPLETED";
+ case STATE_WAITING_FOR_TABLET_MODE_EXIT:
+ return "STATE_WAITING_FOR_TABLET_MODE_EXIT";
+ case STATE_WAITING_FOR_DEVICE_DISCOVERY:
+ return "STATE_WAITING_FOR_DEVICE_DISCOVERY";
+ case STATE_WAITING_FOR_BLUETOOTH:
+ return "STATE_WAITING_FOR_BLUETOOTH";
+ case STATE_WAITING_FOR_STATE_PAIRED:
+ return "STATE_WAITING_FOR_STATE_PAIRED";
+ case STATE_PAIRING:
+ return "STATE_PAIRING";
+ case STATE_PAIRED:
+ return "STATE_PAIRED";
+ case STATE_USER_CANCELLED:
+ return "STATE_USER_CANCELLED";
+ case STATE_DEVICE_NOT_FOUND:
+ return "STATE_DEVICE_NOT_FOUND";
+ case STATE_UNKNOWN:
+ default:
+ return "STATE_UNKNOWN";
+ }
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java
index d78800f..d2c60ef 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java
@@ -80,7 +80,8 @@
@Override // Binder interface
public void keyguardDone(boolean authenticated, boolean wakeup) {
checkPermission();
- mKeyguardViewMediator.keyguardDone(authenticated, wakeup);
+ // TODO: Remove wakeup
+ mKeyguardViewMediator.keyguardDone(authenticated);
}
@Override // Binder interface
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
index a1c8b1a..055b5ef 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
@@ -68,11 +68,14 @@
import com.android.keyguard.KeyguardUpdateMonitorCallback;
import com.android.keyguard.ViewMediatorCallback;
import com.android.systemui.SystemUI;
+import com.android.systemui.statusbar.phone.FingerprintUnlockController;
import com.android.systemui.statusbar.phone.PhoneStatusBar;
import com.android.systemui.statusbar.phone.ScrimController;
import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
import com.android.systemui.statusbar.phone.StatusBarWindowManager;
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;
@@ -151,6 +154,7 @@
private static final int NOTIFY_STARTED_WAKING_UP = 21;
private static final int NOTIFY_SCREEN_TURNED_ON = 22;
private static final int NOTIFY_SCREEN_TURNED_OFF = 23;
+ private static final int NOTIFY_STARTED_GOING_TO_SLEEP = 24;
/**
* The default amount of time we stay awake (used for all key input)
@@ -176,11 +180,6 @@
*/
private static final String KEYGUARD_ANALYTICS_SETTING = "keyguard_analytics";
- /**
- * How much faster we collapse the lockscreen when authenticating with fingerprint.
- */
- private static final float FINGERPRINT_COLLAPSE_SPEEDUP_FACTOR = 1.3f;
-
/** The stream type that the lock sounds are tied to. */
private int mUiSoundsStreamType;
@@ -458,30 +457,6 @@
break;
}
}
-
- @Override
- public void onFingerprintAuthenticated(int userId, boolean wakeAndUnlocking) {
- boolean unlockingWithFingerprintAllowed =
- mUpdateMonitor.isUnlockingWithFingerprintAllowed();
- if (mStatusBarKeyguardViewManager.isBouncerShowing()) {
- if (unlockingWithFingerprintAllowed) {
- mStatusBarKeyguardViewManager.notifyKeyguardAuthenticated();
- }
- } else {
- if (wakeAndUnlocking && mShowing && unlockingWithFingerprintAllowed) {
- mWakeAndUnlocking = true;
- mStatusBarKeyguardViewManager.setWakeAndUnlocking();
- keyguardDone(true, true);
- } else if (mShowing && mDeviceInteractive) {
- if (wakeAndUnlocking) {
- mStatusBarKeyguardViewManager.notifyDeviceWakeUpRequested();
- }
- mStatusBarKeyguardViewManager.animateCollapsePanels(
- FINGERPRINT_COLLAPSE_SPEEDUP_FACTOR);
- }
- }
- };
-
};
ViewMediatorCallback mViewMediatorCallback = new ViewMediatorCallback() {
@@ -490,9 +465,12 @@
KeyguardViewMediator.this.userActivity();
}
- public void keyguardDone(boolean authenticated) {
+ public void keyguardDone(boolean strongAuth) {
if (!mKeyguardDonePending) {
- KeyguardViewMediator.this.keyguardDone(authenticated, true);
+ KeyguardViewMediator.this.keyguardDone(true /* authenticated */);
+ }
+ if (strongAuth) {
+ mUpdateMonitor.reportSuccessfulStrongAuthUnlockAttempt();
}
}
@@ -506,12 +484,15 @@
}
@Override
- public void keyguardDonePending() {
+ public void keyguardDonePending(boolean strongAuth) {
mKeyguardDonePending = true;
mHideAnimationRun = true;
mStatusBarKeyguardViewManager.startPreHideAnimation(null /* finishRunnable */);
mHandler.sendEmptyMessageDelayed(KEYGUARD_DONE_PENDING_TIMEOUT,
KEYGUARD_DONE_PENDING_TIMEOUT_MS);
+ if (strongAuth) {
+ mUpdateMonitor.reportSuccessfulStrongAuthUnlockAttempt();
+ }
}
@Override
@@ -524,7 +505,7 @@
if (mKeyguardDonePending) {
// Somebody has called keyguardDonePending before, which means that we are
// authenticated
- KeyguardViewMediator.this.keyguardDone(true /* authenticated */, true /* wakeUp */);
+ KeyguardViewMediator.this.keyguardDone(true /* authenticated */);
}
}
@@ -552,9 +533,12 @@
public int getBouncerPromptReason() {
int currentUser = ActivityManager.getCurrentUser();
if ((mUpdateMonitor.getUserTrustIsManaged(currentUser)
- || mUpdateMonitor.isUnlockWithFingerPrintPossible(currentUser))
- && !mTrustManager.hasUserAuthenticatedSinceBoot(currentUser)) {
+ || mUpdateMonitor.isUnlockWithFingerprintPossible(currentUser))
+ && !mUpdateMonitor.getStrongAuthTracker().hasUserAuthenticatedSinceBoot()) {
return KeyguardSecurityView.PROMPT_REASON_RESTART;
+ } else if (mUpdateMonitor.isUnlockWithFingerprintPossible(currentUser)
+ && mUpdateMonitor.hasFingerprintUnlockTimedOut(currentUser)) {
+ return KeyguardSecurityView.PROMPT_REASON_TIMEOUT;
}
return KeyguardSecurityView.PROMPT_REASON_NONE;
}
@@ -668,6 +652,7 @@
final boolean lockImmediately =
mLockPatternUtils.getPowerButtonInstantlyLocks(currentUser)
|| !mLockPatternUtils.isSecure(currentUser);
+ long timeout = getLockTimeout();
if (mExitSecureCallback != null) {
if (DEBUG) Log.d(TAG, "pending exit secure callback cancelled");
@@ -682,9 +667,9 @@
}
} else if (mShowing) {
mPendingReset = true;
- } else if (why == WindowManagerPolicy.OFF_BECAUSE_OF_TIMEOUT
+ } else if ((why == WindowManagerPolicy.OFF_BECAUSE_OF_TIMEOUT && timeout > 0)
|| (why == WindowManagerPolicy.OFF_BECAUSE_OF_USER && !lockImmediately)) {
- doKeyguardLaterLocked();
+ doKeyguardLaterLocked(timeout);
} else if (!mLockPatternUtils.isLockScreenDisabled(currentUser)) {
mPendingLock = true;
}
@@ -693,6 +678,8 @@
playSounds(true);
}
}
+ KeyguardUpdateMonitor.getInstance(mContext).dispatchStartedGoingToSleep(why);
+ notifyStartedGoingToSleep();
}
public void onFinishedGoingToSleep(int why) {
@@ -718,7 +705,7 @@
KeyguardUpdateMonitor.getInstance(mContext).dispatchFinishedGoingToSleep(why);
}
- private void doKeyguardLaterLocked() {
+ private long getLockTimeout() {
// if the screen turned off because of timeout or the user hit the power button
// and we don't need to lock immediately, set an alarm
// to enable it a little bit later (i.e, give the user a chance
@@ -747,23 +734,30 @@
} else {
timeout = lockAfterTimeout;
}
+ return timeout;
+ }
- if (timeout <= 0) {
- // Lock now
+ private void doKeyguardLaterLocked() {
+ long timeout = getLockTimeout();
+ if (timeout == 0) {
doKeyguardLocked(null);
} else {
- // Lock in the future
- long when = SystemClock.elapsedRealtime() + timeout;
- Intent intent = new Intent(DELAYED_KEYGUARD_ACTION);
- intent.putExtra("seq", mDelayedShowingSequence);
- PendingIntent sender = PendingIntent.getBroadcast(mContext,
- 0, intent, PendingIntent.FLAG_CANCEL_CURRENT);
- mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, when, sender);
- if (DEBUG) Log.d(TAG, "setting alarm to turn off keyguard, seq = "
- + mDelayedShowingSequence);
+ doKeyguardLaterLocked(timeout);
}
}
+ private void doKeyguardLaterLocked(long timeout) {
+ // Lock in the future
+ long when = SystemClock.elapsedRealtime() + timeout;
+ Intent intent = new Intent(DELAYED_KEYGUARD_ACTION);
+ intent.putExtra("seq", mDelayedShowingSequence);
+ PendingIntent sender = PendingIntent.getBroadcast(mContext,
+ 0, intent, PendingIntent.FLAG_CANCEL_CURRENT);
+ mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, when, sender);
+ if (DEBUG) Log.d(TAG, "setting alarm to turn off keyguard, seq = "
+ + mDelayedShowingSequence);
+ }
+
private void cancelDoKeyguardLaterLocked() {
mDelayedShowingSequence++;
}
@@ -926,9 +920,27 @@
} catch (RemoteException e) {
Slog.w(TAG, "Failed to call onKeyguardExitResult(false)", e);
}
+ } else if (!isSecure()) {
+
+ // Keyguard is not secure, no need to do anything, and we don't need to reshow
+ // the Keyguard after the client releases the Keyguard lock.
+ mExternallyEnabled = true;
+ mNeedToReshowWhenReenabled = false;
+ updateInputRestricted();
+ try {
+ callback.onKeyguardExitResult(true);
+ } catch (RemoteException e) {
+ Slog.w(TAG, "Failed to call onKeyguardExitResult(false)", e);
+ }
} else {
- mExitSecureCallback = callback;
- verifyUnlockLocked();
+
+ // Since we prevent apps from hiding the Keyguard if we are secure, this should be
+ // a no-op as well.
+ try {
+ callback.onKeyguardExitResult(false);
+ } catch (RemoteException e) {
+ Slog.w(TAG, "Failed to call onKeyguardExitResult(false)", e);
+ }
}
}
}
@@ -1065,6 +1077,7 @@
// Without this, settings is not enabled until the lock screen first appears
setShowingLocked(false);
hideLocked();
+ mUpdateMonitor.reportSuccessfulStrongAuthUnlockAttempt();
return;
}
@@ -1108,6 +1121,11 @@
mHandler.sendEmptyMessage(VERIFY_UNLOCK);
}
+ private void notifyStartedGoingToSleep() {
+ if (DEBUG) Log.d(TAG, "notifyStartedGoingToSleep");
+ mHandler.sendEmptyMessage(NOTIFY_STARTED_GOING_TO_SLEEP);
+ }
+
private void notifyFinishedGoingToSleep() {
if (DEBUG) Log.d(TAG, "notifyFinishedGoingToSleep");
mHandler.sendEmptyMessage(NOTIFY_FINISHED_GOING_TO_SLEEP);
@@ -1189,10 +1207,10 @@
}
};
- public void keyguardDone(boolean authenticated, boolean wakeup) {
- if (DEBUG) Log.d(TAG, "keyguardDone(" + authenticated + ")");
+ public void keyguardDone(boolean authenticated) {
+ if (DEBUG) Log.d(TAG, "keyguardDone(" + authenticated +")");
EventLog.writeEvent(70000, 2);
- Message msg = mHandler.obtainMessage(KEYGUARD_DONE, authenticated ? 1 : 0, wakeup ? 1 : 0);
+ Message msg = mHandler.obtainMessage(KEYGUARD_DONE, authenticated ? 1 : 0);
mHandler.sendMessage(msg);
}
@@ -1219,6 +1237,9 @@
case VERIFY_UNLOCK:
handleVerifyUnlock();
break;
+ case NOTIFY_STARTED_GOING_TO_SLEEP:
+ handleNotifyStartedGoingToSleep();
+ break;
case NOTIFY_FINISHED_GOING_TO_SLEEP:
handleNotifyFinishedGoingToSleep();
break;
@@ -1235,14 +1256,11 @@
handleNotifyStartedWakingUp();
break;
case KEYGUARD_DONE:
- handleKeyguardDone(msg.arg1 != 0, msg.arg2 != 0);
+ handleKeyguardDone(msg.arg1 != 0);
break;
case KEYGUARD_DONE_DRAWING:
handleKeyguardDoneDrawing();
break;
- case KEYGUARD_DONE_AUTHENTICATING:
- keyguardDone(true, true);
- break;
case SET_OCCLUDED:
handleSetOccluded(msg.arg1 != 0);
break;
@@ -1272,7 +1290,7 @@
* @see #keyguardDone
* @see #KEYGUARD_DONE
*/
- private void handleKeyguardDone(boolean authenticated, boolean wakeup) {
+ private void handleKeyguardDone(boolean authenticated) {
if (DEBUG) Log.d(TAG, "handleKeyguardDone");
synchronized (this) {
resetKeyguardDonePendingLocked();
@@ -1467,6 +1485,15 @@
}
mHiding = false;
+ if (mWakeAndUnlocking && mDrawnCallback != null) {
+
+ // Hack level over 9000: To speed up wake-and-unlock sequence, force it to report
+ // the next draw from here so we don't have to wait for window manager to signal
+ // this to our ViewRootImpl.
+ mStatusBarKeyguardViewManager.getViewRootImpl().setReportNextDraw();
+ notifyDrawn(mDrawnCallback);
+ }
+
// only play "unlock" noises if not on a call (since the incall UI
// disables the keyguard)
if (TelephonyManager.EXTRA_STATE_IDLE.equals(mPhoneState)) {
@@ -1480,9 +1507,6 @@
updateActivityLockScreenState();
adjustStatusBarLocked();
sendUserPresentBroadcast();
- if (mWakeAndUnlocking && mDrawnCallback != null) {
- notifyDrawn(mDrawnCallback);
- }
}
}
@@ -1543,6 +1567,13 @@
}
}
+ private void handleNotifyStartedGoingToSleep() {
+ synchronized (KeyguardViewMediator.this) {
+ if (DEBUG) Log.d(TAG, "handleNotifyStartedGoingToSleep");
+ mStatusBarKeyguardViewManager.onStartedGoingToSleep();
+ }
+ }
+
/**
* Handle message sent by {@link #notifyFinishedGoingToSleep()}
* @see #NOTIFY_FINISHED_GOING_TO_SLEEP
@@ -1586,6 +1617,7 @@
synchronized (this) {
if (DEBUG) Log.d(TAG, "handleNotifyScreenTurnedOff");
mStatusBarKeyguardViewManager.onScreenTurnedOff();
+ mWakeAndUnlocking = false;
}
}
@@ -1612,11 +1644,17 @@
}
}
+ public void onWakeAndUnlocking() {
+ mWakeAndUnlocking = true;
+ keyguardDone(true /* authenticated */);
+ }
+
public StatusBarKeyguardViewManager registerStatusBar(PhoneStatusBar phoneStatusBar,
ViewGroup container, StatusBarWindowManager statusBarWindowManager,
- ScrimController scrimController) {
+ ScrimController scrimController,
+ FingerprintUnlockController fingerprintUnlockController) {
mStatusBarKeyguardViewManager.registerStatusBar(phoneStatusBar, container,
- statusBarWindowManager, scrimController);
+ statusBarWindowManager, scrimController, fingerprintUnlockController);
return mStatusBarKeyguardViewManager;
}
@@ -1633,6 +1671,30 @@
return mViewMediatorCallback;
}
+ @Override
+ public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+ pw.print(" mSystemReady: "); pw.println(mSystemReady);
+ pw.print(" mBootCompleted: "); pw.println(mBootCompleted);
+ pw.print(" mBootSendUserPresent: "); pw.println(mBootSendUserPresent);
+ pw.print(" mExternallyEnabled: "); pw.println(mExternallyEnabled);
+ pw.print(" mNeedToReshowWhenReenabled: "); pw.println(mNeedToReshowWhenReenabled);
+ pw.print(" mShowing: "); pw.println(mShowing);
+ pw.print(" mInputRestricted: "); pw.println(mInputRestricted);
+ pw.print(" mOccluded: "); pw.println(mOccluded);
+ pw.print(" mDelayedShowingSequence: "); pw.println(mDelayedShowingSequence);
+ pw.print(" mExitSecureCallback: "); pw.println(mExitSecureCallback);
+ pw.print(" mDeviceInteractive: "); pw.println(mDeviceInteractive);
+ pw.print(" mGoingToSleep: "); pw.println(mGoingToSleep);
+ pw.print(" mHiding: "); pw.println(mHiding);
+ pw.print(" mWaitingUntilKeyguardVisible: "); pw.println(mWaitingUntilKeyguardVisible);
+ pw.print(" mKeyguardDonePending: "); pw.println(mKeyguardDonePending);
+ pw.print(" mHideAnimationRun: "); pw.println(mHideAnimationRun);
+ pw.print(" mPendingReset: "); pw.println(mPendingReset);
+ pw.print(" mPendingLock: "); pw.println(mPendingLock);
+ pw.print(" mWakeAndUnlocking: "); pw.println(mWakeAndUnlocking);
+ pw.print(" mDrawnCallback: "); pw.println(mDrawnCallback);
+ }
+
private static class StartKeyguardExitAnimParams {
long startTime;
diff --git a/packages/SystemUI/src/com/android/systemui/media/NotificationPlayer.java b/packages/SystemUI/src/com/android/systemui/media/NotificationPlayer.java
index 803a014..728d558 100644
--- a/packages/SystemUI/src/com/android/systemui/media/NotificationPlayer.java
+++ b/packages/SystemUI/src/com/android/systemui/media/NotificationPlayer.java
@@ -21,6 +21,7 @@
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnCompletionListener;
+import android.media.MediaPlayer.OnErrorListener;
import android.net.Uri;
import android.os.Looper;
import android.os.PowerManager;
@@ -36,7 +37,7 @@
* - whenever audio is played, audio focus is requested,
* - whenever audio playback is stopped or the playback completed, audio focus is abandoned.
*/
-public class NotificationPlayer implements OnCompletionListener {
+public class NotificationPlayer implements OnCompletionListener, OnErrorListener {
private static final int PLAY = 1;
private static final int STOP = 2;
private static final boolean mDebug = false;
@@ -112,6 +113,7 @@
// done playing. This class should be modified to use a single thread, on which
// command are issued, and on which it receives the completion callbacks.
player.setOnCompletionListener(NotificationPlayer.this);
+ player.setOnErrorListener(NotificationPlayer.this);
player.start();
if (mPlayer != null) {
mPlayer.release();
@@ -245,6 +247,13 @@
}
}
+ public boolean onError(MediaPlayer mp, int what, int extra) {
+ Log.e(mTag, "error " + what + " (extra=" + extra + ") playing notification");
+ // error happened, handle it just like a completion
+ onCompletion(mp);
+ return true;
+ }
+
private String mTag;
private CmdThread mThread;
private CreationAndCompletionThread mCompletionThread;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/UsageTracker.java b/packages/SystemUI/src/com/android/systemui/qs/UsageTracker.java
index f36019b..e64f6a0 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/UsageTracker.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/UsageTracker.java
@@ -21,7 +21,6 @@
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
-import android.content.SharedPreferences;
import com.android.systemui.Prefs;
import com.android.systemui.R;
diff --git a/packages/SystemUI/src/com/android/systemui/recents/Recents.java b/packages/SystemUI/src/com/android/systemui/recents/Recents.java
index 3bcbd65..3917bab 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/Recents.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/Recents.java
@@ -20,7 +20,6 @@
import android.app.ActivityManager;
import android.app.ActivityOptions;
import android.app.ITaskStackListener;
-import android.appwidget.AppWidgetProviderInfo;
import android.content.ActivityNotFoundException;
import android.content.BroadcastReceiver;
import android.content.Context;
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
index b47fb30..d0876fa 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
@@ -33,7 +33,6 @@
import android.view.ViewStub;
import android.widget.Toast;
-import com.android.internal.logging.MetricsConstants;
import com.android.internal.logging.MetricsLogger;
import com.android.systemui.Prefs;
import com.android.systemui.R;
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 298a1cc..d5c9253 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java
@@ -20,10 +20,8 @@
import android.app.ActivityManagerNative;
import android.app.ActivityOptions;
import android.app.AppGlobals;
-import android.app.IActivityContainer;
import android.app.IActivityManager;
import android.app.ITaskStackListener;
-import android.app.SearchManager;
import android.appwidget.AppWidgetHost;
import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProviderInfo;
@@ -54,15 +52,12 @@
import android.os.RemoteException;
import android.os.SystemProperties;
import android.os.UserHandle;
-import android.os.UserManager;
import android.provider.Settings;
import android.util.Log;
import android.util.MutableBoolean;
import android.util.Pair;
import android.util.SparseArray;
import android.view.Display;
-import android.view.DisplayInfo;
-import android.view.SurfaceControl;
import android.view.WindowManager;
import android.view.accessibility.AccessibilityManager;
@@ -71,7 +66,6 @@
import com.android.systemui.R;
import com.android.systemui.recents.Constants;
import com.android.systemui.recents.Recents;
-import com.android.systemui.recents.RecentsAppWidgetHost;
import java.io.IOException;
import java.util.ArrayList;
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewTouchHandler.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewTouchHandler.java
index 2e0b80a..be618e2 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewTouchHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewTouchHandler.java
@@ -162,6 +162,14 @@
mVelocityTracker.addMovement(createMotionEventForStackScroll(ev));
break;
}
+ case MotionEvent.ACTION_POINTER_DOWN: {
+ final int index = ev.getActionIndex();
+ mActivePointerId = ev.getPointerId(index);
+ mLastMotionX = (int) ev.getX(index);
+ mLastMotionY = (int) ev.getY(index);
+ mLastP = mSv.mLayoutAlgorithm.screenYToCurveProgress(mLastMotionY);
+ break;
+ }
case MotionEvent.ACTION_MOVE: {
if (mActivePointerId == INACTIVE_POINTER_ID) break;
@@ -187,6 +195,20 @@
mLastP = mSv.mLayoutAlgorithm.screenYToCurveProgress(mLastMotionY);
break;
}
+ case MotionEvent.ACTION_POINTER_UP: {
+ int pointerIndex = ev.getActionIndex();
+ int pointerId = ev.getPointerId(pointerIndex);
+ if (pointerId == mActivePointerId) {
+ // Select a new active pointer id and reset the motion state
+ final int newPointerIndex = (pointerIndex == 0) ? 1 : 0;
+ mActivePointerId = ev.getPointerId(newPointerIndex);
+ mLastMotionX = (int) ev.getX(newPointerIndex);
+ mLastMotionY = (int) ev.getY(newPointerIndex);
+ mLastP = mSv.mLayoutAlgorithm.screenYToCurveProgress(mLastMotionY);
+ mVelocityTracker.clear();
+ }
+ break;
+ }
case MotionEvent.ACTION_CANCEL:
case MotionEvent.ACTION_UP: {
// Animate the scroll back if we've cancelled
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ActivatableNotificationView.java b/packages/SystemUI/src/com/android/systemui/statusbar/ActivatableNotificationView.java
index 403af70..7f17885 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/ActivatableNotificationView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/ActivatableNotificationView.java
@@ -350,6 +350,7 @@
} else {
updateBackground();
}
+ setOutlineAlpha(dark ? 0f : 1f);
}
public void setShowingLegacyBackground(boolean showing) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
index 490a8d8..9ff86eb 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
@@ -90,6 +90,7 @@
import com.android.internal.util.NotificationColorUtil;
import com.android.internal.widget.LockPatternUtils;
import com.android.keyguard.KeyguardUpdateMonitor;
+import com.android.systemui.DejankUtils;
import com.android.systemui.R;
import com.android.systemui.RecentsComponent;
import com.android.systemui.SwipeHelper;
@@ -167,13 +168,7 @@
// on-screen navigation buttons
protected NavigationBarView mNavigationBarView = null;
- protected Boolean mScreenOn;
-
- // The second field is a bit different from the first one because it only listens to screen on/
- // screen of events from Keyguard. We need this so we don't have a race condition with the
- // broadcast. In the future, we should remove the first field altogether and rename the second
- // field.
- protected boolean mScreenOnFromKeyguard;
+ protected boolean mDeviceInteractive;
protected boolean mVisible;
@@ -1565,6 +1560,15 @@
final PendingIntent intent = sbn.getNotification().contentIntent;
final String notificationKey = sbn.getKey();
+ // Mark notification for one frame.
+ row.setJustClicked(true);
+ DejankUtils.postAfterTraversal(new Runnable() {
+ @Override
+ public void run() {
+ row.setJustClicked(false);
+ }
+ });
+
if (NOTIFICATION_CLICK_DEBUG) {
Log.d(TAG, "Clicked on content of " + notificationKey);
}
@@ -1672,7 +1676,7 @@
protected void updateVisibleToUser() {
boolean oldVisibleToUser = mVisibleToUser;
- mVisibleToUser = mVisible && mScreenOnFromKeyguard;
+ mVisibleToUser = mVisible && mDeviceInteractive;
if (oldVisibleToUser != mVisibleToUser) {
handleVisibleToUserChanged(mVisibleToUser);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java b/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java
index a1b07b5..897f5e5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java
@@ -64,6 +64,7 @@
private static final int MSG_APP_TRANSITION_STARTING = 21 << MSG_SHIFT;
private static final int MSG_ASSIST_DISCLOSURE = 22 << MSG_SHIFT;
private static final int MSG_START_ASSIST = 23 << MSG_SHIFT;
+ private static final int MSG_CAMERA_LAUNCH_GESTURE = 24 << MSG_SHIFT;
public static final int FLAG_EXCLUDE_NONE = 0;
public static final int FLAG_EXCLUDE_SEARCH_PANEL = 1 << 0;
@@ -109,6 +110,7 @@
public void appTransitionStarting(long startTime, long duration);
public void showAssistDisclosure();
public void startAssist(Bundle args);
+ public void onCameraLaunchGestureDetected(int source);
}
public CommandQueue(Callbacks callbacks, StatusBarIconList list) {
@@ -293,6 +295,14 @@
}
}
+ @Override
+ public void onCameraLaunchGestureDetected(int source) {
+ synchronized (mList) {
+ mHandler.removeMessages(MSG_CAMERA_LAUNCH_GESTURE);
+ mHandler.obtainMessage(MSG_CAMERA_LAUNCH_GESTURE, source, 0).sendToTarget();
+ }
+ }
+
private final class H extends Handler {
public void handleMessage(Message msg) {
final int what = msg.what & MSG_MASK;
@@ -391,6 +401,9 @@
case MSG_START_ASSIST:
mCallbacks.startAssist((Bundle) msg.obj);
break;
+ case MSG_CAMERA_LAUNCH_GESTURE:
+ mCallbacks.onCameraLaunchGestureDetected(msg.arg1);
+ break;
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
index b88e5ca..56e9af5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
@@ -24,6 +24,7 @@
import android.graphics.drawable.AnimationDrawable;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
+import android.graphics.drawable.RippleDrawable;
import android.service.notification.StatusBarNotification;
import android.util.AttributeSet;
import android.view.MotionEvent;
@@ -31,6 +32,7 @@
import android.view.ViewStub;
import android.view.accessibility.AccessibilityEvent;
import android.view.animation.LinearInterpolator;
+import android.widget.Chronometer;
import android.widget.ImageView;
import com.android.systemui.R;
@@ -87,6 +89,7 @@
private NotificationGuts mGuts;
private StatusBarNotification mStatusBarNotification;
private boolean mIsHeadsUp;
+ private boolean mLastChronometerRunning = true;
private View mExpandButton;
private View mExpandButtonDivider;
private ViewStub mExpandButtonStub;
@@ -110,6 +113,8 @@
}
};
+ private boolean mJustClicked;
+
public NotificationContentView getPrivateLayout() {
return mPrivateLayout;
}
@@ -291,6 +296,7 @@
*/
public void setPinned(boolean pinned) {
mIsPinned = pinned;
+ setChronometerRunning(mLastChronometerRunning);
}
public boolean isPinned() {
@@ -301,6 +307,56 @@
return mHeadsUpHeight;
}
+ /**
+ * Mark whether this notification was just clicked, i.e. the user has just clicked this
+ * notification in this frame.
+ */
+ public void setJustClicked(boolean justClicked) {
+ mJustClicked = justClicked;
+ }
+
+ /**
+ * @return true if this notification has been clicked in this frame, false otherwise
+ */
+ public boolean wasJustClicked() {
+ return mJustClicked;
+ }
+
+ public void setChronometerRunning(boolean running) {
+ mLastChronometerRunning = running;
+ setChronometerRunning(running, mPrivateLayout);
+ setChronometerRunning(running, mPublicLayout);
+ if (mChildrenContainer != null) {
+ List<ExpandableNotificationRow> notificationChildren =
+ mChildrenContainer.getNotificationChildren();
+ for (int i = 0; i < notificationChildren.size(); i++) {
+ ExpandableNotificationRow child = notificationChildren.get(i);
+ child.setChronometerRunning(running);
+ }
+ }
+ }
+
+ private void setChronometerRunning(boolean running, NotificationContentView layout) {
+ if (layout != null) {
+ running = running || isPinned();
+ View contractedChild = layout.getContractedChild();
+ View expandedChild = layout.getExpandedChild();
+ View headsUpChild = layout.getHeadsUpChild();
+ setChronometerRunningForChild(running, contractedChild);
+ setChronometerRunningForChild(running, expandedChild);
+ setChronometerRunningForChild(running, headsUpChild);
+ }
+ }
+
+ private void setChronometerRunningForChild(boolean running, View child) {
+ if (child != null) {
+ View chronometer = child.findViewById(com.android.internal.R.id.chronometer);
+ if (chronometer instanceof Chronometer) {
+ ((Chronometer) chronometer).setStarted(running);
+ }
+ }
+ }
+
public interface ExpansionLogger {
public void logNotificationExpansion(String key, boolean userAction, boolean expanded);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableOutlineView.java b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableOutlineView.java
index d77e050..a6fc4bb 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableOutlineView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableOutlineView.java
@@ -34,6 +34,7 @@
private final Rect mOutlineRect = new Rect();
protected final int mRoundedRectCornerRadius;
private boolean mCustomOutline;
+ private float mOutlineAlpha = 1f;
public ExpandableOutlineView(Context context, AttributeSet attrs) {
super(context, attrs);
@@ -50,6 +51,7 @@
} else {
outline.setRoundRect(mOutlineRect, mRoundedRectCornerRadius);
}
+ outline.setAlpha(mOutlineAlpha);
}
});
}
@@ -66,6 +68,11 @@
invalidateOutline();
}
+ protected void setOutlineAlpha(float alpha) {
+ mOutlineAlpha = alpha;
+ invalidateOutline();
+ }
+
protected void setOutlineRect(RectF rect) {
if (rect != null) {
setOutlineRect(rect.left, rect.top, rect.right, rect.bottom);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardAffordanceView.java b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardAffordanceView.java
index 164c496..8058933 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardAffordanceView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardAffordanceView.java
@@ -36,6 +36,7 @@
import android.view.animation.AnimationUtils;
import android.view.animation.Interpolator;
import android.widget.ImageView;
+
import com.android.systemui.R;
import com.android.systemui.statusbar.phone.KeyguardAffordanceHelper;
import com.android.systemui.statusbar.phone.PhoneStatusBar;
@@ -79,6 +80,7 @@
private float mRestingAlpha = KeyguardAffordanceHelper.SWIPE_RESTING_ALPHA_AMOUNT;
private boolean mSupportHardware;
private boolean mFinishing;
+ private boolean mLaunchingAffordance;
private CanvasProperty<Float> mHwCircleRadius;
private CanvasProperty<Float> mHwCenterX;
@@ -152,7 +154,7 @@
@Override
protected void onDraw(Canvas canvas) {
- mSupportHardware = canvas.isHardwareAccelerated();
+ mSupportHardware = false;//canvas.isHardwareAccelerated();
drawBackgroundCircle(canvas);
canvas.save();
canvas.scale(mImageScale, mImageScale, getWidth() / 2, getHeight() / 2);
@@ -161,9 +163,11 @@
}
public void setPreviewView(View v) {
+ View oldPreviewView = mPreviewView;
mPreviewView = v;
if (mPreviewView != null) {
- mPreviewView.setVisibility(INVISIBLE);
+ mPreviewView.setVisibility(mLaunchingAffordance
+ ? oldPreviewView.getVisibility() : INVISIBLE);
}
}
@@ -176,7 +180,7 @@
}
private void drawBackgroundCircle(Canvas canvas) {
- if (mCircleRadius > 0) {
+ if (mCircleRadius > 0 || mFinishing) {
if (mFinishing && mSupportHardware) {
DisplayListCanvas displayListCanvas = (DisplayListCanvas) canvas;
displayListCanvas.drawCircle(mHwCenterX, mHwCenterY, mHwCircleRadius,
@@ -207,11 +211,12 @@
cancelAnimator(mPreviewClipper);
mFinishing = true;
mCircleStartRadius = mCircleRadius;
- float maxCircleSize = getMaxCircleSize();
+ final float maxCircleSize = getMaxCircleSize();
Animator animatorToRadius;
if (mSupportHardware) {
initHwProperties();
animatorToRadius = getRtAnimatorToRadius(maxCircleSize);
+ startRtAlphaFadeIn();
} else {
animatorToRadius = getAnimatorToRadius(maxCircleSize);
}
@@ -222,6 +227,8 @@
public void onAnimationEnd(Animator animation) {
mAnimationEndRunnable.run();
mFinishing = false;
+ mCircleRadius = maxCircleSize;
+ invalidate();
}
});
animatorToRadius.start();
@@ -241,6 +248,36 @@
}
}
+ /**
+ * Fades in the Circle on the RenderThread. It's used when finishing the circle when it had
+ * alpha 0 in the beginning.
+ */
+ private void startRtAlphaFadeIn() {
+ if (mCircleRadius == 0 && mPreviewView == null) {
+ Paint modifiedPaint = new Paint(mCirclePaint);
+ modifiedPaint.setColor(mCircleColor);
+ modifiedPaint.setAlpha(0);
+ mHwCirclePaint = CanvasProperty.createPaint(modifiedPaint);
+ RenderNodeAnimator animator = new RenderNodeAnimator(mHwCirclePaint,
+ RenderNodeAnimator.PAINT_ALPHA, 255);
+ animator.setTarget(this);
+ animator.setInterpolator(PhoneStatusBar.ALPHA_IN);
+ animator.setDuration(250);
+ animator.start();
+ }
+ }
+
+ public void instantFinishAnimation() {
+ cancelAnimator(mPreviewClipper);
+ if (mPreviewView != null) {
+ mPreviewView.setClipBounds(null);
+ mPreviewView.setVisibility(View.VISIBLE);
+ }
+ mCircleRadius = getMaxCircleSize();
+ setImageAlpha(0, false);
+ invalidate();
+ }
+
private void startRtCircleFadeOut(long duration) {
RenderNodeAnimator animator = new RenderNodeAnimator(mHwCirclePaint,
RenderNodeAnimator.PAINT_ALPHA, 0);
@@ -443,6 +480,7 @@
public void setImageAlpha(float alpha, boolean animate, long duration,
Interpolator interpolator, Runnable runnable) {
cancelAnimator(mAlphaAnimator);
+ alpha = mLaunchingAffordance ? 0 : alpha;
int endAlpha = (int) (alpha * 255);
final Drawable background = getBackground();
if (!animate) {
@@ -509,4 +547,8 @@
return false;
}
}
+
+ public void setLaunchingAffordance(boolean launchingAffordance) {
+ mLaunchingAffordance = launchingAffordance;
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
index 07a055c..fd84345 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
@@ -16,17 +16,13 @@
package com.android.systemui.statusbar;
-import com.android.internal.app.IBatteryStats;
-import com.android.keyguard.KeyguardUpdateMonitor;
-import com.android.keyguard.KeyguardUpdateMonitorCallback;
-import com.android.systemui.R;
-import com.android.systemui.statusbar.phone.KeyguardIndicationTextView;
-
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
+import android.content.res.Resources;
import android.graphics.Color;
+import android.hardware.fingerprint.FingerprintManager;
import android.os.BatteryManager;
import android.os.BatteryStats;
import android.os.Handler;
@@ -39,19 +35,35 @@
import android.util.Log;
import android.view.View;
+import com.android.internal.app.IBatteryStats;
+import com.android.keyguard.KeyguardUpdateMonitor;
+import com.android.keyguard.KeyguardUpdateMonitorCallback;
+import com.android.systemui.R;
+import com.android.systemui.statusbar.phone.KeyguardIndicationTextView;
+import com.android.systemui.statusbar.phone.LockIcon;
+import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
+
/**
- * Controls the little text indicator on the keyguard.
+ * Controls the indications and error messages shown on the Keyguard
*/
public class KeyguardIndicationController {
private static final String TAG = "KeyguardIndicationController";
+ private static final boolean DEBUG_CHARGING_CURRENT = false;
private static final int MSG_HIDE_TRANSIENT = 1;
+ private static final int MSG_CLEAR_FP_MSG = 2;
+ private static final long TRANSIENT_FP_ERROR_TIMEOUT = 1300;
private final Context mContext;
private final KeyguardIndicationTextView mTextView;
private final IBatteryStats mBatteryInfo;
+ private final int mSlowThreshold;
+ private final int mFastThreshold;
+ private final LockIcon mLockIcon;
+ private StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
+
private String mRestingIndication;
private String mTransientIndication;
private int mTransientTextColor;
@@ -59,10 +71,20 @@
private boolean mPowerPluggedIn;
private boolean mPowerCharged;
+ private int mChargingSpeed;
+ private int mChargingCurrent;
+ private String mMessageToShowOnScreenOn;
- public KeyguardIndicationController(Context context, KeyguardIndicationTextView textView) {
+ public KeyguardIndicationController(Context context, KeyguardIndicationTextView textView,
+ LockIcon lockIcon) {
mContext = context;
mTextView = textView;
+ mLockIcon = lockIcon;
+
+ Resources res = context.getResources();
+ mSlowThreshold = res.getInteger(R.integer.config_chargingSlowlyThreshold);
+ mFastThreshold = res.getInteger(R.integer.config_chargingFastThreshold);
+
mBatteryInfo = IBatteryStats.Stub.asInterface(
ServiceManager.getService(BatteryStats.SERVICE_NAME));
@@ -150,7 +172,11 @@
return mTransientIndication;
}
if (mPowerPluggedIn) {
- return computePowerIndication();
+ String indication = computePowerIndication();
+ if (DEBUG_CHARGING_CURRENT) {
+ indication += ", " + (mChargingCurrent / 1000) + " mA";
+ }
+ return indication;
}
return mRestingIndication;
}
@@ -161,20 +187,41 @@
}
// Try fetching charging time from battery stats.
+ long chargingTimeRemaining = 0;
try {
- long chargingTimeRemaining = mBatteryInfo.computeChargeTimeRemaining();
- if (chargingTimeRemaining > 0) {
- String chargingTimeFormatted = Formatter.formatShortElapsedTimeRoundingUpToMinutes(
- mContext, chargingTimeRemaining);
- return mContext.getResources().getString(
- R.string.keyguard_indication_charging_time, chargingTimeFormatted);
- }
+ chargingTimeRemaining = mBatteryInfo.computeChargeTimeRemaining();
+
} catch (RemoteException e) {
Log.e(TAG, "Error calling IBatteryStats: ", e);
}
+ final boolean hasChargingTime = chargingTimeRemaining > 0;
- // Fall back to simple charging label.
- return mContext.getResources().getString(R.string.keyguard_plugged_in);
+ int chargingId;
+ switch (mChargingSpeed) {
+ case KeyguardUpdateMonitor.BatteryStatus.CHARGING_FAST:
+ chargingId = hasChargingTime
+ ? R.string.keyguard_indication_charging_time_fast
+ : R.string.keyguard_plugged_in_charging_fast;
+ break;
+ case KeyguardUpdateMonitor.BatteryStatus.CHARGING_SLOWLY:
+ chargingId = hasChargingTime
+ ? R.string.keyguard_indication_charging_time_slowly
+ : R.string.keyguard_plugged_in_charging_slowly;
+ break;
+ default:
+ chargingId = hasChargingTime
+ ? R.string.keyguard_indication_charging_time
+ : R.string.keyguard_plugged_in;
+ break;
+ }
+
+ if (hasChargingTime) {
+ String chargingTimeFormatted = Formatter.formatShortElapsedTimeRoundingUpToMinutes(
+ mContext, chargingTimeRemaining);
+ return mContext.getResources().getString(chargingId, chargingTimeFormatted);
+ } else {
+ return mContext.getResources().getString(chargingId);
+ }
}
KeyguardUpdateMonitorCallback mUpdateMonitor = new KeyguardUpdateMonitorCallback() {
@@ -184,8 +231,68 @@
|| status.status == BatteryManager.BATTERY_STATUS_FULL;
mPowerPluggedIn = status.isPluggedIn() && isChargingOrFull;
mPowerCharged = status.isCharged();
+ mChargingCurrent = status.maxChargingCurrent;
+ mChargingSpeed = status.getChargingSpeed(mSlowThreshold, mFastThreshold);
updateIndication();
}
+
+ @Override
+ public void onFingerprintHelp(int msgId, String helpString) {
+ KeyguardUpdateMonitor updateMonitor = KeyguardUpdateMonitor.getInstance(mContext);
+ if (!updateMonitor.isUnlockingWithFingerprintAllowed()) {
+ return;
+ }
+ int errorColor = mContext.getResources().getColor(R.color.system_warning_color, null);
+ if (mStatusBarKeyguardViewManager.isBouncerShowing()) {
+ mStatusBarKeyguardViewManager.showBouncerMessage(helpString, errorColor);
+ } else if (updateMonitor.isDeviceInteractive()) {
+ mLockIcon.setTransientFpError(true);
+ showTransientIndication(helpString, errorColor);
+ mHandler.removeMessages(MSG_CLEAR_FP_MSG);
+ mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_CLEAR_FP_MSG),
+ TRANSIENT_FP_ERROR_TIMEOUT);
+ }
+ }
+
+ @Override
+ public void onFingerprintError(int msgId, String errString) {
+ KeyguardUpdateMonitor updateMonitor = KeyguardUpdateMonitor.getInstance(mContext);
+ if (!updateMonitor.isUnlockingWithFingerprintAllowed()
+ || msgId == FingerprintManager.FINGERPRINT_ERROR_CANCELED) {
+ return;
+ }
+ int errorColor = mContext.getResources().getColor(R.color.system_warning_color, null);
+ if (mStatusBarKeyguardViewManager.isBouncerShowing()) {
+ mStatusBarKeyguardViewManager.showBouncerMessage(errString, errorColor);
+ } else if (updateMonitor.isDeviceInteractive()) {
+ showTransientIndication(errString, errorColor);
+ // We want to keep this message around in case the screen was off
+ mHandler.removeMessages(MSG_HIDE_TRANSIENT);
+ hideTransientIndicationDelayed(5000);
+ } else {
+ mMessageToShowOnScreenOn = errString;
+ }
+ }
+
+ @Override
+ public void onScreenTurnedOn() {
+ if (mMessageToShowOnScreenOn != null) {
+ int errorColor = mContext.getResources().getColor(R.color.system_warning_color,
+ null);
+ showTransientIndication(mMessageToShowOnScreenOn, errorColor);
+ // We want to keep this message around in case the screen was off
+ mHandler.removeMessages(MSG_HIDE_TRANSIENT);
+ hideTransientIndicationDelayed(5000);
+ mMessageToShowOnScreenOn = null;
+ }
+ }
+
+ @Override
+ public void onFingerprintRunningStateChanged(boolean running) {
+ if (running) {
+ mMessageToShowOnScreenOn = null;
+ }
+ }
};
BroadcastReceiver mReceiver = new BroadcastReceiver() {
@@ -203,7 +310,15 @@
if (msg.what == MSG_HIDE_TRANSIENT && mTransientIndication != null) {
mTransientIndication = null;
updateIndication();
+ } else if (msg.what == MSG_CLEAR_FP_MSG) {
+ mLockIcon.setTransientFpError(false);
+ hideTransientIndication();
}
}
};
+
+ public void setStatusBarKeyguardViewManager(
+ StatusBarKeyguardViewManager statusBarKeyguardViewManager) {
+ mStatusBarKeyguardViewManager = statusBarKeyguardViewManager;
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationBackgroundView.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationBackgroundView.java
index 01aa8d1..8688c28 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationBackgroundView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationBackgroundView.java
@@ -86,6 +86,9 @@
if (mBackground != null) {
mBackground.setCallback(this);
}
+ if (mBackground instanceof RippleDrawable) {
+ ((RippleDrawable) mBackground).setForceSoftware(true);
+ }
invalidate();
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterView.java b/packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterView.java
index f7c3c67..cc30882 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterView.java
@@ -250,6 +250,7 @@
@Override
public void setNoSims(boolean show) {
mNoSimsVisible = show && !mBlockMobile;
+ apply();
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeParameters.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeParameters.java
index 6b167b4..1d890d0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeParameters.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeParameters.java
@@ -33,7 +33,7 @@
private static final String TAG = "DozeParameters";
private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
- private static final int MAX_DURATION = 10 * 1000;
+ private static final int MAX_DURATION = 60 * 1000;
private final Context mContext;
@@ -50,8 +50,6 @@
pw.print(" getPulseDuration(pickup=true): "); pw.println(getPulseDuration(true));
pw.print(" getPulseInDuration(pickup=false): "); pw.println(getPulseInDuration(false));
pw.print(" getPulseInDuration(pickup=true): "); pw.println(getPulseInDuration(true));
- pw.print(" getPulseInDelay(pickup=false): "); pw.println(getPulseInDelay(false));
- pw.print(" getPulseInDelay(pickup=true): "); pw.println(getPulseInDelay(true));
pw.print(" getPulseInVisibleDuration(): "); pw.println(getPulseVisibleDuration());
pw.print(" getPulseOutDuration(): "); pw.println(getPulseOutDuration());
pw.print(" getPulseOnSigMotion(): "); pw.println(getPulseOnSigMotion());
@@ -80,12 +78,6 @@
: getInt("doze.pulse.duration.in", R.integer.doze_pulse_duration_in);
}
- public int getPulseInDelay(boolean pickup) {
- return pickup
- ? getInt("doze.pulse.delay.in.pickup", R.integer.doze_pulse_delay_in_pickup)
- : getInt("doze.pulse.delay.in", R.integer.doze_pulse_delay_in);
- }
-
public int getPulseVisibleDuration() {
return getInt("doze.pulse.duration.visible", R.integer.doze_pulse_duration_visible);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeScrimController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeScrimController.java
index 3e17328..3ff69c9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeScrimController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeScrimController.java
@@ -100,10 +100,35 @@
mHandler.post(mPulseIn);
}
+ /**
+ * Aborts pulsing immediately.
+ */
+ public void abortPulsing() {
+ cancelPulsing();
+ if (mDozing) {
+ mScrimController.setDozeBehindAlpha(1f);
+ mScrimController.setDozeInFrontAlpha(1f);
+ }
+ }
+
+ public void onScreenTurnedOn() {
+ if (isPulsing()) {
+ final boolean pickup = mPulseReason == DozeLog.PULSE_REASON_SENSOR_PICKUP;
+ startScrimAnimation(true /* inFront */, 0f,
+ mDozeParameters.getPulseInDuration(pickup),
+ pickup ? mPulseInInterpolatorPickup : mPulseInInterpolator,
+ mPulseInFinished);
+ }
+ }
+
public boolean isPulsing() {
return mPulseCallback != null;
}
+ public boolean isDozing() {
+ return mDozing;
+ }
+
private void cancelPulsing() {
if (DEBUG) Log.d(TAG, "Cancel pulsing");
@@ -138,12 +163,11 @@
private void startScrimAnimation(final boolean inFront, float target, long duration,
Interpolator interpolator) {
- startScrimAnimation(inFront, target, duration, interpolator, 0 /* delay */,
- null /* endRunnable */);
+ startScrimAnimation(inFront, target, duration, interpolator, null /* endRunnable */);
}
private void startScrimAnimation(final boolean inFront, float target, long duration,
- Interpolator interpolator, long delay, final Runnable endRunnable) {
+ Interpolator interpolator, final Runnable endRunnable) {
Animator current = getCurrentAnimator(inFront);
if (current != null) {
float currentTarget = getCurrentTarget(inFront);
@@ -162,7 +186,6 @@
});
anim.setInterpolator(interpolator);
anim.setDuration(duration);
- anim.setStartDelay(delay);
anim.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
@@ -222,12 +245,6 @@
+ DozeLog.pulseReasonToString(mPulseReason));
if (!mDozing) return;
DozeLog.tracePulseStart(mPulseReason);
- final boolean pickup = mPulseReason == DozeLog.PULSE_REASON_SENSOR_PICKUP;
- startScrimAnimation(true /* inFront */, 0f,
- mDozeParameters.getPulseInDuration(pickup),
- pickup ? mPulseInInterpolatorPickup : mPulseInInterpolator,
- mDozeParameters.getPulseInDelay(pickup),
- mPulseInFinished);
// Signal that the pulse is ready to turn the screen on and draw.
pulseStarted();
@@ -249,7 +266,7 @@
if (DEBUG) Log.d(TAG, "Pulse out, mDozing=" + mDozing);
if (!mDozing) return;
startScrimAnimation(true /* inFront */, 1f, mDozeParameters.getPulseOutDuration(),
- mPulseOutInterpolator, 0 /* delay */, mPulseOutFinished);
+ mPulseOutInterpolator, mPulseOutFinished);
}
};
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/FingerprintUnlockController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/FingerprintUnlockController.java
new file mode 100644
index 0000000..2912963
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/FingerprintUnlockController.java
@@ -0,0 +1,298 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.systemui.statusbar.phone;
+
+import android.content.Context;
+import android.os.Handler;
+import android.os.PowerManager;
+import android.os.SystemClock;
+import android.util.Log;
+
+import com.android.keyguard.KeyguardConstants;
+import com.android.keyguard.KeyguardUpdateMonitor;
+import com.android.keyguard.KeyguardUpdateMonitorCallback;
+import com.android.systemui.keyguard.KeyguardViewMediator;
+
+/**
+ * Controller which coordinates all the fingerprint unlocking actions with the UI.
+ */
+public class FingerprintUnlockController extends KeyguardUpdateMonitorCallback {
+
+ private static final String TAG = "FingerprintController";
+ private static final boolean DEBUG_FP_WAKELOCK = KeyguardConstants.DEBUG_FP_WAKELOCK;
+ private static final long FINGERPRINT_WAKELOCK_TIMEOUT_MS = 15 * 1000;
+ private static final String FINGERPRINT_WAKE_LOCK_NAME = "wake-and-unlock wakelock";
+
+ /**
+ * Mode in which we don't need to wake up the device when we get a fingerprint.
+ */
+ public static final int MODE_NONE = 0;
+
+ /**
+ * Mode in which we wake up the device, and directly dismiss Keyguard. Active when we acquire
+ * a fingerprint while the screen is off and the device was sleeping.
+ */
+ public static final int MODE_WAKE_AND_UNLOCK = 1;
+
+ /**
+ * Mode in which we wake the device up, and fade out the Keyguard contents because they were
+ * already visible while pulsing in doze mode.
+ */
+ public static final int MODE_WAKE_AND_UNLOCK_PULSING = 2;
+
+ /**
+ * Mode in which we wake up the device, but play the normal dismiss animation. Active when we
+ * acquire a fingerprint pulsing in doze mode.
+ */
+ public static final int MODE_SHOW_BOUNCER = 3;
+
+ /**
+ * Mode in which we only wake up the device, and keyguard was not showing when we acquired a
+ * fingerprint.
+ * */
+ public static final int MODE_ONLY_WAKE = 4;
+
+ /**
+ * Mode in which fingerprint unlocks the device.
+ */
+ public static final int MODE_UNLOCK = 5;
+
+ /**
+ * Mode in which fingerprint brings up the bouncer because fingerprint unlocking is currently
+ * not allowed.
+ */
+ public static final int MODE_DISMISS_BOUNCER = 6;
+
+ /**
+ * How much faster we collapse the lockscreen when authenticating with fingerprint.
+ */
+ private static final float FINGERPRINT_COLLAPSE_SPEEDUP_FACTOR = 1.3f;
+
+ private PowerManager mPowerManager;
+ private Handler mHandler = new Handler();
+ private PowerManager.WakeLock mWakeLock;
+ private KeyguardUpdateMonitor mUpdateMonitor;
+ private int mMode;
+ private StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
+ private StatusBarWindowManager mStatusBarWindowManager;
+ private DozeScrimController mDozeScrimController;
+ private KeyguardViewMediator mKeyguardViewMediator;
+ private ScrimController mScrimController;
+ private PhoneStatusBar mPhoneStatusBar;
+ private boolean mGoingToSleep;
+ private int mPendingAuthenticatedUserId = -1;
+
+ public FingerprintUnlockController(Context context,
+ StatusBarWindowManager statusBarWindowManager,
+ DozeScrimController dozeScrimController,
+ KeyguardViewMediator keyguardViewMediator,
+ ScrimController scrimController,
+ PhoneStatusBar phoneStatusBar) {
+ mPowerManager = context.getSystemService(PowerManager.class);
+ mUpdateMonitor = KeyguardUpdateMonitor.getInstance(context);
+ mUpdateMonitor.registerCallback(this);
+ mStatusBarWindowManager = statusBarWindowManager;
+ mDozeScrimController = dozeScrimController;
+ mKeyguardViewMediator = keyguardViewMediator;
+ mScrimController = scrimController;
+ mPhoneStatusBar = phoneStatusBar;
+ }
+
+ public void setStatusBarKeyguardViewManager(
+ StatusBarKeyguardViewManager statusBarKeyguardViewManager) {
+ mStatusBarKeyguardViewManager = statusBarKeyguardViewManager;
+ }
+
+ private final Runnable mReleaseFingerprintWakeLockRunnable = new Runnable() {
+ @Override
+ public void run() {
+ if (DEBUG_FP_WAKELOCK) {
+ Log.i(TAG, "fp wakelock: TIMEOUT!!");
+ }
+ releaseFingerprintWakeLock();
+ }
+ };
+
+ private void releaseFingerprintWakeLock() {
+ if (mWakeLock != null) {
+ mHandler.removeCallbacks(mReleaseFingerprintWakeLockRunnable);
+ if (DEBUG_FP_WAKELOCK) {
+ Log.i(TAG, "releasing fp wakelock");
+ }
+ mWakeLock.release();
+ mWakeLock = null;
+ }
+ }
+
+ @Override
+ public void onFingerprintAcquired() {
+ releaseFingerprintWakeLock();
+ if (!mUpdateMonitor.isDeviceInteractive()) {
+ mWakeLock = mPowerManager.newWakeLock(
+ PowerManager.PARTIAL_WAKE_LOCK, FINGERPRINT_WAKE_LOCK_NAME);
+ mWakeLock.acquire();
+ if (DEBUG_FP_WAKELOCK) {
+ Log.i(TAG, "fingerprint acquired, grabbing fp wakelock");
+ }
+ mHandler.postDelayed(mReleaseFingerprintWakeLockRunnable,
+ FINGERPRINT_WAKELOCK_TIMEOUT_MS);
+ if (mDozeScrimController.isPulsing()) {
+
+ // If we are waking the device up while we are pulsing the clock and the
+ // notifications would light up first, creating an unpleasant animation.
+ // Defer changing the screen brightness by forcing doze brightness on our window
+ // until the clock and the notifications are faded out.
+ mStatusBarWindowManager.setForceDozeBrightness(true);
+ }
+ }
+ }
+
+ @Override
+ public void onFingerprintAuthenticated(int userId) {
+ if (mUpdateMonitor.isGoingToSleep()) {
+ mPendingAuthenticatedUserId = userId;
+ return;
+ }
+ boolean wasDeviceInteractive = mUpdateMonitor.isDeviceInteractive();
+ mMode = calculateMode();
+ if (!wasDeviceInteractive) {
+ if (DEBUG_FP_WAKELOCK) {
+ Log.i(TAG, "fp wakelock: Authenticated, waking up...");
+ }
+ mPowerManager.wakeUp(SystemClock.uptimeMillis());
+ }
+ releaseFingerprintWakeLock();
+ switch (mMode) {
+ case MODE_DISMISS_BOUNCER:
+ mStatusBarKeyguardViewManager.notifyKeyguardAuthenticated(
+ false /* strongAuth */);
+ break;
+ case MODE_UNLOCK:
+ case MODE_SHOW_BOUNCER:
+ if (!wasDeviceInteractive) {
+ mStatusBarKeyguardViewManager.notifyDeviceWakeUpRequested();
+ }
+ mStatusBarKeyguardViewManager.animateCollapsePanels(
+ FINGERPRINT_COLLAPSE_SPEEDUP_FACTOR);
+ break;
+ case MODE_WAKE_AND_UNLOCK_PULSING:
+ mPhoneStatusBar.updateMediaMetaData(false /* metaDataChanged */);
+ // Fall through.
+ case MODE_WAKE_AND_UNLOCK:
+ mStatusBarWindowManager.setStatusBarFocusable(false);
+ mDozeScrimController.abortPulsing();
+ mKeyguardViewMediator.onWakeAndUnlocking();
+ mScrimController.setWakeAndUnlocking();
+ if (mPhoneStatusBar.getNavigationBarView() != null) {
+ mPhoneStatusBar.getNavigationBarView().setWakeAndUnlocking(true);
+ }
+ break;
+ case MODE_ONLY_WAKE:
+ case MODE_NONE:
+ break;
+ }
+ if (mMode != MODE_WAKE_AND_UNLOCK_PULSING) {
+ mStatusBarWindowManager.setForceDozeBrightness(false);
+ }
+ mPhoneStatusBar.notifyFpAuthModeChanged();
+ }
+
+ @Override
+ public void onStartedGoingToSleep(int why) {
+ mPendingAuthenticatedUserId = -1;
+ }
+
+ @Override
+ public void onFinishedGoingToSleep(int why) {
+ if (mPendingAuthenticatedUserId != -1) {
+
+ // Post this to make sure it's executed after the device is fully locked.
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ onFingerprintAuthenticated(mPendingAuthenticatedUserId);
+ }
+ });
+ }
+ mPendingAuthenticatedUserId = -1;
+ }
+
+ public int getMode() {
+ return mMode;
+ }
+
+ private int calculateMode() {
+ boolean unlockingAllowed = mUpdateMonitor.isUnlockingWithFingerprintAllowed();
+ if (!mUpdateMonitor.isDeviceInteractive()) {
+ if (!mStatusBarKeyguardViewManager.isShowing()) {
+ return MODE_ONLY_WAKE;
+ } else if (mDozeScrimController.isPulsing() && unlockingAllowed) {
+ return MODE_WAKE_AND_UNLOCK_PULSING;
+ } else if (unlockingAllowed) {
+ return MODE_WAKE_AND_UNLOCK;
+ } else {
+ return MODE_SHOW_BOUNCER;
+ }
+ }
+ if (mStatusBarKeyguardViewManager.isShowing()) {
+ if (mStatusBarKeyguardViewManager.isBouncerShowing() && unlockingAllowed) {
+ return MODE_DISMISS_BOUNCER;
+ } else if (unlockingAllowed) {
+ return MODE_UNLOCK;
+ } else if (!mStatusBarKeyguardViewManager.isBouncerShowing()) {
+ return MODE_SHOW_BOUNCER;
+ }
+ }
+ return MODE_NONE;
+ }
+
+ @Override
+ public void onFingerprintAuthFailed() {
+ cleanup();
+ }
+
+ @Override
+ public void onFingerprintError(int msgId, String errString) {
+ cleanup();
+ }
+
+ private void cleanup() {
+ mMode = MODE_NONE;
+ releaseFingerprintWakeLock();
+ mStatusBarWindowManager.setForceDozeBrightness(false);
+ mPhoneStatusBar.notifyFpAuthModeChanged();
+ }
+
+ public void startKeyguardFadingAway() {
+
+ // Disable brightness override when the ambient contents are fully invisible.
+ mHandler.postDelayed(new Runnable() {
+ @Override
+ public void run() {
+ mStatusBarWindowManager.setForceDozeBrightness(false);
+ }
+ }, PhoneStatusBar.FADE_KEYGUARD_DURATION_PULSING);
+ }
+
+ public void finishKeyguardFadingAway() {
+ mMode = MODE_NONE;
+ if (mPhoneStatusBar.getNavigationBarView() != null) {
+ mPhoneStatusBar.getNavigationBarView().setWakeAndUnlocking(false);
+ }
+ mPhoneStatusBar.notifyFpAuthModeChanged();
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardAffordanceHelper.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardAffordanceHelper.java
index 10019f9..60ebfdf 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardAffordanceHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardAffordanceHelper.java
@@ -86,9 +86,9 @@
mContext = context;
mCallback = callback;
initIcons();
- updateIcon(mLeftIcon, 0.0f, mLeftIcon.getRestingAlpha(), false, false, true);
- updateIcon(mCenterIcon, 0.0f, mCenterIcon.getRestingAlpha(), false, false, true);
- updateIcon(mRightIcon, 0.0f, mRightIcon.getRestingAlpha(), false, false, true);
+ updateIcon(mLeftIcon, 0.0f, mLeftIcon.getRestingAlpha(), false, false, true, false);
+ updateIcon(mCenterIcon, 0.0f, mCenterIcon.getRestingAlpha(), false, false, true, false);
+ updateIcon(mRightIcon, 0.0f, mRightIcon.getRestingAlpha(), false, false, true, false);
initDimens();
}
@@ -144,9 +144,7 @@
} else {
mTouchSlopExeeded = false;
}
- mCallback.onSwipingStarted(targetView == mRightIcon);
- mSwipingInProgress = true;
- mTargetedView = targetView;
+ startSwiping(targetView);
mInitialTouchX = x;
mInitialTouchY = y;
mTranslationOnDown = mTranslation;
@@ -192,6 +190,12 @@
return true;
}
+ private void startSwiping(View targetView) {
+ mCallback.onSwipingStarted(targetView == mRightIcon);
+ mSwipingInProgress = true;
+ mTargetedView = targetView;
+ }
+
private View getIconAtPosition(float x, float y) {
if (leftSwipePossible() && isOnIcon(mLeftIcon, x, y)) {
return mLeftIcon;
@@ -324,7 +328,7 @@
boolean velIsInWrongDirection = vel * mTranslation < 0;
snapBack |= Math.abs(vel) > mMinFlingVelocity && velIsInWrongDirection;
vel = snapBack ^ velIsInWrongDirection ? 0 : vel;
- fling(vel, snapBack || forceSnapBack);
+ fling(vel, snapBack || forceSnapBack, mTranslation < 0);
}
private boolean isBelowFalsingThreshold() {
@@ -336,9 +340,8 @@
return (int) (mMinTranslationAmount * factor);
}
- private void fling(float vel, final boolean snapBack) {
- float target = mTranslation < 0
- ? -mCallback.getMaxTranslationDistance()
+ private void fling(float vel, final boolean snapBack, boolean right) {
+ float target = right ? -mCallback.getMaxTranslationDistance()
: mCallback.getMaxTranslationDistance();
target = snapBack ? 0 : target;
@@ -352,8 +355,8 @@
});
animator.addListener(mFlingEndListener);
if (!snapBack) {
- startFinishingCircleAnimation(vel * 0.375f, mAnimationEndRunnable);
- mCallback.onAnimationToSideStarted(mTranslation < 0, mTranslation, vel);
+ startFinishingCircleAnimation(vel * 0.375f, mAnimationEndRunnable, right);
+ mCallback.onAnimationToSideStarted(right, mTranslation, vel);
} else {
reset(true);
}
@@ -364,8 +367,9 @@
}
}
- private void startFinishingCircleAnimation(float velocity, Runnable mAnimationEndRunnable) {
- KeyguardAffordanceView targetView = mTranslation > 0 ? mLeftIcon : mRightIcon;
+ private void startFinishingCircleAnimation(float velocity, Runnable mAnimationEndRunnable,
+ boolean right) {
+ KeyguardAffordanceView targetView = right ? mRightIcon : mLeftIcon;
targetView.finishAnimation(velocity, mAnimationEndRunnable);
}
@@ -383,19 +387,20 @@
fadeOutAlpha = Math.max(fadeOutAlpha, 0.0f);
boolean animateIcons = isReset && animateReset;
+ boolean forceNoCircleAnimation = isReset && !animateReset;
float radius = getRadiusFromTranslation(absTranslation);
boolean slowAnimation = isReset && isBelowFalsingThreshold();
if (!isReset) {
updateIcon(targetView, radius, alpha + fadeOutAlpha * targetView.getRestingAlpha(),
- false, false, false);
+ false, false, false, false);
} else {
updateIcon(targetView, 0.0f, fadeOutAlpha * targetView.getRestingAlpha(),
- animateIcons, slowAnimation, false);
+ animateIcons, slowAnimation, false, forceNoCircleAnimation);
}
updateIcon(otherView, 0.0f, fadeOutAlpha * otherView.getRestingAlpha(),
- animateIcons, slowAnimation, false);
+ animateIcons, slowAnimation, false, forceNoCircleAnimation);
updateIcon(mCenterIcon, 0.0f, fadeOutAlpha * mCenterIcon.getRestingAlpha(),
- animateIcons, slowAnimation, false);
+ animateIcons, slowAnimation, false, forceNoCircleAnimation);
mTranslation = translation;
}
@@ -431,16 +436,21 @@
public void animateHideLeftRightIcon() {
cancelAnimation();
- updateIcon(mRightIcon, 0f, 0f, true, false, false);
- updateIcon(mLeftIcon, 0f, 0f, true, false, false);
+ updateIcon(mRightIcon, 0f, 0f, true, false, false, false);
+ updateIcon(mLeftIcon, 0f, 0f, true, false, false, false);
}
private void updateIcon(KeyguardAffordanceView view, float circleRadius, float alpha,
- boolean animate, boolean slowRadiusAnimation, boolean force) {
+ boolean animate, boolean slowRadiusAnimation, boolean force,
+ boolean forceNoCircleAnimation) {
if (view.getVisibility() != View.VISIBLE && !force) {
return;
}
- view.setCircleRadius(circleRadius, slowRadiusAnimation);
+ if (forceNoCircleAnimation) {
+ view.setCircleRadiusWithoutAnimation(circleRadius);
+ } else {
+ view.setCircleRadius(circleRadius, slowRadiusAnimation);
+ }
updateIconAlpha(view, alpha, animate);
}
@@ -503,8 +513,36 @@
mMotionCancelled = true;
if (mSwipingInProgress) {
mCallback.onSwipingAborted();
+ mSwipingInProgress = false;
}
- mSwipingInProgress = false;
+ }
+
+ public boolean isSwipingInProgress() {
+ return mSwipingInProgress;
+ }
+
+ public void launchAffordance(boolean animate, boolean left) {
+ if (mSwipingInProgress) {
+ // We don't want to mess with the state if the user is actually swiping already.
+ return;
+ }
+ KeyguardAffordanceView targetView = left ? mLeftIcon : mRightIcon;
+ KeyguardAffordanceView otherView = left ? mRightIcon : mLeftIcon;
+ startSwiping(targetView);
+ if (animate) {
+ fling(0, false, !left);
+ updateIcon(otherView, 0.0f, 0, true, false, true, false);
+ updateIcon(mCenterIcon, 0.0f, 0, true, false, true, false);
+ } else {
+ mCallback.onAnimationToSideStarted(!left, mTranslation, 0);
+ mTranslation = left ? mCallback.getMaxTranslationDistance()
+ : mCallback.getMaxTranslationDistance();
+ updateIcon(mCenterIcon, 0.0f, 0.0f, false, false, true, false);
+ updateIcon(otherView, 0.0f, 0.0f, false, false, true, false);
+ targetView.instantFinishAnimation();
+ mFlingEndListener.onAnimationEnd(null);
+ mAnimationEndRunnable.run();
+ }
}
public interface Callback {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
index 1a2fa97..14176a6 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
@@ -29,7 +29,6 @@
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.content.res.Configuration;
-import android.hardware.fingerprint.FingerprintManager;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.IBinder;
@@ -78,15 +77,21 @@
final static String TAG = "PhoneStatusBar/KeyguardBottomAreaView";
+ public static final String CAMERA_LAUNCH_SOURCE_AFFORDANCE = "lockscreen_affordance";
+ public static final String CAMERA_LAUNCH_SOURCE_WIGGLE = "wiggle_gesture";
+ public static final String CAMERA_LAUNCH_SOURCE_POWER_DOUBLE_TAP = "power_double_tap";
+
+ public static final String EXTRA_CAMERA_LAUNCH_SOURCE
+ = "com.android.systemui.camera_launch_source";
+
private static final Intent SECURE_CAMERA_INTENT =
new Intent(MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA_SECURE)
.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
- private static final Intent INSECURE_CAMERA_INTENT =
+ public static final Intent INSECURE_CAMERA_INTENT =
new Intent(MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA);
private static final Intent PHONE_INTENT = new Intent(Intent.ACTION_DIAL);
private static final int DOZE_ANIMATION_STAGGER_DELAY = 48;
private static final int DOZE_ANIMATION_ELEMENT_DURATION = 250;
- private static final long TRANSIENT_FP_ERROR_TIMEOUT = 1300;
private KeyguardAffordanceView mCameraImageView;
private KeyguardAffordanceView mLeftAffordanceView;
@@ -172,7 +177,7 @@
CommandQueue.FLAG_EXCLUDE_RECENTS_PANEL, true /* force */);
return true;
} else if (host == mCameraImageView) {
- launchCamera();
+ launchCamera(CAMERA_LAUNCH_SOURCE_AFFORDANCE);
return true;
} else if (host == mLeftAffordanceView) {
launchLeftAffordance();
@@ -264,14 +269,21 @@
return (secure && !canSkipBouncer) ? SECURE_CAMERA_INTENT : INSECURE_CAMERA_INTENT;
}
+ /**
+ * Resolves the intent to launch the camera application.
+ */
+ public ResolveInfo resolveCameraIntent() {
+ return mContext.getPackageManager().resolveActivityAsUser(getCameraIntent(),
+ PackageManager.MATCH_DEFAULT_ONLY,
+ KeyguardUpdateMonitor.getCurrentUser());
+ }
+
private void updateCameraVisibility() {
if (mCameraImageView == null) {
// Things are not set up yet; reply hazy, ask again later
return;
}
- ResolveInfo resolved = mContext.getPackageManager().resolveActivityAsUser(getCameraIntent(),
- PackageManager.MATCH_DEFAULT_ONLY,
- KeyguardUpdateMonitor.getCurrentUser());
+ ResolveInfo resolved = resolveCameraIntent();
boolean visible = !isCameraDisabledByDpm() && resolved != null
&& getResources().getBoolean(R.bool.config_keyguardShowCameraAffordance)
&& mUserSetupComplete;
@@ -344,7 +356,7 @@
@Override
public void onClick(View v) {
if (v == mCameraImageView) {
- launchCamera();
+ launchCamera(CAMERA_LAUNCH_SOURCE_AFFORDANCE);
} else if (v == mLeftAffordanceView) {
launchLeftAffordance();
} if (v == mLockIcon) {
@@ -385,7 +397,8 @@
serviceIntent.setAction(CameraPrewarmService.ACTION_PREWARM);
try {
if (getContext().bindServiceAsUser(serviceIntent, mPrewarmConnection,
- Context.BIND_AUTO_CREATE, new UserHandle(UserHandle.USER_CURRENT))) {
+ Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE,
+ new UserHandle(UserHandle.USER_CURRENT))) {
mPrewarmBound = true;
}
} catch (SecurityException e) {
@@ -411,8 +424,9 @@
}
}
- public void launchCamera() {
+ public void launchCamera(String source) {
final Intent intent = getCameraIntent();
+ intent.putExtra(EXTRA_CAMERA_LAUNCH_SOURCE, source);
boolean wouldLaunchResolverActivity = PreviewInflater.wouldLaunchResolverActivity(
mContext, intent, KeyguardUpdateMonitor.getCurrentUser());
if (intent == SECURE_CAMERA_INTENT && !wouldLaunchResolverActivity) {
@@ -528,7 +542,7 @@
return mCameraPreview;
}
- public KeyguardAffordanceView getLockIcon() {
+ public LockIcon getLockIcon() {
return mLockIcon;
}
@@ -613,21 +627,6 @@
}
};
- private final Runnable mTransientFpErrorClearRunnable = new Runnable() {
- @Override
- public void run() {
- mLockIcon.setTransientFpError(false);
- mIndicationController.hideTransientIndication();
- }
- };
-
- private final Runnable mHideTransientIndicationRunnable = new Runnable() {
- @Override
- public void run() {
- mIndicationController.hideTransientIndication();
- }
- };
-
private final KeyguardUpdateMonitorCallback mUpdateMonitorCallback =
new KeyguardUpdateMonitorCallback() {
@Override
@@ -646,12 +645,18 @@
}
@Override
- public void onKeyguardVisibilityChanged(boolean showing) {
- mLockIcon.update();
+ public void onScreenTurnedOn() {
+ mLockIcon.setScreenOn(true);
}
@Override
- public void onFingerprintAuthenticated(int userId, boolean wakeAndUnlocking) {
+ public void onScreenTurnedOff() {
+ mLockIcon.setScreenOn(false);
+ }
+
+ @Override
+ public void onKeyguardVisibilityChanged(boolean showing) {
+ mLockIcon.update();
}
@Override
@@ -660,28 +665,8 @@
}
@Override
- public void onFingerprintHelp(int msgId, String helpString) {
- if (!KeyguardUpdateMonitor.getInstance(mContext).isUnlockingWithFingerprintAllowed()) {
- return;
- }
- mLockIcon.setTransientFpError(true);
- mIndicationController.showTransientIndication(helpString,
- getResources().getColor(R.color.system_warning_color, null));
- removeCallbacks(mTransientFpErrorClearRunnable);
- postDelayed(mTransientFpErrorClearRunnable, TRANSIENT_FP_ERROR_TIMEOUT);
- }
-
- @Override
- public void onFingerprintError(int msgId, String errString) {
- if (!KeyguardUpdateMonitor.getInstance(mContext).isUnlockingWithFingerprintAllowed()
- || msgId == FingerprintManager.FINGERPRINT_ERROR_CANCELED) {
- return;
- }
- // TODO: Go to bouncer if this is "too many attempts" (lockout) error.
- mIndicationController.showTransientIndication(errString,
- getResources().getColor(R.color.system_warning_color, null));
- removeCallbacks(mHideTransientIndicationRunnable);
- postDelayed(mHideTransientIndicationRunnable, 5000);
+ public void onStrongAuthStateChanged(int userId) {
+ mLockIcon.update();
}
};
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java
index e9b2c61..893b352 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java
@@ -17,7 +17,6 @@
package com.android.systemui.statusbar.phone;
import android.content.Context;
-import android.view.Choreographer;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
@@ -27,6 +26,8 @@
import com.android.internal.widget.LockPatternUtils;
import com.android.keyguard.KeyguardHostView;
import com.android.keyguard.KeyguardSecurityView;
+import com.android.keyguard.KeyguardUpdateMonitor;
+import com.android.keyguard.KeyguardUpdateMonitorCallback;
import com.android.keyguard.R;
import com.android.keyguard.ViewMediatorCallback;
import com.android.systemui.DejankUtils;
@@ -48,6 +49,13 @@
private ViewGroup mRoot;
private boolean mShowingSoon;
private int mBouncerPromptReason;
+ private KeyguardUpdateMonitorCallback mUpdateMonitorCallback =
+ new KeyguardUpdateMonitorCallback() {
+ @Override
+ public void onStrongAuthStateChanged(int userId) {
+ mBouncerPromptReason = mCallback.getBouncerPromptReason();
+ }
+ };
public KeyguardBouncer(Context context, ViewMediatorCallback callback,
LockPatternUtils lockPatternUtils, StatusBarWindowManager windowManager,
@@ -57,6 +65,7 @@
mLockPatternUtils = lockPatternUtils;
mContainer = container;
mWindowManager = windowManager;
+ KeyguardUpdateMonitor.getInstance(mContext).registerCallback(mUpdateMonitorCallback);
}
public void show(boolean resetSecuritySelection) {
@@ -103,6 +112,10 @@
mKeyguardView.showPromptReason(reason);
}
+ public void showMessage(String message, int color) {
+ mKeyguardView.showMessage(message, color);
+ }
+
private void cancelShowRunnable() {
DejankUtils.removeCallbacks(mShowRunnable);
mShowingSoon = false;
@@ -244,8 +257,8 @@
return mKeyguardView.interceptMediaKey(event);
}
- public void notifyKeyguardAuthenticated() {
+ public void notifyKeyguardAuthenticated(boolean strongAuth) {
ensureView();
- mKeyguardView.finish();
+ mKeyguardView.finish(strongAuth);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockIcon.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockIcon.java
index 06d2fca..8e58d14 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockIcon.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockIcon.java
@@ -34,12 +34,6 @@
*/
public class LockIcon extends KeyguardAffordanceView {
- /**
- * Delay animations a bit when the screen just turned on as a heuristic to start them after
- * the screen has actually turned on.
- */
- private static final long ANIM_DELAY_AFTER_SCREEN_ON = 250;
-
private static final int STATE_LOCKED = 0;
private static final int STATE_LOCK_OPEN = 1;
private static final int STATE_FACE_UNLOCK = 2;
@@ -50,6 +44,8 @@
private boolean mLastDeviceInteractive;
private boolean mTransientFpError;
private boolean mDeviceInteractive;
+ private boolean mScreenOn;
+ private boolean mLastScreenOn;
private final TrustDrawable mTrustDrawable;
private final UnlockMethodCache mUnlockMethodCache;
private AccessibilityController mAccessibilityController;
@@ -88,6 +84,11 @@
update();
}
+ public void setScreenOn(boolean screenOn) {
+ mScreenOn = screenOn;
+ update();
+ }
+
public void update() {
boolean visible = isShown()
&& KeyguardUpdateMonitor.getInstance(mContext).isDeviceInteractive();
@@ -96,20 +97,32 @@
} else {
mTrustDrawable.stop();
}
- if (!visible) {
- return;
- }
// TODO: Real icon for facelock.
int state = getState();
boolean anyFingerprintIcon = state == STATE_FINGERPRINT || state == STATE_FINGERPRINT_ERROR;
- if (state != mLastState || mDeviceInteractive != mLastDeviceInteractive) {
+ boolean useAdditionalPadding = anyFingerprintIcon;
+ boolean trustHidden = anyFingerprintIcon;
+ if (state != mLastState || mDeviceInteractive != mLastDeviceInteractive
+ || mScreenOn != mLastScreenOn) {
+ boolean isAnim = true;
int iconRes = getAnimationResForTransition(mLastState, state, mLastDeviceInteractive,
- mDeviceInteractive);
+ mDeviceInteractive, mLastScreenOn, mScreenOn);
if (iconRes == R.drawable.lockscreen_fingerprint_draw_off_animation) {
anyFingerprintIcon = true;
+ useAdditionalPadding = true;
+ trustHidden = true;
+ } else if (iconRes == R.drawable.trusted_state_to_error_animation) {
+ anyFingerprintIcon = true;
+ useAdditionalPadding = false;
+ trustHidden = true;
+ } else if (iconRes == R.drawable.error_to_trustedstate_animation) {
+ anyFingerprintIcon = true;
+ useAdditionalPadding = false;
+ trustHidden = false;
}
if (iconRes == -1) {
- iconRes = getIconForState(state);
+ iconRes = getIconForState(state, mScreenOn, mDeviceInteractive);
+ isAnim = false;
}
Drawable icon = mContext.getDrawable(iconRes);
final AnimatedVectorDrawable animation = icon instanceof AnimatedVectorDrawable
@@ -123,7 +136,7 @@
|| icon.getIntrinsicWidth() != iconWidth)) {
icon = new IntrinsicSizeDrawable(icon, iconWidth, iconHeight);
}
- setPaddingRelative(0, 0, 0, anyFingerprintIcon
+ setPaddingRelative(0, 0, 0, useAdditionalPadding
? getResources().getDimensionPixelSize(
R.dimen.fingerprint_icon_additional_padding)
: 0);
@@ -135,27 +148,16 @@
: R.string.accessibility_unlock_button);
setContentDescription(contentDescription);
mHasFingerPrintIcon = anyFingerprintIcon;
- if (animation != null) {
-
- // If we play the draw on animation, delay it by one frame when the screen is
- // actually turned on.
- if (iconRes == R.drawable.lockscreen_fingerprint_draw_on_animation) {
- postOnAnimationDelayed(new Runnable() {
- @Override
- public void run() {
- animation.start();
- }
- }, ANIM_DELAY_AFTER_SCREEN_ON);
- } else {
- animation.start();
- }
+ if (animation != null && isAnim) {
+ animation.start();
}
mLastState = state;
mLastDeviceInteractive = mDeviceInteractive;
+ mLastScreenOn = mScreenOn;
}
// Hide trust circle when fingerprint is running.
- boolean trustManaged = mUnlockMethodCache.isTrustManaged() && !anyFingerprintIcon;
+ boolean trustManaged = mUnlockMethodCache.isTrustManaged() && !trustHidden;
mTrustDrawable.setTrustManaged(trustManaged);
updateClickability();
}
@@ -192,7 +194,7 @@
mAccessibilityController = accessibilityController;
}
- private int getIconForState(int state) {
+ private int getIconForState(int state, boolean screenOn, boolean deviceInteractive) {
switch (state) {
case STATE_LOCKED:
return R.drawable.ic_lock_24dp;
@@ -201,7 +203,11 @@
case STATE_FACE_UNLOCK:
return com.android.internal.R.drawable.ic_account_circle;
case STATE_FINGERPRINT:
- return R.drawable.ic_fingerprint;
+ // If screen is off and device asleep, use the draw on animation so the first frame
+ // gets drawn.
+ return screenOn && deviceInteractive
+ ? R.drawable.ic_fingerprint
+ : R.drawable.lockscreen_fingerprint_draw_on_animation;
case STATE_FINGERPRINT_ERROR:
return R.drawable.ic_fingerprint_error;
default:
@@ -209,16 +215,22 @@
}
}
- private int getAnimationResForTransition(int oldState, int newState, boolean oldScreenOn,
- boolean screenOn) {
+ private int getAnimationResForTransition(int oldState, int newState,
+ boolean oldDeviceInteractive, boolean deviceInteractive,
+ boolean oldScreenOn, boolean screenOn) {
if (oldState == STATE_FINGERPRINT && newState == STATE_FINGERPRINT_ERROR) {
return R.drawable.lockscreen_fingerprint_fp_to_error_state_animation;
+ } else if (oldState == STATE_LOCK_OPEN && newState == STATE_FINGERPRINT_ERROR) {
+ return R.drawable.trusted_state_to_error_animation;
+ } else if (oldState == STATE_FINGERPRINT_ERROR && newState == STATE_LOCK_OPEN) {
+ return R.drawable.error_to_trustedstate_animation;
} else if (oldState == STATE_FINGERPRINT_ERROR && newState == STATE_FINGERPRINT) {
return R.drawable.lockscreen_fingerprint_error_state_to_fp_animation;
} else if (oldState == STATE_FINGERPRINT && newState == STATE_LOCK_OPEN
&& !mUnlockMethodCache.isTrusted()) {
return R.drawable.lockscreen_fingerprint_draw_off_animation;
- } else if (newState == STATE_FINGERPRINT && !oldScreenOn && screenOn) {
+ } else if (newState == STATE_FINGERPRINT && (!oldScreenOn && screenOn && deviceInteractive
+ || screenOn && !oldDeviceInteractive && deviceInteractive)) {
return R.drawable.lockscreen_fingerprint_draw_on_animation;
} else {
return -1;
@@ -229,14 +241,14 @@
KeyguardUpdateMonitor updateMonitor = KeyguardUpdateMonitor.getInstance(mContext);
boolean fingerprintRunning = updateMonitor.isFingerprintDetectionRunning();
boolean unlockingAllowed = updateMonitor.isUnlockingWithFingerprintAllowed();
- if (mUnlockMethodCache.canSkipBouncer()) {
- return STATE_LOCK_OPEN;
- } else if (mTransientFpError) {
+ if (mTransientFpError) {
return STATE_FINGERPRINT_ERROR;
- } else if (fingerprintRunning && unlockingAllowed) {
- return STATE_FINGERPRINT;
+ } else if (mUnlockMethodCache.canSkipBouncer()) {
+ return STATE_LOCK_OPEN;
} else if (mUnlockMethodCache.isFaceUnlockRunning()) {
return STATE_FACE_UNLOCK;
+ } else if (fingerprintRunning && unlockingAllowed) {
+ return STATE_FINGERPRINT;
} else {
return STATE_LOCKED;
}
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 059ecee..8046eb5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
@@ -91,7 +91,8 @@
private OnVerticalChangedListener mOnVerticalChangedListener;
private boolean mIsLayoutRtl;
- private boolean mLayoutTransitionsEnabled;
+ private boolean mLayoutTransitionsEnabled = true;
+ private boolean mWakeAndUnlocking;
private class NavTransitionListener implements TransitionListener {
private boolean mBackTransitioning;
@@ -256,11 +257,11 @@
private void getIcons(Resources res) {
mBackIcon = res.getDrawable(R.drawable.ic_sysbar_back);
- mBackLandIcon = res.getDrawable(R.drawable.ic_sysbar_back_land);
+ mBackLandIcon = mBackIcon;
mBackAltIcon = res.getDrawable(R.drawable.ic_sysbar_back_ime);
- mBackAltLandIcon = res.getDrawable(R.drawable.ic_sysbar_back_ime_land);
+ mBackAltLandIcon = mBackAltIcon;
mRecentIcon = res.getDrawable(R.drawable.ic_sysbar_recent);
- mRecentLandIcon = res.getDrawable(R.drawable.ic_sysbar_recent_land);
+ mRecentLandIcon = mRecentIcon;
}
@Override
@@ -361,13 +362,19 @@
}
}
- public void setWakeAndUnlocking(boolean wakeAndUnlocking) {
- setUseFadingAnimations(wakeAndUnlocking);
- setLayoutTransitionsEnabled(!wakeAndUnlocking);
+ public void setLayoutTransitionsEnabled(boolean enabled) {
+ mLayoutTransitionsEnabled = enabled;
+ updateLayoutTransitionsEnabled();
}
- private void setLayoutTransitionsEnabled(boolean enabled) {
- mLayoutTransitionsEnabled = enabled;
+ public void setWakeAndUnlocking(boolean wakeAndUnlocking) {
+ setUseFadingAnimations(wakeAndUnlocking);
+ mWakeAndUnlocking = wakeAndUnlocking;
+ updateLayoutTransitionsEnabled();
+ }
+
+ private void updateLayoutTransitionsEnabled() {
+ boolean enabled = !mWakeAndUnlocking && mLayoutTransitionsEnabled;
ViewGroup navButtons = (ViewGroup) mCurrentView.findViewById(R.id.nav_buttons);
LayoutTransition lt = navButtons.getLayoutTransition();
if (lt != null) {
@@ -459,7 +466,7 @@
}
mCurrentView = mRotatedViews[rot];
mCurrentView.setVisibility(View.VISIBLE);
- setLayoutTransitionsEnabled(mLayoutTransitionsEnabled);
+ updateLayoutTransitionsEnabled();
getImeSwitchButton().setOnClickListener(mImeSwitcherClickListener);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
index 373abe5..bdd2c73 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
@@ -21,7 +21,10 @@
import android.animation.ObjectAnimator;
import android.animation.PropertyValuesHolder;
import android.animation.ValueAnimator;
+import android.app.ActivityManager;
+import android.app.StatusBarManager;
import android.content.Context;
+import android.content.pm.ResolveInfo;
import android.content.res.Configuration;
import android.graphics.Canvas;
import android.graphics.Color;
@@ -61,6 +64,8 @@
import com.android.systemui.statusbar.stack.NotificationStackScrollLayout;
import com.android.systemui.statusbar.stack.StackStateAnimator;
+import java.util.List;
+
public class NotificationPanelView extends PanelView implements
ExpandableView.OnHeightChangedListener, ObservableScrollView.Listener,
View.OnClickListener, NotificationStackScrollLayout.OnOverscrollTopChangedListener,
@@ -106,12 +111,6 @@
private boolean mQsTracking;
/**
- * Handles launching the secure camera properly even when other applications may be using the
- * camera hardware.
- */
- private SecureCameraLaunchManager mSecureCameraLaunchManager;
-
- /**
* If set, the ongoing touch gesture might both trigger the expansion in {@link PanelView} and
* the expansion for quick settings.
*/
@@ -203,6 +202,8 @@
private int mLastOrientation = -1;
private boolean mClosingWithAlphaFadeOut;
private boolean mHeadsUpAnimatingAway;
+ private boolean mLaunchingAffordance;
+ private String mLastCameraLaunchSource = KeyguardBottomAreaView.CAMERA_LAUNCH_SOURCE_AFFORDANCE;
private Runnable mHeadsUpExistenceChangedRunnable = new Runnable() {
@Override
@@ -256,8 +257,6 @@
mKeyguardBottomArea = (KeyguardBottomAreaView) findViewById(R.id.keyguard_bottom_area);
mQsNavbarScrim = findViewById(R.id.qs_navbar_scrim);
mAfforanceHelper = new KeyguardAffordanceHelper(this, getContext());
- mSecureCameraLaunchManager =
- new SecureCameraLaunchManager(getContext(), mKeyguardBottomArea);
mLastOrientation = getResources().getConfiguration().orientation;
// recompute internal state when qspanel height changes
@@ -362,16 +361,6 @@
updateMaxHeadsUpTranslation();
}
- @Override
- public void onAttachedToWindow() {
- mSecureCameraLaunchManager.create();
- }
-
- @Override
- public void onDetachedFromWindow() {
- mSecureCameraLaunchManager.destroy();
- }
-
private void startQsSizeChangeAnimation(int oldHeight, final int newHeight) {
if (mQsSizeChangeAnimator != null) {
oldHeight = (int) mQsSizeChangeAnimator.getAnimatedValue();
@@ -488,7 +477,10 @@
mIsLaunchTransitionFinished = false;
mBlockTouches = false;
mUnlockIconActive = false;
- mAfforanceHelper.reset(true);
+ if (!mLaunchingAffordance) {
+ mAfforanceHelper.reset(false);
+ mLastCameraLaunchSource = KeyguardBottomAreaView.CAMERA_LAUNCH_SOURCE_AFFORDANCE;
+ }
closeQs();
mStatusBar.dismissPopups();
mNotificationStackScroller.setOverScrollAmount(0f, true /* onTop */, false /* animate */,
@@ -918,7 +910,7 @@
}
private int getFalsingThreshold() {
- float factor = mStatusBar.isScreenOnComingFromTouch() ? 1.5f : 1.0f;
+ float factor = mStatusBar.isWakeUpComingFromTouch() ? 1.5f : 1.0f;
return (int) (mQsFalsingThreshold * factor);
}
@@ -1953,9 +1945,13 @@
EventLogConstants.SYSUI_LOCKSCREEN_GESTURE_SWIPE_DIALER, lengthDp, velocityDp);
mKeyguardBottomArea.launchLeftAffordance();
} else {
- EventLogTags.writeSysuiLockscreenGesture(
- EventLogConstants.SYSUI_LOCKSCREEN_GESTURE_SWIPE_CAMERA, lengthDp, velocityDp);
- mSecureCameraLaunchManager.startSecureCameraLaunch();
+ if (KeyguardBottomAreaView.CAMERA_LAUNCH_SOURCE_AFFORDANCE.equals(
+ mLastCameraLaunchSource)) {
+ EventLogTags.writeSysuiLockscreenGesture(
+ EventLogConstants.SYSUI_LOCKSCREEN_GESTURE_SWIPE_CAMERA,
+ lengthDp, velocityDp);
+ }
+ mKeyguardBottomArea.launchCamera(mLastCameraLaunchSource);
}
mStatusBar.startLaunchTransitionTimeout();
mBlockTouches = true;
@@ -2002,7 +1998,6 @@
boolean camera = getLayoutDirection() == LAYOUT_DIRECTION_RTL ? !rightIcon
: rightIcon;
if (camera) {
- mSecureCameraLaunchManager.onSwipingStarted();
mKeyguardBottomArea.bindCameraPrewarmService();
}
requestDisallowInterceptTouchEvent(true);
@@ -2075,7 +2070,7 @@
@Override
public float getAffordanceFalsingFactor() {
- return mStatusBar.isScreenOnComingFromTouch() ? 1.5f : 1.0f;
+ return mStatusBar.isWakeUpComingFromTouch() ? 1.5f : 1.0f;
}
@Override
@@ -2388,4 +2383,72 @@
protected boolean isPanelVisibleBecauseOfHeadsUp() {
return mHeadsUpManager.hasPinnedHeadsUp() || mHeadsUpAnimatingAway;
}
+
+ @Override
+ public boolean hasOverlappingRendering() {
+ return !mDozing;
+ }
+
+ public void launchCamera(boolean animate, int source) {
+ if (source == StatusBarManager.CAMERA_LAUNCH_SOURCE_POWER_DOUBLE_TAP) {
+ mLastCameraLaunchSource = KeyguardBottomAreaView.CAMERA_LAUNCH_SOURCE_POWER_DOUBLE_TAP;
+ } else if (source == StatusBarManager.CAMERA_LAUNCH_SOURCE_WIGGLE) {
+ mLastCameraLaunchSource = KeyguardBottomAreaView.CAMERA_LAUNCH_SOURCE_WIGGLE;
+ } else {
+
+ // Default.
+ mLastCameraLaunchSource = KeyguardBottomAreaView.CAMERA_LAUNCH_SOURCE_AFFORDANCE;
+ }
+
+ // If we are launching it when we are occluded already we don't want it to animate,
+ // nor setting these flags, since the occluded state doesn't change anymore, hence it's
+ // never reset.
+ if (!isFullyCollapsed()) {
+ mLaunchingAffordance = true;
+ setLaunchingAffordance(true);
+ } else {
+ animate = false;
+ }
+ mAfforanceHelper.launchAffordance(animate, getLayoutDirection() == LAYOUT_DIRECTION_RTL);
+ }
+
+ public void onAffordanceLaunchEnded() {
+ mLaunchingAffordance = false;
+ setLaunchingAffordance(false);
+ }
+
+ /**
+ * Set whether we are currently launching an affordance. This is currently only set when
+ * launched via a camera gesture.
+ */
+ private void setLaunchingAffordance(boolean launchingAffordance) {
+ getLeftIcon().setLaunchingAffordance(launchingAffordance);
+ getRightIcon().setLaunchingAffordance(launchingAffordance);
+ getCenterIcon().setLaunchingAffordance(launchingAffordance);
+ }
+
+ /**
+ * Whether the camera application can be launched for the camera launch gesture.
+ *
+ * @param keyguardIsShowing whether keyguard is being shown
+ */
+ public boolean canCameraGestureBeLaunched(boolean keyguardIsShowing) {
+ ResolveInfo resolveInfo = mKeyguardBottomArea.resolveCameraIntent();
+ String packageToLaunch = (resolveInfo == null || resolveInfo.activityInfo == null)
+ ? null : resolveInfo.activityInfo.packageName;
+ return packageToLaunch != null &&
+ (keyguardIsShowing || !isForegroundApp(packageToLaunch)) &&
+ !mAfforanceHelper.isSwipingInProgress();
+ }
+
+ /**
+ * Return true if the applications with the package name is running in foreground.
+ *
+ * @param pkgName application package name.
+ */
+ private boolean isForegroundApp(String pkgName) {
+ ActivityManager am = getContext().getSystemService(ActivityManager.class);
+ List<ActivityManager.RunningTaskInfo> tasks = am.getRunningTasks(1);
+ return !tasks.isEmpty() && pkgName.equals(tasks.get(0).topActivity.getPackageName());
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
index 8b25e08..e03bcfb 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
@@ -123,7 +123,6 @@
};
protected void onExpandingFinished() {
- endClosing();
mBar.onExpandingFinished();
}
@@ -138,6 +137,7 @@
}
protected final void notifyExpandingFinished() {
+ endClosing();
if (mExpanding) {
mExpanding = false;
onExpandingFinished();
@@ -382,7 +382,7 @@
|| forceCancel;
DozeLog.traceFling(expand, mTouchAboveFalsingThreshold,
mStatusBar.isFalsingThresholdNeeded(),
- mStatusBar.isScreenOnComingFromTouch());
+ mStatusBar.isWakeUpComingFromTouch());
// Log collapse gesture if on lock screen.
if (!expand && mStatusBar.getBarState() == StatusBarState.KEYGUARD) {
float displayDensity = mStatusBar.getDisplayDensity();
@@ -411,7 +411,7 @@
}
private int getFalsingThreshold() {
- float factor = mStatusBar.isScreenOnComingFromTouch() ? 1.5f : 1.0f;
+ float factor = mStatusBar.isWakeUpComingFromTouch() ? 1.5f : 1.0f;
return (int) (mUnlockFalsingThreshold * factor);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
index 5fd1a3a..73361bd 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -66,6 +66,7 @@
import android.os.SystemClock;
import android.os.UserHandle;
import android.os.UserManager;
+import android.os.Vibrator;
import android.provider.Settings;
import android.service.notification.NotificationListenerService;
import android.service.notification.NotificationListenerService.RankingMap;
@@ -99,6 +100,7 @@
import com.android.internal.statusbar.StatusBarIcon;
import com.android.keyguard.KeyguardHostView.OnDismissAction;
import com.android.keyguard.KeyguardUpdateMonitor;
+import com.android.keyguard.KeyguardUpdateMonitorCallback;
import com.android.keyguard.ViewMediatorCallback;
import com.android.systemui.BatteryMeterView;
import com.android.systemui.DemoMode;
@@ -153,6 +155,7 @@
import com.android.systemui.statusbar.policy.ZenModeController;
import com.android.systemui.statusbar.stack.NotificationStackScrollLayout;
import com.android.systemui.statusbar.stack.NotificationStackScrollLayout.OnChildLocationsChangedListener;
+import com.android.systemui.statusbar.stack.StackStateAnimator;
import com.android.systemui.statusbar.stack.StackViewState;
import com.android.systemui.volume.VolumeComponent;
@@ -230,6 +233,7 @@
public static final int FADE_KEYGUARD_START_DELAY = 100;
public static final int FADE_KEYGUARD_DURATION = 300;
+ public static final int FADE_KEYGUARD_DURATION_PULSING = 96;
/** Allow some time inbetween the long press for back and recents. */
private static final int LOCK_TO_APP_GESTURE_TOLERENCE = 200;
@@ -270,6 +274,7 @@
KeyguardMonitor mKeyguardMonitor;
BrightnessMirrorController mBrightnessMirrorController;
AccessibilityController mAccessibilityController;
+ FingerprintUnlockController mFingerprintUnlockController;
int mNaturalBarHeight = -1;
@@ -282,8 +287,9 @@
private StatusBarWindowManager mStatusBarWindowManager;
private UnlockMethodCache mUnlockMethodCache;
private DozeServiceHost mDozeServiceHost;
- private boolean mScreenOnComingFromTouch;
- private PointF mScreenOnTouchLocation;
+ private boolean mWakeUpComingFromTouch;
+ private PointF mWakeUpTouchLocation;
+ private boolean mScreenTurningOn;
int mPixelFormat;
Object mQueueLock = new Object();
@@ -306,6 +312,9 @@
boolean mLeaveOpenOnKeyguardHide;
KeyguardIndicationController mKeyguardIndicationController;
+ // Keyguard is going away soon.
+ private boolean mKeyguardGoingAway;
+ // Keyguard is actually fading away now.
private boolean mKeyguardFadingAway;
private long mKeyguardFadingAwayDelay;
private long mKeyguardFadingAwayDuration;
@@ -478,10 +487,20 @@
private Runnable mLaunchTransitionEndRunnable;
private boolean mLaunchTransitionFadingAway;
private ExpandableNotificationRow mDraggedDownRow;
+ private boolean mLaunchCameraOnScreenTurningOn;
+ private boolean mLaunchCameraOnFinishedGoingToSleep;
+ private int mLastCameraLaunchSource;
+ private PowerManager.WakeLock mGestureWakeLock;
+ private Vibrator mVibrator;
// Fingerprint (as computed by getLoggingFingerprint() of the last logged state.
private int mLastLoggedStateFingerprint;
+ /**
+ * If set, the device has started going to sleep but isn't fully non-interactive yet.
+ */
+ protected boolean mStartedGoingToSleep;
+
private static final int VISIBLE_LOCATIONS = StackViewState.LOCATION_FIRST_CARD
| StackViewState.LOCATION_MAIN_AREA;
@@ -621,6 +640,7 @@
startKeyguard();
mDozeServiceHost = new DozeServiceHost();
+ KeyguardUpdateMonitor.getInstance(mContext).registerCallback(mDozeServiceHost);
putComponent(DozeHost.class, mDozeServiceHost);
putComponent(PhoneStatusBar.class, this);
@@ -780,7 +800,8 @@
mKeyguardBottomArea.setAssistManager(mAssistManager);
mKeyguardIndicationController = new KeyguardIndicationController(mContext,
(KeyguardIndicationTextView) mStatusBarWindow.findViewById(
- R.id.keyguard_indication_text));
+ R.id.keyguard_indication_text),
+ mKeyguardBottomArea.getLockIcon());
mKeyguardBottomArea.setKeyguardIndicationController(mKeyguardIndicationController);
// set the inital view visibility
@@ -897,7 +918,9 @@
PowerManager pm = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
mBroadcastReceiver.onReceive(mContext,
new Intent(pm.isScreenOn() ? Intent.ACTION_SCREEN_ON : Intent.ACTION_SCREEN_OFF));
-
+ mGestureWakeLock = pm.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK,
+ "GestureWakeLock");
+ mVibrator = mContext.getSystemService(Vibrator.class);
// receive broadcasts
IntentFilter filter = new IntentFilter();
@@ -1009,8 +1032,15 @@
private void startKeyguard() {
KeyguardViewMediator keyguardViewMediator = getComponent(KeyguardViewMediator.class);
+ mFingerprintUnlockController = new FingerprintUnlockController(mContext,
+ mStatusBarWindowManager, mDozeScrimController, keyguardViewMediator,
+ mScrimController, this);
mStatusBarKeyguardViewManager = keyguardViewMediator.registerStatusBar(this,
- mStatusBarWindow, mStatusBarWindowManager, mScrimController);
+ mStatusBarWindow, mStatusBarWindowManager, mScrimController,
+ mFingerprintUnlockController);
+ mKeyguardIndicationController.setStatusBarKeyguardViewManager(
+ mStatusBarKeyguardViewManager);
+ mFingerprintUnlockController.setStatusBarKeyguardViewManager(mStatusBarKeyguardViewManager);
mKeyguardViewMediatorCallback = keyguardViewMediator.getViewMediatorCallback();
}
@@ -1681,7 +1711,9 @@
final boolean hasArtwork = artworkBitmap != null;
if ((hasArtwork || DEBUG_MEDIA_FAKE_ARTWORK)
- && (mState == StatusBarState.KEYGUARD || mState == StatusBarState.SHADE_LOCKED)) {
+ && (mState == StatusBarState.KEYGUARD || mState == StatusBarState.SHADE_LOCKED)
+ && mFingerprintUnlockController.getMode()
+ != FingerprintUnlockController.MODE_WAKE_AND_UNLOCK_PULSING) {
// time to show some art!
if (mBackdrop.getVisibility() != View.VISIBLE) {
mBackdrop.setVisibility(View.VISIBLE);
@@ -1736,31 +1768,40 @@
if (DEBUG_MEDIA) {
Log.v(TAG, "DEBUG_MEDIA: Fading out album artwork");
}
- mBackdrop.animate()
- // Never let the alpha become zero - otherwise the RenderNode
- // won't draw anything and uninitialized memory will show through
- // if mScrimSrcModeEnabled. Note that 0.001 is rounded down to 0 in libhwui.
- .alpha(0.002f)
- .setInterpolator(mBackdropInterpolator)
- .setDuration(300)
- .setStartDelay(0)
- .withEndAction(new Runnable() {
- @Override
- public void run() {
- mBackdrop.setVisibility(View.GONE);
- mBackdropFront.animate().cancel();
- mBackdropBack.animate().cancel();
- mHandler.post(mHideBackdropFront);
- }
- });
- if (mKeyguardFadingAway) {
- mBackdrop.animate()
+ if (mFingerprintUnlockController.getMode()
+ == FingerprintUnlockController.MODE_WAKE_AND_UNLOCK_PULSING) {
- // Make it disappear faster, as the focus should be on the activity behind.
- .setDuration(mKeyguardFadingAwayDuration / 2)
- .setStartDelay(mKeyguardFadingAwayDelay)
- .setInterpolator(mLinearInterpolator)
- .start();
+ // We are unlocking directly - no animation!
+ mBackdrop.setVisibility(View.GONE);
+ } else {
+ mBackdrop.animate()
+ // Never let the alpha become zero - otherwise the RenderNode
+ // won't draw anything and uninitialized memory will show through
+ // if mScrimSrcModeEnabled. Note that 0.001 is rounded down to 0 in
+ // libhwui.
+ .alpha(0.002f)
+ .setInterpolator(mBackdropInterpolator)
+ .setDuration(300)
+ .setStartDelay(0)
+ .withEndAction(new Runnable() {
+ @Override
+ public void run() {
+ mBackdrop.setVisibility(View.GONE);
+ mBackdropFront.animate().cancel();
+ mBackdropBack.animate().cancel();
+ mHandler.post(mHideBackdropFront);
+ }
+ });
+ if (mKeyguardFadingAway) {
+ mBackdrop.animate()
+
+ // Make it disappear faster, as the focus should be on the activity
+ // behind.
+ .setDuration(mKeyguardFadingAwayDuration / 2)
+ .setStartDelay(mKeyguardFadingAwayDelay)
+ .setInterpolator(mLinearInterpolator)
+ .start();
+ }
}
}
}
@@ -1910,8 +1951,8 @@
return mNotificationPanel.isQsExpanded();
}
- public boolean isScreenOnComingFromTouch() {
- return mScreenOnComingFromTouch;
+ public boolean isWakeUpComingFromTouch() {
+ return mWakeUpComingFromTouch;
}
public boolean isFalsingThresholdNeeded() {
@@ -2423,8 +2464,12 @@
|| mStatusBarMode == MODE_LIGHTS_OUT_TRANSPARENT);
boolean allowLight = isTransparentBar && !mBatteryController.isPowerSave();
boolean light = (vis & View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR) != 0;
-
- mIconController.setIconsDark(allowLight && light);
+ boolean animate = mFingerprintUnlockController == null
+ || (mFingerprintUnlockController.getMode()
+ != FingerprintUnlockController.MODE_WAKE_AND_UNLOCK_PULSING
+ && mFingerprintUnlockController.getMode()
+ != FingerprintUnlockController.MODE_WAKE_AND_UNLOCK);
+ mIconController.setIconsDark(allowLight && light, animate);
}
// restore the recents bit
if (wasRecentsVisible) {
@@ -2471,7 +2516,7 @@
private void checkBarMode(int mode, int windowState, BarTransitions transitions,
boolean noAnimation) {
final boolean powerSave = mBatteryController.isPowerSave();
- final boolean anim = !noAnimation && (mScreenOn == null || mScreenOn)
+ final boolean anim = !noAnimation && mDeviceInteractive
&& windowState != WINDOW_STATE_HIDDEN && !powerSave;
if (powerSave && getBarState() == StatusBarState.SHADE) {
mode = MODE_WARNING;
@@ -2879,14 +2924,12 @@
}
}
else if (Intent.ACTION_SCREEN_OFF.equals(action)) {
- mScreenOn = false;
notifyNavigationBarScreenOn(false);
notifyHeadsUpScreenOff();
finishBarAnimations();
resetUserExpandedStates();
}
else if (Intent.ACTION_SCREEN_ON.equals(action)) {
- mScreenOn = true;
notifyNavigationBarScreenOn(true);
}
}
@@ -3349,7 +3392,7 @@
mHandler.removeMessages(MSG_LAUNCH_TRANSITION_TIMEOUT);
setBarState(StatusBarState.KEYGUARD);
updateKeyguardState(false /* goingToFullShade */, false /* fromShadeLocked */);
- if (!mScreenOnFromKeyguard) {
+ if (!mDeviceInteractive) {
// If the screen is off already, we need to disable touch events because these might
// collapse the panel after we expanded it, and thus we would end up with a blank
@@ -3368,6 +3411,8 @@
private void onLaunchTransitionFadingEnded() {
mNotificationPanel.setAlpha(1.0f);
+ mNotificationPanel.onAffordanceLaunchEnded();
+ releaseGestureWakeLock();
runLaunchTransitionEndRunnable();
mLaunchTransitionFadingAway = false;
mScrimController.forceHideScrims(false /* hide */);
@@ -3431,6 +3476,19 @@
}
/**
+ * Fades the content of the Keyguard while we are dozing and makes it invisible when finished
+ * fading.
+ */
+ public void fadeKeyguardWhilePulsing() {
+ mNotificationPanel.animate()
+ .alpha(0f)
+ .setStartDelay(0)
+ .setDuration(FADE_KEYGUARD_DURATION_PULSING)
+ .setInterpolator(ScrimController.KEYGUARD_FADE_OUT_INTERPOLATOR)
+ .start();
+ }
+
+ /**
* Starts the timeout when we try to start the affordances on Keyguard. We usually rely that
* Keyguard goes away via fadeKeyguardAfterLaunchTransition, however, that might not happen
* because the launched app crashed or something else went wrong.
@@ -3442,6 +3500,8 @@
private void onLaunchTransitionTimeout() {
Log.w(TAG, "Launch transition: Timeout!");
+ mNotificationPanel.onAffordanceLaunchEnded();
+ releaseGestureWakeLock();
mNotificationPanel.resetViews();
}
@@ -3464,11 +3524,24 @@
setBarState(StatusBarState.SHADE);
if (mLeaveOpenOnKeyguardHide) {
mLeaveOpenOnKeyguardHide = false;
- mNotificationPanel.animateToFullShade(calculateGoingToFullShadeDelay());
+ long delay = calculateGoingToFullShadeDelay();
+ mNotificationPanel.animateToFullShade(delay);
if (mDraggedDownRow != null) {
mDraggedDownRow.setUserLocked(false);
mDraggedDownRow = null;
}
+
+ // Disable layout transitions in navbar for this transition because the load is just
+ // too heavy for the CPU and GPU on any device.
+ if (mNavigationBarView != null) {
+ mNavigationBarView.setLayoutTransitionsEnabled(false);
+ mNavigationBarView.postDelayed(new Runnable() {
+ @Override
+ public void run() {
+ mNavigationBarView.setLayoutTransitionsEnabled(true);
+ }
+ }, delay + StackStateAnimator.ANIMATION_DURATION_GO_TO_FULL_SHADE);
+ }
} else {
instantCollapseNotificationPanel();
}
@@ -3480,9 +3553,19 @@
mQSPanel.refreshAllTiles();
}
mHandler.removeMessages(MSG_LAUNCH_TRANSITION_TIMEOUT);
+ releaseGestureWakeLock();
+ mNotificationPanel.onAffordanceLaunchEnded();
+ mNotificationPanel.animate().cancel();
+ mNotificationPanel.setAlpha(1f);
return staying;
}
+ private void releaseGestureWakeLock() {
+ if (mGestureWakeLock.isHeld()) {
+ mGestureWakeLock.release();
+ }
+ }
+
public long calculateGoingToFullShadeDelay() {
return mKeyguardFadingAwayDelay + mKeyguardFadingAwayDuration;
}
@@ -3494,6 +3577,7 @@
// Treat Keyguard exit animation as an app transition to achieve nice transition for status
// bar.
+ mKeyguardGoingAway = true;
mIconController.appTransitionPending();
}
@@ -3525,6 +3609,7 @@
*/
public void finishKeyguardFadingAway() {
mKeyguardFadingAway = false;
+ mKeyguardGoingAway = false;
}
public void stopWaitingForKeyguardExit() {
@@ -3569,9 +3654,14 @@
private void updateDozingState() {
boolean animate = !mDozing && mDozeScrimController.isPulsing();
mNotificationPanel.setDozing(mDozing, animate);
- mStackScroller.setDark(mDozing, animate, mScreenOnTouchLocation);
+ mStackScroller.setDark(mDozing, animate, mWakeUpTouchLocation);
mScrimController.setDozing(mDozing);
- mDozeScrimController.setDozing(mDozing, animate);
+
+ // Immediately abort the dozing from the doze scrim controller in case of wake-and-unlock
+ // for pulsing so the Keyguard fade-out animation scrim can take over.
+ mDozeScrimController.setDozing(mDozing &&
+ mFingerprintUnlockController.getMode()
+ != FingerprintUnlockController.MODE_WAKE_AND_UNLOCK_PULSING, animate);
}
public void updateStackScrollerState(boolean goingToFullShade) {
@@ -3602,6 +3692,11 @@
return mState == StatusBarState.KEYGUARD && mStatusBarKeyguardViewManager.onMenuPressed();
}
+ public void endAffordanceLaunch() {
+ releaseGestureWakeLock();
+ mNotificationPanel.onAffordanceLaunchEnded();
+ }
+
public boolean onBackPressed() {
if (mStatusBarKeyguardViewManager.onBackPressed()) {
return true;
@@ -3622,7 +3717,7 @@
}
public boolean onSpacePressed() {
- if (mScreenOn != null && mScreenOn
+ if (mDeviceInteractive
&& (mState == StatusBarState.KEYGUARD || mState == StatusBarState.SHADE_LOCKED)) {
animateCollapsePanels(
CommandQueue.FLAG_EXCLUDE_RECENTS_PANEL /* flags */, true /* force */);
@@ -3829,23 +3924,58 @@
disable(mDisabledUnmodified1, mDisabledUnmodified2, true /* animate */);
}
- public void onScreenTurnedOff() {
- mScreenOnFromKeyguard = false;
- mScreenOnComingFromTouch = false;
- mScreenOnTouchLocation = null;
- mStackScroller.setAnimationsEnabled(false);
- updateVisibleToUser();
+ public void onStartedGoingToSleep() {
+ mStartedGoingToSleep = true;
}
- public void onScreenTurnedOn() {
- mScreenOnFromKeyguard = true;
+ public void onFinishedGoingToSleep() {
+ mNotificationPanel.onAffordanceLaunchEnded();
+ releaseGestureWakeLock();
+ mLaunchCameraOnScreenTurningOn = false;
+ mStartedGoingToSleep = false;
+ mDeviceInteractive = false;
+ mWakeUpComingFromTouch = false;
+ mWakeUpTouchLocation = null;
+ mStackScroller.setAnimationsEnabled(false);
+ updateVisibleToUser();
+ if (mLaunchCameraOnFinishedGoingToSleep) {
+ mLaunchCameraOnFinishedGoingToSleep = false;
+
+ // This gets executed before we will show Keyguard, so post it in order that the state
+ // is correct.
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ onCameraLaunchGestureDetected(mLastCameraLaunchSource);
+ }
+ });
+ }
+ }
+
+ public void onStartedWakingUp() {
+ mDeviceInteractive = true;
mStackScroller.setAnimationsEnabled(true);
mNotificationPanel.setTouchDisabled(false);
updateVisibleToUser();
}
public void onScreenTurningOn() {
+ mScreenTurningOn = true;
mNotificationPanel.onScreenTurningOn();
+ if (mLaunchCameraOnScreenTurningOn) {
+ mNotificationPanel.launchCamera(false, mLastCameraLaunchSource);
+ mLaunchCameraOnScreenTurningOn = false;
+ }
+ }
+
+ private void vibrateForCameraGesture() {
+ // Make sure to pass -1 for repeat so VibratorService doesn't stop us when going to sleep.
+ mVibrator.vibrate(new long[] { 0, 750L }, -1 /* repeat */);
+ }
+
+ public void onScreenTurnedOn() {
+ mScreenTurningOn = false;
+ mDozeScrimController.onScreenTurnedOn();
}
/**
@@ -3962,8 +4092,8 @@
if (mDozing && mDozeScrimController.isPulsing()) {
PowerManager pm = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
pm.wakeUp(time, "com.android.systemui:NODOZE");
- mScreenOnComingFromTouch = true;
- mScreenOnTouchLocation = new PointF(event.getX(), event.getY());
+ mWakeUpComingFromTouch = true;
+ mWakeUpTouchLocation = new PointF(event.getX(), event.getY());
mNotificationPanel.setTouchDisabled(false);
mStatusBarKeyguardViewManager.notifyDeviceWakeUpRequested();
}
@@ -3988,8 +4118,8 @@
public void appTransitionStarting(long startTime, long duration) {
// Use own timings when Keyguard is going away, see keyguardGoingAway and
- // setKeyguardFadingAway
- if (!mKeyguardFadingAway) {
+ // setKeyguardFadingAway.
+ if (!mKeyguardGoingAway) {
mIconController.appTransitionStarting(startTime, duration);
}
if (mIconPolicy != null) {
@@ -3997,8 +4127,54 @@
}
}
+ @Override
+ public void onCameraLaunchGestureDetected(int source) {
+ mLastCameraLaunchSource = source;
+ if (mStartedGoingToSleep) {
+ mLaunchCameraOnFinishedGoingToSleep = true;
+ return;
+ }
+ if (!mNotificationPanel.canCameraGestureBeLaunched(
+ mStatusBarKeyguardViewManager.isShowing() && mExpandedVisible)) {
+ return;
+ }
+ if (!mDeviceInteractive) {
+ PowerManager pm = mContext.getSystemService(PowerManager.class);
+ pm.wakeUp(SystemClock.uptimeMillis(), "com.android.systemui:CAMERA_GESTURE");
+ mStatusBarKeyguardViewManager.notifyDeviceWakeUpRequested();
+ }
+ vibrateForCameraGesture();
+ if (!mStatusBarKeyguardViewManager.isShowing()) {
+ startActivity(KeyguardBottomAreaView.INSECURE_CAMERA_INTENT,
+ true /* dismissShade */);
+ } else {
+ if (!mDeviceInteractive) {
+ // Avoid flickering of the scrim when we instant launch the camera and the bouncer
+ // comes on.
+ mScrimController.dontAnimateBouncerChangesUntilNextFrame();
+ mGestureWakeLock.acquire(LAUNCH_TRANSITION_TIMEOUT_MS + 1000L);
+ }
+ if (mScreenTurningOn || mStatusBarKeyguardViewManager.isScreenTurnedOn()) {
+ mNotificationPanel.launchCamera(mDeviceInteractive /* animate */, source);
+ } else {
+ // We need to defer the camera launch until the screen comes on, since otherwise
+ // we will dismiss us too early since we are waiting on an activity to be drawn and
+ // incorrectly get notified because of the screen on event (which resumes and pauses
+ // some activities)
+ mLaunchCameraOnScreenTurningOn = true;
+ }
+ }
+ }
+
+ public void notifyFpAuthModeChanged() {
+ updateDozing();
+ }
+
private void updateDozing() {
- mDozing = mDozingRequested && mState == StatusBarState.KEYGUARD;
+ // When in wake-and-unlock while pulsing, keep dozing state until fully unlocked.
+ mDozing = mDozingRequested && mState == StatusBarState.KEYGUARD
+ || mFingerprintUnlockController.getMode()
+ == FingerprintUnlockController.MODE_WAKE_AND_UNLOCK_PULSING;
updateDozingState();
}
@@ -4028,7 +4204,7 @@
}
}
- private final class DozeServiceHost implements DozeHost {
+ private final class DozeServiceHost extends KeyguardUpdateMonitorCallback implements DozeHost {
// Amount of time to allow to update the time shown on the screen before releasing
// the wakelock. This timeout is design to compensate for the fact that we don't
// currently have a way to know when time display contents have actually been
@@ -4102,6 +4278,12 @@
}
@Override
+ public boolean isPulsingBlocked() {
+ return mFingerprintUnlockController.getMode()
+ == FingerprintUnlockController.MODE_WAKE_AND_UNLOCK;
+ }
+
+ @Override
public boolean isNotificationLightOn() {
return mNotificationLightOn;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java
index fa9c4bb..83edc96 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java
@@ -383,6 +383,12 @@
@Override
public void onUserSwitching(int newUserId, IRemoteCallback reply) {
mUserInfoController.reloadUserInfo();
+ if (reply != null) {
+ try {
+ reply.sendResult(null);
+ } catch (RemoteException e) {
+ }
+ }
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
index 1a35500..b9e9292 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
@@ -22,7 +22,6 @@
import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.Color;
-import android.util.Log;
import android.view.View;
import android.view.ViewTreeObserver;
import android.view.animation.DecelerateInterpolator;
@@ -44,12 +43,15 @@
public class ScrimController implements ViewTreeObserver.OnPreDrawListener,
HeadsUpManager.OnHeadsUpChangedListener {
public static final long ANIMATION_DURATION = 220;
+ public static final Interpolator KEYGUARD_FADE_OUT_INTERPOLATOR
+ = new PathInterpolator(0f, 0, 0.7f, 1f);
private static final float SCRIM_BEHIND_ALPHA = 0.62f;
private static final float SCRIM_BEHIND_ALPHA_KEYGUARD = 0.45f;
private static final float SCRIM_BEHIND_ALPHA_UNLOCKING = 0.2f;
private static final float SCRIM_IN_FRONT_ALPHA = 0.75f;
private static final int TAG_KEY_ANIM = R.id.scrim;
+ private static final int TAG_KEY_ANIM_TARGET = R.id.scrim_target;
private static final int TAG_HUN_START_ALPHA = R.id.hun_scrim_alpha_start;
private static final int TAG_HUN_END_ALPHA = R.id.hun_scrim_alpha_end;
@@ -71,9 +73,7 @@
private long mDurationOverride = -1;
private long mAnimationDelay;
private Runnable mOnAnimationFinished;
- private boolean mAnimationStarted;
private final Interpolator mInterpolator = new DecelerateInterpolator();
- private final Interpolator mKeyguardFadeOutInterpolator = new PathInterpolator(0f, 0, 0.7f, 1f);
private BackDropView mBackDropView;
private boolean mScrimSrcEnabled;
private boolean mDozing;
@@ -86,6 +86,8 @@
private float mTopHeadsUpDragAmount;
private View mDraggedHeadsUpView;
private boolean mForceHideScrims;
+ private boolean mSkipFirstFrame;
+ private boolean mDontAnimateBouncerChanges;
public ScrimController(ScrimView scrimBehind, ScrimView scrimInFront, View headsUpScrim,
boolean scrimSrcEnabled) {
@@ -124,7 +126,7 @@
public void setBouncerShowing(boolean showing) {
mBouncerShowing = showing;
- mAnimateChange = !mExpanding;
+ mAnimateChange = !mExpanding && !mDontAnimateBouncerChanges;
scheduleUpdate();
}
@@ -133,19 +135,25 @@
scheduleUpdate();
}
- public void animateKeyguardFadingOut(long delay, long duration, Runnable onAnimationFinished) {
+ public void animateKeyguardFadingOut(long delay, long duration, Runnable onAnimationFinished,
+ boolean skipFirstFrame) {
mWakeAndUnlocking = false;
mAnimateKeyguardFadingOut = true;
mDurationOverride = duration;
mAnimationDelay = delay;
mAnimateChange = true;
+ mSkipFirstFrame = skipFirstFrame;
mOnAnimationFinished = onAnimationFinished;
scheduleUpdate();
+
+ // No need to wait for the next frame to be drawn for this case - onPreDraw will execute
+ // the changes we just scheduled.
+ onPreDraw();
}
public void abortKeyguardFadingOut() {
if (mAnimateKeyguardFadingOut) {
- endAnimateKeyguardFadingOut();
+ endAnimateKeyguardFadingOut(true /* force */);
}
}
@@ -198,8 +206,13 @@
// During wake and unlock, we first hide everything behind a black scrim, which then
// gets faded out from animateKeyguardFadingOut.
- setScrimInFrontColor(1f);
- setScrimBehindColor(0f);
+ if (mDozing) {
+ setScrimInFrontColor(0f);
+ setScrimBehindColor(1f);
+ } else {
+ setScrimInFrontColor(1f);
+ setScrimBehindColor(0f);
+ }
} else if (!mKeyguardShowing && !mBouncerShowing) {
updateScrimNormal();
setScrimInFrontColor(0);
@@ -258,10 +271,14 @@
}
private void setScrimColor(View scrim, float alpha) {
- Object runningAnim = scrim.getTag(TAG_KEY_ANIM);
- if (runningAnim instanceof ValueAnimator) {
- ((ValueAnimator) runningAnim).cancel();
- scrim.setTag(TAG_KEY_ANIM, null);
+ ValueAnimator runningAnim = (ValueAnimator) scrim.getTag(TAG_KEY_ANIM);
+ Float target = (Float) scrim.getTag(TAG_KEY_ANIM_TARGET);
+ if (runningAnim != null && target != null) {
+ if (alpha != target) {
+ runningAnim.cancel();
+ } else {
+ return;
+ }
}
if (mAnimateChange) {
startScrimAnimation(scrim, alpha);
@@ -325,39 +342,51 @@
mOnAnimationFinished = null;
}
scrim.setTag(TAG_KEY_ANIM, null);
+ scrim.setTag(TAG_KEY_ANIM_TARGET, null);
}
});
anim.start();
+ if (mSkipFirstFrame) {
+ anim.setCurrentPlayTime(16);
+ }
scrim.setTag(TAG_KEY_ANIM, anim);
- mAnimationStarted = true;
+ scrim.setTag(TAG_KEY_ANIM_TARGET, target);
}
private Interpolator getInterpolator() {
- return mAnimateKeyguardFadingOut ? mKeyguardFadeOutInterpolator : mInterpolator;
+ return mAnimateKeyguardFadingOut ? KEYGUARD_FADE_OUT_INTERPOLATOR : mInterpolator;
}
@Override
public boolean onPreDraw() {
mScrimBehind.getViewTreeObserver().removeOnPreDrawListener(this);
mUpdatePending = false;
+ if (mDontAnimateBouncerChanges) {
+ mDontAnimateBouncerChanges = false;
+ }
updateScrims();
mDurationOverride = -1;
mAnimationDelay = 0;
+ mSkipFirstFrame = false;
// Make sure that we always call the listener even if we didn't start an animation.
- endAnimateKeyguardFadingOut();
- mAnimationStarted = false;
+ endAnimateKeyguardFadingOut(false /* force */);
return true;
}
- private void endAnimateKeyguardFadingOut() {
+ private void endAnimateKeyguardFadingOut(boolean force) {
mAnimateKeyguardFadingOut = false;
- if (!mAnimationStarted && mOnAnimationFinished != null) {
+ if ((force || (!isAnimating(mScrimInFront) && !isAnimating(mScrimBehind)))
+ && mOnAnimationFinished != null) {
mOnAnimationFinished.run();
mOnAnimationFinished = null;
}
}
+ private boolean isAnimating(View scrim) {
+ return scrim.getTag(TAG_KEY_ANIM) != null;
+ }
+
public void setBackDropView(BackDropView backDropView) {
mBackDropView = backDropView;
mBackDropView.setOnVisibilityChangedRunnable(new Runnable() {
@@ -471,4 +500,8 @@
mAnimateChange = false;
scheduleUpdate();
}
+
+ public void dontAnimateBouncerChangesUntilNextFrame() {
+ mDontAnimateBouncerChanges = true;
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/SecureCameraLaunchManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/SecureCameraLaunchManager.java
deleted file mode 100644
index 45c8938..0000000
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/SecureCameraLaunchManager.java
+++ /dev/null
@@ -1,284 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.statusbar.phone;
-
-import android.content.Context;
-import android.content.Intent;
-import android.content.pm.PackageManager;
-import android.content.pm.ResolveInfo;
-import android.hardware.camera2.CameraManager;
-import android.os.AsyncTask;
-import android.os.Handler;
-import android.provider.MediaStore;
-import android.util.Log;
-
-import com.android.internal.widget.LockPatternUtils;
-import com.android.keyguard.KeyguardUpdateMonitor;
-
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-/**
- * Handles launching the secure camera properly even when other applications may be using the camera
- * hardware.
- *
- * When other applications (e.g., Face Unlock) are using the camera, they must close the camera to
- * allow the secure camera to open it. Since we want to minimize the delay when opening the secure
- * camera, other apps should close the camera at the first possible opportunity (i.e., as soon as
- * the user begins swiping to go to the secure camera).
- *
- * If the camera is unavailable when the user begins to swipe, the SecureCameraLaunchManager sends a
- * broadcast to tell other apps to close the camera. When and if the user completes their swipe to
- * launch the secure camera, the SecureCameraLaunchManager delays launching the secure camera until
- * a callback indicates that the camera has become available. If it doesn't receive that callback
- * within a specified timeout period, the secure camera is launched anyway.
- *
- * Ideally, the secure camera would handle waiting for the camera to become available. This allows
- * some of the time necessary to close the camera to happen in parallel with starting the secure
- * camera app. We can't rely on all third-party camera apps to handle this. However, an app can
- * put com.android.systemui.statusbar.phone.will_wait_for_camera_available in its meta-data to
- * indicate that it will be responsible for waiting for the camera to become available.
- *
- * It is assumed that the functions in this class, including the constructor, will be called from
- * the UI thread.
- */
-public class SecureCameraLaunchManager {
- private static final boolean DEBUG = false;
- private static final String TAG = "SecureCameraLaunchManager";
-
- // Action sent as a broadcast to tell other apps to stop using the camera. Other apps that use
- // the camera from keyguard (e.g., Face Unlock) should listen for this broadcast and close the
- // camera as soon as possible after receiving it.
- private static final String CLOSE_CAMERA_ACTION_NAME =
- "com.android.systemui.statusbar.phone.CLOSE_CAMERA";
-
- // Apps should put this field in their meta-data to indicate that they will take on the
- // responsibility of waiting for the camera to become available. If this field is present, the
- // SecureCameraLaunchManager launches the secure camera even if the camera hardware has not
- // become available. Having the secure camera app do the waiting is the optimal approach, but
- // without this field, the SecureCameraLaunchManager doesn't launch the secure camera until the
- // camera hardware is available.
- private static final String META_DATA_WILL_WAIT_FOR_CAMERA_AVAILABLE =
- "com.android.systemui.statusbar.phone.will_wait_for_camera_available";
-
- // If the camera hardware hasn't become available after this period of time, the
- // SecureCameraLaunchManager launches the secure camera anyway.
- private static final int CAMERA_AVAILABILITY_TIMEOUT_MS = 1000;
-
- private Context mContext;
- private Handler mHandler;
- private LockPatternUtils mLockPatternUtils;
- private KeyguardBottomAreaView mKeyguardBottomArea;
-
- private CameraManager mCameraManager;
- private CameraAvailabilityCallback mCameraAvailabilityCallback;
- private Map<String, Boolean> mCameraAvailabilityMap;
- private boolean mWaitingToLaunchSecureCamera;
- private Runnable mLaunchCameraRunnable;
-
- private class CameraAvailabilityCallback extends CameraManager.AvailabilityCallback {
- @Override
- public void onCameraUnavailable(String cameraId) {
- if (DEBUG) Log.d(TAG, "onCameraUnavailble(" + cameraId + ")");
- mCameraAvailabilityMap.put(cameraId, false);
- }
-
- @Override
- public void onCameraAvailable(String cameraId) {
- if (DEBUG) Log.d(TAG, "onCameraAvailable(" + cameraId + ")");
- mCameraAvailabilityMap.put(cameraId, true);
-
- // If we were waiting for the camera hardware to become available to launch the
- // secure camera, we can launch it now if all cameras are available. If one or more
- // cameras are still not available, we will get this callback again for those
- // cameras.
- if (mWaitingToLaunchSecureCamera && areAllCamerasAvailable()) {
- mKeyguardBottomArea.launchCamera();
- mWaitingToLaunchSecureCamera = false;
-
- // We no longer need to launch the camera after the timeout hits.
- mHandler.removeCallbacks(mLaunchCameraRunnable);
- }
- }
- }
-
- public SecureCameraLaunchManager(Context context, KeyguardBottomAreaView keyguardBottomArea) {
- mContext = context;
- mHandler = new Handler();
- mLockPatternUtils = new LockPatternUtils(context);
- mKeyguardBottomArea = keyguardBottomArea;
-
- mCameraManager = (CameraManager) context.getSystemService(Context.CAMERA_SERVICE);
- mCameraAvailabilityCallback = new CameraAvailabilityCallback();
-
- // An onCameraAvailable() or onCameraUnavailable() callback will be received for each camera
- // when the availability callback is registered, thus initializing the map.
- //
- // Keeping track of the state of all cameras using the onCameraAvailable() and
- // onCameraUnavailable() callbacks can get messy when dealing with hot-pluggable cameras.
- // However, we have a timeout in place such that we will never hang waiting for cameras.
- mCameraAvailabilityMap = new HashMap<String, Boolean>();
-
- mWaitingToLaunchSecureCamera = false;
- mLaunchCameraRunnable = new Runnable() {
- @Override
- public void run() {
- if (mWaitingToLaunchSecureCamera) {
- Log.w(TAG, "Timeout waiting for camera availability");
- mKeyguardBottomArea.launchCamera();
- mWaitingToLaunchSecureCamera = false;
- }
- }
- };
- }
-
- /**
- * Initializes the SecureCameraManager and starts listening for camera availability.
- */
- public void create() {
- mCameraManager.registerAvailabilityCallback(mCameraAvailabilityCallback, mHandler);
- }
-
- /**
- * Stops listening for camera availability and cleans up the SecureCameraManager.
- */
- public void destroy() {
- mCameraManager.unregisterAvailabilityCallback(mCameraAvailabilityCallback);
- }
-
- /**
- * Called when the user is starting to swipe horizontally, possibly to start the secure camera.
- * Although this swipe ultimately may not result in the secure camera opening, we need to stop
- * all other camera usage (e.g., Face Unlock) as soon as possible. We send out a broadcast to
- * notify other apps that they should close the camera immediately. The broadcast is sent even
- * if the camera appears to be available, because there could be an app that is about to open
- * the camera.
- */
- public void onSwipingStarted() {
- if (DEBUG) Log.d(TAG, "onSwipingStarted");
- AsyncTask.execute(new Runnable() {
- @Override
- public void run() {
- Intent intent = new Intent();
- intent.setAction(CLOSE_CAMERA_ACTION_NAME);
- intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
- mContext.sendBroadcast(intent);
- }
- });
- }
-
- /**
- * Called when the secure camera should be started. If the camera is available or the secure
- * camera app has indicated that it will wait for camera availability, the secure camera app is
- * launched immediately. Otherwise, we wait for the camera to become available (or timeout)
- * before launching the secure camera.
- */
- public void startSecureCameraLaunch() {
- if (DEBUG) Log.d(TAG, "startSecureCameraLunch");
- if (areAllCamerasAvailable() || targetWillWaitForCameraAvailable()) {
- mKeyguardBottomArea.launchCamera();
- } else {
- mWaitingToLaunchSecureCamera = true;
- mHandler.postDelayed(mLaunchCameraRunnable, CAMERA_AVAILABILITY_TIMEOUT_MS);
- }
- }
-
- /**
- * Returns true if all of the cameras we are tracking are currently available.
- */
- private boolean areAllCamerasAvailable() {
- for (boolean cameraAvailable: mCameraAvailabilityMap.values()) {
- if (!cameraAvailable) {
- return false;
- }
- }
- return true;
- }
-
- /**
- * Determines if the secure camera app will wait for the camera hardware to become available
- * before trying to open the camera. If so, we can fire off an intent to start the secure
- * camera app before the camera is available. Otherwise, it is our responsibility to wait for
- * the camera hardware to become available before firing off the intent to start the secure
- * camera.
- *
- * Ideally we are able to fire off the secure camera intent as early as possibly so that, if the
- * camera is closing, it can continue to close while the secure camera app is opening. This
- * improves secure camera startup time.
- */
- private boolean targetWillWaitForCameraAvailable() {
- // Create intent that would launch the secure camera.
- Intent intent = new Intent(MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA_SECURE)
- .addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
- PackageManager packageManager = mContext.getPackageManager();
-
- // Get the list of applications that can handle the intent.
- final List<ResolveInfo> appList = packageManager.queryIntentActivitiesAsUser(
- intent, PackageManager.MATCH_DEFAULT_ONLY, KeyguardUpdateMonitor.getCurrentUser());
- if (appList.size() == 0) {
- if (DEBUG) Log.d(TAG, "No targets found for secure camera intent");
- return false;
- }
-
- // Get the application that the intent resolves to.
- ResolveInfo resolved = packageManager.resolveActivityAsUser(intent,
- PackageManager.MATCH_DEFAULT_ONLY | PackageManager.GET_META_DATA,
- KeyguardUpdateMonitor.getCurrentUser());
-
- if (resolved == null || resolved.activityInfo == null) {
- return false;
- }
-
- // If we would need to launch the resolver activity, then we can't assume that the target
- // is one that would wait for the camera.
- if (wouldLaunchResolverActivity(resolved, appList)) {
- if (DEBUG) Log.d(TAG, "Secure camera intent would launch resolver");
- return false;
- }
-
- // If the target doesn't have meta-data we must assume it won't wait for the camera.
- if (resolved.activityInfo.metaData == null || resolved.activityInfo.metaData.isEmpty()) {
- if (DEBUG) Log.d(TAG, "No meta-data found for secure camera application");
- return false;
- }
-
- // Check the secure camera app meta-data to see if it indicates that it will wait for the
- // camera to become available.
- boolean willWaitForCameraAvailability =
- resolved.activityInfo.metaData.getBoolean(META_DATA_WILL_WAIT_FOR_CAMERA_AVAILABLE);
-
- if (DEBUG) Log.d(TAG, "Target will wait for camera: " + willWaitForCameraAvailability);
-
- return willWaitForCameraAvailability;
- }
-
- /**
- * Determines if the activity that would be launched by the intent is the ResolverActivity.
- */
- private boolean wouldLaunchResolverActivity(ResolveInfo resolved, List<ResolveInfo> appList) {
- // If the list contains the resolved activity, then it can't be the ResolverActivity itself.
- for (int i = 0; i < appList.size(); i++) {
- ResolveInfo tmp = appList.get(i);
- if (tmp.activityInfo.name.equals(resolved.activityInfo.name)
- && tmp.activityInfo.packageName.equals(resolved.activityInfo.packageName)) {
- return false;
- }
- }
- return true;
- }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/SettingsButton.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/SettingsButton.java
index a1e9ece..18db5b8 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/SettingsButton.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/SettingsButton.java
@@ -19,6 +19,7 @@
import android.animation.Animator.AnimatorListener;
import android.animation.ObjectAnimator;
import android.content.Context;
+import android.graphics.drawable.RippleDrawable;
import android.os.Handler;
import android.os.Message;
import android.util.AttributeSet;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarHeaderView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarHeaderView.java
index f8bc43f..971978d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarHeaderView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarHeaderView.java
@@ -26,6 +26,7 @@
import android.graphics.Rect;
import android.graphics.drawable.Animatable;
import android.graphics.drawable.Drawable;
+import android.graphics.drawable.RippleDrawable;
import android.util.AttributeSet;
import android.util.MathUtils;
import android.util.TypedValue;
@@ -184,6 +185,12 @@
}
});
requestCaptureValues();
+
+ // RenderThread is doing more harm than good when touching the header (to expand quick
+ // settings), so disable it for this view
+ ((RippleDrawable) getBackground()).setForceSoftware(true);
+ ((RippleDrawable) mSettingsButton.getBackground()).setForceSoftware(true);
+ ((RippleDrawable) mSystemIconsSuperContainer.getBackground()).setForceSoftware(true);
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconController.java
index 067e50e..5de1c13 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconController.java
@@ -335,8 +335,10 @@
}
}
- public void setIconsDark(boolean dark) {
- if (mTransitionPending) {
+ public void setIconsDark(boolean dark, boolean animate) {
+ if (!animate) {
+ setIconTintInternal(dark ? 1.0f : 0.0f);
+ } else if (mTransitionPending) {
deferIconTintChange(dark ? 1.0f : 0.0f);
} else if (mTransitionDeferring) {
animateIconTint(dark ? 1.0f : 0.0f,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
index 7dd3e7c..05f6e57 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
@@ -24,6 +24,7 @@
import android.view.KeyEvent;
import android.view.View;
import android.view.ViewGroup;
+import android.view.ViewRootImpl;
import android.view.WindowManagerGlobal;
import com.android.internal.widget.LockPatternUtils;
@@ -48,6 +49,8 @@
// with the appear animations of the PIN/pattern/password views.
private static final long NAV_BAR_SHOW_DELAY_BOUNCER = 320;
+ private static final long WAKE_AND_UNLOCK_SCRIM_FADEOUT_DURATION_MS = 200;
+
private static String TAG = "StatusBarKeyguardViewManager";
private final Context mContext;
@@ -56,6 +59,7 @@
private ViewMediatorCallback mViewMediatorCallback;
private PhoneStatusBar mPhoneStatusBar;
private ScrimController mScrimController;
+ private FingerprintUnlockController mFingerprintUnlockController;
private ViewGroup mContainer;
private StatusBarWindowManager mStatusBarWindowManager;
@@ -71,10 +75,8 @@
private boolean mLastOccluded;
private boolean mLastBouncerShowing;
private boolean mLastBouncerDismissible;
- private boolean mLastDeferScrimFadeOut;
private OnDismissAction mAfterKeyguardGoneAction;
private boolean mDeviceWillWakeUp;
- private boolean mWakeAndUnlocking;
private boolean mDeferScrimFadeOut;
public StatusBarKeyguardViewManager(Context context, ViewMediatorCallback callback,
@@ -86,11 +88,13 @@
public void registerStatusBar(PhoneStatusBar phoneStatusBar,
ViewGroup container, StatusBarWindowManager statusBarWindowManager,
- ScrimController scrimController) {
+ ScrimController scrimController,
+ FingerprintUnlockController fingerprintUnlockController) {
mPhoneStatusBar = phoneStatusBar;
mContainer = container;
mStatusBarWindowManager = statusBarWindowManager;
mScrimController = scrimController;
+ mFingerprintUnlockController = fingerprintUnlockController;
mBouncer = new KeyguardBouncer(mContext, mViewMediatorCallback, mLockPatternUtils,
mStatusBarWindowManager, container);
}
@@ -160,30 +164,39 @@
}
}
+ public void onStartedGoingToSleep() {
+ mPhoneStatusBar.onStartedGoingToSleep();
+ }
+
public void onFinishedGoingToSleep() {
mDeviceInteractive = false;
- mPhoneStatusBar.onScreenTurnedOff();
+ mPhoneStatusBar.onFinishedGoingToSleep();
mBouncer.onScreenTurnedOff();
}
public void onStartedWakingUp() {
mDeviceInteractive = true;
mDeviceWillWakeUp = false;
- mPhoneStatusBar.onScreenTurnedOn();
+ mPhoneStatusBar.onStartedWakingUp();
}
public void onScreenTurningOn() {
mPhoneStatusBar.onScreenTurningOn();
}
+ public boolean isScreenTurnedOn() {
+ return mScreenTurnedOn;
+ }
+
public void onScreenTurnedOn() {
mScreenTurnedOn = true;
- mWakeAndUnlocking = false;
if (mDeferScrimFadeOut) {
mDeferScrimFadeOut = false;
- animateScrimControllerKeyguardFadingOut(0, 200);
+ animateScrimControllerKeyguardFadingOut(0, WAKE_AND_UNLOCK_SCRIM_FADEOUT_DURATION_MS,
+ true /* skipFirstFrame */);
updateStates();
}
+ mPhoneStatusBar.onScreenTurnedOn();
}
public void onScreenTurnedOff() {
@@ -260,7 +273,8 @@
updateStates();
mScrimController.animateKeyguardFadingOut(
PhoneStatusBar.FADE_KEYGUARD_START_DELAY,
- PhoneStatusBar.FADE_KEYGUARD_DURATION, null);
+ PhoneStatusBar.FADE_KEYGUARD_DURATION, null,
+ false /* skipFirstFrame */);
}
}, new Runnable() {
@Override
@@ -272,18 +286,43 @@
}
});
} else {
- mPhoneStatusBar.setKeyguardFadingAway(startTime, delay, fadeoutDuration);
- boolean staying = mPhoneStatusBar.hideKeyguard();
- if (!staying) {
+ if (mFingerprintUnlockController.getMode()
+ == FingerprintUnlockController.MODE_WAKE_AND_UNLOCK_PULSING) {
+ mFingerprintUnlockController.startKeyguardFadingAway();
+ mPhoneStatusBar.setKeyguardFadingAway(startTime, 0, 240);
mStatusBarWindowManager.setKeyguardFadingAway(true);
- if (mWakeAndUnlocking && !mScreenTurnedOn) {
- mDeferScrimFadeOut = true;
- } else {
- animateScrimControllerKeyguardFadingOut(delay, fadeoutDuration);
- }
+ mPhoneStatusBar.fadeKeyguardWhilePulsing();
+ animateScrimControllerKeyguardFadingOut(0, 240, new Runnable() {
+ @Override
+ public void run() {
+ mPhoneStatusBar.hideKeyguard();
+ }
+ }, false /* skipFirstFrame */);
} else {
- mScrimController.animateGoingToFullShade(delay, fadeoutDuration);
- mPhoneStatusBar.finishKeyguardFadingAway();
+ mFingerprintUnlockController.startKeyguardFadingAway();
+ mPhoneStatusBar.setKeyguardFadingAway(startTime, delay, fadeoutDuration);
+ boolean staying = mPhoneStatusBar.hideKeyguard();
+ if (!staying) {
+ mStatusBarWindowManager.setKeyguardFadingAway(true);
+ if (mFingerprintUnlockController.getMode()
+ == FingerprintUnlockController.MODE_WAKE_AND_UNLOCK) {
+ if (!mScreenTurnedOn) {
+ mDeferScrimFadeOut = true;
+ } else {
+
+ // Screen is already on, don't defer with fading out.
+ animateScrimControllerKeyguardFadingOut(0,
+ WAKE_AND_UNLOCK_SCRIM_FADEOUT_DURATION_MS,
+ true /* skipFirstFrame */);
+ }
+ } else {
+ animateScrimControllerKeyguardFadingOut(delay, fadeoutDuration,
+ false /* skipFirstFrame */);
+ }
+ } else {
+ mScrimController.animateGoingToFullShade(delay, fadeoutDuration);
+ mPhoneStatusBar.finishKeyguardFadingAway();
+ }
}
mStatusBarWindowManager.setKeyguardShowing(false);
mBouncer.hide(true /* destroyView */);
@@ -291,24 +330,31 @@
executeAfterKeyguardGoneAction();
updateStates();
}
-
}
- private void animateScrimControllerKeyguardFadingOut(long delay, long duration) {
+ private void animateScrimControllerKeyguardFadingOut(long delay, long duration,
+ boolean skipFirstFrame) {
+ animateScrimControllerKeyguardFadingOut(delay, duration, null /* endRunnable */,
+ skipFirstFrame);
+ }
+
+ private void animateScrimControllerKeyguardFadingOut(long delay, long duration,
+ final Runnable endRunnable, boolean skipFirstFrame) {
Trace.asyncTraceBegin(Trace.TRACE_TAG_VIEW, "Fading out", 0);
mScrimController.animateKeyguardFadingOut(delay, duration, new Runnable() {
@Override
public void run() {
+ if (endRunnable != null) {
+ endRunnable.run();
+ }
mStatusBarWindowManager.setKeyguardFadingAway(false);
mPhoneStatusBar.finishKeyguardFadingAway();
- if (mPhoneStatusBar.getNavigationBarView() != null) {
- mPhoneStatusBar.getNavigationBarView().setWakeAndUnlocking(false);
- }
+ mFingerprintUnlockController.finishKeyguardFadingAway();
WindowManagerGlobal.getInstance().trimMemory(
ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
Trace.asyncTraceEnd(Trace.TRACE_TAG_VIEW, "Fading out", 0);
}
- });
+ }, skipFirstFrame);
}
private void executeAfterKeyguardGoneAction() {
@@ -348,6 +394,7 @@
*/
public boolean onBackPressed() {
if (mBouncer.isShowing()) {
+ mPhoneStatusBar.endAffordanceLaunch();
reset();
return true;
}
@@ -382,7 +429,6 @@
boolean occluded = mOccluded;
boolean bouncerShowing = mBouncer.isShowing();
boolean bouncerDismissible = !mBouncer.isFullscreenBouncer();
- boolean deferScrimFadeOut = mDeferScrimFadeOut;
if ((bouncerDismissible || !showing) != (mLastBouncerDismissible || !mLastShowing)
|| mFirstUpdate) {
@@ -393,16 +439,18 @@
}
}
- // Hide navigation bar on Keyguard but not on bouncer and also if we are deferring a scrim
- // fade out, i.e. we are waiting for the screen to have turned on.
- boolean navBarVisible = !deferScrimFadeOut && (!(showing && !occluded) || bouncerShowing);
- boolean lastNavBarVisible = !mLastDeferScrimFadeOut && (!(mLastShowing && !mLastOccluded)
- || mLastBouncerShowing);
+ boolean navBarVisible = (!(showing && !occluded) || bouncerShowing);
+ boolean lastNavBarVisible = (!(mLastShowing && !mLastOccluded) || mLastBouncerShowing);
if (navBarVisible != lastNavBarVisible || mFirstUpdate) {
if (mPhoneStatusBar.getNavigationBarView() != null) {
if (navBarVisible) {
- mContainer.postOnAnimationDelayed(mMakeNavigationBarVisibleRunnable,
- getNavBarShowDelay());
+ long delay = getNavBarShowDelay();
+ if (delay == 0) {
+ mMakeNavigationBarVisibleRunnable.run();
+ } else {
+ mContainer.postOnAnimationDelayed(mMakeNavigationBarVisibleRunnable,
+ delay);
+ }
} else {
mContainer.removeCallbacks(mMakeNavigationBarVisibleRunnable);
mPhoneStatusBar.getNavigationBarView().setVisibility(View.GONE);
@@ -418,7 +466,7 @@
KeyguardUpdateMonitor updateMonitor = KeyguardUpdateMonitor.getInstance(mContext);
if ((showing && !occluded) != (mLastShowing && !mLastOccluded) || mFirstUpdate) {
- updateMonitor.sendKeyguardVisibilityChanged(showing && !occluded);
+ updateMonitor.onKeyguardVisibilityChanged(showing && !occluded);
}
if (bouncerShowing != mLastBouncerShowing || mFirstUpdate) {
updateMonitor.sendKeyguardBouncerChanged(bouncerShowing);
@@ -427,7 +475,6 @@
mFirstUpdate = false;
mLastShowing = showing;
mLastOccluded = occluded;
- mLastDeferScrimFadeOut = deferScrimFadeOut;
mLastBouncerShowing = bouncerShowing;
mLastBouncerDismissible = bouncerDismissible;
@@ -484,15 +531,15 @@
* Notifies that the user has authenticated by other means than using the bouncer, for example,
* fingerprint.
*/
- public void notifyKeyguardAuthenticated() {
- mBouncer.notifyKeyguardAuthenticated();
+ public void notifyKeyguardAuthenticated(boolean strongAuth) {
+ mBouncer.notifyKeyguardAuthenticated(strongAuth);
}
- public void setWakeAndUnlocking() {
- mWakeAndUnlocking = true;
- mScrimController.setWakeAndUnlocking();
- if (mPhoneStatusBar.getNavigationBarView() != null) {
- mPhoneStatusBar.getNavigationBarView().setWakeAndUnlocking(true);
- }
+ public void showBouncerMessage(String message, int color) {
+ mBouncer.showMessage(message, color);
+ }
+
+ public ViewRootImpl getViewRootImpl() {
+ return mPhoneStatusBar.getStatusBarView().getViewRootImpl();
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowManager.java
index 038fefb..ccfa0dd 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowManager.java
@@ -24,6 +24,7 @@
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
+import android.view.Window;
import android.view.WindowManager;
import com.android.keyguard.R;
@@ -47,13 +48,15 @@
private WindowManager.LayoutParams mLpChanged;
private int mBarHeight;
private final boolean mKeyguardScreenRotation;
-
+ private final float mScreenBrightnessDoze;
private final State mCurrentState = new State();
public StatusBarWindowManager(Context context) {
mContext = context;
mWindowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
mKeyguardScreenRotation = shouldEnableKeyguardScreenRotation();
+ mScreenBrightnessDoze = mContext.getResources().getInteger(
+ com.android.internal.R.integer.config_screenBrightnessDoze) / 255f;
}
private boolean shouldEnableKeyguardScreenRotation() {
@@ -182,6 +185,7 @@
applyInputFeatures(state);
applyFitsSystemWindows(state);
applyModalFlag(state);
+ applyBrightness(state);
if (mLp.copyFrom(mLpChanged) != 0) {
mWindowManager.updateViewLayout(mStatusBarView, mLp);
}
@@ -205,6 +209,14 @@
}
}
+ private void applyBrightness(State state) {
+ if (state.forceDozeBrightness) {
+ mLpChanged.screenBrightness = mScreenBrightnessDoze;
+ } else {
+ mLpChanged.screenBrightness = WindowManager.LayoutParams.BRIGHTNESS_OVERRIDE_NONE;
+ }
+ }
+
public void setKeyguardShowing(boolean showing) {
mCurrentState.keyguardShowing = showing;
apply(mCurrentState);
@@ -279,6 +291,15 @@
apply(mCurrentState);
}
+ /**
+ * Set whether the screen brightness is forced to the value we use for doze mode by the status
+ * bar window.
+ */
+ public void setForceDozeBrightness(boolean forceDozeBrightness) {
+ mCurrentState.forceDozeBrightness = forceDozeBrightness;
+ apply(mCurrentState);
+ }
+
public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
pw.println("StatusBarWindowManager state:");
pw.println(mCurrentState);
@@ -297,6 +318,7 @@
boolean headsUpShowing;
boolean forceStatusBarVisible;
boolean forceCollapsed;
+ boolean forceDozeBrightness;
/**
* The {@link BaseStatusBar} state from the status bar.
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/UnlockMethodCache.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/UnlockMethodCache.java
index bd537f7..a91cd51 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/UnlockMethodCache.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/UnlockMethodCache.java
@@ -132,7 +132,7 @@
}
@Override
- public void onFingerprintAuthenticated(int userId, boolean wakeAndUnlocking) {
+ public void onFingerprintAuthenticated(int userId) {
if (!mKeyguardUpdateMonitor.isUnlockingWithFingerprintAllowed()) {
return;
}
@@ -143,6 +143,11 @@
public void onFaceUnlockStateChanged(boolean running, int userId) {
update(false /* updateAlways */);
}
+
+ @Override
+ public void onStrongAuthStateChanged(int userId) {
+ update(false /* updateAlways */);
+ }
};
public boolean isTrustManaged() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.java
index ed9b123..4a95d3a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.java
@@ -169,7 +169,6 @@
*/
public void showNotification(NotificationData.Entry headsUp) {
if (DEBUG) Log.v(TAG, "showNotification");
- MetricsLogger.count(mContext, "note_peek", 1);
addHeadsUpEntry(headsUp);
updateNotification(headsUp, true);
headsUp.setInterruption();
@@ -246,6 +245,9 @@
return;
}
mHasPinnedNotification = hasPinnedNotification;
+ if (mHasPinnedNotification) {
+ MetricsLogger.count(mContext, "note_peek", 1);
+ }
updateTouchableRegionListener();
for (OnHeadsUpChangedListener listener : mListeners) {
listener.onHeadsUpPinnedModeChanged(hasPinnedNotification);
@@ -580,6 +582,13 @@
@Override
public int compareTo(HeadsUpEntry o) {
+ boolean selfFullscreen = hasFullScreenIntent(entry);
+ boolean otherFullscreen = hasFullScreenIntent(o.entry);
+ if (selfFullscreen && !otherFullscreen) {
+ return -1;
+ } else if (!selfFullscreen && otherFullscreen) {
+ return 1;
+ }
return postTime < o.postTime ? 1
: postTime == o.postTime ? entry.key.compareTo(o.entry.key)
: -1;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java
index 4c99792..4d268ce 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java
@@ -18,12 +18,14 @@
import android.app.ActivityManager;
import android.content.Context;
+import android.content.res.Configuration;
import android.content.res.TypedArray;
import android.hardware.input.InputManager;
import android.media.AudioManager;
import android.os.Bundle;
import android.os.SystemClock;
import android.util.AttributeSet;
+import android.util.TypedValue;
import android.view.HapticFeedbackConstants;
import android.view.InputDevice;
import android.view.KeyCharacterMap;
@@ -43,6 +45,7 @@
public class KeyButtonView extends ImageView {
+ private int mContentDescriptionRes;
private long mDownTime;
private int mCode;
private int mTouchSlop;
@@ -79,8 +82,14 @@
mSupportsLongpress = a.getBoolean(R.styleable.KeyButtonView_keyRepeat, true);
+ TypedValue value = new TypedValue();
+ if (a.getValue(R.styleable.KeyButtonView_android_contentDescription, value)) {
+ mContentDescriptionRes = value.resourceId;
+ }
+
a.recycle();
+
setClickable(true);
mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
@@ -88,6 +97,15 @@
}
@Override
+ protected void onConfigurationChanged(Configuration newConfig) {
+ super.onConfigurationChanged(newConfig);
+
+ if (mContentDescriptionRes != 0) {
+ setContentDescription(mContext.getString(mContentDescriptionRes));
+ }
+ }
+
+ @Override
public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
super.onInitializeAccessibilityNodeInfo(info);
if (mCode != 0) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SecurityControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SecurityControllerImpl.java
index 6af9854..1595d0d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SecurityControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SecurityControllerImpl.java
@@ -36,6 +36,7 @@
import android.util.Log;
import android.util.SparseArray;
+import com.android.internal.annotations.GuardedBy;
import com.android.internal.net.LegacyVpnInfo;
import com.android.internal.net.VpnConfig;
import com.android.internal.net.VpnInfo;
@@ -62,8 +63,9 @@
private final IConnectivityManager mConnectivityManagerService;
private final DevicePolicyManager mDevicePolicyManager;
private final UserManager mUserManager;
- private final ArrayList<SecurityControllerCallback> mCallbacks
- = new ArrayList<SecurityControllerCallback>();
+
+ @GuardedBy("mCallbacks")
+ private final ArrayList<SecurityControllerCallback> mCallbacks = new ArrayList<>();
private SparseArray<VpnConfig> mCurrentVpns = new SparseArray<>();
private int mCurrentUserId;
@@ -161,16 +163,20 @@
@Override
public void removeCallback(SecurityControllerCallback callback) {
- if (callback == null) return;
- if (DEBUG) Log.d(TAG, "removeCallback " + callback);
- mCallbacks.remove(callback);
+ synchronized (mCallbacks) {
+ if (callback == null) return;
+ if (DEBUG) Log.d(TAG, "removeCallback " + callback);
+ mCallbacks.remove(callback);
+ }
}
@Override
public void addCallback(SecurityControllerCallback callback) {
- if (callback == null || mCallbacks.contains(callback)) return;
- if (DEBUG) Log.d(TAG, "addCallback " + callback);
- mCallbacks.add(callback);
+ synchronized (mCallbacks) {
+ if (callback == null || mCallbacks.contains(callback)) return;
+ if (DEBUG) Log.d(TAG, "addCallback " + callback);
+ mCallbacks.add(callback);
+ }
}
@Override
@@ -202,8 +208,10 @@
}
private void fireCallbacks() {
- for (SecurityControllerCallback callback : mCallbacks) {
- callback.onStateChanged();
+ synchronized (mCallbacks) {
+ for (SecurityControllerCallback callback : mCallbacks) {
+ callback.onStateChanged();
+ }
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/ZenModeController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/ZenModeController.java
index b2df40a..0e91b0b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/ZenModeController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/ZenModeController.java
@@ -27,7 +27,6 @@
void removeCallback(Callback callback);
void setZen(int zen, Uri conditionId, String reason);
int getZen();
- void requestConditions(boolean request);
ZenRule getManualRule();
ZenModeConfig getConfig();
long getNextAlarm();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/ZenModeControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/ZenModeControllerImpl.java
index c07f1a8..96efea1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/ZenModeControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/ZenModeControllerImpl.java
@@ -121,15 +121,6 @@
}
@Override
- public void requestConditions(boolean request) {
- mRequesting = request;
- mNoMan.requestZenModeConditions(mListener, request ? Condition.FLAG_RELEVANT_NOW : 0);
- if (!mRequesting) {
- mConditions.clear();
- }
- }
-
- @Override
public ZenRule getManualRule() {
return mConfig == null ? null : mConfig.manualRule;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/AnimationFilter.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/AnimationFilter.java
index 753a7f7..56f6564 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/AnimationFilter.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/AnimationFilter.java
@@ -34,6 +34,7 @@
boolean hasDelays;
boolean hasGoToFullShadeEvent;
boolean hasDarkEvent;
+ boolean hasHeadsUpDisappearClickEvent;
int darkAnimationOriginIndex;
public AnimationFilter animateAlpha() {
@@ -106,6 +107,10 @@
hasDarkEvent = true;
darkAnimationOriginIndex = ev.darkAnimationOriginIndex;
}
+ if (ev.animationType == NotificationStackScrollLayout.AnimationEvent
+ .ANIMATION_TYPE_HEADS_UP_DISAPPEAR_CLICK) {
+ hasHeadsUpDisappearClickEvent = true;
+ }
}
}
@@ -135,6 +140,7 @@
hasDelays = false;
hasGoToFullShadeEvent = false;
hasDarkEvent = false;
+ hasHeadsUpDisappearClickEvent = false;
darkAnimationOriginIndex =
NotificationStackScrollLayout.AnimationEvent.DARK_ANIMATION_ORIGIN_INDEX_ABOVE;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
index 23d9b9f..af38f5f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
@@ -653,7 +653,7 @@
@Override
public float getFalsingThresholdFactor() {
- return mPhoneStatusBar.isScreenOnComingFromTouch() ? 1.5f : 1.0f;
+ return mPhoneStatusBar.isWakeUpComingFromTouch() ? 1.5f : 1.0f;
}
public View getChildAtPosition(MotionEvent ev) {
@@ -1778,6 +1778,7 @@
((ExpandableView) child).setOnHeightChangedListener(this);
generateAddAnimation(child, false /* fromMoreCard */);
updateAnimationState(child);
+ updateChronometerForChild(child);
if (canChildBeDismissed(child)) {
// Make sure the dismissButton is visible and not in the animated state.
// We need to do this to avoid a race where a clearable notification is added after the
@@ -1915,7 +1916,9 @@
boolean onBottom = false;
boolean pinnedAndClosed = row.isPinned() && !mIsExpanded;
if (!mIsExpanded && !isHeadsUp) {
- type = AnimationEvent.ANIMATION_TYPE_HEADS_UP_DISAPPEAR;
+ type = row.wasJustClicked()
+ ? AnimationEvent.ANIMATION_TYPE_HEADS_UP_DISAPPEAR_CLICK
+ : AnimationEvent.ANIMATION_TYPE_HEADS_UP_DISAPPEAR;
} else {
StackViewState viewState = mCurrentStackScrollState.getViewStateForView(row);
if (viewState == null) {
@@ -2285,6 +2288,21 @@
mStackScrollAlgorithm.setIsExpanded(isExpanded);
if (changed) {
updateNotificationAnimationStates();
+ updateChronometers();
+ }
+ }
+
+ private void updateChronometers() {
+ int childCount = getChildCount();
+ for (int i = 0; i < childCount; i++) {
+ updateChronometerForChild(getChildAt(i));
+ }
+ }
+
+ private void updateChronometerForChild(View child) {
+ if (child instanceof ExpandableNotificationRow) {
+ ExpandableNotificationRow row = (ExpandableNotificationRow) child;
+ row.setChronometerRunning(mIsExpanded);
}
}
@@ -2307,6 +2325,7 @@
}
mStackScrollAlgorithm.onReset(view);
updateAnimationState(view);
+ updateChronometerForChild(view);
}
private void updateScrollPositionOnExpandInBottom(ExpandableView view) {
@@ -3016,6 +3035,15 @@
.animateY()
.animateZ(),
+ // ANIMATION_TYPE_HEADS_UP_DISAPPEAR_CLICK
+ new AnimationFilter()
+ .animateAlpha()
+ .animateHeight()
+ .animateTopInset()
+ .animateY()
+ .animateZ()
+ .hasDelays(),
+
// ANIMATION_TYPE_HEADS_UP_OTHER
new AnimationFilter()
.animateAlpha()
@@ -3087,6 +3115,9 @@
// ANIMATION_TYPE_HEADS_UP_DISAPPEAR
StackStateAnimator.ANIMATION_DURATION_HEADS_UP_DISAPPEAR,
+ // ANIMATION_TYPE_HEADS_UP_DISAPPEAR_CLICK
+ StackStateAnimator.ANIMATION_DURATION_HEADS_UP_DISAPPEAR,
+
// ANIMATION_TYPE_HEADS_UP_OTHER
StackStateAnimator.ANIMATION_DURATION_STANDARD,
@@ -3110,8 +3141,9 @@
static final int ANIMATION_TYPE_GROUP_EXPANSION_CHANGED = 13;
static final int ANIMATION_TYPE_HEADS_UP_APPEAR = 14;
static final int ANIMATION_TYPE_HEADS_UP_DISAPPEAR = 15;
- static final int ANIMATION_TYPE_HEADS_UP_OTHER = 16;
- static final int ANIMATION_TYPE_EVERYTHING = 17;
+ static final int ANIMATION_TYPE_HEADS_UP_DISAPPEAR_CLICK = 16;
+ static final int ANIMATION_TYPE_HEADS_UP_OTHER = 17;
+ static final int ANIMATION_TYPE_EVERYTHING = 18;
static final int DARK_ANIMATION_ORIGIN_INDEX_ABOVE = -1;
static final int DARK_ANIMATION_ORIGIN_INDEX_BELOW = -2;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java
index 82064a7..cf696a1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java
@@ -127,7 +127,7 @@
mCollapseSecondCardPadding = context.getResources().getDimensionPixelSize(
R.dimen.notification_collapse_second_card_padding);
mScaleDimmed = context.getResources().getDisplayMetrics().densityDpi
- >= DisplayMetrics.DENSITY_XXHIGH;
+ >= DisplayMetrics.DENSITY_420;
}
public boolean shouldScaleDimmed() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackStateAnimator.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackStateAnimator.java
index 97c7d30..b4ab48a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackStateAnimator.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackStateAnimator.java
@@ -54,6 +54,7 @@
public static final int ANIMATION_DELAY_PER_ELEMENT_DARK = 24;
public static final int DELAY_EFFECT_MAX_INDEX_DIFFERENCE = 2;
public static final int DELAY_EFFECT_MAX_INDEX_DIFFERENCE_CHILDREN = 3;
+ public static final int ANIMATION_DELAY_HEADS_UP = 120;
private static final int TAG_ANIMATOR_TRANSLATION_Y = R.id.translation_y_animator_tag;
private static final int TAG_ANIMATOR_TRANSLATION_Z = R.id.translation_z_animator_tag;
@@ -320,6 +321,9 @@
if (mAnimationFilter.hasGoToFullShadeEvent) {
return calculateDelayGoToFullShade(viewState);
}
+ if (mAnimationFilter.hasHeadsUpDisappearClickEvent) {
+ return ANIMATION_DELAY_HEADS_UP;
+ }
long minDelay = 0;
for (NotificationStackScrollLayout.AnimationEvent event : mNewEvents) {
long delayPerElement = ANIMATION_DELAY_PER_ELEMENT_INTERRUPTING;
@@ -890,7 +894,9 @@
mHeadsUpAppearChildren.add(changingView);
finalState.applyState(changingView, mTmpState);
} else if (event.animationType == NotificationStackScrollLayout
- .AnimationEvent.ANIMATION_TYPE_HEADS_UP_DISAPPEAR) {
+ .AnimationEvent.ANIMATION_TYPE_HEADS_UP_DISAPPEAR ||
+ event.animationType == NotificationStackScrollLayout
+ .AnimationEvent.ANIMATION_TYPE_HEADS_UP_DISAPPEAR_CLICK) {
mHeadsUpDisappearChildren.add(changingView);
if (mHostLayout.indexOfChild(changingView) == -1) {
// This notification was actually removed, so we need to add it to the overlay
@@ -900,7 +906,11 @@
// We temporarily enable Y animations, the real filter will be combined
// afterwards anyway
mAnimationFilter.animateY = true;
- startViewAnimations(changingView, mTmpState, 0,
+ startViewAnimations(changingView, mTmpState,
+ event.animationType == NotificationStackScrollLayout
+ .AnimationEvent.ANIMATION_TYPE_HEADS_UP_DISAPPEAR_CLICK
+ ? ANIMATION_DELAY_HEADS_UP
+ : 0,
ANIMATION_DURATION_HEADS_UP_DISAPPEAR);
mChildrenToClearFromOverlay.add(changingView);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tv/TvStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/tv/TvStatusBar.java
index 920b682..bbe5dd9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tv/TvStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tv/TvStatusBar.java
@@ -171,6 +171,10 @@
}
@Override
+ public void onCameraLaunchGestureDetected(int source) {
+ }
+
+ @Override
protected void updateHeadsUp(String key, NotificationData.Entry entry, boolean shouldInterrupt,
boolean alertAgain) {
}
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialog.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialog.java
index 7836411..e9f1095 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialog.java
@@ -104,6 +104,7 @@
private final SpTexts mSpTexts;
private final SparseBooleanArray mDynamic = new SparseBooleanArray();
private final KeyguardManager mKeyguard;
+ private final AudioManager mAudioManager;
private final int mExpandButtonAnimationDuration;
private final ZenFooter mZenFooter;
private final LayoutTransition mLayoutTransition;
@@ -135,6 +136,7 @@
mCallback = callback;
mSpTexts = new SpTexts(mContext);
mKeyguard = (KeyguardManager) context.getSystemService(Context.KEYGUARD_SERVICE);
+ mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
mDialog = new CustomDialog(mContext);
@@ -636,7 +638,8 @@
private void updateFooterH() {
if (D.BUG) Log.d(TAG, "updateFooterH");
final boolean wasVisible = mZenFooter.getVisibility() == View.VISIBLE;
- final boolean visible = mState.zenMode != Global.ZEN_MODE_OFF;
+ final boolean visible = mState.zenMode != Global.ZEN_MODE_OFF
+ && mAudioManager.isStreamAffectedByRingerMode(mActiveStream);
if (wasVisible != visible && !visible) {
prepareForCollapse();
}
diff --git a/packages/SystemUI/src/com/android/systemui/volume/ZenModePanel.java b/packages/SystemUI/src/com/android/systemui/volume/ZenModePanel.java
index 3c9a7fc..07ec843 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/ZenModePanel.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/ZenModePanel.java
@@ -1,4 +1,4 @@
-/*
+/**
* Copyright (C) 2014 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -58,6 +58,8 @@
import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.util.Arrays;
+import java.util.Calendar;
+import java.util.GregorianCalendar;
import java.util.Locale;
import java.util.Objects;
@@ -76,6 +78,8 @@
private static final int DEFAULT_BUCKET_INDEX = Arrays.binarySearch(MINUTE_BUCKETS, 60);
private static final int FOREVER_CONDITION_INDEX = 0;
private static final int COUNTDOWN_CONDITION_INDEX = 1;
+ private static final int COUNTDOWN_ALARM_CONDITION_INDEX = 2;
+ private static final int COUNTDOWN_CONDITION_COUNT = 2;
public static final Intent ZEN_SETTINGS
= new Intent(Settings.ACTION_ZEN_MODE_SETTINGS);
@@ -86,7 +90,6 @@
private final LayoutInflater mInflater;
private final H mHandler = new H();
private final ZenPrefs mPrefs;
- private final IconPulser mIconPulser;
private final TransitionHelper mTransitionHelper = new TransitionHelper();
private final Uri mForeverId;
private final SpTexts mSpTexts;
@@ -104,9 +107,6 @@
private Callback mCallback;
private ZenModeController mController;
private boolean mCountdownConditionSupported;
- private int mMaxConditions;
- private int mMaxOptionalConditions;
- private int mFirstConditionIndex;
private boolean mRequestingConditions;
private Condition mExitCondition;
private int mBucketIndex = -1;
@@ -125,7 +125,6 @@
mContext = context;
mPrefs = new ZenPrefs();
mInflater = LayoutInflater.from(mContext.getApplicationContext());
- mIconPulser = new IconPulser(mContext);
mForeverId = Condition.newId(mContext).appendPath("forever").build();
mSpTexts = new SpTexts(mContext);
mVoiceCapable = Util.isVoiceCapable(mContext);
@@ -135,7 +134,6 @@
public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
pw.println("ZenModePanel state:");
pw.print(" mCountdownConditionSupported="); pw.println(mCountdownConditionSupported);
- pw.print(" mMaxConditions="); pw.println(mMaxConditions);
pw.print(" mRequestingConditions="); pw.println(mRequestingConditions);
pw.print(" mAttached="); pw.println(mAttached);
pw.print(" mHidden="); pw.println(mHidden);
@@ -286,14 +284,6 @@
if (mRequestingConditions == requesting) return;
if (DEBUG) Log.d(mTag, "setRequestingConditions " + requesting);
mRequestingConditions = requesting;
- if (mController != null) {
- AsyncTask.execute(new Runnable() {
- @Override
- public void run() {
- mController.requestConditions(requesting);
- }
- });
- }
if (mRequestingConditions) {
mTimeCondition = parseExistingTimeCondition(mContext, mExitCondition);
if (mTimeCondition != null) {
@@ -304,6 +294,7 @@
MINUTE_BUCKETS[mBucketIndex], ActivityManager.getCurrentUser());
}
if (DEBUG) Log.d(mTag, "Initial bucket index: " + mBucketIndex);
+
mConditions = null; // reset conditions
handleUpdateConditions();
} else {
@@ -314,13 +305,9 @@
public void init(ZenModeController controller) {
mController = controller;
mCountdownConditionSupported = mController.isCountdownConditionSupported();
- final int countdownDelta = mCountdownConditionSupported ? 1 : 0;
- mFirstConditionIndex = COUNTDOWN_CONDITION_INDEX + countdownDelta;
+ final int countdownDelta = mCountdownConditionSupported ? COUNTDOWN_CONDITION_COUNT : 0;
final int minConditions = 1 /*forever*/ + countdownDelta;
- mMaxConditions = MathUtils.constrain(mContext.getResources()
- .getInteger(R.integer.zen_mode_max_conditions), minConditions, 100);
- mMaxOptionalConditions = mMaxConditions - minConditions;
- for (int i = 0; i < mMaxConditions; i++) {
+ for (int i = 0; i < minConditions; i++) {
mZenConditions.addView(mInflater.inflate(R.layout.zen_mode_condition, this, false));
}
mSessionZen = getSelectedZen(-1);
@@ -357,28 +344,10 @@
return condition == null ? null : condition.copy();
}
- public static String getExitConditionText(Context context, Condition exitCondition) {
- if (exitCondition == null) {
- return foreverSummary(context);
- } else if (isCountdown(exitCondition)) {
- final Condition condition = parseExistingTimeCondition(context, exitCondition);
- return condition != null ? condition.summary : foreverSummary(context);
- } else {
- return exitCondition.summary;
- }
- }
-
public void setCallback(Callback callback) {
mCallback = callback;
}
- public void showSilentHint() {
- if (DEBUG) Log.d(mTag, "showSilentHint");
- if (mZenButtons == null || mZenButtons.getChildCount() == 0) return;
- final View noneButton = mZenButtons.getChildAt(0);
- mIconPulser.start(noneButton);
- }
-
private void handleUpdateManualRule(ZenRule rule) {
final int zen = rule != null ? rule.zenMode : Global.ZEN_MODE_OFF;
handleUpdateZen(zen);
@@ -410,7 +379,7 @@
final ConditionTag tag = getConditionTagAt(i);
if (tag != null) {
if (sameConditionId(tag.condition, mExitCondition)) {
- bind(exitCondition, mZenConditions.getChildAt(i));
+ bind(exitCondition, mZenConditions.getChildAt(i), i);
}
}
}
@@ -495,64 +464,32 @@
final long span = time - now;
if (span <= 0 || span > MAX_BUCKET_MINUTES * MINUTES_MS) return null;
return ZenModeConfig.toTimeCondition(context,
- time, Math.round(span / (float) MINUTES_MS), now, ActivityManager.getCurrentUser(),
+ time, Math.round(span / (float) MINUTES_MS), ActivityManager.getCurrentUser(),
false /*shortVersion*/);
}
- private void handleUpdateConditions(Condition[] conditions) {
- conditions = trimConditions(conditions);
- if (Arrays.equals(conditions, mConditions)) {
- final int count = mConditions == null ? 0 : mConditions.length;
- if (DEBUG) Log.d(mTag, "handleUpdateConditions unchanged conditionCount=" + count);
- return;
- }
- mConditions = conditions;
- handleUpdateConditions();
- }
-
- private Condition[] trimConditions(Condition[] conditions) {
- if (conditions == null || conditions.length <= mMaxOptionalConditions) {
- // no need to trim
- return conditions;
- }
- // look for current exit condition, ensure it is included if found
- int found = -1;
- for (int i = 0; i < conditions.length; i++) {
- final Condition c = conditions[i];
- if (mSessionExitCondition != null && sameConditionId(mSessionExitCondition, c)) {
- found = i;
- break;
- }
- }
- final Condition[] rt = Arrays.copyOf(conditions, mMaxOptionalConditions);
- if (found >= mMaxOptionalConditions) {
- // found after the first N, promote to the end of the first N
- rt[mMaxOptionalConditions - 1] = conditions[found];
- }
- return rt;
- }
-
private void handleUpdateConditions() {
if (mTransitionHelper.isTransitioning()) {
- mTransitionHelper.pendingUpdateConditions();
return;
}
final int conditionCount = mConditions == null ? 0 : mConditions.length;
if (DEBUG) Log.d(mTag, "handleUpdateConditions conditionCount=" + conditionCount);
// forever
- bind(forever(), mZenConditions.getChildAt(FOREVER_CONDITION_INDEX));
+ bind(forever(), mZenConditions.getChildAt(FOREVER_CONDITION_INDEX),
+ FOREVER_CONDITION_INDEX);
// countdown
if (mCountdownConditionSupported && mTimeCondition != null) {
- bind(mTimeCondition, mZenConditions.getChildAt(COUNTDOWN_CONDITION_INDEX));
+ bind(mTimeCondition, mZenConditions.getChildAt(COUNTDOWN_CONDITION_INDEX),
+ COUNTDOWN_CONDITION_INDEX);
}
- // provider conditions
- for (int i = 0; i < conditionCount; i++) {
- bind(mConditions[i], mZenConditions.getChildAt(mFirstConditionIndex + i));
- }
- // hide the rest
- for (int i = mZenConditions.getChildCount() - 1; i > mFirstConditionIndex + conditionCount;
- i--) {
- mZenConditions.getChildAt(i).setVisibility(GONE);
+ // countdown until alarm
+ if (mCountdownConditionSupported) {
+ Condition nextAlarmCondition = getTimeUntilNextAlarmCondition();
+ if (nextAlarmCondition != null) {
+ bind(nextAlarmCondition,
+ mZenConditions.getChildAt(COUNTDOWN_ALARM_CONDITION_INDEX),
+ COUNTDOWN_ALARM_CONDITION_INDEX);
+ }
}
// ensure something is selected
if (mExpanded && isShown()) {
@@ -569,6 +506,33 @@
return context.getString(com.android.internal.R.string.zen_mode_forever);
}
+ // Returns a time condition if the next alarm is within the next week.
+ private Condition getTimeUntilNextAlarmCondition() {
+ GregorianCalendar weekRange = new GregorianCalendar();
+ final long now = weekRange.getTimeInMillis();
+ setToMidnight(weekRange);
+ weekRange.add(Calendar.DATE, 6);
+ final long nextAlarmMs = mController.getNextAlarm();
+ if (nextAlarmMs > 0) {
+ GregorianCalendar nextAlarm = new GregorianCalendar();
+ nextAlarm.setTimeInMillis(nextAlarmMs);
+ setToMidnight(nextAlarm);
+
+ if (weekRange.compareTo(nextAlarm) >= 0) {
+ return ZenModeConfig.toNextAlarmCondition(mContext, now, nextAlarmMs,
+ ActivityManager.getCurrentUser());
+ }
+ }
+ return null;
+ }
+
+ private void setToMidnight(Calendar calendar) {
+ calendar.set(Calendar.HOUR_OF_DAY, 0);
+ calendar.set(Calendar.MINUTE, 0);
+ calendar.set(Calendar.SECOND, 0);
+ calendar.set(Calendar.MILLISECOND, 0);
+ }
+
private ConditionTag getConditionTagAt(int index) {
return (ConditionTag) mZenConditions.getChildAt(index).getTag();
}
@@ -610,7 +574,8 @@
mTimeCondition = ZenModeConfig.toTimeCondition(mContext,
MINUTE_BUCKETS[favoriteIndex], ActivityManager.getCurrentUser());
mBucketIndex = favoriteIndex;
- bind(mTimeCondition, mZenConditions.getChildAt(COUNTDOWN_CONDITION_INDEX));
+ bind(mTimeCondition, mZenConditions.getChildAt(COUNTDOWN_CONDITION_INDEX),
+ COUNTDOWN_CONDITION_INDEX);
getConditionTagAt(COUNTDOWN_CONDITION_INDEX).rb.setChecked(true);
}
}
@@ -623,7 +588,7 @@
return c != null && mForeverId.equals(c.id);
}
- private void bind(final Condition condition, final View row) {
+ private void bind(final Condition condition, final View row, final int rowId) {
if (condition == null) throw new IllegalArgumentException("condition must not be null");
final boolean enabled = condition.state == Condition.STATE_TRUE;
final ConditionTag tag =
@@ -640,8 +605,7 @@
tag.rb.setEnabled(enabled);
final boolean checked = (mSessionExitCondition != null
|| mAttachedZen != Global.ZEN_MODE_OFF)
- && (sameConditionId(mSessionExitCondition, tag.condition)
- || isCountdown(mSessionExitCondition) && isCountdown(tag.condition));
+ && (sameConditionId(mSessionExitCondition, tag.condition));
if (checked != tag.rb.isChecked()) {
if (DEBUG) Log.d(mTag, "bind checked=" + checked + " condition=" + conditionId);
tag.rb.setChecked(checked);
@@ -692,7 +656,7 @@
button1.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
- onClickTimeButton(row, tag, false /*down*/);
+ onClickTimeButton(row, tag, false /*down*/, rowId);
}
});
@@ -700,7 +664,7 @@
button2.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
- onClickTimeButton(row, tag, true /*up*/);
+ onClickTimeButton(row, tag, true /*up*/, rowId);
}
});
tag.lines.setOnClickListener(new OnClickListener() {
@@ -711,7 +675,7 @@
});
final long time = ZenModeConfig.tryParseCountdownConditionId(conditionId);
- if (time > 0) {
+ if (rowId != COUNTDOWN_ALARM_CONDITION_INDEX && time > 0) {
button1.setVisibility(VISIBLE);
button2.setVisibility(VISIBLE);
if (mBucketIndex > -1) {
@@ -761,7 +725,7 @@
tag.line1.getText()));
}
- private void onClickTimeButton(View row, ConditionTag tag, boolean up) {
+ private void onClickTimeButton(View row, ConditionTag tag, boolean up, int rowId) {
MetricsLogger.action(mContext, MetricsLogger.QS_DND_TIME, up);
Condition newCondition = null;
final int N = MINUTE_BUCKETS.length;
@@ -777,7 +741,7 @@
if (up && bucketTime > time || !up && bucketTime < time) {
mBucketIndex = j;
newCondition = ZenModeConfig.toTimeCondition(mContext,
- bucketTime, bucketMinutes, now, ActivityManager.getCurrentUser(),
+ bucketTime, bucketMinutes, ActivityManager.getCurrentUser(),
false /*shortVersion*/);
break;
}
@@ -794,7 +758,7 @@
MINUTE_BUCKETS[mBucketIndex], ActivityManager.getCurrentUser());
}
mTimeCondition = newCondition;
- bind(mTimeCondition, row);
+ bind(mTimeCondition, row, rowId);
tag.rb.setChecked(true);
select(mTimeCondition);
announceConditionSelection(tag);
@@ -838,18 +802,12 @@
private final ZenModeController.Callback mZenCallback = new ZenModeController.Callback() {
@Override
- public void onConditionsChanged(Condition[] conditions) {
- mHandler.obtainMessage(H.UPDATE_CONDITIONS, conditions).sendToTarget();
- }
-
- @Override
public void onManualRuleChanged(ZenRule rule) {
mHandler.obtainMessage(H.MANUAL_RULE_CHANGED, rule).sendToTarget();
}
};
private final class H extends Handler {
- private static final int UPDATE_CONDITIONS = 1;
private static final int MANUAL_RULE_CHANGED = 2;
private static final int UPDATE_WIDGETS = 3;
@@ -860,7 +818,6 @@
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
- case UPDATE_CONDITIONS: handleUpdateConditions((Condition[]) msg.obj); break;
case MANUAL_RULE_CHANGED: handleUpdateManualRule((ZenRule) msg.obj); break;
case UPDATE_WIDGETS: updateWidgets(); break;
}
@@ -1005,26 +962,20 @@
private final ArraySet<View> mTransitioningViews = new ArraySet<View>();
private boolean mTransitioning;
- private boolean mPendingUpdateConditions;
private boolean mPendingUpdateWidgets;
public void clear() {
mTransitioningViews.clear();
- mPendingUpdateConditions = mPendingUpdateWidgets = false;
+ mPendingUpdateWidgets = false;
}
public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
pw.println(" TransitionHelper state:");
- pw.print(" mPendingUpdateConditions="); pw.println(mPendingUpdateConditions);
pw.print(" mPendingUpdateWidgets="); pw.println(mPendingUpdateWidgets);
pw.print(" mTransitioning="); pw.println(mTransitioning);
pw.print(" mTransitioningViews="); pw.println(mTransitioningViews);
}
- public void pendingUpdateConditions() {
- mPendingUpdateConditions = true;
- }
-
public void pendingUpdateWidgets() {
mPendingUpdateWidgets = true;
}
@@ -1050,15 +1001,11 @@
@Override
public void run() {
if (DEBUG) Log.d(mTag, "TransitionHelper run"
- + " mPendingUpdateWidgets=" + mPendingUpdateWidgets
- + " mPendingUpdateConditions=" + mPendingUpdateConditions);
+ + " mPendingUpdateWidgets=" + mPendingUpdateWidgets);
if (mPendingUpdateWidgets) {
updateWidgets();
}
- if (mPendingUpdateConditions) {
- handleUpdateConditions();
- }
- mPendingUpdateWidgets = mPendingUpdateConditions = false;
+ mPendingUpdateWidgets = false;
}
private void updateTransitioning() {
@@ -1067,10 +1014,10 @@
mTransitioning = transitioning;
if (DEBUG) Log.d(mTag, "TransitionHelper mTransitioning=" + mTransitioning);
if (!mTransitioning) {
- if (mPendingUpdateConditions || mPendingUpdateWidgets) {
+ if (mPendingUpdateWidgets) {
mHandler.post(this);
} else {
- mPendingUpdateConditions = mPendingUpdateWidgets = false;
+ mPendingUpdateWidgets = false;
}
}
}
diff --git a/packages/VpnDialogs/res/values-nl/strings.xml b/packages/VpnDialogs/res/values-nl/strings.xml
index 0f28016..ae789b2 100644
--- a/packages/VpnDialogs/res/values-nl/strings.xml
+++ b/packages/VpnDialogs/res/values-nl/strings.xml
@@ -17,7 +17,7 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="prompt" msgid="3183836924226407828">"Verbindingsverzoek"</string>
- <string name="warning" msgid="809658604548412033">"<xliff:g id="APP">%s</xliff:g> wil een VPN-verbinding opzetten om netwerkverkeer te controleren. Accepteer het verzoek alleen als u de bron vertrouwt. <br /> <br /> <img src=vpn_icon /> wordt boven aan uw scherm weergegeven wanneer VPN actief is."</string>
+ <string name="warning" msgid="809658604548412033">"<xliff:g id="APP">%s</xliff:g> wil een VPN-verbinding opzetten om netwerkverkeer te controleren. Accepteer het verzoek alleen als je de bron vertrouwt. <br /> <br /> <img src=vpn_icon /> wordt boven aan je scherm weergegeven wanneer VPN actief is."</string>
<string name="legacy_title" msgid="192936250066580964">"Verbinding met VPN"</string>
<string name="configure" msgid="4905518375574791375">"Configureren"</string>
<string name="disconnect" msgid="971412338304200056">"Verbinding verbreken"</string>
diff --git a/packages/VpnDialogs/res/values-pt-rBR/strings.xml b/packages/VpnDialogs/res/values-pt-rBR/strings.xml
new file mode 100644
index 0000000..e4154bc
--- /dev/null
+++ b/packages/VpnDialogs/res/values-pt-rBR/strings.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2011 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="prompt" msgid="3183836924226407828">"Solicitação de conexão"</string>
+ <string name="warning" msgid="809658604548412033">"<xliff:g id="APP">%s</xliff:g> quer configurar uma conexão VPN que permite monitorar o tráfego da rede. Aceite se confiar na origem. <br /> <br /> <img src=vpn_icon /> é exibido na parte superior da tela quando a VPN estiver ativa."</string>
+ <string name="legacy_title" msgid="192936250066580964">"O VPN está conectado"</string>
+ <string name="configure" msgid="4905518375574791375">"Configurar"</string>
+ <string name="disconnect" msgid="971412338304200056">"Desconectar"</string>
+ <string name="session" msgid="6470628549473641030">"Sessão:"</string>
+ <string name="duration" msgid="3584782459928719435">"Duração:"</string>
+ <string name="data_transmitted" msgid="7988167672982199061">"Enviado:"</string>
+ <string name="data_received" msgid="4062776929376067820">"Recebido:"</string>
+ <string name="data_value_format" msgid="2192466557826897580">"<xliff:g id="NUMBER_0">%1$s</xliff:g> bytes/<xliff:g id="NUMBER_1">%2$s</xliff:g> pacotes"</string>
+</resources>
diff --git a/rs/java/android/renderscript/RenderScript.java b/rs/java/android/renderscript/RenderScript.java
index 8b1a032..4440417 100644
--- a/rs/java/android/renderscript/RenderScript.java
+++ b/rs/java/android/renderscript/RenderScript.java
@@ -1557,9 +1557,21 @@
nContextDeinitToClient(mContext);
mMessageThread.mRun = false;
- try {
- mMessageThread.join();
- } catch(InterruptedException e) {
+
+ // Wait for mMessageThread to join. Try in a loop, in case this thread gets interrupted
+ // during the wait. If interrupted, set the "interrupted" status of the current thread.
+ boolean hasJoined = false, interrupted = false;
+ while (!hasJoined) {
+ try {
+ mMessageThread.join();
+ hasJoined = true;
+ } catch (InterruptedException e) {
+ interrupted = true;
+ }
+ }
+ if (interrupted) {
+ Log.v(LOG_TAG, "Interrupted during wait for MessageThread to join");
+ Thread.currentThread().interrupt();
}
nContextDestroy();
diff --git a/rs/jni/android_renderscript_RenderScript.cpp b/rs/jni/android_renderscript_RenderScript.cpp
index ffc4fd8..2bc48e4 100644
--- a/rs/jni/android_renderscript_RenderScript.cpp
+++ b/rs/jni/android_renderscript_RenderScript.cpp
@@ -611,7 +611,7 @@
in_allocs[2] = (RsAllocation)C;
rsScriptForEachMulti((RsContext)con, (RsScript)id, 0,
- in_allocs, sizeof(in_allocs), nullptr,
+ in_allocs, NELEM(in_allocs), nullptr,
&call, sizeof(call), nullptr, 0);
}
@@ -646,7 +646,7 @@
in_allocs[2] = (RsAllocation)C;
rsScriptForEachMulti((RsContext)con, (RsScript)id, 0,
- in_allocs, sizeof(in_allocs), nullptr,
+ in_allocs, NELEM(in_allocs), nullptr,
&call, sizeof(call), nullptr, 0);
}
@@ -681,7 +681,7 @@
in_allocs[2] = (RsAllocation)C;
rsScriptForEachMulti((RsContext)con, (RsScript)id, 0,
- in_allocs, sizeof(in_allocs), nullptr,
+ in_allocs, NELEM(in_allocs), nullptr,
&call, sizeof(call), nullptr, 0);
}
@@ -707,7 +707,7 @@
in_allocs[2] = (RsAllocation)C;
rsScriptForEachMulti((RsContext)con, (RsScript)id, 0,
- in_allocs, sizeof(in_allocs), nullptr,
+ in_allocs, NELEM(in_allocs), nullptr,
&call, sizeof(call), nullptr, 0);
}
diff --git a/services/backup/java/com/android/server/backup/BackupManagerService.java b/services/backup/java/com/android/server/backup/BackupManagerService.java
index ac7c5ab..6cf7a8d 100644
--- a/services/backup/java/com/android/server/backup/BackupManagerService.java
+++ b/services/backup/java/com/android/server/backup/BackupManagerService.java
@@ -27,6 +27,7 @@
import android.app.backup.BackupAgent;
import android.app.backup.BackupDataInput;
import android.app.backup.BackupDataOutput;
+import android.app.backup.BackupManager;
import android.app.backup.BackupTransport;
import android.app.backup.FullBackup;
import android.app.backup.FullBackupDataOutput;
@@ -86,6 +87,7 @@
import android.util.AtomicFile;
import android.util.EventLog;
import android.util.Log;
+import android.util.Pair;
import android.util.Slog;
import android.util.SparseArray;
import android.util.StringBuilderPrinter;
@@ -140,8 +142,10 @@
import java.util.Set;
import java.util.TreeMap;
import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.atomic.AtomicLong;
import java.util.zip.Deflater;
import java.util.zip.DeflaterOutputStream;
import java.util.zip.InflaterInputStream;
@@ -220,6 +224,7 @@
private static final int MSG_RETRY_CLEAR = 12;
private static final int MSG_WIDGET_BROADCAST = 13;
private static final int MSG_RUN_FULL_TRANSPORT_BACKUP = 14;
+ private static final int MSG_SCHEDULE_BACKUP_PACKAGE = 16;
// backup task state machine tick
static final int MSG_BACKUP_RESTORE_STEP = 20;
@@ -242,6 +247,11 @@
// How long between attempts to perform a full-data backup of any given app
static final long MIN_FULL_BACKUP_INTERVAL = 1000 * 60 * 60 * 24; // one day
+ // If an app is busy when we want to do a full-data backup, how long to defer the retry.
+ // This is fuzzed, so there are two parameters; backoff_min + Rand[0, backoff_fuzz)
+ static final long BUSY_BACKOFF_MIN_MILLIS = 1000 * 60 * 60; // one hour
+ static final int BUSY_BACKOFF_FUZZ = 1000 * 60 * 60 * 2; // two hours
+
Context mContext;
private PackageManager mPackageManager;
IPackageManager mPackageManagerBinder;
@@ -531,6 +541,21 @@
}
}
+ class BackupParams {
+ public IBackupTransport transport;
+ public String dirName;
+ public ArrayList<String> kvPackages;
+ public ArrayList<String> fullPackages;
+
+ BackupParams(IBackupTransport transport, String dirName, ArrayList<String> kvPackages,
+ ArrayList<String> fullPackages) {
+ this.transport = transport;
+ this.dirName = dirName;
+ this.kvPackages = kvPackages;
+ this.fullPackages = fullPackages;
+ }
+ }
+
// Bookkeeping of in-flight operations for timeout etc. purposes. The operation
// token is the index of the entry in the pending-operations list.
static final int OP_PENDING = 0;
@@ -652,8 +677,13 @@
return true;
}
+ // Checks if the app is in a stopped state, that means it won't receive broadcasts.
+ private static boolean appIsStopped(ApplicationInfo app) {
+ return ((app.flags & ApplicationInfo.FLAG_STOPPED) != 0);
+ }
+
/* does *not* check overall backup eligibility policy! */
- public static boolean appGetsFullBackup(PackageInfo pkg) {
+ private static boolean appGetsFullBackup(PackageInfo pkg) {
if (pkg.applicationInfo.backupAgentName != null) {
// If it has an agent, it gets full backups only if it says so
return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_FULL_BACKUP_ONLY) != 0;
@@ -663,6 +693,19 @@
return true;
}
+ /* adb backup: is this app only capable of doing key/value? We say otherwise if
+ * the app has a backup agent and does not say fullBackupOnly, *unless* it
+ * is a package that we know _a priori_ explicitly supports both key/value and
+ * full-data backup.
+ */
+ private static boolean appIsKeyValueOnly(PackageInfo pkg) {
+ if ("com.android.providers.settings".equals(pkg.packageName)) {
+ return false;
+ }
+
+ return !appGetsFullBackup(pkg);
+ }
+
// ----- Asynchronous backup/restore handler thread -----
private class BackupHandler extends Handler {
@@ -718,10 +761,10 @@
try {
String dirName = transport.transportDirName();
PerformBackupTask pbt = new PerformBackupTask(transport, dirName,
- queue, oldJournal);
+ queue, oldJournal, null);
Message pbtMessage = obtainMessage(MSG_BACKUP_RESTORE_STEP, pbt);
sendMessage(pbtMessage);
- } catch (RemoteException e) {
+ } catch (Exception e) {
// unable to ask the transport its dir name -- transient failure, since
// the above check succeeded. Try again next time.
Slog.e(TAG, "Transport became unavailable attempting backup");
@@ -757,8 +800,9 @@
case MSG_OP_COMPLETE:
{
try {
- BackupRestoreTask task = (BackupRestoreTask) msg.obj;
- task.operationComplete(msg.arg1);
+ Pair<BackupRestoreTask, Long> taskWithResult =
+ (Pair<BackupRestoreTask, Long>) msg.obj;
+ taskWithResult.first.operationComplete(taskWithResult.second);
} catch (ClassCastException e) {
Slog.e(TAG, "Invalid completion in flight, obj=" + msg.obj);
}
@@ -863,7 +907,7 @@
}
if (sets == null) EventLog.writeEvent(EventLogTags.RESTORE_TRANSPORT_FAILURE);
} catch (Exception e) {
- Slog.e(TAG, "Error from transport getting set list");
+ Slog.e(TAG, "Error from transport getting set list: " + e.getMessage());
} finally {
if (params.observer != null) {
try {
@@ -871,7 +915,7 @@
} catch (RemoteException re) {
Slog.e(TAG, "Unable to report listing to observer");
} catch (Exception e) {
- Slog.e(TAG, "Restore observer threw", e);
+ Slog.e(TAG, "Restore observer threw: " + e.getMessage());
}
}
@@ -941,6 +985,16 @@
mContext.sendBroadcastAsUser(intent, UserHandle.OWNER);
break;
}
+
+ case MSG_SCHEDULE_BACKUP_PACKAGE:
+ {
+ String pkgName = (String)msg.obj;
+ if (MORE_DEBUG) {
+ Slog.d(TAG, "MSG_SCHEDULE_BACKUP_PACKAGE " + pkgName);
+ }
+ dataChangedImpl(pkgName);
+ break;
+ }
}
}
}
@@ -1100,6 +1154,7 @@
if (DEBUG) Slog.v(TAG, "Starting with transport " + mCurrentTransport);
// Find all transport hosts and bind to their services
+ // TODO: http://b/22388012
List<ResolveInfo> hosts = mPackageManager.queryIntentServicesAsUser(
mTransportServiceIntent, 0, UserHandle.USER_OWNER);
if (DEBUG) {
@@ -1660,8 +1715,10 @@
}
return; // done; don't fall through to the error case
}
- } catch (RemoteException e) {
+ } catch (Exception e) {
// transport threw when asked its name; fall through to the lookup-failed case
+ Slog.e(TAG, "Transport " + transportName + " failed to report name: "
+ + e.getMessage());
}
// The named transport doesn't exist or threw. This operation is
@@ -1741,7 +1798,7 @@
File initSentinel = new File(stateDir, INIT_SENTINEL_FILE_NAME);
if (initSentinel.exists()) {
synchronized (mQueueLock) {
- mPendingInits.add(transportName);
+ mPendingInits.add(name);
// TODO: pick a better starting time than now + 1 minute
long delay = 1000 * 60; // one minute, in milliseconds
@@ -1749,7 +1806,7 @@
System.currentTimeMillis() + delay, mRunInitIntent);
}
}
- } catch (RemoteException e) {
+ } catch (Exception e) {
// the transport threw when asked its file naming prefs; declare it invalid
Slog.e(TAG, "Unable to register transport as " + name);
mTransportNames.remove(component);
@@ -1874,7 +1931,9 @@
synchronized (mBackupParticipants) {
if (replacing) {
// This is the package-replaced case; we just remove the entry
- // under the old uid and fall through to re-add.
+ // under the old uid and fall through to re-add. If an app
+ // just added key/value backup participation, this picks it up
+ // as a known participant.
removePackageParticipantsLocked(pkgList, uid);
}
addPackageParticipantsLocked(pkgList);
@@ -1887,6 +1946,14 @@
if (appGetsFullBackup(app) && appIsEligibleForBackup(app.applicationInfo)) {
enqueueFullBackup(packageName, now);
scheduleNextFullBackupJob(0);
+ } else {
+ // The app might have just transitioned out of full-data into
+ // doing key/value backups, or might have just disabled backups
+ // entirely. Make sure it is no longer in the full-data queue.
+ synchronized (mQueueLock) {
+ dequeueFullBackupLocked(packageName);
+ }
+ writeFullBackupScheduleAsync();
}
// Transport maintenance: rebind to known existing transports that have
@@ -1918,6 +1985,9 @@
if (replacing) {
// The package is being updated. We'll receive a PACKAGE_ADDED shortly.
} else {
+ // Outright removal. In the full-data case, the app will be dropped
+ // from the queue when its (now obsolete) name comes up again for
+ // backup.
synchronized (mBackupParticipants) {
removePackageParticipantsLocked(pkgList, uid);
}
@@ -1942,8 +2012,9 @@
IBackupTransport transport = IBackupTransport.Stub.asInterface(service);
registerTransport(transport.name(), name, transport);
EventLog.writeEvent(EventLogTags.BACKUP_TRANSPORT_LIFECYCLE, name, 1);
- } catch (RemoteException e) {
- Slog.e(TAG, "Unable to register transport " + component);
+ } catch (Exception e) {
+ Slog.e(TAG, "Unable to register transport " + component
+ + ": " + e.getMessage());
EventLog.writeEvent(EventLogTags.BACKUP_TRANSPORT_LIFECYCLE, name, 0);
}
}
@@ -1961,6 +2032,7 @@
void checkForTransportAndBind(PackageInfo pkgInfo) {
Intent intent = new Intent(mTransportServiceIntent)
.setPackage(pkgInfo.packageName);
+ // TODO: http://b/22388012
List<ResolveInfo> hosts = mPackageManager.queryIntentServicesAsUser(
intent, 0, UserHandle.USER_OWNER);
if (hosts != null) {
@@ -1996,7 +2068,7 @@
return false;
}
- if (DEBUG) {
+ if (MORE_DEBUG) {
Slog.i(TAG, "Binding to transport host " + svcName);
}
Intent intent = new Intent(mTransportServiceIntent);
@@ -2015,6 +2087,7 @@
mContext.unbindService(connection);
}
}
+ // TODO: http://b/22388012
return mContext.bindServiceAsUser(intent,
connection, Context.BIND_AUTO_CREATE,
UserHandle.OWNER);
@@ -2047,7 +2120,7 @@
int uid = pkg.applicationInfo.uid;
HashSet<String> set = mBackupParticipants.get(uid);
if (set == null) {
- set = new HashSet<String>();
+ set = new HashSet<>();
mBackupParticipants.put(uid, set);
}
set.add(pkg.packageName);
@@ -2055,7 +2128,9 @@
// Schedule a backup for it on general principles
if (MORE_DEBUG) Slog.i(TAG, "Scheduling backup for new app " + pkg.packageName);
- dataChangedImpl(pkg.packageName);
+ Message msg = mBackupHandler
+ .obtainMessage(MSG_SCHEDULE_BACKUP_PACKAGE, pkg.packageName);
+ mBackupHandler.sendMessage(msg);
}
}
}
@@ -2108,7 +2183,8 @@
try {
ApplicationInfo app = pkg.applicationInfo;
if (((app.flags&ApplicationInfo.FLAG_ALLOW_BACKUP) == 0)
- || app.backupAgentName == null) {
+ || app.backupAgentName == null
+ || (app.flags&ApplicationInfo.FLAG_FULL_BACKUP_ONLY) != 0) {
packages.remove(a);
}
else {
@@ -2228,6 +2304,25 @@
}
}
+ // What name is this transport registered under...?
+ private String getTransportName(IBackupTransport transport) {
+ if (MORE_DEBUG) {
+ Slog.v(TAG, "Searching for transport name of " + transport);
+ }
+ synchronized (mTransports) {
+ final int N = mTransports.size();
+ for (int i = 0; i < N; i++) {
+ if (mTransports.valueAt(i).equals(transport)) {
+ if (MORE_DEBUG) {
+ Slog.v(TAG, " Name found: " + mTransports.keyAt(i));
+ }
+ return mTransports.keyAt(i);
+ }
+ }
+ }
+ return null;
+ }
+
// fire off a backup agent, blocking until it attaches or times out
IBackupAgent bindToAgentSynchronous(ApplicationInfo app, int mode) {
IBackupAgent agent = null;
@@ -2344,7 +2439,7 @@
void execute();
// An operation that wanted a callback has completed
- void operationComplete(int result);
+ void operationComplete(long result);
// An operation that wanted a callback has timed out
void handleTimeout();
@@ -2352,7 +2447,7 @@
void prepareOperationTimeout(int token, long interval, BackupRestoreTask callback) {
if (MORE_DEBUG) Slog.v(TAG, "starting timeout: token=" + Integer.toHexString(token)
- + " interval=" + interval);
+ + " interval=" + interval + " callback=" + callback);
synchronized (mCurrentOpLock) {
mCurrentOperations.put(token, new Operation(OP_PENDING, callback));
@@ -2404,16 +2499,26 @@
+ " but no op found");
}
int state = (op != null) ? op.state : OP_TIMEOUT;
- if (state == OP_PENDING) {
+ if (state == OP_ACKNOWLEDGED) {
+ // The operation finished cleanly, so we have nothing more to do.
+ if (MORE_DEBUG) {
+ Slog.v(TAG, "handleTimeout() after success; cleanup happens now");
+ }
+ op = null;
+ mCurrentOperations.delete(token);
+ } else if (state == OP_PENDING) {
if (DEBUG) Slog.v(TAG, "TIMEOUT: token=" + Integer.toHexString(token));
op.state = OP_TIMEOUT;
- mCurrentOperations.put(token, op);
+ // Leaves the object in place for later ack
}
mCurrentOpLock.notifyAll();
}
// If there's a TimeoutHandler for this event, call it
if (op != null && op.callback != null) {
+ if (MORE_DEBUG) {
+ Slog.v(TAG, " Invoking timeout on " + op.callback);
+ }
op.callback.handleTimeout();
}
}
@@ -2435,6 +2540,7 @@
File mStateDir;
File mJournal;
BackupState mCurrentState;
+ ArrayList<String> mPendingFullBackups;
// carried information about the current in-flight operation
IBackupAgent mAgentBinder;
@@ -2449,10 +2555,12 @@
boolean mFinished;
public PerformBackupTask(IBackupTransport transport, String dirName,
- ArrayList<BackupRequest> queue, File journal) {
+ ArrayList<BackupRequest> queue, File journal,
+ ArrayList<String> pendingFullBackups) {
mTransport = transport;
mOriginalQueue = queue;
mJournal = journal;
+ mPendingFullBackups = pendingFullBackups;
mStateDir = new File(mBaseStateDir, dirName);
@@ -2504,7 +2612,7 @@
mStatus = BackupTransport.TRANSPORT_OK;
// Sanity check: if the queue is empty we have no work to do.
- if (mOriginalQueue.isEmpty()) {
+ if (mOriginalQueue.isEmpty() && mPendingFullBackups.isEmpty()) {
Slog.w(TAG, "Backup begun with an empty queue - nothing to do.");
addBackupTrace("queue empty at begin");
executeNextState(BackupState.FINAL);
@@ -2590,6 +2698,7 @@
// if things went wrong at this point, we need to
// restage everything and try again later.
resetBackupState(mStateDir); // Just to make sure.
+ // In case of any other error, it's backup transport error.
executeNextState(BackupState.FINAL);
}
}
@@ -2646,7 +2755,7 @@
return;
}
- if ((mCurrentPackage.applicationInfo.flags & ApplicationInfo.FLAG_STOPPED) != 0) {
+ if (appIsStopped(mCurrentPackage.applicationInfo)) {
// The app has been force-stopped or cleared or just installed,
// and not yet launched out of that state, so just as it won't
// receive broadcasts, we won't run it for backup.
@@ -2735,9 +2844,10 @@
try {
mCurrentToken = mTransport.getCurrentRestoreSet();
writeRestoreTokens();
- } catch (RemoteException e) {
+ } catch (Exception e) {
// nothing for it at this point, unfortunately, but this will be
// recorded the next time we fully succeed.
+ Slog.e(TAG, "Transport threw reporting restore set: " + e.getMessage());
addBackupTrace("transport threw returning token");
}
}
@@ -2749,16 +2859,44 @@
mBackupRunning = false;
if (mStatus == BackupTransport.TRANSPORT_NOT_INITIALIZED) {
// Make sure we back up everything and perform the one-time init
- clearMetadata();
if (MORE_DEBUG) Slog.d(TAG, "Server requires init; rerunning");
addBackupTrace("init required; rerunning");
+ try {
+ final String name = getTransportName(mTransport);
+ if (name != null) {
+ mPendingInits.add(name);
+ } else {
+ if (DEBUG) {
+ Slog.w(TAG, "Couldn't find name of transport " + mTransport
+ + " for init");
+ }
+ }
+ } catch (Exception e) {
+ Slog.w(TAG, "Failed to query transport name for init: " + e.getMessage());
+ // swallow it and proceed; we don't rely on this
+ }
+ clearMetadata();
backupNow();
}
}
- // Only once we're entirely finished do we release the wakelock
clearBackupTrace();
- Slog.i(BackupManagerService.TAG, "Backup pass finished.");
+
+ if (mStatus == BackupTransport.TRANSPORT_OK &&
+ mPendingFullBackups != null && !mPendingFullBackups.isEmpty()) {
+ Slog.d(TAG, "Starting full backups for: " + mPendingFullBackups);
+ CountDownLatch latch = new CountDownLatch(1);
+ String[] fullBackups =
+ mPendingFullBackups.toArray(new String[mPendingFullBackups.size()]);
+ PerformFullTransportBackupTask task =
+ new PerformFullTransportBackupTask(/*fullBackupRestoreObserver*/ null,
+ fullBackups, /*updateSchedule*/ false, /*runningJob*/ null, latch);
+ // Acquiring wakelock for PerformFullTransportBackupTask before its start.
+ mWakelock.acquire();
+ (new Thread(task, "full-transport-requested")).start();
+ }
+ Slog.i(BackupManagerService.TAG, "K/V backup pass finished.");
+ // Only once we're entirely finished do we release the wakelock for k/v backup.
mWakelock.release();
}
@@ -2867,6 +3005,7 @@
private void writeWidgetPayloadIfAppropriate(FileDescriptor fd, String pkgName)
throws IOException {
+ // TODO: http://b/22388012
byte[] widgetState = AppWidgetBackupBridge.getWidgetState(pkgName,
UserHandle.USER_OWNER);
// has the widget state changed since last time?
@@ -2926,7 +3065,7 @@
}
@Override
- public void operationComplete(int unusedResult) {
+ public void operationComplete(long unusedResult) {
// The agent reported back to us!
if (mBackupData == null) {
@@ -3001,8 +3140,9 @@
ParcelFileDescriptor backupData = null;
mStatus = BackupTransport.TRANSPORT_OK;
+ long size = 0;
try {
- int size = (int) mBackupDataName.length();
+ size = mBackupDataName.length();
if (size > 0) {
if (mStatus == BackupTransport.TRANSPORT_OK) {
backupData = ParcelFileDescriptor.open(mBackupDataName,
@@ -3061,6 +3201,12 @@
// Success or single-package rejection. Proceed with the next app if any,
// otherwise we're done.
nextState = (mQueue.isEmpty()) ? BackupState.FINAL : BackupState.RUNNING_QUEUE;
+ } else if (mStatus == BackupTransport.TRANSPORT_QUOTA_EXCEEDED) {
+ if (MORE_DEBUG) {
+ Slog.d(TAG, "Package " + mCurrentPackage.packageName +
+ " hit quota limit on k/v backup");
+ }
+ nextState = (mQueue.isEmpty()) ? BackupState.FINAL : BackupState.RUNNING_QUEUE;
} else {
// Any other error here indicates a transport-level failure. That means
// we need to halt everything and reschedule everything for next time.
@@ -3095,7 +3241,7 @@
try {
delay = mTransport.requestBackupTime();
} catch (Exception e) {
- Slog.w(TAG, "Unable to contact transport for recommended backoff");
+ Slog.w(TAG, "Unable to contact transport for recommended backoff: " + e.getMessage());
delay = 0; // use the scheduler's default
}
KeyValueBackupJob.schedule(mContext, delay);
@@ -3161,8 +3307,8 @@
Intent obbIntent = new Intent().setComponent(new ComponentName(
"com.android.sharedstoragebackup",
"com.android.sharedstoragebackup.ObbBackupService"));
- BackupManagerService.this.mContext.bindService(
- obbIntent, this, Context.BIND_AUTO_CREATE);
+ BackupManagerService.this.mContext.bindServiceAsUser(
+ obbIntent, this, Context.BIND_AUTO_CREATE, UserHandle.OWNER);
}
public void tearDown() {
@@ -3245,6 +3391,7 @@
private void routeSocketDataToOutput(ParcelFileDescriptor inPipe, OutputStream out)
throws IOException {
+ // We do not take close() responsibility for the pipe FD
FileInputStream raw = new FileInputStream(inPipe.getFileDescriptor());
DataInputStream in = new DataInputStream(raw);
@@ -3261,6 +3408,11 @@
}
void tearDownAgentAndKill(ApplicationInfo app) {
+ if (app == null) {
+ // Null means the system package, so just quietly move on. :)
+ return;
+ }
+
try {
// unbind and tidy up even on timeout or failure, just in case
mActivityManager.unbindBackupAgent(app);
@@ -3268,9 +3420,8 @@
// The agent was running with a stub Application object, so shut it down.
// !!! We hardcode the confirmation UI's package name here rather than use a
// manifest flag! TODO something less direct.
- if (app.uid != Process.SYSTEM_UID
- && !app.packageName.equals("com.android.backupconfirm")
- && app.uid != Process.PHONE_UID) {
+ if (app.uid >= Process.FIRST_APPLICATION_UID
+ && !app.packageName.equals("com.android.backupconfirm")) {
if (MORE_DEBUG) Slog.d(TAG, "Killing agent host process");
mActivityManager.killApplicationProcess(app.processName, app.uid);
} else {
@@ -3295,16 +3446,20 @@
* or one of the other BackupTransport.* error codes as appropriate
*/
int preflightFullBackup(PackageInfo pkg, IBackupAgent agent);
+
+ long getExpectedSizeOrErrorCode();
};
class FullBackupEngine {
OutputStream mOutput;
FullBackupPreflight mPreflightHook;
- IFullBackupRestoreObserver mObserver;
+ BackupRestoreTask mTimeoutMonitor;
+ IBackupAgent mAgent;
File mFilesDir;
File mManifestFile;
File mMetadataFile;
boolean mIncludeApks;
+ PackageInfo mPkg;
class FullBackupRunner implements Runnable {
PackageInfo mPackage;
@@ -3316,8 +3471,8 @@
boolean mWriteManifest;
FullBackupRunner(PackageInfo pack, IBackupAgent agent, ParcelFileDescriptor pipe,
- int token, boolean sendApk, boolean writeManifest, byte[] widgetData)
- throws IOException {
+ int token, boolean sendApk, boolean writeManifest, byte[] widgetData)
+ throws IOException {
mPackage = pack;
mWidgetData = widgetData;
mAgent = agent;
@@ -3358,7 +3513,8 @@
}
if (DEBUG) Slog.d(TAG, "Calling doFullBackup() on " + mPackage.packageName);
- prepareOperationTimeout(mToken, TIMEOUT_FULL_BACKUP_INTERVAL, null);
+ prepareOperationTimeout(mToken, TIMEOUT_FULL_BACKUP_INTERVAL,
+ mTimeoutMonitor /* in parent class */);
mAgent.doFullBackup(mPipe, mToken, mBackupManagerBinder);
} catch (IOException e) {
Slog.e(TAG, "Error running full backup for " + mPackage.packageName);
@@ -3373,75 +3529,79 @@
}
}
- FullBackupEngine(OutputStream output, String packageName, FullBackupPreflight preflightHook,
- boolean alsoApks) {
+ FullBackupEngine(OutputStream output, FullBackupPreflight preflightHook, PackageInfo pkg,
+ boolean alsoApks, BackupRestoreTask timeoutMonitor) {
mOutput = output;
mPreflightHook = preflightHook;
+ mPkg = pkg;
mIncludeApks = alsoApks;
+ mTimeoutMonitor = timeoutMonitor;
mFilesDir = new File("/data/system");
mManifestFile = new File(mFilesDir, BACKUP_MANIFEST_FILENAME);
mMetadataFile = new File(mFilesDir, BACKUP_METADATA_FILENAME);
}
- public int backupOnePackage(PackageInfo pkg) throws RemoteException {
- int result = BackupTransport.TRANSPORT_OK;
- Slog.d(TAG, "Binding to full backup agent : " + pkg.packageName);
+ public int preflightCheck() throws RemoteException {
+ if (mPreflightHook == null) {
+ if (MORE_DEBUG) {
+ Slog.v(TAG, "No preflight check");
+ }
+ return BackupTransport.TRANSPORT_OK;
+ }
+ if (initializeAgent()) {
+ int result = mPreflightHook.preflightFullBackup(mPkg, mAgent);
+ if (MORE_DEBUG) {
+ Slog.v(TAG, "preflight returned " + result);
+ }
+ return result;
+ } else {
+ Slog.w(TAG, "Unable to bind to full agent for " + mPkg.packageName);
+ return BackupTransport.AGENT_ERROR;
+ }
+ }
- IBackupAgent agent = bindToAgentSynchronous(pkg.applicationInfo,
- IApplicationThread.BACKUP_MODE_FULL);
- if (agent != null) {
+ public int backupOnePackage() throws RemoteException {
+ int result = BackupTransport.AGENT_ERROR;
+
+ if (initializeAgent()) {
ParcelFileDescriptor[] pipes = null;
try {
- // Call the preflight hook, if any
- if (mPreflightHook != null) {
- result = mPreflightHook.preflightFullBackup(pkg, agent);
+ pipes = ParcelFileDescriptor.createPipe();
+
+ ApplicationInfo app = mPkg.applicationInfo;
+ final boolean isSharedStorage =
+ mPkg.packageName.equals(SHARED_BACKUP_AGENT_PACKAGE);
+ final boolean sendApk = mIncludeApks
+ && !isSharedStorage
+ && ((app.privateFlags & ApplicationInfo.PRIVATE_FLAG_FORWARD_LOCK) == 0)
+ && ((app.flags & ApplicationInfo.FLAG_SYSTEM) == 0 ||
+ (app.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0);
+
+ // TODO: http://b/22388012
+ byte[] widgetBlob = AppWidgetBackupBridge.getWidgetState(mPkg.packageName,
+ UserHandle.USER_OWNER);
+
+ final int token = generateToken();
+ FullBackupRunner runner = new FullBackupRunner(mPkg, mAgent, pipes[1],
+ token, sendApk, !isSharedStorage, widgetBlob);
+ pipes[1].close(); // the runner has dup'd it
+ pipes[1] = null;
+ Thread t = new Thread(runner, "app-data-runner");
+ t.start();
+
+ // Now pull data from the app and stuff it into the output
+ routeSocketDataToOutput(pipes[0], mOutput);
+
+ if (!waitUntilOperationComplete(token)) {
+ Slog.e(TAG, "Full backup failed on package " + mPkg.packageName);
+ } else {
if (MORE_DEBUG) {
- Slog.v(TAG, "preflight returned " + result);
+ Slog.d(TAG, "Full package backup success: " + mPkg.packageName);
}
- }
-
- // If we're still good to go after preflighting, start moving data
- if (result == BackupTransport.TRANSPORT_OK) {
- pipes = ParcelFileDescriptor.createPipe();
-
- ApplicationInfo app = pkg.applicationInfo;
- final boolean isSharedStorage = pkg.packageName.equals(SHARED_BACKUP_AGENT_PACKAGE);
- final boolean sendApk = mIncludeApks
- && !isSharedStorage
- && ((app.privateFlags & ApplicationInfo.PRIVATE_FLAG_FORWARD_LOCK) == 0)
- && ((app.flags & ApplicationInfo.FLAG_SYSTEM) == 0 ||
- (app.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0);
-
- byte[] widgetBlob = AppWidgetBackupBridge.getWidgetState(pkg.packageName,
- UserHandle.USER_OWNER);
-
- final int token = generateToken();
- FullBackupRunner runner = new FullBackupRunner(pkg, agent, pipes[1],
- token, sendApk, !isSharedStorage, widgetBlob);
- pipes[1].close(); // the runner has dup'd it
- pipes[1] = null;
- Thread t = new Thread(runner, "app-data-runner");
- t.start();
-
- // Now pull data from the app and stuff it into the output
- try {
- routeSocketDataToOutput(pipes[0], mOutput);
- } catch (IOException e) {
- Slog.i(TAG, "Caught exception reading from agent", e);
- result = BackupTransport.AGENT_ERROR;
- }
-
- if (!waitUntilOperationComplete(token)) {
- Slog.e(TAG, "Full backup failed on package " + pkg.packageName);
- result = BackupTransport.AGENT_ERROR;
- } else {
- if (MORE_DEBUG) {
- Slog.d(TAG, "Full package backup success: " + pkg.packageName);
- }
- }
+ result = BackupTransport.TRANSPORT_OK;
}
} catch (IOException e) {
- Slog.e(TAG, "Error backing up " + pkg.packageName, e);
+ Slog.e(TAG, "Error backing up " + mPkg.packageName + ": " + e.getMessage());
result = BackupTransport.AGENT_ERROR;
} finally {
try {
@@ -3457,13 +3617,23 @@
}
}
} else {
- Slog.w(TAG, "Unable to bind to full agent for " + pkg.packageName);
- result = BackupTransport.AGENT_ERROR;
+ Slog.w(TAG, "Unable to bind to full agent for " + mPkg.packageName);
}
- tearDown(pkg);
+ tearDown();
return result;
}
+ private boolean initializeAgent() {
+ if (mAgent == null) {
+ if (MORE_DEBUG) {
+ Slog.d(TAG, "Binding to full backup agent : " + mPkg.packageName);
+ }
+ mAgent = bindToAgentSynchronous(mPkg.applicationInfo,
+ IApplicationThread.BACKUP_MODE_FULL);
+ }
+ return mAgent != null;
+ }
+
private void writeApkToBackup(PackageInfo pkg, FullBackupDataOutput output) {
// Forward-locked apps, system-bundled .apks, etc are filtered out before we get here
// TODO: handle backing up split APKs
@@ -3477,6 +3647,7 @@
// Save associated .obb content if it exists and we did save the apk
// check for .obb and save those too
+ // TODO: http://b/22388012
final UserEnvironment userEnv = new UserEnvironment(UserHandle.USER_OWNER);
final File obbDir = userEnv.buildExternalStorageAppObbDirs(pkg.packageName)[0];
if (obbDir != null) {
@@ -3579,12 +3750,9 @@
destination.setLastModified(0);
}
- private void tearDown(PackageInfo pkg) {
- if (pkg != null) {
- final ApplicationInfo app = pkg.applicationInfo;
- if (app != null) {
- tearDownAgentAndKill(app);
- }
+ private void tearDown() {
+ if (mPkg != null) {
+ tearDownAgentAndKill(mPkg.applicationInfo);
}
}
}
@@ -3648,7 +3816,7 @@
}
// Full backup task variant used for adb backup
- class PerformAdbBackupTask extends FullBackupTask {
+ class PerformAdbBackupTask extends FullBackupTask implements BackupRestoreTask {
FullBackupEngine mBackupEngine;
final AtomicBoolean mLatch;
@@ -3662,6 +3830,7 @@
boolean mIncludeSystem;
boolean mCompress;
ArrayList<String> mPackages;
+ PackageInfo mCurrentTarget;
String mCurrentPassword;
String mEncryptPassword;
@@ -3692,6 +3861,9 @@
} else {
mEncryptPassword = encryptPassword;
}
+ if (MORE_DEBUG) {
+ Slog.w(TAG, "Encrypting backup with passphrase=" + mEncryptPassword);
+ }
mCompress = doCompress;
}
@@ -3817,6 +3989,7 @@
// If we're doing widget state as well, ensure that we have all the involved
// host & provider packages in the set
if (mDoWidgets) {
+ // TODO: http://b/22388012
List<String> pkgs =
AppWidgetBackupBridge.getWidgetParticipants(UserHandle.USER_OWNER);
if (pkgs != null) {
@@ -3847,7 +4020,9 @@
Iterator<Entry<String, PackageInfo>> iter = packagesToBackup.entrySet().iterator();
while (iter.hasNext()) {
PackageInfo pkg = iter.next().getValue();
- if (!appIsEligibleForBackup(pkg.applicationInfo)) {
+ if (!appIsEligibleForBackup(pkg.applicationInfo)
+ || appIsStopped(pkg.applicationInfo)
+ || appIsKeyValueOnly(pkg)) {
iter.remove();
}
}
@@ -3949,9 +4124,12 @@
final boolean isSharedStorage =
pkg.packageName.equals(SHARED_BACKUP_AGENT_PACKAGE);
- mBackupEngine = new FullBackupEngine(out, pkg.packageName, null, mIncludeApks);
+ mBackupEngine = new FullBackupEngine(out, null, pkg, mIncludeApks, this);
sendOnBackupPackage(isSharedStorage ? "Shared storage" : pkg.packageName);
- mBackupEngine.backupOnePackage(pkg);
+
+ // Don't need to check preflight result as there is no preflight hook.
+ mCurrentTarget = pkg;
+ mBackupEngine.backupOnePackage();
// after the app's agent runs to handle its private filesystem
// contents, back up any OBB content it has on its behalf.
@@ -3971,7 +4149,10 @@
Slog.e(TAG, "Internal exception during full backup", e);
} finally {
try {
- if (out != null) out.close();
+ if (out != null) {
+ out.flush();
+ out.close();
+ }
mOutputFile.close();
} catch (IOException e) {
/* nothing we can do about this */
@@ -3989,6 +4170,28 @@
mWakelock.release();
}
}
+
+ // BackupRestoreTask methods, used for timeout handling
+ @Override
+ public void execute() {
+ // Unused
+ }
+
+ @Override
+ public void operationComplete(long result) {
+ // Unused
+ }
+
+ @Override
+ public void handleTimeout() {
+ final PackageInfo target = mCurrentTarget;
+ if (DEBUG) {
+ Slog.w(TAG, "adb backup timeout of " + target);
+ }
+ if (target != null) {
+ tearDownAgentAndKill(mCurrentTarget.applicationInfo);
+ }
+ }
}
// Full backup task extension used for transport-oriented operation
@@ -4014,24 +4217,24 @@
try {
PackageInfo info = mPackageManager.getPackageInfo(pkg,
PackageManager.GET_SIGNATURES);
- if ((info.applicationInfo.flags & ApplicationInfo.FLAG_ALLOW_BACKUP) == 0
- || pkg.equals(SHARED_BACKUP_AGENT_PACKAGE)) {
+ if (!appIsEligibleForBackup(info.applicationInfo)) {
// Cull any packages that have indicated that backups are not permitted,
+ // that run as system-domain uids but do not define their own backup agents,
// as well as any explicit mention of the 'special' shared-storage agent
// package (we handle that one at the end).
if (MORE_DEBUG) {
- Slog.d(TAG, "Ignoring opted-out package " + pkg);
+ Slog.d(TAG, "Ignoring ineligible package " + pkg);
}
continue;
- } else if ((info.applicationInfo.uid < Process.FIRST_APPLICATION_UID)
- && (info.applicationInfo.backupAgentName == null)) {
- // Cull any packages that run as system-domain uids but do not define their
- // own backup agents
+ } else if (!appGetsFullBackup(info)) {
+ // Cull any packages that are found in the queue but now aren't supposed
+ // to get full-data backup operations.
if (MORE_DEBUG) {
- Slog.d(TAG, "Ignoring non-agent system package " + pkg);
+ Slog.d(TAG, "Ignoring full-data backup of key/value participant "
+ + pkg);
}
continue;
- } else if ((info.applicationInfo.flags & ApplicationInfo.FLAG_STOPPED) != 0) {
+ } else if (appIsStopped(info.applicationInfo)) {
// Cull any packages in the 'stopped' state: they've either just been
// installed or have explicitly been force-stopped by the user. In both
// cases we do not want to launch them for backup.
@@ -4059,8 +4262,8 @@
// Pipe through which we write data to the transport
ParcelFileDescriptor[] transportPipes = null;
- PackageInfo currentPackage;
long backoff = 0;
+ int backupRunStatus = BackupManager.SUCCESS;
try {
if (!mEnabled || !mProvisioned) {
@@ -4070,32 +4273,34 @@
+ " p=" + mProvisioned + "; ignoring");
}
mUpdateSchedule = false;
+ backupRunStatus = BackupManager.ERROR_BACKUP_NOT_ALLOWED;
return;
}
IBackupTransport transport = getTransport(mCurrentTransport);
if (transport == null) {
Slog.w(TAG, "Transport not present; full data backup not performed");
+ backupRunStatus = BackupManager.ERROR_TRANSPORT_ABORTED;
return;
}
// Set up to send data to the transport
final int N = mPackages.size();
+ final byte[] buffer = new byte[8192];
for (int i = 0; i < N; i++) {
- currentPackage = mPackages.get(i);
+ PackageInfo currentPackage = mPackages.get(i);
+ String packageName = currentPackage.packageName;
if (DEBUG) {
- Slog.i(TAG, "Initiating full-data transport backup of "
- + currentPackage.packageName);
+ Slog.i(TAG, "Initiating full-data transport backup of " + packageName);
}
- EventLog.writeEvent(EventLogTags.FULL_BACKUP_PACKAGE,
- currentPackage.packageName);
+ EventLog.writeEvent(EventLogTags.FULL_BACKUP_PACKAGE, packageName);
transportPipes = ParcelFileDescriptor.createPipe();
// Tell the transport the data's coming
- int result = transport.performFullBackup(currentPackage,
+ int backupPackageStatus = transport.performFullBackup(currentPackage,
transportPipes[0]);
- if (result == BackupTransport.TRANSPORT_OK) {
+ if (backupPackageStatus == BackupTransport.TRANSPORT_OK) {
// The transport has its own copy of the read end of the pipe,
// so close ours now
transportPipes[0].close();
@@ -4103,10 +4308,9 @@
// Now set up the backup engine / data source end of things
enginePipes = ParcelFileDescriptor.createPipe();
- CountDownLatch runnerLatch = new CountDownLatch(1);
SinglePackageBackupRunner backupRunner =
new SinglePackageBackupRunner(enginePipes[1], currentPackage,
- transport, runnerLatch);
+ transport);
// The runner dup'd the pipe half, so we close it here
enginePipes[1].close();
enginePipes[1] = null;
@@ -4116,35 +4320,55 @@
(new Thread(backupRunner, "package-backup-bridge")).start();
// Read data off the engine pipe and pass it to the transport
- // pipe until we hit EOD on the input stream.
+ // pipe until we hit EOD on the input stream. We do not take
+ // close() responsibility for these FDs into these stream wrappers.
FileInputStream in = new FileInputStream(
enginePipes[0].getFileDescriptor());
FileOutputStream out = new FileOutputStream(
transportPipes[1].getFileDescriptor());
- byte[] buffer = new byte[8192];
- int nRead = 0;
- do {
- if (!mKeepRunning.get()) {
- if (DEBUG_SCHEDULING) {
- Slog.i(TAG, "Full backup task told to stop");
- }
- break;
- }
- nRead = in.read(buffer);
+ long totalRead = 0;
+ final long preflightResult = backupRunner.getPreflightResultBlocking();
+ // Preflight result is negative if some error happened on preflight.
+ if (preflightResult < 0) {
if (MORE_DEBUG) {
- Slog.v(TAG, "in.read(buffer) from app: " + nRead);
+ Slog.d(TAG, "Backup error after preflight of package "
+ + packageName + ": " + preflightResult
+ + ", not running backup.");
}
- if (nRead > 0) {
- out.write(buffer, 0, nRead);
- result = transport.sendBackupData(nRead);
+ backupPackageStatus = (int) preflightResult;
+ } else {
+ int nRead = 0;
+ do {
+ if (!mKeepRunning.get()) {
+ if (DEBUG_SCHEDULING) {
+ Slog.i(TAG, "Full backup task told to stop");
+ }
+ break;
+ }
+ nRead = in.read(buffer);
+ if (MORE_DEBUG) {
+ Slog.v(TAG, "in.read(buffer) from app: " + nRead);
+ }
+ if (nRead > 0) {
+ out.write(buffer, 0, nRead);
+ backupPackageStatus = transport.sendBackupData(nRead);
+ totalRead += nRead;
+ }
+ } while (nRead > 0
+ && backupPackageStatus == BackupTransport.TRANSPORT_OK);
+
+ // Despite preflight succeeded, package still can hit quota on flight.
+ if (backupPackageStatus == BackupTransport.TRANSPORT_QUOTA_EXCEEDED) {
+ Slog.w(TAG, "Package hit quota limit in-flight " + packageName
+ + ": " + totalRead);
}
- } while (nRead > 0 && result == BackupTransport.TRANSPORT_OK);
+ }
// If we've lost our running criteria, tell the transport to cancel
// and roll back this (partial) backup payload; otherwise tell it
// that we've reached the clean finish state.
if (!mKeepRunning.get()) {
- result = BackupTransport.TRANSPORT_ERROR;
+ backupPackageStatus = BackupTransport.TRANSPORT_ERROR;
transport.cancelFullBackup();
} else {
// If we were otherwise in a good state, now interpret the final
@@ -4152,18 +4376,42 @@
// failure case already, preserve that result and ignore whatever
// finishBackup() reports.
final int finishResult = transport.finishBackup();
- if (result == BackupTransport.TRANSPORT_OK) {
- result = finishResult;
+ if (backupPackageStatus == BackupTransport.TRANSPORT_OK) {
+ backupPackageStatus = finishResult;
+ }
+ }
+
+ // A transport-originated error here means that we've hit an error that the
+ // runner doesn't know about, so it's still moving data but we're pulling the
+ // rug out from under it. Don't ask for its result: we already know better
+ // and we'll hang if we block waiting for it, since it relies on us to
+ // read back the data it's writing into the engine. Just proceed with
+ // a graceful failure. The runner/engine mechanism will tear itself
+ // down cleanly when we close the pipes from this end. Transport-level
+ // errors take precedence over agent/app-specific errors for purposes of
+ // determining our course of action.
+ if (backupPackageStatus == BackupTransport.TRANSPORT_OK) {
+ // We still could fail in backup runner thread, getting result from there.
+ int backupRunnerResult = backupRunner.getBackupResultBlocking();
+ if (backupRunnerResult != BackupTransport.TRANSPORT_OK) {
+ // If there was an error in runner thread and
+ // not TRANSPORT_ERROR here, overwrite it.
+ backupPackageStatus = backupRunnerResult;
+ }
+ } else {
+ if (MORE_DEBUG) {
+ Slog.i(TAG, "Transport-level failure; cancelling agent work");
}
}
if (MORE_DEBUG) {
- Slog.i(TAG, "Done trying to send backup data: result=" + result);
+ Slog.i(TAG, "Done delivering backup data: result="
+ + backupPackageStatus);
}
- if (result != BackupTransport.TRANSPORT_OK) {
- Slog.e(TAG, "Error " + result
- + " backing up " + currentPackage.packageName);
+ if (backupPackageStatus != BackupTransport.TRANSPORT_OK) {
+ Slog.e(TAG, "Error " + backupPackageStatus + " backing up "
+ + packageName);
}
// Also ask the transport how long it wants us to wait before
@@ -4178,40 +4426,56 @@
// Roll this package to the end of the backup queue if we're
// in a queue-driven mode (regardless of success/failure)
if (mUpdateSchedule) {
- enqueueFullBackup(currentPackage.packageName,
- System.currentTimeMillis());
+ enqueueFullBackup(packageName, System.currentTimeMillis());
}
- if (result == BackupTransport.TRANSPORT_PACKAGE_REJECTED) {
+ if (backupPackageStatus == BackupTransport.TRANSPORT_PACKAGE_REJECTED) {
if (DEBUG) {
- Slog.i(TAG, "Transport rejected backup of "
- + currentPackage.packageName
+ Slog.i(TAG, "Transport rejected backup of " + packageName
+ ", skipping");
}
- EventLog.writeEvent(EventLogTags.FULL_BACKUP_AGENT_FAILURE,
- currentPackage.packageName, "transport rejected");
- // do nothing, clean up, and continue looping
- } else if (result != BackupTransport.TRANSPORT_OK) {
- Slog.w(TAG, "Transport failed; aborting backup: " + result);
+ EventLog.writeEvent(EventLogTags.FULL_BACKUP_AGENT_FAILURE, packageName,
+ "transport rejected");
+ // Do nothing, clean up, and continue looping.
+ } else if (backupPackageStatus == BackupTransport.TRANSPORT_QUOTA_EXCEEDED) {
+ if (DEBUG) {
+ Slog.i(TAG, "Transport quota exceeded for package: " + packageName);
+ }
+ // Do nothing, clean up, and continue looping.
+ } else if (backupPackageStatus == BackupTransport.AGENT_ERROR) {
+ Slog.w(TAG, "Application failure for package: " + packageName);
+ EventLog.writeEvent(EventLogTags.BACKUP_AGENT_FAILURE, packageName);
+ tearDownAgentAndKill(currentPackage.applicationInfo);
+ // Do nothing, clean up, and continue looping.
+ } else if (backupPackageStatus != BackupTransport.TRANSPORT_OK) {
+ Slog.w(TAG, "Transport failed; aborting backup: " + backupPackageStatus);
EventLog.writeEvent(EventLogTags.FULL_BACKUP_TRANSPORT_FAILURE);
+ // Abort entire backup pass.
+ backupRunStatus = BackupManager.ERROR_TRANSPORT_ABORTED;
return;
} else {
// Success!
- EventLog.writeEvent(EventLogTags.FULL_BACKUP_SUCCESS,
- currentPackage.packageName);
- logBackupComplete(currentPackage.packageName);
+ EventLog.writeEvent(EventLogTags.FULL_BACKUP_SUCCESS, packageName);
+ logBackupComplete(packageName);
}
cleanUpPipes(transportPipes);
cleanUpPipes(enginePipes);
- currentPackage = null;
- }
-
- if (DEBUG) {
- Slog.i(TAG, "Full backup completed.");
+ if (currentPackage.applicationInfo != null) {
+ Slog.i(TAG, "Unbinding agent in " + packageName);
+ addBackupTrace("unbinding " + packageName);
+ try {
+ mActivityManager.unbindBackupAgent(currentPackage.applicationInfo);
+ } catch (RemoteException e) { /* can't happen; activity manager is local */ }
+ }
}
} catch (Exception e) {
+ backupRunStatus = BackupManager.ERROR_TRANSPORT_ABORTED;
Slog.w(TAG, "Exception trying full transport backup", e);
} finally {
+ if (DEBUG) {
+ Slog.i(TAG, "Full backup completed with status: " + backupRunStatus);
+ }
+
cleanUpPipes(transportPipes);
cleanUpPipes(enginePipes);
@@ -4230,6 +4494,8 @@
if (mUpdateSchedule) {
scheduleNextFullBackupJob(backoff);
}
+ Slog.i(BackupManagerService.TAG, "Full data backup pass finished.");
+ mWakelock.release();
}
}
@@ -4260,7 +4526,7 @@
// a standalone thread. The runner owns this half of the pipe, and closes
// it to indicate EOD to the other end.
class SinglePackageBackupPreflight implements BackupRestoreTask, FullBackupPreflight {
- final AtomicInteger mResult = new AtomicInteger();
+ final AtomicLong mResult = new AtomicLong(BackupTransport.AGENT_ERROR);
final CountDownLatch mLatch = new CountDownLatch(1);
final IBackupTransport mTransport;
@@ -4280,14 +4546,29 @@
}
agent.doMeasureFullBackup(token, mBackupManagerBinder);
- // now wait to get our result back
- mLatch.await();
- int totalSize = mResult.get();
+ // Now wait to get our result back. If this backstop timeout is reached without
+ // the latch being thrown, flow will continue as though a result or "normal"
+ // timeout had been produced. In case of a real backstop timeout, mResult
+ // will still contain the value it was constructed with, AGENT_ERROR, which
+ // intentionaly falls into the "just report failure" code.
+ mLatch.await(TIMEOUT_FULL_BACKUP_INTERVAL, TimeUnit.MILLISECONDS);
+
+ long totalSize = mResult.get();
+ // If preflight timed out, mResult will contain error code as int.
+ if (totalSize < 0) {
+ return (int) totalSize;
+ }
if (MORE_DEBUG) {
Slog.v(TAG, "Got preflight response; size=" + totalSize);
}
result = mTransport.checkFullBackupSize(totalSize);
+ if (result == BackupTransport.TRANSPORT_QUOTA_EXCEEDED) {
+ if (MORE_DEBUG) {
+ Slog.d(TAG, "Package hit quota limit on preflight " +
+ pkg.packageName + ": " + totalSize);
+ }
+ }
} catch (Exception e) {
Slog.w(TAG, "Exception preflighting " + pkg.packageName + ": " + e.getMessage());
result = BackupTransport.AGENT_ERROR;
@@ -4301,7 +4582,7 @@
}
@Override
- public void operationComplete(int result) {
+ public void operationComplete(long result) {
// got the callback, and our preflightFullBackup() method is waiting for the result
if (MORE_DEBUG) {
Slog.i(TAG, "Preflight op complete, result=" + result);
@@ -4318,34 +4599,57 @@
mResult.set(BackupTransport.AGENT_ERROR);
mLatch.countDown();
}
-
+
+ @Override
+ public long getExpectedSizeOrErrorCode() {
+ try {
+ mLatch.await(TIMEOUT_FULL_BACKUP_INTERVAL, TimeUnit.MILLISECONDS);
+ return mResult.get();
+ } catch (InterruptedException e) {
+ return BackupTransport.NO_MORE_DATA;
+ }
+ }
}
- class SinglePackageBackupRunner implements Runnable {
+ class SinglePackageBackupRunner implements Runnable, BackupRestoreTask {
final ParcelFileDescriptor mOutput;
final PackageInfo mTarget;
final FullBackupPreflight mPreflight;
- final CountDownLatch mLatch;
+ final CountDownLatch mPreflightLatch;
+ final CountDownLatch mBackupLatch;
+ private FullBackupEngine mEngine;
+ private volatile int mPreflightResult;
+ private volatile int mBackupResult;
SinglePackageBackupRunner(ParcelFileDescriptor output, PackageInfo target,
- IBackupTransport transport, CountDownLatch latch) throws IOException {
+ IBackupTransport transport) throws IOException {
mOutput = ParcelFileDescriptor.dup(output.getFileDescriptor());
mTarget = target;
mPreflight = new SinglePackageBackupPreflight(transport);
- mLatch = latch;
+ mPreflightLatch = new CountDownLatch(1);
+ mBackupLatch = new CountDownLatch(1);
+ mPreflightResult = BackupTransport.AGENT_ERROR;
+ mBackupResult = BackupTransport.AGENT_ERROR;
}
@Override
public void run() {
+ FileOutputStream out = new FileOutputStream(mOutput.getFileDescriptor());
+ mEngine = new FullBackupEngine(out, mPreflight, mTarget, false, this);
try {
- FileOutputStream out = new FileOutputStream(mOutput.getFileDescriptor());
- FullBackupEngine engine = new FullBackupEngine(out, mTarget.packageName,
- mPreflight, false);
- engine.backupOnePackage(mTarget);
+ try {
+ mPreflightResult = mEngine.preflightCheck();
+ } finally {
+ mPreflightLatch.countDown();
+ }
+ // If there is no error on preflight, continue backup.
+ if (mPreflightResult == BackupTransport.TRANSPORT_OK) {
+ mBackupResult = mEngine.backupOnePackage();
+ }
} catch (Exception e) {
- Slog.e(TAG, "Exception during full package backup of " + mTarget);
+ Slog.e(TAG, "Exception during full package backup of " + mTarget.packageName);
} finally {
- mLatch.countDown();
+ mBackupLatch.countDown();
try {
mOutput.close();
} catch (IOException e) {
@@ -4353,6 +4657,47 @@
}
}
}
+
+ // If preflight succeeded, returns positive number - preflight size,
+ // otherwise return negative error code.
+ long getPreflightResultBlocking() {
+ try {
+ mPreflightLatch.await(TIMEOUT_FULL_BACKUP_INTERVAL, TimeUnit.MILLISECONDS);
+ if (mPreflightResult == BackupTransport.TRANSPORT_OK) {
+ return mPreflight.getExpectedSizeOrErrorCode();
+ } else {
+ return mPreflightResult;
+ }
+ } catch (InterruptedException e) {
+ return BackupTransport.AGENT_ERROR;
+ }
+ }
+
+ int getBackupResultBlocking() {
+ try {
+ mBackupLatch.await(TIMEOUT_FULL_BACKUP_INTERVAL, TimeUnit.MILLISECONDS);
+ return mBackupResult;
+ } catch (InterruptedException e) {
+ return BackupTransport.AGENT_ERROR;
+ }
+ }
+
+
+ // BackupRestoreTask interface: specifically, timeout detection
+
+ @Override
+ public void execute() { /* intentionally empty */ }
+
+ @Override
+ public void operationComplete(long result) { /* intentionally empty */ }
+
+ @Override
+ public void handleTimeout() {
+ if (DEBUG) {
+ Slog.w(TAG, "Full backup timeout of " + mTarget.packageName);
+ }
+ tearDownAgentAndKill(mTarget.applicationInfo);
+ }
}
}
@@ -4387,21 +4732,28 @@
}
/**
+ * Remove a package from the full-data queue.
+ */
+ void dequeueFullBackupLocked(String packageName) {
+ final int N = mFullBackupQueue.size();
+ for (int i = N-1; i >= 0; i--) {
+ final FullBackupEntry e = mFullBackupQueue.get(i);
+ if (packageName.equals(e.packageName)) {
+ mFullBackupQueue.remove(i);
+ }
+ }
+ }
+
+ /**
* Enqueue full backup for the given app, with a note about when it last ran.
*/
void enqueueFullBackup(String packageName, long lastBackedUp) {
FullBackupEntry newEntry = new FullBackupEntry(packageName, lastBackedUp);
synchronized (mQueueLock) {
- int N = mFullBackupQueue.size();
// First, sanity check that we aren't adding a duplicate. Slow but
// straightforward; we'll have at most on the order of a few hundred
// items in this list.
- for (int i = N-1; i >= 0; i--) {
- final FullBackupEntry e = mFullBackupQueue.get(i);
- if (packageName.equals(e.packageName)) {
- mFullBackupQueue.remove(i);
- }
- }
+ dequeueFullBackupLocked(packageName);
// This is also slow but easy for modest numbers of apps: work backwards
// from the end of the queue until we find an item whose last backup
@@ -4443,7 +4795,7 @@
return false;
}
} catch (Exception e) {
- Slog.w(TAG, "Unable to contact transport");
+ Slog.w(TAG, "Unable to get transport name: " + e.getMessage());
return false;
}
@@ -4495,43 +4847,91 @@
return false;
}
- if (mFullBackupQueue.size() == 0) {
- // no work to do so just bow out
- if (DEBUG) {
- Slog.i(TAG, "Backup queue empty; doing nothing");
- }
- return false;
- }
-
- // At this point we know that we have work to do, just not right now. Any
- // exit without actually running backups will also require that we
+ // At this point we think that we have work to do, but possibly not right now.
+ // Any exit without actually running backups will also require that we
// reschedule the job.
boolean runBackup = true;
+ boolean headBusy;
- if (!fullBackupAllowable(getTransport(mCurrentTransport))) {
- if (MORE_DEBUG) {
- Slog.i(TAG, "Preconditions not met; not running full backup");
- }
- runBackup = false;
- // Typically this means we haven't run a key/value backup yet. Back off
- // full-backup operations by the key/value job's run interval so that
- // next time we run, we are likely to be able to make progress.
- latency = KeyValueBackupJob.BATCH_INTERVAL;
- }
-
- if (runBackup) {
- entry = mFullBackupQueue.get(0);
- long timeSinceRun = now - entry.lastBackup;
- runBackup = (timeSinceRun >= MIN_FULL_BACKUP_INTERVAL);
- if (!runBackup) {
- // It's too early to back up the next thing in the queue, so bow out
- if (MORE_DEBUG) {
- Slog.i(TAG, "Device ready but too early to back up next app");
+ do {
+ // Recheck each time, because culling due to ineligibility may
+ // have emptied the queue.
+ if (mFullBackupQueue.size() == 0) {
+ // no work to do so just bow out
+ if (DEBUG) {
+ Slog.i(TAG, "Backup queue empty; doing nothing");
}
- // Wait until the next app in the queue falls due for a full data backup
- latency = MIN_FULL_BACKUP_INTERVAL - timeSinceRun;
+ runBackup = false;
+ break;
}
- }
+
+ headBusy = false;
+
+ if (!fullBackupAllowable(getTransport(mCurrentTransport))) {
+ if (MORE_DEBUG) {
+ Slog.i(TAG, "Preconditions not met; not running full backup");
+ }
+ runBackup = false;
+ // Typically this means we haven't run a key/value backup yet. Back off
+ // full-backup operations by the key/value job's run interval so that
+ // next time we run, we are likely to be able to make progress.
+ latency = KeyValueBackupJob.BATCH_INTERVAL;
+ }
+
+ if (runBackup) {
+ entry = mFullBackupQueue.get(0);
+ long timeSinceRun = now - entry.lastBackup;
+ runBackup = (timeSinceRun >= MIN_FULL_BACKUP_INTERVAL);
+ if (!runBackup) {
+ // It's too early to back up the next thing in the queue, so bow out
+ if (MORE_DEBUG) {
+ Slog.i(TAG, "Device ready but too early to back up next app");
+ }
+ // Wait until the next app in the queue falls due for a full data backup
+ latency = MIN_FULL_BACKUP_INTERVAL - timeSinceRun;
+ break; // we know we aren't doing work yet, so bail.
+ }
+
+ try {
+ PackageInfo appInfo = mPackageManager.getPackageInfo(entry.packageName, 0);
+ if (!appGetsFullBackup(appInfo)) {
+ // The head app isn't supposed to get full-data backups [any more];
+ // so we cull it and force a loop around to consider the new head
+ // app.
+ if (MORE_DEBUG) {
+ Slog.i(TAG, "Culling package " + entry.packageName
+ + " in full-backup queue but not eligible");
+ }
+ mFullBackupQueue.remove(0);
+ headBusy = true; // force the while() condition
+ continue;
+ }
+
+ if (headBusy) {
+ final long nextEligible = System.currentTimeMillis()
+ + BUSY_BACKOFF_MIN_MILLIS
+ + mTokenGenerator.nextInt(BUSY_BACKOFF_FUZZ);
+ if (DEBUG_SCHEDULING) {
+ SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+ Slog.i(TAG, "Full backup time but " + entry.packageName
+ + " is busy; deferring to "
+ + sdf.format(new Date(nextEligible)));
+ }
+ // This relocates the app's entry from the head of the queue to
+ // its order-appropriate position further down, so upon looping
+ // a new candidate will be considered at the head.
+ enqueueFullBackup(entry.packageName,
+ nextEligible - MIN_FULL_BACKUP_INTERVAL);
+ }
+ } catch (NameNotFoundException nnf) {
+ // So, we think we want to back this up, but it turns out the package
+ // in question is no longer installed. We want to drop it from the
+ // queue entirely and move on, but if there's nothing else in the queue
+ // we should bail entirely. headBusy cannot have been set to true yet.
+ runBackup = (mFullBackupQueue.size() > 1);
+ }
+ }
+ } while (headBusy);
if (!runBackup) {
if (DEBUG_SCHEDULING) {
@@ -4546,12 +4946,14 @@
return false;
}
- // Okay, the top thing is runnable now. Pop it off and get going.
+ // Okay, the top thing is ready for backup now. Do it.
mFullBackupQueue.remove(0);
CountDownLatch latch = new CountDownLatch(1);
String[] pkg = new String[] {entry.packageName};
mRunningFullBackupTask = new PerformFullTransportBackupTask(null, pkg, true,
scheduledJob, latch);
+ // Acquiring wakelock for PerformFullTransportBackupTask before its start.
+ mWakelock.acquire();
(new Thread(mRunningFullBackupTask)).start();
}
@@ -4650,6 +5052,9 @@
// Full restore engine, used by both adb restore and transport-based full restore
class FullRestoreEngine extends RestoreEngine {
+ // Task in charge of monitoring timeouts
+ BackupRestoreTask mMonitorTask;
+
// Dedicated observer, if any
IFullBackupRestoreObserver mObserver;
@@ -4698,7 +5103,7 @@
byte[] mWidgetData = null;
// Runner that can be placed in a separate thread to do in-process
- // invocations of the full restore API asynchronously
+ // invocations of the full restore API asynchronously. Used by adb restore.
class RestoreFileRunnable implements Runnable {
IBackupAgent mAgent;
FileMetadata mInfo;
@@ -4731,8 +5136,9 @@
}
}
- public FullRestoreEngine(IFullBackupRestoreObserver observer, PackageInfo onlyPackage,
- boolean allowApks, boolean allowObbs) {
+ public FullRestoreEngine(BackupRestoreTask monitorTask, IFullBackupRestoreObserver observer,
+ PackageInfo onlyPackage, boolean allowApks, boolean allowObbs) {
+ mMonitorTask = monitorTask;
mObserver = observer;
mOnlyPackage = onlyPackage;
mAllowApks = allowApks;
@@ -4745,6 +5151,10 @@
return mAgent;
}
+ public byte[] getWidgetData() {
+ return mWidgetData;
+ }
+
public boolean restoreOneFile(InputStream instream, boolean mustKillAgent) {
if (!isRunning()) {
Slog.w(TAG, "Restore engine used after halting");
@@ -4869,11 +5279,11 @@
// If the policy is satisfied, go ahead and set up to pipe the
// data to the agent.
- if (DEBUG && okay && mAgent != null) {
+ if (MORE_DEBUG && okay && mAgent != null) {
Slog.i(TAG, "Reusing existing agent instance");
}
if (okay && mAgent == null) {
- if (DEBUG) Slog.d(TAG, "Need to launch agent for " + pkg);
+ if (MORE_DEBUG) Slog.d(TAG, "Need to launch agent for " + pkg);
try {
mTargetApp = mPackageManager.getApplicationInfo(pkg, 0);
@@ -4934,7 +5344,9 @@
long toCopy = info.size;
final int token = generateToken();
try {
- prepareOperationTimeout(token, TIMEOUT_FULL_BACKUP_INTERVAL, null);
+ prepareOperationTimeout(token, TIMEOUT_FULL_BACKUP_INTERVAL,
+ mMonitorTask);
+
if (info.domain.equals(FullBackup.OBB_TREE_TOKEN)) {
if (DEBUG) Slog.d(TAG, "Restoring OBB file for " + pkg
+ " : " + info.path);
@@ -4995,7 +5407,8 @@
try {
pipe.write(mBuffer, 0, nRead);
} catch (IOException e) {
- Slog.e(TAG, "Failed to write to restore pipe", e);
+ Slog.e(TAG, "Failed to write to restore pipe: "
+ + e.getMessage());
pipeOkay = false;
}
}
@@ -5048,7 +5461,7 @@
}
}
} catch (IOException e) {
- if (DEBUG) Slog.w(TAG, "io exception on restore socket read", e);
+ if (DEBUG) Slog.w(TAG, "io exception on restore socket read: " + e.getMessage());
setResult(RestoreEngine.TRANSPORT_FAILURE);
info = null;
}
@@ -5072,16 +5485,21 @@
}
void tearDownPipes() {
- if (mPipes != null) {
- try {
- mPipes[0].close();
- mPipes[0] = null;
- mPipes[1].close();
- mPipes[1] = null;
- } catch (IOException e) {
- Slog.w(TAG, "Couldn't close agent pipes", e);
+ // Teardown might arise from the inline restore processing or from the asynchronous
+ // timeout mechanism, and these might race. Make sure we don't try to close and
+ // null out the pipes twice.
+ synchronized (this) {
+ if (mPipes != null) {
+ try {
+ mPipes[0].close();
+ mPipes[0] = null;
+ mPipes[1].close();
+ mPipes[1] = null;
+ } catch (IOException e) {
+ Slog.w(TAG, "Couldn't close agent pipes", e);
+ }
+ mPipes = null;
}
- mPipes = null;
}
}
@@ -5092,6 +5510,12 @@
}
}
+ void handleTimeout() {
+ tearDownPipes();
+ setResult(RestoreEngine.TARGET_FAILURE);
+ setRunning(false);
+ }
+
class RestoreInstallObserver extends PackageInstallObserver {
final AtomicBoolean mDone = new AtomicBoolean();
String mPackageName;
@@ -5833,6 +6257,46 @@
// ***** end new engine class ***
+ // Used for synchronizing doRestoreFinished during adb restore
+ class AdbRestoreFinishedLatch implements BackupRestoreTask {
+ static final String TAG = "AdbRestoreFinishedLatch";
+ final CountDownLatch mLatch;
+
+ AdbRestoreFinishedLatch() {
+ mLatch = new CountDownLatch(1);
+ }
+
+ void await() {
+ boolean latched = false;
+ try {
+ latched = mLatch.await(TIMEOUT_FULL_BACKUP_INTERVAL, TimeUnit.MILLISECONDS);
+ } catch (InterruptedException e) {
+ Slog.w(TAG, "Interrupted!");
+ }
+ }
+
+ @Override
+ public void execute() {
+ // Unused
+ }
+
+ @Override
+ public void operationComplete(long result) {
+ if (MORE_DEBUG) {
+ Slog.w(TAG, "adb onRestoreFinished() complete");
+ }
+ mLatch.countDown();
+ }
+
+ @Override
+ public void handleTimeout() {
+ if (DEBUG) {
+ Slog.w(TAG, "adb onRestoreFinished() timed out");
+ }
+ mLatch.countDown();
+ }
+ }
+
class PerformAdbRestoreTask implements Runnable {
ParcelFileDescriptor mInputFile;
String mCurrentPassword;
@@ -5848,6 +6312,27 @@
long mBytes;
+ // Runner that can be placed on a separate thread to do in-process invocation
+ // of the "restore finished" API asynchronously. Used by adb restore.
+ class RestoreFinishedRunnable implements Runnable {
+ final IBackupAgent mAgent;
+ final int mToken;
+
+ RestoreFinishedRunnable(IBackupAgent agent, int token) {
+ mAgent = agent;
+ mToken = token;
+ }
+
+ @Override
+ public void run() {
+ try {
+ mAgent.doRestoreFinished(mToken, mBackupManagerBinder);
+ } catch (RemoteException e) {
+ // never happens; this is used only for local binder calls
+ }
+ }
+ }
+
// possible handling states for a given package in the restore dataset
final HashMap<String, RestorePolicy> mPackagePolicies
= new HashMap<String, RestorePolicy>();
@@ -5989,7 +6474,7 @@
Slog.e(TAG, "Unable to read restore input");
} finally {
tearDownPipes();
- tearDownAgent(mTargetApp);
+ tearDownAgent(mTargetApp, true);
try {
if (rawDataIn != null) rawDataIn.close();
@@ -6143,7 +6628,7 @@
if (DEBUG) Slog.d(TAG, "Saw new package; finalizing old one");
// Now we're really done
tearDownPipes();
- tearDownAgent(mTargetApp);
+ tearDownAgent(mTargetApp, true);
mTargetApp = null;
mAgentPackage = null;
}
@@ -6365,10 +6850,12 @@
// okay, if the remote end failed at any point, deal with
// it by ignoring the rest of the restore on it
if (!agentSuccess) {
+ if (DEBUG) {
+ Slog.d(TAG, "Agent failure restoring " + pkg + "; now ignoring");
+ }
mBackupHandler.removeMessages(MSG_TIMEOUT);
tearDownPipes();
- tearDownAgent(mTargetApp);
- mAgent = null;
+ tearDownAgent(mTargetApp, false);
mPackagePolicies.put(pkg, RestorePolicy.IGNORE);
}
}
@@ -6417,16 +6904,34 @@
}
}
- void tearDownAgent(ApplicationInfo app) {
+ void tearDownAgent(ApplicationInfo app, boolean doRestoreFinished) {
if (mAgent != null) {
try {
+ // In the adb restore case, we do restore-finished here
+ if (doRestoreFinished) {
+ final int token = generateToken();
+ final AdbRestoreFinishedLatch latch = new AdbRestoreFinishedLatch();
+ prepareOperationTimeout(token, TIMEOUT_FULL_BACKUP_INTERVAL, latch);
+ if (mTargetApp.processName.equals("system")) {
+ if (MORE_DEBUG) {
+ Slog.d(TAG, "system agent - restoreFinished on thread");
+ }
+ Runnable runner = new RestoreFinishedRunnable(mAgent, token);
+ new Thread(runner, "restore-sys-finished-runner").start();
+ } else {
+ mAgent.doRestoreFinished(token, mBackupManagerBinder);
+ }
+
+ latch.await();
+ }
+
// unbind and tidy up even on timeout or failure, just in case
mActivityManager.unbindBackupAgent(app);
// The agent was running with a stub Application object, so shut it down.
// !!! We hardcode the confirmation UI's package name here rather than use a
// manifest flag! TODO something less direct.
- if (app.uid != Process.SYSTEM_UID
+ if (app.uid >= Process.FIRST_APPLICATION_UID
&& !app.packageName.equals("com.android.backupconfirm")) {
if (DEBUG) Slog.d(TAG, "Killing host process");
mActivityManager.killApplicationProcess(app.processName, app.uid);
@@ -7246,6 +7751,10 @@
// Used by both incremental and full restore
void restoreWidgetData(String packageName, byte[] widgetData) {
// Apply the restored widget state and generate the ID update for the app
+ // TODO: http://b/22388012
+ if (MORE_DEBUG) {
+ Slog.i(TAG, "Incorporating restored widget data");
+ }
AppWidgetBackupBridge.restoreWidgetState(packageName, widgetData, UserHandle.USER_OWNER);
}
@@ -7281,6 +7790,11 @@
// when we're finished.
private int mPmToken;
+ // When this is restore-during-install, we need to tell the package manager
+ // whether we actually launched the app, because this affects notifications
+ // around externally-visible state transitions.
+ private boolean mDidLaunch;
+
// Is this a whole-system restore, i.e. are we establishing a new ancestral
// dataset to base future restore-at-install operations from?
private boolean mIsSystemRestore;
@@ -7344,6 +7858,7 @@
mTargetPackage = targetPackage;
mIsSystemRestore = isFullSystemRestore;
mFinished = false;
+ mDidLaunch = false;
if (targetPackage != null) {
// Single package restore
@@ -7503,6 +8018,7 @@
// If we're starting a full-system restore, set up to begin widget ID remapping
if (mIsSystemRestore) {
+ // TODO: http://b/22388012
AppWidgetBackupBridge.restoreStarting(UserHandle.USER_OWNER);
}
@@ -7573,9 +8089,9 @@
// Success; cache the metadata and continue as expected with the
// next state already enqueued
- } catch (RemoteException e) {
+ } catch (Exception e) {
// If we lost the transport at any time, halt
- Slog.e(TAG, "Unable to contact transport for restore");
+ Slog.e(TAG, "Unable to contact transport for restore: " + e.getMessage());
mStatus = BackupTransport.TRANSPORT_ERROR;
mBackupHandler.removeMessages(MSG_BACKUP_RESTORE_STEP, this);
executeNextState(UnifiedRestoreState.FINAL);
@@ -7672,8 +8188,9 @@
nextState = UnifiedRestoreState.RUNNING_QUEUE;
return;
}
- } catch (RemoteException e) {
- Slog.e(TAG, "Can't get next target from transport; ending restore");
+ } catch (Exception e) {
+ Slog.e(TAG, "Can't get next restore target from transport; halting: "
+ + e.getMessage());
EventLog.writeEvent(EventLogTags.RESTORE_TRANSPORT_FAILURE);
nextState = UnifiedRestoreState.FINAL;
return;
@@ -7723,6 +8240,9 @@
return;
}
+ // Whatever happens next, we've launched the target app now; remember that.
+ mDidLaunch = true;
+
// And then finally start the restore on this agent
try {
initiateOneRestore(mCurrentPackage, metaInfo.versionCode);
@@ -7762,10 +8282,6 @@
ParcelFileDescriptor.MODE_CREATE |
ParcelFileDescriptor.MODE_TRUNCATE);
- if (!SELinux.restorecon(mBackupDataName)) {
- if (MORE_DEBUG) Slog.e(TAG, "SElinux restorecon failed for " + downloadFile);
- }
-
if (mTransport.getRestoreData(stage) != BackupTransport.TRANSPORT_OK) {
// Transport-level failure, so we wind everything up and
// terminate the restore operation.
@@ -7819,6 +8335,7 @@
// Okay, we have the data. Now have the agent do the restore.
stage.close();
+
mBackupData = ParcelFileDescriptor.open(mBackupDataName,
ParcelFileDescriptor.MODE_READ_ONLY);
@@ -7894,9 +8411,10 @@
}
}
- class StreamFeederThread extends RestoreEngine implements Runnable {
+ class StreamFeederThread extends RestoreEngine implements Runnable, BackupRestoreTask {
final String TAG = "StreamFeederThread";
FullRestoreEngine mEngine;
+ EngineThread mEngineThread;
// pipe through which we read data from the transport. [0] read, [1] write
ParcelFileDescriptor[] mTransportPipes;
@@ -7918,8 +8436,8 @@
EventLog.writeEvent(EventLogTags.FULL_RESTORE_PACKAGE,
mCurrentPackage.packageName);
- mEngine = new FullRestoreEngine(null, mCurrentPackage, false, false);
- EngineThread eThread = new EngineThread(mEngine, mEnginePipes[0]);
+ mEngine = new FullRestoreEngine(this, null, mCurrentPackage, false, false);
+ mEngineThread = new EngineThread(mEngine, mEnginePipes[0]);
ParcelFileDescriptor eWriteEnd = mEnginePipes[1];
ParcelFileDescriptor tReadEnd = mTransportPipes[0];
@@ -7931,7 +8449,7 @@
FileInputStream transportIn = new FileInputStream(tReadEnd.getFileDescriptor());
// spin up the engine and start moving data to it
- new Thread(eThread, "unified-restore-engine").start();
+ new Thread(mEngineThread, "unified-restore-engine").start();
try {
while (status == BackupTransport.TRANSPORT_OK) {
@@ -7982,11 +8500,11 @@
EventLog.writeEvent(EventLogTags.RESTORE_AGENT_FAILURE,
mCurrentPackage.packageName, "I/O error on pipes");
status = BackupTransport.AGENT_ERROR;
- } catch (RemoteException e) {
- // The transport went away; terminate the whole operation. Closing
+ } catch (Exception e) {
+ // The transport threw; terminate the whole operation. Closing
// the sockets will wake up the engine and it will then tidy up the
// remote end.
- Slog.e(TAG, "Transport failed during restore");
+ Slog.e(TAG, "Transport failed during restore: " + e.getMessage());
EventLog.writeEvent(EventLogTags.RESTORE_TRANSPORT_FAILURE);
status = BackupTransport.TRANSPORT_ERROR;
} finally {
@@ -7997,16 +8515,16 @@
IoUtils.closeQuietly(mTransportPipes[0]);
IoUtils.closeQuietly(mTransportPipes[1]);
- // Don't proceed until the engine has finished
- eThread.waitForResult();
-
- if (MORE_DEBUG) {
- Slog.i(TAG, "engine thread finished; proceeding");
- }
+ // Don't proceed until the engine has wound up operations
+ mEngineThread.waitForResult();
// Now we're really done with this one too
IoUtils.closeQuietly(mEnginePipes[0]);
+ // In all cases we want to remember whether we launched
+ // the target app as part of our work so far.
+ mDidLaunch = (mEngine.getAgent() != null);
+
// If we hit a transport-level error, we are done with everything;
// if we hit an agent error we just go back to running the queue.
if (status == BackupTransport.TRANSPORT_OK) {
@@ -8016,14 +8534,18 @@
// the engine bound the target's agent, so recover that binding
// to use for the callback.
mAgent = mEngine.getAgent();
+
+ // and the restored widget data, if any
+ mWidgetData = mEngine.getWidgetData();
} else {
// Something went wrong somewhere. Whether it was at the transport
// level is immaterial; we need to tell the transport to bail
try {
mTransport.abortFullRestore();
- } catch (RemoteException e) {
+ } catch (Exception e) {
// transport itself is dead; make sure we handle this as a
// fatal error
+ Slog.e(TAG, "Transport threw from abortFullRestore: " + e.getMessage());
status = BackupTransport.TRANSPORT_ERROR;
}
@@ -8043,14 +8565,37 @@
}
}
+ // BackupRestoreTask interface, specifically for timeout handling
+
+ @Override
+ public void execute() { /* intentionally empty */ }
+
+ @Override
+ public void operationComplete(long result) { /* intentionally empty */ }
+
+ // The app has timed out handling a restoring file
+ @Override
+ public void handleTimeout() {
+ if (DEBUG) {
+ Slog.w(TAG, "Full-data restore target timed out; shutting down");
+ }
+ mEngineThread.handleTimeout();
+
+ IoUtils.closeQuietly(mEnginePipes[1]);
+ mEnginePipes[1] = null;
+ IoUtils.closeQuietly(mEnginePipes[0]);
+ mEnginePipes[0] = null;
+ }
}
class EngineThread implements Runnable {
FullRestoreEngine mEngine;
+ ParcelFileDescriptor mEngineSocket;
FileInputStream mEngineStream;
EngineThread(FullRestoreEngine engine, ParcelFileDescriptor engineSocket) {
mEngine = engine;
+ mEngineSocket = engineSocket;
engine.setRunning(true);
mEngineStream = new FileInputStream(engineSocket.getFileDescriptor());
}
@@ -8065,11 +8610,22 @@
@Override
public void run() {
- while (mEngine.isRunning()) {
- // Tell it to be sure to leave the agent instance up after finishing
- mEngine.restoreOneFile(mEngineStream, false);
+ try {
+ while (mEngine.isRunning()) {
+ // Tell it to be sure to leave the agent instance up after finishing
+ mEngine.restoreOneFile(mEngineStream, false);
+ }
+ } finally {
+ IoUtils.closeQuietly(mEngineStream);
+ IoUtils.closeQuietly(mEngineSocket);
}
}
+
+ public void handleTimeout() {
+ IoUtils.closeQuietly(mEngineStream);
+ IoUtils.closeQuietly(mEngineSocket);
+ mEngine.handleTimeout();
+ }
}
// state FINAL : tear everything down and we're done.
@@ -8109,6 +8665,7 @@
}
// Kick off any work that may be needed regarding app widget restores
+ // TODO: http://b/22388012
AppWidgetBackupBridge.restoreFinished(UserHandle.USER_OWNER);
// If this was a full-system restore, record the ancestral
@@ -8170,13 +8727,15 @@
// it is explicitly not killed following that operation.
//
// We execute this kill when these conditions hold:
- // 1. the app did not request its own restore (mTargetPackage == null), and either
- // 2a. the app is a full-data target (TYPE_FULL_STREAM) or
+ // 1. it's not a system-uid process,
+ // 2. the app did not request its own restore (mTargetPackage == null), and either
+ // 3a. the app is a full-data target (TYPE_FULL_STREAM) or
// b. the app does not state android:killAfterRestore="false" in its manifest
final int appFlags = mCurrentPackage.applicationInfo.flags;
final boolean killAfterRestore =
- (mRestoreDescription.getDataType() == RestoreDescription.TYPE_FULL_STREAM)
- || ((appFlags & ApplicationInfo.FLAG_KILL_AFTER_RESTORE) != 0);
+ (mCurrentPackage.applicationInfo.uid >= Process.FIRST_APPLICATION_UID)
+ && ((mRestoreDescription.getDataType() == RestoreDescription.TYPE_FULL_STREAM)
+ || ((appFlags & ApplicationInfo.FLAG_KILL_AFTER_RESTORE) != 0));
if (mTargetPackage == null && killAfterRestore) {
if (DEBUG) Slog.d(TAG, "Restore complete, killing host process of "
@@ -8199,7 +8758,7 @@
}
@Override
- public void operationComplete(int unusedResult) {
+ public void operationComplete(long unusedResult) {
if (MORE_DEBUG) {
Slog.i(TAG, "operationComplete() during restore: target="
+ mCurrentPackage.packageName
@@ -8333,16 +8892,15 @@
// Tell the transport to remove all the persistent storage for the app
// TODO - need to handle failures
mTransport.clearBackupData(mPackage);
- } catch (RemoteException e) {
- // can't happen; the transport is local
} catch (Exception e) {
- Slog.e(TAG, "Transport threw attempting to clear data for " + mPackage);
+ Slog.e(TAG, "Transport threw clearing data for " + mPackage + ": " + e.getMessage());
} finally {
try {
// TODO - need to handle failures
mTransport.finishBackup();
- } catch (RemoteException e) {
- // can't happen; the transport is local
+ } catch (Exception e) {
+ // Nothing we can do here, alas
+ Slog.e(TAG, "Unable to mark clear operation finished: " + e.getMessage());
}
// Last but not least, release the cpu
@@ -8401,8 +8959,6 @@
System.currentTimeMillis() + delay, mRunInitIntent);
}
}
- } catch (RemoteException e) {
- // can't happen; the transports are local
} catch (Exception e) {
Slog.e(TAG, "Unexpected error performing init", e);
} finally {
@@ -8497,9 +9053,11 @@
public void dataChanged(final String packageName) {
final int callingUserHandle = UserHandle.getCallingUserId();
if (callingUserHandle != UserHandle.USER_OWNER) {
+ // TODO: http://b/22388012
// App is running under a non-owner user profile. For now, we do not back
// up data from secondary user profiles.
- // TODO: backups for all user profiles.
+ // TODO: backups for all user profiles although don't add backup for profiles
+ // without adding admin control in DevicePolicyManager.
if (MORE_DEBUG) {
Slog.v(TAG, "dataChanged(" + packageName + ") ignored because it's user "
+ callingUserHandle);
@@ -8618,6 +9176,7 @@
mContext.enforceCallingPermission(android.Manifest.permission.BACKUP, "fullBackup");
final int callingUserHandle = UserHandle.getCallingUserId();
+ // TODO: http://b/22388012
if (callingUserHandle != UserHandle.USER_OWNER) {
throw new IllegalStateException("Backup supported only for the device owner");
}
@@ -8690,6 +9249,7 @@
"fullTransportBackup");
final int callingUserHandle = UserHandle.getCallingUserId();
+ // TODO: http://b/22388012
if (callingUserHandle != UserHandle.USER_OWNER) {
throw new IllegalStateException("Restore supported only for the device owner");
}
@@ -8701,23 +9261,30 @@
Slog.d(TAG, "fullTransportBackup()");
}
- CountDownLatch latch = new CountDownLatch(1);
- PerformFullTransportBackupTask task =
- new PerformFullTransportBackupTask(null, pkgNames, false, null, latch);
- (new Thread(task, "full-transport-master")).start();
- do {
- try {
- latch.await();
- break;
- } catch (InterruptedException e) {
- // Just go back to waiting for the latch to indicate completion
- }
- } while (true);
+ final long oldId = Binder.clearCallingIdentity();
+ try {
+ CountDownLatch latch = new CountDownLatch(1);
+ PerformFullTransportBackupTask task = new PerformFullTransportBackupTask(null,
+ pkgNames, false, null, latch);
+ // Acquiring wakelock for PerformFullTransportBackupTask before its start.
+ mWakelock.acquire();
+ (new Thread(task, "full-transport-master")).start();
+ do {
+ try {
+ latch.await();
+ break;
+ } catch (InterruptedException e) {
+ // Just go back to waiting for the latch to indicate completion
+ }
+ } while (true);
- // We just ran a backup on these packages, so kick them to the end of the queue
- final long now = System.currentTimeMillis();
- for (String pkg : pkgNames) {
- enqueueFullBackup(pkg, now);
+ // We just ran a backup on these packages, so kick them to the end of the queue
+ final long now = System.currentTimeMillis();
+ for (String pkg : pkgNames) {
+ enqueueFullBackup(pkg, now);
+ }
+ } finally {
+ Binder.restoreCallingIdentity(oldId);
}
}
@@ -8730,6 +9297,7 @@
mContext.enforceCallingPermission(android.Manifest.permission.BACKUP, "fullRestore");
final int callingUserHandle = UserHandle.getCallingUserId();
+ // TODO: http://b/22388012
if (callingUserHandle != UserHandle.USER_OWNER) {
throw new IllegalStateException("Restore supported only for the device owner");
}
@@ -8789,7 +9357,7 @@
"com.android.backupconfirm.BackupRestoreConfirmation");
confIntent.putExtra(FullBackup.CONF_TOKEN_INTENT_EXTRA, token);
confIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- mContext.startActivity(confIntent);
+ mContext.startActivityAsUser(confIntent, UserHandle.OWNER);
} catch (ActivityNotFoundException e) {
return false;
}
@@ -9018,8 +9586,9 @@
if (MORE_DEBUG) Slog.d(TAG, "getConfigurationIntent() returning config intent "
+ intent);
return intent;
- } catch (RemoteException e) {
+ } catch (Exception e) {
/* fall through to return null */
+ Slog.e(TAG, "Unable to get configuration intent from transport: " + e.getMessage());
}
}
}
@@ -9043,8 +9612,9 @@
final String text = transport.currentDestinationString();
if (MORE_DEBUG) Slog.d(TAG, "getDestinationString() returning " + text);
return text;
- } catch (RemoteException e) {
+ } catch (Exception e) {
/* fall through to return null */
+ Slog.e(TAG, "Unable to get string from transport: " + e.getMessage());
}
}
}
@@ -9065,8 +9635,9 @@
if (MORE_DEBUG) Slog.d(TAG, "getDataManagementIntent() returning intent "
+ intent);
return intent;
- } catch (RemoteException e) {
+ } catch (Exception e) {
/* fall through to return null */
+ Slog.e(TAG, "Unable to get management intent from transport: " + e.getMessage());
}
}
}
@@ -9087,8 +9658,9 @@
final String text = transport.dataManagementLabel();
if (MORE_DEBUG) Slog.d(TAG, "getDataManagementLabel() returning " + text);
return text;
- } catch (RemoteException e) {
+ } catch (Exception e) {
/* fall through to return null */
+ Slog.e(TAG, "Unable to get management label from transport: " + e.getMessage());
}
}
}
@@ -9181,9 +9753,9 @@
msg.obj = new RestoreParams(transport, dirName, null,
restoreSet, packageName, token);
mBackupHandler.sendMessage(msg);
- } catch (RemoteException e) {
- // Binding to the transport broke; back off and proceed with the installation.
- Slog.e(TAG, "Unable to contact transport");
+ } catch (Exception e) {
+ // Calling into the transport broke; back off and proceed with the installation.
+ Slog.e(TAG, "Unable to contact transport: " + e.getMessage());
skip = true;
}
}
@@ -9234,7 +9806,11 @@
synchronized(this) {
if (mActiveRestoreSession != null) {
- Slog.d(TAG, "Restore session requested but one already active");
+ Slog.i(TAG, "Restore session requested but one already active");
+ return null;
+ }
+ if (mBackupRunning) {
+ Slog.i(TAG, "Restore session requested but currently running backups");
return null;
}
mActiveRestoreSession = new ActiveRestoreSession(packageName, transport);
@@ -9265,20 +9841,42 @@
synchronized (mCurrentOpLock) {
op = mCurrentOperations.get(token);
if (op != null) {
- op.state = OP_ACKNOWLEDGED;
+ if (op.state == OP_TIMEOUT) {
+ // The operation already timed out, and this is a late response. Tidy up
+ // and ignore it; we've already dealt with the timeout.
+ op = null;
+ mCurrentOperations.delete(token);
+ } else {
+ op.state = OP_ACKNOWLEDGED;
+ }
}
mCurrentOpLock.notifyAll();
}
// The completion callback, if any, is invoked on the handler
if (op != null && op.callback != null) {
- Message msg = mBackupHandler.obtainMessage(MSG_OP_COMPLETE, op.callback);
- // NB: this cannot distinguish between results > 2 gig
- msg.arg1 = (result > Integer.MAX_VALUE) ? Integer.MAX_VALUE : (int) result;
+ Pair<BackupRestoreTask, Long> callbackAndResult = Pair.create(op.callback, result);
+ Message msg = mBackupHandler.obtainMessage(MSG_OP_COMPLETE, callbackAndResult);
mBackupHandler.sendMessage(msg);
}
}
+ public boolean isAppEligibleForBackup(String packageName) {
+ mContext.enforceCallingOrSelfPermission(android.Manifest.permission.BACKUP,
+ "isAppEligibleForBackup");
+ try {
+ PackageInfo packageInfo = mPackageManager.getPackageInfo(packageName,
+ PackageManager.GET_SIGNATURES);
+ if (!appIsEligibleForBackup(packageInfo.applicationInfo) ||
+ appIsStopped(packageInfo.applicationInfo)) {
+ return false;
+ }
+ return true;
+ } catch (NameNotFoundException e) {
+ return false;
+ }
+ }
+
// ----- Restore session -----
class ActiveRestoreSession extends IRestoreSession.Stub {
@@ -9371,9 +9969,9 @@
String dirName;
try {
dirName = mRestoreTransport.transportDirName();
- } catch (RemoteException e) {
+ } catch (Exception e) {
// Transport went AWOL; fail.
- Slog.e(TAG, "Unable to contact transport for restore");
+ Slog.e(TAG, "Unable to get transport dir for restore: " + e.getMessage());
return -1;
}
@@ -9453,9 +10051,9 @@
String dirName;
try {
dirName = mRestoreTransport.transportDirName();
- } catch (RemoteException e) {
+ } catch (Exception e) {
// Transport went AWOL; fail.
- Slog.e(TAG, "Unable to contact transport for restore");
+ Slog.e(TAG, "Unable to get transport name for restoreSome: " + e.getMessage());
return -1;
}
@@ -9543,9 +10141,9 @@
String dirName;
try {
dirName = mRestoreTransport.transportDirName();
- } catch (RemoteException e) {
+ } catch (Exception e) {
// Transport went AWOL; fail.
- Slog.e(TAG, "Unable to contact transport for restore");
+ Slog.e(TAG, "Unable to get transport dir for restorePackage: " + e.getMessage());
return -1;
}
diff --git a/services/core/Android.mk b/services/core/Android.mk
index 64b6134..666f2ff 100644
--- a/services/core/Android.mk
+++ b/services/core/Android.mk
@@ -9,7 +9,7 @@
java/com/android/server/EventLogTags.logtags \
java/com/android/server/am/EventLogTags.logtags
-LOCAL_JAVA_LIBRARIES := telephony-common
+LOCAL_JAVA_LIBRARIES := services.net telephony-common
LOCAL_STATIC_JAVA_LIBRARIES := tzdata_update
include $(BUILD_STATIC_JAVA_LIBRARY)
diff --git a/services/core/java/com/android/server/AlarmManagerService.java b/services/core/java/com/android/server/AlarmManagerService.java
index e3d5d38..130a234 100644
--- a/services/core/java/com/android/server/AlarmManagerService.java
+++ b/services/core/java/com/android/server/AlarmManagerService.java
@@ -178,7 +178,7 @@
private static final long DEFAULT_MIN_FUTURITY = 5 * 1000;
private static final long DEFAULT_MIN_INTERVAL = 60 * 1000;
private static final long DEFAULT_ALLOW_WHILE_IDLE_SHORT_TIME = DEFAULT_MIN_FUTURITY;
- private static final long DEFAULT_ALLOW_WHILE_IDLE_LONG_TIME = 15*60*1000;
+ private static final long DEFAULT_ALLOW_WHILE_IDLE_LONG_TIME = 9*60*1000;
private static final long DEFAULT_ALLOW_WHILE_IDLE_WHITELIST_DURATION = 10*1000;
// Minimum futurity of a new alarm
@@ -971,8 +971,8 @@
// This is a special alarm that will put the system into idle until it goes off.
// The caller has given the time they want this to happen at, however we need
// to pull that earlier if there are existing alarms that have requested to
- // bring us out of idle.
- if (mNextWakeFromIdle != null) {
+ // bring us out of idle at an earlier time.
+ if (mNextWakeFromIdle != null && a.whenElapsed > mNextWakeFromIdle.whenElapsed) {
a.when = a.whenElapsed = a.maxWhenElapsed = mNextWakeFromIdle.whenElapsed;
}
// Add fuzz to make the alarm go off some time before the actual desired time.
@@ -1256,7 +1256,7 @@
pw.print(" Idling until: ");
if (mPendingIdleUntil != null) {
pw.println(mPendingIdleUntil);
- mPendingIdleUntil.dump(pw, " ", nowRTC, nowELAPSED, sdf);
+ mPendingIdleUntil.dump(pw, " ", nowRTC, nowELAPSED, sdf);
} else {
pw.println("null");
}
diff --git a/services/core/java/com/android/server/AppOpsService.java b/services/core/java/com/android/server/AppOpsService.java
index c373fb8..96c1e2a 100644
--- a/services/core/java/com/android/server/AppOpsService.java
+++ b/services/core/java/com/android/server/AppOpsService.java
@@ -39,7 +39,6 @@
import android.content.pm.ApplicationInfo;
import android.content.pm.IPackageManager;
import android.content.pm.PackageManager;
-import android.content.pm.PackageManager.NameNotFoundException;
import android.media.AudioAttributes;
import android.os.AsyncTask;
import android.os.Binder;
@@ -263,12 +262,12 @@
Iterator<Ops> it = pkgs.values().iterator();
while (it.hasNext()) {
Ops ops = it.next();
- int curUid;
+ int curUid = -1;
try {
- curUid = mContext.getPackageManager().getPackageUid(ops.packageName,
+ curUid = AppGlobals.getPackageManager().getPackageUidEtc(ops.packageName,
+ PackageManager.GET_UNINSTALLED_PACKAGES,
UserHandle.getUserId(ops.uidState.uid));
- } catch (NameNotFoundException e) {
- curUid = -1;
+ } catch (RemoteException ignored) {
}
if (curUid != ops.uidState.uid) {
Slog.i(TAG, "Pruning old package " + ops.packageName
diff --git a/services/core/java/com/android/server/BatteryService.java b/services/core/java/com/android/server/BatteryService.java
index b3b4651..2eeaec9 100644
--- a/services/core/java/com/android/server/BatteryService.java
+++ b/services/core/java/com/android/server/BatteryService.java
@@ -120,6 +120,7 @@
private int mLastBatteryVoltage;
private int mLastBatteryTemperature;
private boolean mLastBatteryLevelCritical;
+ private int mLastMaxChargingCurrent;
private int mInvalidCharger;
private int mLastInvalidCharger;
@@ -323,6 +324,7 @@
+ "chargerAcOnline=" + mBatteryProps.chargerAcOnline
+ ", chargerUsbOnline=" + mBatteryProps.chargerUsbOnline
+ ", chargerWirelessOnline=" + mBatteryProps.chargerWirelessOnline
+ + ", maxChargingCurrent" + mBatteryProps.maxChargingCurrent
+ ", batteryStatus=" + mBatteryProps.batteryStatus
+ ", batteryHealth=" + mBatteryProps.batteryHealth
+ ", batteryPresent=" + mBatteryProps.batteryPresent
@@ -353,6 +355,7 @@
mPlugType != mLastPlugType ||
mBatteryProps.batteryVoltage != mLastBatteryVoltage ||
mBatteryProps.batteryTemperature != mLastBatteryTemperature ||
+ mBatteryProps.maxChargingCurrent != mLastMaxChargingCurrent ||
mInvalidCharger != mLastInvalidCharger)) {
if (mPlugType != mLastPlugType) {
@@ -479,6 +482,7 @@
mLastPlugType = mPlugType;
mLastBatteryVoltage = mBatteryProps.batteryVoltage;
mLastBatteryTemperature = mBatteryProps.batteryTemperature;
+ mLastMaxChargingCurrent = mBatteryProps.maxChargingCurrent;
mLastBatteryLevelCritical = mBatteryLevelCritical;
mLastInvalidCharger = mInvalidCharger;
}
@@ -503,17 +507,21 @@
intent.putExtra(BatteryManager.EXTRA_TEMPERATURE, mBatteryProps.batteryTemperature);
intent.putExtra(BatteryManager.EXTRA_TECHNOLOGY, mBatteryProps.batteryTechnology);
intent.putExtra(BatteryManager.EXTRA_INVALID_CHARGER, mInvalidCharger);
+ intent.putExtra(BatteryManager.EXTRA_MAX_CHARGING_CURRENT, mBatteryProps.maxChargingCurrent);
if (DEBUG) {
Slog.d(TAG, "Sending ACTION_BATTERY_CHANGED. level:" + mBatteryProps.batteryLevel +
", scale:" + BATTERY_SCALE + ", status:" + mBatteryProps.batteryStatus +
- ", health:" + mBatteryProps.batteryHealth + ", present:" + mBatteryProps.batteryPresent +
+ ", health:" + mBatteryProps.batteryHealth +
+ ", present:" + mBatteryProps.batteryPresent +
", voltage: " + mBatteryProps.batteryVoltage +
", temperature: " + mBatteryProps.batteryTemperature +
", technology: " + mBatteryProps.batteryTechnology +
- ", AC powered:" + mBatteryProps.chargerAcOnline + ", USB powered:" + mBatteryProps.chargerUsbOnline +
+ ", AC powered:" + mBatteryProps.chargerAcOnline +
+ ", USB powered:" + mBatteryProps.chargerUsbOnline +
", Wireless powered:" + mBatteryProps.chargerWirelessOnline +
- ", icon:" + icon + ", invalid charger:" + mInvalidCharger);
+ ", icon:" + icon + ", invalid charger:" + mInvalidCharger +
+ ", maxChargingCurrent:" + mBatteryProps.maxChargingCurrent);
}
mHandler.post(new Runnable() {
@@ -618,6 +626,7 @@
pw.println(" AC powered: " + mBatteryProps.chargerAcOnline);
pw.println(" USB powered: " + mBatteryProps.chargerUsbOnline);
pw.println(" Wireless powered: " + mBatteryProps.chargerWirelessOnline);
+ pw.println(" Max charging current: " + mBatteryProps.maxChargingCurrent);
pw.println(" status: " + mBatteryProps.batteryStatus);
pw.println(" health: " + mBatteryProps.batteryHealth);
pw.println(" present: " + mBatteryProps.batteryPresent);
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index 4919bed..327fb8a 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -47,6 +47,7 @@
import android.content.res.Resources;
import android.database.ContentObserver;
import android.net.ConnectivityManager;
+import android.net.ConnectivityManager.PacketKeepalive;
import android.net.IConnectivityManager;
import android.net.INetworkManagementEventObserver;
import android.net.INetworkPolicyListener;
@@ -117,6 +118,7 @@
import com.android.internal.util.XmlUtils;
import com.android.server.am.BatteryStatsService;
import com.android.server.connectivity.DataConnectionStats;
+import com.android.server.connectivity.KeepaliveTracker;
import com.android.server.connectivity.NetworkDiagnostics;
import com.android.server.connectivity.Nat464Xlat;
import com.android.server.connectivity.NetworkAgentInfo;
@@ -148,6 +150,8 @@
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
+import java.util.SortedSet;
+import java.util.TreeSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
@@ -355,6 +359,9 @@
*/
private static final int EVENT_REGISTER_NETWORK_LISTENER_WITH_INTENT = 31;
+ /** Handler thread used for both of the handlers below. */
+ @VisibleForTesting
+ protected final HandlerThread mHandlerThread;
/** Handler used for internal events. */
final private InternalHandler mHandler;
/** Handler used for incoming {@link NetworkStateTracker} events. */
@@ -399,6 +406,8 @@
TelephonyManager mTelephonyManager;
+ private KeepaliveTracker mKeepaliveTracker;
+
// sequence number for Networks; keep in sync with system/netd/NetworkController.cpp
private final static int MIN_NET_ID = 100; // some reserved marks
private final static int MAX_NET_ID = 65535;
@@ -505,7 +514,6 @@
ArrayList<NetworkAgentInfo> list = mTypeLists[type];
if (list.contains(nai)) {
- loge("Attempting to register duplicate agent for type " + type + ": " + nai);
return;
}
@@ -609,6 +617,11 @@
}
private LegacyTypeTracker mLegacyTypeTracker = new LegacyTypeTracker();
+ @VisibleForTesting
+ protected HandlerThread createHandlerThread() {
+ return new HandlerThread("ConnectivityServiceThread");
+ }
+
public ConnectivityService(Context context, INetworkManagementService netManager,
INetworkStatsService statsService, INetworkPolicyManager policyManager) {
if (DBG) log("ConnectivityService starting up");
@@ -622,10 +635,10 @@
mDefaultMobileDataRequest = createInternetRequestForTransport(
NetworkCapabilities.TRANSPORT_CELLULAR);
- HandlerThread handlerThread = new HandlerThread("ConnectivityServiceThread");
- handlerThread.start();
- mHandler = new InternalHandler(handlerThread.getLooper());
- mTrackerHandler = new NetworkStateTrackerHandler(handlerThread.getLooper());
+ mHandlerThread = createHandlerThread();
+ mHandlerThread.start();
+ mHandler = new InternalHandler(mHandlerThread.getLooper());
+ mTrackerHandler = new NetworkStateTrackerHandler(mHandlerThread.getLooper());
// setup our unique device name
if (TextUtils.isEmpty(SystemProperties.get("net.hostname"))) {
@@ -764,6 +777,8 @@
mPacManager = new PacManager(mContext, mHandler, EVENT_PROXY_HAS_CHANGED);
mUserManager = (UserManager) context.getSystemService(Context.USER_SERVICE);
+
+ mKeepaliveTracker = new KeepaliveTracker(mHandler);
}
private NetworkRequest createInternetRequestForTransport(int transportType) {
@@ -931,13 +946,13 @@
uidRules = mUidRules.get(uid, RULE_ALLOW_ALL);
}
- if ((uidRules & RULE_REJECT_ALL) != 0
- || (networkCostly && (uidRules & RULE_REJECT_METERED) != 0)) {
+ if (uidRules == RULE_REJECT_ALL) {
return true;
+ } else if ((uidRules == RULE_REJECT_METERED) && networkCostly) {
+ return true;
+ } else {
+ return false;
}
-
- // no restrictive rules; network is visible
- return false;
}
/**
@@ -1432,10 +1447,7 @@
}
private void enforceChangePermission() {
- int uid = Binder.getCallingUid();
- Settings.checkAndNoteChangeNetworkStateOperation(mContext, uid, Settings
- .getPackageNameForUid(mContext, uid), true);
-
+ ConnectivityManager.enforceChangePermission(mContext);
}
private void enforceTetherAccessPermission() {
@@ -1450,6 +1462,10 @@
"ConnectivityService");
}
+ private void enforceKeepalivePermission() {
+ mContext.enforceCallingOrSelfPermission(KeepaliveTracker.PERMISSION, "ConnectivityService");
+ }
+
public void sendConnectedBroadcast(NetworkInfo info) {
enforceConnectivityInternalPermission();
sendGeneralBroadcast(info, CONNECTIVITY_ACTION);
@@ -1512,10 +1528,14 @@
final long ident = Binder.clearCallingIdentity();
if (ConnectivityManager.CONNECTIVITY_ACTION.equals(intent.getAction())) {
+ final NetworkInfo ni = intent.getParcelableExtra(
+ ConnectivityManager.EXTRA_NETWORK_INFO);
+ if (ni.getType() == ConnectivityManager.TYPE_MOBILE_SUPL) {
+ intent.setAction(ConnectivityManager.CONNECTIVITY_ACTION_SUPL);
+ intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
+ }
final IBatteryStats bs = BatteryStatsService.getService();
try {
- NetworkInfo ni = intent.getParcelableExtra(
- ConnectivityManager.EXTRA_NETWORK_INFO);
bs.noteConnectivityChanged(intent.getIntExtra(
ConnectivityManager.EXTRA_NETWORK_TYPE, ConnectivityManager.TYPE_NONE),
ni != null ? ni.getState().toString() : "?");
@@ -1841,10 +1861,13 @@
pw.println(", last requested never");
}
}
- pw.println();
+ pw.println();
mTethering.dump(fd, pw, args);
+ pw.println();
+ mKeepaliveTracker.dump(pw);
+
if (mInetLog != null && mInetLog.size() > 0) {
pw.println();
pw.println("Inet condition reports:");
@@ -1922,7 +1945,12 @@
(NetworkCapabilities)msg.obj;
if (networkCapabilities.hasCapability(NET_CAPABILITY_CAPTIVE_PORTAL) ||
networkCapabilities.hasCapability(NET_CAPABILITY_VALIDATED)) {
- Slog.wtf(TAG, "BUG: " + nai + " has stateful capability.");
+ Slog.wtf(TAG, "BUG: " + nai + " has CS-managed capability.");
+ }
+ if (nai.created && !nai.networkCapabilities.equalImmutableCapabilities(
+ networkCapabilities)) {
+ Slog.wtf(TAG, "BUG: " + nai + " changed immutable capabilities: "
+ + nai.networkCapabilities + " -> " + networkCapabilities);
}
updateCapabilities(nai, networkCapabilities);
}
@@ -2006,6 +2034,15 @@
nai.networkMisc.acceptUnvalidated = (boolean) msg.obj;
break;
}
+ case NetworkAgent.EVENT_PACKET_KEEPALIVE: {
+ NetworkAgentInfo nai = mNetworkAgentInfos.get(msg.replyTo);
+ if (nai == null) {
+ loge("EVENT_PACKET_KEEPALIVE from unknown NetworkAgent");
+ break;
+ }
+ mKeepaliveTracker.handleEventPacketKeepalive(nai, msg);
+ break;
+ }
case NetworkMonitor.EVENT_NETWORK_TESTED: {
NetworkAgentInfo nai = (NetworkAgentInfo)msg.obj;
if (isLiveNetworkAgent(nai, "EVENT_NETWORK_TESTED")) {
@@ -2148,6 +2185,8 @@
// sending all CALLBACK_LOST messages (for requests, not listens) at the end
// of rematchAllNetworksAndRequests
notifyNetworkCallbacks(nai, ConnectivityManager.CALLBACK_LOST);
+ mKeepaliveTracker.handleStopAllKeepalives(nai,
+ ConnectivityManager.PacketKeepalive.ERROR_INVALID_NETWORK);
nai.networkMonitor.sendMessage(NetworkMonitor.CMD_NETWORK_DISCONNECTED);
mNetworkAgentInfos.remove(msg.replyTo);
updateClat(null, nai.linkProperties, nai);
@@ -2226,6 +2265,14 @@
private void handleRegisterNetworkRequest(NetworkRequestInfo nri) {
mNetworkRequests.put(nri.request, nri);
mNetworkRequestInfoLogs.log("REGISTER " + nri);
+ if (!nri.isRequest) {
+ for (NetworkAgentInfo network : mNetworkAgentInfos.values()) {
+ if (nri.request.networkCapabilities.hasSignalStrength() &&
+ network.satisfiesImmutableCapabilitiesOf(nri.request)) {
+ updateSignalStrengthThresholds(network, "REGISTER", nri.request);
+ }
+ }
+ }
rematchAllNetworksAndRequests(null, 0);
if (nri.isRequest && mNetworkForRequestId.get(nri.request.requestId) == null) {
sendUpdatedScoreToFactories(nri.request, 0);
@@ -2339,6 +2386,10 @@
// if this listen request applies and remove it.
for (NetworkAgentInfo nai : mNetworkAgentInfos.values()) {
nai.networkRequests.remove(nri.request.requestId);
+ if (nri.request.networkCapabilities.hasSignalStrength() &&
+ nai.satisfiesImmutableCapabilitiesOf(nri.request)) {
+ updateSignalStrengthThresholds(nai, "RELEASE", nri.request);
+ }
}
}
callCallbackForRequest(nri, null, ConnectivityManager.CALLBACK_RELEASED);
@@ -2505,6 +2556,19 @@
handleMobileDataAlwaysOn();
break;
}
+ // Sent by KeepaliveTracker to process an app request on the state machine thread.
+ case NetworkAgent.CMD_START_PACKET_KEEPALIVE: {
+ mKeepaliveTracker.handleStartKeepalive(msg);
+ break;
+ }
+ // Sent by KeepaliveTracker to process an app request on the state machine thread.
+ case NetworkAgent.CMD_STOP_PACKET_KEEPALIVE: {
+ NetworkAgentInfo nai = getNetworkAgentInfoForNetwork((Network) msg.obj);
+ int slot = msg.arg1;
+ int reason = msg.arg2;
+ mKeepaliveTracker.handleStopKeepalive(nai, slot, reason);
+ break;
+ }
case EVENT_SYSTEM_READY: {
for (NetworkAgentInfo nai : mNetworkAgentInfos.values()) {
nai.networkMonitor.systemReady = true;
@@ -3145,6 +3209,11 @@
final String profileName = new String(mKeyStore.get(Credentials.LOCKDOWN_VPN));
final VpnProfile profile = VpnProfile.decode(
profileName, mKeyStore.get(Credentials.VPN + profileName));
+ if (profile == null) {
+ Slog.e(TAG, "Lockdown VPN configured invalid profile " + profileName);
+ setLockdownTracker(null);
+ return true;
+ }
int user = UserHandle.getUserId(Binder.getCallingUid());
synchronized(mVpns) {
setLockdownTracker(new LockdownVpnTracker(mContext, mNetd, this, mVpns.get(user),
@@ -3291,7 +3360,7 @@
.setPriority(highPriority ?
Notification.PRIORITY_HIGH :
Notification.PRIORITY_DEFAULT)
- .setDefaults(Notification.DEFAULT_ALL)
+ .setDefaults(highPriority ? Notification.DEFAULT_ALL : 0)
.setOnlyAlertOnce(true)
.build();
@@ -3554,15 +3623,47 @@
}
}
- private void ensureImmutableCapabilities(NetworkCapabilities networkCapabilities) {
- if (networkCapabilities.hasCapability(NET_CAPABILITY_VALIDATED)) {
- throw new IllegalArgumentException(
- "Cannot request network with NET_CAPABILITY_VALIDATED");
+ private void ensureRequestableCapabilities(NetworkCapabilities networkCapabilities) {
+ final String badCapability = networkCapabilities.describeFirstNonRequestableCapability();
+ if (badCapability != null) {
+ throw new IllegalArgumentException("Cannot request network with " + badCapability);
}
- if (networkCapabilities.hasCapability(NET_CAPABILITY_CAPTIVE_PORTAL)) {
- throw new IllegalArgumentException(
- "Cannot request network with NET_CAPABILITY_CAPTIVE_PORTAL");
+ }
+
+ private ArrayList<Integer> getSignalStrengthThresholds(NetworkAgentInfo nai) {
+ final SortedSet<Integer> thresholds = new TreeSet();
+ synchronized (nai) {
+ for (NetworkRequestInfo nri : mNetworkRequests.values()) {
+ if (nri.request.networkCapabilities.hasSignalStrength() &&
+ nai.satisfiesImmutableCapabilitiesOf(nri.request)) {
+ thresholds.add(nri.request.networkCapabilities.getSignalStrength());
+ }
+ }
}
+ return new ArrayList<Integer>(thresholds);
+ }
+
+ private void updateSignalStrengthThresholds(
+ NetworkAgentInfo nai, String reason, NetworkRequest request) {
+ ArrayList<Integer> thresholdsArray = getSignalStrengthThresholds(nai);
+ Bundle thresholds = new Bundle();
+ thresholds.putIntegerArrayList("thresholds", thresholdsArray);
+
+ // TODO: Switch to VDBG.
+ if (DBG) {
+ String detail;
+ if (request != null && request.networkCapabilities.hasSignalStrength()) {
+ detail = reason + " " + request.networkCapabilities.getSignalStrength();
+ } else {
+ detail = reason;
+ }
+ log(String.format("updateSignalStrengthThresholds: %s, sending %s to %s",
+ detail, Arrays.toString(thresholdsArray.toArray()), nai.name()));
+ }
+
+ nai.asyncChannel.sendMessage(
+ android.net.NetworkAgent.CMD_SET_SIGNAL_STRENGTH_THRESHOLDS,
+ 0, 0, thresholds);
}
@Override
@@ -3571,7 +3672,7 @@
networkCapabilities = new NetworkCapabilities(networkCapabilities);
enforceNetworkRequestPermissions(networkCapabilities);
enforceMeteredApnPolicy(networkCapabilities);
- ensureImmutableCapabilities(networkCapabilities);
+ ensureRequestableCapabilities(networkCapabilities);
if (timeoutMs < 0 || timeoutMs > ConnectivityManager.MAX_NETWORK_REQUEST_TIMEOUT_MS) {
throw new IllegalArgumentException("Bad timeout specified");
@@ -3625,7 +3726,7 @@
synchronized(mRulesLock) {
uidRules = mUidRules.get(uid, RULE_ALLOW_ALL);
}
- if ((uidRules & (RULE_REJECT_METERED | RULE_REJECT_ALL)) != 0) {
+ if (uidRules != RULE_ALLOW_ALL) {
// we could silently fail or we can filter the available nets to only give
// them those they have access to. Chose the more useful
networkCapabilities.addCapability(NET_CAPABILITY_NOT_METERED);
@@ -3640,7 +3741,7 @@
networkCapabilities = new NetworkCapabilities(networkCapabilities);
enforceNetworkRequestPermissions(networkCapabilities);
enforceMeteredApnPolicy(networkCapabilities);
- ensureImmutableCapabilities(networkCapabilities);
+ ensureRequestableCapabilities(networkCapabilities);
NetworkRequest networkRequest = new NetworkRequest(networkCapabilities, TYPE_NONE,
nextNetworkRequestId());
@@ -3866,6 +3967,8 @@
notifyIfacesChanged();
notifyNetworkCallbacks(networkAgent, ConnectivityManager.CALLBACK_IP_CHANGED);
}
+
+ mKeepaliveTracker.handleCheckKeepalivesStillValid(networkAgent);
}
private void updateClat(LinkProperties newLp, LinkProperties oldLp, NetworkAgentInfo nai) {
@@ -4203,7 +4306,7 @@
boolean keep = newNetwork.isVPN();
boolean isNewDefault = false;
NetworkAgentInfo oldDefaultNetwork = null;
- if (DBG) log("rematching " + newNetwork.name());
+ if (VDBG) log("rematching " + newNetwork.name());
// Find and migrate to this Network any NetworkRequests for
// which this network is now the best.
ArrayList<NetworkAgentInfo> affectedNetworks = new ArrayList<NetworkAgentInfo>();
@@ -4240,6 +4343,7 @@
}
if (currentNetwork == null ||
currentNetwork.getCurrentScore() < newNetwork.getCurrentScore()) {
+ if (DBG) log("rematch for " + newNetwork.name());
if (currentNetwork != null) {
if (DBG) log(" accepting network in place of " + currentNetwork.name());
currentNetwork.networkRequests.remove(nri.request.requestId);
@@ -4532,6 +4636,15 @@
// TODO: support proxy per network.
}
+ // Whether a particular NetworkRequest listen should cause signal strength thresholds to
+ // be communicated to a particular NetworkAgent depends only on the network's immutable,
+ // capabilities, so it only needs to be done once on initial connect, not every time the
+ // network's capabilities change. Note that we do this before rematching the network,
+ // so we could decide to tear it down immediately afterwards. That's fine though - on
+ // disconnection NetworkAgents should stop any signal strength monitoring they have been
+ // doing.
+ updateSignalStrengthThresholds(networkAgent, "CONNECT", null);
+
// Consider network even though it is not yet validated.
rematchNetworkAndRequests(networkAgent, ReapUnvalidatedNetworks.REAP);
@@ -4711,6 +4824,22 @@
}
@Override
+ public void startNattKeepalive(Network network, int intervalSeconds, Messenger messenger,
+ IBinder binder, String srcAddr, int srcPort, String dstAddr) {
+ enforceKeepalivePermission();
+ mKeepaliveTracker.startNattKeepalive(
+ getNetworkAgentInfoForNetwork(network),
+ intervalSeconds, messenger, binder,
+ srcAddr, srcPort, dstAddr, ConnectivityManager.PacketKeepalive.NATT_PORT);
+ }
+
+ @Override
+ public void stopKeepalive(Network network, int slot) {
+ mHandler.sendMessage(mHandler.obtainMessage(
+ NetworkAgent.CMD_STOP_PACKET_KEEPALIVE, slot, PacketKeepalive.SUCCESS, network));
+ }
+
+ @Override
public void factoryReset() {
enforceConnectivityInternalPermission();
diff --git a/services/core/java/com/android/server/DeviceIdleController.java b/services/core/java/com/android/server/DeviceIdleController.java
index 80fd441..b88658b 100644
--- a/services/core/java/com/android/server/DeviceIdleController.java
+++ b/services/core/java/com/android/server/DeviceIdleController.java
@@ -242,6 +242,14 @@
if (Intent.ACTION_BATTERY_CHANGED.equals(intent.getAction())) {
int plugged = intent.getIntExtra("plugged", 0);
updateChargingLocked(plugged != 0);
+ } else if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())) {
+ if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
+ Uri data = intent.getData();
+ String ssp;
+ if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
+ removePowerSaveWhitelistAppInternal(ssp);
+ }
+ }
} else if (ACTION_STEP_IDLE_STATE.equals(intent.getAction())) {
synchronized (DeviceIdleController.this) {
stepIdleStateLocked();
@@ -912,6 +920,10 @@
filter.addAction(Intent.ACTION_BATTERY_CHANGED);
filter.addAction(ACTION_STEP_IDLE_STATE);
getContext().registerReceiver(mReceiver, filter);
+ filter = new IntentFilter();
+ filter.addAction(Intent.ACTION_PACKAGE_REMOVED);
+ filter.addDataScheme("package");
+ getContext().registerReceiver(mReceiver, filter);
mLocalPowerManager.setDeviceIdleWhitelist(mPowerSaveWhitelistAllAppIdArray);
@@ -924,7 +936,10 @@
public boolean addPowerSaveWhitelistAppInternal(String name) {
synchronized (this) {
try {
- ApplicationInfo ai = getContext().getPackageManager().getApplicationInfo(name, 0);
+ ApplicationInfo ai = getContext().getPackageManager().getApplicationInfo(name,
+ PackageManager.GET_UNINSTALLED_PACKAGES
+ | PackageManager.GET_DISABLED_COMPONENTS
+ | PackageManager.GET_DISABLED_UNTIL_USED_COMPONENTS);
if (mPowerSaveWhitelistUserApps.put(name, UserHandle.getAppId(ai.uid)) == null) {
reportPowerSaveWhitelistChangedLocked();
updateWhitelistAppIdsLocked();
@@ -1265,7 +1280,6 @@
if (DEBUG) Slog.d(TAG, "Moved from STATE_IDLE_PENDING to STATE_SENSING.");
EventLogTags.writeDeviceIdle(mState, "step");
scheduleSensingAlarmLocked(mConstants.SENSING_TIMEOUT);
- cancelSensingAlarmLocked();
cancelLocatingLocked();
mAnyMotionDetector.checkForAnyMotion();
mNotMoving = false;
@@ -1277,7 +1291,6 @@
mState = STATE_LOCATING;
if (DEBUG) Slog.d(TAG, "Moved from STATE_SENSING to STATE_LOCATING.");
EventLogTags.writeDeviceIdle(mState, "step");
- cancelSensingAlarmLocked();
scheduleSensingAlarmLocked(mConstants.LOCATING_TIMEOUT);
mLocating = true;
mLocationManager.requestLocationUpdates(mLocationRequest, mGenericLocationListener,
@@ -1335,6 +1348,7 @@
mState = STATE_ACTIVE;
mInactiveTimeout = timeout;
EventLogTags.writeDeviceIdle(mState, type);
+ cancelSensingAlarmLocked();
becomeInactiveIfAppropriateLocked();
}
}
@@ -1518,7 +1532,6 @@
} catch (IOException e) {
}
}
-
}
private void readConfigFileLocked(XmlPullParser parser) {
@@ -1547,7 +1560,10 @@
String name = parser.getAttributeValue(null, "n");
if (name != null) {
try {
- ApplicationInfo ai = pm.getApplicationInfo(name, 0);
+ ApplicationInfo ai = pm.getApplicationInfo(name,
+ PackageManager.GET_UNINSTALLED_PACKAGES
+ | PackageManager.GET_DISABLED_COMPONENTS
+ | PackageManager.GET_DISABLED_UNTIL_USED_COMPONENTS);
mPowerSaveWhitelistUserApps.put(ai.packageName,
UserHandle.getAppId(ai.uid));
} catch (PackageManager.NameNotFoundException e) {
diff --git a/services/core/java/com/android/server/EventLogTags.logtags b/services/core/java/com/android/server/EventLogTags.logtags
index 7aebc1a..ab2ea8b 100644
--- a/services/core/java/com/android/server/EventLogTags.logtags
+++ b/services/core/java/com/android/server/EventLogTags.logtags
@@ -244,3 +244,8 @@
# ---------------------------
40000 volume_changed (stream|1), (prev_level|1), (level|1), (max_level|1), (caller|3)
40001 stream_devices_changed (stream|1), (prev_devices|1), (devices|1)
+
+# ---------------------------
+# GestureLauncherService.java
+# ---------------------------
+40100 camera_gesture_triggered (gesture_on_time|2|3), (sensor1_on_time|2|3), (sensor2_on_time|2|3), (event_extra|1|1)
diff --git a/services/core/java/com/android/server/GestureLauncherService.java b/services/core/java/com/android/server/GestureLauncherService.java
new file mode 100644
index 0000000..2aa0390
--- /dev/null
+++ b/services/core/java/com/android/server/GestureLauncherService.java
@@ -0,0 +1,401 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server;
+
+import android.app.ActivityManager;
+import android.app.StatusBarManager;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.res.Resources;
+import android.database.ContentObserver;
+import android.hardware.Sensor;
+import android.hardware.SensorEvent;
+import android.hardware.SensorEventListener;
+import android.hardware.SensorManager;
+import android.os.Handler;
+import android.os.PowerManager;
+import android.os.PowerManager.WakeLock;
+import android.os.SystemClock;
+import android.os.SystemProperties;
+import android.provider.Settings;
+import android.util.Slog;
+import android.view.KeyEvent;
+
+import com.android.internal.logging.MetricsLogger;
+import com.android.server.statusbar.StatusBarManagerInternal;
+
+/**
+ * The service that listens for gestures detected in sensor firmware and starts the intent
+ * accordingly.
+ * <p>For now, only camera launch gesture is supported, and in the future, more gestures can be
+ * added.</p>
+ * @hide
+ */
+public class GestureLauncherService extends SystemService {
+ private static final boolean DBG = false;
+ private static final String TAG = "GestureLauncherService";
+
+ /**
+ * Time in milliseconds in which the power button must be pressed twice so it will be considered
+ * as a camera launch.
+ */
+ private static final long CAMERA_POWER_DOUBLE_TAP_MAX_TIME_MS = 300;
+ private static final long CAMERA_POWER_DOUBLE_TAP_MIN_TIME_MS = 120;
+
+ /** The listener that receives the gesture event. */
+ private final GestureEventListener mGestureListener = new GestureEventListener();
+
+ private Sensor mCameraLaunchSensor;
+ private Context mContext;
+
+ /** The wake lock held when a gesture is detected. */
+ private WakeLock mWakeLock;
+ private boolean mRegistered;
+ private int mUserId;
+
+ // Below are fields used for event logging only.
+ /** Elapsed real time when the camera gesture is turned on. */
+ private long mCameraGestureOnTimeMs = 0L;
+
+ /** Elapsed real time when the last camera gesture was detected. */
+ private long mCameraGestureLastEventTime = 0L;
+
+ /**
+ * How long the sensor 1 has been turned on since camera launch sensor was
+ * subscribed to and when the last camera launch gesture was detected.
+ * <p>Sensor 1 is the main sensor used to detect camera launch gesture.</p>
+ */
+ private long mCameraGestureSensor1LastOnTimeMs = 0L;
+
+ /**
+ * If applicable, how long the sensor 2 has been turned on since camera
+ * launch sensor was subscribed to and when the last camera launch
+ * gesture was detected.
+ * <p>Sensor 2 is the secondary sensor used to detect camera launch gesture.
+ * This is optional and if only sensor 1 is used for detect camera launch
+ * gesture, this value would always be 0.</p>
+ */
+ private long mCameraGestureSensor2LastOnTimeMs = 0L;
+
+ /**
+ * Extra information about the event when the last camera launch gesture
+ * was detected.
+ */
+ private int mCameraLaunchLastEventExtra = 0;
+
+ /**
+ * Whether camera double tap power button gesture is currently enabled;
+ */
+ private boolean mCameraDoubleTapPowerEnabled;
+ private long mLastPowerDown;
+
+ public GestureLauncherService(Context context) {
+ super(context);
+ mContext = context;
+ }
+
+ public void onStart() {
+ LocalServices.addService(GestureLauncherService.class, this);
+ }
+
+ public void onBootPhase(int phase) {
+ if (phase == PHASE_THIRD_PARTY_APPS_CAN_START) {
+ Resources resources = mContext.getResources();
+ if (!isGestureLauncherEnabled(resources)) {
+ if (DBG) Slog.d(TAG, "Gesture launcher is disabled in system properties.");
+ return;
+ }
+
+ PowerManager powerManager = (PowerManager) mContext.getSystemService(
+ Context.POWER_SERVICE);
+ mWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
+ "GestureLauncherService");
+ updateCameraRegistered();
+ updateCameraDoubleTapPowerEnabled();
+
+ mUserId = ActivityManager.getCurrentUser();
+ mContext.registerReceiver(mUserReceiver, new IntentFilter(Intent.ACTION_USER_SWITCHED));
+ registerContentObservers();
+ }
+ }
+
+ private void registerContentObservers() {
+ mContext.getContentResolver().registerContentObserver(
+ Settings.Secure.getUriFor(Settings.Secure.CAMERA_GESTURE_DISABLED),
+ false, mSettingObserver, mUserId);
+ mContext.getContentResolver().registerContentObserver(
+ Settings.Secure.getUriFor(Settings.Secure.CAMERA_DOUBLE_TAP_POWER_GESTURE_DISABLED),
+ false, mSettingObserver, mUserId);
+ }
+
+ private void updateCameraRegistered() {
+ Resources resources = mContext.getResources();
+ if (isCameraLaunchSettingEnabled(mContext, mUserId)) {
+ registerCameraLaunchGesture(resources);
+ } else {
+ unregisterCameraLaunchGesture();
+ }
+ }
+
+ private void updateCameraDoubleTapPowerEnabled() {
+ boolean enabled = isCameraDoubleTapPowerSettingEnabled(mContext, mUserId);
+ synchronized (this) {
+ mCameraDoubleTapPowerEnabled = enabled;
+ }
+ }
+
+ private void unregisterCameraLaunchGesture() {
+ if (mRegistered) {
+ mRegistered = false;
+ mCameraGestureOnTimeMs = 0L;
+ mCameraGestureLastEventTime = 0L;
+ mCameraGestureSensor1LastOnTimeMs = 0;
+ mCameraGestureSensor2LastOnTimeMs = 0;
+ mCameraLaunchLastEventExtra = 0;
+
+ SensorManager sensorManager = (SensorManager) mContext.getSystemService(
+ Context.SENSOR_SERVICE);
+ sensorManager.unregisterListener(mGestureListener);
+ }
+ }
+
+ /**
+ * Registers for the camera launch gesture.
+ */
+ private void registerCameraLaunchGesture(Resources resources) {
+ if (mRegistered) {
+ return;
+ }
+ mCameraGestureOnTimeMs = SystemClock.elapsedRealtime();
+ mCameraGestureLastEventTime = mCameraGestureOnTimeMs;
+ SensorManager sensorManager = (SensorManager) mContext.getSystemService(
+ Context.SENSOR_SERVICE);
+ int cameraLaunchGestureId = resources.getInteger(
+ com.android.internal.R.integer.config_cameraLaunchGestureSensorType);
+ if (cameraLaunchGestureId != -1) {
+ mRegistered = false;
+ String sensorName = resources.getString(
+ com.android.internal.R.string.config_cameraLaunchGestureSensorStringType);
+ mCameraLaunchSensor = sensorManager.getDefaultSensor(
+ cameraLaunchGestureId,
+ true /*wakeUp*/);
+
+ // Compare the camera gesture string type to that in the resource file to make
+ // sure we are registering the correct sensor. This is redundant check, it
+ // makes the code more robust.
+ if (mCameraLaunchSensor != null) {
+ if (sensorName.equals(mCameraLaunchSensor.getStringType())) {
+ mRegistered = sensorManager.registerListener(mGestureListener,
+ mCameraLaunchSensor, 0);
+ } else {
+ String message = String.format("Wrong configuration. Sensor type and sensor "
+ + "string type don't match: %s in resources, %s in the sensor.",
+ sensorName, mCameraLaunchSensor.getStringType());
+ throw new RuntimeException(message);
+ }
+ }
+ if (DBG) Slog.d(TAG, "Camera launch sensor registered: " + mRegistered);
+ } else {
+ if (DBG) Slog.d(TAG, "Camera launch sensor is not specified.");
+ }
+ }
+
+ public static boolean isCameraLaunchSettingEnabled(Context context, int userId) {
+ return isCameraLaunchEnabled(context.getResources())
+ && (Settings.Secure.getIntForUser(context.getContentResolver(),
+ Settings.Secure.CAMERA_GESTURE_DISABLED, 0, userId) == 0);
+ }
+
+ public static boolean isCameraDoubleTapPowerSettingEnabled(Context context, int userId) {
+ return isCameraDoubleTapPowerEnabled(context.getResources())
+ && (Settings.Secure.getIntForUser(context.getContentResolver(),
+ Settings.Secure.CAMERA_DOUBLE_TAP_POWER_GESTURE_DISABLED, 0, userId) == 0);
+ }
+
+ /**
+ * Whether to enable the camera launch gesture.
+ */
+ public static boolean isCameraLaunchEnabled(Resources resources) {
+ boolean configSet = resources.getInteger(
+ com.android.internal.R.integer.config_cameraLaunchGestureSensorType) != -1;
+ return configSet &&
+ !SystemProperties.getBoolean("gesture.disable_camera_launch", false);
+ }
+
+ public static boolean isCameraDoubleTapPowerEnabled(Resources resources) {
+ return resources.getBoolean(
+ com.android.internal.R.bool.config_cameraDoubleTapPowerGestureEnabled);
+ }
+
+ /**
+ * Whether GestureLauncherService should be enabled according to system properties.
+ */
+ public static boolean isGestureLauncherEnabled(Resources resources) {
+ return isCameraLaunchEnabled(resources) || isCameraDoubleTapPowerEnabled(resources);
+ }
+
+ public boolean interceptPowerKeyDown(KeyEvent event, boolean interactive) {
+ boolean launched = false;
+ boolean intercept = false;
+ long doubleTapInterval;
+ synchronized (this) {
+ doubleTapInterval = event.getEventTime() - mLastPowerDown;
+ if (mCameraDoubleTapPowerEnabled
+ && doubleTapInterval < CAMERA_POWER_DOUBLE_TAP_MAX_TIME_MS
+ && doubleTapInterval > CAMERA_POWER_DOUBLE_TAP_MIN_TIME_MS) {
+ launched = true;
+ intercept = interactive;
+ }
+ mLastPowerDown = event.getEventTime();
+ }
+ if (launched) {
+ Slog.i(TAG, "Power button double tap gesture detected, launching camera. Interval="
+ + doubleTapInterval + "ms");
+ launched = handleCameraLaunchGesture(false /* useWakelock */,
+ StatusBarManager.CAMERA_LAUNCH_SOURCE_POWER_DOUBLE_TAP);
+ if (launched) {
+ MetricsLogger.action(mContext, MetricsLogger.ACTION_DOUBLE_TAP_POWER_CAMERA_GESTURE,
+ (int) doubleTapInterval);
+ }
+ }
+ MetricsLogger.histogram(mContext, "power_double_tap_interval", (int) doubleTapInterval);
+ return intercept && launched;
+ }
+
+ /**
+ * @return true if camera was launched, false otherwise.
+ */
+ private boolean handleCameraLaunchGesture(boolean useWakelock, int source) {
+ boolean userSetupComplete = Settings.Secure.getInt(mContext.getContentResolver(),
+ Settings.Secure.USER_SETUP_COMPLETE, 0) != 0;
+ if (!userSetupComplete) {
+ if (DBG) Slog.d(TAG, String.format(
+ "userSetupComplete = %s, ignoring camera launch gesture.",
+ userSetupComplete));
+ return false;
+ }
+ if (DBG) Slog.d(TAG, String.format(
+ "userSetupComplete = %s, performing camera launch gesture.",
+ userSetupComplete));
+
+ if (useWakelock) {
+ // Make sure we don't sleep too early
+ mWakeLock.acquire(500L);
+ }
+ StatusBarManagerInternal service = LocalServices.getService(
+ StatusBarManagerInternal.class);
+ service.onCameraLaunchGestureDetected(source);
+ return true;
+ }
+
+ private final BroadcastReceiver mUserReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ if (Intent.ACTION_USER_SWITCHED.equals(intent.getAction())) {
+ mUserId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0);
+ mContext.getContentResolver().unregisterContentObserver(mSettingObserver);
+ registerContentObservers();
+ updateCameraRegistered();
+ updateCameraDoubleTapPowerEnabled();
+ }
+ }
+ };
+
+ private final ContentObserver mSettingObserver = new ContentObserver(new Handler()) {
+ public void onChange(boolean selfChange, android.net.Uri uri, int userId) {
+ if (userId == mUserId) {
+ updateCameraRegistered();
+ updateCameraDoubleTapPowerEnabled();
+ }
+ }
+ };
+
+ private final class GestureEventListener implements SensorEventListener {
+ @Override
+ public void onSensorChanged(SensorEvent event) {
+ if (!mRegistered) {
+ if (DBG) Slog.d(TAG, "Ignoring gesture event because it's unregistered.");
+ return;
+ }
+ if (event.sensor == mCameraLaunchSensor) {
+ if (DBG) {
+ float[] values = event.values;
+ Slog.d(TAG, String.format("Received a camera launch event: " +
+ "values=[%.4f, %.4f, %.4f].", values[0], values[1], values[2]));
+ }
+ if (handleCameraLaunchGesture(true /* useWakelock */,
+ StatusBarManager.CAMERA_LAUNCH_SOURCE_WIGGLE)) {
+ MetricsLogger.action(mContext, MetricsLogger.ACTION_WIGGLE_CAMERA_GESTURE);
+ trackCameraLaunchEvent(event);
+ }
+ return;
+ }
+ }
+
+ @Override
+ public void onAccuracyChanged(Sensor sensor, int accuracy) {
+ // Ignored.
+ }
+
+ private void trackCameraLaunchEvent(SensorEvent event) {
+ long now = SystemClock.elapsedRealtime();
+ long totalDuration = now - mCameraGestureOnTimeMs;
+ // values[0]: ratio between total time duration when accel is turned on and time
+ // duration since camera launch gesture is subscribed.
+ // values[1]: ratio between total time duration when gyro is turned on and time duration
+ // since camera launch gesture is subscribed.
+ // values[2]: extra information
+ float[] values = event.values;
+
+ long sensor1OnTime = (long) (totalDuration * (double) values[0]);
+ long sensor2OnTime = (long) (totalDuration * (double) values[1]);
+ int extra = (int) values[2];
+
+ // We only log the difference in the event log to make aggregation easier.
+ long gestureOnTimeDiff = now - mCameraGestureLastEventTime;
+ long sensor1OnTimeDiff = sensor1OnTime - mCameraGestureSensor1LastOnTimeMs;
+ long sensor2OnTimeDiff = sensor2OnTime - mCameraGestureSensor2LastOnTimeMs;
+ int extraDiff = extra - mCameraLaunchLastEventExtra;
+
+ // Gating against negative time difference. This doesn't usually happen, but it may
+ // happen because of numeric errors.
+ if (gestureOnTimeDiff < 0 || sensor1OnTimeDiff < 0 || sensor2OnTimeDiff < 0) {
+ if (DBG) Slog.d(TAG, "Skipped event logging because negative numbers.");
+ return;
+ }
+
+ if (DBG) Slog.d(TAG, String.format("totalDuration: %d, sensor1OnTime: %s, " +
+ "sensor2OnTime: %d, extra: %d",
+ gestureOnTimeDiff,
+ sensor1OnTimeDiff,
+ sensor2OnTimeDiff,
+ extraDiff));
+ EventLogTags.writeCameraGestureTriggered(
+ gestureOnTimeDiff,
+ sensor1OnTimeDiff,
+ sensor2OnTimeDiff,
+ extraDiff);
+
+ mCameraGestureLastEventTime = now;
+ mCameraGestureSensor1LastOnTimeMs = sensor1OnTime;
+ mCameraGestureSensor2LastOnTimeMs = sensor2OnTime;
+ mCameraLaunchLastEventExtra = extra;
+ }
+ }
+}
diff --git a/services/core/java/com/android/server/InputMethodManagerService.java b/services/core/java/com/android/server/InputMethodManagerService.java
index 4e11070..6d07a57 100644
--- a/services/core/java/com/android/server/InputMethodManagerService.java
+++ b/services/core/java/com/android/server/InputMethodManagerService.java
@@ -40,6 +40,7 @@
import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlSerializer;
+import android.annotation.Nullable;
import android.app.ActivityManagerNative;
import android.app.AppGlobals;
import android.app.AlertDialog;
@@ -286,8 +287,19 @@
boolean mSystemReady;
/**
- * Id of the currently selected input method.
+ * Id obtained with {@link InputMethodInfo#getId()} for the currently selected input method.
+ * method. This is to be synchronized with the secure settings keyed with
+ * {@link Settings.Secure#DEFAULT_INPUT_METHOD}.
+ *
+ * <p>This can be transiently {@code null} when the system is re-initializing input method
+ * settings, e.g., the system locale is just changed.</p>
+ *
+ * <p>Note that {@link #mCurId} is used to track which IME is being connected to
+ * {@link InputMethodManagerService}.</p>
+ *
+ * @see #mCurId
*/
+ @Nullable
String mCurMethodId;
/**
@@ -317,9 +329,14 @@
EditorInfo mCurAttribute;
/**
- * The input method ID of the input method service that we are currently
+ * Id obtained with {@link InputMethodInfo#getId()} for the input method that we are currently
* connected to or in the process of connecting to.
+ *
+ * <p>This can be {@code null} when no input method is connected.</p>
+ *
+ * @see #mCurMethodId
*/
+ @Nullable
String mCurId;
/**
@@ -967,7 +984,6 @@
|| (newLocale != null && !newLocale.equals(mLastSystemLocale))) {
if (!updateOnlyWhenLocaleChanged) {
hideCurrentInputLocked(0, null);
- mCurMethodId = null;
unbindCurrentMethodLocked(true, false);
}
if (DEBUG) {
@@ -1523,7 +1539,11 @@
channel.dispose();
}
- void unbindCurrentMethodLocked(boolean reportToClient, boolean savePosition) {
+ void unbindCurrentMethodLocked(boolean resetCurrentMethodAndClient, boolean savePosition) {
+ if (resetCurrentMethodAndClient) {
+ mCurMethodId = null;
+ }
+
if (mVisibleBound) {
mContext.unbindService(mVisibleConnection);
mVisibleBound = false;
@@ -1550,9 +1570,8 @@
mCurId = null;
clearCurMethodLocked();
- if (reportToClient && mCurClient != null) {
- executeOrSendMessage(mCurClient.client, mCaller.obtainMessageIO(
- MSG_UNBIND_METHOD, mCurSeq, mCurClient.client));
+ if (resetCurrentMethodAndClient) {
+ unbindCurrentClientLocked();
}
}
@@ -1903,13 +1922,11 @@
setInputMethodLocked(id, mSettings.getSelectedInputMethodSubtypeId(id));
} catch (IllegalArgumentException e) {
Slog.w(TAG, "Unknown input method from prefs: " + id, e);
- mCurMethodId = null;
unbindCurrentMethodLocked(true, false);
}
mShortcutInputMethodsAndSubtypes.clear();
} else {
// There is no longer an input method set, so stop any current one.
- mCurMethodId = null;
unbindCurrentMethodLocked(true, false);
}
// Here is not the perfect place to reset the switching controller. Ideally
diff --git a/services/core/java/com/android/server/LocationManagerService.java b/services/core/java/com/android/server/LocationManagerService.java
index cae060a..468ead0 100644
--- a/services/core/java/com/android/server/LocationManagerService.java
+++ b/services/core/java/com/android/server/LocationManagerService.java
@@ -542,22 +542,25 @@
Slog.e(TAG, "Unable to bind FLP Geofence proxy.");
}
- // bind to the hardware activity recognition if supported
- if (ActivityRecognitionHardware.isSupported()) {
- ActivityRecognitionProxy proxy = ActivityRecognitionProxy.createAndBind(
- mContext,
- mLocationHandler,
- ActivityRecognitionHardware.getInstance(mContext),
- com.android.internal.R.bool.config_enableActivityRecognitionHardwareOverlay,
- com.android.internal.R.string.config_activityRecognitionHardwarePackageName,
- com.android.internal.R.array.config_locationProviderPackageNames);
-
- if (proxy == null) {
- Slog.e(TAG, "Unable to bind ActivityRecognitionProxy.");
- }
+ // bind to hardware activity recognition
+ boolean activityRecognitionHardwareIsSupported = ActivityRecognitionHardware.isSupported();
+ ActivityRecognitionHardware activityRecognitionHardware = null;
+ if (activityRecognitionHardwareIsSupported) {
+ activityRecognitionHardware = ActivityRecognitionHardware.getInstance(mContext);
} else {
Slog.e(TAG, "Hardware Activity-Recognition not supported.");
}
+ ActivityRecognitionProxy proxy = ActivityRecognitionProxy.createAndBind(
+ mContext,
+ mLocationHandler,
+ activityRecognitionHardwareIsSupported,
+ activityRecognitionHardware,
+ com.android.internal.R.bool.config_enableActivityRecognitionHardwareOverlay,
+ com.android.internal.R.string.config_activityRecognitionHardwarePackageName,
+ com.android.internal.R.array.config_locationProviderPackageNames);
+ if (proxy == null) {
+ Slog.e(TAG, "Unable to bind ActivityRecognitionProxy.");
+ }
String[] testProviderStrings = resources.getStringArray(
com.android.internal.R.array.config_testLocationProviders);
diff --git a/services/core/java/com/android/server/LockSettingsService.java b/services/core/java/com/android/server/LockSettingsService.java
index e3e7181..6cb2875 100644
--- a/services/core/java/com/android/server/LockSettingsService.java
+++ b/services/core/java/com/android/server/LockSettingsService.java
@@ -18,6 +18,7 @@
import android.app.admin.DevicePolicyManager;
import android.app.backup.BackupManager;
+import android.app.trust.IStrongAuthTracker;
import android.content.BroadcastReceiver;
import android.content.ContentResolver;
import android.content.Context;
@@ -28,6 +29,8 @@
import static android.Manifest.permission.ACCESS_KEYGUARD_SECURE_STORAGE;
import static android.content.Context.USER_SERVICE;
import static android.Manifest.permission.READ_CONTACTS;
+import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_LOCKOUT;
+
import android.database.sqlite.SQLiteDatabase;
import android.os.Binder;
import android.os.IBinder;
@@ -70,6 +73,7 @@
private final Context mContext;
private final LockSettingsStorage mStorage;
+ private final LockSettingsStrongAuth mStrongAuth = new LockSettingsStrongAuth();
private LockPatternUtils mLockPatternUtils;
private boolean mFirstCallToVold;
@@ -93,6 +97,7 @@
filter.addAction(Intent.ACTION_USER_ADDED);
filter.addAction(Intent.ACTION_USER_STARTING);
filter.addAction(Intent.ACTION_USER_REMOVED);
+ filter.addAction(Intent.ACTION_USER_PRESENT);
mContext.registerReceiverAsUser(mBroadcastReceiver, UserHandle.ALL, filter, null, null);
mStorage = new LockSettingsStorage(context, new LockSettingsStorage.Callback() {
@@ -122,6 +127,8 @@
} else if (Intent.ACTION_USER_STARTING.equals(intent.getAction())) {
final int userHandle = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0);
mStorage.prefetchUser(userHandle);
+ } else if (Intent.ACTION_USER_PRESENT.equals(intent.getAction())) {
+ mStrongAuth.reportUnlock(getSendingUserId());
} else if (Intent.ACTION_USER_REMOVED.equals(intent.getAction())) {
final int userHandle = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0);
if (userHandle > 0) {
@@ -667,6 +674,10 @@
if (shouldReEnroll) {
credentialUtil.setCredential(credential, credential, userId);
}
+ } else if (response.getResponseCode() == VerifyCredentialResponse.RESPONSE_RETRY) {
+ if (response.getTimeout() > 0) {
+ requireStrongAuth(STRONG_AUTH_REQUIRED_AFTER_LOCKOUT, userId);
+ }
}
return response;
@@ -721,6 +732,7 @@
private void removeUser(int userId) {
mStorage.removeUser(userId);
+ mStrongAuth.removeUser(userId);
final KeyStore ks = KeyStore.getInstance();
ks.onUserRemoved(userId);
@@ -735,6 +747,24 @@
}
}
+ @Override
+ public void registerStrongAuthTracker(IStrongAuthTracker tracker) {
+ checkPasswordReadPermission(UserHandle.USER_ALL);
+ mStrongAuth.registerStrongAuthTracker(tracker);
+ }
+
+ @Override
+ public void unregisterStrongAuthTracker(IStrongAuthTracker tracker) {
+ checkPasswordReadPermission(UserHandle.USER_ALL);
+ mStrongAuth.unregisterStrongAuthTracker(tracker);
+ }
+
+ @Override
+ public void requireStrongAuth(int strongAuthReason, int userId) {
+ checkWritePermission(userId);
+ mStrongAuth.requireStrongAuth(strongAuthReason, userId);
+ }
+
private static final String[] VALID_SETTINGS = new String[] {
LockPatternUtils.LOCKOUT_PERMANENT_KEY,
LockPatternUtils.LOCKOUT_ATTEMPT_DEADLINE,
@@ -805,5 +835,4 @@
Slog.e(TAG, "Unable to acquire GateKeeperService");
return null;
}
-
}
diff --git a/services/core/java/com/android/server/LockSettingsStrongAuth.java b/services/core/java/com/android/server/LockSettingsStrongAuth.java
new file mode 100644
index 0000000..c023f4a
--- /dev/null
+++ b/services/core/java/com/android/server/LockSettingsStrongAuth.java
@@ -0,0 +1,167 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server;
+
+import com.android.internal.widget.LockPatternUtils;
+import com.android.internal.widget.LockPatternUtils.StrongAuthTracker;
+
+import android.app.trust.IStrongAuthTracker;
+import android.os.DeadObjectException;
+import android.os.Handler;
+import android.os.Message;
+import android.os.RemoteException;
+import android.os.UserHandle;
+import android.util.Slog;
+import android.util.SparseIntArray;
+
+import java.util.ArrayList;
+
+import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_NOT_REQUIRED;
+
+/**
+ * Keeps track of requests for strong authentication.
+ */
+public class LockSettingsStrongAuth {
+
+ private static final String TAG = "LockSettings";
+
+ private static final int MSG_REQUIRE_STRONG_AUTH = 1;
+ private static final int MSG_REGISTER_TRACKER = 2;
+ private static final int MSG_UNREGISTER_TRACKER = 3;
+ private static final int MSG_REMOVE_USER = 4;
+
+ private final ArrayList<IStrongAuthTracker> mStrongAuthTrackers = new ArrayList<>();
+ private final SparseIntArray mStrongAuthForUser = new SparseIntArray();
+
+ private void handleAddStrongAuthTracker(IStrongAuthTracker tracker) {
+ for (int i = 0; i < mStrongAuthTrackers.size(); i++) {
+ if (mStrongAuthTrackers.get(i).asBinder() == tracker.asBinder()) {
+ return;
+ }
+ }
+ mStrongAuthTrackers.add(tracker);
+
+ for (int i = 0; i < mStrongAuthForUser.size(); i++) {
+ int key = mStrongAuthForUser.keyAt(i);
+ int value = mStrongAuthForUser.valueAt(i);
+ try {
+ tracker.onStrongAuthRequiredChanged(value, key);
+ } catch (RemoteException e) {
+ Slog.e(TAG, "Exception while adding StrongAuthTracker.", e);
+ }
+ }
+ }
+
+ private void handleRemoveStrongAuthTracker(IStrongAuthTracker tracker) {
+ for (int i = 0; i < mStrongAuthTrackers.size(); i++) {
+ if (mStrongAuthTrackers.get(i).asBinder() == tracker.asBinder()) {
+ mStrongAuthTrackers.remove(i);
+ return;
+ }
+ }
+ }
+
+ private void handleRequireStrongAuth(int strongAuthReason, int userId) {
+ if (userId == UserHandle.USER_ALL) {
+ for (int i = 0; i < mStrongAuthForUser.size(); i++) {
+ int key = mStrongAuthForUser.keyAt(i);
+ handleRequireStrongAuthOneUser(strongAuthReason, key);
+ }
+ } else {
+ handleRequireStrongAuthOneUser(strongAuthReason, userId);
+ }
+ }
+
+ private void handleRequireStrongAuthOneUser(int strongAuthReason, int userId) {
+ int oldValue = mStrongAuthForUser.get(userId, LockPatternUtils.StrongAuthTracker.DEFAULT);
+ int newValue = strongAuthReason == STRONG_AUTH_NOT_REQUIRED
+ ? STRONG_AUTH_NOT_REQUIRED
+ : (oldValue | strongAuthReason);
+ if (oldValue != newValue) {
+ mStrongAuthForUser.put(userId, newValue);
+ notifyStrongAuthTrackers(newValue, userId);
+ }
+ }
+
+ private void handleRemoveUser(int userId) {
+ int index = mStrongAuthForUser.indexOfKey(userId);
+ if (index >= 0) {
+ mStrongAuthForUser.removeAt(index);
+ notifyStrongAuthTrackers(StrongAuthTracker.DEFAULT, userId);
+ }
+ }
+
+ private void notifyStrongAuthTrackers(int strongAuthReason, int userId) {
+ for (int i = 0; i < mStrongAuthTrackers.size(); i++) {
+ try {
+ mStrongAuthTrackers.get(i).onStrongAuthRequiredChanged(strongAuthReason, userId);
+ } catch (DeadObjectException e) {
+ Slog.d(TAG, "Removing dead StrongAuthTracker.");
+ mStrongAuthTrackers.remove(i);
+ i--;
+ } catch (RemoteException e) {
+ Slog.e(TAG, "Exception while notifying StrongAuthTracker.", e);
+ }
+ }
+ }
+
+ public void registerStrongAuthTracker(IStrongAuthTracker tracker) {
+ mHandler.obtainMessage(MSG_REGISTER_TRACKER, tracker).sendToTarget();
+ }
+
+ public void unregisterStrongAuthTracker(IStrongAuthTracker tracker) {
+ mHandler.obtainMessage(MSG_UNREGISTER_TRACKER, tracker).sendToTarget();
+ }
+
+ public void removeUser(int userId) {
+ mHandler.obtainMessage(MSG_REMOVE_USER, userId, 0).sendToTarget();
+ }
+
+ public void requireStrongAuth(int strongAuthReason, int userId) {
+ if (userId == UserHandle.USER_ALL || userId >= UserHandle.USER_OWNER) {
+ mHandler.obtainMessage(MSG_REQUIRE_STRONG_AUTH, strongAuthReason,
+ userId).sendToTarget();
+ } else {
+ throw new IllegalArgumentException(
+ "userId must be an explicit user id or USER_ALL");
+ }
+ }
+
+ public void reportUnlock(int userId) {
+ requireStrongAuth(STRONG_AUTH_NOT_REQUIRED, userId);
+ }
+
+ private final Handler mHandler = new Handler() {
+ @Override
+ public void handleMessage(Message msg) {
+ switch (msg.what) {
+ case MSG_REGISTER_TRACKER:
+ handleAddStrongAuthTracker((IStrongAuthTracker) msg.obj);
+ break;
+ case MSG_UNREGISTER_TRACKER:
+ handleRemoveStrongAuthTracker((IStrongAuthTracker) msg.obj);
+ break;
+ case MSG_REQUIRE_STRONG_AUTH:
+ handleRequireStrongAuth(msg.arg1, msg.arg2);
+ break;
+ case MSG_REMOVE_USER:
+ handleRemoveUser(msg.arg1);
+ break;
+ }
+ }
+ };
+}
diff --git a/services/core/java/com/android/server/MountService.java b/services/core/java/com/android/server/MountService.java
index d10a457..5e67414 100644
--- a/services/core/java/com/android/server/MountService.java
+++ b/services/core/java/com/android/server/MountService.java
@@ -368,11 +368,17 @@
private boolean shouldBenchmark() {
final long benchInterval = Settings.Global.getLong(mContext.getContentResolver(),
Settings.Global.STORAGE_BENCHMARK_INTERVAL, DateUtils.WEEK_IN_MILLIS);
+ if (benchInterval == -1) {
+ return false;
+ } else if (benchInterval == 0) {
+ return true;
+ }
+
synchronized (mLock) {
for (int i = 0; i < mVolumes.size(); i++) {
final VolumeInfo vol = mVolumes.valueAt(i);
final VolumeRecord rec = mRecords.get(vol.fsUuid);
- if (vol.isMountedReadable() && rec != null) {
+ if (vol.isMountedWritable() && rec != null) {
final long benchAge = System.currentTimeMillis() - rec.lastBenchMillis;
if (benchAge >= benchInterval) {
return true;
@@ -2409,8 +2415,13 @@
}
try {
- mCryptConnector.execute("cryptfs", "enablecrypto", "inplace", CRYPTO_TYPES[type],
- new SensitiveArg(password));
+ if (type == StorageManager.CRYPT_TYPE_DEFAULT) {
+ mCryptConnector.execute("cryptfs", "enablecrypto", "inplace",
+ CRYPTO_TYPES[type]);
+ } else {
+ mCryptConnector.execute("cryptfs", "enablecrypto", "inplace",
+ CRYPTO_TYPES[type], new SensitiveArg(password));
+ }
} catch (NativeDaemonConnectorException e) {
// Encryption failed
return e.getCode();
@@ -2582,6 +2593,63 @@
}
@Override
+ public void createNewUserDir(int userHandle, String path) {
+ if (Binder.getCallingUid() != Process.SYSTEM_UID) {
+ throw new SecurityException("Only SYSTEM_UID can create user directories");
+ }
+
+ waitForReady();
+
+ if (DEBUG_EVENTS) {
+ Slog.i(TAG, "Creating new user dir");
+ }
+
+ try {
+ NativeDaemonEvent event = mCryptConnector.execute(
+ "cryptfs", "createnewuserdir", userHandle, path);
+ if (!"0".equals(event.getMessage())) {
+ String error = "createnewuserdir sent unexpected message: "
+ + event.getMessage();
+ Slog.e(TAG, error);
+ // ext4enc:TODO is this the right exception?
+ throw new RuntimeException(error);
+ }
+ } catch (NativeDaemonConnectorException e) {
+ Slog.e(TAG, "createnewuserdir threw exception", e);
+ throw new RuntimeException("createnewuserdir threw exception", e);
+ }
+ }
+
+ // ext4enc:TODO duplication between this and createNewUserDir is nasty
+ @Override
+ public void deleteUserKey(int userHandle) {
+ if (Binder.getCallingUid() != Process.SYSTEM_UID) {
+ throw new SecurityException("Only SYSTEM_UID can delete user keys");
+ }
+
+ waitForReady();
+
+ if (DEBUG_EVENTS) {
+ Slog.i(TAG, "Deleting user key");
+ }
+
+ try {
+ NativeDaemonEvent event = mCryptConnector.execute(
+ "cryptfs", "deleteuserkey", userHandle);
+ if (!"0".equals(event.getMessage())) {
+ String error = "deleteuserkey sent unexpected message: "
+ + event.getMessage();
+ Slog.e(TAG, error);
+ // ext4enc:TODO is this the right exception?
+ throw new RuntimeException(error);
+ }
+ } catch (NativeDaemonConnectorException e) {
+ Slog.e(TAG, "deleteuserkey threw exception", e);
+ throw new RuntimeException("deleteuserkey threw exception", e);
+ }
+ }
+
+ @Override
public int mkdirs(String callingPkg, String appPath) {
final int userId = UserHandle.getUserId(Binder.getCallingUid());
final UserEnvironment userEnv = new UserEnvironment(userId);
diff --git a/services/core/java/com/android/server/NetworkManagementService.java b/services/core/java/com/android/server/NetworkManagementService.java
index 433f707..ba9279c 100644
--- a/services/core/java/com/android/server/NetworkManagementService.java
+++ b/services/core/java/com/android/server/NetworkManagementService.java
@@ -2023,9 +2023,9 @@
public void setFirewallChainEnabled(int chain, boolean enable) {
enforceSystemUid();
synchronized (mQuotaLock) {
- if (mFirewallChainStates.indexOfKey(chain) >= 0 &&
- mFirewallChainStates.get(chain) == enable) {
- // All is the same, nothing to do.
+ if (mFirewallChainStates.get(chain, false) == enable) {
+ // All is the same, nothing to do. This relies on the fact that netd has child
+ // chains default detached.
return;
}
mFirewallChainStates.put(chain, enable);
diff --git a/services/core/java/com/android/server/NetworkTimeUpdateService.java b/services/core/java/com/android/server/NetworkTimeUpdateService.java
index a0d305c..3f0664d 100644
--- a/services/core/java/com/android/server/NetworkTimeUpdateService.java
+++ b/services/core/java/com/android/server/NetworkTimeUpdateService.java
@@ -30,6 +30,7 @@
import android.os.Looper;
import android.os.Message;
import android.os.SystemClock;
+import android.os.PowerManager;
import android.provider.Settings;
import android.util.Log;
import android.util.NtpTrustedTime;
@@ -75,6 +76,7 @@
private SettingsObserver mSettingsObserver;
// The last time that we successfully fetched the NTP time.
private long mLastNtpFetchTime = NOT_SET;
+ private final PowerManager.WakeLock mWakeLock;
// Normal polling frequency
private final long mPollingIntervalMs;
@@ -104,6 +106,9 @@
com.android.internal.R.integer.config_ntpRetry);
mTimeErrorThresholdMs = mContext.getResources().getInteger(
com.android.internal.R.integer.config_ntpThreshold);
+
+ mWakeLock = ((PowerManager) context.getSystemService(Context.POWER_SERVICE)).newWakeLock(
+ PowerManager.PARTIAL_WAKE_LOCK, TAG);
}
/** Initialize the receivers and initiate the first NTP request */
@@ -148,7 +153,15 @@
private void onPollNetworkTime(int event) {
// If Automatic time is not set, don't bother.
if (!isAutomaticTimeRequested()) return;
+ mWakeLock.acquire();
+ try {
+ onPollNetworkTimeUnderWakeLock(event);
+ } finally {
+ mWakeLock.release();
+ }
+ }
+ private void onPollNetworkTimeUnderWakeLock(int event) {
final long refTime = SystemClock.elapsedRealtime();
// If NITZ time was received less than mPollingIntervalMs time ago,
// no need to sync to NTP.
diff --git a/services/core/java/com/android/server/VibratorService.java b/services/core/java/com/android/server/VibratorService.java
index 30f4dce..c228422 100644
--- a/services/core/java/com/android/server/VibratorService.java
+++ b/services/core/java/com/android/server/VibratorService.java
@@ -59,6 +59,7 @@
implements InputManager.InputDeviceListener {
private static final String TAG = "VibratorService";
private static final boolean DEBUG = false;
+ private static final String SYSTEM_UI_PACKAGE = "com.android.systemui";
private final LinkedList<Vibration> mVibrations;
private final LinkedList<VibrationInfo> mPreviousVibrations;
@@ -147,7 +148,8 @@
}
public boolean isSystemHapticFeedback() {
- return (mUid == Process.SYSTEM_UID || mUid == 0) && mRepeat < 0;
+ return (mUid == Process.SYSTEM_UID || mUid == 0 || SYSTEM_UI_PACKAGE.equals(mOpPkg))
+ && mRepeat < 0;
}
}
diff --git a/services/core/java/com/android/server/accounts/AccountManagerService.java b/services/core/java/com/android/server/accounts/AccountManagerService.java
index d5e9a32..3c6de07 100644
--- a/services/core/java/com/android/server/accounts/AccountManagerService.java
+++ b/services/core/java/com/android/server/accounts/AccountManagerService.java
@@ -3791,7 +3791,6 @@
boolean isPermitted =
isPermitted(opPackageName, callingUid, Manifest.permission.GET_ACCOUNTS,
Manifest.permission.GET_ACCOUNTS_PRIVILEGED);
- Log.i(TAG, String.format("getTypesVisibleToCaller: isPermitted? %s", isPermitted));
return getTypesForCaller(callingUid, userId, isPermitted);
}
diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java
index b87e109..970f1b5 100755
--- a/services/core/java/com/android/server/am/ActiveServices.java
+++ b/services/core/java/com/android/server/am/ActiveServices.java
@@ -1314,6 +1314,15 @@
if (!mRestartingServices.contains(r)) {
return;
}
+ if (!isServiceNeeded(r, false, false)) {
+ // Paranoia: is this service actually needed? In theory a service that is not
+ // needed should never remain on the restart list. In practice... well, there
+ // have been bugs where this happens, and bad things happen because the process
+ // ends up just being cached, so quickly killed, then restarted again and again.
+ // Let's not let that happen.
+ Slog.wtf(TAG, "Restarting service that is not needed: " + r);
+ return;
+ }
try {
bringUpServiceLocked(r, r.intent.getIntent().getFlags(), r.createdFromFg, true);
} catch (TransactionTooLargeException e) {
@@ -2043,6 +2052,13 @@
mAm.mProcessStats);
realStartServiceLocked(sr, proc, sr.createdFromFg);
didSomething = true;
+ if (!isServiceNeeded(sr, false, false)) {
+ // We were waiting for this service to start, but it is actually no
+ // longer needed. This could happen because bringDownServiceIfNeeded
+ // won't bring down a service that is pending... so now the pending
+ // is done, so let's drop it.
+ bringDownServiceLocked(sr);
+ }
}
} catch (RemoteException e) {
Slog.w(TAG, "Exception in new application when starting service "
@@ -2055,7 +2071,7 @@
// be weird to bring up the process but arbitrarily not let the services
// run at this point just because their restart time hasn't come up.
if (mRestartingServices.size() > 0) {
- ServiceRecord sr = null;
+ ServiceRecord sr;
for (int i=0; i<mRestartingServices.size(); i++) {
sr = mRestartingServices.get(i);
if (proc != sr.isolatedProc && (proc.uid != sr.appInfo.uid
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 8540f2a..701cb84 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -317,6 +317,9 @@
// How long we wait for a launched process to attach to the activity manager
// before we decide it's never going to come up for real.
static final int PROC_START_TIMEOUT = 10*1000;
+ // How long we wait for an attached process to publish its content providers
+ // before we decide it must be hung.
+ static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT = 10*1000;
// How long we wait for a launched process to attach to the activity manager
// before we decide it's never going to come up for real, when the process was
@@ -366,6 +369,10 @@
// we will consider it to be doing interaction for usage stats.
static final int SERVICE_USAGE_INTERACTION_TIME = 30*60*1000;
+ // Maximum amount of time we will allow to elapse before re-reporting usage stats
+ // interaction with foreground processes.
+ static final long USAGE_STATS_INTERACTION_INTERVAL = 24*60*60*1000L;
+
// Maximum number of users we allow to be running at a time.
static final int MAX_RUNNING_USERS = 3;
@@ -401,6 +408,17 @@
private static final int PERSISTENT_MASK =
ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT;
+
+ // Delay to disable app launch boost
+ static final int APP_BOOST_MESSAGE_DELAY = 3000;
+ // Lower delay than APP_BOOST_MESSAGE_DELAY to disable the boost
+ static final int APP_BOOST_TIMEOUT = 2500;
+
+ private static native int nativeMigrateToBoost();
+ private static native int nativeMigrateFromBoost();
+ private boolean mIsBoosted = false;
+ private long mBoostStartTime = 0;
+
/** All system services */
SystemServiceManager mSystemServiceManager;
@@ -1357,6 +1375,8 @@
static final int REPORT_TIME_TRACKER_MSG = 55;
static final int REPORT_USER_SWITCH_COMPLETE_MSG = 56;
static final int SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG = 57;
+ static final int APP_BOOST_DEACTIVATE_MSG = 58;
+ static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG = 59;
static final int FIRST_ACTIVITY_STACK_MSG = 100;
static final int FIRST_BROADCAST_QUEUE_MSG = 200;
@@ -1690,6 +1710,12 @@
processStartTimedOutLocked(app);
}
} break;
+ case CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG: {
+ ProcessRecord app = (ProcessRecord)msg.obj;
+ synchronized (ActivityManagerService.this) {
+ processContentProviderPublishTimedOutLocked(app);
+ }
+ } break;
case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
synchronized (ActivityManagerService.this) {
mStackSupervisor.doPendingActivityLaunchesLocked(true);
@@ -2032,6 +2058,20 @@
// it is finished we make sure it is reset to its default.
mUserIsMonkey = false;
} break;
+ case APP_BOOST_DEACTIVATE_MSG : {
+ synchronized(ActivityManagerService.this) {
+ if (mIsBoosted) {
+ if (mBoostStartTime < (SystemClock.uptimeMillis() - APP_BOOST_TIMEOUT)) {
+ nativeMigrateFromBoost();
+ mIsBoosted = false;
+ mBoostStartTime = 0;
+ } else {
+ Message newmsg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
+ mHandler.sendMessageDelayed(newmsg, APP_BOOST_TIMEOUT);
+ }
+ }
+ }
+ } break;
}
}
};
@@ -3115,6 +3155,16 @@
app = null;
}
+ // app launch boost for big.little configurations
+ // use cpusets to migrate freshly launched tasks to big cores
+ synchronized(ActivityManagerService.this) {
+ nativeMigrateToBoost();
+ mIsBoosted = true;
+ mBoostStartTime = SystemClock.uptimeMillis();
+ Message msg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
+ mHandler.sendMessageDelayed(msg, APP_BOOST_MESSAGE_DELAY);
+ }
+
// We don't have to do anything more if:
// (1) There is an existing application record; and
// (2) The caller doesn't think it is dead, OR there is no thread
@@ -5919,6 +5969,11 @@
return needRestart;
}
+ private final void processContentProviderPublishTimedOutLocked(ProcessRecord app) {
+ cleanupAppInLaunchingProvidersLocked(app, true);
+ removeProcessLocked(app, false, true, "timeout publishing content providers");
+ }
+
private final void processStartTimedOutLocked(ProcessRecord app) {
final int pid = app.pid;
boolean gone = false;
@@ -5945,7 +6000,7 @@
mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
}
// Take care of any launching providers waiting for this process.
- checkAppInLaunchingProvidersLocked(app, true);
+ cleanupAppInLaunchingProvidersLocked(app, true);
// Take care of any services that are waiting for the process.
mServices.processStartTimedOutLocked(app);
app.kill("start timeout", true);
@@ -6041,6 +6096,12 @@
boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
+ if (providers != null && checkAppInLaunchingProvidersLocked(app)) {
+ Message msg = mHandler.obtainMessage(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG);
+ msg.obj = app;
+ mHandler.sendMessageDelayed(msg, CONTENT_PROVIDER_PUBLISH_TIMEOUT);
+ }
+
if (!normalMode) {
Slog.i(TAG, "Launching preboot mode app: " + app);
}
@@ -9876,7 +9937,7 @@
final long origId = Binder.clearCallingIdentity();
final int N = providers.size();
- for (int i=0; i<N; i++) {
+ for (int i = 0; i < N; i++) {
ContentProviderHolder src = providers.get(i);
if (src == null || src.info == null || src.provider == null) {
continue;
@@ -9891,15 +9952,20 @@
mProviderMap.putProviderByName(names[j], dst);
}
- int NL = mLaunchingProviders.size();
+ int launchingCount = mLaunchingProviders.size();
int j;
- for (j=0; j<NL; j++) {
+ boolean wasInLaunchingProviders = false;
+ for (j = 0; j < launchingCount; j++) {
if (mLaunchingProviders.get(j) == dst) {
mLaunchingProviders.remove(j);
+ wasInLaunchingProviders = true;
j--;
- NL--;
+ launchingCount--;
}
}
+ if (wasInLaunchingProviders) {
+ mHandler.removeMessages(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG, r);
+ }
synchronized (dst) {
dst.provider = src.provider;
dst.proc = r;
@@ -15511,7 +15577,7 @@
app.pubProviders.clear();
// Take care of any launching providers waiting for this process.
- if (checkAppInLaunchingProvidersLocked(app, false)) {
+ if (cleanupAppInLaunchingProvidersLocked(app, false)) {
restart = true;
}
@@ -15635,7 +15701,17 @@
return false;
}
- boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
+ boolean checkAppInLaunchingProvidersLocked(ProcessRecord app) {
+ for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
+ ContentProviderRecord cpr = mLaunchingProviders.get(i);
+ if (cpr.launchingApp == app) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ boolean cleanupAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
// Look through the content providers we are waiting to have launched,
// and if any run in this process then either schedule a restart of
// the process or kill the client waiting for it if this process has
@@ -18613,7 +18689,8 @@
}
}
- private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now) {
+ private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now,
+ long nowElapsed) {
boolean success = true;
if (app.curRawAdj != app.setRawAdj) {
@@ -18717,7 +18794,7 @@
if (app.setProcState != app.curProcState) {
if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
"Proc state change of " + app.processName
- + " to " + app.curProcState);
+ + " to " + app.curProcState);
boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
if (setImportant && !curImportant) {
@@ -18728,14 +18805,14 @@
BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
synchronized (stats) {
app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
- app.pid, SystemClock.elapsedRealtime());
+ app.pid, nowElapsed);
}
app.lastCpuTime = app.curCpuTime;
}
// Inform UsageStats of important process state change
// Must be called before updating setProcState
- maybeUpdateUsageStatsLocked(app);
+ maybeUpdateUsageStatsLocked(app, nowElapsed);
app.setProcState = app.curProcState;
if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
@@ -18746,6 +18823,11 @@
} else {
app.procStateChanged = true;
}
+ } else if (app.reportedInteraction && (nowElapsed-app.interactionEventTime)
+ > USAGE_STATS_INTERACTION_INTERVAL) {
+ // For apps that sit around for a long time in the interactive state, we need
+ // to report this at least once a day so they don't go idle.
+ maybeUpdateUsageStatsLocked(app, nowElapsed);
}
if (changes != 0) {
@@ -18840,7 +18922,7 @@
}
}
- private void maybeUpdateUsageStatsLocked(ProcessRecord app) {
+ private void maybeUpdateUsageStatsLocked(ProcessRecord app, long nowElapsed) {
if (DEBUG_USAGE_STATS) {
Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList())
+ "] state changes: old = " + app.setProcState + ", new = "
@@ -18857,19 +18939,20 @@
isInteraction = true;
app.fgInteractionTime = 0;
} else if (app.curProcState <= ActivityManager.PROCESS_STATE_TOP_SLEEPING) {
- final long now = SystemClock.elapsedRealtime();
if (app.fgInteractionTime == 0) {
- app.fgInteractionTime = now;
+ app.fgInteractionTime = nowElapsed;
isInteraction = false;
} else {
- isInteraction = now > app.fgInteractionTime + SERVICE_USAGE_INTERACTION_TIME;
+ isInteraction = nowElapsed > app.fgInteractionTime + SERVICE_USAGE_INTERACTION_TIME;
}
} else {
isInteraction = app.curProcState
<= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
app.fgInteractionTime = 0;
}
- if (isInteraction && !app.reportedInteraction) {
+ if (isInteraction && (!app.reportedInteraction
+ || (nowElapsed-app.interactionEventTime) > USAGE_STATS_INTERACTION_INTERVAL)) {
+ app.interactionEventTime = nowElapsed;
String[] packages = app.getPackageList();
if (packages != null) {
for (int i = 0; i < packages.length; i++) {
@@ -18879,6 +18962,9 @@
}
}
app.reportedInteraction = isInteraction;
+ if (!isInteraction) {
+ app.interactionEventTime = 0;
+ }
}
private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
@@ -18901,7 +18987,7 @@
computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
- return applyOomAdjLocked(app, doingAll, now);
+ return applyOomAdjLocked(app, doingAll, now, SystemClock.elapsedRealtime());
}
final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
@@ -18993,6 +19079,7 @@
final ActivityRecord TOP_ACT = resumedAppLocked();
final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
final long now = SystemClock.uptimeMillis();
+ final long nowElapsed = SystemClock.elapsedRealtime();
final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
final int N = mLruProcesses.size();
@@ -19119,7 +19206,7 @@
}
}
- applyOomAdjLocked(app, true, now);
+ applyOomAdjLocked(app, true, now, nowElapsed);
// Count the number of process types.
switch (app.curProcState) {
diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
index 68ec0c6..29f8d6f 100644
--- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
@@ -2467,8 +2467,13 @@
final void doPendingActivityLaunchesLocked(boolean doResume) {
while (!mPendingActivityLaunches.isEmpty()) {
PendingActivityLaunch pal = mPendingActivityLaunches.remove(0);
- startActivityUncheckedLocked(pal.r, pal.sourceRecord, null, null, pal.startFlags,
- doResume && mPendingActivityLaunches.isEmpty(), null, null);
+
+ try {
+ startActivityUncheckedLocked(pal.r, pal.sourceRecord, null, null, pal.startFlags,
+ doResume && mPendingActivityLaunches.isEmpty(), null, null);
+ } catch (Exception e) {
+ Slog.w(TAG, "Exception during pending activity launch pal=" + pal, e);
+ }
}
}
@@ -3922,7 +3927,7 @@
mLockTaskModeTasks.add(task);
if (task.mLockTaskUid == -1) {
- task.mLockTaskUid = task.mCallingUid;
+ task.mLockTaskUid = task.effectiveUid;
}
if (andResume) {
diff --git a/services/core/java/com/android/server/am/BatteryStatsService.java b/services/core/java/com/android/server/am/BatteryStatsService.java
index 335288d..62768c3 100644
--- a/services/core/java/com/android/server/am/BatteryStatsService.java
+++ b/services/core/java/com/android/server/am/BatteryStatsService.java
@@ -171,12 +171,11 @@
public void publish(Context context) {
mContext = context;
- ServiceManager.addService(BatteryStats.SERVICE_NAME, asBinder());
- mStats.setNumSpeedSteps(new PowerProfile(mContext).getNumSpeedSteps());
mStats.setRadioScanningTimeout(mContext.getResources().getInteger(
com.android.internal.R.integer.config_radioScanningTimeout)
* 1000L);
mStats.setPowerProfile(new PowerProfile(context));
+ ServiceManager.addService(BatteryStats.SERVICE_NAME, asBinder());
}
/**
diff --git a/services/core/java/com/android/server/am/BroadcastQueue.java b/services/core/java/com/android/server/am/BroadcastQueue.java
index c56f591..089c33b 100644
--- a/services/core/java/com/android/server/am/BroadcastQueue.java
+++ b/services/core/java/com/android/server/am/BroadcastQueue.java
@@ -44,6 +44,7 @@
import android.os.UserHandle;
import android.util.EventLog;
import android.util.Slog;
+import android.util.TimeUtils;
import com.android.server.DeviceIdleController;
import static com.android.server.am.ActivityManagerDebugConfig.*;
@@ -1289,6 +1290,7 @@
final boolean dumpLocked(FileDescriptor fd, PrintWriter pw, String[] args,
int opti, boolean dumpAll, String dumpPackage, boolean needSep) {
+ SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
if (mParallelBroadcasts.size() > 0 || mOrderedBroadcasts.size() > 0
|| mPendingBroadcast != null) {
boolean printed = false;
@@ -1306,7 +1308,7 @@
pw.println(" Active broadcasts [" + mQueueName + "]:");
}
pw.println(" Active Broadcast " + mQueueName + " #" + i + ":");
- br.dump(pw, " ");
+ br.dump(pw, " ", sdf);
}
printed = false;
needSep = true;
@@ -1324,7 +1326,7 @@
pw.println(" Active ordered broadcasts [" + mQueueName + "]:");
}
pw.println(" Active Ordered Broadcast " + mQueueName + " #" + i + ":");
- mOrderedBroadcasts.get(i).dump(pw, " ");
+ mOrderedBroadcasts.get(i).dump(pw, " ", sdf);
}
if (dumpPackage == null || (mPendingBroadcast != null
&& dumpPackage.equals(mPendingBroadcast.callerPackage))) {
@@ -1333,7 +1335,7 @@
}
pw.println(" Pending broadcast [" + mQueueName + "]:");
if (mPendingBroadcast != null) {
- mPendingBroadcast.dump(pw, " ");
+ mPendingBroadcast.dump(pw, " ", sdf);
} else {
pw.println(" (null)");
}
@@ -1371,7 +1373,7 @@
if (dumpAll) {
pw.print(" Historical Broadcast " + mQueueName + " #");
pw.print(i); pw.println(":");
- r.dump(pw, " ");
+ r.dump(pw, " ", sdf);
} else {
pw.print(" #"); pw.print(i); pw.print(": "); pw.println(r);
pw.print(" ");
@@ -1405,7 +1407,6 @@
}
// done skipping; dump the remainder of the ring. 'i' is still the ordinal within
// the overall broadcast history.
- SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
do {
ringIndex = ringAdvance(ringIndex, -1, MAX_BROADCAST_SUMMARY_HISTORY);
Intent intent = mBroadcastSummaryHistory[ringIndex];
@@ -1427,9 +1428,19 @@
i++;
pw.print(" #"); pw.print(i); pw.print(": ");
pw.println(intent.toShortString(false, true, true, false));
- pw.print(" enq="); pw.print(sdf.format(new Date(mSummaryHistoryEnqueueTime[ringIndex])));
- pw.print(" disp="); pw.print(sdf.format(new Date(mSummaryHistoryDispatchTime[ringIndex])));
- pw.print(" fin="); pw.println(sdf.format(new Date(mSummaryHistoryFinishTime[ringIndex])));
+ pw.print(" ");
+ TimeUtils.formatDuration(mSummaryHistoryDispatchTime[ringIndex]
+ - mSummaryHistoryEnqueueTime[ringIndex], pw);
+ pw.print(" dispatch ");
+ TimeUtils.formatDuration(mSummaryHistoryFinishTime[ringIndex]
+ - mSummaryHistoryDispatchTime[ringIndex], pw);
+ pw.println(" finish");
+ pw.print(" enq=");
+ pw.print(sdf.format(new Date(mSummaryHistoryEnqueueTime[ringIndex])));
+ pw.print(" disp=");
+ pw.print(sdf.format(new Date(mSummaryHistoryDispatchTime[ringIndex])));
+ pw.print(" fin=");
+ pw.println(sdf.format(new Date(mSummaryHistoryFinishTime[ringIndex])));
Bundle bundle = intent.getExtras();
if (bundle != null) {
pw.print(" extras: "); pw.println(bundle.toString());
diff --git a/services/core/java/com/android/server/am/BroadcastRecord.java b/services/core/java/com/android/server/am/BroadcastRecord.java
index 1fbfd9f..b42bcff 100644
--- a/services/core/java/com/android/server/am/BroadcastRecord.java
+++ b/services/core/java/com/android/server/am/BroadcastRecord.java
@@ -32,6 +32,7 @@
import android.util.TimeUtils;
import java.io.PrintWriter;
+import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
@@ -88,7 +89,7 @@
ComponentName curComponent; // the receiver class that is currently running.
ActivityInfo curReceiver; // info about the receiver that is currently running.
- void dump(PrintWriter pw, String prefix) {
+ void dump(PrintWriter pw, String prefix, SimpleDateFormat sdf) {
final long now = SystemClock.uptimeMillis();
pw.print(prefix); pw.print(this); pw.print(" to user "); pw.println(userId);
@@ -114,13 +115,19 @@
pw.print(prefix); pw.print("options="); pw.println(options.toBundle());
}
pw.print(prefix); pw.print("enqueueClockTime=");
- pw.print(new Date(enqueueClockTime));
+ pw.print(sdf.format(new Date(enqueueClockTime)));
pw.print(" dispatchClockTime=");
- pw.println(new Date(dispatchClockTime));
+ pw.println(sdf.format(new Date(dispatchClockTime)));
pw.print(prefix); pw.print("dispatchTime=");
TimeUtils.formatDuration(dispatchTime, now, pw);
+ pw.print(" (");
+ TimeUtils.formatDuration(dispatchClockTime-enqueueClockTime, pw);
+ pw.print(" since enq)");
if (finishTime != 0) {
pw.print(" finishTime="); TimeUtils.formatDuration(finishTime, now, pw);
+ pw.print(" (");
+ TimeUtils.formatDuration(finishTime-dispatchTime, pw);
+ pw.print(" since disp)");
} else {
pw.print(" receiverTime="); TimeUtils.formatDuration(receiverTime, now, pw);
}
diff --git a/services/core/java/com/android/server/am/ProcessRecord.java b/services/core/java/com/android/server/am/ProcessRecord.java
index 9e74a19..3e9d0b8 100644
--- a/services/core/java/com/android/server/am/ProcessRecord.java
+++ b/services/core/java/com/android/server/am/ProcessRecord.java
@@ -114,6 +114,7 @@
boolean killed; // True once we know the process has been killed
boolean procStateChanged; // Keep track of whether we changed 'setAdj'.
boolean reportedInteraction;// Whether we have told usage stats about it being an interaction
+ long interactionEventTime; // The time we sent the last interaction event
long fgInteractionTime; // When we became foreground for interaction purposes
String waitingToKill; // Process is waiting to be killed when in the bg, and reason
IBinder forcingToForeground;// Token that is forcing this process to be foreground
@@ -297,6 +298,10 @@
if (reportedInteraction || fgInteractionTime != 0) {
pw.print(prefix); pw.print("reportedInteraction=");
pw.print(reportedInteraction);
+ if (interactionEventTime != 0) {
+ pw.print(" time=");
+ TimeUtils.formatDuration(interactionEventTime, SystemClock.elapsedRealtime(), pw);
+ }
if (fgInteractionTime != 0) {
pw.print(" fgInteractionTime=");
TimeUtils.formatDuration(fgInteractionTime, SystemClock.elapsedRealtime(), pw);
diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java
index 7565e9d..0f957db 100644
--- a/services/core/java/com/android/server/audio/AudioService.java
+++ b/services/core/java/com/android/server/audio/AudioService.java
@@ -502,7 +502,6 @@
private volatile IRingtonePlayer mRingtonePlayer;
private int mDeviceOrientation = Configuration.ORIENTATION_UNDEFINED;
- private int mDeviceRotation = Surface.ROTATION_0;
// Request to override default use of A2DP for media.
private boolean mBluetoothA2dpEnabled;
@@ -546,8 +545,6 @@
// If absolute volume is supported in AVRCP device
private boolean mAvrcpAbsVolSupported = false;
- private AudioOrientationEventListener mOrientationListener;
-
private static Long mLastDeviceConnectMsgTime = new Long(0);
private AudioManagerInternal.RingerModeDelegate mRingerModeDelegate;
@@ -670,15 +667,7 @@
}
mMonitorRotation = SystemProperties.getBoolean("ro.audio.monitorRotation", false);
if (mMonitorRotation) {
- mDeviceRotation = ((WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE))
- .getDefaultDisplay().getRotation();
- Log.v(TAG, "monitoring device rotation, initial=" + mDeviceRotation);
-
- mOrientationListener = new AudioOrientationEventListener(mContext);
- mOrientationListener.enable();
-
- // initialize rotation in AudioSystem
- setRotationForAudioSystem();
+ RotationHelper.init(mContext, mAudioHandler);
}
context.registerReceiverAsUser(mReceiver, UserHandle.ALL, intentFilter, null, null);
@@ -808,7 +797,7 @@
setOrientationForAudioSystem();
}
if (mMonitorRotation) {
- setRotationForAudioSystem();
+ RotationHelper.updateOrientation();
}
synchronized (mBluetoothA2dpEnabledLock) {
@@ -1061,25 +1050,6 @@
return (index * mStreamStates[dstStream].getMaxIndex() + mStreamStates[srcStream].getMaxIndex() / 2) / mStreamStates[srcStream].getMaxIndex();
}
- private class AudioOrientationEventListener
- extends OrientationEventListener {
- public AudioOrientationEventListener(Context context) {
- super(context);
- }
-
- @Override
- public void onOrientationChanged(int orientation) {
- //Even though we're responding to phone orientation events,
- //use display rotation so audio stays in sync with video/dialogs
- int newRotation = ((WindowManager) mContext.getSystemService(
- Context.WINDOW_SERVICE)).getDefaultDisplay().getRotation();
- if (newRotation != mDeviceRotation) {
- mDeviceRotation = newRotation;
- setRotationForAudioSystem();
- }
- }
- }
-
///////////////////////////////////////////////////////////////////////////
// IPC methods
///////////////////////////////////////////////////////////////////////////
@@ -2527,11 +2497,14 @@
}
/** @see AudioManager#setBluetoothScoOn(boolean) */
- public void setBluetoothScoOn(boolean on){
+ public void setBluetoothScoOn(boolean on) {
if (!checkAudioSettingsPermission("setBluetoothScoOn()")) {
return;
}
+ setBluetoothScoOnInt(on);
+ }
+ public void setBluetoothScoOnInt(boolean on) {
if (on) {
mForcedUseForComm = AudioSystem.FORCE_BT_SCO;
} else if (mForcedUseForComm == AudioSystem.FORCE_BT_SCO) {
@@ -2892,6 +2865,8 @@
mScoAudioState = SCO_STATE_INACTIVE;
broadcastScoConnectionState(AudioManager.SCO_AUDIO_STATE_DISCONNECTED);
}
+ AudioSystem.setParameters("A2dpSuspended=false");
+ setBluetoothScoOnInt(false);
}
private void broadcastScoConnectionState(int state) {
@@ -3762,8 +3737,29 @@
int index;
if (mIsMuted) {
index = 0;
- } else if (((device & AudioSystem.DEVICE_OUT_ALL_A2DP) != 0 && mAvrcpAbsVolSupported)
- || ((device & mFullVolumeDevices) != 0)) {
+ } else if ((device & AudioSystem.DEVICE_OUT_ALL_A2DP) != 0 && mAvrcpAbsVolSupported) {
+ /* Special handling for Bluetooth Absolute Volume scenario
+ * If we send full audio gain, some accessories are too loud even at its lowest
+ * volume. We are not able to enumerate all such accessories, so here is the
+ * workaround from phone side.
+ * For the lowest volume steps 1 and 2, restrict audio gain to 50% and 75%.
+ * For volume step 0, set audio gain to 0 as some accessories won't mute on their end.
+ */
+ int i = (getIndex(device) + 5)/10;
+ if (i == 0) {
+ // 0% for volume 0
+ index = 0;
+ } else if (i == 1) {
+ // 50% for volume 1
+ index = (int)(mIndexMax * 0.5) /10;
+ } else if (i == 2) {
+ // 75% for volume 2
+ index = (int)(mIndexMax * 0.75) /10;
+ } else {
+ // otherwise, full gain
+ index = (mIndexMax + 5)/10;
+ }
+ } else if ((device & mFullVolumeDevices) != 0) {
index = (mIndexMax + 5)/10;
} else {
index = (getIndex(device) + 5)/10;
@@ -5064,14 +5060,13 @@
}
} else if (action.equals(Intent.ACTION_SCREEN_ON)) {
if (mMonitorRotation) {
- mOrientationListener.onOrientationChanged(0); //argument is ignored anyway
- mOrientationListener.enable();
+ RotationHelper.enable();
}
AudioSystem.setParameters("screen_state=on");
} else if (action.equals(Intent.ACTION_SCREEN_OFF)) {
if (mMonitorRotation) {
//reduce wakeups (save current) by only listening when display is on
- mOrientationListener.disable();
+ RotationHelper.disable();
}
AudioSystem.setParameters("screen_state=off");
} else if (action.equals(Intent.ACTION_CONFIGURATION_CHANGED)) {
@@ -5316,6 +5311,7 @@
}
}
+ //TODO move to an external "orientation helper" class
private void setOrientationForAudioSystem() {
switch (mDeviceOrientation) {
case Configuration.ORIENTATION_LANDSCAPE:
@@ -5339,26 +5335,6 @@
}
}
- private void setRotationForAudioSystem() {
- switch (mDeviceRotation) {
- case Surface.ROTATION_0:
- AudioSystem.setParameters("rotation=0");
- break;
- case Surface.ROTATION_90:
- AudioSystem.setParameters("rotation=90");
- break;
- case Surface.ROTATION_180:
- AudioSystem.setParameters("rotation=180");
- break;
- case Surface.ROTATION_270:
- AudioSystem.setParameters("rotation=270");
- break;
- default:
- Log.e(TAG, "Unknown device rotation");
- }
- }
-
-
// Handles request to override default use of A2DP for media.
// Must be called synchronized on mConnectedDevices
public void setBluetoothA2dpOnInt(boolean on) {
diff --git a/services/core/java/com/android/server/audio/RotationHelper.java b/services/core/java/com/android/server/audio/RotationHelper.java
new file mode 100644
index 0000000..359cc36
--- /dev/null
+++ b/services/core/java/com/android/server/audio/RotationHelper.java
@@ -0,0 +1,211 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.audio;
+
+import android.content.Context;
+import android.media.AudioSystem;
+import android.os.Handler;
+import android.util.Log;
+import android.view.OrientationEventListener;
+import android.view.Surface;
+import android.view.WindowManager;
+
+import com.android.server.policy.WindowOrientationListener;
+
+/**
+ * Class to handle device rotation events for AudioService, and forward device rotation
+ * to the audio HALs through AudioSystem.
+ *
+ * The role of this class is to monitor device orientation changes, and upon rotation,
+ * verify the UI orientation. In case of a change, send the new orientation, in increments
+ * of 90deg, through AudioSystem.
+ *
+ * Note that even though we're responding to device orientation events, we always
+ * query the display rotation so audio stays in sync with video/dialogs. This is
+ * done with .getDefaultDisplay().getRotation() from WINDOW_SERVICE.
+ */
+class RotationHelper {
+
+ private static final String TAG = "AudioService.RotationHelper";
+
+ private static AudioOrientationListener sOrientationListener;
+ private static AudioWindowOrientationListener sWindowOrientationListener;
+
+ private static final Object sRotationLock = new Object();
+ private static int sDeviceRotation = Surface.ROTATION_0; // R/W synchronized on sRotationLock
+
+ private static Context sContext;
+
+ /**
+ * post conditions:
+ * - (sWindowOrientationListener != null) xor (sOrientationListener != null)
+ * - sWindowOrientationListener xor sOrientationListener is enabled
+ * - sContext != null
+ */
+ static void init(Context context, Handler handler) {
+ if (context == null) {
+ throw new IllegalArgumentException("Invalid null context");
+ }
+ sContext = context;
+ sWindowOrientationListener = new AudioWindowOrientationListener(context, handler);
+ sWindowOrientationListener.enable();
+ if (!sWindowOrientationListener.canDetectOrientation()) {
+ // cannot use com.android.server.policy.WindowOrientationListener, revert to public
+ // orientation API
+ Log.i(TAG, "Not using WindowOrientationListener, reverting to OrientationListener");
+ sWindowOrientationListener.disable();
+ sWindowOrientationListener = null;
+ sOrientationListener = new AudioOrientationListener(context);
+ sOrientationListener.enable();
+ }
+ }
+
+ static void enable() {
+ if (sWindowOrientationListener != null) {
+ sWindowOrientationListener.enable();
+ } else {
+ sOrientationListener.enable();
+ }
+ updateOrientation();
+ }
+
+ static void disable() {
+ if (sWindowOrientationListener != null) {
+ sWindowOrientationListener.disable();
+ } else {
+ sOrientationListener.disable();
+ }
+ }
+
+ /**
+ * Query current display rotation and publish the change if any.
+ */
+ static void updateOrientation() {
+ // Even though we're responding to device orientation events,
+ // use display rotation so audio stays in sync with video/dialogs
+ int newRotation = ((WindowManager) sContext.getSystemService(
+ Context.WINDOW_SERVICE)).getDefaultDisplay().getRotation();
+ synchronized(sRotationLock) {
+ if (newRotation != sDeviceRotation) {
+ sDeviceRotation = newRotation;
+ publishRotation(sDeviceRotation);
+ }
+ }
+ }
+
+ private static void publishRotation(int rotation) {
+ Log.v(TAG, "publishing device rotation =" + rotation + " (x90deg)");
+ switch (rotation) {
+ case Surface.ROTATION_0:
+ AudioSystem.setParameters("rotation=0");
+ break;
+ case Surface.ROTATION_90:
+ AudioSystem.setParameters("rotation=90");
+ break;
+ case Surface.ROTATION_180:
+ AudioSystem.setParameters("rotation=180");
+ break;
+ case Surface.ROTATION_270:
+ AudioSystem.setParameters("rotation=270");
+ break;
+ default:
+ Log.e(TAG, "Unknown device rotation");
+ }
+ }
+
+ /**
+ * Uses android.view.OrientationEventListener
+ */
+ final static class AudioOrientationListener extends OrientationEventListener {
+ AudioOrientationListener(Context context) {
+ super(context);
+ }
+
+ @Override
+ public void onOrientationChanged(int orientation) {
+ updateOrientation();
+ }
+ }
+
+ /**
+ * Uses com.android.server.policy.WindowOrientationListener
+ */
+ final static class AudioWindowOrientationListener extends WindowOrientationListener {
+ private static RotationCheckThread sRotationCheckThread;
+
+ AudioWindowOrientationListener(Context context, Handler handler) {
+ super(context, handler);
+ }
+
+ public void onProposedRotationChanged(int rotation) {
+ updateOrientation();
+ if (sRotationCheckThread != null) {
+ sRotationCheckThread.endCheck();
+ }
+ sRotationCheckThread = new RotationCheckThread();
+ sRotationCheckThread.beginCheck();
+ }
+ }
+
+ /**
+ * When com.android.server.policy.WindowOrientationListener report an orientation change,
+ * the UI may not have rotated yet. This thread polls with gradually increasing delays
+ * the new orientation.
+ */
+ final static class RotationCheckThread extends Thread {
+ // how long to wait between each rotation check
+ private final int[] WAIT_TIMES_MS = { 10, 20, 50, 100, 100, 200, 200, 500 };
+ private int mWaitCounter;
+ private final Object mCounterLock = new Object();
+
+ RotationCheckThread() {
+ super("RotationCheck");
+ }
+
+ void beginCheck() {
+ synchronized(mCounterLock) {
+ mWaitCounter = 0;
+ }
+ try {
+ start();
+ } catch (IllegalStateException e) { }
+ }
+
+ void endCheck() {
+ synchronized(mCounterLock) {
+ mWaitCounter = WAIT_TIMES_MS.length;
+ }
+ }
+
+ public void run() {
+ while (mWaitCounter < WAIT_TIMES_MS.length) {
+ int waitTimeMs;
+ synchronized(mCounterLock) {
+ waitTimeMs = mWaitCounter < WAIT_TIMES_MS.length ?
+ WAIT_TIMES_MS[mWaitCounter] : 0;
+ mWaitCounter++;
+ }
+ try {
+ if (waitTimeMs > 0) {
+ sleep(waitTimeMs);
+ updateOrientation();
+ }
+ } catch (InterruptedException e) { }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/services/core/java/com/android/server/camera/CameraService.java b/services/core/java/com/android/server/camera/CameraService.java
index 0be24f4..f82454a 100644
--- a/services/core/java/com/android/server/camera/CameraService.java
+++ b/services/core/java/com/android/server/camera/CameraService.java
@@ -23,13 +23,17 @@
import android.content.pm.UserInfo;
import android.hardware.ICameraService;
import android.hardware.ICameraServiceProxy;
+import android.nfc.INfcAdapter;
import android.os.Handler;
import android.os.IBinder;
+import android.os.Binder;
import android.os.Message;
import android.os.Process;
import android.os.RemoteException;
import android.os.UserManager;
+import android.os.SystemProperties;
import android.util.Slog;
+import android.util.ArraySet;
import com.android.server.ServiceThread;
import com.android.server.SystemService;
@@ -44,8 +48,10 @@
*
* @hide
*/
-public class CameraService extends SystemService implements Handler.Callback {
+public class CameraService extends SystemService
+ implements Handler.Callback, IBinder.DeathRecipient {
private static final String TAG = "CameraService_proxy";
+ private static final boolean DEBUG = false;
/**
* This must match the ICameraService.aidl definition
@@ -58,6 +64,16 @@
public static final int NO_EVENT = 0; // NOOP
public static final int USER_SWITCHED = 1; // User changed, argument is the new user handle
+ // State arguments to use with the notifyCameraState call from camera service:
+ public static final int CAMERA_STATE_OPEN = 0;
+ public static final int CAMERA_STATE_ACTIVE = 1;
+ public static final int CAMERA_STATE_IDLE = 2;
+ public static final int CAMERA_STATE_CLOSED = 3;
+
+ // Flags arguments to NFC adapter to enable/disable NFC
+ public static final int DISABLE_POLLING_FLAGS = 0x1000;
+ public static final int ENABLE_POLLING_FLAGS = 0x0000;
+
// Handler message codes
private static final int MSG_SWITCH_USER = 1;
@@ -72,6 +88,17 @@
private Set<Integer> mEnabledCameraUsers;
private int mLastUser;
+ private ICameraService mCameraServiceRaw;
+
+ private final ArraySet<String> mActiveCameraIds = new ArraySet<>();
+
+ private static final String NFC_NOTIFICATION_PROP = "ro.camera.notify_nfc";
+ private static final String NFC_SERVICE_BINDER_NAME = "nfc";
+ private static final IBinder nfcInterfaceToken = new Binder();
+
+ private final boolean mNotifyNfc;
+ private int mActiveCameraCount = 0;
+
private final BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
@@ -102,6 +129,14 @@
public void pingForUserUpdate() {
notifySwitchWithRetries(30);
}
+
+ @Override
+ public void notifyCameraState(String cameraId, int newCameraState) {
+ String state = cameraStateToString(newCameraState);
+ if (DEBUG) Slog.v(TAG, "Camera " + cameraId + " state now " + state);
+
+ updateActivityCount(cameraId, newCameraState);
+ }
};
public CameraService(Context context) {
@@ -110,6 +145,9 @@
mHandlerThread = new ServiceThread(TAG, Process.THREAD_PRIORITY_DISPLAY, /*allowTo*/false);
mHandlerThread.start();
mHandler = new Handler(mHandlerThread.getLooper(), this);
+
+ mNotifyNfc = SystemProperties.getInt(NFC_NOTIFICATION_PROP, 0) > 0;
+ if (DEBUG) Slog.v(TAG, "Notify NFC behavior is " + (mNotifyNfc ? "active" : "disabled"));
}
@Override
@@ -161,13 +199,32 @@
}
}
+ /**
+ * Handle the death of the native camera service
+ */
+ @Override
+ public void binderDied() {
+ if (DEBUG) Slog.w(TAG, "Native camera service has died");
+ synchronized(mLock) {
+ mCameraServiceRaw = null;
+
+ // All cameras reset to idle on camera service death
+ boolean wasEmpty = mActiveCameraIds.isEmpty();
+ mActiveCameraIds.clear();
+
+ if ( mNotifyNfc && !wasEmpty ) {
+ notifyNfcService(/*enablePolling*/ true);
+ }
+ }
+ }
+
private void switchUserLocked(int userHandle) {
Set<Integer> currentUserHandles = getEnabledUserHandles(userHandle);
mLastUser = userHandle;
if (mEnabledCameraUsers == null || !mEnabledCameraUsers.equals(currentUserHandles)) {
// Some user handles have been added or removed, update mediaserver.
mEnabledCameraUsers = currentUserHandles;
- notifyMediaserver(USER_SWITCHED, currentUserHandles);
+ notifyMediaserverLocked(USER_SWITCHED, currentUserHandles);
}
}
@@ -187,7 +244,7 @@
if (mEnabledCameraUsers == null) {
return;
}
- if (notifyMediaserver(USER_SWITCHED, mEnabledCameraUsers)) {
+ if (notifyMediaserverLocked(USER_SWITCHED, mEnabledCameraUsers)) {
retries = 0;
}
}
@@ -199,19 +256,27 @@
RETRY_DELAY_TIME);
}
- private boolean notifyMediaserver(int eventType, Set<Integer> updatedUserHandles) {
+ private boolean notifyMediaserverLocked(int eventType, Set<Integer> updatedUserHandles) {
// Forward the user switch event to the native camera service running in the mediaserver
// process.
- IBinder cameraServiceBinder = getBinderService(CAMERA_SERVICE_BINDER_NAME);
- if (cameraServiceBinder == null) {
- Slog.w(TAG, "Could not notify mediaserver, camera service not available.");
- return false; // Camera service not active, cannot evict user clients.
+ if (mCameraServiceRaw == null) {
+ IBinder cameraServiceBinder = getBinderService(CAMERA_SERVICE_BINDER_NAME);
+ if (cameraServiceBinder == null) {
+ Slog.w(TAG, "Could not notify mediaserver, camera service not available.");
+ return false; // Camera service not active, cannot evict user clients.
+ }
+ try {
+ cameraServiceBinder.linkToDeath(this, /*flags*/ 0);
+ } catch (RemoteException e) {
+ Slog.w(TAG, "Could not link to death of native camera service");
+ return false;
+ }
+
+ mCameraServiceRaw = ICameraService.Stub.asInterface(cameraServiceBinder);
}
- ICameraService cameraServiceRaw = ICameraService.Stub.asInterface(cameraServiceBinder);
-
try {
- cameraServiceRaw.notifySystemEvent(eventType, toArray(updatedUserHandles));
+ mCameraServiceRaw.notifySystemEvent(eventType, toArray(updatedUserHandles));
} catch (RemoteException e) {
Slog.w(TAG, "Could not notify mediaserver, remote exception: " + e);
// Not much we can do if camera service is dead.
@@ -220,6 +285,44 @@
return true;
}
+ private void updateActivityCount(String cameraId, int newCameraState) {
+ synchronized(mLock) {
+ boolean wasEmpty = mActiveCameraIds.isEmpty();
+ switch (newCameraState) {
+ case CAMERA_STATE_OPEN:
+ break;
+ case CAMERA_STATE_ACTIVE:
+ mActiveCameraIds.add(cameraId);
+ break;
+ case CAMERA_STATE_IDLE:
+ case CAMERA_STATE_CLOSED:
+ mActiveCameraIds.remove(cameraId);
+ break;
+ }
+ boolean isEmpty = mActiveCameraIds.isEmpty();
+ if ( mNotifyNfc && (wasEmpty != isEmpty) ) {
+ notifyNfcService(isEmpty);
+ }
+ }
+ }
+
+ private void notifyNfcService(boolean enablePolling) {
+
+ IBinder nfcServiceBinder = getBinderService(NFC_SERVICE_BINDER_NAME);
+ if (nfcServiceBinder == null) {
+ Slog.w(TAG, "Could not connect to NFC service to notify it of camera state");
+ return;
+ }
+ INfcAdapter nfcAdapterRaw = INfcAdapter.Stub.asInterface(nfcServiceBinder);
+ int flags = enablePolling ? ENABLE_POLLING_FLAGS : DISABLE_POLLING_FLAGS;
+ if (DEBUG) Slog.v(TAG, "Setting NFC reader mode to flags " + flags);
+ try {
+ nfcAdapterRaw.setReaderMode(nfcInterfaceToken, null, flags, null);
+ } catch (RemoteException e) {
+ Slog.w(TAG, "Could not notify NFC service, remote exception: " + e);
+ }
+ }
+
private static int[] toArray(Collection<Integer> c) {
int len = c.size();
int[] ret = new int[len];
@@ -229,4 +332,15 @@
}
return ret;
}
+
+ private static String cameraStateToString(int newCameraState) {
+ switch (newCameraState) {
+ case CAMERA_STATE_OPEN: return "CAMERA_STATE_OPEN";
+ case CAMERA_STATE_ACTIVE: return "CAMERA_STATE_ACTIVE";
+ case CAMERA_STATE_IDLE: return "CAMERA_STATE_IDLE";
+ case CAMERA_STATE_CLOSED: return "CAMERA_STATE_CLOSED";
+ default: break;
+ }
+ return "CAMERA_STATE_UNKNOWN";
+ }
}
diff --git a/services/core/java/com/android/server/connectivity/KeepalivePacketData.java b/services/core/java/com/android/server/connectivity/KeepalivePacketData.java
new file mode 100644
index 0000000..2ccfdd1
--- /dev/null
+++ b/services/core/java/com/android/server/connectivity/KeepalivePacketData.java
@@ -0,0 +1,137 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.connectivity;
+
+import android.system.OsConstants;
+import android.net.ConnectivityManager;
+import android.net.NetworkUtils;
+import android.net.util.IpUtils;
+
+import java.net.Inet4Address;
+import java.net.Inet6Address;
+import java.net.InetAddress;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+
+import static android.net.ConnectivityManager.PacketKeepalive.*;
+
+/**
+ * Represents the actual packets that are sent by the
+ * {@link android.net.ConnectivityManager.PacketKeepalive} API.
+ *
+ * @hide
+ */
+public class KeepalivePacketData {
+ /** Protocol of the packet to send; one of the OsConstants.ETH_P_* values. */
+ public final int protocol;
+
+ /** Source IP address */
+ public final InetAddress srcAddress;
+
+ /** Destination IP address */
+ public final InetAddress dstAddress;
+
+ /** Source port */
+ public final int srcPort;
+
+ /** Destination port */
+ public final int dstPort;
+
+ /** Destination MAC address. Can change if routing changes. */
+ public byte[] dstMac;
+
+ /** Packet data. A raw byte string of packet data, not including the link-layer header. */
+ public final byte[] data;
+
+ private static final int IPV4_HEADER_LENGTH = 20;
+ private static final int UDP_HEADER_LENGTH = 8;
+
+ protected KeepalivePacketData(InetAddress srcAddress, int srcPort,
+ InetAddress dstAddress, int dstPort, byte[] data) throws InvalidPacketException {
+ this.srcAddress = srcAddress;
+ this.dstAddress = dstAddress;
+ this.srcPort = srcPort;
+ this.dstPort = dstPort;
+ this.data = data;
+
+ // Check we have two IP addresses of the same family.
+ if (srcAddress == null || dstAddress == null ||
+ !srcAddress.getClass().getName().equals(dstAddress.getClass().getName())) {
+ throw new InvalidPacketException(ERROR_INVALID_IP_ADDRESS);
+ }
+
+ // Set the protocol.
+ if (this.dstAddress instanceof Inet4Address) {
+ this.protocol = OsConstants.ETH_P_IP;
+ } else if (this.dstAddress instanceof Inet6Address) {
+ this.protocol = OsConstants.ETH_P_IPV6;
+ } else {
+ throw new InvalidPacketException(ERROR_INVALID_IP_ADDRESS);
+ }
+
+ // Check the ports.
+ if (!IpUtils.isValidUdpOrTcpPort(srcPort) || !IpUtils.isValidUdpOrTcpPort(dstPort)) {
+ throw new InvalidPacketException(ERROR_INVALID_PORT);
+ }
+ }
+
+ public static class InvalidPacketException extends Exception {
+ final public int error;
+ public InvalidPacketException(int error) {
+ this.error = error;
+ }
+ }
+
+ /**
+ * Creates an IPsec NAT-T keepalive packet with the specified parameters.
+ */
+ public static KeepalivePacketData nattKeepalivePacket(
+ InetAddress srcAddress, int srcPort,
+ InetAddress dstAddress, int dstPort) throws InvalidPacketException {
+
+ if (!(srcAddress instanceof Inet4Address) || !(dstAddress instanceof Inet4Address)) {
+ throw new InvalidPacketException(ERROR_INVALID_IP_ADDRESS);
+ }
+
+ if (dstPort != NATT_PORT) {
+ throw new InvalidPacketException(ERROR_INVALID_PORT);
+ }
+
+ int length = IPV4_HEADER_LENGTH + UDP_HEADER_LENGTH + 1;
+ ByteBuffer buf = ByteBuffer.allocate(length);
+ buf.order(ByteOrder.BIG_ENDIAN);
+ buf.putShort((short) 0x4500); // IP version and TOS
+ buf.putShort((short) length);
+ buf.putInt(0); // ID, flags, offset
+ buf.put((byte) 64); // TTL
+ buf.put((byte) OsConstants.IPPROTO_UDP);
+ int ipChecksumOffset = buf.position();
+ buf.putShort((short) 0); // IP checksum
+ buf.put(srcAddress.getAddress());
+ buf.put(dstAddress.getAddress());
+ buf.putShort((short) srcPort);
+ buf.putShort((short) dstPort);
+ buf.putShort((short) (length - 20)); // UDP length
+ int udpChecksumOffset = buf.position();
+ buf.putShort((short) 0); // UDP checksum
+ buf.put((byte) 0xff); // NAT-T keepalive
+ buf.putShort(ipChecksumOffset, IpUtils.ipChecksum(buf, 0));
+ buf.putShort(udpChecksumOffset, IpUtils.udpChecksum(buf, 0, IPV4_HEADER_LENGTH));
+
+ return new KeepalivePacketData(srcAddress, srcPort, dstAddress, dstPort, buf.array());
+ }
+}
diff --git a/services/core/java/com/android/server/connectivity/KeepaliveTracker.java b/services/core/java/com/android/server/connectivity/KeepaliveTracker.java
new file mode 100644
index 0000000..90c9ddf
--- /dev/null
+++ b/services/core/java/com/android/server/connectivity/KeepaliveTracker.java
@@ -0,0 +1,376 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.connectivity;
+
+import com.android.internal.util.HexDump;
+import com.android.internal.util.IndentingPrintWriter;
+import com.android.server.connectivity.KeepalivePacketData;
+import com.android.server.connectivity.NetworkAgentInfo;
+import android.net.ConnectivityManager;
+import android.net.ConnectivityManager.PacketKeepalive;
+import android.net.LinkAddress;
+import android.net.NetworkAgent;
+import android.net.NetworkUtils;
+import android.net.util.IpUtils;
+import android.os.Binder;
+import android.os.IBinder;
+import android.os.Handler;
+import android.os.Message;
+import android.os.Messenger;
+import android.os.Process;
+import android.os.RemoteException;
+import android.system.OsConstants;
+import android.util.Log;
+import android.util.Pair;
+
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.net.Inet4Address;
+import java.net.Inet6Address;
+import java.net.InetAddress;
+import java.util.ArrayList;
+import java.util.HashMap;
+
+import static android.net.ConnectivityManager.PacketKeepalive.*;
+import static android.net.NetworkAgent.CMD_START_PACKET_KEEPALIVE;
+import static android.net.NetworkAgent.CMD_STOP_PACKET_KEEPALIVE;
+import static android.net.NetworkAgent.EVENT_PACKET_KEEPALIVE;
+
+/**
+ * Manages packet keepalive requests.
+ *
+ * Provides methods to stop and start keepalive requests, and keeps track of keepalives across all
+ * networks. This class is tightly coupled to ConnectivityService. It is not thread-safe and its
+ * methods must be called only from the ConnectivityService handler thread.
+ */
+public class KeepaliveTracker {
+
+ private static final String TAG = "KeepaliveTracker";
+ private static final boolean DBG = true;
+
+ public static final String PERMISSION = android.Manifest.permission.PACKET_KEEPALIVE_OFFLOAD;
+
+ /** Keeps track of keepalive requests. */
+ private final HashMap <NetworkAgentInfo, HashMap<Integer, KeepaliveInfo>> mKeepalives =
+ new HashMap<> ();
+ private final Handler mConnectivityServiceHandler;
+
+ public KeepaliveTracker(Handler handler) {
+ mConnectivityServiceHandler = handler;
+ }
+
+ /**
+ * Tracks information about a packet keepalive.
+ *
+ * All information about this keepalive is known at construction time except the slot number,
+ * which is only returned when the hardware has successfully started the keepalive.
+ */
+ class KeepaliveInfo implements IBinder.DeathRecipient {
+ // Bookkeping data.
+ private final Messenger mMessenger;
+ private final IBinder mBinder;
+ private final int mUid;
+ private final int mPid;
+ private final NetworkAgentInfo mNai;
+
+ /** Keepalive slot. A small integer that identifies this keepalive among the ones handled
+ * by this network. */
+ private int mSlot = PacketKeepalive.NO_KEEPALIVE;
+
+ // Packet data.
+ private final KeepalivePacketData mPacket;
+ private final int mInterval;
+
+ // Whether the keepalive is started or not.
+ public boolean isStarted;
+
+ public KeepaliveInfo(Messenger messenger, IBinder binder, NetworkAgentInfo nai,
+ KeepalivePacketData packet, int interval) {
+ mMessenger = messenger;
+ mBinder = binder;
+ mPid = Binder.getCallingPid();
+ mUid = Binder.getCallingUid();
+
+ mNai = nai;
+ mPacket = packet;
+ mInterval = interval;
+
+ try {
+ mBinder.linkToDeath(this, 0);
+ } catch (RemoteException e) {
+ binderDied();
+ }
+ }
+
+ public NetworkAgentInfo getNai() {
+ return mNai;
+ }
+
+ public String toString() {
+ return new StringBuffer("KeepaliveInfo [")
+ .append(" network=").append(mNai.network)
+ .append(" isStarted=").append(isStarted)
+ .append(" ")
+ .append(IpUtils.addressAndPortToString(mPacket.srcAddress, mPacket.srcPort))
+ .append("->")
+ .append(IpUtils.addressAndPortToString(mPacket.dstAddress, mPacket.dstPort))
+ .append(" interval=" + mInterval)
+ .append(" data=" + HexDump.toHexString(mPacket.data))
+ .append(" uid=").append(mUid).append(" pid=").append(mPid)
+ .append(" ]")
+ .toString();
+ }
+
+ /** Sends a message back to the application via its PacketKeepalive.Callback. */
+ void notifyMessenger(int slot, int err) {
+ KeepaliveTracker.this.notifyMessenger(mMessenger, slot, err);
+ }
+
+ /** Called when the application process is killed. */
+ public void binderDied() {
+ // Not called from ConnectivityService handler thread, so send it a message.
+ mConnectivityServiceHandler.obtainMessage(
+ NetworkAgent.CMD_STOP_PACKET_KEEPALIVE,
+ mSlot, PacketKeepalive.BINDER_DIED, mNai.network).sendToTarget();
+ }
+
+ void unlinkDeathRecipient() {
+ if (mBinder != null) {
+ mBinder.unlinkToDeath(this, 0);
+ }
+ }
+
+ private int checkNetworkConnected() {
+ if (!mNai.networkInfo.isConnectedOrConnecting()) {
+ return ERROR_INVALID_NETWORK;
+ }
+ return SUCCESS;
+ }
+
+ private int checkSourceAddress() {
+ // Check that we have the source address.
+ for (InetAddress address : mNai.linkProperties.getAddresses()) {
+ if (address.equals(mPacket.srcAddress)) {
+ return SUCCESS;
+ }
+ }
+ return ERROR_INVALID_IP_ADDRESS;
+ }
+
+ private int checkInterval() {
+ return mInterval >= 20 ? SUCCESS : ERROR_INVALID_INTERVAL;
+ }
+
+ private int isValid() {
+ synchronized (mNai) {
+ int error = checkInterval();
+ if (error == SUCCESS) error = checkNetworkConnected();
+ if (error == SUCCESS) error = checkSourceAddress();
+ return error;
+ }
+ }
+
+ void start(int slot) {
+ int error = isValid();
+ if (error == SUCCESS) {
+ mSlot = slot;
+ Log.d(TAG, "Starting keepalive " + mSlot + " on " + mNai.name());
+ mNai.asyncChannel.sendMessage(CMD_START_PACKET_KEEPALIVE, slot, mInterval, mPacket);
+ } else {
+ notifyMessenger(NO_KEEPALIVE, error);
+ return;
+ }
+ }
+
+ void stop(int reason) {
+ int uid = Binder.getCallingUid();
+ if (uid != mUid && uid != Process.SYSTEM_UID) {
+ if (DBG) {
+ Log.e(TAG, "Cannot stop unowned keepalive " + mSlot + " on " + mNai.network);
+ }
+ }
+ if (isStarted) {
+ Log.d(TAG, "Stopping keepalive " + mSlot + " on " + mNai.name());
+ mNai.asyncChannel.sendMessage(CMD_STOP_PACKET_KEEPALIVE, mSlot);
+ }
+ // TODO: at the moment we unconditionally return failure here. In cases where the
+ // NetworkAgent is alive, should we ask it to reply, so it can return failure?
+ notifyMessenger(mSlot, reason);
+ unlinkDeathRecipient();
+ }
+ }
+
+ void notifyMessenger(Messenger messenger, int slot, int err) {
+ Message message = Message.obtain();
+ message.what = EVENT_PACKET_KEEPALIVE;
+ message.arg1 = slot;
+ message.arg2 = err;
+ message.obj = null;
+ try {
+ messenger.send(message);
+ } catch (RemoteException e) {
+ // Process died?
+ }
+ }
+
+ private int findFirstFreeSlot(NetworkAgentInfo nai) {
+ HashMap networkKeepalives = mKeepalives.get(nai);
+ if (networkKeepalives == null) {
+ networkKeepalives = new HashMap<Integer, KeepaliveInfo>();
+ mKeepalives.put(nai, networkKeepalives);
+ }
+
+ // Find the lowest-numbered free slot. Slot numbers start from 1, because that's what two
+ // separate chipset implementations independently came up with.
+ int slot;
+ for (slot = 1; slot <= networkKeepalives.size(); slot++) {
+ if (networkKeepalives.get(slot) == null) {
+ return slot;
+ }
+ }
+ return slot;
+ }
+
+ public void handleStartKeepalive(Message message) {
+ KeepaliveInfo ki = (KeepaliveInfo) message.obj;
+ NetworkAgentInfo nai = ki.getNai();
+ int slot = findFirstFreeSlot(nai);
+ mKeepalives.get(nai).put(slot, ki);
+ ki.start(slot);
+ }
+
+ public void handleStopAllKeepalives(NetworkAgentInfo nai, int reason) {
+ HashMap <Integer, KeepaliveInfo> networkKeepalives = mKeepalives.get(nai);
+ if (networkKeepalives != null) {
+ for (KeepaliveInfo ki : networkKeepalives.values()) {
+ ki.stop(reason);
+ }
+ networkKeepalives.clear();
+ mKeepalives.remove(nai);
+ }
+ }
+
+ public void handleStopKeepalive(NetworkAgentInfo nai, int slot, int reason) {
+ String networkName = (nai == null) ? "(null)" : nai.name();
+ HashMap <Integer, KeepaliveInfo> networkKeepalives = mKeepalives.get(nai);
+ if (networkKeepalives == null) {
+ Log.e(TAG, "Attempt to stop keepalive on nonexistent network " + networkName);
+ return;
+ }
+ KeepaliveInfo ki = networkKeepalives.get(slot);
+ if (ki == null) {
+ Log.e(TAG, "Attempt to stop nonexistent keepalive " + slot + " on " + networkName);
+ return;
+ }
+ ki.stop(reason);
+ networkKeepalives.remove(slot);
+ if (networkKeepalives.isEmpty()) {
+ mKeepalives.remove(nai);
+ }
+ }
+
+ public void handleCheckKeepalivesStillValid(NetworkAgentInfo nai) {
+ HashMap <Integer, KeepaliveInfo> networkKeepalives = mKeepalives.get(nai);
+ if (networkKeepalives != null) {
+ ArrayList<Pair<Integer, Integer>> invalidKeepalives = new ArrayList<>();
+ for (int slot : networkKeepalives.keySet()) {
+ int error = networkKeepalives.get(slot).isValid();
+ if (error != SUCCESS) {
+ invalidKeepalives.add(Pair.create(slot, error));
+ }
+ }
+ for (Pair<Integer, Integer> slotAndError: invalidKeepalives) {
+ handleStopKeepalive(nai, slotAndError.first, slotAndError.second);
+ }
+ }
+ }
+
+ public void handleEventPacketKeepalive(NetworkAgentInfo nai, Message message) {
+ int slot = message.arg1;
+ int reason = message.arg2;
+
+ KeepaliveInfo ki = null;
+ try {
+ ki = mKeepalives.get(nai).get(slot);
+ } catch(NullPointerException e) {}
+ if (ki == null) {
+ Log.e(TAG, "Event for unknown keepalive " + slot + " on " + nai.name());
+ return;
+ }
+
+ if (reason == SUCCESS && !ki.isStarted) {
+ // Keepalive successfully started.
+ if (DBG) Log.d(TAG, "Started keepalive " + slot + " on " + nai.name());
+ ki.isStarted = true;
+ ki.notifyMessenger(slot, reason);
+ } else {
+ // Keepalive successfully stopped, or error.
+ ki.isStarted = false;
+ if (reason == SUCCESS) {
+ if (DBG) Log.d(TAG, "Successfully stopped keepalive " + slot + " on " + nai.name());
+ } else {
+ if (DBG) Log.d(TAG, "Keepalive " + slot + " on " + nai.name() + " error " + reason);
+ }
+ handleStopKeepalive(nai, slot, reason);
+ }
+ }
+
+ public void startNattKeepalive(NetworkAgentInfo nai, int intervalSeconds, Messenger messenger,
+ IBinder binder, String srcAddrString, int srcPort, String dstAddrString, int dstPort) {
+ if (nai == null) {
+ notifyMessenger(messenger, NO_KEEPALIVE, ERROR_INVALID_NETWORK);
+ return;
+ }
+
+ InetAddress srcAddress, dstAddress;
+ try {
+ srcAddress = NetworkUtils.numericToInetAddress(srcAddrString);
+ dstAddress = NetworkUtils.numericToInetAddress(dstAddrString);
+ } catch (IllegalArgumentException e) {
+ notifyMessenger(messenger, NO_KEEPALIVE, ERROR_INVALID_IP_ADDRESS);
+ return;
+ }
+
+ KeepalivePacketData packet;
+ try {
+ packet = KeepalivePacketData.nattKeepalivePacket(
+ srcAddress, srcPort, dstAddress, NATT_PORT);
+ } catch (KeepalivePacketData.InvalidPacketException e) {
+ notifyMessenger(messenger, NO_KEEPALIVE, e.error);
+ return;
+ }
+ KeepaliveInfo ki = new KeepaliveInfo(messenger, binder, nai, packet, intervalSeconds);
+ Log.d(TAG, "Created keepalive: " + ki.toString());
+ mConnectivityServiceHandler.obtainMessage(
+ NetworkAgent.CMD_START_PACKET_KEEPALIVE, ki).sendToTarget();
+ }
+
+ public void dump(IndentingPrintWriter pw) {
+ pw.println("Packet keepalives:");
+ pw.increaseIndent();
+ for (NetworkAgentInfo nai : mKeepalives.keySet()) {
+ pw.println(nai.name());
+ pw.increaseIndent();
+ for (int slot : mKeepalives.get(nai).keySet()) {
+ KeepaliveInfo ki = mKeepalives.get(nai).get(slot);
+ pw.println(slot + ": " + ki.toString());
+ }
+ pw.decreaseIndent();
+ }
+ pw.decreaseIndent();
+ }
+}
diff --git a/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java b/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java
index 39333f6..0029279 100644
--- a/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java
+++ b/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java
@@ -195,6 +195,12 @@
request.networkCapabilities.satisfiedByNetworkCapabilities(networkCapabilities);
}
+ public boolean satisfiesImmutableCapabilitiesOf(NetworkRequest request) {
+ return created &&
+ request.networkCapabilities.satisfiedByImmutableNetworkCapabilities(
+ networkCapabilities);
+ }
+
public boolean isVPN() {
return networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_VPN);
}
diff --git a/services/core/java/com/android/server/connectivity/NetworkDiagnostics.java b/services/core/java/com/android/server/connectivity/NetworkDiagnostics.java
index aca6991..5fd39c0 100644
--- a/services/core/java/com/android/server/connectivity/NetworkDiagnostics.java
+++ b/services/core/java/com/android/server/connectivity/NetworkDiagnostics.java
@@ -18,6 +18,7 @@
import static android.system.OsConstants.*;
+import android.net.LinkAddress;
import android.net.LinkProperties;
import android.net.Network;
import android.net.NetworkUtils;
@@ -27,6 +28,7 @@
import android.system.Os;
import android.system.StructTimeval;
import android.text.TextUtils;
+import android.util.Pair;
import com.android.internal.util.IndentingPrintWriter;
@@ -149,6 +151,8 @@
}
private final Map<InetAddress, Measurement> mIcmpChecks = new HashMap<>();
+ private final Map<Pair<InetAddress, InetAddress>, Measurement> mExplicitSourceIcmpChecks =
+ new HashMap<>();
private final Map<InetAddress, Measurement> mDnsUdpChecks = new HashMap<>();
private final String mDescription;
@@ -178,7 +182,11 @@
for (RouteInfo route : mLinkProperties.getRoutes()) {
if (route.hasGateway()) {
- prepareIcmpMeasurement(route.getGateway());
+ InetAddress gateway = route.getGateway();
+ prepareIcmpMeasurement(gateway);
+ if (route.isIPv6Default()) {
+ prepareExplicitSourceIcmpMeasurements(gateway);
+ }
}
}
for (InetAddress nameserver : mLinkProperties.getDnsServers()) {
@@ -213,6 +221,20 @@
}
}
+ private void prepareExplicitSourceIcmpMeasurements(InetAddress target) {
+ for (LinkAddress l : mLinkProperties.getLinkAddresses()) {
+ InetAddress source = l.getAddress();
+ if (source instanceof Inet6Address && l.isGlobalPreferred()) {
+ Pair<InetAddress, InetAddress> srcTarget = new Pair<>(source, target);
+ if (!mExplicitSourceIcmpChecks.containsKey(srcTarget)) {
+ Measurement measurement = new Measurement();
+ measurement.thread = new Thread(new IcmpCheck(source, target, measurement));
+ mExplicitSourceIcmpChecks.put(srcTarget, measurement);
+ }
+ }
+ }
+ }
+
private void prepareDnsMeasurement(InetAddress target) {
if (!mDnsUdpChecks.containsKey(target)) {
Measurement measurement = new Measurement();
@@ -222,13 +244,16 @@
}
private int totalMeasurementCount() {
- return mIcmpChecks.size() + mDnsUdpChecks.size();
+ return mIcmpChecks.size() + mExplicitSourceIcmpChecks.size() + mDnsUdpChecks.size();
}
private void startMeasurements() {
for (Measurement measurement : mIcmpChecks.values()) {
measurement.thread.start();
}
+ for (Measurement measurement : mExplicitSourceIcmpChecks.values()) {
+ measurement.thread.start();
+ }
for (Measurement measurement : mDnsUdpChecks.values()) {
measurement.thread.start();
}
@@ -261,6 +286,10 @@
pw.println(entry.getValue().toString());
}
}
+ for (Map.Entry<Pair<InetAddress, InetAddress>, Measurement> entry :
+ mExplicitSourceIcmpChecks.entrySet()) {
+ pw.println(entry.getValue().toString());
+ }
for (Map.Entry<InetAddress, Measurement> entry : mDnsUdpChecks.entrySet()) {
if (entry.getKey() instanceof Inet4Address) {
pw.println(entry.getValue().toString());
@@ -276,13 +305,15 @@
private class SimpleSocketCheck implements Closeable {
+ protected final InetAddress mSource; // Usually null.
protected final InetAddress mTarget;
protected final int mAddressFamily;
protected final Measurement mMeasurement;
protected FileDescriptor mFileDescriptor;
protected SocketAddress mSocketAddress;
- protected SimpleSocketCheck(InetAddress target, Measurement measurement) {
+ protected SimpleSocketCheck(
+ InetAddress source, InetAddress target, Measurement measurement) {
mMeasurement = measurement;
if (target instanceof Inet6Address) {
@@ -301,6 +332,14 @@
mTarget = target;
mAddressFamily = AF_INET;
}
+
+ // We don't need to check the scope ID here because we currently only do explicit-source
+ // measurements from global IPv6 addresses.
+ mSource = source;
+ }
+
+ protected SimpleSocketCheck(InetAddress target, Measurement measurement) {
+ this(null, target, measurement);
}
protected void setupSocket(
@@ -314,6 +353,9 @@
SOL_SOCKET, SO_RCVTIMEO, StructTimeval.fromMillis(readTimeout));
// TODO: Use IP_RECVERR/IPV6_RECVERR, pending OsContants availability.
mNetwork.bindSocket(mFileDescriptor);
+ if (mSource != null) {
+ Os.bind(mFileDescriptor, mSource, 0);
+ }
Os.connect(mFileDescriptor, mTarget, dstPort);
mSocketAddress = Os.getsockname(mFileDescriptor);
}
@@ -343,8 +385,8 @@
private final int mProtocol;
private final int mIcmpType;
- public IcmpCheck(InetAddress target, Measurement measurement) {
- super(target, measurement);
+ public IcmpCheck(InetAddress source, InetAddress target, Measurement measurement) {
+ super(source, target, measurement);
if (mAddressFamily == AF_INET6) {
mProtocol = IPPROTO_ICMPV6;
@@ -359,6 +401,10 @@
mMeasurement.description += " dst{" + mTarget.getHostAddress() + "}";
}
+ public IcmpCheck(InetAddress target, Measurement measurement) {
+ this(null, target, measurement);
+ }
+
@Override
public void run() {
// Check if this measurement has already failed during setup.
diff --git a/services/core/java/com/android/server/content/AppIdleMonitor.java b/services/core/java/com/android/server/content/AppIdleMonitor.java
index fe5c2da..2d768d8 100644
--- a/services/core/java/com/android/server/content/AppIdleMonitor.java
+++ b/services/core/java/com/android/server/content/AppIdleMonitor.java
@@ -50,8 +50,8 @@
}
}
- boolean isAppIdle(String packageName, int userId) {
- return !mAppIdleParoleOn && mUsageStats.isAppIdle(packageName, userId);
+ boolean isAppIdle(String packageName, int uidForAppId, int userId) {
+ return !mAppIdleParoleOn && mUsageStats.isAppIdle(packageName, uidForAppId, userId);
}
@Override
diff --git a/services/core/java/com/android/server/content/SyncManager.java b/services/core/java/com/android/server/content/SyncManager.java
index b61f90e..ef086da 100644
--- a/services/core/java/com/android/server/content/SyncManager.java
+++ b/services/core/java/com/android/server/content/SyncManager.java
@@ -2604,6 +2604,31 @@
}
continue;
}
+ String packageName = getPackageName(op.target);
+ ApplicationInfo ai = null;
+ if (packageName != null) {
+ try {
+ ai = mContext.getPackageManager().getApplicationInfo(packageName,
+ PackageManager.GET_UNINSTALLED_PACKAGES
+ | PackageManager.GET_DISABLED_COMPONENTS);
+ } catch (NameNotFoundException e) {
+ operationIterator.remove();
+ mSyncStorageEngine.deleteFromPending(op.pendingOperation);
+ continue;
+ }
+ }
+ // If app is considered idle, then skip for now and backoff
+ if (ai != null
+ && mAppIdleMonitor.isAppIdle(packageName, ai.uid, op.target.userId)) {
+ increaseBackoffSetting(op);
+ op.appIdle = true;
+ if (isLoggable) {
+ Log.v(TAG, "Sync backing off idle app " + packageName);
+ }
+ continue;
+ } else {
+ op.appIdle = false;
+ }
if (!isOperationValidLocked(op)) {
operationIterator.remove();
mSyncStorageEngine.deleteFromPending(op.pendingOperation);
@@ -2622,19 +2647,6 @@
}
continue;
}
- String packageName = getPackageName(op.target);
- // If app is considered idle, then skip for now and backoff
- if (packageName != null
- && mAppIdleMonitor.isAppIdle(packageName, op.target.userId)) {
- increaseBackoffSetting(op);
- op.appIdle = true;
- if (isLoggable) {
- Log.v(TAG, "Sync backing off idle app " + packageName);
- }
- continue;
- } else {
- op.appIdle = false;
- }
// Add this sync to be run.
operations.add(op);
}
diff --git a/services/core/java/com/android/server/display/ColorFade.java b/services/core/java/com/android/server/display/ColorFade.java
index bb4dbc3..835ba17 100644
--- a/services/core/java/com/android/server/display/ColorFade.java
+++ b/services/core/java/com/android/server/display/ColorFade.java
@@ -74,6 +74,7 @@
// Set to true when the animation context has been fully prepared.
private boolean mPrepared;
+ private boolean mCreatedResources;
private int mMode;
private final DisplayManagerInternal mDisplayManagerInternal;
@@ -169,6 +170,7 @@
}
// Done.
+ mCreatedResources = true;
mPrepared = true;
// Dejanking optimization.
@@ -313,6 +315,34 @@
}
/**
+ * Dismisses the color fade animation resources.
+ *
+ * This function destroys the resources that are created for the color fade
+ * animation but does not clean up the surface.
+ */
+ public void dismissResources() {
+ if (DEBUG) {
+ Slog.d(TAG, "dismissResources");
+ }
+
+ if (mCreatedResources) {
+ attachEglContext();
+ try {
+ destroyScreenshotTexture();
+ destroyGLShaders();
+ destroyGLBuffers();
+ destroyEglSurface();
+ } finally {
+ detachEglContext();
+ }
+ // This is being called with no active context so shouldn't be
+ // needed but is safer to not change for now.
+ GLES20.glFlush();
+ mCreatedResources = false;
+ }
+ }
+
+ /**
* Dismisses the color fade animation surface and cleans up.
*
* To prevent stray photons from leaking out after the color fade has been
@@ -325,17 +355,8 @@
}
if (mPrepared) {
- attachEglContext();
- try {
- destroyScreenshotTexture();
- destroyGLShaders();
- destroyGLBuffers();
- destroyEglSurface();
- } finally {
- detachEglContext();
- }
+ dismissResources();
destroySurface();
- GLES20.glFlush();
mPrepared = false;
}
}
diff --git a/services/core/java/com/android/server/display/DisplayAdapter.java b/services/core/java/com/android/server/display/DisplayAdapter.java
index 6ba25a5..701b9f1 100644
--- a/services/core/java/com/android/server/display/DisplayAdapter.java
+++ b/services/core/java/com/android/server/display/DisplayAdapter.java
@@ -49,6 +49,13 @@
*/
private static final AtomicInteger NEXT_DISPLAY_MODE_ID = new AtomicInteger(1); // 0 = no mode.
+ /**
+ * Used to generate globally unique color transform ids.
+ *
+ * Valid IDs start at 1 with 0 as the sentinel value for the default mode.
+ */
+ private static final AtomicInteger NEXT_COLOR_TRANSFORM_ID = new AtomicInteger(1);
+
// Called with SyncRoot lock held.
public DisplayAdapter(DisplayManagerService.SyncRoot syncRoot,
Context context, Handler handler, Listener listener, String name) {
@@ -134,6 +141,11 @@
NEXT_DISPLAY_MODE_ID.getAndIncrement(), width, height, refreshRate);
}
+ public static Display.ColorTransform createColorTransform(int colorTransform) {
+ return new Display.ColorTransform(
+ NEXT_COLOR_TRANSFORM_ID.getAndIncrement(), colorTransform);
+ }
+
public interface Listener {
public void onDisplayDeviceEvent(DisplayDevice device, int event);
public void onTraversalRequested();
diff --git a/services/core/java/com/android/server/display/DisplayDevice.java b/services/core/java/com/android/server/display/DisplayDevice.java
index 93bda46..7af0bdb 100644
--- a/services/core/java/com/android/server/display/DisplayDevice.java
+++ b/services/core/java/com/android/server/display/DisplayDevice.java
@@ -135,7 +135,7 @@
/**
* Sets the mode, if supported.
*/
- public void requestModeInTransactionLocked(int id) {
+ public void requestColorTransformAndModeInTransactionLocked(int colorTransformId, int modeId) {
}
/**
diff --git a/services/core/java/com/android/server/display/DisplayDeviceInfo.java b/services/core/java/com/android/server/display/DisplayDeviceInfo.java
index 97ada15..55ba302 100644
--- a/services/core/java/com/android/server/display/DisplayDeviceInfo.java
+++ b/services/core/java/com/android/server/display/DisplayDeviceInfo.java
@@ -155,6 +155,15 @@
*/
public Display.Mode[] supportedModes = Display.Mode.EMPTY_ARRAY;
+ /** The active color transform of the display */
+ public int colorTransformId;
+
+ /** The default color transform of the display */
+ public int defaultColorTransformId;
+
+ /** The supported color transforms of the display */
+ public Display.ColorTransform[] supportedColorTransforms = Display.ColorTransform.EMPTY_ARRAY;
+
/**
* The nominal apparent density of the display in DPI used for layout calculations.
* This density is sensitive to the viewing distance. A big TV and a tablet may have
@@ -276,6 +285,9 @@
|| modeId != other.modeId
|| defaultModeId != other.defaultModeId
|| !Arrays.equals(supportedModes, other.supportedModes)
+ || colorTransformId != other.colorTransformId
+ || defaultColorTransformId != other.defaultColorTransformId
+ || !Arrays.equals(supportedColorTransforms, other.supportedColorTransforms)
|| densityDpi != other.densityDpi
|| xDpi != other.xDpi
|| yDpi != other.yDpi
@@ -306,6 +318,9 @@
modeId = other.modeId;
defaultModeId = other.defaultModeId;
supportedModes = other.supportedModes;
+ colorTransformId = other.colorTransformId;
+ defaultColorTransformId = other.defaultColorTransformId;
+ supportedColorTransforms = other.supportedColorTransforms;
densityDpi = other.densityDpi;
xDpi = other.xDpi;
yDpi = other.yDpi;
@@ -331,6 +346,9 @@
sb.append(", modeId ").append(modeId);
sb.append(", defaultModeId ").append(defaultModeId);
sb.append(", supportedModes ").append(Arrays.toString(supportedModes));
+ sb.append(", colorTransformId ").append(colorTransformId);
+ sb.append(", defaultColorTransformId ").append(defaultColorTransformId);
+ sb.append(", supportedColorTransforms ").append(Arrays.toString(supportedColorTransforms));
sb.append(", density ").append(densityDpi);
sb.append(", ").append(xDpi).append(" x ").append(yDpi).append(" dpi");
sb.append(", appVsyncOff ").append(appVsyncOffsetNanos);
diff --git a/services/core/java/com/android/server/display/DisplayManagerService.java b/services/core/java/com/android/server/display/DisplayManagerService.java
index b2ab797..6a6570b 100644
--- a/services/core/java/com/android/server/display/DisplayManagerService.java
+++ b/services/core/java/com/android/server/display/DisplayManagerService.java
@@ -540,6 +540,17 @@
}
}
+ private void requestColorTransformInternal(int displayId, int colorTransformId) {
+ synchronized (mSyncRoot) {
+ LogicalDisplay display = mLogicalDisplays.get(displayId);
+ if (display != null &&
+ display.getRequestedColorTransformIdLocked() != colorTransformId) {
+ display.setRequestedColorTransformIdLocked(colorTransformId);
+ scheduleTraversalLocked(false);
+ }
+ }
+ }
+
private int createVirtualDisplayInternal(IVirtualDisplayCallback callback,
IMediaProjection projection, int callingUid, String packageName,
String name, int width, int height, int densityDpi, Surface surface, int flags) {
@@ -1340,6 +1351,19 @@
}
@Override // Binder call
+ public void requestColorTransform(int displayId, int colorTransformId) {
+ mContext.enforceCallingOrSelfPermission(
+ Manifest.permission.CONFIGURE_DISPLAY_COLOR_TRANSFORM,
+ "Permission required to change the display color transform");
+ final long token = Binder.clearCallingIdentity();
+ try {
+ requestColorTransformInternal(displayId, colorTransformId);
+ } finally {
+ Binder.restoreCallingIdentity(token);
+ }
+ }
+
+ @Override // Binder call
public int createVirtualDisplay(IVirtualDisplayCallback callback,
IMediaProjection projection, String packageName, String name,
int width, int height, int densityDpi, Surface surface, int flags) {
diff --git a/services/core/java/com/android/server/display/DisplayPowerController.java b/services/core/java/com/android/server/display/DisplayPowerController.java
index 452378f..7b49530 100644
--- a/services/core/java/com/android/server/display/DisplayPowerController.java
+++ b/services/core/java/com/android/server/display/DisplayPowerController.java
@@ -837,6 +837,7 @@
if (mPendingScreenOff && target != Display.STATE_OFF) {
setScreenState(Display.STATE_OFF);
mPendingScreenOff = false;
+ mPowerState.dismissColorFadeResources();
}
if (target == Display.STATE_ON) {
@@ -910,6 +911,7 @@
// A black surface is already hiding the contents of the screen.
setScreenState(Display.STATE_OFF);
mPendingScreenOff = false;
+ mPowerState.dismissColorFadeResources();
} else if (performScreenOffTransition
&& mPowerState.prepareColorFade(mContext,
mColorFadeFadesConfig ?
diff --git a/services/core/java/com/android/server/display/DisplayPowerState.java b/services/core/java/com/android/server/display/DisplayPowerState.java
index f53ccc9..9862516 100644
--- a/services/core/java/com/android/server/display/DisplayPowerState.java
+++ b/services/core/java/com/android/server/display/DisplayPowerState.java
@@ -187,7 +187,7 @@
}
/**
- * Dismisses the electron beam surface.
+ * Dismisses the color fade surface.
*/
public void dismissColorFade() {
mColorFade.dismiss();
@@ -195,6 +195,13 @@
mColorFadeReady = true;
}
+ /**
+ * Dismisses the color fade resources.
+ */
+ public void dismissColorFadeResources() {
+ mColorFade.dismissResources();
+ }
+
/**
* Sets the level of the electron beam steering current.
*
@@ -341,7 +348,8 @@
private int mPendingBacklight = INITIAL_BACKLIGHT;
private int mActualState = INITIAL_SCREEN_STATE;
private int mActualBacklight = INITIAL_BACKLIGHT;
- private boolean mChangeInProgress;
+ private boolean mStateChangeInProgress;
+ private boolean mBacklightChangeInProgress;
public PhotonicModulator() {
super("PhotonicModulator");
@@ -349,7 +357,9 @@
public boolean setState(int state, int backlight) {
synchronized (mLock) {
- if (state != mPendingState || backlight != mPendingBacklight) {
+ boolean stateChanged = state != mPendingState;
+ boolean backlightChanged = backlight != mPendingBacklight;
+ if (stateChanged || backlightChanged) {
if (DEBUG) {
Slog.d(TAG, "Requesting new screen state: state="
+ Display.stateToString(state) + ", backlight=" + backlight);
@@ -358,12 +368,15 @@
mPendingState = state;
mPendingBacklight = backlight;
- if (!mChangeInProgress) {
- mChangeInProgress = true;
+ boolean changeInProgress = mStateChangeInProgress || mBacklightChangeInProgress;
+ mStateChangeInProgress = stateChanged;
+ mBacklightChangeInProgress = backlightChanged;
+
+ if (!changeInProgress) {
mLock.notifyAll();
}
}
- return !mChangeInProgress;
+ return !mStateChangeInProgress;
}
}
@@ -375,7 +388,8 @@
pw.println(" mPendingBacklight=" + mPendingBacklight);
pw.println(" mActualState=" + Display.stateToString(mActualState));
pw.println(" mActualBacklight=" + mActualBacklight);
- pw.println(" mChangeInProgress=" + mChangeInProgress);
+ pw.println(" mStateChangeInProgress=" + mStateChangeInProgress);
+ pw.println(" mBacklightChangeInProgress=" + mBacklightChangeInProgress);
}
}
@@ -392,10 +406,15 @@
stateChanged = (state != mActualState);
backlight = mPendingBacklight;
backlightChanged = (backlight != mActualBacklight);
- if (!stateChanged && !backlightChanged) {
- // All changed applied, notify outer class and wait for more.
- mChangeInProgress = false;
+ if (!stateChanged) {
+ // State changed applied, notify outer class.
postScreenUpdateThreadSafe();
+ mStateChangeInProgress = false;
+ }
+ if (!backlightChanged) {
+ mBacklightChangeInProgress = false;
+ }
+ if (!stateChanged && !backlightChanged) {
try {
mLock.wait();
} catch (InterruptedException ex) { }
diff --git a/services/core/java/com/android/server/display/LocalDisplayAdapter.java b/services/core/java/com/android/server/display/LocalDisplayAdapter.java
index 517a825..088d96e 100644
--- a/services/core/java/com/android/server/display/LocalDisplayAdapter.java
+++ b/services/core/java/com/android/server/display/LocalDisplayAdapter.java
@@ -31,6 +31,7 @@
import android.os.Trace;
import android.util.Slog;
import android.util.SparseArray;
+import android.util.SparseBooleanArray;
import android.view.Display;
import android.view.DisplayEventReceiver;
import android.view.Surface;
@@ -38,6 +39,7 @@
import java.io.PrintWriter;
import java.util.ArrayList;
+import java.util.Arrays;
/**
* A display adapter for the local displays managed by Surface Flinger.
@@ -143,14 +145,22 @@
private final int mBuiltInDisplayId;
private final Light mBacklight;
private final SparseArray<DisplayModeRecord> mSupportedModes = new SparseArray<>();
+ private final SparseArray<Display.ColorTransform> mSupportedColorTransforms =
+ new SparseArray<>();
private DisplayDeviceInfo mInfo;
private boolean mHavePendingChanges;
private int mState = Display.STATE_UNKNOWN;
private int mBrightness = PowerManager.BRIGHTNESS_DEFAULT;
+ private int mActivePhysIndex;
private int mDefaultModeId;
private int mActiveModeId;
private boolean mActiveModeInvalid;
+ private int mDefaultColorTransformId;
+ private int mActiveColorTransformId;
+ private boolean mActiveColorTransformInvalid;
+
+ private SurfaceControl.PhysicalDisplayInfo mDisplayInfos[];
public LocalDisplayDevice(IBinder displayToken, int builtInDisplayId,
SurfaceControl.PhysicalDisplayInfo[] physicalDisplayInfos, int activeDisplayInfo) {
@@ -167,22 +177,73 @@
public boolean updatePhysicalDisplayInfoLocked(
SurfaceControl.PhysicalDisplayInfo[] physicalDisplayInfos, int activeDisplayInfo) {
- // Build an updated list of all existing modes.
- boolean modesAdded = false;
- DisplayModeRecord activeRecord = null;
- ArrayList<DisplayModeRecord> records = new ArrayList<DisplayModeRecord>();
+ mDisplayInfos = Arrays.copyOf(physicalDisplayInfos, physicalDisplayInfos.length);
+ mActivePhysIndex = activeDisplayInfo;
+ ArrayList<Display.ColorTransform> colorTransforms = new ArrayList<>();
+
+ // Build an updated list of all existing color transforms.
+ boolean colorTransformsAdded = false;
+ Display.ColorTransform activeColorTransform = null;
for (int i = 0; i < physicalDisplayInfos.length; i++) {
SurfaceControl.PhysicalDisplayInfo info = physicalDisplayInfos[i];
+ // First check to see if we've already added this color transform
+ boolean existingMode = false;
+ for (int j = 0; j < colorTransforms.size(); j++) {
+ if (colorTransforms.get(j).getColorTransform() == info.colorTransform) {
+ existingMode = true;
+ break;
+ }
+ }
+ if (existingMode) {
+ continue;
+ }
+ Display.ColorTransform colorTransform = findColorTransform(info);
+ if (colorTransform == null) {
+ colorTransform = createColorTransform(info.colorTransform);
+ colorTransformsAdded = true;
+ }
+ colorTransforms.add(colorTransform);
+ if (i == activeDisplayInfo) {
+ activeColorTransform = colorTransform;
+ }
+ }
+
+ // Build an updated list of all existing modes.
+ ArrayList<DisplayModeRecord> records = new ArrayList<DisplayModeRecord>();
+ boolean modesAdded = false;
+ for (int i = 0; i < physicalDisplayInfos.length; i++) {
+ SurfaceControl.PhysicalDisplayInfo info = physicalDisplayInfos[i];
+ // First, check to see if we've already added a matching mode. Since not all
+ // configuration options are exposed via Display.Mode, it's possible that we have
+ // multiple PhysicalDisplayInfos that would generate the same Display.Mode.
+ boolean existingMode = false;
+ for (int j = 0; j < records.size(); j++) {
+ if (records.get(j).hasMatchingMode(info)) {
+ existingMode = true;
+ break;
+ }
+ }
+ if (existingMode) {
+ continue;
+ }
+ // If we haven't already added a mode for this configuration to the new set of
+ // supported modes then check to see if we have one in the prior set of supported
+ // modes to reuse.
DisplayModeRecord record = findDisplayModeRecord(info);
- if (record != null) {
- record.mPhysIndex = i;
- } else {
- record = new DisplayModeRecord(info, i);
+ if (record == null) {
+ record = new DisplayModeRecord(info);
modesAdded = true;
}
records.add(record);
- if (i == activeDisplayInfo) {
+ }
+
+ // Get the currently active mode
+ DisplayModeRecord activeRecord = null;
+ for (int i = 0; i < records.size(); i++) {
+ DisplayModeRecord record = records.get(i);
+ if (record.hasMatchingMode(physicalDisplayInfos[activeDisplayInfo])){
activeRecord = record;
+ break;
}
}
// Check whether surface flinger spontaneously changed modes out from under us. Schedule
@@ -192,25 +253,48 @@
mActiveModeInvalid = true;
sendTraversalRequestLocked();
}
- // If no modes were added and we have the same number of modes as before, then nothing
- // actually changed except possibly the physical index (which we only care about when
- // setting the mode) so we're done.
- if (records.size() == mSupportedModes.size() && !modesAdded) {
+ // Check whether surface flinger spontaneously changed color transforms out from under
+ // us.
+ if (mActiveColorTransformId != 0
+ && mActiveColorTransformId != activeColorTransform.getId()) {
+ mActiveColorTransformInvalid = true;
+ sendTraversalRequestLocked();
+ }
+
+ boolean colorTransformsChanged =
+ colorTransforms.size() != mSupportedColorTransforms.size()
+ || colorTransformsAdded;
+ boolean recordsChanged = records.size() != mSupportedModes.size() || modesAdded;
+ // If neither the records nor the supported color transforms have changed then we're
+ // done here.
+ if (!recordsChanged && !colorTransformsChanged) {
return false;
}
// Update the index of modes.
mHavePendingChanges = true;
+
mSupportedModes.clear();
for (DisplayModeRecord record : records) {
mSupportedModes.put(record.mMode.getModeId(), record);
}
- // Update the default mode if needed.
- if (mSupportedModes.indexOfKey(mDefaultModeId) < 0) {
+ mSupportedColorTransforms.clear();
+ for (Display.ColorTransform colorTransform : colorTransforms) {
+ mSupportedColorTransforms.put(colorTransform.getId(), colorTransform);
+ }
+
+ // Update the default mode and color transform if needed. This needs to be done in
+ // tandem so we always have a default state to fall back to.
+ if (findDisplayInfoIndexLocked(mDefaultColorTransformId, mDefaultModeId) < 0) {
if (mDefaultModeId != 0) {
- Slog.w(TAG, "Default display mode no longer available, using currently active"
- + " mode as default.");
+ Slog.w(TAG, "Default display mode no longer available, using currently"
+ + " active mode as default.");
}
mDefaultModeId = activeRecord.mMode.getModeId();
+ if (mDefaultColorTransformId != 0) {
+ Slog.w(TAG, "Default color transform no longer available, using currently"
+ + " active color transform as default");
+ }
+ mDefaultColorTransformId = activeColorTransform.getId();
}
// Determine whether the active mode is still there.
if (mSupportedModes.indexOfKey(mActiveModeId) < 0) {
@@ -221,6 +305,16 @@
mActiveModeId = mDefaultModeId;
mActiveModeInvalid = true;
}
+
+ // Determine whether the active color transform is still there.
+ if (mSupportedColorTransforms.indexOfKey(mActiveColorTransformId) < 0) {
+ if (mActiveColorTransformId != 0) {
+ Slog.w(TAG, "Active color transform no longer available, reverting"
+ + " to default transform.");
+ }
+ mActiveColorTransformId = mDefaultColorTransformId;
+ mActiveColorTransformInvalid = true;
+ }
// Schedule traversals so that we apply pending changes.
sendTraversalRequestLocked();
return true;
@@ -229,13 +323,23 @@
private DisplayModeRecord findDisplayModeRecord(SurfaceControl.PhysicalDisplayInfo info) {
for (int i = 0; i < mSupportedModes.size(); i++) {
DisplayModeRecord record = mSupportedModes.valueAt(i);
- if (record.mPhys.equals(info)) {
+ if (record.hasMatchingMode(info)) {
return record;
}
}
return null;
}
+ private Display.ColorTransform findColorTransform(SurfaceControl.PhysicalDisplayInfo info) {
+ for (int i = 0; i < mSupportedColorTransforms.size(); i++) {
+ Display.ColorTransform transform = mSupportedColorTransforms.valueAt(i);
+ if (transform.getColorTransform() == info.colorTransform) {
+ return transform;
+ }
+ }
+ return null;
+ }
+
@Override
public void applyPendingDisplayDeviceInfoChangesLocked() {
if (mHavePendingChanges) {
@@ -247,7 +351,7 @@
@Override
public DisplayDeviceInfo getDisplayDeviceInfoLocked() {
if (mInfo == null) {
- SurfaceControl.PhysicalDisplayInfo phys = mSupportedModes.get(mActiveModeId).mPhys;
+ SurfaceControl.PhysicalDisplayInfo phys = mDisplayInfos[mActivePhysIndex];
mInfo = new DisplayDeviceInfo();
mInfo.width = phys.width;
mInfo.height = phys.height;
@@ -258,6 +362,13 @@
DisplayModeRecord record = mSupportedModes.valueAt(i);
mInfo.supportedModes[i] = record.mMode;
}
+ mInfo.colorTransformId = mActiveColorTransformId;
+ mInfo.defaultColorTransformId = mDefaultColorTransformId;
+ mInfo.supportedColorTransforms =
+ new Display.ColorTransform[mSupportedColorTransforms.size()];
+ for (int i = 0; i < mSupportedColorTransforms.size(); i++) {
+ mInfo.supportedColorTransforms[i] = mSupportedColorTransforms.valueAt(i);
+ }
mInfo.appVsyncOffsetNanos = phys.appVsyncOffsetNanos;
mInfo.presentationDeadlineNanos = phys.presentationDeadlineNanos;
mInfo.state = mState;
@@ -402,7 +513,8 @@
}
@Override
- public void requestModeInTransactionLocked(int modeId) {
+ public void requestColorTransformAndModeInTransactionLocked(
+ int colorTransformId, int modeId) {
if (modeId == 0) {
modeId = mDefaultModeId;
} else if (mSupportedModes.indexOfKey(modeId) < 0) {
@@ -410,13 +522,37 @@
+ " reverting to default display mode.");
modeId = mDefaultModeId;
}
- if (mActiveModeId == modeId && !mActiveModeInvalid) {
+
+ if (colorTransformId == 0) {
+ colorTransformId = mDefaultColorTransformId;
+ } else if (mSupportedColorTransforms.indexOfKey(colorTransformId) < 0) {
+ Slog.w(TAG, "Requested color transform " + colorTransformId + " is not supported"
+ + " by this display, reverting to the default color transform");
+ colorTransformId = mDefaultColorTransformId;
+ }
+ int physIndex = findDisplayInfoIndexLocked(colorTransformId, modeId);
+ if (physIndex < 0) {
+ Slog.w(TAG, "Requested color transform, mode ID pair (" + colorTransformId + ", "
+ + modeId + ") not available, trying color transform with default mode ID");
+ modeId = mDefaultModeId;
+ physIndex = findDisplayInfoIndexLocked(colorTransformId, modeId);
+ if (physIndex < 0) {
+ Slog.w(TAG, "Requested color transform with default mode ID still not"
+ + " available, falling back to default color transform with default"
+ + " mode.");
+ colorTransformId = mDefaultColorTransformId;
+ physIndex = findDisplayInfoIndexLocked(colorTransformId, modeId);
+ }
+ }
+ if (mActivePhysIndex == physIndex) {
return;
}
- DisplayModeRecord record = mSupportedModes.get(modeId);
- SurfaceControl.setActiveConfig(getDisplayTokenLocked(), record.mPhysIndex);
+ SurfaceControl.setActiveConfig(getDisplayTokenLocked(), physIndex);
+ mActivePhysIndex = physIndex;
mActiveModeId = modeId;
mActiveModeInvalid = false;
+ mActiveColorTransformId = colorTransformId;
+ mActiveColorTransformInvalid = false;
updateDeviceInfoLocked();
}
@@ -424,10 +560,43 @@
public void dumpLocked(PrintWriter pw) {
super.dumpLocked(pw);
pw.println("mBuiltInDisplayId=" + mBuiltInDisplayId);
+ pw.println("mActivePhysIndex=" + mActivePhysIndex);
pw.println("mActiveModeId=" + mActiveModeId);
+ pw.println("mActiveColorTransformId=" + mActiveColorTransformId);
pw.println("mState=" + Display.stateToString(mState));
pw.println("mBrightness=" + mBrightness);
pw.println("mBacklight=" + mBacklight);
+ pw.println("mDisplayInfos=");
+ for (int i = 0; i < mDisplayInfos.length; i++) {
+ pw.println(" " + mDisplayInfos[i]);
+ }
+ pw.println("mSupportedModes=");
+ for (int i = 0; i < mSupportedModes.size(); i++) {
+ pw.println(" " + mSupportedModes.valueAt(i));
+ }
+ pw.println("mSupportedColorTransforms=[");
+ for (int i = 0; i < mSupportedColorTransforms.size(); i++) {
+ if (i != 0) {
+ pw.print(", ");
+ }
+ pw.print(mSupportedColorTransforms.valueAt(i));
+ }
+ pw.println("]");
+ }
+
+ private int findDisplayInfoIndexLocked(int colorTransformId, int modeId) {
+ DisplayModeRecord record = mSupportedModes.get(modeId);
+ Display.ColorTransform transform = mSupportedColorTransforms.get(colorTransformId);
+ if (record != null && transform != null) {
+ for (int i = 0; i < mDisplayInfos.length; i++) {
+ SurfaceControl.PhysicalDisplayInfo info = mDisplayInfos[i];
+ if (info.colorTransform == transform.getColorTransform()
+ && record.hasMatchingMode(info)){
+ return i;
+ }
+ }
+ }
+ return -1;
}
private void updateDeviceInfoLocked() {
@@ -441,13 +610,28 @@
*/
private static final class DisplayModeRecord {
public final Display.Mode mMode;
- public final SurfaceControl.PhysicalDisplayInfo mPhys;
- public int mPhysIndex;
- public DisplayModeRecord(SurfaceControl.PhysicalDisplayInfo phys, int physIndex) {
+ public DisplayModeRecord(SurfaceControl.PhysicalDisplayInfo phys) {
mMode = createMode(phys.width, phys.height, phys.refreshRate);
- mPhys = phys;
- mPhysIndex = physIndex;
+ }
+
+ /**
+ * Returns whether the mode generated by the given PhysicalDisplayInfo matches the mode
+ * contained by the record modulo mode ID.
+ *
+ * Note that this doesn't necessarily mean the the PhysicalDisplayInfos are identical, just
+ * that they generate identical modes.
+ */
+ public boolean hasMatchingMode(SurfaceControl.PhysicalDisplayInfo info) {
+ int modeRefreshRate = Float.floatToIntBits(mMode.getRefreshRate());
+ int displayInfoRefreshRate = Float.floatToIntBits(info.refreshRate);
+ return mMode.getPhysicalWidth() == info.width
+ && mMode.getPhysicalHeight() == info.height
+ && modeRefreshRate == displayInfoRefreshRate;
+ }
+
+ public String toString() {
+ return "DisplayModeRecord{mMode=" + mMode + "}";
}
}
diff --git a/services/core/java/com/android/server/display/LogicalDisplay.java b/services/core/java/com/android/server/display/LogicalDisplay.java
index 6efc99a..6dae397 100644
--- a/services/core/java/com/android/server/display/LogicalDisplay.java
+++ b/services/core/java/com/android/server/display/LogicalDisplay.java
@@ -74,6 +74,7 @@
private boolean mHasContent;
private int mRequestedModeId;
+ private int mRequestedColorTransformId;
// The display offsets to apply to the display projection.
private int mDisplayOffsetX;
@@ -235,6 +236,11 @@
mBaseDisplayInfo.defaultModeId = deviceInfo.defaultModeId;
mBaseDisplayInfo.supportedModes = Arrays.copyOf(
deviceInfo.supportedModes, deviceInfo.supportedModes.length);
+ mBaseDisplayInfo.colorTransformId = deviceInfo.colorTransformId;
+ mBaseDisplayInfo.defaultColorTransformId = deviceInfo.defaultColorTransformId;
+ mBaseDisplayInfo.supportedColorTransforms = Arrays.copyOf(
+ deviceInfo.supportedColorTransforms,
+ deviceInfo.supportedColorTransforms.length);
mBaseDisplayInfo.logicalDensityDpi = deviceInfo.densityDpi;
mBaseDisplayInfo.physicalXDpi = deviceInfo.xDpi;
mBaseDisplayInfo.physicalYDpi = deviceInfo.yDpi;
@@ -275,11 +281,12 @@
// Set the layer stack.
device.setLayerStackInTransactionLocked(isBlanked ? BLANK_LAYER_STACK : mLayerStack);
- // Set the mode.
+ // Set the color transform and mode.
if (device == mPrimaryDisplayDevice) {
- device.requestModeInTransactionLocked(mRequestedModeId);
+ device.requestColorTransformAndModeInTransactionLocked(
+ mRequestedColorTransformId, mRequestedModeId);
} else {
- device.requestModeInTransactionLocked(0); // Revert to default.
+ device.requestColorTransformAndModeInTransactionLocked(0, 0); // Revert to default.
}
// Only grab the display info now as it may have been changed based on the requests above.
@@ -383,6 +390,18 @@
}
/**
+ * Requests the given color transform.
+ */
+ public void setRequestedColorTransformIdLocked(int colorTransformId) {
+ mRequestedColorTransformId = colorTransformId;
+ }
+
+ /** Returns the pending requested color transform. */
+ public int getRequestedColorTransformIdLocked() {
+ return mRequestedColorTransformId;
+ }
+
+ /**
* Gets the burn-in offset in X.
*/
public int getDisplayOffsetXLocked() {
@@ -409,6 +428,7 @@
pw.println("mLayerStack=" + mLayerStack);
pw.println("mHasContent=" + mHasContent);
pw.println("mRequestedMode=" + mRequestedModeId);
+ pw.println("mRequestedColorTransformId=" + mRequestedColorTransformId);
pw.println("mDisplayOffset=(" + mDisplayOffsetX + ", " + mDisplayOffsetY + ")");
pw.println("mPrimaryDisplayDevice=" + (mPrimaryDisplayDevice != null ?
mPrimaryDisplayDevice.getNameLocked() : "null"));
diff --git a/services/core/java/com/android/server/display/OverlayDisplayAdapter.java b/services/core/java/com/android/server/display/OverlayDisplayAdapter.java
index 0bddff0..cf6264a 100644
--- a/services/core/java/com/android/server/display/OverlayDisplayAdapter.java
+++ b/services/core/java/com/android/server/display/OverlayDisplayAdapter.java
@@ -310,7 +310,7 @@
}
@Override
- public void requestModeInTransactionLocked(int id) {
+ public void requestColorTransformAndModeInTransactionLocked(int color, int id) {
int index = -1;
if (id == 0) {
// Use the default.
diff --git a/services/core/java/com/android/server/fingerprint/FingerprintService.java b/services/core/java/com/android/server/fingerprint/FingerprintService.java
index 2c9d82b..84aa2d7 100644
--- a/services/core/java/com/android/server/fingerprint/FingerprintService.java
+++ b/services/core/java/com/android/server/fingerprint/FingerprintService.java
@@ -16,21 +16,29 @@
package com.android.server.fingerprint;
+import android.Manifest;
import android.app.ActivityManager;
+import android.app.ActivityManager.RunningAppProcessInfo;
+import android.app.ActivityManager.RunningTaskInfo;
import android.app.ActivityManagerNative;
+import android.app.AlarmManager;
import android.app.AppOpsManager;
import android.app.IUserSwitchObserver;
-import android.content.ContentResolver;
+import android.app.PendingIntent;
+import android.content.ComponentName;
+import android.content.BroadcastReceiver;
import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.content.pm.UserInfo;
+import android.hardware.fingerprint.IFingerprintServiceLockoutResetCallback;
import android.os.Binder;
+import android.os.DeadObjectException;
import android.os.Environment;
import android.os.Handler;
import android.os.IBinder;
import android.os.IRemoteCallback;
-import android.os.Looper;
-import android.os.MessageQueue;
import android.os.PowerManager;
import android.os.RemoteException;
import android.os.SELinux;
@@ -40,8 +48,13 @@
import android.os.UserManager;
import android.util.Slog;
+import com.android.internal.logging.MetricsLogger;
import com.android.server.SystemService;
+import org.json.JSONArray;
+import org.json.JSONException;
+import org.json.JSONObject;
+
import android.hardware.fingerprint.Fingerprint;
import android.hardware.fingerprint.FingerprintManager;
import android.hardware.fingerprint.IFingerprintService;
@@ -49,10 +62,14 @@
import android.hardware.fingerprint.IFingerprintDaemonCallback;
import android.hardware.fingerprint.IFingerprintServiceReceiver;
+import static android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
import static android.Manifest.permission.MANAGE_FINGERPRINT;
+import static android.Manifest.permission.RESET_FINGERPRINT_LOCKOUT;
import static android.Manifest.permission.USE_FINGERPRINT;
import java.io.File;
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
@@ -73,16 +90,21 @@
private static final String FINGERPRINTD = "android.hardware.fingerprint.IFingerprintDaemon";
private static final int MSG_USER_SWITCHING = 10;
private static final int ENROLLMENT_TIMEOUT_MS = 60 * 1000; // 1 minute
+ private static final String ACTION_LOCKOUT_RESET =
+ "com.android.server.fingerprint.ACTION_LOCKOUT_RESET";
private ClientMonitor mAuthClient = null;
private ClientMonitor mEnrollClient = null;
private ClientMonitor mRemoveClient = null;
+ private final ArrayList<FingerprintServiceLockoutResetMonitor> mLockoutMonitors =
+ new ArrayList<>();
private final AppOpsManager mAppOps;
private static final long MS_PER_SEC = 1000;
private static final long FAIL_LOCKOUT_TIMEOUT_MS = 30*1000;
private static final int MAX_FAILED_ATTEMPTS = 5;
private static final int FINGERPRINT_ACQUIRED_GOOD = 0;
+ private final String mKeyguardPackage;
Handler mHandler = new Handler() {
@Override
@@ -103,9 +125,20 @@
private long mHalDeviceId;
private int mFailedAttempts;
private IFingerprintDaemon mDaemon;
- private PowerManager mPowerManager;
+ private final PowerManager mPowerManager;
+ private final AlarmManager mAlarmManager;
+ private int mCurrentUserId = UserHandle.USER_NULL;
- private final Runnable mLockoutReset = new Runnable() {
+ private final BroadcastReceiver mLockoutReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ if (ACTION_LOCKOUT_RESET.equals(intent.getAction())) {
+ resetFailedAttempts();
+ }
+ }
+ };
+
+ private final Runnable mResetFailedAttemptsRunnable = new Runnable() {
@Override
public void run() {
resetFailedAttempts();
@@ -115,15 +148,20 @@
public FingerprintService(Context context) {
super(context);
mContext = context;
+ mKeyguardPackage = ComponentName.unflattenFromString(context.getResources().getString(
+ com.android.internal.R.string.config_keyguardComponent)).getPackageName();
mAppOps = context.getSystemService(AppOpsManager.class);
- mPowerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
+ mPowerManager = mContext.getSystemService(PowerManager.class);
+ mAlarmManager = mContext.getSystemService(AlarmManager.class);
+ mContext.registerReceiver(mLockoutReceiver, new IntentFilter(ACTION_LOCKOUT_RESET),
+ RESET_FINGERPRINT_LOCKOUT, null /* handler */);
}
@Override
public void binderDied() {
Slog.v(TAG, "fingerprintd died");
mDaemon = null;
- dispatchError(mHalDeviceId, FingerprintManager.FINGERPRINT_ERROR_HW_UNAVAILABLE);
+ handleError(mHalDeviceId, FingerprintManager.FINGERPRINT_ERROR_HW_UNAVAILABLE);
}
public IFingerprintDaemon getFingerprintDaemon() {
@@ -151,7 +189,7 @@
return mDaemon;
}
- protected void dispatchEnumerate(long deviceId, int[] fingerIds, int[] groupIds) {
+ protected void handleEnumerate(long deviceId, int[] fingerIds, int[] groupIds) {
if (fingerIds.length != groupIds.length) {
Slog.w(TAG, "fingerIds and groupIds differ in length: f[]="
+ fingerIds + ", g[]=" + groupIds);
@@ -161,7 +199,7 @@
// TODO: update fingerprint/name pairs
}
- protected void dispatchRemoved(long deviceId, int fingerId, int groupId) {
+ protected void handleRemoved(long deviceId, int fingerId, int groupId) {
final ClientMonitor client = mRemoveClient;
if (fingerId != 0) {
removeTemplateForUser(mRemoveClient, fingerId);
@@ -171,7 +209,7 @@
}
}
- protected void dispatchError(long deviceId, int error) {
+ protected void handleError(long deviceId, int error) {
if (mEnrollClient != null) {
final IBinder token = mEnrollClient.token;
if (mEnrollClient.sendError(error)) {
@@ -187,7 +225,7 @@
}
}
- protected void dispatchAuthenticated(long deviceId, int fingerId, int groupId) {
+ protected void handleAuthenticated(long deviceId, int fingerId, int groupId) {
if (mAuthClient != null) {
final IBinder token = mAuthClient.token;
if (mAuthClient.sendAuthenticated(fingerId, groupId)) {
@@ -197,7 +235,7 @@
}
}
- protected void dispatchAcquired(long deviceId, int acquiredInfo) {
+ protected void handleAcquired(long deviceId, int acquiredInfo) {
if (mEnrollClient != null) {
if (mEnrollClient.sendAcquired(acquiredInfo)) {
removeClient(mEnrollClient);
@@ -209,16 +247,7 @@
}
}
- private void userActivity() {
- long now = SystemClock.uptimeMillis();
- mPowerManager.userActivity(now, PowerManager.USER_ACTIVITY_EVENT_TOUCH, 0);
- }
-
- void handleUserSwitching(int userId) {
- updateActiveGroup(userId);
- }
-
- protected void dispatchEnrollResult(long deviceId, int fingerId, int groupId, int remaining) {
+ protected void handleEnrollResult(long deviceId, int fingerId, int groupId, int remaining) {
if (mEnrollClient != null) {
if (mEnrollClient.sendEnrollResult(fingerId, groupId, remaining)) {
if (remaining == 0) {
@@ -229,6 +258,15 @@
}
}
+ private void userActivity() {
+ long now = SystemClock.uptimeMillis();
+ mPowerManager.userActivity(now, PowerManager.USER_ACTIVITY_EVENT_TOUCH, 0);
+ }
+
+ void handleUserSwitching(int userId) {
+ updateActiveGroup(userId);
+ }
+
private void removeClient(ClientMonitor client) {
if (client == null) return;
client.destroy();
@@ -242,7 +280,21 @@
}
private boolean inLockoutMode() {
- return mFailedAttempts > MAX_FAILED_ATTEMPTS;
+ return mFailedAttempts >= MAX_FAILED_ATTEMPTS;
+ }
+
+ private void scheduleLockoutReset() {
+ mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,
+ SystemClock.elapsedRealtime() + FAIL_LOCKOUT_TIMEOUT_MS, getLockoutResetIntent());
+ }
+
+ private void cancelLockoutReset() {
+ mAlarmManager.cancel(getLockoutResetIntent());
+ }
+
+ private PendingIntent getLockoutResetIntent() {
+ return PendingIntent.getBroadcast(mContext, 0,
+ new Intent(ACTION_LOCKOUT_RESET), PendingIntent.FLAG_UPDATE_CURRENT);
}
private void resetFailedAttempts() {
@@ -250,14 +302,17 @@
Slog.v(TAG, "Reset fingerprint lockout");
}
mFailedAttempts = 0;
+ // If we're asked to reset failed attempts externally (i.e. from Keyguard), the alarm might
+ // still be pending; remove it.
+ cancelLockoutReset();
+ notifyLockoutResetMonitors();
}
private boolean handleFailedAttempt(ClientMonitor clientMonitor) {
mFailedAttempts++;
- if (mFailedAttempts > MAX_FAILED_ATTEMPTS) {
+ if (inLockoutMode()) {
// Failing multiple times will continue to push out the lockout time.
- mHandler.removeCallbacks(mLockoutReset);
- mHandler.postDelayed(mLockoutReset, FAIL_LOCKOUT_TIMEOUT_MS);
+ scheduleLockoutReset();
if (clientMonitor != null
&& !clientMonitor.sendError(FingerprintManager.FINGERPRINT_ERROR_LOCKOUT)) {
Slog.w(TAG, "Cannot send lockout message to client");
@@ -283,12 +338,14 @@
return;
}
stopPendingOperations(true);
- mEnrollClient = new ClientMonitor(token, receiver, groupId, restricted);
+ mEnrollClient = new ClientMonitor(token, receiver, mCurrentUserId, groupId, restricted,
+ token.toString());
final int timeout = (int) (ENROLLMENT_TIMEOUT_MS / MS_PER_SEC);
try {
final int result = daemon.enroll(cryptoToken, groupId, timeout);
if (result != 0) {
Slog.w(TAG, "startEnroll failed, result=" + result);
+ handleError(mHalDeviceId, FingerprintManager.FINGERPRINT_ERROR_HW_UNAVAILABLE);
}
} catch (RemoteException e) {
Slog.e(TAG, "startEnroll failed", e);
@@ -362,14 +419,16 @@
}
void startAuthentication(IBinder token, long opId, int groupId,
- IFingerprintServiceReceiver receiver, int flags, boolean restricted) {
+ IFingerprintServiceReceiver receiver, int flags, boolean restricted,
+ String opPackageName) {
IFingerprintDaemon daemon = getFingerprintDaemon();
if (daemon == null) {
Slog.w(TAG, "startAuthentication: no fingeprintd!");
return;
}
stopPendingOperations(true);
- mAuthClient = new ClientMonitor(token, receiver, groupId, restricted);
+ mAuthClient = new ClientMonitor(token, receiver, mCurrentUserId, groupId, restricted,
+ opPackageName);
if (inLockoutMode()) {
Slog.v(TAG, "In lockout mode; disallowing authentication");
if (!mAuthClient.sendError(FingerprintManager.FINGERPRINT_ERROR_LOCKOUT)) {
@@ -382,6 +441,7 @@
final int result = daemon.authenticate(opId, groupId);
if (result != 0) {
Slog.w(TAG, "startAuthentication failed, result=" + result);
+ handleError(mHalDeviceId, FingerprintManager.FINGERPRINT_ERROR_HW_UNAVAILABLE);
}
} catch (RemoteException e) {
Slog.e(TAG, "startAuthentication failed", e);
@@ -424,12 +484,15 @@
return;
}
- mRemoveClient = new ClientMonitor(token, receiver, userId, restricted);
+ stopPendingOperations(true);
+ mRemoveClient = new ClientMonitor(token, receiver, mCurrentUserId, userId, restricted,
+ token.toString());
// The fingerprint template ids will be removed when we get confirmation from the HAL
try {
final int result = daemon.remove(fingerId, userId);
if (result != 0) {
Slog.w(TAG, "startRemove with id = " + fingerId + " failed, result=" + result);
+ handleError(mHalDeviceId, FingerprintManager.FINGERPRINT_ERROR_HW_UNAVAILABLE);
}
} catch (RemoteException e) {
Slog.e(TAG, "startRemove failed", e);
@@ -480,24 +543,85 @@
return false;
}
- private boolean canUseFingerprint(String opPackageName) {
+ private boolean isForegroundActivity(int uid, int pid) {
+ try {
+ List<RunningAppProcessInfo> procs =
+ ActivityManagerNative.getDefault().getRunningAppProcesses();
+ int N = procs.size();
+ for (int i = 0; i < N; i++) {
+ RunningAppProcessInfo proc = procs.get(i);
+ if (proc.pid == pid && proc.uid == uid
+ && proc.importance == IMPORTANCE_FOREGROUND) {
+ return true;
+ }
+ }
+ } catch (RemoteException e) {
+ Slog.w(TAG, "am.getRunningAppProcesses() failed");
+ }
+ return false;
+ }
+
+ /**
+ * @param opPackageName name of package for caller
+ * @param foregroundOnly only allow this call while app is in the foreground
+ * @return true if caller can use fingerprint API
+ */
+ private boolean canUseFingerprint(String opPackageName, boolean foregroundOnly) {
checkPermission(USE_FINGERPRINT);
- return mAppOps.noteOp(AppOpsManager.OP_USE_FINGERPRINT, Binder.getCallingUid(),
- opPackageName) == AppOpsManager.MODE_ALLOWED;
+ final int uid = Binder.getCallingUid();
+ final int pid = Binder.getCallingPid();
+ if (opPackageName.equals(mKeyguardPackage)) {
+ return true; // Keyguard is always allowed
+ }
+ if (!isCurrentUserOrProfile(UserHandle.getCallingUserId())) {
+ Slog.w(TAG,"Rejecting " + opPackageName + " ; not a current user or profile");
+ return false;
+ }
+ if (mAppOps.noteOp(AppOpsManager.OP_USE_FINGERPRINT, uid, opPackageName)
+ != AppOpsManager.MODE_ALLOWED) {
+ Slog.w(TAG, "Rejecting " + opPackageName + " ; permission denied");
+ return false;
+ }
+ if (foregroundOnly && !isForegroundActivity(uid, pid)) {
+ Slog.w(TAG, "Rejecting " + opPackageName + " ; not in foreground");
+ return false;
+ }
+ return true;
+ }
+
+ private void addLockoutResetMonitor(FingerprintServiceLockoutResetMonitor monitor) {
+ if (!mLockoutMonitors.contains(monitor)) {
+ mLockoutMonitors.add(monitor);
+ }
+ }
+
+ private void removeLockoutResetCallback(
+ FingerprintServiceLockoutResetMonitor monitor) {
+ mLockoutMonitors.remove(monitor);
+ }
+
+ private void notifyLockoutResetMonitors() {
+ for (int i = 0; i < mLockoutMonitors.size(); i++) {
+ mLockoutMonitors.get(i).sendLockoutReset();
+ }
}
private class ClientMonitor implements IBinder.DeathRecipient {
IBinder token;
IFingerprintServiceReceiver receiver;
- int userId;
+ int userId; // userId of the caller
+ int currentUserId; // current user id when this was created
boolean restricted; // True if client does not have MANAGE_FINGERPRINT permission
+ String owner;
- public ClientMonitor(IBinder token, IFingerprintServiceReceiver receiver, int userId,
- boolean restricted) {
+ public ClientMonitor(IBinder token, IFingerprintServiceReceiver receiver,
+ int currentUserId, int userId, boolean restricted, String owner) {
this.token = token;
this.receiver = receiver;
this.userId = userId;
+ this.currentUserId = currentUserId;
this.restricted = restricted;
+ this.owner = owner; // name of the client that owns this - for debugging
try {
token.linkToDeath(this, 0);
} catch (RemoteException e) {
@@ -557,6 +681,7 @@
private boolean sendEnrollResult(int fpId, int groupId, int remaining) {
if (receiver == null) return true; // client not listening
FingerprintUtils.vibrateFingerprintSuccess(getContext());
+ MetricsLogger.action(mContext, MetricsLogger.ACTION_FINGERPRINT_ENROLL);
try {
receiver.onEnrollResult(mHalDeviceId, fpId, groupId, remaining);
return remaining == 0;
@@ -574,12 +699,18 @@
boolean authenticated = fpId != 0;
if (receiver != null) {
try {
+ MetricsLogger.action(mContext, MetricsLogger.ACTION_FINGERPRINT_AUTH,
+ authenticated);
if (!authenticated) {
receiver.onAuthenticationFailed(mHalDeviceId);
} else {
- Fingerprint fp = !restricted ?
- new Fingerprint("" /* TODO */, groupId, fpId, mHalDeviceId) : null;
- receiver.onAuthenticationSucceeded(mHalDeviceId, fp);
+ if (DEBUG) {
+ Slog.v(TAG, "onAuthenticated(owner=" + mAuthClient.owner
+ + ", id=" + fpId + ", gp=" + groupId + ")");
+ }
+ Fingerprint fp = !restricted ? new Fingerprint("" /* TODO */, groupId, fpId,
+ mHalDeviceId) : null;
+ receiver.onAuthenticationSucceeded(mHalDeviceId, fp, currentUserId);
}
} catch (RemoteException e) {
Slog.w(TAG, "Failed to notify Authenticated:", e);
@@ -589,12 +720,16 @@
result = true; // client not listening
}
if (fpId == 0) {
- FingerprintUtils.vibrateFingerprintError(getContext());
+ if (receiver != null) {
+ FingerprintUtils.vibrateFingerprintError(getContext());
+ }
result |= handleFailedAttempt(this);
} else {
- FingerprintUtils.vibrateFingerprintSuccess(getContext());
+ if (receiver != null) {
+ FingerprintUtils.vibrateFingerprintSuccess(getContext());
+ }
result |= true; // we have a valid fingerprint
- mLockoutReset.run();
+ resetFailedAttempts();
}
return result;
}
@@ -634,38 +769,98 @@
}
}
+ private class FingerprintServiceLockoutResetMonitor {
+
+ private final IFingerprintServiceLockoutResetCallback mCallback;
+
+ public FingerprintServiceLockoutResetMonitor(
+ IFingerprintServiceLockoutResetCallback callback) {
+ mCallback = callback;
+ }
+
+ public void sendLockoutReset() {
+ if (mCallback != null) {
+ try {
+ mCallback.onLockoutReset(mHalDeviceId);
+ } catch (DeadObjectException e) {
+ Slog.w(TAG, "Death object while invoking onLockoutReset: ", e);
+ mHandler.post(mRemoveCallbackRunnable);
+ } catch (RemoteException e) {
+ Slog.w(TAG, "Failed to invoke onLockoutReset: ", e);
+ }
+ }
+ }
+
+ private final Runnable mRemoveCallbackRunnable = new Runnable() {
+ @Override
+ public void run() {
+ removeLockoutResetCallback(FingerprintServiceLockoutResetMonitor.this);
+ }
+ };
+ }
+
private IFingerprintDaemonCallback mDaemonCallback = new IFingerprintDaemonCallback.Stub() {
@Override
- public void onEnrollResult(long deviceId, int fingerId, int groupId, int remaining) {
- dispatchEnrollResult(deviceId, fingerId, groupId, remaining);
+ public void onEnrollResult(final long deviceId, final int fingerId, final int groupId,
+ final int remaining) {
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ handleEnrollResult(deviceId, fingerId, groupId, remaining);
+ }
+ });
}
@Override
- public void onAcquired(long deviceId, int acquiredInfo) {
- dispatchAcquired(deviceId, acquiredInfo);
+ public void onAcquired(final long deviceId, final int acquiredInfo) {
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ handleAcquired(deviceId, acquiredInfo);
+ }
+ });
}
@Override
- public void onAuthenticated(long deviceId, int fingerId, int groupId) {
- dispatchAuthenticated(deviceId, fingerId, groupId);
+ public void onAuthenticated(final long deviceId, final int fingerId, final int groupId) {
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ handleAuthenticated(deviceId, fingerId, groupId);
+ }
+ });
}
@Override
- public void onError(long deviceId, int error) {
- dispatchError(deviceId, error);
+ public void onError(final long deviceId, final int error) {
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ handleError(deviceId, error);
+ }
+ });
}
@Override
- public void onRemoved(long deviceId, int fingerId, int groupId) {
- dispatchRemoved(deviceId, fingerId, groupId);
+ public void onRemoved(final long deviceId, final int fingerId, final int groupId) {
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ handleRemoved(deviceId, fingerId, groupId);
+ }
+ });
}
@Override
- public void onEnumerate(long deviceId, int[] fingerIds, int[] groupIds) {
- dispatchEnumerate(deviceId, fingerIds, groupIds);
+ public void onEnumerate(final long deviceId, final int[] fingerIds, final int[] groupIds) {
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ handleEnumerate(deviceId, fingerIds, groupIds);
+ }
+ });
}
-
};
private final class FingerprintServiceWrapper extends IFingerprintService.Stub {
@@ -732,12 +927,8 @@
public void authenticate(final IBinder token, final long opId, final int groupId,
final IFingerprintServiceReceiver receiver, final int flags,
final String opPackageName) {
- if (!isCurrentUserOrProfile(UserHandle.getCallingUserId())) {
- Slog.w(TAG, "Can't authenticate non-current user");
- return;
- }
- if (!canUseFingerprint(opPackageName)) {
- Slog.w(TAG, "Calling not granted permission to use fingerprint");
+ if (!canUseFingerprint(opPackageName, true /* foregroundOnly */)) {
+ if (DEBUG) Slog.v(TAG, "authenticate(): reject " + opPackageName);
return;
}
@@ -749,14 +940,16 @@
mHandler.post(new Runnable() {
@Override
public void run() {
- startAuthentication(token, opId, effectiveGroupId, receiver, flags, restricted);
+ MetricsLogger.histogram(mContext, "fingerprint_token", opId != 0L ? 1 : 0);
+ startAuthentication(token, opId, effectiveGroupId, receiver, flags, restricted,
+ opPackageName);
}
});
}
@Override // Binder call
public void cancelAuthentication(final IBinder token, String opPackageName) {
- if (!canUseFingerprint(opPackageName)) {
+ if (!canUseFingerprint(opPackageName, false /* foregroundOnly */)) {
return;
}
mHandler.post(new Runnable() {
@@ -787,7 +980,7 @@
@Override // Binder call
public boolean isHardwareDetected(long deviceId, String opPackageName) {
- if (!canUseFingerprint(opPackageName)) {
+ if (!canUseFingerprint(opPackageName, false /* foregroundOnly */)) {
return false;
}
return mHalDeviceId != 0;
@@ -811,7 +1004,7 @@
@Override // Binder call
public List<Fingerprint> getEnrolledFingerprints(int userId, String opPackageName) {
- if (!canUseFingerprint(opPackageName)) {
+ if (!canUseFingerprint(opPackageName, false /* foregroundOnly */)) {
return Collections.emptyList();
}
int effectiveUserId = getEffectiveUserId(userId);
@@ -821,7 +1014,7 @@
@Override // Binder call
public boolean hasEnrolledFingerprints(int userId, String opPackageName) {
- if (!canUseFingerprint(opPackageName)) {
+ if (!canUseFingerprint(opPackageName, false /* foregroundOnly */)) {
return false;
}
@@ -849,6 +1042,64 @@
return FingerprintService.this.getAuthenticatorId();
}
+
+ @Override // Binder call
+ protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+ if (mContext.checkCallingOrSelfPermission(Manifest.permission.DUMP)
+ != PackageManager.PERMISSION_GRANTED) {
+ pw.println("Permission Denial: can't dump Fingerprint from from pid="
+ + Binder.getCallingPid()
+ + ", uid=" + Binder.getCallingUid());
+ return;
+ }
+
+ final long ident = Binder.clearCallingIdentity();
+ try {
+ dumpInternal(pw);
+ } finally {
+ Binder.restoreCallingIdentity(ident);
+ }
+ }
+ @Override // Binder call
+ public void resetTimeout(byte [] token) {
+ checkPermission(RESET_FINGERPRINT_LOCKOUT);
+ // TODO: confirm security token when we move timeout management into the HAL layer.
+ mHandler.post(mResetFailedAttemptsRunnable);
+ }
+
+ @Override
+ public void addLockoutResetCallback(final IFingerprintServiceLockoutResetCallback callback)
+ throws RemoteException {
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ addLockoutResetMonitor(
+ new FingerprintServiceLockoutResetMonitor(callback));
+ }
+ });
+ }
+ }
+
+ private void dumpInternal(PrintWriter pw) {
+ JSONObject dump = new JSONObject();
+ try {
+ dump.put("service", "Fingerprint Manager");
+
+ JSONArray sets = new JSONArray();
+ for (UserInfo user : UserManager.get(getContext()).getUsers()) {
+ final int userId = user.getUserHandle().getIdentifier();
+ final int N = mFingerprintUtils.getFingerprintsForUser(mContext, userId).size();
+ JSONObject set = new JSONObject();
+ set.put("id", userId);
+ set.put("count", N);
+ sets.put(set);
+ }
+
+ dump.put("prints", sets);
+ } catch (JSONException e) {
+ Slog.e(TAG, "dump formatting failure", e);
+ }
+ pw.println(dump);
}
@Override
@@ -884,6 +1135,7 @@
Slog.e(TAG, "Failed to setActiveGroup():", e);
}
}
+ mCurrentUserId = userId;
}
private void listenForUserSwitches() {
@@ -894,6 +1146,12 @@
public void onUserSwitching(int newUserId, IRemoteCallback reply) {
mHandler.obtainMessage(MSG_USER_SWITCHING, newUserId, 0 /* unused */)
.sendToTarget();
+ if (reply != null) {
+ try {
+ reply.sendResult(null);
+ } catch (RemoteException e) {
+ }
+ }
}
@Override
public void onUserSwitchComplete(int newUserId) throws RemoteException {
diff --git a/services/core/java/com/android/server/fingerprint/FingerprintUtils.java b/services/core/java/com/android/server/fingerprint/FingerprintUtils.java
index d274412..49dc8e4 100644
--- a/services/core/java/com/android/server/fingerprint/FingerprintUtils.java
+++ b/services/core/java/com/android/server/fingerprint/FingerprintUtils.java
@@ -19,6 +19,7 @@
import android.content.Context;
import android.hardware.fingerprint.Fingerprint;
import android.os.Vibrator;
+import android.text.TextUtils;
import android.util.SparseArray;
import com.android.internal.annotations.GuardedBy;
@@ -64,6 +65,10 @@
}
public void renameFingerprintForUser(Context ctx, int fingerId, int userId, CharSequence name) {
+ if (TextUtils.isEmpty(name)) {
+ // Don't do the rename if it's empty
+ return;
+ }
getStateForUser(ctx, userId).renameFingerprint(fingerId, name);
}
diff --git a/services/core/java/com/android/server/input/InputManagerService.java b/services/core/java/com/android/server/input/InputManagerService.java
index 17b4f9c..0205a20 100644
--- a/services/core/java/com/android/server/input/InputManagerService.java
+++ b/services/core/java/com/android/server/input/InputManagerService.java
@@ -17,6 +17,7 @@
package com.android.server.input;
import android.view.Display;
+import com.android.internal.os.SomeArgs;
import com.android.internal.R;
import com.android.internal.util.XmlUtils;
import com.android.server.DisplayThread;
@@ -52,6 +53,7 @@
import android.hardware.input.InputDeviceIdentifier;
import android.hardware.input.InputManager;
import android.hardware.input.InputManagerInternal;
+import android.hardware.input.ITabletModeChangedListener;
import android.hardware.input.KeyboardLayout;
import android.hardware.input.TouchCalibration;
import android.os.Binder;
@@ -93,6 +95,7 @@
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
+import java.util.List;
import libcore.io.Streams;
import libcore.util.Objects;
@@ -112,6 +115,7 @@
private static final int MSG_RELOAD_KEYBOARD_LAYOUTS = 3;
private static final int MSG_UPDATE_KEYBOARD_LAYOUTS = 4;
private static final int MSG_RELOAD_DEVICE_ALIASES = 5;
+ private static final int MSG_DELIVER_TABLET_MODE_CHANGED = 6;
// Pointer to native input manager service object.
private final long mPtr;
@@ -124,6 +128,13 @@
private boolean mSystemReady;
private NotificationManager mNotificationManager;
+ private final Object mTabletModeLock = new Object();
+ // List of currently registered tablet mode changed listeners by process id
+ private final SparseArray<TabletModeChangedListenerRecord> mTabletModeChangedListeners =
+ new SparseArray<>(); // guarded by mTabletModeLock
+ private final List<TabletModeChangedListenerRecord> mTempTabletModeChangedListenersToNotify =
+ new ArrayList<>();
+
// Persistent data store. Must be locked each time during use.
private final PersistentDataStore mDataStore = new PersistentDataStore();
@@ -227,6 +238,11 @@
/** Switch code: Lid switch. When set, lid is shut. */
public static final int SW_LID = 0x00;
+ /** Switch code: Tablet mode switch.
+ * When set, the device is in tablet mode (i.e. no keyboard is connected).
+ */
+ public static final int SW_TABLET_MODE = 0x01;
+
/** Switch code: Keypad slide. When set, keyboard is exposed. */
public static final int SW_KEYPAD_SLIDE = 0x0a;
@@ -246,6 +262,7 @@
public static final int SW_CAMERA_LENS_COVER = 0x09;
public static final int SW_LID_BIT = 1 << SW_LID;
+ public static final int SW_TABLET_MODE_BIT = 1 << SW_TABLET_MODE;
public static final int SW_KEYPAD_SLIDE_BIT = 1 << SW_KEYPAD_SLIDE;
public static final int SW_HEADPHONE_INSERT_BIT = 1 << SW_HEADPHONE_INSERT;
public static final int SW_MICROPHONE_INSERT_BIT = 1 << SW_MICROPHONE_INSERT;
@@ -774,6 +791,66 @@
}
}
+ @Override // Binder call
+ public int isInTabletMode() {
+ if (!checkCallingPermission(android.Manifest.permission.TABLET_MODE,
+ "isInTabletMode()")) {
+ throw new SecurityException("Requires TABLET_MODE permission");
+ }
+ return getSwitchState(-1, InputDevice.SOURCE_ANY, SW_TABLET_MODE);
+ }
+
+ @Override // Binder call
+ public void registerTabletModeChangedListener(ITabletModeChangedListener listener) {
+ if (!checkCallingPermission(android.Manifest.permission.TABLET_MODE,
+ "registerTabletModeChangedListener()")) {
+ throw new SecurityException("Requires TABLET_MODE_LISTENER permission");
+ }
+ if (listener == null) {
+ throw new IllegalArgumentException("listener must not be null");
+ }
+
+ synchronized (mTabletModeLock) {
+ final int callingPid = Binder.getCallingPid();
+ if (mTabletModeChangedListeners.get(callingPid) != null) {
+ throw new IllegalStateException("The calling process has already registered "
+ + "a TabletModeChangedListener.");
+ }
+ TabletModeChangedListenerRecord record =
+ new TabletModeChangedListenerRecord(callingPid, listener);
+ try {
+ IBinder binder = listener.asBinder();
+ binder.linkToDeath(record, 0);
+ } catch (RemoteException ex) {
+ throw new RuntimeException(ex);
+ }
+ mTabletModeChangedListeners.put(callingPid, record);
+ }
+ }
+
+ private void onTabletModeChangedListenerDied(int pid) {
+ synchronized (mTabletModeLock) {
+ mTabletModeChangedListeners.remove(pid);
+ }
+ }
+
+ // Must be called on handler
+ private void deliverTabletModeChanged(long whenNanos, boolean inTabletMode) {
+ mTempTabletModeChangedListenersToNotify.clear();
+ final int numListeners;
+ synchronized (mTabletModeLock) {
+ numListeners = mTabletModeChangedListeners.size();
+ for (int i = 0; i < numListeners; i++) {
+ mTempTabletModeChangedListenersToNotify.add(
+ mTabletModeChangedListeners.valueAt(i));
+ }
+ }
+ for (int i = 0; i < numListeners; i++) {
+ mTempTabletModeChangedListenersToNotify.get(i).notifyTabletModeChanged(
+ whenNanos, inTabletMode);
+ }
+ }
+
// Must be called on handler.
private void showMissingKeyboardLayoutNotification(InputDevice device) {
if (!mKeyboardLayoutNotificationShown) {
@@ -1419,6 +1496,15 @@
mWiredAccessoryCallbacks.notifyWiredAccessoryChanged(whenNanos, switchValues,
switchMask);
}
+
+ if ((switchMask & SW_TABLET_MODE_BIT) != 0) {
+ SomeArgs args = SomeArgs.obtain();
+ args.argi1 = (int) (whenNanos & 0xFFFFFFFF);
+ args.argi2 = (int) (whenNanos >> 32);
+ args.arg1 = Boolean.valueOf((switchValues & SW_TABLET_MODE_BIT) != 0);
+ mHandler.obtainMessage(MSG_DELIVER_TABLET_MODE_CHANGED,
+ args).sendToTarget();
+ }
}
// Native callback.
@@ -1664,6 +1750,12 @@
case MSG_RELOAD_DEVICE_ALIASES:
reloadDeviceAliases();
break;
+ case MSG_DELIVER_TABLET_MODE_CHANGED:
+ SomeArgs args = (SomeArgs) msg.obj;
+ long whenNanos = (args.argi1 & 0xFFFFFFFFl) | ((long) args.argi2 << 32);
+ boolean inTabletMode = (boolean) args.arg1;
+ deliverTabletModeChanged(whenNanos, inTabletMode);
+ break;
}
}
}
@@ -1755,6 +1847,34 @@
}
}
+ private final class TabletModeChangedListenerRecord implements DeathRecipient {
+ private final int mPid;
+ private final ITabletModeChangedListener mListener;
+
+ public TabletModeChangedListenerRecord(int pid, ITabletModeChangedListener listener) {
+ mPid = pid;
+ mListener = listener;
+ }
+
+ @Override
+ public void binderDied() {
+ if (DEBUG) {
+ Slog.d(TAG, "Tablet mode changed listener for pid " + mPid + " died.");
+ }
+ onTabletModeChangedListenerDied(mPid);
+ }
+
+ public void notifyTabletModeChanged(long whenNanos, boolean inTabletMode) {
+ try {
+ mListener.onTabletModeChanged(whenNanos, inTabletMode);
+ } catch (RemoteException ex) {
+ Slog.w(TAG, "Failed to notify process " + mPid +
+ " that tablet mode changed, assuming it died.", ex);
+ binderDied();
+ }
+ }
+ }
+
private final class VibratorToken implements DeathRecipient {
public final int mDeviceId;
public final IBinder mToken;
diff --git a/services/core/java/com/android/server/job/JobSchedulerService.java b/services/core/java/com/android/server/job/JobSchedulerService.java
index ecda36a..3c50102 100644
--- a/services/core/java/com/android/server/job/JobSchedulerService.java
+++ b/services/core/java/com/android/server/job/JobSchedulerService.java
@@ -73,7 +73,7 @@
*/
public class JobSchedulerService extends com.android.server.SystemService
implements StateChangedListener, JobCompletedListener {
- static final boolean DEBUG = false;
+ public static final boolean DEBUG = false;
/** The number of concurrent jobs we run at one time. */
private static final int MAX_JOB_CONTEXTS_COUNT
= ActivityManager.isLowRamDeviceStatic() ? 1 : 3;
@@ -99,7 +99,7 @@
* Minimum # of connectivity jobs that must be ready in order to force the JMS to schedule
* things early.
*/
- static final int MIN_CONNECTIVITY_COUNT = 2;
+ static final int MIN_CONNECTIVITY_COUNT = 1; // Run connectivity jobs as soon as ready.
/**
* Minimum # of jobs (with no particular constraints) for which the JMS will be happy running
* some work early.
@@ -443,13 +443,16 @@
}
/**
- * A job is rescheduled with exponential back-off if the client requests this from their
- * execution logic.
- * A caveat is for idle-mode jobs, for which the idle-mode constraint will usurp the
- * timeliness of the reschedule. For an idle-mode job, no deadline is given.
+ * Reschedules the given job based on the job's backoff policy. It doesn't make sense to
+ * specify an override deadline on a failed job (the failed job will run even though it's not
+ * ready), so we reschedule it with {@link JobStatus#NO_LATEST_RUNTIME}, but specify that any
+ * ready job with {@link JobStatus#numFailures} > 0 will be executed.
+ *
* @param failureToReschedule Provided job status that we will reschedule.
* @return A newly instantiated JobStatus with the same constraints as the last job except
* with adjusted timing constraints.
+ *
+ * @see JobHandler#maybeQueueReadyJobsForExecutionLockedH
*/
private JobStatus getRescheduleJobForFailure(JobStatus failureToReschedule) {
final long elapsedNowMillis = SystemClock.elapsedRealtime();
@@ -479,8 +482,9 @@
}
/**
- * Called after a periodic has executed so we can to re-add it. We take the last execution time
- * of the job to be the time of completion (i.e. the time at which this function is called).
+ * Called after a periodic has executed so we can reschedule it. We take the last execution
+ * time of the job to be the time of completion (i.e. the time at which this function is
+ * called).
* This could be inaccurate b/c the job can run for as long as
* {@link com.android.server.job.JobServiceContext#EXECUTING_TIMESLICE_MILLIS}, but will lead
* to underscheduling at least, rather than if we had taken the last execution time to be the
@@ -491,7 +495,12 @@
private JobStatus getRescheduleJobForPeriodic(JobStatus periodicToReschedule) {
final long elapsedNow = SystemClock.elapsedRealtime();
// Compute how much of the period is remaining.
- long runEarly = Math.max(periodicToReschedule.getLatestRunTimeElapsed() - elapsedNow, 0);
+ long runEarly = 0L;
+
+ // If this periodic was rescheduled it won't have a deadline.
+ if (periodicToReschedule.hasDeadlineConstraint()) {
+ runEarly = Math.max(periodicToReschedule.getLatestRunTimeElapsed() - elapsedNow, 0L);
+ }
long newEarliestRunTimeElapsed = elapsedNow + runEarly;
long period = periodicToReschedule.getJob().getIntervalMillis();
long newLatestRuntimeElapsed = newEarliestRunTimeElapsed + period;
diff --git a/services/core/java/com/android/server/job/JobServiceContext.java b/services/core/java/com/android/server/job/JobServiceContext.java
index bb4e388..5515393 100644
--- a/services/core/java/com/android/server/job/JobServiceContext.java
+++ b/services/core/java/com/android/server/job/JobServiceContext.java
@@ -62,13 +62,13 @@
*
*/
public class JobServiceContext extends IJobCallback.Stub implements ServiceConnection {
- private static final boolean DEBUG = false;
+ private static final boolean DEBUG = JobSchedulerService.DEBUG;
private static final String TAG = "JobServiceContext";
/** Define the maximum # of jobs allowed to run on a service at once. */
private static final int defaultMaxActiveJobsPerService =
ActivityManager.isLowRamDeviceStatic() ? 1 : 3;
/** Amount of time a job is allowed to execute for before being considered timed-out. */
- private static final long EXECUTING_TIMESLICE_MILLIS = 10 * 60 * 1000;
+ private static final long EXECUTING_TIMESLICE_MILLIS = 10 * 60 * 1000; // 10mins.
/** Amount of time the JobScheduler will wait for a response from an app for a message. */
private static final long OP_TIMEOUT_MILLIS = 8 * 1000;
@@ -108,7 +108,13 @@
int mVerb;
private AtomicBoolean mCancelled = new AtomicBoolean();
- /** All the information maintained about the job currently being executed. */
+ /**
+ * All the information maintained about the job currently being executed.
+ *
+ * Any reads (dereferences) not done from the handler thread must be synchronized on
+ * {@link #mLock}.
+ * Writes can only be done from the handler thread, or {@link #executeRunnableJob(JobStatus)}.
+ */
private JobStatus mRunningJob;
/** Binder to the client service. */
IJobService service;
@@ -192,7 +198,8 @@
*/
JobStatus getRunningJob() {
synchronized (mLock) {
- return mRunningJob;
+ return mRunningJob == null ?
+ null : new JobStatus(mRunningJob);
}
}
@@ -253,15 +260,22 @@
*/
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
- if (!name.equals(mRunningJob.getServiceComponent())) {
+ JobStatus runningJob;
+ synchronized (mLock) {
+ // This isn't strictly necessary b/c the JobServiceHandler is running on the main
+ // looper and at this point we can't get any binder callbacks from the client. Better
+ // safe than sorry.
+ runningJob = mRunningJob;
+ }
+ if (runningJob == null || !name.equals(runningJob.getServiceComponent())) {
mCallbackHandler.obtainMessage(MSG_SHUTDOWN_EXECUTION).sendToTarget();
return;
}
this.service = IJobService.Stub.asInterface(service);
final PowerManager pm =
(PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
- mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, mRunningJob.getTag());
- mWakeLock.setWorkSource(new WorkSource(mRunningJob.getUid()));
+ mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, runningJob.getTag());
+ mWakeLock.setWorkSource(new WorkSource(runningJob.getUid()));
mWakeLock.setReferenceCounted(false);
mWakeLock.acquire();
mCallbackHandler.obtainMessage(MSG_SERVICE_BOUND).sendToTarget();
@@ -279,13 +293,15 @@
* @return True if the binder calling is coming from the client we expect.
*/
private boolean verifyCallingUid() {
- if (mRunningJob == null || Binder.getCallingUid() != mRunningJob.getUid()) {
- if (DEBUG) {
- Slog.d(TAG, "Stale callback received, ignoring.");
+ synchronized (mLock) {
+ if (mRunningJob == null || Binder.getCallingUid() != mRunningJob.getUid()) {
+ if (DEBUG) {
+ Slog.d(TAG, "Stale callback received, ignoring.");
+ }
+ return false;
}
- return false;
+ return true;
}
- return true;
}
/**
diff --git a/services/core/java/com/android/server/job/JobStore.java b/services/core/java/com/android/server/job/JobStore.java
index 24d4f15..53125c0 100644
--- a/services/core/java/com/android/server/job/JobStore.java
+++ b/services/core/java/com/android/server/job/JobStore.java
@@ -24,6 +24,7 @@
import android.os.PersistableBundle;
import android.os.SystemClock;
import android.os.UserHandle;
+import android.text.format.DateUtils;
import android.util.AtomicFile;
import android.util.ArraySet;
import android.util.Pair;
@@ -552,9 +553,10 @@
return null;
}
- Pair<Long, Long> runtimes;
+ // Tuple of (earliest runtime, latest runtime) in elapsed realtime after disk load.
+ Pair<Long, Long> elapsedRuntimes;
try {
- runtimes = buildExecutionTimesFromXml(parser);
+ elapsedRuntimes = buildExecutionTimesFromXml(parser);
} catch (NumberFormatException e) {
if (DEBUG) {
Slog.d(TAG, "Error parsing execution time parameters, skipping.");
@@ -562,22 +564,45 @@
return null;
}
+ final long elapsedNow = SystemClock.elapsedRealtime();
if (XML_TAG_PERIODIC.equals(parser.getName())) {
try {
String val = parser.getAttributeValue(null, "period");
- jobBuilder.setPeriodic(Long.valueOf(val));
+ final long periodMillis = Long.valueOf(val);
+ jobBuilder.setPeriodic(periodMillis);
+ // As a sanity check, cap the recreated run time to be no later than 2 periods
+ // from now. This is the latest the periodic could be pushed out. This could
+ // happen if the periodic ran early (at the start of its period), and then the
+ // device rebooted.
+ if (elapsedRuntimes.second > elapsedNow + 2 * periodMillis) {
+ final long clampedEarlyRuntimeElapsed = elapsedNow + periodMillis;
+ final long clampedLateRuntimeElapsed = elapsedNow + 2 * periodMillis;
+ Slog.w(TAG,
+ String.format("Periodic job for uid='%d' persisted run-time is" +
+ " too big [%s, %s]. Clamping to [%s,%s]",
+ uid,
+ DateUtils.formatElapsedTime(elapsedRuntimes.first / 1000),
+ DateUtils.formatElapsedTime(elapsedRuntimes.second / 1000),
+ DateUtils.formatElapsedTime(
+ clampedEarlyRuntimeElapsed / 1000),
+ DateUtils.formatElapsedTime(
+ clampedLateRuntimeElapsed / 1000))
+ );
+ elapsedRuntimes =
+ Pair.create(clampedEarlyRuntimeElapsed, clampedLateRuntimeElapsed);
+ }
} catch (NumberFormatException e) {
Slog.d(TAG, "Error reading periodic execution criteria, skipping.");
return null;
}
} else if (XML_TAG_ONEOFF.equals(parser.getName())) {
try {
- if (runtimes.first != JobStatus.NO_EARLIEST_RUNTIME) {
- jobBuilder.setMinimumLatency(runtimes.first - SystemClock.elapsedRealtime());
+ if (elapsedRuntimes.first != JobStatus.NO_EARLIEST_RUNTIME) {
+ jobBuilder.setMinimumLatency(elapsedRuntimes.first - elapsedNow);
}
- if (runtimes.second != JobStatus.NO_LATEST_RUNTIME) {
+ if (elapsedRuntimes.second != JobStatus.NO_LATEST_RUNTIME) {
jobBuilder.setOverrideDeadline(
- runtimes.second - SystemClock.elapsedRealtime());
+ elapsedRuntimes.second - elapsedNow);
}
} catch (NumberFormatException e) {
Slog.d(TAG, "Error reading job execution criteria, skipping.");
@@ -598,7 +623,8 @@
do {
eventType = parser.next();
} while (eventType == XmlPullParser.TEXT);
- if (!(eventType == XmlPullParser.START_TAG && XML_TAG_EXTRAS.equals(parser.getName()))) {
+ if (!(eventType == XmlPullParser.START_TAG
+ && XML_TAG_EXTRAS.equals(parser.getName()))) {
if (DEBUG) {
Slog.d(TAG, "Error reading extras, skipping.");
}
@@ -609,7 +635,8 @@
jobBuilder.setExtras(extras);
parser.nextTag(); // Consume </extras>
- return new JobStatus(jobBuilder.build(), uid, runtimes.first, runtimes.second);
+ return new JobStatus(
+ jobBuilder.build(), uid, elapsedRuntimes.first, elapsedRuntimes.second);
}
private JobInfo.Builder buildBuilderFromXml(XmlPullParser parser) throws NumberFormatException {
diff --git a/services/core/java/com/android/server/job/controllers/AppIdleController.java b/services/core/java/com/android/server/job/controllers/AppIdleController.java
index 02d4f40..6fc02f6 100644
--- a/services/core/java/com/android/server/job/controllers/AppIdleController.java
+++ b/services/core/java/com/android/server/job/controllers/AppIdleController.java
@@ -67,7 +67,7 @@
mTrackedTasks.add(jobStatus);
String packageName = jobStatus.job.getService().getPackageName();
final boolean appIdle = !mAppIdleParoleOn && mUsageStatsInternal.isAppIdle(packageName,
- jobStatus.getUserId());
+ jobStatus.uId, jobStatus.getUserId());
if (DEBUG) {
Slog.d(LOG_TAG, "Start tracking, setting idle state of "
+ packageName + " to " + appIdle);
@@ -108,7 +108,7 @@
for (JobStatus task : mTrackedTasks) {
String packageName = task.job.getService().getPackageName();
final boolean appIdle = !mAppIdleParoleOn && mUsageStatsInternal.isAppIdle(packageName,
- task.getUserId());
+ task.uId, task.getUserId());
if (DEBUG) {
Slog.d(LOG_TAG, "Setting idle state of " + packageName + " to " + appIdle);
}
diff --git a/services/core/java/com/android/server/job/controllers/JobStatus.java b/services/core/java/com/android/server/job/controllers/JobStatus.java
index 69c63f3..c02611f 100644
--- a/services/core/java/com/android/server/job/controllers/JobStatus.java
+++ b/services/core/java/com/android/server/job/controllers/JobStatus.java
@@ -82,6 +82,13 @@
this.numFailures = numFailures;
}
+ /** Copy constructor. */
+ public JobStatus(JobStatus jobStatus) {
+ this(jobStatus.getJob(), jobStatus.getUid(), jobStatus.getNumFailures());
+ this.earliestRunTimeElapsedMillis = jobStatus.getEarliestRunTime();
+ this.latestRunTimeElapsedMillis = jobStatus.getLatestRunTimeElapsed();
+ }
+
/** Create a newly scheduled job. */
public JobStatus(JobInfo job, int uId) {
this(job, uId, 0);
diff --git a/services/core/java/com/android/server/job/controllers/StateController.java b/services/core/java/com/android/server/job/controllers/StateController.java
index cda7c32..21c30c7 100644
--- a/services/core/java/com/android/server/job/controllers/StateController.java
+++ b/services/core/java/com/android/server/job/controllers/StateController.java
@@ -18,6 +18,7 @@
import android.content.Context;
+import com.android.server.job.JobSchedulerService;
import com.android.server.job.StateChangedListener;
import java.io.PrintWriter;
@@ -28,7 +29,7 @@
* are ready to run, or whether they must be stopped.
*/
public abstract class StateController {
- protected static final boolean DEBUG = false;
+ protected static final boolean DEBUG = JobSchedulerService.DEBUG;
protected Context mContext;
protected StateChangedListener mStateChangedListener;
protected boolean mDeviceIdleMode;
diff --git a/services/core/java/com/android/server/location/ActivityRecognitionProxy.java b/services/core/java/com/android/server/location/ActivityRecognitionProxy.java
index 607805b..55222dc 100644
--- a/services/core/java/com/android/server/location/ActivityRecognitionProxy.java
+++ b/services/core/java/com/android/server/location/ActivityRecognitionProxy.java
@@ -20,8 +20,10 @@
import android.content.Context;
import android.hardware.location.ActivityRecognitionHardware;
+import android.hardware.location.IActivityRecognitionHardwareClient;
import android.hardware.location.IActivityRecognitionHardwareWatcher;
import android.os.Handler;
+import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;
@@ -34,21 +36,24 @@
private static final String TAG = "ActivityRecognitionProxy";
private final ServiceWatcher mServiceWatcher;
- private final ActivityRecognitionHardware mActivityRecognitionHardware;
+ private final boolean mIsSupported;
+ private final ActivityRecognitionHardware mInstance;
private ActivityRecognitionProxy(
Context context,
Handler handler,
+ boolean activityRecognitionHardwareIsSupported,
ActivityRecognitionHardware activityRecognitionHardware,
int overlaySwitchResId,
int defaultServicePackageNameResId,
int initialPackageNameResId) {
- mActivityRecognitionHardware = activityRecognitionHardware;
+ mIsSupported = activityRecognitionHardwareIsSupported;
+ mInstance = activityRecognitionHardware;
Runnable newServiceWork = new Runnable() {
@Override
public void run() {
- bindProvider(mActivityRecognitionHardware);
+ bindProvider();
}
};
@@ -72,6 +77,7 @@
public static ActivityRecognitionProxy createAndBind(
Context context,
Handler handler,
+ boolean activityRecognitionHardwareIsSupported,
ActivityRecognitionHardware activityRecognitionHardware,
int overlaySwitchResId,
int defaultServicePackageNameResId,
@@ -79,6 +85,7 @@
ActivityRecognitionProxy activityRecognitionProxy = new ActivityRecognitionProxy(
context,
handler,
+ activityRecognitionHardwareIsSupported,
activityRecognitionHardware,
overlaySwitchResId,
defaultServicePackageNameResId,
@@ -89,25 +96,58 @@
Log.e(TAG, "ServiceWatcher could not start.");
return null;
}
-
return activityRecognitionProxy;
}
/**
* Helper function to bind the FusedLocationHardware to the appropriate FusedProvider instance.
*/
- private void bindProvider(ActivityRecognitionHardware activityRecognitionHardware) {
- IActivityRecognitionHardwareWatcher watcher =
- IActivityRecognitionHardwareWatcher.Stub.asInterface(mServiceWatcher.getBinder());
- if (watcher == null) {
- Log.e(TAG, "No provider instance found on connection.");
+ private void bindProvider() {
+ IBinder binder = mServiceWatcher.getBinder();
+ if (binder == null) {
+ Log.e(TAG, "Null binder found on connection.");
+ return;
+ }
+ String descriptor;
+ try {
+ descriptor = binder.getInterfaceDescriptor();
+ } catch (RemoteException e) {
+ Log.e(TAG, "Unable to get interface descriptor.", e);
return;
}
- try {
- watcher.onInstanceChanged(mActivityRecognitionHardware);
- } catch (RemoteException e) {
- Log.e(TAG, "Error delivering hardware interface.", e);
+ if (IActivityRecognitionHardwareWatcher.class.getCanonicalName().equals(descriptor)) {
+ IActivityRecognitionHardwareWatcher watcher =
+ IActivityRecognitionHardwareWatcher.Stub.asInterface(binder);
+ if (watcher == null) {
+ Log.e(TAG, "No watcher found on connection.");
+ return;
+ }
+ if (mInstance == null) {
+ // to keep backwards compatibility do not update the watcher when there is no
+ // instance available, or it will cause an NPE
+ Log.d(TAG, "AR HW instance not available, binding will be a no-op.");
+ return;
+ }
+ try {
+ watcher.onInstanceChanged(mInstance);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Error delivering hardware interface to watcher.", e);
+ }
+ } else if (IActivityRecognitionHardwareClient.class.getCanonicalName().equals(descriptor)) {
+ IActivityRecognitionHardwareClient client =
+ IActivityRecognitionHardwareClient.Stub.asInterface(binder);
+ if (client == null) {
+ Log.e(TAG, "No client found on connection.");
+ return;
+ }
+ try {
+ client.onAvailabilityChanged(mIsSupported, mInstance);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Error delivering hardware interface to client.", e);
+ }
+ } else {
+ Log.e(TAG, "Invalid descriptor found on connection: " + descriptor);
}
}
}
diff --git a/services/core/java/com/android/server/location/GpsLocationProvider.java b/services/core/java/com/android/server/location/GpsLocationProvider.java
index ba5f516..f671e64 100644
--- a/services/core/java/com/android/server/location/GpsLocationProvider.java
+++ b/services/core/java/com/android/server/location/GpsLocationProvider.java
@@ -444,7 +444,8 @@
checkSmsSuplInit(intent);
} else if (action.equals(Intents.WAP_PUSH_RECEIVED_ACTION)) {
checkWapSuplInit(intent);
- } else if (action.equals(ConnectivityManager.CONNECTIVITY_ACTION)) {
+ } else if (action.equals(ConnectivityManager.CONNECTIVITY_ACTION)
+ || action.equals(ConnectivityManager.CONNECTIVITY_ACTION_SUPL)) {
// retrieve NetworkInfo result for this UID
NetworkInfo info =
intent.getParcelableExtra(ConnectivityManager.EXTRA_NETWORK_INFO);
@@ -2045,6 +2046,7 @@
intentFilter.addAction(ALARM_WAKEUP);
intentFilter.addAction(ALARM_TIMEOUT);
intentFilter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
+ intentFilter.addAction(ConnectivityManager.CONNECTIVITY_ACTION_SUPL);
intentFilter.addAction(PowerManager.ACTION_POWER_SAVE_MODE_CHANGED);
intentFilter.addAction(PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED);
intentFilter.addAction(Intent.ACTION_SCREEN_OFF);
diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
index 5c1878e..b428322 100644
--- a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
+++ b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
@@ -39,17 +39,17 @@
import static android.net.NetworkPolicyManager.EXTRA_NETWORK_TEMPLATE;
import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_DOZABLE;
import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_STANDBY;
-import static android.net.NetworkPolicyManager.FIREWALL_RULE_DEFAULT;
import static android.net.NetworkPolicyManager.FIREWALL_RULE_ALLOW;
+import static android.net.NetworkPolicyManager.FIREWALL_RULE_DEFAULT;
import static android.net.NetworkPolicyManager.FIREWALL_RULE_DENY;
import static android.net.NetworkPolicyManager.POLICY_ALLOW_BACKGROUND_BATTERY_SAVE;
import static android.net.NetworkPolicyManager.POLICY_NONE;
import static android.net.NetworkPolicyManager.POLICY_REJECT_METERED_BACKGROUND;
import static android.net.NetworkPolicyManager.RULE_ALLOW_ALL;
+import static android.net.NetworkPolicyManager.RULE_REJECT_ALL;
import static android.net.NetworkPolicyManager.RULE_REJECT_METERED;
+import static android.net.NetworkPolicyManager.RULE_UNKNOWN;
import static android.net.NetworkPolicyManager.computeLastCycleBoundary;
-import static android.net.NetworkPolicyManager.dumpPolicy;
-import static android.net.NetworkPolicyManager.dumpRules;
import static android.net.NetworkTemplate.MATCH_MOBILE_3G_LOWER;
import static android.net.NetworkTemplate.MATCH_MOBILE_4G;
import static android.net.NetworkTemplate.MATCH_MOBILE_ALL;
@@ -108,6 +108,7 @@
import android.net.NetworkIdentity;
import android.net.NetworkInfo;
import android.net.NetworkPolicy;
+import android.net.NetworkPolicyManager;
import android.net.NetworkQuotaInfo;
import android.net.NetworkState;
import android.net.NetworkTemplate;
@@ -138,6 +139,7 @@
import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.AtomicFile;
+import android.util.DebugUtils;
import android.util.Log;
import android.util.NtpTrustedTime;
import android.util.Pair;
@@ -147,8 +149,6 @@
import android.util.TrustedTime;
import android.util.Xml;
-import com.android.server.DeviceIdleController;
-import com.android.server.EventLogTags;
import libcore.io.IoUtils;
import com.android.internal.R;
@@ -156,6 +156,8 @@
import com.android.internal.util.ArrayUtils;
import com.android.internal.util.FastXmlSerializer;
import com.android.internal.util.IndentingPrintWriter;
+import com.android.server.DeviceIdleController;
+import com.android.server.EventLogTags;
import com.android.server.LocalServices;
import com.google.android.collect.Lists;
@@ -279,6 +281,10 @@
final SparseIntArray mUidPolicy = new SparseIntArray();
/** Currently derived rules for each UID. */
final SparseIntArray mUidRules = new SparseIntArray();
+
+ final SparseIntArray mUidFirewallStandbyRules = new SparseIntArray();
+ final SparseIntArray mUidFirewallDozableRules = new SparseIntArray();
+
/** Set of states for the child firewall chains. True if the chain is active. */
final SparseBooleanArray mFirewallChainStates = new SparseBooleanArray();
@@ -446,14 +452,8 @@
// read policy from disk
readPolicyLocked();
- if (mRestrictBackground || mRestrictPower || mDeviceIdleMode) {
- updateRulesForGlobalChangeLocked(false);
- updateNotificationsLocked();
- } else {
- // If we are not in any special mode, we just need to make sure the current
- // app idle state is updated.
- updateRulesForAppIdleLocked();
- }
+ updateRulesForGlobalChangeLocked(false);
+ updateNotificationsLocked();
}
updateScreenOn();
@@ -1800,7 +1800,9 @@
if (mDeviceIdleMode != enabled) {
mDeviceIdleMode = enabled;
if (mSystemReady) {
- updateRulesForDeviceIdleLocked();
+ // Device idle change means we need to rebuild rules for all
+ // known apps, so do a global refresh.
+ updateRulesForGlobalChangeLocked(false);
}
if (enabled) {
EventLogTags.writeDeviceIdleOnPhase("net");
@@ -1938,7 +1940,7 @@
fout.print("UID=");
fout.print(uid);
fout.print(" policy=");
- dumpPolicy(fout, policy);
+ fout.print(DebugUtils.flagsToString(NetworkPolicyManager.class, "POLICY_", policy));
fout.println();
}
fout.decreaseIndent();
@@ -1983,18 +1985,14 @@
fout.print("UID=");
fout.print(uid);
- int state = mUidState.get(uid, ActivityManager.PROCESS_STATE_CACHED_EMPTY);
+ final int state = mUidState.get(uid, ActivityManager.PROCESS_STATE_CACHED_EMPTY);
fout.print(" state=");
fout.print(state);
fout.print(state <= ActivityManager.PROCESS_STATE_TOP ? " (fg)" : " (bg)");
- fout.print(" rules=");
- final int rulesIndex = mUidRules.indexOfKey(uid);
- if (rulesIndex < 0) {
- fout.print("UNKNOWN");
- } else {
- dumpRules(fout, mUidRules.valueAt(rulesIndex));
- }
+ final int rule = mUidRules.get(uid, RULE_UNKNOWN);
+ fout.print(" rule=");
+ fout.print(DebugUtils.valueToString(NetworkPolicyManager.class, "RULE_", rule));
fout.println();
}
@@ -2029,7 +2027,7 @@
updateRulesForUidStateChangeLocked(uid, oldUidState, uidState);
if (mDeviceIdleMode && isProcStateAllowedWhileIdle(oldUidState)
!= isProcStateAllowedWhileIdle(uidState)) {
- updateRulesForDeviceIdleLocked();
+ updateRuleForDeviceIdleLocked(uid);
}
}
}
@@ -2043,7 +2041,7 @@
updateRulesForUidStateChangeLocked(uid, oldUidState,
ActivityManager.PROCESS_STATE_CACHED_EMPTY);
if (mDeviceIdleMode) {
- updateRulesForDeviceIdleLocked();
+ updateRuleForDeviceIdleLocked(uid);
}
}
}
@@ -2090,7 +2088,8 @@
if (mDeviceIdleMode) {
// sync the whitelists before enable dozable chain. We don't care about the rules if
// we are disabling the chain.
- SparseIntArray uidRules = new SparseIntArray();
+ final SparseIntArray uidRules = mUidFirewallDozableRules;
+ uidRules.clear();
final List<UserInfo> users = mUserManager.getUsers();
for (int ui = users.size() - 1; ui >= 0; ui--) {
UserInfo user = users.get(ui);
@@ -2114,6 +2113,7 @@
}
setUidFirewallRules(FIREWALL_CHAIN_DOZABLE, uidRules);
}
+
enableFirewallChainLocked(FIREWALL_CHAIN_DOZABLE, mDeviceIdleMode);
}
@@ -2127,11 +2127,15 @@
setUidFirewallRule(FIREWALL_CHAIN_DOZABLE, uid, FIREWALL_RULE_DEFAULT);
}
}
+
+ updateRulesForUidLocked(uid);
}
void updateRulesForAppIdleLocked() {
+ final SparseIntArray uidRules = mUidFirewallStandbyRules;
+ uidRules.clear();
+
// Fully update the app idle firewall chain.
- SparseIntArray uidRules = new SparseIntArray();
final List<UserInfo> users = mUserManager.getUsers();
for (int ui = users.size() - 1; ui >= 0; ui--) {
UserInfo user = users.get(ui);
@@ -2142,6 +2146,7 @@
}
}
}
+
setUidFirewallRules(FIREWALL_CHAIN_STANDBY, uidRules);
}
@@ -2154,11 +2159,14 @@
} else {
setUidFirewallRule(FIREWALL_CHAIN_STANDBY, uid, FIREWALL_RULE_DEFAULT);
}
+
+ updateRulesForUidLocked(uid);
}
void updateRulesForAppIdleParoleLocked() {
boolean enableChain = !mUsageStats.isAppIdleParoleOn();
enableFirewallChainLocked(FIREWALL_CHAIN_STANDBY, enableChain);
+ updateRulesForUidsLocked(mUidFirewallStandbyRules);
}
/**
@@ -2221,13 +2229,19 @@
final int userId = UserHandle.getUserId(uid);
for (String packageName : packages) {
- if (!mUsageStats.isAppIdle(packageName, userId)) {
+ if (!mUsageStats.isAppIdle(packageName, uid, userId)) {
return false;
}
}
return true;
}
+ void updateRulesForUidsLocked(SparseIntArray uids) {
+ for (int i = 0; i < uids.size(); i++) {
+ updateRulesForUidLocked(uids.keyAt(i));
+ }
+ }
+
/**
* Applies network rules to bandwidth and firewall controllers based on uid policy.
* @param uid The uid for which to apply the latest policy
@@ -2249,8 +2263,7 @@
final int uidPolicy = mUidPolicy.get(uid, POLICY_NONE);
final boolean uidForeground = isUidForegroundLocked(uid);
- // derive active rules based on policy and active state
-
+ // Derive active rules based on policy and active state
int appId = UserHandle.getAppId(uid);
int uidRules = RULE_ALLOW_ALL;
if (!uidForeground && (uidPolicy & POLICY_REJECT_METERED_BACKGROUND) != 0) {
@@ -2273,20 +2286,27 @@
}
}
- final int oldRules = mUidRules.get(uid);
+ // Check dozable state, which is whitelist
+ if (mFirewallChainStates.get(FIREWALL_CHAIN_DOZABLE)
+ && mUidFirewallDozableRules.get(uid, FIREWALL_RULE_DEFAULT) != FIREWALL_RULE_ALLOW) {
+ uidRules = RULE_REJECT_ALL;
+ }
+ // Check standby state, which is blacklist
+ if (mFirewallChainStates.get(FIREWALL_CHAIN_STANDBY)
+ && mUidFirewallStandbyRules.get(uid, FIREWALL_RULE_DEFAULT) == FIREWALL_RULE_DENY) {
+ uidRules = RULE_REJECT_ALL;
+ }
+
+ final int oldRules = mUidRules.get(uid);
if (uidRules == RULE_ALLOW_ALL) {
mUidRules.delete(uid);
} else {
mUidRules.put(uid, uidRules);
}
- // Update bandwidth rules if necessary
- final boolean oldRejectMetered = (oldRules & RULE_REJECT_METERED) != 0;
- final boolean rejectMetered = (uidRules & RULE_REJECT_METERED) != 0;
- if (oldRejectMetered != rejectMetered) {
- setUidNetworkRules(uid, rejectMetered);
- }
+ final boolean rejectMetered = (uidRules == RULE_REJECT_METERED);
+ setUidNetworkRules(uid, rejectMetered);
// dispatch changed rule to existing listeners
if (oldRules != uidRules) {
@@ -2472,6 +2492,12 @@
* Add or remove a uid to the firewall blacklist for all network ifaces.
*/
private void setUidFirewallRule(int chain, int uid, int rule) {
+ if (chain == FIREWALL_CHAIN_DOZABLE) {
+ mUidFirewallDozableRules.put(uid, rule);
+ } else if (chain == FIREWALL_CHAIN_STANDBY) {
+ mUidFirewallStandbyRules.put(uid, rule);
+ }
+
try {
mNetworkManager.setFirewallUidRule(chain, uid, rule);
} catch (IllegalStateException e) {
@@ -2485,9 +2511,9 @@
* Add or remove a uid to the firewall blacklist for all network ifaces.
*/
private void enableFirewallChainLocked(int chain, boolean enable) {
- if (mFirewallChainStates.indexOfKey(chain) >= 0 &&
- mFirewallChainStates.get(chain) == enable) {
- // All is the same, nothing to do.
+ if (mFirewallChainStates.get(chain, false) == enable) {
+ // All is the same, nothing to do. This relies on the fact that netd has child
+ // chains default detached.
return;
}
mFirewallChainStates.put(chain, enable);
diff --git a/services/core/java/com/android/server/notification/ZenModeConditions.java b/services/core/java/com/android/server/notification/ZenModeConditions.java
index b89a654..c2e4349 100644
--- a/services/core/java/com/android/server/notification/ZenModeConditions.java
+++ b/services/core/java/com/android/server/notification/ZenModeConditions.java
@@ -104,7 +104,7 @@
public void onServiceAdded(ComponentName component) {
if (DEBUG) Log.d(TAG, "onServiceAdded " + component);
if (isAutomaticActive(component)) {
- mHelper.setConfig(mHelper.getConfig(), "zmc.onServiceAdded");
+ mHelper.setConfigAsync(mHelper.getConfig(), "zmc.onServiceAdded");
}
}
@@ -120,7 +120,7 @@
updated |= updateSnoozing(automaticRule);
}
if (updated) {
- mHelper.setConfig(config, "conditionChanged");
+ mHelper.setConfigAsync(config, "conditionChanged");
}
}
diff --git a/services/core/java/com/android/server/notification/ZenModeHelper.java b/services/core/java/com/android/server/notification/ZenModeHelper.java
index 57d7758..c9a1f78 100644
--- a/services/core/java/com/android/server/notification/ZenModeHelper.java
+++ b/services/core/java/com/android/server/notification/ZenModeHelper.java
@@ -315,6 +315,10 @@
return setConfig(config, reason, true /*setRingerMode*/);
}
+ public void setConfigAsync(ZenModeConfig config, String reason) {
+ mHandler.postSetConfig(config, reason);
+ }
+
private boolean setConfig(ZenModeConfig config, String reason, boolean setRingerMode) {
if (config == null || !config.isValid()) {
Log.w(TAG, "Invalid config in setConfig; " + config);
@@ -328,14 +332,16 @@
}
mConditions.evaluateConfig(config, false /*processSubscriptions*/); // may modify config
mConfigs.put(config.user, config);
- if (config.equals(mConfig)) return true;
if (DEBUG) Log.d(TAG, "setConfig reason=" + reason, new Throwable());
ZenLog.traceConfig(reason, mConfig, config);
final boolean policyChanged = !Objects.equals(getNotificationPolicy(mConfig),
getNotificationPolicy(config));
+ boolean configChanged = !config.equals(mConfig);
mConfig = config;
- dispatchOnConfigChanged();
- if (policyChanged){
+ if (configChanged) {
+ dispatchOnConfigChanged();
+ }
+ if (policyChanged) {
dispatchOnPolicyChanged();
}
final String val = Integer.toString(mConfig.hashCode());
@@ -368,9 +374,9 @@
private boolean evaluateZenMode(String reason, boolean setRingerMode) {
if (DEBUG) Log.d(TAG, "evaluateZenMode");
+ final int zenBefore = mZenMode;
final ArraySet<ZenRule> automaticRules = new ArraySet<ZenRule>();
final int zen = computeZenMode(automaticRules);
- if (zen == mZenMode) return false;
ZenLog.traceSetZenMode(zen, reason);
mZenMode = zen;
updateRingerModeAffectedStreams();
@@ -379,7 +385,9 @@
applyZenToRingerMode();
}
applyRestrictions();
- mHandler.postDispatchOnZenModeChanged();
+ if (zen != zenBefore) {
+ mHandler.postDispatchOnZenModeChanged();
+ }
return true;
}
@@ -743,6 +751,17 @@
private final class H extends Handler {
private static final int MSG_DISPATCH = 1;
private static final int MSG_METRICS = 2;
+ private static final int MSG_SET_CONFIG = 3;
+
+ private final class ConfigMessageData {
+ public final ZenModeConfig config;
+ public final String reason;
+
+ ConfigMessageData(ZenModeConfig config, String reason) {
+ this.config = config;
+ this.reason = reason;
+ }
+ }
private static final long METRICS_PERIOD_MS = 6 * 60 * 60 * 1000;
@@ -760,6 +779,10 @@
sendEmptyMessageDelayed(MSG_METRICS, METRICS_PERIOD_MS);
}
+ private void postSetConfig(ZenModeConfig config, String reason) {
+ sendMessage(obtainMessage(MSG_SET_CONFIG, new ConfigMessageData(config, reason)));
+ }
+
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
@@ -769,6 +792,10 @@
case MSG_METRICS:
mMetrics.emit();
break;
+ case MSG_SET_CONFIG:
+ ConfigMessageData configData = (ConfigMessageData)msg.obj;
+ setConfig(configData.config, configData.reason);
+ break;
}
}
}
diff --git a/services/core/java/com/android/server/pm/Installer.java b/services/core/java/com/android/server/pm/Installer.java
index b59b4b2..f292c9c 100644
--- a/services/core/java/com/android/server/pm/Installer.java
+++ b/services/core/java/com/android/server/pm/Installer.java
@@ -77,24 +77,37 @@
public int dexopt(String apkPath, int uid, boolean isPublic,
String instructionSet, int dexoptNeeded) {
+ return dexopt(apkPath, uid, isPublic, instructionSet, dexoptNeeded, true);
+ }
+
+ public int dexopt(String apkPath, int uid, boolean isPublic,
+ String instructionSet, int dexoptNeeded, boolean bootComplete) {
if (!isValidInstructionSet(instructionSet)) {
Slog.e(TAG, "Invalid instruction set: " + instructionSet);
return -1;
}
- return mInstaller.dexopt(apkPath, uid, isPublic, instructionSet, dexoptNeeded);
+ return mInstaller.dexopt(apkPath, uid, isPublic, instructionSet, dexoptNeeded,
+ bootComplete);
}
public int dexopt(String apkPath, int uid, boolean isPublic, String pkgName,
String instructionSet, int dexoptNeeded, boolean vmSafeMode,
boolean debuggable, @Nullable String outputPath) {
+ return dexopt(apkPath, uid, isPublic, pkgName, instructionSet, dexoptNeeded, vmSafeMode,
+ debuggable, outputPath, true);
+ }
+
+ public int dexopt(String apkPath, int uid, boolean isPublic, String pkgName,
+ String instructionSet, int dexoptNeeded, boolean vmSafeMode,
+ boolean debuggable, @Nullable String outputPath, boolean bootComplete) {
if (!isValidInstructionSet(instructionSet)) {
Slog.e(TAG, "Invalid instruction set: " + instructionSet);
return -1;
}
return mInstaller.dexopt(apkPath, uid, isPublic, pkgName,
instructionSet, dexoptNeeded, vmSafeMode,
- debuggable, outputPath);
+ debuggable, outputPath, bootComplete);
}
public int idmap(String targetApkPath, String overlayApkPath, int uid) {
diff --git a/services/core/java/com/android/server/pm/PackageDexOptimizer.java b/services/core/java/com/android/server/pm/PackageDexOptimizer.java
index 7024ec8..b692def 100644
--- a/services/core/java/com/android/server/pm/PackageDexOptimizer.java
+++ b/services/core/java/com/android/server/pm/PackageDexOptimizer.java
@@ -71,7 +71,7 @@
* {@link PackageManagerService#mInstallLock}.
*/
int performDexOpt(PackageParser.Package pkg, String[] instructionSets,
- boolean forceDex, boolean defer, boolean inclDependencies) {
+ boolean forceDex, boolean defer, boolean inclDependencies, boolean bootComplete) {
ArraySet<String> done;
if (inclDependencies && (pkg.usesLibraries != null || pkg.usesOptionalLibraries != null)) {
done = new ArraySet<String>();
@@ -86,7 +86,7 @@
mDexoptWakeLock.acquire();
}
try {
- return performDexOptLI(pkg, instructionSets, forceDex, defer, done);
+ return performDexOptLI(pkg, instructionSets, forceDex, defer, bootComplete, done);
} finally {
if (useLock) {
mDexoptWakeLock.release();
@@ -96,18 +96,19 @@
}
private int performDexOptLI(PackageParser.Package pkg, String[] targetInstructionSets,
- boolean forceDex, boolean defer, ArraySet<String> done) {
+ boolean forceDex, boolean defer, boolean bootComplete, ArraySet<String> done) {
final String[] instructionSets = targetInstructionSets != null ?
targetInstructionSets : getAppDexInstructionSets(pkg.applicationInfo);
if (done != null) {
done.add(pkg.packageName);
if (pkg.usesLibraries != null) {
- performDexOptLibsLI(pkg.usesLibraries, instructionSets, forceDex, defer, done);
+ performDexOptLibsLI(pkg.usesLibraries, instructionSets, forceDex, defer,
+ bootComplete, done);
}
if (pkg.usesOptionalLibraries != null) {
performDexOptLibsLI(pkg.usesOptionalLibraries, instructionSets, forceDex, defer,
- done);
+ bootComplete, done);
}
}
@@ -174,11 +175,11 @@
Log.i(TAG, "Running dexopt (" + dexoptType + ") on: " + path + " pkg="
+ pkg.applicationInfo.packageName + " isa=" + dexCodeInstructionSet
+ " vmSafeMode=" + vmSafeMode + " debuggable=" + debuggable
- + " oatDir = " + oatDir);
+ + " oatDir = " + oatDir + " bootComplete=" + bootComplete);
final int sharedGid = UserHandle.getSharedAppGid(pkg.applicationInfo.uid);
final int ret = mPackageManagerService.mInstaller.dexopt(path, sharedGid,
!pkg.isForwardLocked(), pkg.packageName, dexCodeInstructionSet,
- dexoptNeeded, vmSafeMode, debuggable, oatDir);
+ dexoptNeeded, vmSafeMode, debuggable, oatDir, bootComplete);
// Dex2oat might fail due to compiler / verifier errors. We soldier on
// regardless, and attempt to interpret the app as a safety net.
@@ -217,8 +218,7 @@
@Nullable
private String createOatDirIfSupported(PackageParser.Package pkg, String dexInstructionSet)
throws IOException {
- if ((pkg.isSystemApp() && !pkg.isUpdatedSystemApp()) || pkg.isForwardLocked()
- || pkg.applicationInfo.isExternalAsec()) {
+ if (!pkg.canHaveOatDir()) {
return null;
}
File codePath = new File(pkg.codePath);
@@ -236,12 +236,12 @@
}
private void performDexOptLibsLI(ArrayList<String> libs, String[] instructionSets,
- boolean forceDex, boolean defer, ArraySet<String> done) {
+ boolean forceDex, boolean defer, boolean bootComplete, ArraySet<String> done) {
for (String libName : libs) {
PackageParser.Package libPkg = mPackageManagerService.findSharedNonSystemLibrary(
libName);
if (libPkg != null && !done.contains(libName)) {
- performDexOptLI(libPkg, instructionSets, forceDex, defer, done);
+ performDexOptLI(libPkg, instructionSets, forceDex, defer, bootComplete, done);
}
}
}
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index d19da1c..7654cc9 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -1714,13 +1714,16 @@
return;
}
- PermissionsState permissionsState = sb.getPermissionsState();
-
- for (String permission : pkg.requestedPermissions) {
- BasePermission bp = mSettings.mPermissions.get(permission);
- if (bp != null && bp.isRuntime() && (grantedPermissions == null
- || ArrayUtils.contains(grantedPermissions, permission))) {
- permissionsState.grantRuntimePermission(bp, userId);
+ synchronized (mPackages) {
+ for (String permission : pkg.requestedPermissions) {
+ BasePermission bp = mSettings.mPermissions.get(permission);
+ if (bp != null && (bp.isRuntime() || bp.isDevelopment())
+ && (grantedPermissions == null
+ || ArrayUtils.contains(grantedPermissions, permission))
+ && (getPermissionFlags(permission, pkg.packageName, userId)
+ & PackageManager.FLAG_PERMISSION_SYSTEM_FIXED) == 0) {
+ grantRuntimePermission(pkg.packageName, permission, userId);
+ }
}
}
}
@@ -1980,7 +1983,7 @@
int dexoptNeeded = DexFile.getDexOptNeeded(lib, null, dexCodeInstructionSet, false);
if (dexoptNeeded != DexFile.NO_DEXOPT_NEEDED) {
alreadyDexOpted.add(lib);
- mInstaller.dexopt(lib, Process.SYSTEM_UID, true, dexCodeInstructionSet, dexoptNeeded);
+ mInstaller.dexopt(lib, Process.SYSTEM_UID, true, dexCodeInstructionSet, dexoptNeeded, false);
}
} catch (FileNotFoundException e) {
Slog.w(TAG, "Library not found: " + lib);
@@ -2028,7 +2031,7 @@
try {
int dexoptNeeded = DexFile.getDexOptNeeded(path, null, dexCodeInstructionSet, false);
if (dexoptNeeded != DexFile.NO_DEXOPT_NEEDED) {
- mInstaller.dexopt(path, Process.SYSTEM_UID, true, dexCodeInstructionSet, dexoptNeeded);
+ mInstaller.dexopt(path, Process.SYSTEM_UID, true, dexCodeInstructionSet, dexoptNeeded, false);
}
} catch (FileNotFoundException e) {
Slog.w(TAG, "Jar not found: " + path);
@@ -2257,7 +2260,8 @@
// the rest of the commands above) because there's precious little we
// can do about it. A settings error is reported, though.
adjustCpuAbisForSharedUserLPw(setting.packages, null /* scanned package */,
- false /* force dexopt */, false /* defer dexopt */);
+ false /* force dexopt */, false /* defer dexopt */,
+ false /* boot complete */);
}
// Now that we know all the packages we are keeping,
@@ -2282,7 +2286,7 @@
+ mSdkVersion + "; regranting permissions for internal storage");
updateFlags |= UPDATE_PERMISSIONS_REPLACE_PKG | UPDATE_PERMISSIONS_REPLACE_ALL;
}
- updatePermissionsLPw(null, null, updateFlags);
+ updatePermissionsLPw(null, null, StorageManager.UUID_PRIVATE_INTERNAL, updateFlags);
ver.sdkVersion = mSdkVersion;
// If this is the first boot or an update from pre-M, and it is a normal
@@ -2732,26 +2736,38 @@
@Override
public int getPackageUid(String packageName, int userId) {
+ return getPackageUidEtc(packageName, 0, userId);
+ }
+
+ @Override
+ public int getPackageUidEtc(String packageName, int flags, int userId) {
if (!sUserManager.exists(userId)) return -1;
enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get package uid");
// reader
synchronized (mPackages) {
- PackageParser.Package p = mPackages.get(packageName);
- if(p != null) {
+ final PackageParser.Package p = mPackages.get(packageName);
+ if (p != null) {
return UserHandle.getUid(userId, p.applicationInfo.uid);
}
- PackageSetting ps = mSettings.mPackages.get(packageName);
- if((ps == null) || (ps.pkg == null) || (ps.pkg.applicationInfo == null)) {
- return -1;
+ if ((flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0) {
+ final PackageSetting ps = mSettings.mPackages.get(packageName);
+ if (ps != null) {
+ return UserHandle.getUid(userId, ps.appId);
+ }
}
- p = ps.pkg;
- return p != null ? UserHandle.getUid(userId, p.applicationInfo.uid) : -1;
}
+
+ return -1;
}
@Override
- public int[] getPackageGids(String packageName, int userId) throws RemoteException {
+ public int[] getPackageGids(String packageName, int userId) {
+ return getPackageGidsEtc(packageName, 0, userId);
+ }
+
+ @Override
+ public int[] getPackageGidsEtc(String packageName, int flags, int userId) {
if (!sUserManager.exists(userId)) {
return null;
}
@@ -2761,14 +2777,17 @@
// reader
synchronized (mPackages) {
- PackageParser.Package p = mPackages.get(packageName);
- if (DEBUG_PACKAGE_INFO) {
- Log.v(TAG, "getPackageGids" + packageName + ": " + p);
- }
+ final PackageParser.Package p = mPackages.get(packageName);
if (p != null) {
PackageSetting ps = (PackageSetting) p.mExtras;
return ps.getPermissionsState().computeGids(userId);
}
+ if ((flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0) {
+ final PackageSetting ps = mSettings.mPackages.get(packageName);
+ if (ps != null) {
+ return ps.getPermissionsState().computeGids(userId);
+ }
+ }
}
return null;
@@ -3519,7 +3538,8 @@
killUid(appId, userId, KILL_APP_REASON_GIDS_CHANGED);
}
});
- } break;
+ }
+ break;
}
mOnPermissionChangeListeners.onPermissionsChanged(uid);
@@ -4772,18 +4792,13 @@
// First try to add the "always" resolution(s) for the current user, if any
if (alwaysList.size() > 0) {
result.addAll(alwaysList);
- // if there is an "always" for the parent user, add it.
- } else if (xpDomainInfo != null && xpDomainInfo.bestDomainVerificationStatus
- == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS) {
- result.add(xpDomainInfo.resolveInfo);
} else {
// Add all undefined apps as we want them to appear in the disambiguation dialog.
result.addAll(undefinedList);
+ // Maybe add one for the other profile.
if (xpDomainInfo != null && (
xpDomainInfo.bestDomainVerificationStatus
- == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED
- || xpDomainInfo.bestDomainVerificationStatus
- == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK)) {
+ != INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER)) {
result.add(xpDomainInfo.resolveInfo);
}
includeBrowser = true;
@@ -6083,41 +6098,6 @@
it.remove();
}
}
- // Give priority to system apps.
- for (Iterator<PackageParser.Package> it = pkgs.iterator(); it.hasNext();) {
- PackageParser.Package pkg = it.next();
- if (isSystemApp(pkg) && !pkg.isUpdatedSystemApp()) {
- if (DEBUG_DEXOPT) {
- Log.i(TAG, "Adding system app " + sortedPkgs.size() + ": " + pkg.packageName);
- }
- sortedPkgs.add(pkg);
- it.remove();
- }
- }
- // Give priority to updated system apps.
- for (Iterator<PackageParser.Package> it = pkgs.iterator(); it.hasNext();) {
- PackageParser.Package pkg = it.next();
- if (pkg.isUpdatedSystemApp()) {
- if (DEBUG_DEXOPT) {
- Log.i(TAG, "Adding updated system app " + sortedPkgs.size() + ": " + pkg.packageName);
- }
- sortedPkgs.add(pkg);
- it.remove();
- }
- }
- // Give priority to apps that listen for boot complete.
- intent = new Intent(Intent.ACTION_BOOT_COMPLETED);
- pkgNames = getPackageNamesForIntent(intent);
- for (Iterator<PackageParser.Package> it = pkgs.iterator(); it.hasNext();) {
- PackageParser.Package pkg = it.next();
- if (pkgNames.contains(pkg.packageName)) {
- if (DEBUG_DEXOPT) {
- Log.i(TAG, "Adding boot app " + sortedPkgs.size() + ": " + pkg.packageName);
- }
- sortedPkgs.add(pkg);
- it.remove();
- }
- }
// Filter out packages that aren't recently used.
filterRecentlyUsedApps(pkgs);
// Add all remaining apps.
@@ -6209,7 +6189,8 @@
PackageParser.Package p = pkg;
synchronized (mInstallLock) {
mPackageDexOptimizer.performDexOpt(p, null /* instruction sets */,
- false /* force dex */, false /* defer */, true /* include dependencies */);
+ false /* force dex */, false /* defer */, true /* include dependencies */,
+ false /* boot complete */);
}
}
@@ -6252,7 +6233,8 @@
synchronized (mInstallLock) {
final String[] instructionSets = new String[] { targetInstructionSet };
int result = mPackageDexOptimizer.performDexOpt(p, instructionSets,
- false /* forceDex */, false /* defer */, true /* inclDependencies */);
+ false /* forceDex */, false /* defer */, true /* inclDependencies */,
+ true /* boot complete */);
return result == PackageDexOptimizer.DEX_OPT_PERFORMED;
}
} finally {
@@ -6299,7 +6281,8 @@
final String[] instructionSets = new String[] {
getPrimaryInstructionSet(pkg.applicationInfo) };
final int res = mPackageDexOptimizer.performDexOpt(pkg, instructionSets,
- true /*forceDex*/, false /* defer */, true /* inclDependencies */);
+ true /*forceDex*/, false /* defer */, true /* inclDependencies */,
+ true /* boot complete */);
if (res != PackageDexOptimizer.DEX_OPT_PERFORMED) {
throw new IllegalStateException("Failed to dexopt: " + res);
}
@@ -7091,12 +7074,13 @@
// we can avoid redundant dexopts, and also to make sure we've got the
// code and package path correct.
adjustCpuAbisForSharedUserLPw(pkgSetting.sharedUser.packages,
- pkg, forceDex, (scanFlags & SCAN_DEFER_DEX) != 0);
+ pkg, forceDex, (scanFlags & SCAN_DEFER_DEX) != 0, true /* boot complete */);
}
if ((scanFlags & SCAN_NO_DEX) == 0) {
int result = mPackageDexOptimizer.performDexOpt(pkg, null /* instruction sets */,
- forceDex, (scanFlags & SCAN_DEFER_DEX) != 0, false /* inclDependencies */);
+ forceDex, (scanFlags & SCAN_DEFER_DEX) != 0, false /* inclDependencies */,
+ (scanFlags & SCAN_BOOTING) == 0);
if (result == PackageDexOptimizer.DEX_OPT_FAILED) {
throw new PackageManagerException(INSTALL_FAILED_DEXOPT, "scanPackageLI");
}
@@ -7172,7 +7156,8 @@
PackageParser.Package clientPkg = clientLibPkgs.get(i);
int result = mPackageDexOptimizer.performDexOpt(clientPkg,
null /* instruction sets */, forceDex,
- (scanFlags & SCAN_DEFER_DEX) != 0, false);
+ (scanFlags & SCAN_DEFER_DEX) != 0, false,
+ (scanFlags & SCAN_BOOTING) == 0);
if (result == PackageDexOptimizer.DEX_OPT_FAILED) {
throw new PackageManagerException(INSTALL_FAILED_DEXOPT,
"scanPackageLI failed to dexopt clientLibPkgs");
@@ -7581,8 +7566,8 @@
// We would never need to extract libs for forward-locked and external packages,
// since the container service will do it for us. We shouldn't attempt to
// extract libs from system app when it was not updated.
- if (pkg.isForwardLocked() || isExternal(pkg) ||
- (isSystemApp(pkg) && !pkg.isUpdatedSystemApp()) ) {
+ if (pkg.isForwardLocked() || pkg.applicationInfo.isExternalAsec() ||
+ (isSystemApp(pkg) && !pkg.isUpdatedSystemApp())) {
extractLibs = false;
}
@@ -7713,7 +7698,8 @@
* adds unnecessary complexity.
*/
private void adjustCpuAbisForSharedUserLPw(Set<PackageSetting> packagesForUser,
- PackageParser.Package scannedPackage, boolean forceDexOpt, boolean deferDexOpt) {
+ PackageParser.Package scannedPackage, boolean forceDexOpt, boolean deferDexOpt,
+ boolean bootComplete) {
String requiredInstructionSet = null;
if (scannedPackage != null && scannedPackage.applicationInfo.primaryCpuAbi != null) {
requiredInstructionSet = VMRuntime.getInstructionSet(
@@ -7777,7 +7763,8 @@
Slog.i(TAG, "Adjusting ABI for : " + ps.name + " to " + adjustedAbi);
int result = mPackageDexOptimizer.performDexOpt(ps.pkg,
- null /* instruction sets */, forceDexOpt, deferDexOpt, true);
+ null /* instruction sets */, forceDexOpt, deferDexOpt, true,
+ bootComplete);
if (result == PackageDexOptimizer.DEX_OPT_FAILED) {
ps.primaryCpuAbiString = null;
ps.pkg.applicationInfo.primaryCpuAbi = null;
@@ -7857,7 +7844,7 @@
final String codePath = pkg.codePath;
final File codeFile = new File(codePath);
final boolean bundledApp = info.isSystemApp() && !info.isUpdatedSystemApp();
- final boolean asecApp = info.isForwardLocked() || isExternal(info);
+ final boolean asecApp = info.isForwardLocked() || info.isExternalAsec();
info.nativeLibraryRootDir = null;
info.nativeLibraryRootRequiresIsa = false;
@@ -8255,8 +8242,14 @@
static final int UPDATE_PERMISSIONS_REPLACE_PKG = 1<<1;
static final int UPDATE_PERMISSIONS_REPLACE_ALL = 1<<2;
+ private void updatePermissionsLPw(String changingPkg, PackageParser.Package pkgInfo,
+ int flags) {
+ final String volumeUuid = (pkgInfo != null) ? getVolumeUuidForPackage(pkgInfo) : null;
+ updatePermissionsLPw(changingPkg, pkgInfo, volumeUuid, flags);
+ }
+
private void updatePermissionsLPw(String changingPkg,
- PackageParser.Package pkgInfo, int flags) {
+ PackageParser.Package pkgInfo, String replaceVolumeUuid, int flags) {
// Make sure there are no dangling permission trees.
Iterator<BasePermission> it = mSettings.mPermissionTrees.values().iterator();
while (it.hasNext()) {
@@ -8325,14 +8318,21 @@
if ((flags&UPDATE_PERMISSIONS_ALL) != 0) {
for (PackageParser.Package pkg : mPackages.values()) {
if (pkg != pkgInfo) {
- grantPermissionsLPw(pkg, (flags&UPDATE_PERMISSIONS_REPLACE_ALL) != 0,
- changingPkg);
+ // Only replace for packages on requested volume
+ final String volumeUuid = getVolumeUuidForPackage(pkg);
+ final boolean replace = ((flags & UPDATE_PERMISSIONS_REPLACE_ALL) != 0)
+ && Objects.equals(replaceVolumeUuid, volumeUuid);
+ grantPermissionsLPw(pkg, replace, changingPkg);
}
}
}
if (pkgInfo != null) {
- grantPermissionsLPw(pkgInfo, (flags&UPDATE_PERMISSIONS_REPLACE_PKG) != 0, changingPkg);
+ // Only replace for packages on requested volume
+ final String volumeUuid = getVolumeUuidForPackage(pkgInfo);
+ final boolean replace = ((flags & UPDATE_PERMISSIONS_REPLACE_PKG) != 0)
+ && Objects.equals(replaceVolumeUuid, volumeUuid);
+ grantPermissionsLPw(pkgInfo, replace, changingPkg);
}
}
@@ -8359,6 +8359,7 @@
final int[] currentUserIds = UserManagerService.getInstance().getUserIds();
+ boolean runtimePermissionsRevoked = false;
int[] changedRuntimePermissionUserIds = EMPTY_INT_ARRAY;
boolean changedInstallPermission = false;
@@ -8368,6 +8369,17 @@
if (!ps.isSharedUser()) {
origPermissions = new PermissionsState(permissionsState);
permissionsState.reset();
+ } else {
+ // We need to know only about runtime permission changes since the
+ // calling code always writes the install permissions state but
+ // the runtime ones are written only if changed. The only cases of
+ // changed runtime permissions here are promotion of an install to
+ // runtime and revocation of a runtime from a shared user.
+ changedRuntimePermissionUserIds = revokeUnusedSharedUserPermissionsLPw(
+ ps.sharedUser, UserManagerService.getInstance().getUserIds());
+ if (!ArrayUtils.isEmpty(changedRuntimePermissionUserIds)) {
+ runtimePermissionsRevoked = true;
+ }
}
}
@@ -8583,9 +8595,11 @@
ps.installPermissionsFixed = true;
}
- // Persist the runtime permissions state for users with changes.
+ // Persist the runtime permissions state for users with changes. If permissions
+ // were revoked because no app in the shared user declares them we have to
+ // write synchronously to avoid losing runtime permissions state.
for (int userId : changedRuntimePermissionUserIds) {
- mSettings.writeRuntimePermissionsForUserLPr(userId, false);
+ mSettings.writeRuntimePermissionsForUserLPr(userId, runtimePermissionsRevoked);
}
}
@@ -12319,6 +12333,66 @@
}
}
+ private int[] revokeUnusedSharedUserPermissionsLPw(SharedUserSetting su, int[] allUserIds) {
+ // Collect all used permissions in the UID
+ ArraySet<String> usedPermissions = new ArraySet<>();
+ final int packageCount = su.packages.size();
+ for (int i = 0; i < packageCount; i++) {
+ PackageSetting ps = su.packages.valueAt(i);
+ if (ps.pkg == null) {
+ continue;
+ }
+ final int requestedPermCount = ps.pkg.requestedPermissions.size();
+ for (int j = 0; j < requestedPermCount; j++) {
+ String permission = ps.pkg.requestedPermissions.get(j);
+ BasePermission bp = mSettings.mPermissions.get(permission);
+ if (bp != null) {
+ usedPermissions.add(permission);
+ }
+ }
+ }
+
+ PermissionsState permissionsState = su.getPermissionsState();
+ // Prune install permissions
+ List<PermissionState> installPermStates = permissionsState.getInstallPermissionStates();
+ final int installPermCount = installPermStates.size();
+ for (int i = installPermCount - 1; i >= 0; i--) {
+ PermissionState permissionState = installPermStates.get(i);
+ if (!usedPermissions.contains(permissionState.getName())) {
+ BasePermission bp = mSettings.mPermissions.get(permissionState.getName());
+ if (bp != null) {
+ permissionsState.revokeInstallPermission(bp);
+ permissionsState.updatePermissionFlags(bp, UserHandle.USER_ALL,
+ PackageManager.MASK_PERMISSION_FLAGS, 0);
+ }
+ }
+ }
+
+ int[] runtimePermissionChangedUserIds = EmptyArray.INT;
+
+ // Prune runtime permissions
+ for (int userId : allUserIds) {
+ List<PermissionState> runtimePermStates = permissionsState
+ .getRuntimePermissionStates(userId);
+ final int runtimePermCount = runtimePermStates.size();
+ for (int i = runtimePermCount - 1; i >= 0; i--) {
+ PermissionState permissionState = runtimePermStates.get(i);
+ if (!usedPermissions.contains(permissionState.getName())) {
+ BasePermission bp = mSettings.mPermissions.get(permissionState.getName());
+ if (bp != null) {
+ permissionsState.revokeRuntimePermission(bp, userId);
+ permissionsState.updatePermissionFlags(bp, userId,
+ PackageManager.MASK_PERMISSION_FLAGS, 0);
+ runtimePermissionChangedUserIds = ArrayUtils.appendInt(
+ runtimePermissionChangedUserIds, userId);
+ }
+ }
+ }
+ }
+
+ return runtimePermissionChangedUserIds;
+ }
+
private void updateSettingsLI(PackageParser.Package newPackage, String installerPackageName,
String volumeUuid, int[] allUsers, boolean[] perUserInstalled, PackageInstalledInfo res,
UserHandle user) {
@@ -12614,7 +12688,8 @@
// Run dexopt before old package gets removed, to minimize time when app is unavailable
int result = mPackageDexOptimizer
.performDexOpt(pkg, null /* instruction sets */, false /* forceDex */,
- false /* defer */, false /* inclDependencies */);
+ false /* defer */, false /* inclDependencies */,
+ true /* boot complete */);
if (result == PackageDexOptimizer.DEX_OPT_FAILED) {
res.setError(INSTALL_FAILED_DEXOPT, "Dexopt failed for " + pkg.codePath);
return;
@@ -12815,6 +12890,18 @@
return installFlags;
}
+ private String getVolumeUuidForPackage(PackageParser.Package pkg) {
+ if (isExternal(pkg)) {
+ if (TextUtils.isEmpty(pkg.volumeUuid)) {
+ return StorageManager.UUID_PRIMARY_PHYSICAL;
+ } else {
+ return pkg.volumeUuid;
+ }
+ } else {
+ return StorageManager.UUID_PRIVATE_INTERNAL;
+ }
+ }
+
private VersionInfo getSettingsVersionForPackage(PackageParser.Package pkg) {
if (isExternal(pkg)) {
if (TextUtils.isEmpty(pkg.volumeUuid)) {
@@ -13837,7 +13924,7 @@
if (ps != null) {
libDirRoot = ps.legacyNativeLibraryPathString;
}
- if (p != null && (isExternal(p) || p.isForwardLocked())) {
+ if (p != null && (p.isForwardLocked() || p.applicationInfo.isExternalAsec())) {
final long token = Binder.clearCallingIdentity();
try {
String secureContainerId = cidFromCodePath(p.applicationInfo.getBaseCodePath());
@@ -13866,7 +13953,21 @@
// TODO(multiArch): Extend getSizeInfo to look at *all* instruction sets, not
// just the primary.
String[] dexCodeInstructionSets = getDexCodeInstructionSets(getAppDexInstructionSets(ps));
- int res = mInstaller.getSizeInfo(p.volumeUuid, packageName, userHandle, p.baseCodePath,
+
+ String apkPath;
+ File packageDir = new File(p.codePath);
+
+ if (packageDir.isDirectory() && p.canHaveOatDir()) {
+ apkPath = packageDir.getAbsolutePath();
+ // If libDirRoot is inside a package dir, set it to null to avoid it being counted twice
+ if (libDirRoot != null && libDirRoot.startsWith(apkPath)) {
+ libDirRoot = null;
+ }
+ } else {
+ apkPath = p.baseCodePath;
+ }
+
+ int res = mInstaller.getSizeInfo(p.volumeUuid, packageName, userHandle, apkPath,
libDirRoot, publicSrcDir, asecPath, dexCodeInstructionSets, pStats);
if (res < 0) {
return false;
@@ -15677,7 +15778,7 @@
if (isMounted) {
if (DEBUG_SD_INSTALL)
Log.i(TAG, "Loading packages");
- loadMediaPackages(processCids, uidArr);
+ loadMediaPackages(processCids, uidArr, externalStorage);
startCleaningPackages();
mInstallerService.onSecureContainersAvailable();
} else {
@@ -15732,7 +15833,8 @@
* the cid is added to list of removeCids. We currently don't delete stale
* containers.
*/
- private void loadMediaPackages(ArrayMap<AsecInstallArgs, String> processCids, int[] uidArr) {
+ private void loadMediaPackages(ArrayMap<AsecInstallArgs, String> processCids, int[] uidArr,
+ boolean externalStorage) {
ArrayList<String> pkgList = new ArrayList<String>();
Set<AsecInstallArgs> keys = processCids.keySet();
@@ -15804,7 +15906,10 @@
// cases get permissions that the user didn't initially explicitly
// allow... it would be nice to have some better way to handle
// this situation.
- final VersionInfo ver = mSettings.getExternalVersion();
+ final VersionInfo ver = externalStorage ? mSettings.getExternalVersion()
+ : mSettings.getInternalVersion();
+ final String volumeUuid = externalStorage ? StorageManager.UUID_PRIMARY_PHYSICAL
+ : StorageManager.UUID_PRIVATE_INTERNAL;
int updateFlags = UPDATE_PERMISSIONS_ALL;
if (ver.sdkVersion != mSdkVersion) {
@@ -15812,7 +15917,7 @@
+ mSdkVersion + "; regranting permissions for external");
updateFlags |= UPDATE_PERMISSIONS_REPLACE_PKG | UPDATE_PERMISSIONS_REPLACE_ALL;
}
- updatePermissionsLPw(null, null, updateFlags);
+ updatePermissionsLPw(null, null, volumeUuid, updateFlags);
// Yay, everything is now upgraded
ver.forceCurrent();
@@ -15945,7 +16050,7 @@
+ mSdkVersion + "; regranting permissions for " + vol.fsUuid);
updateFlags |= UPDATE_PERMISSIONS_REPLACE_PKG | UPDATE_PERMISSIONS_REPLACE_ALL;
}
- updatePermissionsLPw(null, null, updateFlags);
+ updatePermissionsLPw(null, null, vol.fsUuid, updateFlags);
// Yay, everything is now upgraded
ver.forceCurrent();
@@ -16041,7 +16146,7 @@
if (userDir.exists()) continue;
try {
- UserManagerService.prepareUserDirectory(userDir);
+ UserManagerService.prepareUserDirectory(mContext, volumeUuid, user.id);
UserManagerService.enforceSerialNumber(userDir, user.serialNumber);
} catch (IOException e) {
Log.wtf(TAG, "Failed to create user directory on " + volumeUuid, e);
@@ -16119,13 +16224,18 @@
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MOVE_PACKAGE, null);
final int moveId = mNextMoveId.getAndIncrement();
- try {
- movePackageInternal(packageName, volumeUuid, moveId);
- } catch (PackageManagerException e) {
- Slog.w(TAG, "Failed to move " + packageName, e);
- mMoveCallbacks.notifyStatusChanged(moveId,
- PackageManager.MOVE_FAILED_INTERNAL_ERROR);
- }
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ try {
+ movePackageInternal(packageName, volumeUuid, moveId);
+ } catch (PackageManagerException e) {
+ Slog.w(TAG, "Failed to move " + packageName, e);
+ mMoveCallbacks.notifyStatusChanged(moveId,
+ PackageManager.MOVE_FAILED_INTERNAL_ERROR);
+ }
+ }
+ });
return moveId;
}
diff --git a/services/core/java/com/android/server/pm/PackageSettingBase.java b/services/core/java/com/android/server/pm/PackageSettingBase.java
index bbdfe31..78328f5 100644
--- a/services/core/java/com/android/server/pm/PackageSettingBase.java
+++ b/services/core/java/com/android/server/pm/PackageSettingBase.java
@@ -239,6 +239,7 @@
keySetData = base.keySetData;
verificationInfo = base.verificationInfo;
installerPackageName = base.installerPackageName;
+ volumeUuid = base.volumeUuid;
}
private PackageUserState modifyUserState(int userId) {
diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java
index a762014..647c17b 100644
--- a/services/core/java/com/android/server/pm/Settings.java
+++ b/services/core/java/com/android/server/pm/Settings.java
@@ -38,10 +38,13 @@
import android.os.Build;
import android.os.Environment;
import android.os.FileUtils;
+import android.os.IBinder;
import android.os.Handler;
import android.os.Message;
import android.os.PatternMatcher;
import android.os.Process;
+import android.os.RemoteException;
+import android.os.ServiceManager;
import android.os.SystemClock;
import android.os.UserHandle;
import android.os.UserManager;
@@ -514,7 +517,18 @@
ArrayList<String> removeStage = new ArrayList<String>();
for (Map.Entry<String,SharedUserSetting> entry : mSharedUsers.entrySet()) {
final SharedUserSetting sus = entry.getValue();
- if (sus == null || sus.packages.size() == 0) {
+ if (sus == null) {
+ removeStage.add(entry.getKey());
+ continue;
+ }
+ // remove packages that are no longer installed
+ for (Iterator<PackageSetting> iter = sus.packages.iterator(); iter.hasNext();) {
+ PackageSetting ps = iter.next();
+ if (mPackages.get(ps.name) == null) {
+ iter.remove();
+ }
+ }
+ if (sus.packages.size() == 0) {
removeStage.add(entry.getKey());
}
}
diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java
index dbb2005..583d764 100644
--- a/services/core/java/com/android/server/pm/UserManagerService.java
+++ b/services/core/java/com/android/server/pm/UserManagerService.java
@@ -1367,7 +1367,7 @@
try {
final File userDir = Environment.getDataUserDirectory(volumeUuid,
userId);
- prepareUserDirectory(userDir);
+ prepareUserDirectory(mContext, volumeUuid, userId);
enforceSerialNumber(userDir, userInfo.serialNumber);
} catch (IOException e) {
Log.wtf(LOG_TAG, "Failed to create user directory on " + volumeUuid, e);
@@ -1575,6 +1575,8 @@
}
private void removeUserStateLocked(final int userHandle) {
+ mContext.getSystemService(StorageManager.class)
+ .deleteUserKey(userHandle);
// Cleanup package manager settings
mPm.cleanUpUserLILPw(this, userHandle);
@@ -1981,16 +1983,10 @@
* Create new {@code /data/user/[id]} directory and sets default
* permissions.
*/
- public static void prepareUserDirectory(File file) throws IOException {
- if (!file.exists()) {
- if (!file.mkdir()) {
- throw new IOException("Failed to create " + file);
- }
- }
- if (FileUtils.setPermissions(file.getAbsolutePath(), 0771, Process.SYSTEM_UID,
- Process.SYSTEM_UID) != 0) {
- throw new IOException("Failed to prepare " + file);
- }
+ public static void prepareUserDirectory(Context context, String volumeUuid, int userId) {
+ final StorageManager storage = context.getSystemService(StorageManager.class);
+ final File userDir = Environment.getDataUserDirectory(volumeUuid, userId);
+ storage.createNewUserDir(userId, userDir);
}
/**
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index 7a84698..0d96ca6 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -65,6 +65,7 @@
import android.os.Message;
import android.os.Messenger;
import android.os.PowerManager;
+import android.os.PowerManagerInternal;
import android.os.Process;
import android.os.RemoteException;
import android.os.ServiceManager;
@@ -117,6 +118,7 @@
import com.android.internal.statusbar.IStatusBarService;
import com.android.internal.util.ScreenShapeHelper;
import com.android.internal.widget.PointerLocationView;
+import com.android.server.GestureLauncherService;
import com.android.server.LocalServices;
import com.android.server.policy.keyguard.KeyguardServiceDelegate;
import com.android.server.policy.keyguard.KeyguardServiceDelegate.DrawnListener;
@@ -125,7 +127,6 @@
import java.io.FileReader;
import java.io.IOException;
import java.io.PrintWriter;
-import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
@@ -267,6 +268,7 @@
PowerManager mPowerManager;
ActivityManagerInternal mActivityManagerInternal;
DreamManagerInternal mDreamManagerInternal;
+ PowerManagerInternal mPowerManagerInternal;
IStatusBarService mStatusBarService;
boolean mPreloadedRecentApps;
final Object mServiceAquireLock = new Object();
@@ -762,6 +764,15 @@
}
class MyOrientationListener extends WindowOrientationListener {
+ private final Runnable mUpdateRotationRunnable = new Runnable() {
+ @Override
+ public void run() {
+ // send interaction hint to improve redraw performance
+ mPowerManagerInternal.powerHint(PowerManagerInternal.POWER_HINT_INTERACTION, 0);
+ updateRotation(false);
+ }
+ };
+
MyOrientationListener(Context context, Handler handler) {
super(context, handler);
}
@@ -769,7 +780,7 @@
@Override
public void onProposedRotationChanged(int rotation) {
if (localLOGV) Slog.v(TAG, "onProposedRotationChanged, rotation=" + rotation);
- updateRotation(false);
+ mHandler.post(mUpdateRotationRunnable);
}
}
MyOrientationListener mOrientationListener;
@@ -924,10 +935,17 @@
}
}
+ GestureLauncherService gestureService = LocalServices.getService(
+ GestureLauncherService.class);
+ boolean gesturedServiceIntercepted = false;
+ if (gestureService != null) {
+ gesturedServiceIntercepted = gestureService.interceptPowerKeyDown(event, interactive);
+ }
+
// If the power key has still not yet been handled, then detect short
// press, long press, or multi press and decide what to do.
mPowerKeyHandled = hungUp || mScreenshotChordVolumeDownKeyTriggered
- || mScreenshotChordVolumeUpKeyTriggered;
+ || mScreenshotChordVolumeUpKeyTriggered || gesturedServiceIntercepted;
if (!mPowerKeyHandled) {
if (interactive) {
// When interactive, we're already awake.
@@ -1316,6 +1334,7 @@
mWindowManagerInternal = LocalServices.getService(WindowManagerInternal.class);
mActivityManagerInternal = LocalServices.getService(ActivityManagerInternal.class);
mDreamManagerInternal = LocalServices.getService(DreamManagerInternal.class);
+ mPowerManagerInternal = LocalServices.getService(PowerManagerInternal.class);
mAppOpsManager = (AppOpsManager) mContext.getSystemService(Context.APP_OPS_SERVICE);
// Init display burn-in protection
@@ -1492,6 +1511,13 @@
}
}
@Override
+ public void onFling(int duration) {
+ if (mPowerManagerInternal != null) {
+ mPowerManagerInternal.powerHint(
+ PowerManagerInternal.POWER_HINT_INTERACTION, duration);
+ }
+ }
+ @Override
public void onDebug() {
// no-op
}
@@ -4364,6 +4390,7 @@
if (attrs.type == TYPE_STATUS_BAR) {
if ((attrs.privateFlags & PRIVATE_FLAG_KEYGUARD) != 0) {
mForceStatusBarFromKeyguard = true;
+ mShowingLockscreen = true;
}
if ((attrs.privateFlags & PRIVATE_FLAG_FORCE_STATUS_BAR_VISIBLE_TRANSPARENT) != 0) {
mForceStatusBarTransparent = true;
@@ -4384,9 +4411,6 @@
mForceStatusBar = true;
}
}
- if ((attrs.privateFlags & PRIVATE_FLAG_KEYGUARD) != 0) {
- mShowingLockscreen = true;
- }
if (attrs.type == TYPE_DREAM) {
// If the lockscreen was showing when the dream started then wait
// for the dream to draw before hiding the lockscreen.
@@ -4410,7 +4434,7 @@
if (mAppsToBeHidden.isEmpty()) {
if (dismissKeyguard && !mKeyguardSecure) {
mAppsThatDismissKeyguard.add(appToken);
- } else {
+ } else if (win.isDrawnLw() || win.hasAppShownWindows()) {
mWinShowWhenLocked = win;
mHideLockScreen = true;
mForceStatusBarFromKeyguard = false;
@@ -4444,7 +4468,8 @@
mWinDismissingKeyguard = win;
mSecureDismissingKeyguard = mKeyguardSecure;
mForceStatusBarFromKeyguard = mShowingLockscreen && mKeyguardSecure;
- } else if (mAppsToBeHidden.isEmpty() && showWhenLocked) {
+ } else if (mAppsToBeHidden.isEmpty() && showWhenLocked
+ && (win.isDrawnLw() || win.hasAppShownWindows())) {
if (DEBUG_LAYOUT) Slog.v(TAG,
"Setting mHideLockScreen to true by win " + win);
mHideLockScreen = true;
@@ -6059,6 +6084,7 @@
mKeyguardDelegate.bindService(mContext);
mKeyguardDelegate.onBootCompleted();
}
+ mSystemGestures.systemReady();
}
/** {@inheritDoc} */
@@ -6085,6 +6111,7 @@
}
startedWakingUp();
screenTurningOn(null);
+ screenTurnedOn();
}
ProgressDialog mBootMsgDialog = null;
@@ -7001,5 +7028,8 @@
if (mBurnInProtectionHelper != null) {
mBurnInProtectionHelper.dump(prefix, pw);
}
+ if (mKeyguardDelegate != null) {
+ mKeyguardDelegate.dump(prefix, pw);
+ }
}
}
diff --git a/services/core/java/com/android/server/policy/StatusBarController.java b/services/core/java/com/android/server/policy/StatusBarController.java
index d1b50da..b1ae922 100644
--- a/services/core/java/com/android/server/policy/StatusBarController.java
+++ b/services/core/java/com/android/server/policy/StatusBarController.java
@@ -72,7 +72,9 @@
if (statusbar != null) {
long startTime = calculateStatusBarTransitionStartTime(openAnimation,
closeAnimation);
- statusbar.appTransitionStarting(startTime, TRANSITION_DURATION);
+ long duration = closeAnimation != null || openAnimation != null
+ ? TRANSITION_DURATION : 0;
+ statusbar.appTransitionStarting(startTime, duration);
}
} catch (RemoteException e) {
Slog.e(mTag, "RemoteException when app transition is starting", e);
diff --git a/services/core/java/com/android/server/policy/SystemGesturesPointerEventListener.java b/services/core/java/com/android/server/policy/SystemGesturesPointerEventListener.java
index 627b328..e4bd21d 100644
--- a/services/core/java/com/android/server/policy/SystemGesturesPointerEventListener.java
+++ b/services/core/java/com/android/server/policy/SystemGesturesPointerEventListener.java
@@ -17,9 +17,14 @@
package com.android.server.policy;
import android.content.Context;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.SystemClock;
import android.util.Slog;
+import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.WindowManagerPolicy.PointerEventListener;
+import android.widget.OverScroller;
/*
* Listens for system-wide input gestures, firing callbacks when detected.
@@ -31,12 +36,14 @@
private static final long SWIPE_TIMEOUT_MS = 500;
private static final int MAX_TRACKED_POINTERS = 32; // max per input system
private static final int UNTRACKED_POINTER = -1;
+ private static final int MAX_FLING_TIME_MILLIS = 5000;
private static final int SWIPE_NONE = 0;
private static final int SWIPE_FROM_TOP = 1;
private static final int SWIPE_FROM_BOTTOM = 2;
private static final int SWIPE_FROM_RIGHT = 3;
+ private final Context mContext;
private final int mSwipeStartThreshold;
private final int mSwipeDistanceThreshold;
private final Callbacks mCallbacks;
@@ -45,13 +52,18 @@
private final float[] mDownY = new float[MAX_TRACKED_POINTERS];
private final long[] mDownTime = new long[MAX_TRACKED_POINTERS];
+ private GestureDetector mGestureDetector;
+ private OverScroller mOverscroller;
+
int screenHeight;
int screenWidth;
private int mDownPointers;
private boolean mSwipeFireable;
private boolean mDebugFireable;
+ private long mLastFlingTime;
public SystemGesturesPointerEventListener(Context context, Callbacks callbacks) {
+ mContext = context;
mCallbacks = checkNull("callbacks", callbacks);
mSwipeStartThreshold = checkNull("context", context).getResources()
.getDimensionPixelSize(com.android.internal.R.dimen.status_bar_height);
@@ -67,8 +79,17 @@
return arg;
}
+ public void systemReady() {
+ Handler h = new Handler(Looper.myLooper());
+ mGestureDetector = new GestureDetector(mContext, new FlingGestureDetector(), h);
+ mOverscroller = new OverScroller(mContext);
+ }
+
@Override
public void onPointerEvent(MotionEvent event) {
+ if (mGestureDetector != null) {
+ mGestureDetector.onTouchEvent(event);
+ }
switch (event.getActionMasked()) {
case MotionEvent.ACTION_DOWN:
mSwipeFireable = true;
@@ -190,10 +211,40 @@
return SWIPE_NONE;
}
+ private final class FlingGestureDetector extends GestureDetector.SimpleOnGestureListener {
+ @Override
+ public boolean onSingleTapUp(MotionEvent e) {
+ if (!mOverscroller.isFinished()) {
+ mOverscroller.forceFinished(true);
+ }
+ return true;
+ }
+ @Override
+ public boolean onFling(MotionEvent down, MotionEvent up,
+ float velocityX, float velocityY) {
+ mOverscroller.computeScrollOffset();
+ long now = SystemClock.uptimeMillis();
+
+ if (mLastFlingTime != 0 && now > mLastFlingTime + MAX_FLING_TIME_MILLIS) {
+ mOverscroller.forceFinished(true);
+ }
+ mOverscroller.fling(0, 0, (int)velocityX, (int)velocityY,
+ Integer.MIN_VALUE, Integer.MAX_VALUE, Integer.MIN_VALUE, Integer.MAX_VALUE);
+ int duration = mOverscroller.getDuration();
+ if (duration > MAX_FLING_TIME_MILLIS) {
+ duration = MAX_FLING_TIME_MILLIS;
+ }
+ mLastFlingTime = now;
+ mCallbacks.onFling(duration);
+ return true;
+ }
+ }
+
interface Callbacks {
void onSwipeFromTop();
void onSwipeFromBottom();
void onSwipeFromRight();
+ void onFling(int durationMs);
void onDown();
void onUpOrCancel();
void onDebug();
diff --git a/services/core/java/com/android/server/policy/WindowOrientationListener.java b/services/core/java/com/android/server/policy/WindowOrientationListener.java
index c71b48f..9916223 100644
--- a/services/core/java/com/android/server/policy/WindowOrientationListener.java
+++ b/services/core/java/com/android/server/policy/WindowOrientationListener.java
@@ -24,10 +24,12 @@
import android.os.Handler;
import android.os.SystemClock;
import android.os.SystemProperties;
+import android.text.TextUtils;
import android.util.Slog;
import java.io.PrintWriter;
import java.util.Arrays;
+import java.util.List;
/**
* A special helper class used by the WindowManager
@@ -52,8 +54,9 @@
private SensorManager mSensorManager;
private boolean mEnabled;
private int mRate;
+ private String mSensorType;
private Sensor mSensor;
- private SensorEventListenerImpl mSensorEventListener;
+ private OrientationJudge mOrientationJudge;
private int mCurrentRotation = -1;
private final Object mLock = new Object();
@@ -67,7 +70,7 @@
public WindowOrientationListener(Context context, Handler handler) {
this(context, handler, SensorManager.SENSOR_DELAY_UI);
}
-
+
/**
* Creates a new WindowOrientationListener.
*
@@ -84,11 +87,31 @@
mHandler = handler;
mSensorManager = (SensorManager)context.getSystemService(Context.SENSOR_SERVICE);
mRate = rate;
- mSensor = mSensorManager.getDefaultSensor(USE_GRAVITY_SENSOR
- ? Sensor.TYPE_GRAVITY : Sensor.TYPE_ACCELEROMETER);
- if (mSensor != null) {
- // Create listener only if sensors do exist
- mSensorEventListener = new SensorEventListenerImpl(context);
+
+ mSensorType = context.getResources().getString(
+ com.android.internal.R.string.config_orientationSensorType);
+ if (!TextUtils.isEmpty(mSensorType)) {
+ List<Sensor> sensors = mSensorManager.getSensorList(Sensor.TYPE_ALL);
+ final int N = sensors.size();
+ for (int i = 0; i < N; i++) {
+ Sensor sensor = sensors.get(i);
+ if (mSensorType.equals(sensor.getStringType())) {
+ mSensor = sensor;
+ break;
+ }
+ }
+ if (mSensor != null) {
+ mOrientationJudge = new OrientationSensorJudge();
+ }
+ }
+
+ if (mOrientationJudge == null) {
+ mSensor = mSensorManager.getDefaultSensor(USE_GRAVITY_SENSOR
+ ? Sensor.TYPE_GRAVITY : Sensor.TYPE_ACCELEROMETER);
+ if (mSensor != null) {
+ // Create listener only if sensors do exist
+ mOrientationJudge = new AccelSensorJudge(context);
+ }
}
}
@@ -106,8 +129,8 @@
if (LOG) {
Slog.d(TAG, "WindowOrientationListener enabled");
}
- mSensorEventListener.resetLocked();
- mSensorManager.registerListener(mSensorEventListener, mSensor, mRate, mHandler);
+ mOrientationJudge.resetLocked();
+ mSensorManager.registerListener(mOrientationJudge, mSensor, mRate, mHandler);
mEnabled = true;
}
}
@@ -126,7 +149,7 @@
if (LOG) {
Slog.d(TAG, "WindowOrientationListener disabled");
}
- mSensorManager.unregisterListener(mSensorEventListener);
+ mSensorManager.unregisterListener(mOrientationJudge);
mEnabled = false;
}
}
@@ -134,8 +157,8 @@
public void onTouchStart() {
synchronized (mLock) {
- if (mSensorEventListener != null) {
- mSensorEventListener.onTouchStartLocked();
+ if (mOrientationJudge != null) {
+ mOrientationJudge.onTouchStartLocked();
}
}
}
@@ -144,8 +167,8 @@
long whenElapsedNanos = SystemClock.elapsedRealtimeNanos();
synchronized (mLock) {
- if (mSensorEventListener != null) {
- mSensorEventListener.onTouchEndLocked(whenElapsedNanos);
+ if (mOrientationJudge != null) {
+ mOrientationJudge.onTouchEndLocked(whenElapsedNanos);
}
}
}
@@ -172,7 +195,7 @@
public int getProposedRotation() {
synchronized (mLock) {
if (mEnabled) {
- return mSensorEventListener.getProposedRotationLocked();
+ return mOrientationJudge.getProposedRotationLocked();
}
return -1;
}
@@ -194,6 +217,8 @@
* It is called each time the orientation determination transitions from being
* uncertain to being certain again, even if it is the same orientation as before.
*
+ * This should only be called on the Handler thread.
+ *
* @param rotation The new orientation of the device, one of the Surface.ROTATION_* constants.
* @see android.view.Surface
*/
@@ -205,15 +230,77 @@
prefix += " ";
pw.println(prefix + "mEnabled=" + mEnabled);
pw.println(prefix + "mCurrentRotation=" + mCurrentRotation);
+ pw.println(prefix + "mSensorType=" + mSensorType);
pw.println(prefix + "mSensor=" + mSensor);
pw.println(prefix + "mRate=" + mRate);
- if (mSensorEventListener != null) {
- mSensorEventListener.dumpLocked(pw, prefix);
+ if (mOrientationJudge != null) {
+ mOrientationJudge.dumpLocked(pw, prefix);
}
}
}
+ abstract class OrientationJudge implements SensorEventListener {
+ // Number of nanoseconds per millisecond.
+ protected static final long NANOS_PER_MS = 1000000;
+
+ // Number of milliseconds per nano second.
+ protected static final float MILLIS_PER_NANO = 0.000001f;
+
+ // The minimum amount of time that must have elapsed since the screen was last touched
+ // before the proposed rotation can change.
+ protected static final long PROPOSAL_MIN_TIME_SINCE_TOUCH_END_NANOS =
+ 500 * NANOS_PER_MS;
+
+ /**
+ * Gets the proposed rotation.
+ *
+ * This method only returns a rotation if the orientation listener is certain
+ * of its proposal. If the rotation is indeterminate, returns -1.
+ *
+ * Should only be called when holding WindowOrientationListener lock.
+ *
+ * @return The proposed rotation, or -1 if unknown.
+ */
+ public abstract int getProposedRotationLocked();
+
+ /**
+ * Notifies the orientation judge that the screen is being touched.
+ *
+ * Should only be called when holding WindowOrientationListener lock.
+ */
+ public abstract void onTouchStartLocked();
+
+ /**
+ * Notifies the orientation judge that the screen is no longer being touched.
+ *
+ * Should only be called when holding WindowOrientationListener lock.
+ *
+ * @param whenElapsedNanos Given in the elapsed realtime nanos time base.
+ */
+ public abstract void onTouchEndLocked(long whenElapsedNanos);
+
+ /**
+ * Resets the state of the judge.
+ *
+ * Should only be called when holding WindowOrientationListener lock.
+ */
+ public abstract void resetLocked();
+
+ /**
+ * Dumps internal state of the orientation judge.
+ *
+ * Should only be called when holding WindowOrientationListener lock.
+ */
+ public abstract void dumpLocked(PrintWriter pw, String prefix);
+
+ @Override
+ public abstract void onAccuracyChanged(Sensor sensor, int accuracy);
+
+ @Override
+ public abstract void onSensorChanged(SensorEvent event);
+ }
+
/**
* This class filters the raw accelerometer data and tries to detect actual changes in
* orientation. This is a very ill-defined problem so there are a lot of tweakable parameters,
@@ -252,13 +339,10 @@
* See http://en.wikipedia.org/wiki/Low-pass_filter#Discrete-time_realization for
* signal processing background.
*/
- final class SensorEventListenerImpl implements SensorEventListener {
+ final class AccelSensorJudge extends OrientationJudge {
// We work with all angles in degrees in this class.
private static final float RADIANS_TO_DEGREES = (float) (180 / Math.PI);
- // Number of nanoseconds per millisecond.
- private static final long NANOS_PER_MS = 1000000;
-
// Indices into SensorEvent.values for the accelerometer sensor.
private static final int ACCELEROMETER_DATA_X = 0;
private static final int ACCELEROMETER_DATA_Y = 1;
@@ -286,11 +370,6 @@
private static final long PROPOSAL_MIN_TIME_SINCE_ACCELERATION_ENDED_NANOS =
500 * NANOS_PER_MS;
- // The minimum amount of time that must have elapsed since the screen was last touched
- // before the proposed rotation can change.
- private static final long PROPOSAL_MIN_TIME_SINCE_TOUCH_END_NANOS =
- 500 * NANOS_PER_MS;
-
// If the tilt angle remains greater than the specified angle for a minimum of
// the specified time, then the device is deemed to be lying flat
// (just chillin' on a table).
@@ -434,7 +513,7 @@
private long[] mTiltHistoryTimestampNanos = new long[TILT_HISTORY_SIZE];
private int mTiltHistoryIndex;
- public SensorEventListenerImpl(Context context) {
+ public AccelSensorJudge(Context context) {
// Load tilt tolerance configuration.
int[] tiltTolerance = context.getResources().getIntArray(
com.android.internal.R.array.config_autoRotationTiltTolerance);
@@ -455,11 +534,15 @@
}
}
+ @Override
public int getProposedRotationLocked() {
return mProposedRotation;
}
+ @Override
public void dumpLocked(PrintWriter pw, String prefix) {
+ pw.println(prefix + "AccelSensorJudge");
+ prefix += " ";
pw.println(prefix + "mProposedRotation=" + mProposedRotation);
pw.println(prefix + "mPredictedRotation=" + mPredictedRotation);
pw.println(prefix + "mLastFilteredX=" + mLastFilteredX);
@@ -689,6 +772,33 @@
}
}
+ @Override
+ public void onTouchStartLocked() {
+ mTouched = true;
+ }
+
+ @Override
+ public void onTouchEndLocked(long whenElapsedNanos) {
+ mTouched = false;
+ mTouchEndedTimestampNanos = whenElapsedNanos;
+ }
+
+ @Override
+ public void resetLocked() {
+ mLastFilteredTimestampNanos = Long.MIN_VALUE;
+ mProposedRotation = -1;
+ mFlatTimestampNanos = Long.MIN_VALUE;
+ mFlat = false;
+ mSwingTimestampNanos = Long.MIN_VALUE;
+ mSwinging = false;
+ mAccelerationTimestampNanos = Long.MIN_VALUE;
+ mAccelerating = false;
+ mOverhead = false;
+ clearPredictedRotationLocked();
+ clearTiltHistoryLocked();
+ }
+
+
/**
* Returns true if the tilt angle is acceptable for a given predicted rotation.
*/
@@ -787,20 +897,6 @@
return true;
}
- private void resetLocked() {
- mLastFilteredTimestampNanos = Long.MIN_VALUE;
- mProposedRotation = -1;
- mFlatTimestampNanos = Long.MIN_VALUE;
- mFlat = false;
- mSwingTimestampNanos = Long.MIN_VALUE;
- mSwinging = false;
- mAccelerationTimestampNanos = Long.MIN_VALUE;
- mAccelerating = false;
- mOverhead = false;
- clearPredictedRotationLocked();
- clearTiltHistoryLocked();
- }
-
private void clearPredictedRotationLocked() {
mPredictedRotation = -1;
mPredictedRotationTimestampNanos = Long.MIN_VALUE;
@@ -869,14 +965,147 @@
private float remainingMS(long now, long until) {
return now >= until ? 0 : (until - now) * 0.000001f;
}
+ }
- private void onTouchStartLocked() {
- mTouched = true;
+ final class OrientationSensorJudge extends OrientationJudge {
+ private boolean mTouching;
+ private long mTouchEndedTimestampNanos = Long.MIN_VALUE;
+ private int mProposedRotation = -1;
+ private int mDesiredRotation = -1;
+ private boolean mRotationEvaluationScheduled;
+
+ @Override
+ public int getProposedRotationLocked() {
+ return mProposedRotation;
}
- private void onTouchEndLocked(long whenElapsedNanos) {
- mTouched = false;
+ @Override
+ public void onTouchStartLocked() {
+ mTouching = true;
+ }
+
+ @Override
+ public void onTouchEndLocked(long whenElapsedNanos) {
+ mTouching = false;
mTouchEndedTimestampNanos = whenElapsedNanos;
+ if (mDesiredRotation != mProposedRotation) {
+ final long now = SystemClock.elapsedRealtimeNanos();
+ scheduleRotationEvaluationIfNecessaryLocked(now);
+ }
}
+
+
+ @Override
+ public void onSensorChanged(SensorEvent event) {
+ int newRotation;
+ synchronized (mLock) {
+ mDesiredRotation = (int) event.values[0];
+ newRotation = evaluateRotationChangeLocked();
+ }
+ if (newRotation >=0) {
+ onProposedRotationChanged(newRotation);
+ }
+ }
+
+ @Override
+ public void onAccuracyChanged(Sensor sensor, int accuracy) { }
+
+ @Override
+ public void dumpLocked(PrintWriter pw, String prefix) {
+ pw.println(prefix + "OrientationSensorJudge");
+ prefix += " ";
+ pw.println(prefix + "mDesiredRotation=" + mDesiredRotation);
+ pw.println(prefix + "mProposedRotation=" + mProposedRotation);
+ pw.println(prefix + "mTouching=" + mTouching);
+ pw.println(prefix + "mTouchEndedTimestampNanos=" + mTouchEndedTimestampNanos);
+ }
+
+ @Override
+ public void resetLocked() {
+ mProposedRotation = -1;
+ mDesiredRotation = -1;
+ mTouching = false;
+ mTouchEndedTimestampNanos = Long.MIN_VALUE;
+ unscheduleRotationEvaluationLocked();
+ }
+
+ public int evaluateRotationChangeLocked() {
+ unscheduleRotationEvaluationLocked();
+ if (mDesiredRotation == mProposedRotation) {
+ return -1;
+ }
+ final long now = SystemClock.elapsedRealtimeNanos();
+ if (isDesiredRotationAcceptableLocked(now)) {
+ mProposedRotation = mDesiredRotation;
+ return mProposedRotation;
+ } else {
+ scheduleRotationEvaluationIfNecessaryLocked(now);
+ }
+ return -1;
+ }
+
+ private boolean isDesiredRotationAcceptableLocked(long now) {
+ if (mTouching) {
+ return false;
+ }
+ if (now < mTouchEndedTimestampNanos + PROPOSAL_MIN_TIME_SINCE_TOUCH_END_NANOS) {
+ return false;
+ }
+ return true;
+ }
+
+ private void scheduleRotationEvaluationIfNecessaryLocked(long now) {
+ if (mRotationEvaluationScheduled || mDesiredRotation == mProposedRotation) {
+ if (LOG) {
+ Slog.d(TAG, "scheduleRotationEvaluationLocked: " +
+ "ignoring, an evaluation is already scheduled or is unnecessary.");
+ }
+ return;
+ }
+ if (mTouching) {
+ if (LOG) {
+ Slog.d(TAG, "scheduleRotationEvaluationLocked: " +
+ "ignoring, user is still touching the screen.");
+ }
+ return;
+ }
+ long timeOfNextPossibleRotationNanos =
+ mTouchEndedTimestampNanos + PROPOSAL_MIN_TIME_SINCE_TOUCH_END_NANOS;
+ if (now >= timeOfNextPossibleRotationNanos) {
+ if (LOG) {
+ Slog.d(TAG, "scheduleRotationEvaluationLocked: " +
+ "ignoring, already past the next possible time of rotation.");
+ }
+ return;
+ }
+ // Use a delay instead of an absolute time since handlers are in uptime millis and we
+ // use elapsed realtime.
+ final long delayMs =
+ (long) Math.ceil((timeOfNextPossibleRotationNanos - now) * MILLIS_PER_NANO);
+ mHandler.postDelayed(mRotationEvaluator, delayMs);
+ mRotationEvaluationScheduled = true;
+ }
+
+ private void unscheduleRotationEvaluationLocked() {
+ if (!mRotationEvaluationScheduled) {
+ return;
+ }
+ mHandler.removeCallbacks(mRotationEvaluator);
+ mRotationEvaluationScheduled = false;
+ }
+
+ private Runnable mRotationEvaluator = new Runnable() {
+ @Override
+ public void run() {
+ int newRotation;
+ synchronized (mLock) {
+ mRotationEvaluationScheduled = false;
+ newRotation = evaluateRotationChangeLocked();
+ }
+ if (newRotation >= 0) {
+ onProposedRotationChanged(newRotation);
+ }
+ }
+ };
}
}
diff --git a/services/core/java/com/android/server/policy/keyguard/KeyguardServiceDelegate.java b/services/core/java/com/android/server/policy/keyguard/KeyguardServiceDelegate.java
index 5d52307..7ae3c79 100644
--- a/services/core/java/com/android/server/policy/keyguard/KeyguardServiceDelegate.java
+++ b/services/core/java/com/android/server/policy/keyguard/KeyguardServiceDelegate.java
@@ -23,6 +23,8 @@
import com.android.internal.policy.IKeyguardExitCallback;
import com.android.internal.policy.IKeyguardService;
+import java.io.PrintWriter;
+
/**
* A local class that keeps a cache of keyguard state that can be restored in the event
* keyguard crashes. It currently also allows runtime-selectable
@@ -32,6 +34,14 @@
private static final String TAG = "KeyguardServiceDelegate";
private static final boolean DEBUG = true;
+ private static final int SCREEN_STATE_OFF = 0;
+ private static final int SCREEN_STATE_TURNING_ON = 1;
+ private static final int SCREEN_STATE_ON = 2;
+
+ private static final int INTERACTIVE_STATE_SLEEP = 0;
+ private static final int INTERACTIVE_STATE_AWAKE = 1;
+ private static final int INTERACTIVE_STATE_GOING_TO_SLEEP = 2;
+
protected KeyguardServiceWrapper mKeyguardService;
private final Context mContext;
private final View mScrim; // shown if keyguard crashes
@@ -61,6 +71,8 @@
public int offReason;
public int currentUser;
public boolean bootCompleted;
+ public int screenState;
+ public int interactiveState;
};
public interface DrawnListener {
@@ -144,10 +156,17 @@
// If the system is ready, it means keyguard crashed and restarted.
mKeyguardService.onSystemReady();
// This is used to hide the scrim once keyguard displays.
- mKeyguardService.onStartedWakingUp();
- mKeyguardService.onScreenTurningOn(
- new KeyguardShowDelegate(mDrawnListenerWhenConnect));
- mKeyguardService.onScreenTurnedOn();
+ if (mKeyguardState.interactiveState == INTERACTIVE_STATE_AWAKE) {
+ mKeyguardService.onStartedWakingUp();
+ }
+ if (mKeyguardState.screenState == SCREEN_STATE_ON
+ || mKeyguardState.screenState == SCREEN_STATE_TURNING_ON) {
+ mKeyguardService.onScreenTurningOn(
+ new KeyguardShowDelegate(mDrawnListenerWhenConnect));
+ }
+ if (mKeyguardState.screenState == SCREEN_STATE_ON) {
+ mKeyguardService.onScreenTurnedOn();
+ }
mDrawnListenerWhenConnect = null;
}
if (mKeyguardState.bootCompleted) {
@@ -231,6 +250,7 @@
if (DEBUG) Log.v(TAG, "onStartedWakingUp()");
mKeyguardService.onStartedWakingUp();
}
+ mKeyguardState.interactiveState = INTERACTIVE_STATE_AWAKE;
}
public void onScreenTurnedOff() {
@@ -238,6 +258,7 @@
if (DEBUG) Log.v(TAG, "onScreenTurnedOff()");
mKeyguardService.onScreenTurnedOff();
}
+ mKeyguardState.screenState = SCREEN_STATE_OFF;
}
public void onScreenTurningOn(final DrawnListener drawnListener) {
@@ -252,6 +273,7 @@
mDrawnListenerWhenConnect = drawnListener;
showScrim();
}
+ mKeyguardState.screenState = SCREEN_STATE_TURNING_ON;
}
public void onScreenTurnedOn() {
@@ -259,6 +281,7 @@
if (DEBUG) Log.v(TAG, "onScreenTurnedOn()");
mKeyguardService.onScreenTurnedOn();
}
+ mKeyguardState.screenState = SCREEN_STATE_ON;
}
public void onStartedGoingToSleep(int why) {
@@ -266,12 +289,14 @@
mKeyguardService.onStartedGoingToSleep(why);
}
mKeyguardState.offReason = why;
+ mKeyguardState.interactiveState = INTERACTIVE_STATE_GOING_TO_SLEEP;
}
public void onFinishedGoingToSleep(int why) {
if (mKeyguardService != null) {
mKeyguardService.onFinishedGoingToSleep(why);
}
+ mKeyguardState.interactiveState = INTERACTIVE_STATE_SLEEP;
}
public void setKeyguardEnabled(boolean enabled) {
@@ -370,4 +395,26 @@
mKeyguardService.onActivityDrawn();
}
}
+
+ public void dump(String prefix, PrintWriter pw) {
+ pw.println(prefix + TAG);
+ prefix += " ";
+ pw.println(prefix + "showing=" + mKeyguardState.showing);
+ pw.println(prefix + "showingAndNotOccluded=" + mKeyguardState.showingAndNotOccluded);
+ pw.println(prefix + "inputRestricted=" + mKeyguardState.inputRestricted);
+ pw.println(prefix + "occluded=" + mKeyguardState.occluded);
+ pw.println(prefix + "secure=" + mKeyguardState.secure);
+ pw.println(prefix + "dreaming=" + mKeyguardState.dreaming);
+ pw.println(prefix + "systemIsReady=" + mKeyguardState.systemIsReady);
+ pw.println(prefix + "deviceHasKeyguard=" + mKeyguardState.deviceHasKeyguard);
+ pw.println(prefix + "enabled=" + mKeyguardState.enabled);
+ pw.println(prefix + "offReason=" + mKeyguardState.offReason);
+ pw.println(prefix + "currentUser=" + mKeyguardState.currentUser);
+ pw.println(prefix + "bootCompleted=" + mKeyguardState.bootCompleted);
+ pw.println(prefix + "screenState=" + mKeyguardState.screenState);
+ pw.println(prefix + "interactiveState=" + mKeyguardState.interactiveState);
+ if (mKeyguardService != null) {
+ mKeyguardService.dump(prefix, pw);
+ }
+ }
}
diff --git a/services/core/java/com/android/server/policy/keyguard/KeyguardServiceWrapper.java b/services/core/java/com/android/server/policy/keyguard/KeyguardServiceWrapper.java
index cd88b66..429b188 100644
--- a/services/core/java/com/android/server/policy/keyguard/KeyguardServiceWrapper.java
+++ b/services/core/java/com/android/server/policy/keyguard/KeyguardServiceWrapper.java
@@ -27,6 +27,8 @@
import com.android.internal.policy.IKeyguardService;
import com.android.internal.policy.IKeyguardStateCallback;
+import java.io.PrintWriter;
+
/**
* A wrapper class for KeyguardService. It implements IKeyguardService to ensure the interface
* remains consistent.
@@ -239,4 +241,8 @@
public boolean isInputRestricted() {
return mKeyguardStateMonitor.isInputRestricted();
}
+
+ public void dump(String prefix, PrintWriter pw) {
+ mKeyguardStateMonitor.dump(prefix, pw);
+ }
}
\ No newline at end of file
diff --git a/services/core/java/com/android/server/policy/keyguard/KeyguardStateMonitor.java b/services/core/java/com/android/server/policy/keyguard/KeyguardStateMonitor.java
index f1f9c50..30cff03 100644
--- a/services/core/java/com/android/server/policy/keyguard/KeyguardStateMonitor.java
+++ b/services/core/java/com/android/server/policy/keyguard/KeyguardStateMonitor.java
@@ -25,6 +25,8 @@
import com.android.internal.policy.IKeyguardStateCallback;
import com.android.internal.widget.LockPatternUtils;
+import java.io.PrintWriter;
+
/**
* Maintains a cached copy of Keyguard's state.
* @hide
@@ -90,4 +92,13 @@
public void onInputRestrictedStateChanged(boolean inputRestricted) {
mInputRestricted = inputRestricted;
}
+
+ public void dump(String prefix, PrintWriter pw) {
+ pw.println(prefix + TAG);
+ prefix += " ";
+ pw.println(prefix + "mIsShowing=" + mIsShowing);
+ pw.println(prefix + "mSimSecure=" + mSimSecure);
+ pw.println(prefix + "mInputRestricted=" + mInputRestricted);
+ pw.println(prefix + "mCurrentUserId=" + mCurrentUserId);
+ }
}
\ No newline at end of file
diff --git a/services/core/java/com/android/server/power/PowerManagerService.java b/services/core/java/com/android/server/power/PowerManagerService.java
index b920f97..f7a8970 100644
--- a/services/core/java/com/android/server/power/PowerManagerService.java
+++ b/services/core/java/com/android/server/power/PowerManagerService.java
@@ -76,6 +76,7 @@
import libcore.util.Objects;
+import static android.os.PowerManagerInternal.POWER_HINT_INTERACTION;
import static android.os.PowerManagerInternal.WAKEFULNESS_ASLEEP;
import static android.os.PowerManagerInternal.WAKEFULNESS_AWAKE;
import static android.os.PowerManagerInternal.WAKEFULNESS_DREAMING;
@@ -150,7 +151,6 @@
private static final int SCREEN_BRIGHTNESS_BOOST_TIMEOUT = 5 * 1000;
// Power hints defined in hardware/libhardware/include/hardware/power.h.
- private static final int POWER_HINT_INTERACTION = 2;
private static final int POWER_HINT_LOW_POWER = 5;
// Power features defined in hardware/libhardware/include/hardware/power.h.
@@ -3534,5 +3534,10 @@
public void uidGone(int uid) {
uidGoneInternal(uid);
}
+
+ @Override
+ public void powerHint(int hintId, int data) {
+ powerHintInternal(hintId, data);
+ }
}
}
diff --git a/services/core/java/com/android/server/statusbar/StatusBarManagerInternal.java b/services/core/java/com/android/server/statusbar/StatusBarManagerInternal.java
index 130815e..25d646d 100644
--- a/services/core/java/com/android/server/statusbar/StatusBarManagerInternal.java
+++ b/services/core/java/com/android/server/statusbar/StatusBarManagerInternal.java
@@ -28,4 +28,5 @@
void showScreenPinningRequest();
void showAssistDisclosure();
void startAssist(Bundle args);
+ void onCameraLaunchGestureDetected(int source);
}
diff --git a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
index 2a817ea..e9ace29 100644
--- a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
+++ b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
@@ -176,6 +176,16 @@
}
}
}
+
+ @Override
+ public void onCameraLaunchGestureDetected(int source) {
+ if (mBar != null) {
+ try {
+ mBar.onCameraLaunchGestureDetected(source);
+ } catch (RemoteException e) {
+ }
+ }
+ }
};
// ================================================================================
diff --git a/services/core/java/com/android/server/trust/TrustManagerService.java b/services/core/java/com/android/server/trust/TrustManagerService.java
index 15da829..6c70fe9 100644
--- a/services/core/java/com/android/server/trust/TrustManagerService.java
+++ b/services/core/java/com/android/server/trust/TrustManagerService.java
@@ -19,6 +19,7 @@
import com.android.internal.annotations.GuardedBy;
import com.android.internal.content.PackageMonitor;
import com.android.internal.widget.LockPatternUtils;
+import com.android.internal.widget.LockPatternUtils.StrongAuthTracker;
import com.android.server.SystemService;
import org.xmlpull.v1.XmlPullParser;
@@ -59,6 +60,7 @@
import android.util.Log;
import android.util.Slog;
import android.util.SparseBooleanArray;
+import android.util.SparseIntArray;
import android.util.Xml;
import android.view.IWindowManager;
import android.view.WindowManagerGlobal;
@@ -96,16 +98,15 @@
private static final int MSG_UNREGISTER_LISTENER = 2;
private static final int MSG_DISPATCH_UNLOCK_ATTEMPT = 3;
private static final int MSG_ENABLED_AGENTS_CHANGED = 4;
- private static final int MSG_REQUIRE_CREDENTIAL_ENTRY = 5;
private static final int MSG_KEYGUARD_SHOWING_CHANGED = 6;
private static final int MSG_START_USER = 7;
private static final int MSG_CLEANUP_USER = 8;
private static final int MSG_SWITCH_USER = 9;
- private final ArraySet<AgentInfo> mActiveAgents = new ArraySet<AgentInfo>();
- private final ArrayList<ITrustListener> mTrustListeners = new ArrayList<ITrustListener>();
+ private final ArraySet<AgentInfo> mActiveAgents = new ArraySet<>();
+ private final ArrayList<ITrustListener> mTrustListeners = new ArrayList<>();
private final Receiver mReceiver = new Receiver();
- private final SparseBooleanArray mUserHasAuthenticated = new SparseBooleanArray();
+
/* package */ final TrustArchive mArchive = new TrustArchive();
private final Context mContext;
private final LockPatternUtils mLockPatternUtils;
@@ -118,9 +119,6 @@
@GuardedBy("mDeviceLockedForUser")
private final SparseBooleanArray mDeviceLockedForUser = new SparseBooleanArray();
- @GuardedBy("mUserHasAuthenticatedSinceBoot")
- private final SparseBooleanArray mUserHasAuthenticatedSinceBoot = new SparseBooleanArray();
-
private boolean mTrustAgentsCanRun = false;
private int mCurrentUser = UserHandle.USER_OWNER;
@@ -146,6 +144,7 @@
if (phase == SystemService.PHASE_SYSTEM_SERVICES_READY) {
mPackageMonitor.register(mContext, mHandler.getLooper(), UserHandle.ALL, true);
mReceiver.register(mContext);
+ mLockPatternUtils.registerStrongAuthTracker(mStrongAuthTracker);
} else if (phase == SystemService.PHASE_THIRD_PARTY_APPS_CAN_START) {
mTrustAgentsCanRun = true;
refreshAgentList(UserHandle.USER_ALL);
@@ -230,7 +229,7 @@
if (!userInfo.supportsSwitchTo()) continue;
if (!mActivityManager.isUserRunning(userInfo.id)) continue;
if (!lockPatternUtils.isSecure(userInfo.id)) continue;
- if (!getUserHasAuthenticated(userInfo.id)) continue;
+ if (!mStrongAuthTracker.isTrustAllowedForUser(userInfo.id)) continue;
DevicePolicyManager dpm = lockPatternUtils.getDevicePolicyManager();
int disabledFeatures = dpm.getKeyguardDisabledFeatures(null, userInfo.id);
final boolean disableTrustAgents =
@@ -509,7 +508,7 @@
// Agent dispatch and aggregation
private boolean aggregateIsTrusted(int userId) {
- if (!getUserHasAuthenticated(userId)) {
+ if (!mStrongAuthTracker.isTrustAllowedForUser(userId)) {
return false;
}
for (int i = 0; i < mActiveAgents.size(); i++) {
@@ -524,7 +523,7 @@
}
private boolean aggregateIsTrustManaged(int userId) {
- if (!getUserHasAuthenticated(userId)) {
+ if (!mStrongAuthTracker.isTrustAllowedForUser(userId)) {
return false;
}
for (int i = 0; i < mActiveAgents.size(); i++) {
@@ -545,54 +544,6 @@
info.agent.onUnlockAttempt(successful);
}
}
-
- if (successful) {
- updateUserHasAuthenticated(userId);
- }
- }
-
- private void updateUserHasAuthenticated(int userId) {
- boolean changed = setUserHasAuthenticated(userId);
- if (changed) {
- refreshAgentList(userId);
- }
- }
-
- private boolean getUserHasAuthenticated(int userId) {
- return mUserHasAuthenticated.get(userId);
- }
-
- /**
- * @return whether the value has changed
- */
- private boolean setUserHasAuthenticated(int userId) {
- if (!mUserHasAuthenticated.get(userId)) {
- mUserHasAuthenticated.put(userId, true);
- synchronized (mUserHasAuthenticatedSinceBoot) {
- mUserHasAuthenticatedSinceBoot.put(userId, true);
- }
- return true;
- }
- return false;
- }
-
- private void clearUserHasAuthenticated(int userId) {
- if (userId == UserHandle.USER_ALL) {
- mUserHasAuthenticated.clear();
- } else {
- mUserHasAuthenticated.put(userId, false);
- }
- }
-
- private boolean getUserHasAuthenticatedSinceBoot(int userId) {
- synchronized (mUserHasAuthenticatedSinceBoot) {
- return mUserHasAuthenticatedSinceBoot.get(userId);
- }
- }
-
- private void requireCredentialEntry(int userId) {
- clearUserHasAuthenticated(userId);
- refreshAgentList(userId);
}
// Listeners
@@ -681,17 +632,6 @@
}
@Override
- public void reportRequireCredentialEntry(int userId) throws RemoteException {
- enforceReportPermission();
- if (userId == UserHandle.USER_ALL || userId >= UserHandle.USER_OWNER) {
- mHandler.obtainMessage(MSG_REQUIRE_CREDENTIAL_ENTRY, userId, 0).sendToTarget();
- } else {
- throw new IllegalArgumentException(
- "userId must be an explicit user id or USER_ALL");
- }
- }
-
- @Override
public void reportKeyguardShowingChanged() throws RemoteException {
enforceReportPermission();
// coalesce refresh messages.
@@ -734,18 +674,6 @@
}
}
- @Override
- public boolean hasUserAuthenticatedSinceBoot(int userId) throws RemoteException {
- mContext.enforceCallingOrSelfPermission(
- Manifest.permission.ACCESS_KEYGUARD_SECURE_STORAGE, null);
- long token = Binder.clearCallingIdentity();
- try {
- return getUserHasAuthenticatedSinceBoot(userId);
- } finally {
- Binder.restoreCallingIdentity(token);
- }
- }
-
private void enforceReportPermission() {
mContext.enforceCallingOrSelfPermission(
Manifest.permission.ACCESS_KEYGUARD_SECURE_STORAGE, "reporting trust events");
@@ -794,9 +722,8 @@
fout.print(": trusted=" + dumpBool(aggregateIsTrusted(user.id)));
fout.print(", trustManaged=" + dumpBool(aggregateIsTrustManaged(user.id)));
fout.print(", deviceLocked=" + dumpBool(isDeviceLockedInner(user.id)));
- fout.print(", hasAuthenticated=" + dumpBool(getUserHasAuthenticated(user.id)));
- fout.print(", hasAuthenticatedSinceBoot="
- + dumpBool(getUserHasAuthenticatedSinceBoot(user.id)));
+ fout.print(", strongAuthRequired=" + dumpHex(
+ mStrongAuthTracker.getStrongAuthForUser(user.id)));
fout.println();
fout.println(" Enabled agents:");
boolean duplicateSimpleNames = false;
@@ -831,6 +758,10 @@
private String dumpBool(boolean b) {
return b ? "1" : "0";
}
+
+ private String dumpHex(int i) {
+ return "0x" + Integer.toHexString(i);
+ }
};
private int resolveProfileParent(int userId) {
@@ -864,9 +795,6 @@
// This is also called when the security mode of a user changes.
refreshDeviceLockedForUser(UserHandle.USER_ALL);
break;
- case MSG_REQUIRE_CREDENTIAL_ENTRY:
- requireCredentialEntry(msg.arg1);
- break;
case MSG_KEYGUARD_SHOWING_CHANGED:
refreshDeviceLockedForUser(mCurrentUser);
break;
@@ -900,6 +828,13 @@
}
};
+ private final StrongAuthTracker mStrongAuthTracker = new StrongAuthTracker() {
+ @Override
+ public void onStrongAuthRequiredChanged(int userId) {
+ refreshAgentList(userId);
+ }
+ };
+
private class Receiver extends BroadcastReceiver {
@Override
@@ -908,8 +843,6 @@
if (DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED.equals(action)) {
refreshAgentList(getSendingUserId());
updateDevicePolicyFeatures();
- } else if (Intent.ACTION_USER_PRESENT.equals(action)) {
- updateUserHasAuthenticated(getSendingUserId());
} else if (Intent.ACTION_USER_ADDED.equals(action)) {
int userId = getUserId(intent);
if (userId > 0) {
@@ -918,7 +851,6 @@
} else if (Intent.ACTION_USER_REMOVED.equals(action)) {
int userId = getUserId(intent);
if (userId > 0) {
- mUserHasAuthenticated.delete(userId);
synchronized (mUserIsTrusted) {
mUserIsTrusted.delete(userId);
}
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 88ef1aef..d695d93 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -643,6 +643,7 @@
final InputManagerService mInputManager;
final DisplayManagerInternal mDisplayManagerInternal;
final DisplayManager mDisplayManager;
+ final Display[] mDisplays;
// Who is holding the screen on.
Session mHoldingScreenOn;
@@ -916,8 +917,8 @@
mFxSession = new SurfaceSession();
mDisplayManager = (DisplayManager)context.getSystemService(Context.DISPLAY_SERVICE);
- Display[] displays = mDisplayManager.getDisplays();
- for (Display display : displays) {
+ mDisplays = mDisplayManager.getDisplays();
+ for (Display display : mDisplays) {
createDisplayContentLocked(display);
}
@@ -7648,7 +7649,9 @@
}
public void displayReady() {
- displayReady(Display.DEFAULT_DISPLAY);
+ for (Display display : mDisplays) {
+ displayReady(display.getDisplayId());
+ }
synchronized(mWindowMap) {
final DisplayContent displayContent = getDefaultDisplayContentLocked();
@@ -10425,8 +10428,8 @@
": removed=" + win.mRemoved + " visible=" + win.isVisibleLw() +
" mHasSurface=" + win.mHasSurface +
" drawState=" + win.mWinAnimator.mDrawState);
- if (win.mRemoved || !win.mHasSurface) {
- // Window has been removed; no draw will now happen, so stop waiting.
+ if (win.mRemoved || !win.mHasSurface || !win.mPolicyVisibility) {
+ // Window has been removed or hidden; no draw will now happen, so stop waiting.
if (DEBUG_SCREEN_ON) Slog.w(TAG, "Aborted waiting for drawn: " + win);
mWaitingForDrawn.remove(win);
} else if (win.hasDrawnLw()) {
@@ -11969,12 +11972,18 @@
final WindowList windows = getDefaultWindowListLocked();
for (int winNdx = windows.size() - 1; winNdx >= 0; --winNdx) {
final WindowState win = windows.get(winNdx);
+ final boolean isForceHiding = mPolicy.isForceHiding(win.mAttrs);
if (win.isVisibleLw()
- && (win.mAppToken != null || mPolicy.isForceHiding(win.mAttrs))) {
+ && (win.mAppToken != null || isForceHiding)) {
win.mWinAnimator.mDrawState = WindowStateAnimator.DRAW_PENDING;
// Force add to mResizingWindows.
win.mLastContentInsets.set(-1, -1, -1, -1);
mWaitingForDrawn.add(win);
+
+ // No need to wait for the windows below Keyguard.
+ if (isForceHiding) {
+ break;
+ }
}
}
requestTraversalLocked();
diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java
index 726d29d..42042b94 100644
--- a/services/core/java/com/android/server/wm/WindowStateAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java
@@ -1064,6 +1064,8 @@
mAnimator.getScreenRotationAnimationLocked(displayId);
final boolean screenAnimation =
screenRotationAnimation != null && screenRotationAnimation.isAnimating();
+
+ mHasClipRect = false;
if (selfTransformation || attachedTransformation != null
|| appTransformation != null || screenAnimation) {
// cache often used attributes locally
@@ -1139,7 +1141,6 @@
// transforming since it is more important to have that
// animation be smooth.
mShownAlpha = mAlpha;
- mHasClipRect = false;
if (!mService.mLimitedAlphaCompositing
|| (!PixelFormat.formatHasAlpha(mWin.mAttrs.format)
|| (mWin.isIdentityMatrix(mDsDx, mDtDx, mDsDy, mDtDy)
diff --git a/services/core/jni/Android.mk b/services/core/jni/Android.mk
index 9556b08..98d8d08 100644
--- a/services/core/jni/Android.mk
+++ b/services/core/jni/Android.mk
@@ -4,9 +4,16 @@
LOCAL_CFLAGS += -Wall -Werror -Wno-unused-parameter
+ifneq ($(ENABLE_CPUSETS),)
+ifneq ($(ENABLE_SCHED_BOOST),)
+LOCAL_CFLAGS += -DUSE_SCHED_BOOST
+endif
+endif
+
LOCAL_SRC_FILES += \
$(LOCAL_REL_DIR)/com_android_server_AlarmManagerService.cpp \
$(LOCAL_REL_DIR)/com_android_server_am_BatteryStatsService.cpp \
+ $(LOCAL_REL_DIR)/com_android_server_am_ActivityManagerService.cpp \
$(LOCAL_REL_DIR)/com_android_server_AssetAtlasService.cpp \
$(LOCAL_REL_DIR)/com_android_server_connectivity_Vpn.cpp \
$(LOCAL_REL_DIR)/com_android_server_ConsumerIrService.cpp \
diff --git a/services/core/jni/com_android_server_am_ActivityManagerService.cpp b/services/core/jni/com_android_server_am_ActivityManagerService.cpp
new file mode 100644
index 0000000..52217b9
--- /dev/null
+++ b/services/core/jni/com_android_server_am_ActivityManagerService.cpp
@@ -0,0 +1,151 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "ActivityManagerService"
+//#define LOG_NDEBUG 0
+
+#include <android_runtime/AndroidRuntime.h>
+#include <jni.h>
+
+#include <ScopedLocalRef.h>
+#include <ScopedPrimitiveArray.h>
+
+#include <cutils/log.h>
+#include <utils/misc.h>
+#include <utils/Log.h>
+
+#include <stdio.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <semaphore.h>
+#include <stddef.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+namespace android
+{
+
+ // migrate from foreground to foreground_boost
+ static jint migrateToBoost(JNIEnv *env, jobject _this)
+ {
+#ifdef USE_SCHED_BOOST
+ // File descriptors open to /dev/cpuset/../tasks, setup by initialize, or -1 on error
+ FILE* fg_cpuset_file = NULL;
+ int boost_cpuset_fd = 0;
+ if (!access("/dev/cpuset/tasks", F_OK)) {
+ fg_cpuset_file = fopen("/dev/cpuset/foreground/tasks", "r+");
+ if (ferror(fg_cpuset_file)) {
+ return 0;
+ }
+ boost_cpuset_fd = open("/dev/cpuset/foreground/boost/tasks", O_WRONLY);
+ if (boost_cpuset_fd < 0) {
+ fclose(fg_cpuset_file);
+ return 0;
+ }
+
+ }
+ if (!fg_cpuset_file || !boost_cpuset_fd) {
+ fclose(fg_cpuset_file);
+ close(boost_cpuset_fd);
+ return 0;
+ }
+ char buf[17];
+ while (fgets(buf, 16, fg_cpuset_file)) {
+ int i = 0;
+ for (; i < 16; i++) {
+ if (buf[i] == '\n') {
+ buf[i] = 0;
+ break;
+ }
+ }
+ if (write(boost_cpuset_fd, buf, i) < 0) {
+ // ignore error
+ }
+ if (feof(fg_cpuset_file))
+ break;
+ }
+ fclose(fg_cpuset_file);
+ close(boost_cpuset_fd);
+#endif
+ return 0;
+ }
+
+ // migrate from foreground_boost to foreground
+ static jint migrateFromBoost(JNIEnv *env, jobject _this)
+ {
+#ifdef USE_SCHED_BOOST
+ // File descriptors open to /dev/cpuset/../tasks, setup by initialize, or -1 on error
+ int fg_cpuset_fd = 0;
+ FILE* boost_cpuset_file = NULL;
+ if (!access("/dev/cpuset/tasks", F_OK)) {
+ boost_cpuset_file = fopen("/dev/cpuset/foreground/boost/tasks", "r+");
+ if (ferror(boost_cpuset_file)) {
+ return 0;
+ }
+ fg_cpuset_fd = open("/dev/cpuset/foreground/tasks", O_WRONLY);
+ if (fg_cpuset_fd < 0) {
+ fclose(boost_cpuset_file);
+ return 0;
+ }
+
+ }
+ if (!boost_cpuset_file || !fg_cpuset_fd) {
+ fclose(boost_cpuset_file);
+ close(fg_cpuset_fd);
+ return 0;
+ }
+ char buf[17];
+ char *curBuf = buf;
+ while (fgets(buf, 16, boost_cpuset_file)) {
+ //ALOGE("Appending FD %s to fg", buf);
+ int i = 0;
+ for (; i < 16; i++) {
+ if (buf[i] == '\n') {
+ buf[i] = 0;
+ break;
+ }
+ }
+ if (write(fg_cpuset_fd, buf, i) < 0) {
+ //ALOGE("Appending FD %s to fg ERROR", buf);
+ // handle error?
+ }
+ if (feof(boost_cpuset_file))
+ break;
+ }
+
+ close(fg_cpuset_fd);
+ fclose(boost_cpuset_file);
+
+#endif
+ return 0;
+
+ }
+
+
+ static JNINativeMethod method_table[] = {
+ { "nativeMigrateToBoost", "()I", (void*)migrateToBoost },
+ { "nativeMigrateFromBoost", "()I", (void*)migrateFromBoost },
+ };
+
+ int register_android_server_ActivityManagerService(JNIEnv *env)
+ {
+ return jniRegisterNativeMethods(env, "com/android/server/am/ActivityManagerService",
+ method_table, NELEM(method_table));
+ }
+
+}
diff --git a/services/core/jni/onload.cpp b/services/core/jni/onload.cpp
index 67872da..1f3fde6 100644
--- a/services/core/jni/onload.cpp
+++ b/services/core/jni/onload.cpp
@@ -20,6 +20,7 @@
#include "utils/misc.h"
namespace android {
+int register_android_server_ActivityManagerService(JNIEnv* env);
int register_android_server_AlarmManagerService(JNIEnv* env);
int register_android_server_AssetAtlasService(JNIEnv* env);
int register_android_server_BatteryStatsService(JNIEnv* env);
@@ -57,6 +58,7 @@
}
ALOG_ASSERT(env, "Could not retrieve the env!");
+ register_android_server_ActivityManagerService(env);
register_android_server_PowerManagerService(env);
register_android_server_SerialService(env);
register_android_server_InputApplicationHandle(env);
@@ -80,5 +82,6 @@
register_android_server_PersistentDataBlockService(env);
register_android_server_Watchdog(env);
+
return JNI_VERSION_1_4;
}
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index cd2885b..dedf1d9 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -21,6 +21,7 @@
import static android.app.admin.DevicePolicyManager.WIPE_EXTERNAL_STORAGE;
import static android.app.admin.DevicePolicyManager.WIPE_RESET_PROTECTION_DATA;
import static android.content.pm.PackageManager.GET_UNINSTALLED_PACKAGES;
+import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_DPM_LOCK_NOW;
import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
import static org.xmlpull.v1.XmlPullParser.END_TAG;
import static org.xmlpull.v1.XmlPullParser.TEXT;
@@ -44,6 +45,7 @@
import android.app.admin.IDevicePolicyManager;
import android.app.admin.SystemUpdatePolicy;
import android.app.backup.IBackupManager;
+import android.app.trust.TrustManager;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.ContentResolver;
@@ -2957,7 +2959,8 @@
}
boolean requireEntry = (flags & DevicePolicyManager.RESET_PASSWORD_REQUIRE_ENTRY) != 0;
if (requireEntry) {
- utils.requireCredentialEntry(UserHandle.USER_ALL);
+ utils.requireStrongAuth(STRONG_AUTH_REQUIRED_AFTER_DPM_LOCK_NOW,
+ UserHandle.USER_ALL);
}
synchronized (this) {
int newOwner = requireEntry ? callingUid : -1;
@@ -3089,7 +3092,8 @@
mPowerManager.goToSleep(SystemClock.uptimeMillis(),
PowerManager.GO_TO_SLEEP_REASON_DEVICE_ADMIN, 0);
// Ensure the device is locked
- new LockPatternUtils(mContext).requireCredentialEntry(UserHandle.USER_ALL);
+ new LockPatternUtils(mContext).requireStrongAuth(
+ STRONG_AUTH_REQUIRED_AFTER_DPM_LOCK_NOW, UserHandle.USER_ALL);
getWindowManager().lockNow(null);
} catch (RemoteException e) {
} finally {
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index bd72860..7dd16d1 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -875,6 +875,11 @@
if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_VOICE_RECOGNIZERS)) {
mSystemServiceManager.startService(VOICE_RECOGNITION_MANAGER_SERVICE_CLASS);
}
+
+ if (GestureLauncherService.isGestureLauncherEnabled(context.getResources())) {
+ Slog.i(TAG, "Gesture Launcher Service");
+ mSystemServiceManager.startService(GestureLauncherService.class);
+ }
}
try {
diff --git a/services/midi/java/com/android/server/midi/MidiService.java b/services/midi/java/com/android/server/midi/MidiService.java
index 3ecfd55..c6d5a7e 100644
--- a/services/midi/java/com/android/server/midi/MidiService.java
+++ b/services/midi/java/com/android/server/midi/MidiService.java
@@ -27,6 +27,7 @@
import android.content.pm.ResolveInfo;
import android.content.pm.ServiceInfo;
import android.content.res.XmlResourceParser;
+import android.media.midi.IBluetoothMidiService;
import android.media.midi.IMidiDeviceListener;
import android.media.midi.IMidiDeviceOpenCallback;
import android.media.midi.IMidiDeviceServer;
@@ -394,7 +395,20 @@
mServiceConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
- IMidiDeviceServer server = IMidiDeviceServer.Stub.asInterface(service);
+ IMidiDeviceServer server = null;
+ if (mBluetoothDevice != null) {
+ IBluetoothMidiService mBluetoothMidiService = IBluetoothMidiService.Stub.asInterface(service);
+ try {
+ // We need to explicitly add the device in a separate method
+ // because onBind() is only called once.
+ IBinder deviceBinder = mBluetoothMidiService.addBluetoothDevice(mBluetoothDevice);
+ server = IMidiDeviceServer.Stub.asInterface(deviceBinder);
+ } catch(RemoteException e) {
+ Log.e(TAG, "Could not call addBluetoothDevice()", e);
+ }
+ } else {
+ server = IMidiDeviceServer.Stub.asInterface(service);
+ }
setDeviceServer(server);
}
@@ -411,7 +425,6 @@
intent.setComponent(new ComponentName(
MidiManager.BLUETOOTH_MIDI_SERVICE_PACKAGE,
MidiManager.BLUETOOTH_MIDI_SERVICE_CLASS));
- intent.putExtra("device", mBluetoothDevice);
} else {
intent = new Intent(MidiDeviceService.SERVICE_INTERFACE);
intent.setComponent(
@@ -575,6 +588,8 @@
Client client = getClient(token);
if (client == null) return;
client.addListener(listener);
+ // Let listener know whether any ports are already busy.
+ updateStickyDeviceStatus(client.mUid, listener);
}
@Override
@@ -584,6 +599,25 @@
client.removeListener(listener);
}
+ // Inform listener of the status of all known devices.
+ private void updateStickyDeviceStatus(int uid, IMidiDeviceListener listener) {
+ synchronized (mDevicesByInfo) {
+ for (Device device : mDevicesByInfo.values()) {
+ // ignore private devices that our client cannot access
+ if (device.isUidAllowed(uid)) {
+ try {
+ MidiDeviceStatus status = device.getDeviceStatus();
+ if (status != null) {
+ listener.onDeviceStatusChanged(status);
+ }
+ } catch (RemoteException e) {
+ Log.e(TAG, "remote exception", e);
+ }
+ }
+ }
+ }
+ }
+
private static final MidiDeviceInfo[] EMPTY_DEVICE_INFO_ARRAY = new MidiDeviceInfo[0];
public MidiDeviceInfo[] getDevices() {
diff --git a/services/net/java/android/net/dhcp/DhcpAckPacket.java b/services/net/java/android/net/dhcp/DhcpAckPacket.java
index 334f708..df44b11 100644
--- a/services/net/java/android/net/dhcp/DhcpAckPacket.java
+++ b/services/net/java/android/net/dhcp/DhcpAckPacket.java
@@ -46,7 +46,7 @@
return s + " ACK: your new IP " + mYourIp +
", netmask " + mSubnetMask +
- ", gateway " + mGateway + dnsServers +
+ ", gateways " + mGateways + dnsServers +
", lease time " + mLeaseTime;
}
@@ -79,7 +79,7 @@
}
addTlv(buffer, DHCP_SUBNET_MASK, mSubnetMask);
- addTlv(buffer, DHCP_ROUTER, mGateway);
+ addTlv(buffer, DHCP_ROUTER, mGateways);
addTlv(buffer, DHCP_DOMAIN_NAME, mDomainName);
addTlv(buffer, DHCP_BROADCAST_ADDRESS, mBroadcastAddress);
addTlv(buffer, DHCP_DNS_SERVER, mDnsServers);
diff --git a/services/net/java/android/net/dhcp/DhcpClient.java b/services/net/java/android/net/dhcp/DhcpClient.java
index 9ee9cf4..c9efc69 100644
--- a/services/net/java/android/net/dhcp/DhcpClient.java
+++ b/services/net/java/android/net/dhcp/DhcpClient.java
@@ -244,8 +244,9 @@
private PendingIntent createStateMachineCommandIntent(final String cmdName, final int cmd) {
String action = DhcpClient.class.getName() + "." + mIfaceName + "." + cmdName;
- Intent intent = new Intent(action, null)
- .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
+ Intent intent = new Intent(action, null).addFlags(
+ Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT |
+ Intent.FLAG_RECEIVER_FOREGROUND);
// TODO: The intent's package covers the whole of the system server, so it's pretty generic.
// Consider adding some sort of token as well.
intent.setPackage(mContext.getPackageName());
@@ -298,6 +299,7 @@
Os.setsockoptInt(mUdpSock, SOL_SOCKET, SO_REUSEADDR, 1);
Os.setsockoptIfreq(mUdpSock, SOL_SOCKET, SO_BINDTODEVICE, mIfaceName);
Os.setsockoptInt(mUdpSock, SOL_SOCKET, SO_BROADCAST, 1);
+ Os.setsockoptInt(mUdpSock, SOL_SOCKET, SO_RCVBUF, 0);
Os.bind(mUdpSock, Inet4Address.ANY, DhcpPacket.DHCP_CLIENT);
NetworkUtils.protectFromVpn(mUdpSock);
} catch(SocketException|ErrnoException e) {
@@ -307,6 +309,16 @@
return true;
}
+ private boolean connectUdpSock(Inet4Address to) {
+ try {
+ Os.connect(mUdpSock, to, DhcpPacket.DHCP_SERVER);
+ return true;
+ } catch (SocketException|ErrnoException e) {
+ Log.e(TAG, "Error connecting UDP socket", e);
+ return false;
+ }
+ }
+
private static void closeQuietly(FileDescriptor fd) {
try {
IoBridge.closeAndSignalBlockedThreads(fd);
@@ -324,7 +336,7 @@
try {
mNMService.setInterfaceConfig(mIfaceName, ifcg);
} catch (RemoteException|IllegalStateException e) {
- Log.e(TAG, "Error configuring IP address : " + e);
+ Log.e(TAG, "Error configuring IP address " + address + ": ", e);
return false;
}
return true;
@@ -344,21 +356,22 @@
public void run() {
maybeLog("Receive thread started");
while (!stopped) {
+ int length = 0; // Or compiler can't tell it's initialized if a parse error occurs.
try {
- int length = Os.read(mPacketSock, mPacket, 0, mPacket.length);
+ length = Os.read(mPacketSock, mPacket, 0, mPacket.length);
DhcpPacket packet = null;
packet = DhcpPacket.decodeFullPacket(mPacket, length, DhcpPacket.ENCAP_L2);
- if (packet != null) {
- maybeLog("Received packet: " + packet);
- sendMessage(CMD_RECEIVED_PACKET, packet);
- } else if (PACKET_DBG) {
- Log.d(TAG,
- "Can't parse packet" + HexDump.dumpHexString(mPacket, 0, length));
- }
+ maybeLog("Received packet: " + packet);
+ sendMessage(CMD_RECEIVED_PACKET, packet);
} catch (IOException|ErrnoException e) {
if (!stopped) {
Log.e(TAG, "Read error", e);
}
+ } catch (DhcpPacket.ParseException e) {
+ Log.e(TAG, "Can't parse packet: " + e.getMessage());
+ if (PACKET_DBG) {
+ Log.d(TAG, HexDump.dumpHexString(mPacket, 0, length));
+ }
}
}
maybeLog("Receive thread stopped");
@@ -375,8 +388,10 @@
maybeLog("Broadcasting " + description);
Os.sendto(mPacketSock, buf.array(), 0, buf.limit(), 0, mInterfaceBroadcastAddr);
} else {
- maybeLog("Unicasting " + description + " to " + to.getHostAddress());
- Os.sendto(mUdpSock, buf, 0, to, DhcpPacket.DHCP_SERVER);
+ // It's safe to call getpeername here, because we only send unicast packets if we
+ // have an IP address, and we connect the UDP socket in DhcpHaveAddressState#enter.
+ maybeLog("Unicasting " + description + " to " + Os.getpeername(mUdpSock));
+ Os.write(mUdpSock, buf);
}
} catch(ErrnoException|IOException e) {
Log.e(TAG, "Can't send packet: ", e);
@@ -402,9 +417,10 @@
encap, mTransactionId, getSecs(), clientAddress,
DO_UNICAST, mHwAddr, requestedAddress,
serverAddress, REQUESTED_PARAMS, null);
+ String serverStr = (serverAddress != null) ? serverAddress.getHostAddress() : null;
String description = "DHCPREQUEST ciaddr=" + clientAddress.getHostAddress() +
" request=" + requestedAddress.getHostAddress() +
- " to=" + serverAddress.getHostAddress();
+ " serverid=" + serverStr;
return transmitPacket(packet, description, to);
}
@@ -788,6 +804,7 @@
transitionTo(mDhcpBoundState);
}
} else if (packet instanceof DhcpNakPacket) {
+ // TODO: Wait a while before returning into INIT state.
Log.d(TAG, "Received NAK, returning to INIT");
mOffer = null;
transitionTo(mDhcpInitState);
@@ -805,10 +822,9 @@
@Override
public void enter() {
super.enter();
- if (setIpAddress(mDhcpLease.ipAddress)) {
- maybeLog("Configured IP address " + mDhcpLease.ipAddress);
- } else {
- Log.e(TAG, "Failed to configure IP address " + mDhcpLease.ipAddress);
+ if (!setIpAddress(mDhcpLease.ipAddress) ||
+ (mDhcpLease.serverAddress != null &&
+ !connectUdpSock((mDhcpLease.serverAddress)))) {
notifyFailure();
// There's likely no point in going into DhcpInitState here, we'll probably just
// repeat the transaction, get the same IP address as before, and fail.
@@ -864,11 +880,15 @@
}
protected boolean sendPacket() {
+ // Not specifying a SERVER_IDENTIFIER option is a violation of RFC 2131, but...
+ // http://b/25343517 . Try to make things work anyway by using broadcast renews.
+ Inet4Address to = (mDhcpLease.serverAddress != null) ?
+ mDhcpLease.serverAddress : INADDR_BROADCAST;
return sendRequestPacket(
(Inet4Address) mDhcpLease.ipAddress.getAddress(), // ciaddr
INADDR_ANY, // DHCP_REQUESTED_IP
- INADDR_ANY, // DHCP_SERVER_IDENTIFIER
- (Inet4Address) mDhcpLease.serverAddress); // packet destination address
+ null, // DHCP_SERVER_IDENTIFIER
+ to); // packet destination address
}
protected void receivePacket(DhcpPacket packet) {
diff --git a/services/net/java/android/net/dhcp/DhcpOfferPacket.java b/services/net/java/android/net/dhcp/DhcpOfferPacket.java
index 7ca7100..99154ef 100644
--- a/services/net/java/android/net/dhcp/DhcpOfferPacket.java
+++ b/services/net/java/android/net/dhcp/DhcpOfferPacket.java
@@ -48,7 +48,7 @@
}
return s + " OFFER, ip " + mYourIp + ", mask " + mSubnetMask +
- dnsServers + ", gateway " + mGateway +
+ dnsServers + ", gateways " + mGateways +
" lease time " + mLeaseTime + ", domain " + mDomainName;
}
@@ -81,7 +81,7 @@
}
addTlv(buffer, DHCP_SUBNET_MASK, mSubnetMask);
- addTlv(buffer, DHCP_ROUTER, mGateway);
+ addTlv(buffer, DHCP_ROUTER, mGateways);
addTlv(buffer, DHCP_DOMAIN_NAME, mDomainName);
addTlv(buffer, DHCP_BROADCAST_ADDRESS, mBroadcastAddress);
addTlv(buffer, DHCP_DNS_SERVER, mDnsServers);
diff --git a/services/net/java/android/net/dhcp/DhcpPacket.java b/services/net/java/android/net/dhcp/DhcpPacket.java
index cbf8fc2..8927bfa 100644
--- a/services/net/java/android/net/dhcp/DhcpPacket.java
+++ b/services/net/java/android/net/dhcp/DhcpPacket.java
@@ -114,6 +114,11 @@
protected static final int MAX_LENGTH = 1500;
/**
+ * The magic cookie that identifies this as a DHCP packet instead of BOOTP.
+ */
+ private static final int DHCP_MAGIC_COOKIE = 0x63825363;
+
+ /**
* DHCP Optional Type: DHCP Subnet Mask
*/
protected static final byte DHCP_SUBNET_MASK = 1;
@@ -123,7 +128,7 @@
* DHCP Optional Type: DHCP Router
*/
protected static final byte DHCP_ROUTER = 3;
- protected Inet4Address mGateway;
+ protected List <Inet4Address> mGateways;
/**
* DHCP Optional Type: DHCP DNS Server
@@ -403,7 +408,7 @@
(HWADDR_LEN - mClientMac.length) // pad addr to 16 bytes
+ 64 // empty server host name (64 bytes)
+ 128); // empty boot file name (128 bytes)
- buf.putInt(0x63825363); // magic number
+ buf.putInt(DHCP_MAGIC_COOKIE); // magic number
finishPacket(buf);
// round up to an even number of octets
@@ -668,6 +673,20 @@
return new String(bytes, 0, length, StandardCharsets.US_ASCII);
}
+ private static boolean isPacketToOrFromClient(short udpSrcPort, short udpDstPort) {
+ return (udpSrcPort == DHCP_CLIENT) || (udpDstPort == DHCP_CLIENT);
+ }
+
+ private static boolean isPacketServerToServer(short udpSrcPort, short udpDstPort) {
+ return (udpSrcPort == DHCP_SERVER) && (udpDstPort == DHCP_SERVER);
+ }
+
+ public static class ParseException extends Exception {
+ public ParseException(String msg, Object... args) {
+ super(String.format(msg, args));
+ }
+ }
+
/**
* Creates a concrete DhcpPacket from the supplied ByteBuffer. The
* buffer may have an L2 encapsulation (which is the full EthernetII
@@ -677,7 +696,7 @@
* A subset of the optional parameters are parsed and are stored
* in object fields.
*/
- public static DhcpPacket decodeFullPacket(ByteBuffer packet, int pktType)
+ public static DhcpPacket decodeFullPacket(ByteBuffer packet, int pktType) throws ParseException
{
// bootp parameters
int transactionId;
@@ -687,8 +706,8 @@
Inet4Address nextIp;
Inet4Address relayIp;
byte[] clientMac;
- List<Inet4Address> dnsServers = new ArrayList<Inet4Address>();
- Inet4Address gateway = null; // aka router
+ List<Inet4Address> dnsServers = new ArrayList<>();
+ List<Inet4Address> gateways = new ArrayList<>(); // aka router
Inet4Address serverIdentifier = null;
Inet4Address netMask = null;
String message = null;
@@ -720,7 +739,8 @@
// check to see if we need to parse L2, IP, and UDP encaps
if (pktType == ENCAP_L2) {
if (packet.remaining() < MIN_PACKET_LENGTH_L2) {
- return null;
+ throw new ParseException("L2 packet too short, %d < %d",
+ packet.remaining(), MIN_PACKET_LENGTH_L2);
}
byte[] l2dst = new byte[6];
@@ -732,18 +752,20 @@
short l2type = packet.getShort();
if (l2type != OsConstants.ETH_P_IP)
- return null;
+ throw new ParseException("Unexpected L2 type 0x%04x, expected 0x%04x",
+ l2type, OsConstants.ETH_P_IP);
}
if (pktType <= ENCAP_L3) {
if (packet.remaining() < MIN_PACKET_LENGTH_L3) {
- return null;
+ throw new ParseException("L3 packet too short, %d < %d",
+ packet.remaining(), MIN_PACKET_LENGTH_L3);
}
byte ipTypeAndLength = packet.get();
int ipVersion = (ipTypeAndLength & 0xf0) >> 4;
if (ipVersion != 4) {
- return null;
+ throw new ParseException("Invalid IP version %d", ipVersion);
}
// System.out.println("ipType is " + ipType);
@@ -759,8 +781,9 @@
ipSrc = readIpAddress(packet);
ipDst = readIpAddress(packet);
- if (ipProto != IP_TYPE_UDP) // UDP
- return null;
+ if (ipProto != IP_TYPE_UDP) {
+ throw new ParseException("Protocol not UDP: %d", ipProto);
+ }
// Skip options. This cannot cause us to read beyond the end of the buffer because the
// IPv4 header cannot be more than (0x0f * 4) = 60 bytes long, and that is less than
@@ -776,13 +799,19 @@
short udpLen = packet.getShort();
short udpChkSum = packet.getShort();
- if ((udpSrcPort != DHCP_SERVER) && (udpSrcPort != DHCP_CLIENT))
+ // Only accept packets to or from the well-known client port (expressly permitting
+ // packets from ports other than the well-known server port; http://b/24687559), and
+ // server-to-server packets, e.g. for relays.
+ if (!isPacketToOrFromClient(udpSrcPort, udpDstPort) &&
+ !isPacketServerToServer(udpSrcPort, udpDstPort)) {
return null;
+ }
}
// We need to check the length even for ENCAP_L3 because the IPv4 header is variable-length.
if (pktType > ENCAP_BOOTP || packet.remaining() < MIN_PACKET_LENGTH_BOOTP) {
- return null;
+ throw new ParseException("Invalid type or BOOTP packet too short, %d < %d",
+ packet.remaining(), MIN_PACKET_LENGTH_BOOTP);
}
byte type = packet.get();
@@ -805,7 +834,7 @@
packet.get(ipv4addr);
relayIp = (Inet4Address) Inet4Address.getByAddress(ipv4addr);
} catch (UnknownHostException ex) {
- return null;
+ throw new ParseException("Invalid IPv4 address: %s", Arrays.toString(ipv4addr));
}
// Some DHCP servers have been known to announce invalid client hardware address values such
@@ -828,8 +857,10 @@
int dhcpMagicCookie = packet.getInt();
- if (dhcpMagicCookie != 0x63825363)
- return null;
+ if (dhcpMagicCookie != DHCP_MAGIC_COOKIE) {
+ throw new ParseException("Bad magic cookie 0x%08x, should be 0x%08x", dhcpMagicCookie,
+ DHCP_MAGIC_COOKIE);
+ }
// parse options
boolean notFinishedOptions = true;
@@ -852,8 +883,9 @@
expectedLen = 4;
break;
case DHCP_ROUTER:
- gateway = readIpAddress(packet);
- expectedLen = 4;
+ for (expectedLen = 0; expectedLen < optionLen; expectedLen += 4) {
+ gateways.add(readIpAddress(packet));
+ }
break;
case DHCP_DNS_SERVER:
for (expectedLen = 0; expectedLen < optionLen; expectedLen += 4) {
@@ -937,18 +969,20 @@
}
if (expectedLen != optionLen) {
- return null;
+ throw new ParseException("Invalid length %d for option %d, expected %d",
+ optionLen, optionType, expectedLen);
}
}
} catch (BufferUnderflowException e) {
- return null;
+ throw new ParseException("BufferUnderflowException");
}
}
DhcpPacket newPacket;
switch(dhcpType) {
- case -1: return null;
+ case (byte) 0xFF:
+ throw new ParseException("No DHCP message type option");
case DHCP_MESSAGE_TYPE_DISCOVER:
newPacket = new DhcpDiscoverPacket(
transactionId, secs, clientMac, broadcast);
@@ -981,14 +1015,13 @@
clientMac);
break;
default:
- System.out.println("Unimplemented type: " + dhcpType);
- return null;
+ throw new ParseException("Unimplemented DHCP type %d", dhcpType);
}
newPacket.mBroadcastAddress = bcAddr;
newPacket.mDnsServers = dnsServers;
newPacket.mDomainName = domainName;
- newPacket.mGateway = gateway;
+ newPacket.mGateways = gateways;
newPacket.mHostName = hostName;
newPacket.mLeaseTime = leaseTime;
newPacket.mMessage = message;
@@ -1009,7 +1042,7 @@
* Parse a packet from an array of bytes, stopping at the given length.
*/
public static DhcpPacket decodeFullPacket(byte[] packet, int length, int pktType)
- {
+ throws ParseException {
ByteBuffer buffer = ByteBuffer.wrap(packet, 0, length).order(ByteOrder.BIG_ENDIAN);
return decodeFullPacket(buffer, pktType);
}
@@ -1044,7 +1077,11 @@
} catch (IllegalArgumentException e) {
return null;
}
- results.gateway = mGateway;
+
+ if (mGateways.size() > 0) {
+ results.gateway = mGateways.get(0);
+ }
+
results.dnsServers.addAll(mDnsServers);
results.domains = mDomainName;
results.serverAddress = mServerIdentifier;
@@ -1086,11 +1123,11 @@
public static ByteBuffer buildOfferPacket(int encap, int transactionId,
boolean broadcast, Inet4Address serverIpAddr, Inet4Address clientIpAddr,
byte[] mac, Integer timeout, Inet4Address netMask, Inet4Address bcAddr,
- Inet4Address gateway, List<Inet4Address> dnsServers,
+ List<Inet4Address> gateways, List<Inet4Address> dnsServers,
Inet4Address dhcpServerIdentifier, String domainName) {
DhcpPacket pkt = new DhcpOfferPacket(
transactionId, (short) 0, broadcast, serverIpAddr, INADDR_ANY, clientIpAddr, mac);
- pkt.mGateway = gateway;
+ pkt.mGateways = gateways;
pkt.mDnsServers = dnsServers;
pkt.mLeaseTime = timeout;
pkt.mDomainName = domainName;
@@ -1106,11 +1143,11 @@
public static ByteBuffer buildAckPacket(int encap, int transactionId,
boolean broadcast, Inet4Address serverIpAddr, Inet4Address clientIpAddr,
byte[] mac, Integer timeout, Inet4Address netMask, Inet4Address bcAddr,
- Inet4Address gateway, List<Inet4Address> dnsServers,
+ List<Inet4Address> gateways, List<Inet4Address> dnsServers,
Inet4Address dhcpServerIdentifier, String domainName) {
DhcpPacket pkt = new DhcpAckPacket(
transactionId, (short) 0, broadcast, serverIpAddr, INADDR_ANY, clientIpAddr, mac);
- pkt.mGateway = gateway;
+ pkt.mGateways = gateways;
pkt.mDnsServers = dnsServers;
pkt.mLeaseTime = timeout;
pkt.mDomainName = domainName;
diff --git a/services/net/java/android/net/util/IpUtils.java b/services/net/java/android/net/util/IpUtils.java
new file mode 100644
index 0000000..e037c40
--- /dev/null
+++ b/services/net/java/android/net/util/IpUtils.java
@@ -0,0 +1,151 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.util;
+
+import java.net.Inet6Address;
+import java.net.InetAddress;
+import java.nio.BufferOverflowException;
+import java.nio.BufferUnderflowException;
+import java.nio.ByteBuffer;
+import java.nio.ShortBuffer;
+
+import static android.system.OsConstants.IPPROTO_TCP;
+import static android.system.OsConstants.IPPROTO_UDP;
+
+/**
+ * @hide
+ */
+public class IpUtils {
+ /**
+ * Converts a signed short value to an unsigned int value. Needed
+ * because Java does not have unsigned types.
+ */
+ private static int intAbs(short v) {
+ return v & 0xFFFF;
+ }
+
+ /**
+ * Performs an IP checksum (used in IP header and across UDP
+ * payload) on the specified portion of a ByteBuffer. The seed
+ * allows the checksum to commence with a specified value.
+ */
+ private static int checksum(ByteBuffer buf, int seed, int start, int end) {
+ int sum = seed;
+ final int bufPosition = buf.position();
+
+ // set position of original ByteBuffer, so that the ShortBuffer
+ // will be correctly initialized
+ buf.position(start);
+ ShortBuffer shortBuf = buf.asShortBuffer();
+
+ // re-set ByteBuffer position
+ buf.position(bufPosition);
+
+ final int numShorts = (end - start) / 2;
+ for (int i = 0; i < numShorts; i++) {
+ sum += intAbs(shortBuf.get(i));
+ }
+ start += numShorts * 2;
+
+ // see if a singleton byte remains
+ if (end != start) {
+ short b = buf.get(start);
+
+ // make it unsigned
+ if (b < 0) {
+ b += 256;
+ }
+
+ sum += b * 256;
+ }
+
+ sum = ((sum >> 16) & 0xFFFF) + (sum & 0xFFFF);
+ sum = ((sum + ((sum >> 16) & 0xFFFF)) & 0xFFFF);
+ int negated = ~sum;
+ return intAbs((short) negated);
+ }
+
+ private static int pseudoChecksumIPv4(
+ ByteBuffer buf, int headerOffset, int protocol, int transportLen) {
+ int partial = protocol + transportLen;
+ partial += intAbs(buf.getShort(headerOffset + 12));
+ partial += intAbs(buf.getShort(headerOffset + 14));
+ partial += intAbs(buf.getShort(headerOffset + 16));
+ partial += intAbs(buf.getShort(headerOffset + 18));
+ return partial;
+ }
+
+ private static int pseudoChecksumIPv6(
+ ByteBuffer buf, int headerOffset, int protocol, int transportLen) {
+ int partial = protocol + transportLen;
+ for (int offset = 8; offset < 40; offset += 2) {
+ partial += intAbs(buf.getShort(headerOffset + offset));
+ }
+ return partial;
+ }
+
+ private static byte ipversion(ByteBuffer buf, int headerOffset) {
+ return (byte) ((buf.get(headerOffset) & (byte) 0xf0) >> 4);
+ }
+
+ public static short ipChecksum(ByteBuffer buf, int headerOffset) {
+ byte ihl = (byte) (buf.get(headerOffset) & 0x0f);
+ return (short) checksum(buf, 0, headerOffset, headerOffset + ihl * 4);
+ }
+
+ private static short transportChecksum(ByteBuffer buf, int protocol,
+ int ipOffset, int transportOffset, int transportLen) {
+ if (transportLen < 0) {
+ throw new IllegalArgumentException("Transport length < 0: " + transportLen);
+ }
+ int sum;
+ byte ver = ipversion(buf, ipOffset);
+ if (ver == 4) {
+ sum = pseudoChecksumIPv4(buf, ipOffset, protocol, transportLen);
+ } else if (ver == 6) {
+ sum = pseudoChecksumIPv6(buf, ipOffset, protocol, transportLen);
+ } else {
+ throw new UnsupportedOperationException("Checksum must be IPv4 or IPv6");
+ }
+
+ sum = checksum(buf, sum, transportOffset, transportOffset + transportLen);
+ if (protocol == IPPROTO_UDP && sum == 0) {
+ sum = (short) 0xffff;
+ }
+ return (short) sum;
+ }
+
+ public static short udpChecksum(ByteBuffer buf, int ipOffset, int transportOffset) {
+ int transportLen = intAbs(buf.getShort(transportOffset + 4));
+ return transportChecksum(buf, IPPROTO_UDP, ipOffset, transportOffset, transportLen);
+ }
+
+ public static short tcpChecksum(ByteBuffer buf, int ipOffset, int transportOffset,
+ int transportLen) {
+ return transportChecksum(buf, IPPROTO_TCP, ipOffset, transportOffset, transportLen);
+ }
+
+ public static String addressAndPortToString(InetAddress address, int port) {
+ return String.format(
+ (address instanceof Inet6Address) ? "[%s]:%d" : "%s:%d",
+ address.getHostAddress(), port);
+ }
+
+ public static boolean isValidUdpOrTcpPort(int port) {
+ return port > 0 && port < 65536;
+ }
+}
diff --git a/services/tests/servicestests/AndroidManifest.xml b/services/tests/servicestests/AndroidManifest.xml
index 919293a..8bb20a6 100644
--- a/services/tests/servicestests/AndroidManifest.xml
+++ b/services/tests/servicestests/AndroidManifest.xml
@@ -39,6 +39,7 @@
<uses-permission android:name="android.permission.MODIFY_PHONE_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
+ <uses-permission android:name="android.permission.PACKET_KEEPALIVE_OFFLOAD" />
<application>
<uses-library android:name="android.test.runner" />
diff --git a/services/tests/servicestests/src/android/net/IpUtilsTest.java b/services/tests/servicestests/src/android/net/IpUtilsTest.java
new file mode 100644
index 0000000..c2d1608
--- /dev/null
+++ b/services/tests/servicestests/src/android/net/IpUtilsTest.java
@@ -0,0 +1,162 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.util;
+
+import android.net.util.IpUtils;
+import android.test.suitebuilder.annotation.SmallTest;
+
+import java.nio.ByteBuffer;
+
+import junit.framework.TestCase;
+
+
+public class IpUtilsTest extends TestCase {
+
+ private static final int IPV4_HEADER_LENGTH = 20;
+ private static final int IPV6_HEADER_LENGTH = 40;
+ private static final int TCP_HEADER_LENGTH = 20;
+ private static final int UDP_HEADER_LENGTH = 8;
+ private static final int IP_CHECKSUM_OFFSET = 10;
+ private static final int TCP_CHECKSUM_OFFSET = 16;
+ private static final int UDP_CHECKSUM_OFFSET = 6;
+
+ private int getUnsignedByte(ByteBuffer buf, int offset) {
+ return buf.get(offset) & 0xff;
+ }
+
+ private int getChecksum(ByteBuffer buf, int offset) {
+ return getUnsignedByte(buf, offset) * 256 + getUnsignedByte(buf, offset + 1);
+ }
+
+ private void assertChecksumEquals(int expected, short actual) {
+ assertEquals(Integer.toHexString(expected), Integer.toHexString(actual & 0xffff));
+ }
+
+ // Generate test packets using Python code like this::
+ //
+ // from scapy import all as scapy
+ //
+ // def JavaPacketDefinition(bytes):
+ // out = " ByteBuffer packet = ByteBuffer.wrap(new byte[] {\n "
+ // for i in xrange(len(bytes)):
+ // out += "(byte) 0x%02x" % ord(bytes[i])
+ // if i < len(bytes) - 1:
+ // if i % 4 == 3:
+ // out += ",\n "
+ // else:
+ // out += ", "
+ // out += "\n });"
+ // return out
+ //
+ // packet = (scapy.IPv6(src="2001:db8::1", dst="2001:db8::2") /
+ // scapy.UDP(sport=12345, dport=7) /
+ // "hello")
+ // print JavaPacketDefinition(str(packet))
+
+ @SmallTest
+ public void testIpv6TcpChecksum() throws Exception {
+ // packet = (scapy.IPv6(src="2001:db8::1", dst="2001:db8::2", tc=0x80) /
+ // scapy.TCP(sport=12345, dport=7,
+ // seq=1692871236, ack=128376451, flags=16,
+ // window=32768) /
+ // "hello, world")
+ ByteBuffer packet = ByteBuffer.wrap(new byte[] {
+ (byte) 0x68, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+ (byte) 0x00, (byte) 0x20, (byte) 0x06, (byte) 0x40,
+ (byte) 0x20, (byte) 0x01, (byte) 0x0d, (byte) 0xb8,
+ (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+ (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+ (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x01,
+ (byte) 0x20, (byte) 0x01, (byte) 0x0d, (byte) 0xb8,
+ (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+ (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+ (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x02,
+ (byte) 0x30, (byte) 0x39, (byte) 0x00, (byte) 0x07,
+ (byte) 0x64, (byte) 0xe7, (byte) 0x2a, (byte) 0x44,
+ (byte) 0x07, (byte) 0xa6, (byte) 0xde, (byte) 0x83,
+ (byte) 0x50, (byte) 0x10, (byte) 0x80, (byte) 0x00,
+ (byte) 0xee, (byte) 0x71, (byte) 0x00, (byte) 0x00,
+ (byte) 0x68, (byte) 0x65, (byte) 0x6c, (byte) 0x6c,
+ (byte) 0x6f, (byte) 0x2c, (byte) 0x20, (byte) 0x77,
+ (byte) 0x6f, (byte) 0x72, (byte) 0x6c, (byte) 0x64
+ });
+
+ // Check that a valid packet has checksum 0.
+ int transportLen = packet.limit() - IPV6_HEADER_LENGTH;
+ assertEquals(0, IpUtils.tcpChecksum(packet, 0, IPV6_HEADER_LENGTH, transportLen));
+
+ // Check that we can calculate the checksum from scratch.
+ int sumOffset = IPV6_HEADER_LENGTH + TCP_CHECKSUM_OFFSET;
+ int sum = getUnsignedByte(packet, sumOffset) * 256 + getUnsignedByte(packet, sumOffset + 1);
+ assertEquals(0xee71, sum);
+
+ packet.put(sumOffset, (byte) 0);
+ packet.put(sumOffset + 1, (byte) 0);
+ assertChecksumEquals(sum, IpUtils.tcpChecksum(packet, 0, IPV6_HEADER_LENGTH, transportLen));
+
+ // Check that writing the checksum back into the packet results in a valid packet.
+ packet.putShort(
+ sumOffset,
+ IpUtils.tcpChecksum(packet, 0, IPV6_HEADER_LENGTH, transportLen));
+ assertEquals(0, IpUtils.tcpChecksum(packet, 0, IPV6_HEADER_LENGTH, transportLen));
+ }
+
+ @SmallTest
+ public void testIpv4UdpChecksum() {
+ // packet = (scapy.IP(src="192.0.2.1", dst="192.0.2.2", tos=0x40) /
+ // scapy.UDP(sport=32012, dport=4500) /
+ // "\xff")
+ ByteBuffer packet = ByteBuffer.wrap(new byte[] {
+ (byte) 0x45, (byte) 0x40, (byte) 0x00, (byte) 0x1d,
+ (byte) 0x00, (byte) 0x01, (byte) 0x00, (byte) 0x00,
+ (byte) 0x40, (byte) 0x11, (byte) 0xf6, (byte) 0x8b,
+ (byte) 0xc0, (byte) 0x00, (byte) 0x02, (byte) 0x01,
+ (byte) 0xc0, (byte) 0x00, (byte) 0x02, (byte) 0x02,
+ (byte) 0x7d, (byte) 0x0c, (byte) 0x11, (byte) 0x94,
+ (byte) 0x00, (byte) 0x09, (byte) 0xee, (byte) 0x36,
+ (byte) 0xff
+ });
+
+ // Check that a valid packet has IP checksum 0 and UDP checksum 0xffff (0 is not a valid
+ // UDP checksum, so the udpChecksum rewrites 0 to 0xffff).
+ assertEquals(0, IpUtils.ipChecksum(packet, 0));
+ assertEquals((short) 0xffff, IpUtils.udpChecksum(packet, 0, IPV4_HEADER_LENGTH));
+
+ // Check that we can calculate the checksums from scratch.
+ final int ipSumOffset = IP_CHECKSUM_OFFSET;
+ final int ipSum = getChecksum(packet, ipSumOffset);
+ assertEquals(0xf68b, ipSum);
+
+ packet.put(ipSumOffset, (byte) 0);
+ packet.put(ipSumOffset + 1, (byte) 0);
+ assertChecksumEquals(ipSum, IpUtils.ipChecksum(packet, 0));
+
+ final int udpSumOffset = IPV4_HEADER_LENGTH + UDP_CHECKSUM_OFFSET;
+ final int udpSum = getChecksum(packet, udpSumOffset);
+ assertEquals(0xee36, udpSum);
+
+ packet.put(udpSumOffset, (byte) 0);
+ packet.put(udpSumOffset + 1, (byte) 0);
+ assertChecksumEquals(udpSum, IpUtils.udpChecksum(packet, 0, IPV4_HEADER_LENGTH));
+
+ // Check that writing the checksums back into the packet results in a valid packet.
+ packet.putShort(ipSumOffset, IpUtils.ipChecksum(packet, 0));
+ packet.putShort(udpSumOffset, IpUtils.udpChecksum(packet, 0, IPV4_HEADER_LENGTH));
+ assertEquals(0, IpUtils.ipChecksum(packet, 0));
+ assertEquals((short) 0xffff, IpUtils.udpChecksum(packet, 0, IPV4_HEADER_LENGTH));
+ }
+}
diff --git a/services/tests/servicestests/src/android/net/dhcp/DhcpPacketTest.java b/services/tests/servicestests/src/android/net/dhcp/DhcpPacketTest.java
index cd3b8bb..7e60bf1 100644
--- a/services/tests/servicestests/src/android/net/dhcp/DhcpPacketTest.java
+++ b/services/tests/servicestests/src/android/net/dhcp/DhcpPacketTest.java
@@ -117,7 +117,7 @@
private void assertDomainAndVendorInfoParses(
String expectedDomain, byte[] domainBytes,
- String expectedVendorInfo, byte[] vendorInfoBytes) {
+ String expectedVendorInfo, byte[] vendorInfoBytes) throws Exception {
ByteBuffer packet = new TestDhcpPacket(DHCP_MESSAGE_TYPE_OFFER)
.setDomainBytes(domainBytes)
.setVendorInfoBytes(vendorInfoBytes)
@@ -158,17 +158,25 @@
}
private void assertLeaseTimeParses(boolean expectValid, Integer rawLeaseTime,
- long leaseTimeMillis, byte[] leaseTimeBytes) {
+ long leaseTimeMillis, byte[] leaseTimeBytes) throws Exception {
TestDhcpPacket testPacket = new TestDhcpPacket(DHCP_MESSAGE_TYPE_OFFER);
if (leaseTimeBytes != null) {
testPacket.setLeaseTimeBytes(leaseTimeBytes);
}
ByteBuffer packet = testPacket.build();
- DhcpPacket offerPacket = DhcpPacket.decodeFullPacket(packet, ENCAP_BOOTP);
+ DhcpPacket offerPacket = null;
+
if (!expectValid) {
- assertNull(offerPacket);
+ try {
+ offerPacket = DhcpPacket.decodeFullPacket(packet, ENCAP_BOOTP);
+ fail("Invalid packet parsed successfully: " + offerPacket);
+ } catch (ParseException expected) {
+ }
return;
}
+
+ offerPacket = DhcpPacket.decodeFullPacket(packet, ENCAP_BOOTP);
+ assertNotNull(offerPacket);
assertEquals(rawLeaseTime, offerPacket.mLeaseTime);
DhcpResults dhcpResults = offerPacket.toDhcpResults(); // Just check this doesn't crash.
assertEquals(leaseTimeMillis, offerPacket.getLeaseTimeMillis());
@@ -200,14 +208,14 @@
}
private void checkIpAddress(String expected, Inet4Address clientIp, Inet4Address yourIp,
- byte[] netmaskBytes) {
+ byte[] netmaskBytes) throws Exception {
checkIpAddress(expected, DHCP_MESSAGE_TYPE_OFFER, clientIp, yourIp, netmaskBytes);
checkIpAddress(expected, DHCP_MESSAGE_TYPE_ACK, clientIp, yourIp, netmaskBytes);
}
private void checkIpAddress(String expected, byte type,
Inet4Address clientIp, Inet4Address yourIp,
- byte[] netmaskBytes) {
+ byte[] netmaskBytes) throws Exception {
ByteBuffer packet = new TestDhcpPacket(type, clientIp, yourIp)
.setNetmaskBytes(netmaskBytes)
.build();
@@ -506,4 +514,74 @@
assertDhcpResults("10.32.158.205/20", "10.32.144.1", "148.88.65.52,148.88.65.53",
"lancs.ac.uk", "10.32.255.128", null, 7200, false, dhcpResults);
}
+
+ @SmallTest
+ public void testUdpServerAnySourcePort() throws Exception {
+ final ByteBuffer packet = ByteBuffer.wrap(HexEncoding.decode((
+ // Ethernet header.
+ "9cd917000000001c2e0000000800" +
+ // IP header.
+ "45a00148000040003d115087d18194fb0a0f7af2" +
+ // UDP header. TODO: fix invalid checksum (due to MAC address obfuscation).
+ // NOTE: The server source port is not the canonical port 67.
+ "C29F004401341268" +
+ // BOOTP header.
+ "02010600d628ba8200000000000000000a0f7af2000000000a0fc818" +
+ // MAC address.
+ "9cd91700000000000000000000000000" +
+ // Server name.
+ "0000000000000000000000000000000000000000000000000000000000000000" +
+ "0000000000000000000000000000000000000000000000000000000000000000" +
+ // File.
+ "0000000000000000000000000000000000000000000000000000000000000000" +
+ "0000000000000000000000000000000000000000000000000000000000000000" +
+ "0000000000000000000000000000000000000000000000000000000000000000" +
+ "0000000000000000000000000000000000000000000000000000000000000000" +
+ // Options.
+ "6382536335010236040a0169fc3304000151800104ffff000003040a0fc817060cd1818003d1819403" +
+ "d18180060f0777766d2e6564751c040a0fffffff000000"
+ ).toCharArray(), false));
+
+ DhcpPacket offerPacket = DhcpPacket.decodeFullPacket(packet, ENCAP_L2);
+ assertTrue(offerPacket instanceof DhcpOfferPacket);
+ assertEquals("9CD917000000", HexDump.toHexString(offerPacket.getClientMac()));
+ DhcpResults dhcpResults = offerPacket.toDhcpResults();
+ assertDhcpResults("10.15.122.242/16", "10.15.200.23",
+ "209.129.128.3,209.129.148.3,209.129.128.6",
+ "wvm.edu", "10.1.105.252", null, 86400, false, dhcpResults);
+ }
+
+ @SmallTest
+ public void testMultipleRouters() throws Exception {
+ final ByteBuffer packet = ByteBuffer.wrap(HexEncoding.decode((
+ // Ethernet header.
+ "fc3d93000000" + "081735000000" + "0800" +
+ // IP header.
+ "45000148c2370000ff117ac2c0a8bd02ffffffff" +
+ // UDP header. TODO: fix invalid checksum (due to MAC address obfuscation).
+ "0043004401343beb" +
+ // BOOTP header.
+ "0201060027f518e20000800000000000c0a8bd310000000000000000" +
+ // MAC address.
+ "fc3d9300000000000000000000000000" +
+ // Server name.
+ "0000000000000000000000000000000000000000000000000000000000000000" +
+ "0000000000000000000000000000000000000000000000000000000000000000" +
+ // File.
+ "0000000000000000000000000000000000000000000000000000000000000000" +
+ "0000000000000000000000000000000000000000000000000000000000000000" +
+ "0000000000000000000000000000000000000000000000000000000000000000" +
+ "0000000000000000000000000000000000000000000000000000000000000000" +
+ // Options.
+ "638253633501023604c0abbd023304000070803a04000038403b04000062700104ffffff00" +
+ "0308c0a8bd01ffffff0006080808080808080404ff000000000000"
+ ).toCharArray(), false));
+
+ DhcpPacket offerPacket = DhcpPacket.decodeFullPacket(packet, ENCAP_L2);
+ assertTrue(offerPacket instanceof DhcpOfferPacket);
+ assertEquals("FC3D93000000", HexDump.toHexString(offerPacket.getClientMac()));
+ DhcpResults dhcpResults = offerPacket.toDhcpResults();
+ assertDhcpResults("192.168.189.49/24", "192.168.189.1", "8.8.8.8,8.8.4.4",
+ null, "192.171.189.2", null, 28800, false, dhcpResults);
+ }
}
diff --git a/services/tests/servicestests/src/com/android/server/ConnectivityServiceTest.java b/services/tests/servicestests/src/com/android/server/ConnectivityServiceTest.java
index b4c76b7..97e16da 100644
--- a/services/tests/servicestests/src/com/android/server/ConnectivityServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/ConnectivityServiceTest.java
@@ -20,35 +20,9 @@
import static android.net.ConnectivityManager.TYPE_MOBILE;
import static android.net.ConnectivityManager.TYPE_WIFI;
import static android.net.ConnectivityManager.getNetworkTypeName;
-import static android.net.NetworkCapabilities.NET_CAPABILITY_CAPTIVE_PORTAL;
-import static android.net.NetworkCapabilities.NET_CAPABILITY_CBS;
-import static android.net.NetworkCapabilities.NET_CAPABILITY_DUN;
-import static android.net.NetworkCapabilities.NET_CAPABILITY_EIMS;
-import static android.net.NetworkCapabilities.NET_CAPABILITY_FOTA;
-import static android.net.NetworkCapabilities.NET_CAPABILITY_IA;
-import static android.net.NetworkCapabilities.NET_CAPABILITY_IMS;
-import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET;
-import static android.net.NetworkCapabilities.NET_CAPABILITY_MMS;
-import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_METERED;
-import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED;
-import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_VPN;
-import static android.net.NetworkCapabilities.NET_CAPABILITY_RCS;
-import static android.net.NetworkCapabilities.NET_CAPABILITY_SUPL;
-import static android.net.NetworkCapabilities.NET_CAPABILITY_TRUSTED;
-import static android.net.NetworkCapabilities.NET_CAPABILITY_VALIDATED;
-import static android.net.NetworkCapabilities.NET_CAPABILITY_WIFI_P2P;
-import static android.net.NetworkCapabilities.NET_CAPABILITY_XCAP;
-import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
-import static android.net.NetworkCapabilities.TRANSPORT_WIFI;
-import static org.mockito.Matchers.anyInt;
-import static org.mockito.Matchers.eq;
-import static org.mockito.Matchers.isA;
-import static org.mockito.Mockito.doNothing;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.doThrow;
+import static android.net.NetworkCapabilities.*;
+
import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.reset;
-import static org.mockito.Mockito.verify;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
@@ -58,8 +32,12 @@
import android.content.IntentFilter;
import android.net.ConnectivityManager;
import android.net.ConnectivityManager.NetworkCallback;
+import android.net.ConnectivityManager.PacketKeepalive;
+import android.net.ConnectivityManager.PacketKeepaliveCallback;
import android.net.INetworkPolicyManager;
import android.net.INetworkStatsService;
+import android.net.IpPrefix;
+import android.net.LinkAddress;
import android.net.LinkProperties;
import android.net.Network;
import android.net.NetworkAgent;
@@ -74,8 +52,11 @@
import android.os.ConditionVariable;
import android.os.Handler;
import android.os.HandlerThread;
-import android.os.Looper;
import android.os.INetworkManagementService;
+import android.os.Looper;
+import android.os.Message;
+import android.os.MessageQueue;
+import android.os.MessageQueue.IdleHandler;
import android.test.AndroidTestCase;
import android.test.suitebuilder.annotation.LargeTest;
import android.util.Log;
@@ -84,10 +65,10 @@
import com.android.server.connectivity.NetworkAgentInfo;
import com.android.server.connectivity.NetworkMonitor;
-import org.mockito.ArgumentCaptor;
-
import java.net.InetAddress;
-import java.util.concurrent.Future;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
/**
@@ -99,24 +80,7 @@
public class ConnectivityServiceTest extends AndroidTestCase {
private static final String TAG = "ConnectivityServiceTest";
- private static final String MOBILE_IFACE = "rmnet3";
- private static final String WIFI_IFACE = "wlan6";
-
- private static final RouteInfo MOBILE_ROUTE_V4 = RouteInfo.makeHostRoute(parse("10.0.0.33"),
- MOBILE_IFACE);
- private static final RouteInfo MOBILE_ROUTE_V6 = RouteInfo.makeHostRoute(parse("fd00::33"),
- MOBILE_IFACE);
-
- private static final RouteInfo WIFI_ROUTE_V4 = RouteInfo.makeHostRoute(parse("192.168.0.66"),
- parse("192.168.0.1"),
- WIFI_IFACE);
- private static final RouteInfo WIFI_ROUTE_V6 = RouteInfo.makeHostRoute(parse("fd00::66"),
- parse("fd00::"),
- WIFI_IFACE);
-
- private INetworkManagementService mNetManager;
- private INetworkStatsService mStatsService;
- private INetworkPolicyManager mPolicyService;
+ private static final int TIMEOUT_MS = 500;
private BroadcastInterceptingContext mServiceContext;
private WrappedConnectivityService mService;
@@ -148,14 +112,93 @@
}
}
+ /**
+ * A subclass of HandlerThread that allows callers to wait for it to become idle. waitForIdle
+ * will return immediately if the handler is already idle.
+ */
+ private class IdleableHandlerThread extends HandlerThread {
+ private IdleHandler mIdleHandler;
+
+ public IdleableHandlerThread(String name) {
+ super(name);
+ }
+
+ public void waitForIdle(int timeoutMs) {
+ final ConditionVariable cv = new ConditionVariable();
+ final MessageQueue queue = getLooper().getQueue();
+
+ synchronized (queue) {
+ if (queue.isIdle()) {
+ return;
+ }
+
+ assertNull("BUG: only one idle handler allowed", mIdleHandler);
+ mIdleHandler = new IdleHandler() {
+ public boolean queueIdle() {
+ cv.open();
+ mIdleHandler = null;
+ return false; // Remove the handler.
+ }
+ };
+ queue.addIdleHandler(mIdleHandler);
+ }
+
+ if (!cv.block(timeoutMs)) {
+ fail("HandlerThread " + getName() +
+ " did not become idle after " + timeoutMs + " ms");
+ queue.removeIdleHandler(mIdleHandler);
+ }
+ }
+ }
+
+ // Tests that IdleableHandlerThread works as expected.
+ public void testIdleableHandlerThread() {
+ final int attempts = 50; // Causes the test to take about 200ms on bullhead-eng.
+
+ // Tests that waitForIdle returns immediately if the service is already idle.
+ for (int i = 0; i < attempts; i++) {
+ mService.waitForIdle();
+ }
+
+ // Bring up a network that we can use to send messages to ConnectivityService.
+ ConditionVariable cv = waitForConnectivityBroadcasts(1);
+ mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
+ mWiFiNetworkAgent.connect(false);
+ waitFor(cv);
+ Network n = mWiFiNetworkAgent.getNetwork();
+ assertNotNull(n);
+
+ // Tests that calling waitForIdle waits for messages to be processed.
+ for (int i = 0; i < attempts; i++) {
+ mWiFiNetworkAgent.setSignalStrength(i);
+ mService.waitForIdle();
+ assertEquals(i, mCm.getNetworkCapabilities(n).getSignalStrength());
+ }
+
+ // Ensure that not calling waitForIdle causes a race condition.
+ for (int i = 0; i < attempts; i++) {
+ mWiFiNetworkAgent.setSignalStrength(i);
+ if (i != mCm.getNetworkCapabilities(n).getSignalStrength()) {
+ // We hit a race condition, as expected. Pass the test.
+ return;
+ }
+ }
+
+ // No race? There is a bug in this test.
+ fail("expected race condition at least once in " + attempts + " attempts");
+ }
+
private class MockNetworkAgent {
private final WrappedNetworkMonitor mWrappedNetworkMonitor;
private final NetworkInfo mNetworkInfo;
private final NetworkCapabilities mNetworkCapabilities;
- private final Thread mThread;
+ private final IdleableHandlerThread mHandlerThread;
private final ConditionVariable mDisconnected = new ConditionVariable();
private int mScore;
private NetworkAgent mNetworkAgent;
+ private int mStartKeepaliveError = PacketKeepalive.ERROR_HARDWARE_UNSUPPORTED;
+ private int mStopKeepaliveError = PacketKeepalive.NO_KEEPALIVE;
+ private Integer mExpectedKeepaliveSlot = null;
MockNetworkAgent(int transport) {
final int type = transportToLegacyType(transport);
@@ -173,26 +216,42 @@
default:
throw new UnsupportedOperationException("unimplemented network type");
}
- final ConditionVariable initComplete = new ConditionVariable();
- final ConditionVariable networkMonitorAvailable = mService.getNetworkMonitorCreatedCV();
- mThread = new Thread() {
- public void run() {
- Looper.prepare();
- mNetworkAgent = new NetworkAgent(Looper.myLooper(), mServiceContext,
- "Mock" + typeName, mNetworkInfo, mNetworkCapabilities,
- new LinkProperties(), mScore, new NetworkMisc()) {
- public void unwanted() { mDisconnected.open(); }
- };
- initComplete.open();
- Looper.loop();
+ mHandlerThread = new IdleableHandlerThread("Mock-" + typeName);
+ mHandlerThread.start();
+ mNetworkAgent = new NetworkAgent(mHandlerThread.getLooper(), mServiceContext,
+ "Mock-" + typeName, mNetworkInfo, mNetworkCapabilities,
+ new LinkProperties(), mScore, new NetworkMisc()) {
+ @Override
+ public void unwanted() { mDisconnected.open(); }
+
+ @Override
+ public void startPacketKeepalive(Message msg) {
+ int slot = msg.arg1;
+ if (mExpectedKeepaliveSlot != null) {
+ assertEquals((int) mExpectedKeepaliveSlot, slot);
+ }
+ onPacketKeepaliveEvent(slot, mStartKeepaliveError);
+ }
+
+ @Override
+ public void stopPacketKeepalive(Message msg) {
+ onPacketKeepaliveEvent(msg.arg1, mStopKeepaliveError);
}
};
- mThread.start();
- waitFor(initComplete);
- waitFor(networkMonitorAvailable);
+ // Waits for the NetworkAgent to be registered, which includes the creation of the
+ // NetworkMonitor.
+ mService.waitForIdle();
mWrappedNetworkMonitor = mService.getLastCreatedWrappedNetworkMonitor();
}
+ public void waitForIdle(int timeoutMs) {
+ mHandlerThread.waitForIdle(timeoutMs);
+ }
+
+ public void waitForIdle() {
+ waitForIdle(TIMEOUT_MS);
+ }
+
public void adjustScore(int change) {
mScore += change;
mNetworkAgent.sendNetworkScore(mScore);
@@ -203,6 +262,11 @@
mNetworkAgent.sendNetworkCapabilities(mNetworkCapabilities);
}
+ public void setSignalStrength(int signalStrength) {
+ mNetworkCapabilities.setSignalStrength(signalStrength);
+ mNetworkAgent.sendNetworkCapabilities(mNetworkCapabilities);
+ }
+
public void connectWithoutInternet() {
mNetworkInfo.setDetailedState(DetailedState.CONNECTED, null, null);
mNetworkAgent.sendNetworkInfo(mNetworkInfo);
@@ -272,15 +336,46 @@
public WrappedNetworkMonitor getWrappedNetworkMonitor() {
return mWrappedNetworkMonitor;
}
+
+ public void sendLinkProperties(LinkProperties lp) {
+ mNetworkAgent.sendLinkProperties(lp);
+ }
+
+ public void setStartKeepaliveError(int error) {
+ mStartKeepaliveError = error;
+ }
+
+ public void setStopKeepaliveError(int error) {
+ mStopKeepaliveError = error;
+ }
+
+ public void setExpectedKeepaliveSlot(Integer slot) {
+ mExpectedKeepaliveSlot = slot;
+ }
}
+ /**
+ * A NetworkFactory that allows tests to wait until any in-flight NetworkRequest add or remove
+ * operations have been processed. Before ConnectivityService can add or remove any requests,
+ * the factory must be told to expect those operations by calling expectAddRequests or
+ * expectRemoveRequests.
+ */
private static class MockNetworkFactory extends NetworkFactory {
private final ConditionVariable mNetworkStartedCV = new ConditionVariable();
private final ConditionVariable mNetworkStoppedCV = new ConditionVariable();
- private final ConditionVariable mNetworkRequestedCV = new ConditionVariable();
- private final ConditionVariable mNetworkReleasedCV = new ConditionVariable();
private final AtomicBoolean mNetworkStarted = new AtomicBoolean(false);
+ // Used to expect that requests be removed or added on a separate thread, without sleeping.
+ // Callers can call either expectAddRequests() or expectRemoveRequests() exactly once, then
+ // cause some other thread to add or remove requests, then call waitForRequests(). We can
+ // either expect requests to be added or removed, but not both, because CountDownLatch can
+ // only count in one direction.
+ private CountDownLatch mExpectations;
+
+ // Whether we are currently expecting requests to be added or removed. Valid only if
+ // mExpectations is non-null.
+ private boolean mExpectingAdditions;
+
public MockNetworkFactory(Looper looper, Context context, String logTag,
NetworkCapabilities filter) {
super(looper, context, logTag, filter);
@@ -314,28 +409,75 @@
return mNetworkStoppedCV;
}
- protected void needNetworkFor(NetworkRequest networkRequest, int score) {
- super.needNetworkFor(networkRequest, score);
- mNetworkRequestedCV.open();
+ @Override
+ protected void handleAddRequest(NetworkRequest request, int score) {
+ // If we're expecting anything, we must be expecting additions.
+ if (mExpectations != null && !mExpectingAdditions) {
+ fail("Can't add requests while expecting requests to be removed");
+ }
+
+ // Add the request.
+ super.handleAddRequest(request, score);
+
+ // Reduce the number of request additions we're waiting for.
+ if (mExpectingAdditions) {
+ assertTrue("Added more requests than expected", mExpectations.getCount() > 0);
+ mExpectations.countDown();
+ }
}
- protected void releaseNetworkFor(NetworkRequest networkRequest) {
- super.releaseNetworkFor(networkRequest);
- mNetworkReleasedCV.open();
+ @Override
+ protected void handleRemoveRequest(NetworkRequest request) {
+ // If we're expecting anything, we must be expecting removals.
+ if (mExpectations != null && mExpectingAdditions) {
+ fail("Can't remove requests while expecting requests to be added");
+ }
+
+ // Remove the request.
+ super.handleRemoveRequest(request);
+
+ // Reduce the number of request removals we're waiting for.
+ if (!mExpectingAdditions) {
+ assertTrue("Removed more requests than expected", mExpectations.getCount() > 0);
+ mExpectations.countDown();
+ }
}
- public ConditionVariable getNetworkRequestedCV() {
- mNetworkRequestedCV.close();
- return mNetworkRequestedCV;
+ private void assertNoExpectations() {
+ if (mExpectations != null) {
+ fail("Can't add expectation, " + mExpectations.getCount() + " already pending");
+ }
}
- public ConditionVariable getNetworkReleasedCV() {
- mNetworkReleasedCV.close();
- return mNetworkReleasedCV;
+ // Expects that count requests will be added.
+ public void expectAddRequests(final int count) {
+ assertNoExpectations();
+ mExpectingAdditions = true;
+ mExpectations = new CountDownLatch(count);
}
- public void waitForNetworkRequests(final int count) {
- waitFor(new Criteria() { public boolean get() { return count == getRequestCount(); } });
+ // Expects that count requests will be removed.
+ public void expectRemoveRequests(final int count) {
+ assertNoExpectations();
+ mExpectingAdditions = false;
+ mExpectations = new CountDownLatch(count);
+ }
+
+ // Waits for the expected request additions or removals to happen within a timeout.
+ public void waitForRequests() throws InterruptedException {
+ assertNotNull("Nothing to wait for", mExpectations);
+ mExpectations.await(TIMEOUT_MS, TimeUnit.MILLISECONDS);
+ final long count = mExpectations.getCount();
+ final String msg = count + " requests still not " +
+ (mExpectingAdditions ? "added" : "removed") +
+ " after " + TIMEOUT_MS + " ms";
+ assertEquals(msg, 0, count);
+ mExpectations = null;
+ }
+
+ public void waitForNetworkRequests(final int count) throws InterruptedException {
+ waitForRequests();
+ assertEquals(count, getMyRequestCount());
}
}
@@ -356,7 +498,6 @@
}
private class WrappedConnectivityService extends ConnectivityService {
- private final ConditionVariable mNetworkMonitorCreated = new ConditionVariable();
private WrappedNetworkMonitor mLastCreatedNetworkMonitor;
public WrappedConnectivityService(Context context, INetworkManagementService netManager,
@@ -365,6 +506,11 @@
}
@Override
+ protected HandlerThread createHandlerThread() {
+ return new IdleableHandlerThread("WrappedConnectivityService");
+ }
+
+ @Override
protected int getDefaultTcpRwnd() {
// Prevent wrapped ConnectivityService from trying to write to SystemProperties.
return 0;
@@ -397,7 +543,6 @@
final WrappedNetworkMonitor monitor = new WrappedNetworkMonitor(context, handler, nai,
defaultRequest);
mLastCreatedNetworkMonitor = monitor;
- mNetworkMonitorCreated.open();
return monitor;
}
@@ -405,10 +550,14 @@
return mLastCreatedNetworkMonitor;
}
- public ConditionVariable getNetworkMonitorCreatedCV() {
- mNetworkMonitorCreated.close();
- return mNetworkMonitorCreated;
+ public void waitForIdle(int timeoutMs) {
+ ((IdleableHandlerThread) mHandlerThread).waitForIdle(timeoutMs);
}
+
+ public void waitForIdle() {
+ waitForIdle(TIMEOUT_MS);
+ }
+
}
private interface Criteria {
@@ -431,23 +580,11 @@
}
/**
- * Wait up to 500ms for {@code conditonVariable} to open.
- * Fails if 500ms goes by before {@code conditionVariable} opens.
+ * Wait up to TIMEOUT_MS for {@code conditionVariable} to open.
+ * Fails if TIMEOUT_MS goes by before {@code conditionVariable} opens.
*/
static private void waitFor(ConditionVariable conditionVariable) {
- assertTrue(conditionVariable.block(500));
- }
-
- /**
- * This should only be used to verify that nothing happens, in other words that no unexpected
- * changes occur. It should never be used to wait for a specific positive signal to occur.
- */
- private void shortSleep() {
- // TODO: Instead of sleeping, instead wait for all message loops to idle.
- try {
- Thread.sleep(500);
- } catch (InterruptedException e) {
- }
+ assertTrue(conditionVariable.block(TIMEOUT_MS));
}
@Override
@@ -455,13 +592,11 @@
super.setUp();
mServiceContext = new MockContext(getContext());
+ mService = new WrappedConnectivityService(mServiceContext,
+ mock(INetworkManagementService.class),
+ mock(INetworkStatsService.class),
+ mock(INetworkPolicyManager.class));
- mNetManager = mock(INetworkManagementService.class);
- mStatsService = mock(INetworkStatsService.class);
- mPolicyService = mock(INetworkPolicyManager.class);
-
- mService = new WrappedConnectivityService(
- mServiceContext, mNetManager, mStatsService, mPolicyService);
mService.systemReady();
mCm = new ConnectivityManager(getContext(), mService);
}
@@ -583,11 +718,11 @@
// Test bringing up unvalidated cellular
mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
mCellNetworkAgent.connect(false);
- shortSleep();
+ mService.waitForIdle();
verifyActiveNetwork(TRANSPORT_WIFI);
// Test cellular disconnect.
mCellNetworkAgent.disconnect();
- shortSleep();
+ mService.waitForIdle();
verifyActiveNetwork(TRANSPORT_WIFI);
// Test bringing up validated cellular
mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
@@ -797,6 +932,11 @@
LOST
}
+ /**
+ * Utility NetworkCallback for testing. The caller must explicitly test for all the callbacks
+ * this class receives, by calling expectCallback() exactly once each time a callback is
+ * received. assertNoCallback may be called at any time.
+ */
private class TestNetworkCallback extends NetworkCallback {
private final ConditionVariable mConditionVariable = new ConditionVariable();
private CallbackState mLastCallback = CallbackState.NONE;
@@ -819,14 +959,15 @@
mConditionVariable.open();
}
- ConditionVariable getConditionVariable() {
+ void expectCallback(CallbackState state) {
+ waitFor(mConditionVariable);
+ assertEquals(state, mLastCallback);
mLastCallback = CallbackState.NONE;
mConditionVariable.close();
- return mConditionVariable;
}
- CallbackState getLastCallback() {
- return mLastCallback;
+ void assertNoCallback() {
+ assertEquals(CallbackState.NONE, mLastCallback);
}
}
@@ -842,98 +983,68 @@
mCm.registerNetworkCallback(cellRequest, cellNetworkCallback);
// Test unvalidated networks
- ConditionVariable cellCv = cellNetworkCallback.getConditionVariable();
- ConditionVariable wifiCv = wifiNetworkCallback.getConditionVariable();
ConditionVariable cv = waitForConnectivityBroadcasts(1);
mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
mCellNetworkAgent.connect(false);
- waitFor(cellCv);
- assertEquals(CallbackState.AVAILABLE, cellNetworkCallback.getLastCallback());
- assertEquals(CallbackState.NONE, wifiNetworkCallback.getLastCallback());
+ cellNetworkCallback.expectCallback(CallbackState.AVAILABLE);
+ wifiNetworkCallback.assertNoCallback();
assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork());
waitFor(cv);
- cellCv = cellNetworkCallback.getConditionVariable();
- wifiCv = wifiNetworkCallback.getConditionVariable();
// This should not trigger spurious onAvailable() callbacks, b/21762680.
mCellNetworkAgent.adjustScore(-1);
- shortSleep();
- assertEquals(CallbackState.NONE, wifiNetworkCallback.getLastCallback());
- assertEquals(CallbackState.NONE, cellNetworkCallback.getLastCallback());
+ mService.waitForIdle();
+ wifiNetworkCallback.assertNoCallback();
+ cellNetworkCallback.assertNoCallback();
assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork());
- cellCv = cellNetworkCallback.getConditionVariable();
- wifiCv = wifiNetworkCallback.getConditionVariable();
cv = waitForConnectivityBroadcasts(2);
mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
mWiFiNetworkAgent.connect(false);
- waitFor(wifiCv);
- assertEquals(CallbackState.AVAILABLE, wifiNetworkCallback.getLastCallback());
- assertEquals(CallbackState.NONE, cellNetworkCallback.getLastCallback());
+ wifiNetworkCallback.expectCallback(CallbackState.AVAILABLE);
+ cellNetworkCallback.assertNoCallback();
assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork());
waitFor(cv);
- cellCv = cellNetworkCallback.getConditionVariable();
- wifiCv = wifiNetworkCallback.getConditionVariable();
cv = waitForConnectivityBroadcasts(2);
mWiFiNetworkAgent.disconnect();
- waitFor(wifiCv);
- assertEquals(CallbackState.LOST, wifiNetworkCallback.getLastCallback());
- assertEquals(CallbackState.NONE, cellNetworkCallback.getLastCallback());
+ wifiNetworkCallback.expectCallback(CallbackState.LOST);
+ cellNetworkCallback.assertNoCallback();
waitFor(cv);
- cellCv = cellNetworkCallback.getConditionVariable();
- wifiCv = wifiNetworkCallback.getConditionVariable();
cv = waitForConnectivityBroadcasts(1);
mCellNetworkAgent.disconnect();
- waitFor(cellCv);
- assertEquals(CallbackState.LOST, cellNetworkCallback.getLastCallback());
- assertEquals(CallbackState.NONE, wifiNetworkCallback.getLastCallback());
+ cellNetworkCallback.expectCallback(CallbackState.LOST);
+ wifiNetworkCallback.assertNoCallback();
waitFor(cv);
// Test validated networks
-
- cellCv = cellNetworkCallback.getConditionVariable();
- wifiCv = wifiNetworkCallback.getConditionVariable();
mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
mCellNetworkAgent.connect(true);
- waitFor(cellCv);
- assertEquals(CallbackState.AVAILABLE, cellNetworkCallback.getLastCallback());
- assertEquals(CallbackState.NONE, wifiNetworkCallback.getLastCallback());
+ cellNetworkCallback.expectCallback(CallbackState.AVAILABLE);
+ wifiNetworkCallback.assertNoCallback();
assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork());
- cellCv = cellNetworkCallback.getConditionVariable();
- wifiCv = wifiNetworkCallback.getConditionVariable();
// This should not trigger spurious onAvailable() callbacks, b/21762680.
mCellNetworkAgent.adjustScore(-1);
- shortSleep();
- assertEquals(CallbackState.NONE, wifiNetworkCallback.getLastCallback());
- assertEquals(CallbackState.NONE, cellNetworkCallback.getLastCallback());
+ mService.waitForIdle();
+ wifiNetworkCallback.assertNoCallback();
+ cellNetworkCallback.assertNoCallback();
assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork());
- cellCv = cellNetworkCallback.getConditionVariable();
- wifiCv = wifiNetworkCallback.getConditionVariable();
mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
mWiFiNetworkAgent.connect(true);
- waitFor(wifiCv);
- assertEquals(CallbackState.AVAILABLE, wifiNetworkCallback.getLastCallback());
- waitFor(cellCv);
- assertEquals(CallbackState.LOSING, cellNetworkCallback.getLastCallback());
+ wifiNetworkCallback.expectCallback(CallbackState.AVAILABLE);
+ cellNetworkCallback.expectCallback(CallbackState.LOSING);
assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork());
- cellCv = cellNetworkCallback.getConditionVariable();
- wifiCv = wifiNetworkCallback.getConditionVariable();
mWiFiNetworkAgent.disconnect();
- waitFor(wifiCv);
- assertEquals(CallbackState.LOST, wifiNetworkCallback.getLastCallback());
- assertEquals(CallbackState.NONE, cellNetworkCallback.getLastCallback());
+ wifiNetworkCallback.expectCallback(CallbackState.LOST);
+ cellNetworkCallback.assertNoCallback();
- cellCv = cellNetworkCallback.getConditionVariable();
- wifiCv = wifiNetworkCallback.getConditionVariable();
mCellNetworkAgent.disconnect();
- waitFor(cellCv);
- assertEquals(CallbackState.LOST, cellNetworkCallback.getLastCallback());
- assertEquals(CallbackState.NONE, wifiNetworkCallback.getLastCallback());
+ cellNetworkCallback.expectCallback(CallbackState.LOST);
+ wifiNetworkCallback.assertNoCallback();
}
private void tryNetworkFactoryRequests(int capability) throws Exception {
@@ -957,18 +1068,21 @@
mServiceContext, "testFactory", filter);
testFactory.setScoreFilter(40);
ConditionVariable cv = testFactory.getNetworkStartedCV();
+ testFactory.expectAddRequests(1);
testFactory.register();
+ testFactory.waitForNetworkRequests(1);
int expectedRequestCount = 1;
NetworkCallback networkCallback = null;
// For non-INTERNET capabilities we cannot rely on the default request being present, so
// add one.
if (capability != NET_CAPABILITY_INTERNET) {
- testFactory.waitForNetworkRequests(1);
assertFalse(testFactory.getMyStartRequested());
NetworkRequest request = new NetworkRequest.Builder().addCapability(capability).build();
networkCallback = new NetworkCallback();
+ testFactory.expectAddRequests(1);
mCm.requestNetwork(request, networkCallback);
expectedRequestCount++;
+ testFactory.waitForNetworkRequests(expectedRequestCount);
}
waitFor(cv);
assertEquals(expectedRequestCount, testFactory.getMyRequestCount());
@@ -981,13 +1095,20 @@
// unvalidated penalty.
testAgent.adjustScore(40);
cv = testFactory.getNetworkStoppedCV();
+
+ // When testAgent connects, ConnectivityService will re-send us all current requests with
+ // the new score. There are expectedRequestCount such requests, and we must wait for all of
+ // them.
+ testFactory.expectAddRequests(expectedRequestCount);
testAgent.connect(false);
testAgent.addCapability(capability);
waitFor(cv);
- assertEquals(expectedRequestCount, testFactory.getMyRequestCount());
+ testFactory.waitForNetworkRequests(expectedRequestCount);
assertFalse(testFactory.getMyStartRequested());
// Bring in a bunch of requests.
+ testFactory.expectAddRequests(10);
+ assertEquals(expectedRequestCount, testFactory.getMyRequestCount());
ConnectivityManager.NetworkCallback[] networkCallbacks =
new ConnectivityManager.NetworkCallback[10];
for (int i = 0; i< networkCallbacks.length; i++) {
@@ -1000,6 +1121,7 @@
assertFalse(testFactory.getMyStartRequested());
// Remove the requests.
+ testFactory.expectRemoveRequests(10);
for (int i = 0; i < networkCallbacks.length; i++) {
mCm.unregisterNetworkCallback(networkCallbacks[i]);
}
@@ -1088,10 +1210,8 @@
// Test bringing up unvalidated cellular with MMS
mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
mCellNetworkAgent.addCapability(NET_CAPABILITY_MMS);
- cv = networkCallback.getConditionVariable();
mCellNetworkAgent.connectWithoutInternet();
- waitFor(cv);
- assertEquals(CallbackState.AVAILABLE, networkCallback.getLastCallback());
+ networkCallback.expectCallback(CallbackState.AVAILABLE);
verifyActiveNetwork(TRANSPORT_WIFI);
// Test releasing NetworkRequest disconnects cellular with MMS
cv = mCellNetworkAgent.getDisconnectedCV();
@@ -1114,12 +1234,10 @@
final TestNetworkCallback networkCallback = new TestNetworkCallback();
mCm.requestNetwork(builder.build(), networkCallback);
// Test bringing up MMS cellular network
- cv = networkCallback.getConditionVariable();
MockNetworkAgent mmsNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
mmsNetworkAgent.addCapability(NET_CAPABILITY_MMS);
mmsNetworkAgent.connectWithoutInternet();
- waitFor(cv);
- assertEquals(CallbackState.AVAILABLE, networkCallback.getLastCallback());
+ networkCallback.expectCallback(CallbackState.AVAILABLE);
verifyActiveNetwork(TRANSPORT_CELLULAR);
// Test releasing MMS NetworkRequest does not disconnect main cellular NetworkAgent
cv = mmsNetworkAgent.getDisconnectedCV();
@@ -1139,133 +1257,245 @@
final NetworkRequest validatedRequest = new NetworkRequest.Builder()
.addCapability(NET_CAPABILITY_VALIDATED).build();
mCm.registerNetworkCallback(validatedRequest, validatedCallback);
- ConditionVariable validatedCv = validatedCallback.getConditionVariable();
// Bring up a network with a captive portal.
// Expect onAvailable callback of listen for NET_CAPABILITY_CAPTIVE_PORTAL.
- ConditionVariable cv = captivePortalCallback.getConditionVariable();
mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
mWiFiNetworkAgent.connectWithCaptivePortal();
- waitFor(cv);
- assertEquals(CallbackState.AVAILABLE, captivePortalCallback.getLastCallback());
+ captivePortalCallback.expectCallback(CallbackState.AVAILABLE);
// Take down network.
// Expect onLost callback.
- cv = captivePortalCallback.getConditionVariable();
mWiFiNetworkAgent.disconnect();
- waitFor(cv);
- assertEquals(CallbackState.LOST, captivePortalCallback.getLastCallback());
+ captivePortalCallback.expectCallback(CallbackState.LOST);
// Bring up a network with a captive portal.
// Expect onAvailable callback of listen for NET_CAPABILITY_CAPTIVE_PORTAL.
- cv = captivePortalCallback.getConditionVariable();
mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
mWiFiNetworkAgent.connectWithCaptivePortal();
- waitFor(cv);
- assertEquals(CallbackState.AVAILABLE, captivePortalCallback.getLastCallback());
+ captivePortalCallback.expectCallback(CallbackState.AVAILABLE);
// Make captive portal disappear then revalidate.
// Expect onLost callback because network no longer provides NET_CAPABILITY_CAPTIVE_PORTAL.
- cv = captivePortalCallback.getConditionVariable();
mWiFiNetworkAgent.getWrappedNetworkMonitor().gen204ProbeResult = 204;
mCm.reportNetworkConnectivity(mWiFiNetworkAgent.getNetwork(), true);
- waitFor(cv);
- assertEquals(CallbackState.LOST, captivePortalCallback.getLastCallback());
+ captivePortalCallback.expectCallback(CallbackState.LOST);
// Expect NET_CAPABILITY_VALIDATED onAvailable callback.
- waitFor(validatedCv);
- assertEquals(CallbackState.AVAILABLE, validatedCallback.getLastCallback());
+ validatedCallback.expectCallback(CallbackState.AVAILABLE);
// Break network connectivity.
// Expect NET_CAPABILITY_VALIDATED onLost callback.
- validatedCv = validatedCallback.getConditionVariable();
mWiFiNetworkAgent.getWrappedNetworkMonitor().gen204ProbeResult = 500;
mCm.reportNetworkConnectivity(mWiFiNetworkAgent.getNetwork(), false);
- waitFor(validatedCv);
- assertEquals(CallbackState.LOST, validatedCallback.getLastCallback());
+ validatedCallback.expectCallback(CallbackState.LOST);
}
-// @Override
-// public void tearDown() throws Exception {
-// super.tearDown();
-// }
-//
-// public void testMobileConnectedAddedRoutes() throws Exception {
-// Future<?> nextConnBroadcast;
-//
-// // bring up mobile network
-// mMobile.info.setDetailedState(DetailedState.CONNECTED, null, null);
-// mMobile.link.setInterfaceName(MOBILE_IFACE);
-// mMobile.link.addRoute(MOBILE_ROUTE_V4);
-// mMobile.link.addRoute(MOBILE_ROUTE_V6);
-// mMobile.doReturnDefaults();
-//
-// cv = waitForConnectivityBroadcasts(1);
-// mTrackerHandler.obtainMessage(EVENT_STATE_CHANGED, mMobile.info).sendToTarget();
-// waitFor(cv);
-//
-// // verify that both routes were added
-// int mobileNetId = mMobile.tracker.getNetwork().netId;
-// verify(mNetManager).addRoute(eq(mobileNetId), eq(MOBILE_ROUTE_V4));
-// verify(mNetManager).addRoute(eq(mobileNetId), eq(MOBILE_ROUTE_V6));
-// }
-//
-// public void testMobileWifiHandoff() throws Exception {
-// Future<?> nextConnBroadcast;
-//
-// // bring up mobile network
-// mMobile.info.setDetailedState(DetailedState.CONNECTED, null, null);
-// mMobile.link.setInterfaceName(MOBILE_IFACE);
-// mMobile.link.addRoute(MOBILE_ROUTE_V4);
-// mMobile.link.addRoute(MOBILE_ROUTE_V6);
-// mMobile.doReturnDefaults();
-//
-// cv = waitForConnectivityBroadcasts(1);
-// mTrackerHandler.obtainMessage(EVENT_STATE_CHANGED, mMobile.info).sendToTarget();
-// waitFor(cv);
-//
-// reset(mNetManager);
-//
-// // now bring up wifi network
-// mWifi.info.setDetailedState(DetailedState.CONNECTED, null, null);
-// mWifi.link.setInterfaceName(WIFI_IFACE);
-// mWifi.link.addRoute(WIFI_ROUTE_V4);
-// mWifi.link.addRoute(WIFI_ROUTE_V6);
-// mWifi.doReturnDefaults();
-//
-// // expect that mobile will be torn down
-// doReturn(true).when(mMobile.tracker).teardown();
-//
-// cv = waitForConnectivityBroadcasts(1);
-// mTrackerHandler.obtainMessage(EVENT_STATE_CHANGED, mWifi.info).sendToTarget();
-// waitFor(cv);
-//
-// // verify that wifi routes added, and teardown requested
-// int wifiNetId = mWifi.tracker.getNetwork().netId;
-// verify(mNetManager).addRoute(eq(wifiNetId), eq(WIFI_ROUTE_V4));
-// verify(mNetManager).addRoute(eq(wifiNetId), eq(WIFI_ROUTE_V6));
-// verify(mMobile.tracker).teardown();
-//
-// int mobileNetId = mMobile.tracker.getNetwork().netId;
-//
-// reset(mNetManager, mMobile.tracker);
-//
-// // tear down mobile network, as requested
-// mMobile.info.setDetailedState(DetailedState.DISCONNECTED, null, null);
-// mMobile.link.clear();
-// mMobile.doReturnDefaults();
-//
-// cv = waitForConnectivityBroadcasts(1);
-// mTrackerHandler.obtainMessage(EVENT_STATE_CHANGED, mMobile.info).sendToTarget();
-// waitFor(cv);
-//
-// verify(mNetManager).removeRoute(eq(mobileNetId), eq(MOBILE_ROUTE_V4));
-// verify(mNetManager).removeRoute(eq(mobileNetId), eq(MOBILE_ROUTE_V6));
-//
-// }
+ private static class TestKeepaliveCallback extends PacketKeepaliveCallback {
- private static InetAddress parse(String addr) {
- return InetAddress.parseNumericAddress(addr);
+ public static enum CallbackType { ON_STARTED, ON_STOPPED, ON_ERROR };
+
+ private class CallbackValue {
+ public CallbackType callbackType;
+ public int error;
+
+ public CallbackValue(CallbackType type) {
+ this.callbackType = type;
+ this.error = PacketKeepalive.SUCCESS;
+ assertTrue("onError callback must have error", type != CallbackType.ON_ERROR);
+ }
+
+ public CallbackValue(CallbackType type, int error) {
+ this.callbackType = type;
+ this.error = error;
+ assertEquals("error can only be set for onError", type, CallbackType.ON_ERROR);
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ return o instanceof CallbackValue &&
+ this.callbackType == ((CallbackValue) o).callbackType &&
+ this.error == ((CallbackValue) o).error;
+ }
+
+ @Override
+ public String toString() {
+ return String.format("%s(%s, %d)", getClass().getSimpleName(), callbackType, error);
+ }
+ }
+
+ private LinkedBlockingQueue<CallbackValue> mCallbacks = new LinkedBlockingQueue<>();
+
+ @Override
+ public void onStarted() {
+ mCallbacks.add(new CallbackValue(CallbackType.ON_STARTED));
+ }
+
+ @Override
+ public void onStopped() {
+ mCallbacks.add(new CallbackValue(CallbackType.ON_STOPPED));
+ }
+
+ @Override
+ public void onError(int error) {
+ mCallbacks.add(new CallbackValue(CallbackType.ON_ERROR, error));
+ }
+
+ private void expectCallback(CallbackValue callbackValue) {
+ try {
+ assertEquals(
+ callbackValue,
+ mCallbacks.poll(TIMEOUT_MS, TimeUnit.MILLISECONDS));
+ } catch (InterruptedException e) {
+ fail(callbackValue.callbackType + " callback not seen after " + TIMEOUT_MS + " ms");
+ }
+ }
+
+ public void expectStarted() {
+ expectCallback(new CallbackValue(CallbackType.ON_STARTED));
+ }
+
+ public void expectStopped() {
+ expectCallback(new CallbackValue(CallbackType.ON_STOPPED));
+ }
+
+ public void expectError(int error) {
+ expectCallback(new CallbackValue(CallbackType.ON_ERROR, error));
+ }
}
+ private Network connectKeepaliveNetwork(LinkProperties lp) {
+ // Ensure the network is disconnected before we do anything.
+ if (mWiFiNetworkAgent != null) {
+ assertNull(mCm.getNetworkCapabilities(mWiFiNetworkAgent.getNetwork()));
+ }
+
+ mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
+ ConditionVariable cv = waitForConnectivityBroadcasts(1);
+ mWiFiNetworkAgent.connect(true);
+ waitFor(cv);
+ verifyActiveNetwork(TRANSPORT_WIFI);
+ mWiFiNetworkAgent.sendLinkProperties(lp);
+ mService.waitForIdle();
+ return mWiFiNetworkAgent.getNetwork();
+ }
+
+ public void testPacketKeepalives() throws Exception {
+ InetAddress myIPv4 = InetAddress.getByName("192.0.2.129");
+ InetAddress notMyIPv4 = InetAddress.getByName("192.0.2.35");
+ InetAddress myIPv6 = InetAddress.getByName("2001:db8::1");
+ InetAddress dstIPv4 = InetAddress.getByName("8.8.8.8");
+ InetAddress dstIPv6 = InetAddress.getByName("2001:4860:4860::8888");
+
+ LinkProperties lp = new LinkProperties();
+ lp.setInterfaceName("wlan12");
+ lp.addLinkAddress(new LinkAddress(myIPv6, 64));
+ lp.addLinkAddress(new LinkAddress(myIPv4, 25));
+ lp.addRoute(new RouteInfo(InetAddress.getByName("fe80::1234")));
+ lp.addRoute(new RouteInfo(InetAddress.getByName("192.0.2.254")));
+
+ Network notMyNet = new Network(61234);
+ Network myNet = connectKeepaliveNetwork(lp);
+
+ TestKeepaliveCallback callback = new TestKeepaliveCallback();
+ PacketKeepalive ka;
+
+ // Attempt to start keepalives with invalid parameters and check for errors.
+ ka = mCm.startNattKeepalive(notMyNet, 25, callback, myIPv4, 1234, dstIPv4);
+ callback.expectError(PacketKeepalive.ERROR_INVALID_NETWORK);
+
+ ka = mCm.startNattKeepalive(myNet, 19, callback, notMyIPv4, 1234, dstIPv4);
+ callback.expectError(PacketKeepalive.ERROR_INVALID_INTERVAL);
+
+ ka = mCm.startNattKeepalive(myNet, 25, callback, myIPv4, 1234, dstIPv6);
+ callback.expectError(PacketKeepalive.ERROR_INVALID_IP_ADDRESS);
+
+ ka = mCm.startNattKeepalive(myNet, 25, callback, myIPv6, 1234, dstIPv4);
+ callback.expectError(PacketKeepalive.ERROR_INVALID_IP_ADDRESS);
+
+ ka = mCm.startNattKeepalive(myNet, 25, callback, myIPv6, 1234, dstIPv6);
+ callback.expectError(PacketKeepalive.ERROR_INVALID_IP_ADDRESS); // NAT-T is IPv4-only.
+
+ ka = mCm.startNattKeepalive(myNet, 25, callback, myIPv4, 123456, dstIPv4);
+ callback.expectError(PacketKeepalive.ERROR_INVALID_PORT);
+
+ ka = mCm.startNattKeepalive(myNet, 25, callback, myIPv4, 123456, dstIPv4);
+ callback.expectError(PacketKeepalive.ERROR_INVALID_PORT);
+
+ ka = mCm.startNattKeepalive(myNet, 25, callback, myIPv4, 12345, dstIPv4);
+ callback.expectError(PacketKeepalive.ERROR_HARDWARE_UNSUPPORTED);
+
+ ka = mCm.startNattKeepalive(myNet, 25, callback, myIPv4, 12345, dstIPv4);
+ callback.expectError(PacketKeepalive.ERROR_HARDWARE_UNSUPPORTED);
+
+ // Check that a started keepalive can be stopped.
+ mWiFiNetworkAgent.setStartKeepaliveError(PacketKeepalive.SUCCESS);
+ ka = mCm.startNattKeepalive(myNet, 25, callback, myIPv4, 12345, dstIPv4);
+ callback.expectStarted();
+ mWiFiNetworkAgent.setStopKeepaliveError(PacketKeepalive.SUCCESS);
+ ka.stop();
+ callback.expectStopped();
+
+ // Check that deleting the IP address stops the keepalive.
+ LinkProperties bogusLp = new LinkProperties(lp);
+ ka = mCm.startNattKeepalive(myNet, 25, callback, myIPv4, 12345, dstIPv4);
+ callback.expectStarted();
+ bogusLp.removeLinkAddress(new LinkAddress(myIPv4, 25));
+ bogusLp.addLinkAddress(new LinkAddress(notMyIPv4, 25));
+ mWiFiNetworkAgent.sendLinkProperties(bogusLp);
+ callback.expectError(PacketKeepalive.ERROR_INVALID_IP_ADDRESS);
+ mWiFiNetworkAgent.sendLinkProperties(lp);
+
+ // Check that a started keepalive is stopped correctly when the network disconnects.
+ ka = mCm.startNattKeepalive(myNet, 25, callback, myIPv4, 12345, dstIPv4);
+ callback.expectStarted();
+ mWiFiNetworkAgent.disconnect();
+ callback.expectError(PacketKeepalive.ERROR_INVALID_NETWORK);
+
+ // ... and that stopping it after that has no adverse effects.
+ assertNull(mCm.getNetworkCapabilities(myNet));
+ ka.stop();
+
+ // Reconnect.
+ myNet = connectKeepaliveNetwork(lp);
+ mWiFiNetworkAgent.setStartKeepaliveError(PacketKeepalive.SUCCESS);
+
+ // Check things work as expected when the keepalive is stopped and the network disconnects.
+ ka = mCm.startNattKeepalive(myNet, 25, callback, myIPv4, 12345, dstIPv4);
+ callback.expectStarted();
+ ka.stop();
+ mWiFiNetworkAgent.disconnect();
+ mService.waitForIdle();
+ callback.expectStopped();
+
+ // Reconnect.
+ myNet = connectKeepaliveNetwork(lp);
+ mWiFiNetworkAgent.setStartKeepaliveError(PacketKeepalive.SUCCESS);
+
+ // Check that keepalive slots start from 1 and increment. The first one gets slot 1.
+ mWiFiNetworkAgent.setExpectedKeepaliveSlot(1);
+ ka = mCm.startNattKeepalive(myNet, 25, callback, myIPv4, 12345, dstIPv4);
+ callback.expectStarted();
+
+ // The second one gets slot 2.
+ mWiFiNetworkAgent.setExpectedKeepaliveSlot(2);
+ TestKeepaliveCallback callback2 = new TestKeepaliveCallback();
+ PacketKeepalive ka2 = mCm.startNattKeepalive(myNet, 25, callback2, myIPv4, 6789, dstIPv4);
+ callback2.expectStarted();
+
+ // Now stop the first one and create a third. This also gets slot 1.
+ ka.stop();
+ callback.expectStopped();
+
+ mWiFiNetworkAgent.setExpectedKeepaliveSlot(1);
+ TestKeepaliveCallback callback3 = new TestKeepaliveCallback();
+ PacketKeepalive ka3 = mCm.startNattKeepalive(myNet, 25, callback3, myIPv4, 9876, dstIPv4);
+ callback3.expectStarted();
+
+ ka2.stop();
+ callback2.expectStopped();
+
+ ka3.stop();
+ callback3.expectStopped();
+ }
}
diff --git a/services/tests/servicestests/src/com/android/server/job/JobStoreTest.java b/services/tests/servicestests/src/com/android/server/job/JobStoreTest.java
index bd64392..0b73beb 100644
--- a/services/tests/servicestests/src/com/android/server/job/JobStoreTest.java
+++ b/services/tests/servicestests/src/com/android/server/job/JobStoreTest.java
@@ -6,6 +6,7 @@
import android.app.job.JobInfo;
import android.app.job.JobInfo.Builder;
import android.os.PersistableBundle;
+import android.os.SystemClock;
import android.test.AndroidTestCase;
import android.test.RenamingDelegatingContext;
import android.util.Log;
@@ -102,6 +103,14 @@
Iterator<JobStatus> it = jobStatusSet.iterator();
JobStatus loaded1 = it.next();
JobStatus loaded2 = it.next();
+
+ // Reverse them so we know which comparison to make.
+ if (loaded1.getJobId() != 8) {
+ JobStatus tmp = loaded1;
+ loaded1 = loaded2;
+ loaded2 = tmp;
+ }
+
assertTasksEqual(task1, loaded1.getJob());
assertTasksEqual(task2, loaded2.getJob());
assertTrue("JobStore#contains invalid.", mTaskStoreUnderTest.containsJob(taskStatus1));
@@ -143,6 +152,36 @@
assertTasksEqual(task, loaded.getJob());
}
+ public void testMassivePeriodClampedOnRead() throws Exception {
+ final long TEN_SECONDS = 10000L;
+ JobInfo.Builder b = new Builder(8, mComponent)
+ .setPeriodic(TEN_SECONDS)
+ .setPersisted(true);
+ final long invalidLateRuntimeElapsedMillis =
+ SystemClock.elapsedRealtime() + (TEN_SECONDS * 2) + 5000; // >2P from now.
+ final long invalidEarlyRuntimeElapsedMillis =
+ invalidLateRuntimeElapsedMillis - TEN_SECONDS; // Early is (late - period).
+ final JobStatus js = new JobStatus(b.build(), SOME_UID,
+ invalidEarlyRuntimeElapsedMillis, invalidLateRuntimeElapsedMillis);
+
+ mTaskStoreUnderTest.add(js);
+ Thread.sleep(IO_WAIT);
+
+ final ArraySet<JobStatus> jobStatusSet = new ArraySet<JobStatus>();
+ mTaskStoreUnderTest.readJobMapFromDisk(jobStatusSet);
+ assertEquals("Incorrect # of persisted tasks.", 1, jobStatusSet.size());
+ JobStatus loaded = jobStatusSet.iterator().next();
+
+ // Assert early runtime was clamped to be under now + period. We can do <= here b/c we'll
+ // call SystemClock.elapsedRealtime after doing the disk i/o.
+ final long newNowElapsed = SystemClock.elapsedRealtime();
+ assertTrue("Early runtime wasn't correctly clamped.",
+ loaded.getEarliestRunTime() <= newNowElapsed + TEN_SECONDS);
+ // Assert late runtime was clamped to be now + period*2.
+ assertTrue("Early runtime wasn't correctly clamped.",
+ loaded.getEarliestRunTime() <= newNowElapsed + TEN_SECONDS*2);
+ }
+
/**
* Helper function to throw an error if the provided task and TaskStatus objects are not equal.
*/
diff --git a/services/usage/java/com/android/server/usage/UsageStatsService.java b/services/usage/java/com/android/server/usage/UsageStatsService.java
index 4146c1c0..583bac2 100644
--- a/services/usage/java/com/android/server/usage/UsageStatsService.java
+++ b/services/usage/java/com/android/server/usage/UsageStatsService.java
@@ -123,6 +123,7 @@
static final int MSG_PAROLE_END_TIMEOUT = 7;
static final int MSG_REPORT_CONTENT_PROVIDER_USAGE = 8;
static final int MSG_PAROLE_STATE_CHANGED = 9;
+ static final int MSG_ONE_TIME_CHECK_IDLE_STATES = 10;
private final Object mLock = new Object();
Handler mHandler;
@@ -144,8 +145,10 @@
private boolean mScreenOn;
private long mLastAppIdleParoledTime;
+ private volatile boolean mPendingOneTimeCheckIdleStates;
+
long mScreenOnTime;
- long mScreenOnSystemTimeSnapshot;
+ long mLastScreenOnEventRealtime;
@GuardedBy("mLock")
private AppIdleHistory mAppIdleHistory = new AppIdleHistory();
@@ -188,6 +191,8 @@
synchronized (mLock) {
cleanUpRemovedUsersLocked();
+ mLastScreenOnEventRealtime = SystemClock.elapsedRealtime();
+ mScreenOnTime = readScreenOnTimeLocked();
}
mRealTimeSnapshot = SystemClock.elapsedRealtime();
@@ -214,14 +219,14 @@
Context.DISPLAY_SERVICE);
mPowerManager = getContext().getSystemService(PowerManager.class);
- mScreenOnSystemTimeSnapshot = System.currentTimeMillis();
- synchronized (this) {
- mScreenOnTime = readScreenOnTimeLocked();
- }
mDisplayManager.registerDisplayListener(mDisplayListener, null);
synchronized (this) {
updateDisplayLocked();
}
+
+ if (mPendingOneTimeCheckIdleStates) {
+ postOneTimeCheckIdleStates();
+ }
} else if (phase == PHASE_BOOT_COMPLETED) {
setAppIdleParoled(getContext().getSystemService(BatteryManager.class).isCharging());
}
@@ -280,6 +285,16 @@
mHandler.sendEmptyMessageDelayed(MSG_FLUSH_TO_DISK, FLUSH_INTERVAL);
}
+ @Override
+ public void onStatsReloaded() {
+ postOneTimeCheckIdleStates();
+ }
+
+ @Override
+ public long getAppIdleRollingWindowDurationMillis() {
+ return mAppIdleWallclockThresholdMillis * 2;
+ }
+
private void cleanUpRemovedUsersLocked() {
final List<UserInfo> users = mUserManager.getUsers(true);
if (users == null || users.size() == 0) {
@@ -314,6 +329,8 @@
mAppIdleParoled = paroled;
if (DEBUG) Slog.d(TAG, "Changing paroled to " + mAppIdleParoled);
if (paroled) {
+ postParoleEndTimeout();
+ } else {
mLastAppIdleParoledTime = checkAndGetTimeLocked();
postNextParoleTimeout();
}
@@ -352,6 +369,20 @@
mHandler.sendMessage(mHandler.obtainMessage(MSG_CHECK_IDLE_STATES, userId, 0));
}
+ /**
+ * We send a different message to check idle states once, otherwise we would end up
+ * scheduling a series of repeating checkIdleStates each time we fired off one.
+ */
+ void postOneTimeCheckIdleStates() {
+ if (mDeviceIdleController == null) {
+ // Not booted yet; wait for it!
+ mPendingOneTimeCheckIdleStates = true;
+ } else {
+ mHandler.sendEmptyMessage(MSG_ONE_TIME_CHECK_IDLE_STATES);
+ mPendingOneTimeCheckIdleStates = false;
+ }
+ }
+
/** Check all running users' or specified user's apps to see if they enter an idle state. */
void checkIdleStates(int checkUserId) {
if (!mAppIdleEnabled) {
@@ -378,22 +409,22 @@
userId);
synchronized (mLock) {
final long timeNow = checkAndGetTimeLocked();
- final long screenOnTime = getScreenOnTimeLocked(timeNow);
+ final long screenOnTime = getScreenOnTimeLocked();
UserUsageStatsService service = getUserDataAndInitializeIfNeededLocked(userId,
timeNow);
final int packageCount = packages.size();
for (int p = 0; p < packageCount; p++) {
- final String packageName = packages.get(p).packageName;
- final boolean isIdle = isAppIdleFiltered(packageName, userId, service, timeNow,
- screenOnTime);
+ final PackageInfo pi = packages.get(p);
+ final String packageName = pi.packageName;
+ final boolean isIdle = isAppIdleFiltered(packageName,
+ UserHandle.getAppId(pi.applicationInfo.uid),
+ userId, service, timeNow, screenOnTime);
mHandler.sendMessage(mHandler.obtainMessage(MSG_INFORM_LISTENERS,
userId, isIdle ? 1 : 0, packageName));
mAppIdleHistory.addEntry(packageName, userId, isIdle, timeNow);
}
}
}
- mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_CHECK_IDLE_STATES, checkUserId, 0),
- mCheckIdleIntervalMillis);
}
/** Check if it's been a while since last parole and let idle apps do some work */
@@ -404,8 +435,6 @@
if (timeSinceLastParole > mAppIdleParoleIntervalMillis) {
if (DEBUG) Slog.d(TAG, "Crossed default parole interval");
setAppIdleParoled(true);
- // Make sure it ends at some point
- postParoleEndTimeout();
} else {
if (DEBUG) Slog.d(TAG, "Not long enough to go to parole");
postNextParoleTimeout();
@@ -435,21 +464,21 @@
if (screenOn == mScreenOn) return;
mScreenOn = screenOn;
- long now = System.currentTimeMillis();
+ long now = SystemClock.elapsedRealtime();
if (mScreenOn) {
- mScreenOnSystemTimeSnapshot = now;
+ mLastScreenOnEventRealtime = now;
} else {
- mScreenOnTime += now - mScreenOnSystemTimeSnapshot;
+ mScreenOnTime += now - mLastScreenOnEventRealtime;
writeScreenOnTimeLocked(mScreenOnTime);
}
}
- private long getScreenOnTimeLocked(long now) {
+ long getScreenOnTimeLocked() {
+ long screenOnTime = mScreenOnTime;
if (mScreenOn) {
- return now - mScreenOnSystemTimeSnapshot + mScreenOnTime;
- } else {
- return mScreenOnTime;
+ screenOnTime += SystemClock.elapsedRealtime() - mLastScreenOnEventRealtime;
}
+ return screenOnTime;
}
private File getScreenOnTimeFile() {
@@ -492,7 +521,6 @@
if (!deviceIdle
&& timeSinceLastParole >= mAppIdleParoleIntervalMillis) {
if (DEBUG) Slog.i(TAG, "Bringing idle apps out of inactive state due to deviceIdleMode=false");
- postNextParoleTimeout();
setAppIdleParoled(true);
} else if (deviceIdle) {
if (DEBUG) Slog.i(TAG, "Device idle, back to prison");
@@ -520,7 +548,7 @@
if (service == null) {
service = new UserUsageStatsService(getContext(), userId,
new File(mUsageStatsDir, Integer.toString(userId)), this);
- service.init(currentTimeMillis, getScreenOnTimeLocked(currentTimeMillis));
+ service.init(currentTimeMillis, getScreenOnTimeLocked());
mUserState.put(userId, service);
}
return service;
@@ -533,20 +561,15 @@
final long actualSystemTime = System.currentTimeMillis();
final long actualRealtime = SystemClock.elapsedRealtime();
final long expectedSystemTime = (actualRealtime - mRealTimeSnapshot) + mSystemTimeSnapshot;
- boolean resetBeginIdleTime = false;
- if (Math.abs(actualSystemTime - expectedSystemTime) > TIME_CHANGE_THRESHOLD_MILLIS) {
+ final long diffSystemTime = actualSystemTime - expectedSystemTime;
+ if (Math.abs(diffSystemTime) > TIME_CHANGE_THRESHOLD_MILLIS) {
// The time has changed.
-
- // Check if it's severe enough a change to reset screenOnTime
- if (Math.abs(actualSystemTime - expectedSystemTime) > mAppIdleDurationMillis) {
- mScreenOnSystemTimeSnapshot = actualSystemTime;
- mScreenOnTime = 0;
- resetBeginIdleTime = true;
- }
+ Slog.i(TAG, "Time changed in UsageStats by " + (diffSystemTime / 1000) + " seconds");
final int userCount = mUserState.size();
for (int i = 0; i < userCount; i++) {
final UserUsageStatsService service = mUserState.valueAt(i);
- service.onTimeChanged(expectedSystemTime, actualSystemTime, resetBeginIdleTime);
+ service.onTimeChanged(expectedSystemTime, actualSystemTime, getScreenOnTimeLocked(),
+ false);
}
mRealTimeSnapshot = actualRealtime;
mSystemTimeSnapshot = actualSystemTime;
@@ -578,7 +601,7 @@
void reportEvent(UsageEvents.Event event, int userId) {
synchronized (mLock) {
final long timeNow = checkAndGetTimeLocked();
- final long screenOnTime = getScreenOnTimeLocked(timeNow);
+ final long screenOnTime = getScreenOnTimeLocked();
convertToSystemTimeLocked(event);
final UserUsageStatsService service =
@@ -594,7 +617,6 @@
|| event.mEventType == Event.SYSTEM_INTERACTION
|| event.mEventType == Event.USER_INTERACTION)) {
if (previouslyIdle) {
- // Slog.d(TAG, "Informing listeners of out-of-idle " + event.mPackage);
mHandler.sendMessage(mHandler.obtainMessage(MSG_INFORM_LISTENERS, userId,
/* idle = */ 0, event.mPackage));
notifyBatteryStats(event.mPackage, userId, false);
@@ -635,7 +657,7 @@
void forceIdleState(String packageName, int userId, boolean idle) {
synchronized (mLock) {
final long timeNow = checkAndGetTimeLocked();
- final long screenOnTime = getScreenOnTimeLocked(timeNow);
+ final long screenOnTime = getScreenOnTimeLocked();
final long deviceUsageTime = screenOnTime - (idle ? mAppIdleDurationMillis : 0) - 5000;
final UserUsageStatsService service =
@@ -649,7 +671,6 @@
timeNow - (idle ? mAppIdleWallclockThresholdMillis : 0) - 5000);
// Inform listeners if necessary
if (previouslyIdle != idle) {
- // Slog.d(TAG, "Informing listeners of out-of-idle " + packageName);
mHandler.sendMessage(mHandler.obtainMessage(MSG_INFORM_LISTENERS, userId,
/* idle = */ idle ? 1 : 0, packageName));
if (!idle) {
@@ -770,10 +791,17 @@
if (mAppIdleParoled) {
return false;
}
- return isAppIdleFiltered(packageName, userId, timeNow);
+ try {
+ ApplicationInfo ai = getContext().getPackageManager().getApplicationInfo(packageName,
+ PackageManager.GET_UNINSTALLED_PACKAGES
+ | PackageManager.GET_DISABLED_COMPONENTS);
+ return isAppIdleFiltered(packageName, ai.uid, userId, timeNow);
+ } catch (PackageManager.NameNotFoundException e) {
+ }
+ return false;
}
- boolean isAppIdleFiltered(String packageName, int userId, long timeNow) {
+ boolean isAppIdleFiltered(String packageName, int uidForAppId, int userId, long timeNow) {
final UserUsageStatsService userService;
final long screenOnTime;
synchronized (mLock) {
@@ -781,9 +809,10 @@
timeNow = checkAndGetTimeLocked();
}
userService = getUserDataAndInitializeIfNeededLocked(userId, timeNow);
- screenOnTime = getScreenOnTimeLocked(timeNow);
+ screenOnTime = getScreenOnTimeLocked();
}
- return isAppIdleFiltered(packageName, userId, userService, timeNow, screenOnTime);
+ return isAppIdleFiltered(packageName, UserHandle.getAppId(uidForAppId), userId,
+ userService, timeNow, screenOnTime);
}
/**
@@ -792,14 +821,22 @@
* This happens if the device is plugged in or temporarily allowed to make exceptions.
* Called by interface impls.
*/
- private boolean isAppIdleFiltered(String packageName, int userId,
+ private boolean isAppIdleFiltered(String packageName, int appId, int userId,
UserUsageStatsService userService, long timeNow, long screenOnTime) {
if (packageName == null) return false;
// If not enabled at all, of course nobody is ever idle.
if (!mAppIdleEnabled) {
return false;
}
- if (packageName.equals("android")) return false;
+ if (appId < Process.FIRST_APPLICATION_UID) {
+ // System uids never go idle.
+ return false;
+ }
+ if (packageName.equals("android")) {
+ // Nor does the framework (which should be redundant with the above, but for MR1 we will
+ // retain this for safety).
+ return false;
+ }
try {
// We allow all whitelisted apps, including those that don't want to be whitelisted
// for idle mode, because app idle (aka app standby) is really not as big an issue
@@ -841,7 +878,7 @@
synchronized (mLock) {
timeNow = checkAndGetTimeLocked();
userService = getUserDataAndInitializeIfNeededLocked(userId, timeNow);
- screenOnTime = getScreenOnTimeLocked(timeNow);
+ screenOnTime = getScreenOnTimeLocked();
}
List<ApplicationInfo> apps;
@@ -866,8 +903,8 @@
ApplicationInfo ai = apps.get(i);
// Check whether this app is idle.
- boolean idle = isAppIdleFiltered(ai.packageName, userId, userService, timeNow,
- screenOnTime);
+ boolean idle = isAppIdleFiltered(ai.packageName, UserHandle.getAppId(ai.uid),
+ userId, userService, timeNow, screenOnTime);
int index = uidStates.indexOfKey(ai.uid);
if (index < 0) {
@@ -963,7 +1000,7 @@
*/
void dump(String[] args, PrintWriter pw) {
synchronized (mLock) {
- final long screenOnTime = getScreenOnTimeLocked(checkAndGetTimeLocked());
+ final long screenOnTime = getScreenOnTimeLocked();
IndentingPrintWriter idpw = new IndentingPrintWriter(pw, " ");
ArraySet<String> argSet = new ArraySet<>();
argSet.addAll(Arrays.asList(args));
@@ -984,7 +1021,11 @@
}
idpw.decreaseIndent();
}
- pw.println("Screen On Timebase:" + mScreenOnTime);
+ pw.print("Screen On Timebase: ");
+ pw.print(screenOnTime);
+ pw.print(" (");
+ TimeUtils.formatDuration(screenOnTime, pw);
+ pw.println(")");
pw.println();
pw.println("Settings:");
@@ -1018,8 +1059,8 @@
pw.println();
pw.print("mScreenOnTime="); TimeUtils.formatDuration(mScreenOnTime, pw);
pw.println();
- pw.print("mScreenOnSystemTimeSnapshot=");
- TimeUtils.formatDuration(mScreenOnSystemTimeSnapshot, pw);
+ pw.print("mLastScreenOnEventRealtime=");
+ TimeUtils.formatDuration(mLastScreenOnEventRealtime, pw);
pw.println();
}
}
@@ -1054,6 +1095,14 @@
case MSG_CHECK_IDLE_STATES:
checkIdleStates(msg.arg1);
+ mHandler.sendMessageDelayed(mHandler.obtainMessage(
+ MSG_CHECK_IDLE_STATES, msg.arg1, 0),
+ mCheckIdleIntervalMillis);
+ break;
+
+ case MSG_ONE_TIME_CHECK_IDLE_STATES:
+ mHandler.removeMessages(MSG_ONE_TIME_CHECK_IDLE_STATES);
+ checkIdleStates(UserHandle.USER_ALL);
break;
case MSG_CHECK_PAROLE_TIMEOUT:
@@ -1089,7 +1138,13 @@
* Observe settings changes for {@link Settings.Global#APP_IDLE_CONSTANTS}.
*/
private class SettingsObserver extends ContentObserver {
- private static final String KEY_IDLE_DURATION = "idle_duration";
+ /**
+ * This flag has been used to disable app idle on older builds with bug b/26355386.
+ */
+ @Deprecated
+ private static final String KEY_IDLE_DURATION_OLD = "idle_duration";
+
+ private static final String KEY_IDLE_DURATION = "idle_duration2";
private static final String KEY_WALLCLOCK_THRESHOLD = "wallclock_threshold";
private static final String KEY_PAROLE_INTERVAL = "parole_interval";
private static final String KEY_PAROLE_DURATION = "parole_duration";
@@ -1108,7 +1163,7 @@
@Override
public void onChange(boolean selfChange) {
updateSettings();
- postCheckIdleStates(UserHandle.USER_ALL);
+ postOneTimeCheckIdleStates();
}
void updateSettings() {
@@ -1353,8 +1408,8 @@
}
@Override
- public boolean isAppIdle(String packageName, int userId) {
- return UsageStatsService.this.isAppIdleFiltered(packageName, userId, -1);
+ public boolean isAppIdle(String packageName, int uidForAppId, int userId) {
+ return UsageStatsService.this.isAppIdleFiltered(packageName, uidForAppId, userId, -1);
}
@Override
diff --git a/services/usage/java/com/android/server/usage/UserUsageStatsService.java b/services/usage/java/com/android/server/usage/UserUsageStatsService.java
index b07b815..a9f7ae0 100644
--- a/services/usage/java/com/android/server/usage/UserUsageStatsService.java
+++ b/services/usage/java/com/android/server/usage/UserUsageStatsService.java
@@ -59,6 +59,7 @@
private final Context mContext;
private final UsageStatsDatabase mDatabase;
private final IntervalStats[] mCurrentStats;
+ private IntervalStats mAppIdleRollingWindow;
private boolean mStatsChanged = false;
private final UnixCalendar mDailyExpiryDate;
private final StatsUpdatedListener mListener;
@@ -67,6 +68,8 @@
interface StatsUpdatedListener {
void onStatsUpdated();
+ void onStatsReloaded();
+ long getAppIdleRollingWindowDurationMillis();
}
UserUsageStatsService(Context context, int userId, File usageStatsDir,
@@ -134,6 +137,8 @@
stat.updateConfigurationStats(null, stat.lastTimeSaved);
}
+ refreshAppIdleRollingWindow(currentTimeMillis, deviceUsageTime);
+
if (mDatabase.isNewUpdate()) {
initializeDefaultsForApps(currentTimeMillis, deviceUsageTime,
mDatabase.isFirstUpdate());
@@ -159,18 +164,23 @@
for (IntervalStats stats : mCurrentStats) {
stats.update(packageName, currentTimeMillis, Event.SYSTEM_INTERACTION);
stats.updateBeginIdleTime(packageName, deviceUsageTime);
- mStatsChanged = true;
}
+ mAppIdleRollingWindow.update(packageName, currentTimeMillis,
+ Event.SYSTEM_INTERACTION);
+ mAppIdleRollingWindow.updateBeginIdleTime(packageName, deviceUsageTime);
+ mStatsChanged = true;
}
}
// Persist the new OTA-related access stats.
persistActiveStats();
}
- void onTimeChanged(long oldTime, long newTime, boolean resetBeginIdleTime) {
+ void onTimeChanged(long oldTime, long newTime, long deviceUsageTime,
+ boolean resetBeginIdleTime) {
persistActiveStats();
mDatabase.onTimeChanged(newTime - oldTime);
loadActiveStats(newTime, /* force= */ true, resetBeginIdleTime);
+ refreshAppIdleRollingWindow(newTime, deviceUsageTime);
}
void reportEvent(UsageEvents.Event event, long deviceUsageTime) {
@@ -182,7 +192,7 @@
if (event.mTimeStamp >= mDailyExpiryDate.getTimeInMillis()) {
// Need to rollover
- rolloverStats(event.mTimeStamp);
+ rolloverStats(event.mTimeStamp, deviceUsageTime);
}
final IntervalStats currentDailyStats = mCurrentStats[UsageStatsManager.INTERVAL_DAILY];
@@ -212,6 +222,11 @@
}
}
+ if (event.mEventType != Event.CONFIGURATION_CHANGE) {
+ mAppIdleRollingWindow.update(event.mPackage, event.mTimeStamp, event.mEventType);
+ mAppIdleRollingWindow.updateBeginIdleTime(event.mPackage, deviceUsageTime);
+ }
+
notifyStatsChanged();
}
@@ -223,6 +238,7 @@
for (IntervalStats stats : mCurrentStats) {
stats.updateBeginIdleTime(packageName, beginIdleTime);
}
+ mAppIdleRollingWindow.updateBeginIdleTime(packageName, beginIdleTime);
notifyStatsChanged();
}
@@ -230,6 +246,7 @@
for (IntervalStats stats : mCurrentStats) {
stats.updateSystemLastUsedTime(packageName, lastUsedTime);
}
+ mAppIdleRollingWindow.updateSystemLastUsedTime(packageName, lastUsedTime);
notifyStatsChanged();
}
@@ -388,9 +405,8 @@
}
long getBeginIdleTime(String packageName) {
- final IntervalStats yearly = mCurrentStats[UsageStatsManager.INTERVAL_YEARLY];
UsageStats packageUsage;
- if ((packageUsage = yearly.packageStats.get(packageName)) == null) {
+ if ((packageUsage = mAppIdleRollingWindow.packageStats.get(packageName)) == null) {
return -1;
} else {
return packageUsage.getBeginIdleTime();
@@ -398,9 +414,8 @@
}
long getSystemLastUsedTime(String packageName) {
- final IntervalStats yearly = mCurrentStats[UsageStatsManager.INTERVAL_YEARLY];
UsageStats packageUsage;
- if ((packageUsage = yearly.packageStats.get(packageName)) == null) {
+ if ((packageUsage = mAppIdleRollingWindow.packageStats.get(packageName)) == null) {
return -1;
} else {
return packageUsage.getLastTimeSystemUsed();
@@ -421,7 +436,7 @@
}
}
- private void rolloverStats(final long currentTimeMillis) {
+ private void rolloverStats(final long currentTimeMillis, final long deviceUsageTime) {
final long startTime = SystemClock.elapsedRealtime();
Slog.i(TAG, mLogPrefix + "Rolling over usage stats");
@@ -462,6 +477,8 @@
}
persistActiveStats();
+ refreshAppIdleRollingWindow(currentTimeMillis, deviceUsageTime);
+
final long totalTime = SystemClock.elapsedRealtime() - startTime;
Slog.i(TAG, mLogPrefix + "Rolling over usage stats complete. Took " + totalTime
+ " milliseconds");
@@ -521,6 +538,7 @@
}
}
}
+
mStatsChanged = false;
mDailyExpiryDate.setTimeInMillis(currentTimeMillis);
mDailyExpiryDate.addDays(1);
@@ -528,6 +546,74 @@
Slog.i(TAG, mLogPrefix + "Rollover scheduled @ " +
sDateFormat.format(mDailyExpiryDate.getTimeInMillis()) + "(" +
tempCal.getTimeInMillis() + ")");
+
+ // Tell the listener that the stats reloaded, which may have changed idle states.
+ mListener.onStatsReloaded();
+ }
+
+ private static void mergePackageStats(IntervalStats dst, IntervalStats src,
+ final long deviceUsageTime) {
+ dst.endTime = Math.max(dst.endTime, src.endTime);
+
+ final int srcPackageCount = src.packageStats.size();
+ for (int i = 0; i < srcPackageCount; i++) {
+ final String packageName = src.packageStats.keyAt(i);
+ final UsageStats srcStats = src.packageStats.valueAt(i);
+ UsageStats dstStats = dst.packageStats.get(packageName);
+ if (dstStats == null) {
+ dstStats = new UsageStats(srcStats);
+ dst.packageStats.put(packageName, dstStats);
+ } else {
+ dstStats.add(src.packageStats.valueAt(i));
+ }
+
+ // App idle times can not begin in the future. This happens if we had a time change.
+ if (dstStats.mBeginIdleTime > deviceUsageTime) {
+ dstStats.mBeginIdleTime = deviceUsageTime;
+ }
+ }
+ }
+
+ /**
+ * App idle operates on a rolling window of time. When we roll over time, we end up with a
+ * period of time where in-memory stats are empty and we don't hit the disk for older stats
+ * for performance reasons. Suddenly all apps will become idle.
+ *
+ * Instead, at times we do a deep query to find all the apps that have run in the past few
+ * days and keep the cached data up to date.
+ *
+ * @param currentTimeMillis
+ */
+ void refreshAppIdleRollingWindow(final long currentTimeMillis, final long deviceUsageTime) {
+ // Start the rolling window for AppIdle requests.
+ final long startRangeMillis = currentTimeMillis -
+ mListener.getAppIdleRollingWindowDurationMillis();
+
+ List<IntervalStats> stats = mDatabase.queryUsageStats(UsageStatsManager.INTERVAL_DAILY,
+ startRangeMillis, currentTimeMillis, new StatCombiner<IntervalStats>() {
+ @Override
+ public void combine(IntervalStats stats, boolean mutable,
+ List<IntervalStats> accumulatedResult) {
+ IntervalStats accum;
+ if (accumulatedResult.isEmpty()) {
+ accum = new IntervalStats();
+ accum.beginTime = stats.beginTime;
+ accumulatedResult.add(accum);
+ } else {
+ accum = accumulatedResult.get(0);
+ }
+
+ mergePackageStats(accum, stats, deviceUsageTime);
+ }
+ });
+
+ if (stats == null || stats.isEmpty()) {
+ mAppIdleRollingWindow = new IntervalStats();
+ mergePackageStats(mAppIdleRollingWindow,
+ mCurrentStats[UsageStatsManager.INTERVAL_YEARLY], deviceUsageTime);
+ } else {
+ mAppIdleRollingWindow = stats.get(0);
+ }
}
//
@@ -552,6 +638,9 @@
pw.println(" stats");
printIntervalStats(pw, mCurrentStats[interval], screenOnTime, true);
}
+
+ pw.println("AppIdleRollingWindow cache");
+ printIntervalStats(pw, mAppIdleRollingWindow, screenOnTime, true);
}
private String formatDateTime(long dateTime, boolean pretty) {
diff --git a/services/usb/java/com/android/server/usb/UsbDeviceManager.java b/services/usb/java/com/android/server/usb/UsbDeviceManager.java
index 09e15a8..a4a4d84 100644
--- a/services/usb/java/com/android/server/usb/UsbDeviceManager.java
+++ b/services/usb/java/com/android/server/usb/UsbDeviceManager.java
@@ -19,15 +19,19 @@
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
+import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
+import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.content.res.Resources;
import android.database.ContentObserver;
import android.hardware.usb.UsbAccessory;
import android.hardware.usb.UsbManager;
+import android.hardware.usb.UsbPort;
+import android.hardware.usb.UsbPortStatus;
import android.os.FileUtils;
import android.os.Handler;
import android.os.Looper;
@@ -105,6 +109,7 @@
private static final int MSG_USER_SWITCHED = 5;
private static final int MSG_SET_USB_DATA_UNLOCKED = 6;
private static final int MSG_UPDATE_USER_RESTRICTIONS = 7;
+ private static final int MSG_UPDATE_HOST_STATE = 8;
private static final int AUDIO_MODE_SOURCE = 1;
@@ -175,6 +180,15 @@
}
};
+ private final BroadcastReceiver mHostReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ UsbPort port = intent.getParcelableExtra(UsbManager.EXTRA_PORT);
+ UsbPortStatus status = intent.getParcelableExtra(UsbManager.EXTRA_PORT_STATUS);
+ mHandler.updateHostState(port, status);
+ }
+ };
+
public UsbDeviceManager(Context context, UsbAlsaManager alsaManager) {
mContext = context;
mUsbAlsaManager = alsaManager;
@@ -197,6 +211,8 @@
if (secureAdbEnabled && !dataEncrypted) {
mDebuggingManager = new UsbDebuggingManager(context);
}
+ mContext.registerReceiver(mHostReceiver,
+ new IntentFilter(UsbManager.ACTION_USB_PORT_CHANGED));
}
private UsbSettingsManager getCurrentSettings() {
@@ -299,6 +315,7 @@
// current USB state
private boolean mConnected;
+ private boolean mHostConnected;
private boolean mConfigured;
private boolean mUsbDataUnlocked;
private String mCurrentFunctions;
@@ -377,6 +394,11 @@
sendMessageDelayed(msg, (connected == 0) ? UPDATE_DELAY : 0);
}
+ public void updateHostState(UsbPort port, UsbPortStatus status) {
+ boolean hostConnected = status.getCurrentDataRole() == UsbPort.DATA_ROLE_HOST;
+ obtainMessage(MSG_UPDATE_HOST_STATE, hostConnected ? 1 :0, 0).sendToTarget();
+ }
+
private boolean waitForState(String state) {
// wait for the transition to complete.
// give up after 1 second.
@@ -394,10 +416,9 @@
private boolean setUsbConfig(String config) {
if (DEBUG) Slog.d(TAG, "setUsbConfig(" + config + ")");
// set the new configuration
- String oldConfig = SystemProperties.get(USB_CONFIG_PROPERTY);
- if (!config.equals(oldConfig)) {
- SystemProperties.set(USB_CONFIG_PROPERTY, config);
- }
+ // we always set it due to b/23631400, where adbd was getting killed
+ // and not restarted due to property timeouts on some devices
+ SystemProperties.set(USB_CONFIG_PROPERTY, config);
return waitForState(config);
}
@@ -652,6 +673,10 @@
updateUsbFunctions();
}
break;
+ case MSG_UPDATE_HOST_STATE:
+ mHostConnected = (msg.arg1 == 1);
+ updateUsbNotification();
+ break;
case MSG_ENABLE_ADB:
setAdbEnabled(msg.arg1 == 1);
break;
@@ -690,6 +715,8 @@
if (active && mCurrentUser != UserHandle.USER_NULL) {
Slog.v(TAG, "Current user switched to " + mCurrentUser
+ "; resetting USB host stack for MTP or PTP");
+ // avoid leaking sensitive data from previous user
+ mUsbDataUnlocked = false;
setEnabledFunctions(mCurrentFunctions, true);
}
mCurrentUser = msg.arg1;
@@ -707,7 +734,7 @@
if (mNotificationManager == null || !mUseUsbNotification) return;
int id = 0;
Resources r = mContext.getResources();
- if (mConnected) {
+ if (mConnected || mHostConnected) {
if (!mUsbDataUnlocked) {
id = com.android.internal.R.string.usb_charging_notification_title;
} else if (UsbManager.containsFunction(mCurrentFunctions,
diff --git a/services/usb/java/com/android/server/usb/UsbPortManager.java b/services/usb/java/com/android/server/usb/UsbPortManager.java
index 52abcfe..7f182a4 100644
--- a/services/usb/java/com/android/server/usb/UsbPortManager.java
+++ b/services/usb/java/com/android/server/usb/UsbPortManager.java
@@ -26,8 +26,13 @@
import android.hardware.usb.UsbPortStatus;
import android.os.Handler;
import android.os.Message;
+import android.os.SystemClock;
+import android.os.SystemProperties;
import android.os.UEventObserver;
import android.os.UserHandle;
+import android.system.ErrnoException;
+import android.system.Os;
+import android.system.OsConstants;
import android.util.ArrayMap;
import android.util.Log;
import android.util.Slog;
@@ -89,6 +94,9 @@
private static final String PORT_DATA_ROLE_HOST = "host";
private static final String PORT_DATA_ROLE_DEVICE = "device";
+ private static final String USB_TYPEC_PROP_PREFIX = "sys.usb.typec.";
+ private static final String USB_TYPEC_STATE = "sys.usb.typec.state";
+
// All non-trivial role combinations.
private static final int COMBO_SOURCE_HOST =
UsbPort.combineRolesAsBit(UsbPort.POWER_ROLE_SOURCE, UsbPort.DATA_ROLE_HOST);
@@ -621,16 +629,25 @@
return 0;
}
+ private static boolean fileIsRootWritable(String path) {
+ try {
+ // If the file is user writable, then it is root writable.
+ return (Os.stat(path).st_mode & OsConstants.S_IWUSR) != 0;
+ } catch (ErrnoException e) {
+ return false;
+ }
+ }
+
private static boolean canChangeMode(File portDir) {
- return new File(portDir, SYSFS_PORT_MODE).canWrite();
+ return fileIsRootWritable(new File(portDir, SYSFS_PORT_MODE).getPath());
}
private static boolean canChangePowerRole(File portDir) {
- return new File(portDir, SYSFS_PORT_POWER_ROLE).canWrite();
+ return fileIsRootWritable(new File(portDir, SYSFS_PORT_POWER_ROLE).getPath());
}
private static boolean canChangeDataRole(File portDir) {
- return new File(portDir, SYSFS_PORT_DATA_ROLE).canWrite();
+ return fileIsRootWritable(new File(portDir, SYSFS_PORT_DATA_ROLE).getPath());
}
private static String readFile(File dir, String filename) {
@@ -642,16 +659,29 @@
}
}
- private static boolean writeFile(File dir, String filename, String contents) {
- final File file = new File(dir, filename);
- try {
- try (FileWriter writer = new FileWriter(file)) {
- writer.write(contents);
- }
- return true;
- } catch (IOException ex) {
- return false;
+ private static boolean waitForState(String property, String state) {
+ // wait for the transition to complete.
+ // give up after 5 seconds.
+ // 5 seconds is probably too long, but we have seen hardware that takes
+ // over 3 seconds to change states.
+ String value = null;
+ for (int i = 0; i < 100; i++) {
+ // State transition is done when property is set to the new configuration
+ value = SystemProperties.get(property);
+ if (state.equals(value)) return true;
+ SystemClock.sleep(50);
}
+ Slog.e(TAG, "waitForState(" + state + ") for " + property + " FAILED: got " + value);
+ return false;
+ }
+
+ private static String propertyFromFilename(String filename) {
+ return USB_TYPEC_PROP_PREFIX + filename;
+ }
+
+ private static boolean writeFile(File dir, String filename, String contents) {
+ SystemProperties.set(propertyFromFilename(filename), contents);
+ return waitForState(USB_TYPEC_STATE, contents);
}
private static void logAndPrint(int priority, IndentingPrintWriter pw, String msg) {
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/SoundTriggerHelper.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/SoundTriggerHelper.java
index 3ca0c84..31d859f 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/SoundTriggerHelper.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/SoundTriggerHelper.java
@@ -87,6 +87,7 @@
// This is an indirect indication of the microphone being open in some other application.
private boolean mServiceDisabled = false;
private boolean mStarted = false;
+ private boolean mRecognitionAborted = false;
private PowerSaveModeListener mPowerSaveModeListener;
SoundTriggerHelper(Context context) {
@@ -386,8 +387,9 @@
private void onRecognitionAbortLocked() {
Slog.w(TAG, "Recognition aborted");
- // No-op
- // This is handled via service state changes instead.
+ // If abort has been called, the hardware has already stopped recognition, so we shouldn't
+ // call it again when we process the state change.
+ mRecognitionAborted = true;
}
private void onRecognitionFailureLocked() {
@@ -490,8 +492,13 @@
}
return status;
} else {
- // Stop recognition.
- int status = mModule.stopRecognition(mCurrentSoundModelHandle);
+ // Stop recognition (only if we haven't been aborted).
+ int status = STATUS_OK;
+ if (!mRecognitionAborted) {
+ status = mModule.stopRecognition(mCurrentSoundModelHandle);
+ } else {
+ mRecognitionAborted = false;
+ }
if (status != SoundTrigger.STATUS_OK) {
Slog.w(TAG, "stopRecognition call failed with " + status);
if (notify) {
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
index a8874d0..a96c164 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
@@ -925,7 +925,7 @@
return;
}
synchronized (this) {
- pw.println("VOICE INTERACTION MANAGER (dumpsys voiceinteraction)\n");
+ pw.println("VOICE INTERACTION MANAGER (dumpsys voiceinteraction)");
pw.println(" mEnableService: " + mEnableService);
if (mImpl == null) {
pw.println(" (No active implementation)");
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java
index 28520be..30296e1 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java
@@ -36,6 +36,7 @@
import android.service.voice.IVoiceInteractionSession;
import android.service.voice.VoiceInteractionService;
import android.service.voice.VoiceInteractionServiceInfo;
+import android.util.PrintWriterPrinter;
import android.util.Slog;
import android.view.IWindowManager;
@@ -114,9 +115,9 @@
mAm = ActivityManagerNative.getDefault();
VoiceInteractionServiceInfo info;
try {
- info = new VoiceInteractionServiceInfo(context.getPackageManager(), service);
- } catch (PackageManager.NameNotFoundException e) {
- Slog.w(TAG, "Voice interaction service not found: " + service);
+ info = new VoiceInteractionServiceInfo(context.getPackageManager(), service, mUser);
+ } catch (RemoteException|PackageManager.NameNotFoundException e) {
+ Slog.w(TAG, "Voice interaction service not found: " + service, e);
mInfo = null;
mSessionComponentName = null;
mIWindowManager = null;
@@ -260,9 +261,18 @@
}
return;
}
+ pw.print(" mUser="); pw.println(mUser);
pw.print(" mComponent="); pw.println(mComponent.flattenToShortString());
pw.print(" Session service="); pw.println(mInfo.getSessionService());
+ pw.println(" Service info:");
+ mInfo.getServiceInfo().dump(new PrintWriterPrinter(pw), " ");
+ pw.println(" Application info:");
+ mInfo.getServiceInfo().applicationInfo.dump(new PrintWriterPrinter(pw), " ");
+ pw.print(" Recognition service="); pw.println(mInfo.getRecognitionService());
pw.print(" Settings activity="); pw.println(mInfo.getSettingsActivity());
+ pw.print(" Supports assist="); pw.println(mInfo.getSupportsAssist());
+ pw.print(" Supports launch from keyguard=");
+ pw.println(mInfo.getSupportsLaunchFromKeyguard());
if (mDisabledShowContext != 0) {
pw.print(" mDisabledShowContext=");
pw.println(Integer.toHexString(mDisabledShowContext));
diff --git a/telecomm/java/android/telecom/Call.java b/telecomm/java/android/telecom/Call.java
index 0a1dbf6..f149f24 100644
--- a/telecomm/java/android/telecom/Call.java
+++ b/telecomm/java/android/telecom/Call.java
@@ -970,7 +970,6 @@
unregisterCallback(listener);
}
-
/** {@hide} */
Call(Phone phone, String telecomCallId, InCallAdapter inCallAdapter) {
mPhone = phone;
@@ -980,6 +979,14 @@
}
/** {@hide} */
+ Call(Phone phone, String telecomCallId, InCallAdapter inCallAdapter, int state) {
+ mPhone = phone;
+ mTelecomCallId = telecomCallId;
+ mInCallAdapter = inCallAdapter;
+ mState = state;
+ }
+
+ /** {@hide} */
final String internalGetCallId() {
return mTelecomCallId;
}
diff --git a/telecomm/java/android/telecom/ConnectionService.java b/telecomm/java/android/telecom/ConnectionService.java
index 96f44b9..383e45b 100644
--- a/telecomm/java/android/telecom/ConnectionService.java
+++ b/telecomm/java/android/telecom/ConnectionService.java
@@ -656,6 +656,9 @@
connection.getDisconnectCause(),
createIdList(connection.getConferenceables()),
connection.getExtras()));
+ if (isUnknown) {
+ triggerConferenceRecalculate();
+ }
}
private void abort(String callId) {
@@ -1016,6 +1019,16 @@
}
/**
+ * Trigger recalculate functinality for conference calls. This is used when a Telephony
+ * Connection is part of a conference controller but is not yet added to Connection
+ * Service and hence cannot be added to the conference call.
+ *
+ * @hide
+ */
+ public void triggerConferenceRecalculate() {
+ }
+
+ /**
* Create a {@code Connection} given an outgoing request. This is used to initiate new
* outgoing calls.
*
diff --git a/telecomm/java/android/telecom/Phone.java b/telecomm/java/android/telecom/Phone.java
index 8eb091b..47154da 100644
--- a/telecomm/java/android/telecom/Phone.java
+++ b/telecomm/java/android/telecom/Phone.java
@@ -122,7 +122,8 @@
}
final void internalAddCall(ParcelableCall parcelableCall) {
- Call call = new Call(this, parcelableCall.getId(), mInCallAdapter);
+ Call call = new Call(this, parcelableCall.getId(), mInCallAdapter,
+ parcelableCall.getState());
mCallByTelecomCallId.put(parcelableCall.getId(), call);
mCalls.add(call);
checkCallTree(parcelableCall);
diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java
index e9c41a1..29e54a3 100644
--- a/telephony/java/android/telephony/CarrierConfigManager.java
+++ b/telephony/java/android/telephony/CarrierConfigManager.java
@@ -78,6 +78,15 @@
public static final String KEY_WORLD_PHONE_BOOL = "world_phone_bool";
/**
+ * Flag to require or skip entitlement checks.
+ * If true, entitlement checks will be executed if device has been configured for it,
+ * If false, entitlement checks will be skipped.
+ * @hide
+ */
+ public static final String
+ KEY_REQUIRE_ENTITLEMENT_CHECKS_BOOL = "require_entitlement_checks_bool";
+
+ /**
* If true, enable vibration (haptic feedback) for key presses in the EmergencyDialer activity.
* The pattern is set on a per-platform basis using config_virtualKeyVibePattern. To be
* consistent with the regular Dialer, this value should agree with the corresponding values
@@ -182,7 +191,7 @@
public static final String
KEY_DISABLE_CDMA_ACTIVATION_CODE_BOOL = "disable_cdma_activation_code_bool";
- /**
+ /**
* Override the platform's notion of a network operator being considered roaming.
* Value is string array of MCCMNCs to be considered roaming for 3GPP RATs.
*/
@@ -259,6 +268,42 @@
= "carrier_allow_turnoff_ims_bool";
/**
+ * Flag specifying whether Generic Bootstrapping Architecture capable SIM is required for IMS.
+ * @hide
+ */
+ public static final String KEY_CARRIER_IMS_GBA_REQUIRED_BOOL
+ = "carrier_ims_gba_required_bool";
+
+ /**
+ * Flag specifying whether IMS instant lettering is available for the carrier. {@code True} if
+ * instant lettering is available for the carrier, {@code false} otherwise.
+ * @hide
+ */
+ public static final String KEY_CARRIER_INSTANT_LETTERING_AVAILABLE_BOOL =
+ "carrier_instant_lettering_available_bool";
+
+ /**
+ * When IMS instant lettering is available for a carrier (see
+ * {@link #KEY_CARRIER_INSTANT_LETTERING_AVAILABLE_BOOL}), determines the list of characters
+ * which may not be contained in messages. Should be specified as a regular expression suitable
+ * for use with {@link String#matches(String)}.
+ * @hide
+ */
+ public static final String KEY_CARRIER_INSTANT_LETTERING_INVALID_CHARS_STRING =
+ "carrier_instant_lettering_invalid_chars_string";
+
+ /**
+ * When IMS instant lettering is available for a carrier (see
+ * {@link #KEY_CARRIER_INSTANT_LETTERING_AVAILABLE_BOOL}), determines a list of characters which
+ * must be escaped with a backslash '\' character. Should be specified as a string containing
+ * the characters to be escaped. For example to escape quote and backslash the string would be
+ * a quote and a backslash.
+ * @hide
+ */
+ public static final String KEY_CARRIER_INSTANT_LETTERING_ESCAPED_CHARS_STRING =
+ "carrier_instant_lettering_escaped_chars_string";
+
+ /**
* If Voice Radio Technology is RIL_RADIO_TECHNOLOGY_LTE:14 or RIL_RADIO_TECHNOLOGY_UNKNOWN:0
* this is the value that should be used instead. A configuration value of
* RIL_RADIO_TECHNOLOGY_UNKNOWN:0 means there is no replacement value and that the default
@@ -281,6 +326,14 @@
public static final String KEY_CARRIER_FORCE_DISABLE_ETWS_CMAS_TEST_BOOL =
"carrier_force_disable_etws_cmas_test_bool";
+ /**
+ * The default flag specifying whether "Turn on Notifications" option will be always shown in
+ * Settings->More->Emergency broadcasts menu regardless developer options is turned on or not.
+ * @hide
+ */
+ public static final String KEY_ALWAYS_SHOW_EMERGENCY_ALERT_ONOFF_BOOL =
+ "always_show_emergency_alert_onoff_bool";
+
/* The following 3 fields are related to carrier visual voicemail. */
/**
@@ -334,6 +387,55 @@
"ci_action_on_sys_update_extra_val_string";
/**
+ * Specifies the amount of gap to be added in millis between postdial DTMF tones. When a
+ * non-zero value is specified, the UE shall wait for the specified amount of time before it
+ * sends out successive DTMF tones on the network.
+ * @hide
+ */
+ public static final String KEY_GSM_DTMF_TONE_DELAY_INT = "gsm_dtmf_tone_delay_int";
+
+ /**
+ * Specifies the amount of gap to be added in millis between DTMF tones. When a non-zero value
+ * is specified, the UE shall wait for the specified amount of time before it sends out
+ * successive DTMF tones on the network.
+ * @hide
+ */
+ public static final String KEY_IMS_DTMF_TONE_DELAY_INT = "ims_dtmf_tone_delay_int";
+
+ /**
+ * Determines whether conference calls are supported by a carrier. When {@code true},
+ * conference calling is supported, {@code false otherwise}.
+ * @hide
+ */
+ public static final String KEY_SUPPORT_CONFERENCE_CALL_BOOL = "support_conference_call_bool";
+
+ /**
+ * Determine whether user can toggle Enhanced 4G LTE Mode in Settings.
+ * @hide
+ */
+ public static final String KEY_EDITABLE_ENHANCED_4G_LTE_BOOL = "editable_enhanced_4g_lte_bool";
+
+ /**
+ * Determine whether IMS apn can be shown.
+ * @hide
+ */
+ public static final String KEY_HIDE_IMS_APN_BOOL = "hide_ims_apn_bool";
+
+ /**
+ * Determine whether preferred network type can be shown.
+ * @hide
+ */
+ public static final String KEY_HIDE_PREFERRED_NETWORK_TYPE_BOOL = "hide_preferred_network_type_bool";
+
+ /**
+ * Specifies the amount of gap to be added in millis between postdial DTMF tones. When a
+ * non-zero value is specified, the UE shall wait for the specified amount of time before it
+ * sends out successive DTMF tones on the network.
+ * @hide
+ */
+ public static final String KEY_CDMA_DTMF_TONE_DELAY_INT = "cdma_dtmf_tone_delay_int";
+
+ /**
* If this is true, the SIM card (through Customer Service Profile EF file) will be able to
* prevent manual operator selection. If false, this SIM setting will be ignored and manual
* operator selection will always be available. See CPHS4_2.WW6, CPHS B.4.7.1 for more
@@ -341,6 +443,12 @@
*/
public static final String KEY_CSP_ENABLED_BOOL = "csp_enabled_bool";
+ /**
+ * Allow user to add APNs
+ * @hide
+ */
+ public static final String KEY_ALLOW_ADDING_APNS_BOOL = "allow_adding_apns_bool";
+
// These variables are used by the MMS service and exposed through another API, {@link
// SmsManager}. The variable names and string values are copied from there.
public static final String KEY_MMS_ALIAS_ENABLED_BOOL = "aliasEnabled";
@@ -375,6 +483,15 @@
public static final String KEY_MMS_UA_PROF_URL_STRING = "uaProfUrl";
public static final String KEY_MMS_USER_AGENT_STRING = "userAgent";
+ /**
+ * Determines whether the carrier supports making non-emergency phone calls while the phone is
+ * in emergency callback mode. Default value is {@code true}, meaning that non-emergency calls
+ * are allowed in emergency callback mode.
+ * @hide
+ */
+ public static final String KEY_ALLOW_NON_EMERGENCY_CALLS_IN_ECM_BOOL =
+ "allow_non_emergency_calls_in_ecm_bool";
+
/** The default value for every variable. */
private final static PersistableBundle sDefaults;
@@ -393,6 +510,10 @@
sDefaults.putBoolean(KEY_CARRIER_VOLTE_PROVISIONING_REQUIRED_BOOL, false);
sDefaults.putBoolean(KEY_CARRIER_VOLTE_TTY_SUPPORTED_BOOL, true);
sDefaults.putBoolean(KEY_CARRIER_ALLOW_TURNOFF_IMS_BOOL, true);
+ sDefaults.putBoolean(KEY_CARRIER_IMS_GBA_REQUIRED_BOOL, false);
+ sDefaults.putBoolean(KEY_CARRIER_INSTANT_LETTERING_AVAILABLE_BOOL, false);
+ sDefaults.putString(KEY_CARRIER_INSTANT_LETTERING_INVALID_CHARS_STRING, "");
+ sDefaults.putString(KEY_CARRIER_INSTANT_LETTERING_ESCAPED_CHARS_STRING, "");
sDefaults.putBoolean(KEY_DISABLE_CDMA_ACTIVATION_CODE_BOOL, false);
sDefaults.putBoolean(KEY_DTMF_TYPE_ENABLED_BOOL, false);
sDefaults.putBoolean(KEY_ENABLE_DIALER_KEY_VIBRATION_BOOL, true);
@@ -413,6 +534,7 @@
sDefaults.putBoolean(KEY_VOICEMAIL_NOTIFICATION_PERSISTENT_BOOL, false);
sDefaults.putBoolean(KEY_VOICE_PRIVACY_DISABLE_UI_BOOL, false);
sDefaults.putBoolean(KEY_WORLD_PHONE_BOOL, false);
+ sDefaults.putBoolean(KEY_REQUIRE_ENTITLEMENT_CHECKS_BOOL, true);
sDefaults.putInt(KEY_VOLTE_REPLACEMENT_RAT_INT, 0);
sDefaults.putString(KEY_DEFAULT_SIM_CALL_MANAGER_STRING, "");
sDefaults.putString(KEY_VVM_DESTINATION_NUMBER_STRING, "");
@@ -424,12 +546,21 @@
sDefaults.putString(KEY_CI_ACTION_ON_SYS_UPDATE_EXTRA_STRING, "");
sDefaults.putString(KEY_CI_ACTION_ON_SYS_UPDATE_EXTRA_VAL_STRING, "");
sDefaults.putBoolean(KEY_CSP_ENABLED_BOOL, false);
+ sDefaults.putBoolean(KEY_ALLOW_ADDING_APNS_BOOL, true);
+ sDefaults.putBoolean(KEY_ALWAYS_SHOW_EMERGENCY_ALERT_ONOFF_BOOL, false);
sDefaults.putStringArray(KEY_GSM_ROAMING_NETWORKS_STRING_ARRAY, null);
sDefaults.putStringArray(KEY_GSM_NONROAMING_NETWORKS_STRING_ARRAY, null);
sDefaults.putStringArray(KEY_CDMA_ROAMING_NETWORKS_STRING_ARRAY, null);
sDefaults.putStringArray(KEY_CDMA_NONROAMING_NETWORKS_STRING_ARRAY, null);
sDefaults.putBoolean(KEY_FORCE_HOME_NETWORK_BOOL, false);
+ sDefaults.putInt(KEY_GSM_DTMF_TONE_DELAY_INT, 0);
+ sDefaults.putInt(KEY_IMS_DTMF_TONE_DELAY_INT, 0);
+ sDefaults.putBoolean(KEY_SUPPORT_CONFERENCE_CALL_BOOL, true);
+ sDefaults.putBoolean(KEY_EDITABLE_ENHANCED_4G_LTE_BOOL, true);
+ sDefaults.putBoolean(KEY_HIDE_IMS_APN_BOOL, false);
+ sDefaults.putBoolean(KEY_HIDE_PREFERRED_NETWORK_TYPE_BOOL, false);
+ sDefaults.putInt(KEY_CDMA_DTMF_TONE_DELAY_INT, 100);
// MMS defaults
sDefaults.putBoolean(KEY_MMS_ALIAS_ENABLED_BOOL, false);
@@ -463,6 +594,7 @@
sDefaults.putString(KEY_MMS_UA_PROF_TAG_NAME_STRING, "x-wap-profile");
sDefaults.putString(KEY_MMS_UA_PROF_URL_STRING, "");
sDefaults.putString(KEY_MMS_USER_AGENT_STRING, "");
+ sDefaults.putBoolean(KEY_ALLOW_NON_EMERGENCY_CALLS_IN_ECM_BOOL, true);
}
/**
diff --git a/telephony/java/android/telephony/PhoneNumberUtils.java b/telephony/java/android/telephony/PhoneNumberUtils.java
index 79146f3..b430340 100644
--- a/telephony/java/android/telephony/PhoneNumberUtils.java
+++ b/telephony/java/android/telephony/PhoneNumberUtils.java
@@ -1135,6 +1135,8 @@
"VI", // U.S. Virgin Islands
};
+ private static final String KOREA_ISO_COUNTRY_CODE = "KR";
+
/**
* Breaks the given number down and formats it according to the rules
* for the country the number is from.
@@ -1455,7 +1457,19 @@
String result = null;
try {
PhoneNumber pn = util.parseAndKeepRawInput(phoneNumber, defaultCountryIso);
- result = util.formatInOriginalFormat(pn, defaultCountryIso);
+ /**
+ * Need to reformat any local Korean phone numbers (when the user is in Korea) with
+ * country code to corresponding national format which would replace the leading
+ * +82 with 0.
+ */
+ if (KOREA_ISO_COUNTRY_CODE.equals(defaultCountryIso) &&
+ (pn.getCountryCode() == util.getCountryCodeForRegion(KOREA_ISO_COUNTRY_CODE)) &&
+ (pn.getCountryCodeSource() ==
+ PhoneNumber.CountryCodeSource.FROM_NUMBER_WITH_PLUS_SIGN)) {
+ result = util.format(pn, PhoneNumberUtil.PhoneNumberFormat.NATIONAL);
+ } else {
+ result = util.formatInOriginalFormat(pn, defaultCountryIso);
+ }
} catch (NumberParseException e) {
}
return result;
diff --git a/telephony/java/android/telephony/RadioAccessFamily.java b/telephony/java/android/telephony/RadioAccessFamily.java
index 0c5c557..2bfaf1b 100644
--- a/telephony/java/android/telephony/RadioAccessFamily.java
+++ b/telephony/java/android/telephony/RadioAccessFamily.java
@@ -185,6 +185,36 @@
case RILConstants.NETWORK_MODE_GLOBAL:
raf = GSM | WCDMA | CDMA | EVDO;
break;
+ case RILConstants.NETWORK_MODE_TDSCDMA_ONLY:
+ raf = RAF_TD_SCDMA;
+ break;
+ case RILConstants.NETWORK_MODE_TDSCDMA_WCDMA:
+ raf = RAF_TD_SCDMA | WCDMA;
+ break;
+ case RILConstants.NETWORK_MODE_LTE_TDSCDMA:
+ raf = RAF_LTE | RAF_TD_SCDMA;
+ break;
+ case RILConstants.NETWORK_MODE_TDSCDMA_GSM:
+ raf = RAF_TD_SCDMA | GSM;
+ break;
+ case RILConstants.NETWORK_MODE_LTE_TDSCDMA_GSM:
+ raf = RAF_LTE | RAF_TD_SCDMA | GSM;
+ break;
+ case RILConstants.NETWORK_MODE_TDSCDMA_GSM_WCDMA:
+ raf = RAF_TD_SCDMA | GSM | WCDMA;
+ break;
+ case RILConstants.NETWORK_MODE_LTE_TDSCDMA_WCDMA:
+ raf = RAF_LTE | RAF_TD_SCDMA | WCDMA;
+ break;
+ case RILConstants.NETWORK_MODE_LTE_TDSCDMA_GSM_WCDMA:
+ raf = RAF_LTE | RAF_TD_SCDMA | GSM | WCDMA;
+ break;
+ case RILConstants.NETWORK_MODE_TDSCDMA_CDMA_EVDO_GSM_WCDMA:
+ raf = RAF_TD_SCDMA | CDMA | EVDO | GSM | WCDMA;
+ break;
+ case RILConstants.NETWORK_MODE_LTE_TDSCDMA_CDMA_EVDO_GSM_WCDMA:
+ raf = RAF_LTE | RAF_TD_SCDMA | CDMA | EVDO | GSM | WCDMA;
+ break;
default:
raf = RAF_UNKNOWN;
break;
@@ -248,6 +278,36 @@
case (GSM | WCDMA | CDMA | EVDO):
type = RILConstants.NETWORK_MODE_GLOBAL;
break;
+ case RAF_TD_SCDMA:
+ type = RILConstants.NETWORK_MODE_TDSCDMA_ONLY;
+ break;
+ case (RAF_TD_SCDMA | WCDMA):
+ type = RILConstants.NETWORK_MODE_TDSCDMA_WCDMA;
+ break;
+ case (RAF_LTE | RAF_TD_SCDMA):
+ type = RILConstants.NETWORK_MODE_LTE_TDSCDMA;
+ break;
+ case (RAF_TD_SCDMA | GSM):
+ type = RILConstants.NETWORK_MODE_TDSCDMA_GSM;
+ break;
+ case (RAF_LTE | RAF_TD_SCDMA | GSM):
+ type = RILConstants.NETWORK_MODE_LTE_TDSCDMA_GSM;
+ break;
+ case (RAF_TD_SCDMA | GSM | WCDMA):
+ type = RILConstants.NETWORK_MODE_TDSCDMA_GSM_WCDMA;
+ break;
+ case (RAF_LTE | RAF_TD_SCDMA | WCDMA):
+ type = RILConstants.NETWORK_MODE_LTE_TDSCDMA_WCDMA;
+ break;
+ case (RAF_LTE | RAF_TD_SCDMA | GSM | WCDMA):
+ type = RILConstants.NETWORK_MODE_LTE_TDSCDMA_GSM_WCDMA;
+ break;
+ case (RAF_TD_SCDMA | CDMA | EVDO | GSM | WCDMA):
+ type = RILConstants.NETWORK_MODE_TDSCDMA_CDMA_EVDO_GSM_WCDMA;
+ break;
+ case (RAF_LTE | RAF_TD_SCDMA | RAF_LTE | CDMA | EVDO | GSM | WCDMA):
+ type = RILConstants.NETWORK_MODE_LTE_TDSCDMA_CDMA_EVDO_GSM_WCDMA;
+ break;
default:
type = RILConstants.PREFERRED_NETWORK_MODE ;
break;
diff --git a/telephony/java/android/telephony/ServiceState.java b/telephony/java/android/telephony/ServiceState.java
index 80515cf..1337487 100644
--- a/telephony/java/android/telephony/ServiceState.java
+++ b/telephony/java/android/telephony/ServiceState.java
@@ -731,6 +731,9 @@
case RIL_RADIO_TECHNOLOGY_IWLAN:
rtString = "IWLAN";
break;
+ case RIL_RADIO_TECHNOLOGY_TD_SCDMA:
+ rtString = "TD-SCDMA";
+ break;
default:
rtString = "Unexpected";
Rlog.w(LOG_TAG, "Unexpected radioTechnology=" + rt);
@@ -1068,6 +1071,8 @@
return TelephonyManager.NETWORK_TYPE_HSPAP;
case ServiceState.RIL_RADIO_TECHNOLOGY_GSM:
return TelephonyManager.NETWORK_TYPE_GSM;
+ case ServiceState.RIL_RADIO_TECHNOLOGY_TD_SCDMA:
+ return TelephonyManager.NETWORK_TYPE_TD_SCDMA;
case ServiceState.RIL_RADIO_TECHNOLOGY_IWLAN:
return TelephonyManager.NETWORK_TYPE_IWLAN;
default:
diff --git a/telephony/java/android/telephony/SignalStrength.java b/telephony/java/android/telephony/SignalStrength.java
index f02d109..fced667 100644
--- a/telephony/java/android/telephony/SignalStrength.java
+++ b/telephony/java/android/telephony/SignalStrength.java
@@ -68,6 +68,7 @@
private int mLteRsrq;
private int mLteRssnr;
private int mLteCqi;
+ private int mTdScdmaRscp;
private boolean isGsm; // This value is set by the ServiceStateTracker onSignalStrengthResult
@@ -107,6 +108,7 @@
mLteRsrq = INVALID;
mLteRssnr = INVALID;
mLteCqi = INVALID;
+ mTdScdmaRscp = INVALID;
isGsm = true;
}
@@ -131,6 +133,7 @@
mLteRsrq = INVALID;
mLteRssnr = INVALID;
mLteCqi = INVALID;
+ mTdScdmaRscp = INVALID;
isGsm = gsmFlag;
}
@@ -143,6 +146,22 @@
int cdmaDbm, int cdmaEcio,
int evdoDbm, int evdoEcio, int evdoSnr,
int lteSignalStrength, int lteRsrp, int lteRsrq, int lteRssnr, int lteCqi,
+ int tdScdmaRscp, boolean gsmFlag) {
+ initialize(gsmSignalStrength, gsmBitErrorRate, cdmaDbm, cdmaEcio,
+ evdoDbm, evdoEcio, evdoSnr, lteSignalStrength, lteRsrp,
+ lteRsrq, lteRssnr, lteCqi, gsmFlag);
+ mTdScdmaRscp = tdScdmaRscp;
+ }
+
+ /**
+ * Constructor
+ *
+ * @hide
+ */
+ public SignalStrength(int gsmSignalStrength, int gsmBitErrorRate,
+ int cdmaDbm, int cdmaEcio,
+ int evdoDbm, int evdoEcio, int evdoSnr,
+ int lteSignalStrength, int lteRsrp, int lteRsrq, int lteRssnr, int lteCqi,
boolean gsmFlag) {
initialize(gsmSignalStrength, gsmBitErrorRate, cdmaDbm, cdmaEcio,
evdoDbm, evdoEcio, evdoSnr, lteSignalStrength, lteRsrp,
@@ -233,6 +252,7 @@
mLteRsrq = lteRsrq;
mLteRssnr = lteRssnr;
mLteCqi = lteCqi;
+ mTdScdmaRscp = INVALID;
isGsm = gsm;
if (DBG) log("initialize: " + toString());
}
@@ -253,6 +273,7 @@
mLteRsrq = s.mLteRsrq;
mLteRssnr = s.mLteRssnr;
mLteCqi = s.mLteCqi;
+ mTdScdmaRscp = s.mTdScdmaRscp;
isGsm = s.isGsm;
}
@@ -276,6 +297,7 @@
mLteRsrq = in.readInt();
mLteRssnr = in.readInt();
mLteCqi = in.readInt();
+ mTdScdmaRscp = in.readInt();
isGsm = (in.readInt() != 0);
}
@@ -302,7 +324,7 @@
ss.mLteRsrq = in.readInt();
ss.mLteRssnr = in.readInt();
ss.mLteCqi = in.readInt();
-
+ ss.mTdScdmaRscp = in.readInt();
return ss;
}
@@ -322,6 +344,7 @@
out.writeInt(mLteRsrq);
out.writeInt(mLteRssnr);
out.writeInt(mLteCqi);
+ out.writeInt(mTdScdmaRscp);
out.writeInt(isGsm ? 1 : 0);
}
@@ -377,6 +400,9 @@
mLteRsrq = ((mLteRsrq >= 3) && (mLteRsrq <= 20)) ? -mLteRsrq : SignalStrength.INVALID;
mLteRssnr = ((mLteRssnr >= -200) && (mLteRssnr <= 300)) ? mLteRssnr
: SignalStrength.INVALID;
+
+ mTdScdmaRscp = ((mTdScdmaRscp >= 25) && (mTdScdmaRscp <= 120))
+ ? -mTdScdmaRscp : SignalStrength.INVALID;
// Cqi no change
if (DBG) log("Signal after validate=" + this);
}
@@ -477,12 +503,15 @@
* while 4 represents a very strong signal strength.
*/
public int getLevel() {
- int level;
+ int level = 0;
if (isGsm) {
level = getLteLevel();
if (level == SIGNAL_STRENGTH_NONE_OR_UNKNOWN) {
- level = getGsmLevel();
+ level = getTdScdmaLevel();
+ if (level == SIGNAL_STRENGTH_NONE_OR_UNKNOWN) {
+ level = getGsmLevel();
+ }
}
} else {
int cdmaLevel = getCdmaLevel();
@@ -508,10 +537,14 @@
* @hide
*/
public int getAsuLevel() {
- int asuLevel;
+ int asuLevel = 0;
if (isGsm) {
if (getLteLevel() == SIGNAL_STRENGTH_NONE_OR_UNKNOWN) {
- asuLevel = getGsmAsuLevel();
+ if (getTdScdmaLevel() == SIGNAL_STRENGTH_NONE_OR_UNKNOWN) {
+ asuLevel = getGsmAsuLevel();
+ } else {
+ asuLevel = getTdScdmaAsuLevel();
+ }
} else {
asuLevel = getLteAsuLevel();
}
@@ -539,12 +572,16 @@
* @hide
*/
public int getDbm() {
- int dBm;
+ int dBm = INVALID;
if(isGsm()) {
dBm = getLteDbm();
if (dBm == INVALID) {
- dBm = getGsmDbm();
+ if (getTdScdmaLevel() == SIGNAL_STRENGTH_NONE_OR_UNKNOWN) {
+ dBm = getGsmDbm();
+ } else {
+ dBm = getTdScdmaDbm();
+ }
}
} else {
int cdmaDbm = getCdmaDbm();
@@ -849,6 +886,54 @@
}
/**
+ * @return get TD_SCDMA dbm
+ *
+ * @hide
+ */
+ public int getTdScdmaDbm() {
+ return this.mTdScdmaRscp;
+ }
+
+ /**
+ * Get TD-SCDMA as level 0..4
+ * Range : 25 to 120
+ * INT_MAX: 0x7FFFFFFF denotes invalid value
+ * Reference: 3GPP TS 25.123, section 9.1.1.1
+ *
+ * @hide
+ */
+ public int getTdScdmaLevel() {
+ final int tdScdmaDbm = getTdScdmaDbm();
+ int level;
+
+ if ((tdScdmaDbm > -25) || (tdScdmaDbm == SignalStrength.INVALID))
+ level = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
+ else if (tdScdmaDbm >= -49) level = SIGNAL_STRENGTH_GREAT;
+ else if (tdScdmaDbm >= -73) level = SIGNAL_STRENGTH_GOOD;
+ else if (tdScdmaDbm >= -97) level = SIGNAL_STRENGTH_MODERATE;
+ else if (tdScdmaDbm >= -110) level = SIGNAL_STRENGTH_POOR;
+ else level = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
+
+ if (DBG) log("getTdScdmaLevel = " + level);
+ return level;
+ }
+
+ /**
+ * Get the TD-SCDMA signal level as an asu value.
+ *
+ * @hide
+ */
+ public int getTdScdmaAsuLevel() {
+ final int tdScdmaDbm = getTdScdmaDbm();
+ int tdScdmaAsuLevel;
+
+ if (tdScdmaDbm == INVALID) tdScdmaAsuLevel = 255;
+ else tdScdmaAsuLevel = tdScdmaDbm + 120;
+ if (DBG) log("TD-SCDMA Asu level: " + tdScdmaAsuLevel);
+ return tdScdmaAsuLevel;
+ }
+
+ /**
* @return hash code
*/
@Override
@@ -860,7 +945,7 @@
+ (mEvdoDbm * primeNum) + (mEvdoEcio * primeNum) + (mEvdoSnr * primeNum)
+ (mLteSignalStrength * primeNum) + (mLteRsrp * primeNum)
+ (mLteRsrq * primeNum) + (mLteRssnr * primeNum) + (mLteCqi * primeNum)
- + (isGsm ? 1 : 0));
+ + (mTdScdmaRscp * primeNum) + (isGsm ? 1 : 0));
}
/**
@@ -892,6 +977,7 @@
&& mLteRsrq == s.mLteRsrq
&& mLteRssnr == s.mLteRssnr
&& mLteCqi == s.mLteCqi
+ && mTdScdmaRscp == s.mTdScdmaRscp
&& isGsm == s.isGsm);
}
@@ -913,6 +999,7 @@
+ " " + mLteRsrq
+ " " + mLteRssnr
+ " " + mLteCqi
+ + " " + mTdScdmaRscp
+ " " + (isGsm ? "gsm|lte" : "cdma"));
}
@@ -935,6 +1022,7 @@
mLteRsrq = m.getInt("LteRsrq");
mLteRssnr = m.getInt("LteRssnr");
mLteCqi = m.getInt("LteCqi");
+ mTdScdmaRscp = m.getInt("TdScdma");
isGsm = m.getBoolean("isGsm");
}
@@ -957,6 +1045,7 @@
m.putInt("LteRsrq", mLteRsrq);
m.putInt("LteRssnr", mLteRssnr);
m.putInt("LteCqi", mLteCqi);
+ m.putInt("TdScdma", mTdScdmaRscp);
m.putBoolean("isGsm", Boolean.valueOf(isGsm));
}
diff --git a/telephony/java/android/telephony/SubscriptionInfo.java b/telephony/java/android/telephony/SubscriptionInfo.java
index 37ffa06..d1d6e0d 100644
--- a/telephony/java/android/telephony/SubscriptionInfo.java
+++ b/telephony/java/android/telephony/SubscriptionInfo.java
@@ -332,9 +332,25 @@
return 0;
}
+ /**
+ * @hide
+ */
+ public static String givePrintableIccid(String iccId) {
+ String iccIdToPrint = null;
+ if (iccId != null) {
+ if (iccId.length() > 9) {
+ iccIdToPrint = iccId.substring(0, 9) + "XXXXXXXXXXX";
+ } else {
+ iccIdToPrint = iccId;
+ }
+ }
+ return iccIdToPrint;
+ }
+
@Override
public String toString() {
- return "{id=" + mId + ", iccId=" + mIccId + " simSlotIndex=" + mSimSlotIndex
+ String iccIdToPrint = givePrintableIccid(mIccId);
+ return "{id=" + mId + ", iccId=" + iccIdToPrint + " simSlotIndex=" + mSimSlotIndex
+ " displayName=" + mDisplayName + " carrierName=" + mCarrierName
+ " nameSource=" + mNameSource + " iconTint=" + mIconTint
+ " dataRoaming=" + mDataRoaming + " iconBitmap=" + mIconBitmap + " mcc " + mMcc
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index 7f724f1..2e25ec7 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -1059,11 +1059,21 @@
case RILConstants.NETWORK_MODE_LTE_GSM_WCDMA:
case RILConstants.NETWORK_MODE_LTE_WCDMA:
case RILConstants.NETWORK_MODE_LTE_CDMA_EVDO_GSM_WCDMA:
+ case RILConstants.NETWORK_MODE_TDSCDMA_ONLY:
+ case RILConstants.NETWORK_MODE_TDSCDMA_WCDMA:
+ case RILConstants.NETWORK_MODE_LTE_TDSCDMA:
+ case RILConstants.NETWORK_MODE_TDSCDMA_GSM:
+ case RILConstants.NETWORK_MODE_LTE_TDSCDMA_GSM:
+ case RILConstants.NETWORK_MODE_TDSCDMA_GSM_WCDMA:
+ case RILConstants.NETWORK_MODE_LTE_TDSCDMA_WCDMA:
+ case RILConstants.NETWORK_MODE_LTE_TDSCDMA_GSM_WCDMA:
+ case RILConstants.NETWORK_MODE_LTE_TDSCDMA_CDMA_EVDO_GSM_WCDMA:
return PhoneConstants.PHONE_TYPE_GSM;
// Use CDMA Phone for the global mode including CDMA
case RILConstants.NETWORK_MODE_GLOBAL:
case RILConstants.NETWORK_MODE_LTE_CDMA_EVDO:
+ case RILConstants.NETWORK_MODE_TDSCDMA_CDMA_EVDO_GSM_WCDMA:
return PhoneConstants.PHONE_TYPE_CDMA;
case RILConstants.NETWORK_MODE_LTE_ONLY:
@@ -2824,7 +2834,7 @@
/**
* Returns all observed cell information from all radios on the
* device including the primary and neighboring cells. This does
- * not cause or change the rate of PhoneStateListner#onCellInfoChanged.
+ * not cause or change the rate of PhoneStateListener#onCellInfoChanged.
*<p>
* The list can include one or more of {@link android.telephony.CellInfoGsm CellInfoGsm},
* {@link android.telephony.CellInfoCdma CellInfoCdma},
@@ -2838,6 +2848,9 @@
* devices this may return null in which case getCellLocation should
* be called.
*<p>
+ * This API will return valid data for registered cells on devices with
+ * {@link android.content.pm.PackageManager#FEATURE_TELEPHONY}
+ *<p>
* @return List of CellInfo or null if info unavailable.
*
* <p>Requires Permission: {@link android.Manifest.permission#ACCESS_COARSE_LOCATION}
@@ -3561,11 +3574,12 @@
*
* @hide
*/
- public boolean setNetworkSelectionModeManual(int subId, OperatorInfo operator) {
+ public boolean setNetworkSelectionModeManual(int subId, OperatorInfo operator,
+ boolean persistSelection) {
try {
ITelephony telephony = getITelephony();
if (telephony != null)
- return telephony.setNetworkSelectionModeManual(subId, operator);
+ return telephony.setNetworkSelectionModeManual(subId, operator, persistSelection);
} catch (RemoteException ex) {
Rlog.e(TAG, "setNetworkSelectionModeManual RemoteException", ex);
} catch (NullPointerException ex) {
@@ -4352,13 +4366,13 @@
}
}
- /**
- * Returns the Status of Volte
- *@hide
- */
- public boolean isVolteEnabled() {
+ /**
+ * Returns the Status of Volte
+ * @hide
+ */
+ public boolean isVolteAvailable() {
try {
- return getITelephony().isVolteEnabled();
+ return getITelephony().isVolteAvailable();
} catch (RemoteException ex) {
return false;
} catch (NullPointerException ex) {
@@ -4366,13 +4380,27 @@
}
}
- /**
- * Returns the Status of Wi-Fi Calling
- *@hide
- */
- public boolean isWifiCallingEnabled() {
+ /**
+ * Returns the Status of video telephony (VT)
+ * @hide
+ */
+ public boolean isVideoTelephonyAvailable() {
+ try {
+ return getITelephony().isVideoTelephonyAvailable();
+ } catch (RemoteException ex) {
+ return false;
+ } catch (NullPointerException ex) {
+ return false;
+ }
+ }
+
+ /**
+ * Returns the Status of Wi-Fi Calling
+ * @hide
+ */
+ public boolean isWifiCallingAvailable() {
try {
- return getITelephony().isWifiCallingEnabled();
+ return getITelephony().isWifiCallingAvailable();
} catch (RemoteException ex) {
return false;
} catch (NullPointerException ex) {
diff --git a/telephony/java/com/android/ims/ImsCallProfile.java b/telephony/java/com/android/ims/ImsCallProfile.java
index 2c4354b..5f84e0c 100644
--- a/telephony/java/com/android/ims/ImsCallProfile.java
+++ b/telephony/java/com/android/ims/ImsCallProfile.java
@@ -174,11 +174,35 @@
* cna : Calling name
* ussd : For network-initiated USSD, MT only
* remote_uri : Connected user identity (it can be used for the conference)
+ * ChildNum: Child number info.
+ * Codec: Codec info.
+ * DisplayText: Display text for the call.
+ * AdditionalCallInfo: Additional call info.
+ * CallRadioTech: The radio tech on which the call is placed.
*/
public static final String EXTRA_OI = "oi";
public static final String EXTRA_CNA = "cna";
public static final String EXTRA_USSD = "ussd";
public static final String EXTRA_REMOTE_URI = "remote_uri";
+ public static final String EXTRA_CHILD_NUMBER = "ChildNum";
+ public static final String EXTRA_CODEC = "Codec";
+ public static final String EXTRA_DISPLAY_TEXT = "DisplayText";
+ public static final String EXTRA_ADDITIONAL_CALL_INFO = "AdditionalCallInfo";
+
+ /**
+ * Extra key which the RIL can use to indicate the radio technology used for a call.
+ * Valid values are:
+ * {@link android.telephony.ServiceState#RIL_RADIO_TECHNOLOGY_LTE},
+ * {@link android.telephony.ServiceState#RIL_RADIO_TECHNOLOGY_IWLAN}, and the other defined
+ * {@code RIL_RADIO_TECHNOLOGY_*} constants.
+ * Note: Despite the fact the {@link android.telephony.ServiceState} values are integer
+ * constants, the values passed for the {@link #EXTRA_CALL_RAT_TYPE} should be strings (e.g.
+ * "14" vs (int) 14).
+ * Note: This is used by {@link com.android.internal.telephony.imsphone.ImsPhoneConnection#
+ * updateWifiStateFromExtras(Bundle)} to determine whether to set the
+ * {@link android.telecom.Connection#CAPABILITY_WIFI} capability on a connection.
+ */
+ public static final String EXTRA_CALL_RAT_TYPE = "CallRadioTech";
public int mServiceType;
public int mCallType;
diff --git a/telephony/java/com/android/ims/ImsReasonInfo.java b/telephony/java/com/android/ims/ImsReasonInfo.java
index 9628915..2769a2b 100644
--- a/telephony/java/com/android/ims/ImsReasonInfo.java
+++ b/telephony/java/com/android/ims/ImsReasonInfo.java
@@ -99,6 +99,9 @@
// MT : No action from user after alerting the call
public static final int CODE_TIMEOUT_NO_ANSWER_CALL_UPDATE = 203;
+ //Call failures for FDN
+ public static final int CODE_FDN_BLOCKED = 241;
+
/**
* STATUSCODE (SIP response code) (IMS -> Telephony)
*/
@@ -227,6 +230,12 @@
public static final int CODE_CALL_DROP_IWLAN_TO_LTE_UNAVAILABLE = 1100;
/**
+ * MT call has ended due to a release from the network
+ * because the call was answered elsewhere
+ */
+ public static final int CODE_ANSWERED_ELSEWHERE = 1014;
+
+ /**
* Network string error messages.
* mExtraMessage may have these values.
*/
diff --git a/telephony/java/com/android/ims/ImsSsInfo.java b/telephony/java/com/android/ims/ImsSsInfo.java
index dbde1c6..7acc3bf 100644
--- a/telephony/java/com/android/ims/ImsSsInfo.java
+++ b/telephony/java/com/android/ims/ImsSsInfo.java
@@ -34,6 +34,7 @@
// 0: disabled, 1: enabled
public int mStatus;
+ public String mIcbNum;
public ImsSsInfo() {
}
@@ -50,6 +51,7 @@
@Override
public void writeToParcel(Parcel out, int flags) {
out.writeInt(mStatus);
+ out.writeString(mIcbNum);
}
@Override
@@ -59,6 +61,7 @@
private void readFromParcel(Parcel in) {
mStatus = in.readInt();
+ mIcbNum = in.readString();
}
public static final Creator<ImsSsInfo> CREATOR =
diff --git a/telephony/java/com/android/ims/ImsSuppServiceNotification.aidl b/telephony/java/com/android/ims/ImsSuppServiceNotification.aidl
new file mode 100644
index 0000000..6b4479f
--- /dev/null
+++ b/telephony/java/com/android/ims/ImsSuppServiceNotification.aidl
@@ -0,0 +1,20 @@
+/*
+ * Copyright (c) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+package com.android.ims;
+
+parcelable ImsSuppServiceNotification;
diff --git a/telephony/java/com/android/ims/ImsSuppServiceNotification.java b/telephony/java/com/android/ims/ImsSuppServiceNotification.java
new file mode 100644
index 0000000..faf7499
--- /dev/null
+++ b/telephony/java/com/android/ims/ImsSuppServiceNotification.java
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+package com.android.ims;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.util.Arrays;
+
+
+/**
+ * Parcelable object to handle IMS supplementary service notifications.
+ *
+ * @hide
+ */
+public class ImsSuppServiceNotification implements Parcelable {
+ private static final String TAG = "ImsSuppServiceNotification";
+
+ /** Type of notification: 0 = MO; 1 = MT */
+ public int notificationType;
+ /** TS 27.007 7.17 "code1" or "code2" */
+ public int code;
+ /** TS 27.007 7.17 "index" - Not used currently*/
+ public int index;
+ /** TS 27.007 7.17 "type" (MT only) - Not used currently */
+ public int type;
+ /** TS 27.007 7.17 "number" (MT only) */
+ public String number;
+ /** List of forwarded numbers, if any */
+ public String[] history;
+
+ public ImsSuppServiceNotification() {
+ }
+
+ public ImsSuppServiceNotification(Parcel in) {
+ readFromParcel(in);
+ }
+
+ @Override
+ public String toString() {
+ return "{ notificationType=" + notificationType +
+ ", code=" + code +
+ ", index=" + index +
+ ", type=" + type +
+ ", number=" + number +
+ ", history=" + Arrays.toString(history) +
+ " }";
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel out, int flags) {
+ out.writeInt(notificationType);
+ out.writeInt(code);
+ out.writeInt(index);
+ out.writeInt(type);
+ out.writeString(number);
+ out.writeStringArray(history);
+ }
+
+ private void readFromParcel(Parcel in) {
+ notificationType = in.readInt();
+ code = in.readInt();
+ index = in.readInt();
+ type = in.readInt();
+ number = in.readString();
+ history = in.createStringArray();
+ }
+
+ public static final Creator<ImsSuppServiceNotification> CREATOR =
+ new Creator<ImsSuppServiceNotification>() {
+ @Override
+ public ImsSuppServiceNotification createFromParcel(Parcel in) {
+ return new ImsSuppServiceNotification(in);
+ }
+
+ @Override
+ public ImsSuppServiceNotification[] newArray(int size) {
+ return new ImsSuppServiceNotification[size];
+ }
+ };
+}
diff --git a/telephony/java/com/android/ims/internal/IImsCallSessionListener.aidl b/telephony/java/com/android/ims/internal/IImsCallSessionListener.aidl
index 0443c3e..d562ecc 100644
--- a/telephony/java/com/android/ims/internal/IImsCallSessionListener.aidl
+++ b/telephony/java/com/android/ims/internal/IImsCallSessionListener.aidl
@@ -21,6 +21,7 @@
import com.android.ims.ImsReasonInfo;
import com.android.ims.ImsConferenceState;
import com.android.ims.internal.IImsCallSession;
+import com.android.ims.ImsSuppServiceNotification;
/**
* A listener type for receiving notification on IMS call session events.
@@ -123,4 +124,10 @@
* @param isMultiParty {@code true} if the session became multiparty, {@code false} otherwise.
*/
void callSessionMultipartyStateChanged(in IImsCallSession session, in boolean isMultiParty);
+
+ /**
+ * Notifies the supplementary service information for the current session.
+ */
+ void callSessionSuppServiceReceived(in IImsCallSession session,
+ in ImsSuppServiceNotification suppSrvNotification);
}
diff --git a/telephony/java/com/android/ims/internal/IImsRegistrationListener.aidl b/telephony/java/com/android/ims/internal/IImsRegistrationListener.aidl
index c910600..23a69d1 100644
--- a/telephony/java/com/android/ims/internal/IImsRegistrationListener.aidl
+++ b/telephony/java/com/android/ims/internal/IImsRegistrationListener.aidl
@@ -71,5 +71,11 @@
* @param disabledFeatures features disabled as defined in com.android.ims.ImsConfig#FeatureConstants.
*/
void registrationFeatureCapabilityChanged(int serviceClass,
- out int[] enabledFeatures, out int[] disabledFeatures);
+ in int[] enabledFeatures, in int[] disabledFeatures);
+
+ /**
+ * Updates the application with the waiting voice message count.
+ * @param count The number of waiting voice messages.
+ */
+ void voiceMessageCountUpdate(int count);
}
diff --git a/telephony/java/com/android/ims/internal/IImsUt.aidl b/telephony/java/com/android/ims/internal/IImsUt.aidl
index c531ea5..4ab5ee3 100644
--- a/telephony/java/com/android/ims/internal/IImsUt.aidl
+++ b/telephony/java/com/android/ims/internal/IImsUt.aidl
@@ -74,7 +74,7 @@
/**
* Updates the configuration of the call barring.
*/
- int updateCallBarring(int cbType, boolean enable, in String[] barrList);
+ int updateCallBarring(int cbType, int action, in String[] barrList);
/**
* Updates the configuration of the call forward.
diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl
index a93e465..dcece26 100644
--- a/telephony/java/com/android/internal/telephony/ITelephony.aidl
+++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl
@@ -707,9 +707,13 @@
*
* @param subId the id of the subscription.
* @param operatorInfo the operator to attach to.
+ * @param persistSelection should the selection persist till reboot or its
+ * turned off? Will also result in notification being not shown to
+ * the user if the signal is lost.
* @return true if the request suceeded.
*/
- boolean setNetworkSelectionModeManual(int subId, in OperatorInfo operator);
+ boolean setNetworkSelectionModeManual(int subId, in OperatorInfo operator,
+ boolean persistSelection);
/**
* Set the preferred network type.
@@ -951,6 +955,7 @@
* @return {@code true} if the device supports hearing aid compatibility.
*/
boolean isHearingAidCompatibilitySupported();
+
/**
* Get IMS Registration Status
*/
@@ -958,15 +963,18 @@
/**
* Returns the Status of Wi-Fi Calling
- *@hide
*/
- boolean isWifiCallingEnabled();
+ boolean isWifiCallingAvailable();
+
+ /**
+ * Returns the Status of Volte
+ */
+ boolean isVolteAvailable();
/**
- * Returns the Status of Volte
- *@hide
+ * Returns the Status of VT (video telephony)
*/
- boolean isVolteEnabled();
+ boolean isVideoTelephonyAvailable();
/**
* Returns the unique device ID of phone, for example, the IMEI for
@@ -995,7 +1003,6 @@
/**
* Return the modem activity info.
- *@hide
*/
ModemActivityInfo getModemActivityInfo();
}
diff --git a/telephony/java/com/android/internal/telephony/RILConstants.java b/telephony/java/com/android/internal/telephony/RILConstants.java
index 8d48c86..7088be8 100644
--- a/telephony/java/com/android/internal/telephony/RILConstants.java
+++ b/telephony/java/com/android/internal/telephony/RILConstants.java
@@ -96,6 +96,16 @@
int NETWORK_MODE_LTE_CDMA_EVDO_GSM_WCDMA = 10; /* LTE, CDMA, EvDo, GSM/WCDMA */
int NETWORK_MODE_LTE_ONLY = 11; /* LTE Only mode. */
int NETWORK_MODE_LTE_WCDMA = 12; /* LTE/WCDMA */
+ int NETWORK_MODE_TDSCDMA_ONLY = 13; /* TD-SCDMA only */
+ int NETWORK_MODE_TDSCDMA_WCDMA = 14; /* TD-SCDMA and WCDMA */
+ int NETWORK_MODE_LTE_TDSCDMA = 15; /* TD-SCDMA and LTE */
+ int NETWORK_MODE_TDSCDMA_GSM = 16; /* TD-SCDMA and GSM */
+ int NETWORK_MODE_LTE_TDSCDMA_GSM = 17; /* TD-SCDMA,GSM and LTE */
+ int NETWORK_MODE_TDSCDMA_GSM_WCDMA = 18; /* TD-SCDMA, GSM/WCDMA */
+ int NETWORK_MODE_LTE_TDSCDMA_WCDMA = 19; /* TD-SCDMA, WCDMA and LTE */
+ int NETWORK_MODE_LTE_TDSCDMA_GSM_WCDMA = 20; /* TD-SCDMA, GSM/WCDMA and LTE */
+ int NETWORK_MODE_TDSCDMA_CDMA_EVDO_GSM_WCDMA = 21; /*TD-SCDMA,EvDo,CDMA,GSM/WCDMA*/
+ int NETWORK_MODE_LTE_TDSCDMA_CDMA_EVDO_GSM_WCDMA = 22; /* TD-SCDMA/LTE/GSM/WCDMA, CDMA, and EvDo */
int PREFERRED_NETWORK_MODE = SystemProperties.getInt("ro.telephony.default_network",
NETWORK_MODE_WCDMA_PREF);
diff --git a/tests/CameraPrewarmTest/src/com/google/android/test/cameraprewarm/CameraActivity.java b/tests/CameraPrewarmTest/src/com/google/android/test/cameraprewarm/CameraActivity.java
index 0b43666..8085db7 100644
--- a/tests/CameraPrewarmTest/src/com/google/android/test/cameraprewarm/CameraActivity.java
+++ b/tests/CameraPrewarmTest/src/com/google/android/test/cameraprewarm/CameraActivity.java
@@ -31,5 +31,7 @@
super.onCreate(savedInstanceState);
setContentView(R.layout.camera_activity);
Log.i(TAG, "Activity created");
+ Log.i(TAG, "Source: "
+ + getIntent().getStringExtra("com.android.systemui.camera_launch_source"));
}
}
diff --git a/tests/CameraPrewarmTest/src/com/google/android/test/cameraprewarm/SecureCameraActivity.java b/tests/CameraPrewarmTest/src/com/google/android/test/cameraprewarm/SecureCameraActivity.java
index 530fe00..242d3b2 100644
--- a/tests/CameraPrewarmTest/src/com/google/android/test/cameraprewarm/SecureCameraActivity.java
+++ b/tests/CameraPrewarmTest/src/com/google/android/test/cameraprewarm/SecureCameraActivity.java
@@ -17,6 +17,7 @@
package com.google.android.test.cameraprewarm;
import android.app.Activity;
+import android.graphics.Camera;
import android.os.Bundle;
import android.util.Log;
import android.view.WindowManager;
@@ -31,5 +32,7 @@
setContentView(R.layout.camera_activity);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED);
Log.i(CameraActivity.TAG, "Activity created");
+ Log.i(CameraActivity.TAG, "Source: "
+ + getIntent().getStringExtra("com.android.systemui.camera_launch_source"));
}
}
diff --git a/wifi/java/android/net/wifi/WifiEnterpriseConfig.java b/wifi/java/android/net/wifi/WifiEnterpriseConfig.java
index 66d922e..a337755 100644
--- a/wifi/java/android/net/wifi/WifiEnterpriseConfig.java
+++ b/wifi/java/android/net/wifi/WifiEnterpriseConfig.java
@@ -101,9 +101,18 @@
public static final String REALM_KEY = "realm";
/** @hide */
public static final String PLMN_KEY = "plmn";
+ /** @hide */
+ public static final String PHASE1_KEY = "phase1";
+ /** {@hide} */
+ public static final String ENABLE_TLS_1_2 = "\"tls_disable_tlsv1_2=0\"";
+ /** {@hide} */
+ public static final String DISABLE_TLS_1_2 = "\"tls_disable_tlsv1_2=1\"";
private HashMap<String, String> mFields = new HashMap<String, String>();
+ //By default, we enable TLS1.2. However, due to a known bug on some radius, we may disable it to
+ // fall back to TLS 1.1.
+ private boolean mTls12Enable = true;
private X509Certificate mCaCert;
private PrivateKey mClientPrivateKey;
private X509Certificate mClientCertificate;
@@ -149,6 +158,7 @@
}
writeCertificate(dest, mClientCertificate);
+ dest.writeInt(mTls12Enable ? 1: 0);
}
private void writeCertificate(Parcel dest, X509Certificate cert) {
@@ -196,6 +206,7 @@
enterpriseConfig.mClientPrivateKey = userKey;
enterpriseConfig.mClientCertificate = readCertificate(in);
+ enterpriseConfig.mTls12Enable = (in.readInt() == 1);
return enterpriseConfig;
}
@@ -300,6 +311,26 @@
}
/**
+ * Set the TLS version
+ * @param enable: true -- enable TLS1.2 false -- disable TLS1.2
+ * @hide
+ */
+ public void setTls12Enable(boolean enable) {
+ mTls12Enable = enable;
+ mFields.put(PHASE1_KEY,
+ enable ? ENABLE_TLS_1_2 : DISABLE_TLS_1_2);
+ }
+
+ /**
+ * Get the TLS1.2 enabled or not
+ * @return eap method configured
+ * @hide
+ */
+ public boolean getTls12Enable() {
+ return mTls12Enable;
+ }
+
+ /**
* Get the eap method.
* @return eap method configured
*/