Merge "Add keycodes for diagonal dpad inputs"
diff --git a/api/current.txt b/api/current.txt
index d3c30bf..d468831 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -3360,6 +3360,7 @@
method public boolean isImmersive();
method public boolean isTaskRoot();
method public boolean isVoiceInteraction();
+ method public boolean isVoiceInteractionRoot();
method public final deprecated android.database.Cursor managedQuery(android.net.Uri, java.lang.String[], java.lang.String, java.lang.String[], java.lang.String);
method public boolean moveTaskToBack(boolean);
method public boolean navigateUpTo(android.content.Intent);
@@ -3430,6 +3431,7 @@
method public boolean onSearchRequested(android.view.SearchEvent);
method public boolean onSearchRequested();
method protected void onStart();
+ method public void onStateNotSaved();
method protected void onStop();
method protected void onTitleChanged(java.lang.CharSequence, int);
method public boolean onTouchEvent(android.view.MotionEvent);
@@ -22723,7 +22725,7 @@
field public static final int KITKAT_WATCH = 20; // 0x14
field public static final int LOLLIPOP = 21; // 0x15
field public static final int LOLLIPOP_MR1 = 22; // 0x16
- field public static final int MNC = 23; // 0x17
+ field public static final int M = 23; // 0x17
}
public final class Bundle extends android.os.BaseBundle implements java.lang.Cloneable android.os.Parcelable {
@@ -30113,7 +30115,6 @@
method public final void setConferenceableConnections(java.util.List<android.telecom.Connection>);
method public final void setConferenceables(java.util.List<android.telecom.Conferenceable>);
method public final void setConnectionCapabilities(int);
- method public final void setConnectionService(android.telecom.ConnectionService);
method public final void setDialing();
method public final void setDisconnected(android.telecom.DisconnectCause);
method public final void setExtras(android.os.Bundle);
@@ -30145,6 +30146,9 @@
field public static final int CAPABILITY_SUPPORTS_VT_REMOTE_TX = 2048; // 0x800
field public static final int CAPABILITY_SUPPORT_HOLD = 2; // 0x2
field public static final int CAPABILITY_SWAP_CONFERENCE = 8; // 0x8
+ field public static final java.lang.String EXTRA_CALL_SUBJECT = "android.telecom.extra.CALL_SUBJECT";
+ field public static final java.lang.String EXTRA_CHILD_ADDRESS = "android.telecom.extra.CHILD_ADDRESS";
+ field public static final java.lang.String EXTRA_LAST_FORWARDED_NUMBER = "android.telecom.extra.LAST_FORWARDED_NUMBER";
field public static final int STATE_ACTIVE = 4; // 0x4
field public static final int STATE_DIALING = 3; // 0x3
field public static final int STATE_DISCONNECTED = 6; // 0x6
@@ -30505,6 +30509,7 @@
field public static final java.lang.String EXTRA_CALL_BACK_NUMBER = "android.telecom.extra.CALL_BACK_NUMBER";
field public static final java.lang.String EXTRA_CALL_DISCONNECT_CAUSE = "android.telecom.extra.CALL_DISCONNECT_CAUSE";
field public static final java.lang.String EXTRA_CALL_DISCONNECT_MESSAGE = "android.telecom.extra.CALL_DISCONNECT_MESSAGE";
+ field public static final java.lang.String EXTRA_CALL_SUBJECT = "android.telecom.extra.CALL_SUBJECT";
field public static final java.lang.String EXTRA_CHANGE_DEFAULT_DIALER_PACKAGE_NAME = "android.telecom.extra.CHANGE_DEFAULT_DIALER_PACKAGE_NAME";
field public static final java.lang.String EXTRA_INCOMING_CALL_ADDRESS = "android.telecom.extra.INCOMING_CALL_ADDRESS";
field public static final java.lang.String EXTRA_INCOMING_CALL_EXTRAS = "android.telecom.extra.INCOMING_CALL_EXTRAS";
diff --git a/api/system-current.txt b/api/system-current.txt
index 9134433..4dd85e6 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -141,6 +141,7 @@
field public static final java.lang.String OVERRIDE_WIFI_CONFIG = "android.permission.OVERRIDE_WIFI_CONFIG";
field public static final java.lang.String PACKAGE_USAGE_STATS = "android.permission.PACKAGE_USAGE_STATS";
field public static final java.lang.String PACKAGE_VERIFICATION_AGENT = "android.permission.PACKAGE_VERIFICATION_AGENT";
+ field public static final java.lang.String PEERS_MAC_ADDRESS = "android.permission.PEERS_MAC_ADDRESS";
field public static final java.lang.String PERFORM_CDMA_PROVISIONING = "android.permission.PERFORM_CDMA_PROVISIONING";
field public static final java.lang.String PERFORM_SIM_ACTIVATION = "android.permission.PERFORM_SIM_ACTIVATION";
field public static final deprecated java.lang.String PERSISTENT_ACTIVITY = "android.permission.PERSISTENT_ACTIVITY";
@@ -3462,6 +3463,7 @@
method public boolean isImmersive();
method public boolean isTaskRoot();
method public boolean isVoiceInteraction();
+ method public boolean isVoiceInteractionRoot();
method public final deprecated android.database.Cursor managedQuery(android.net.Uri, java.lang.String[], java.lang.String, java.lang.String[], java.lang.String);
method public boolean moveTaskToBack(boolean);
method public boolean navigateUpTo(android.content.Intent);
@@ -3533,6 +3535,7 @@
method public boolean onSearchRequested(android.view.SearchEvent);
method public boolean onSearchRequested();
method protected void onStart();
+ method public void onStateNotSaved();
method protected void onStop();
method protected void onTitleChanged(java.lang.CharSequence, int);
method public boolean onTouchEvent(android.view.MotionEvent);
@@ -24668,7 +24671,7 @@
field public static final int KITKAT_WATCH = 20; // 0x14
field public static final int LOLLIPOP = 21; // 0x15
field public static final int LOLLIPOP_MR1 = 22; // 0x16
- field public static final int MNC = 23; // 0x17
+ field public static final int M = 23; // 0x17
}
public final class Bundle extends android.os.BaseBundle implements java.lang.Cloneable android.os.Parcelable {
@@ -32314,7 +32317,6 @@
method public final void setConferenceableConnections(java.util.List<android.telecom.Connection>);
method public final void setConferenceables(java.util.List<android.telecom.Conferenceable>);
method public final void setConnectionCapabilities(int);
- method public final void setConnectionService(android.telecom.ConnectionService);
method public final void setDialing();
method public final void setDisconnected(android.telecom.DisconnectCause);
method public final void setExtras(android.os.Bundle);
@@ -32346,6 +32348,9 @@
field public static final int CAPABILITY_SUPPORTS_VT_REMOTE_TX = 2048; // 0x800
field public static final int CAPABILITY_SUPPORT_HOLD = 2; // 0x2
field public static final int CAPABILITY_SWAP_CONFERENCE = 8; // 0x8
+ field public static final java.lang.String EXTRA_CALL_SUBJECT = "android.telecom.extra.CALL_SUBJECT";
+ field public static final java.lang.String EXTRA_CHILD_ADDRESS = "android.telecom.extra.CHILD_ADDRESS";
+ field public static final java.lang.String EXTRA_LAST_FORWARDED_NUMBER = "android.telecom.extra.LAST_FORWARDED_NUMBER";
field public static final int STATE_ACTIVE = 4; // 0x4
field public static final int STATE_DIALING = 3; // 0x3
field public static final int STATE_DISCONNECTED = 6; // 0x6
@@ -32754,6 +32759,7 @@
field public static final java.lang.String EXTRA_CALL_BACK_NUMBER = "android.telecom.extra.CALL_BACK_NUMBER";
field public static final java.lang.String EXTRA_CALL_DISCONNECT_CAUSE = "android.telecom.extra.CALL_DISCONNECT_CAUSE";
field public static final java.lang.String EXTRA_CALL_DISCONNECT_MESSAGE = "android.telecom.extra.CALL_DISCONNECT_MESSAGE";
+ field public static final java.lang.String EXTRA_CALL_SUBJECT = "android.telecom.extra.CALL_SUBJECT";
field public static final java.lang.String EXTRA_CHANGE_DEFAULT_DIALER_PACKAGE_NAME = "android.telecom.extra.CHANGE_DEFAULT_DIALER_PACKAGE_NAME";
field public static final java.lang.String EXTRA_CONNECTION_SERVICE = "android.telecom.extra.CONNECTION_SERVICE";
field public static final java.lang.String EXTRA_INCOMING_CALL_ADDRESS = "android.telecom.extra.INCOMING_CALL_ADDRESS";
diff --git a/cmds/am/src/com/android/commands/am/Am.java b/cmds/am/src/com/android/commands/am/Am.java
index b1e4701..85de12f 100644
--- a/cmds/am/src/com/android/commands/am/Am.java
+++ b/cmds/am/src/com/android/commands/am/Am.java
@@ -139,6 +139,7 @@
" am stack movetask <TASK_ID> <STACK_ID> [true|false]\n" +
" am stack resize <STACK_ID> <LEFT,TOP,RIGHT,BOTTOM>\n" +
" am stack split <STACK_ID> <v|h> [INTENT]\n" +
+ " am stack positiontask <TASK_ID> <STACK_ID> <POSITION>\n" +
" am stack list\n" +
" am stack info <STACK_ID>\n" +
" am task lock <TASK_ID>\n" +
@@ -280,6 +281,8 @@
" of the current task will be moved to the new stack. Command will also force\n" +
" all current tasks in both stacks to be resizeable.\n" +
"\n" +
+ "am stack positiontask: place <TASK_ID> in <STACK_ID> at <POSITION>" +
+ "\n" +
"am stack list: list all of the activity stacks and their sizes.\n" +
"\n" +
"am stack info: display the information about activity stack <STACK_ID>.\n" +
@@ -1921,6 +1924,8 @@
runStackMoveTask();
} else if (op.equals("resize")) {
runStackResize();
+ } else if (op.equals("positiontask")) {
+ runStackPositionTask();
} else if (op.equals("list")) {
runStackList();
} else if (op.equals("info")) {
@@ -1984,6 +1989,20 @@
}
}
+ private void runStackPositionTask() throws Exception {
+ String taskIdStr = nextArgRequired();
+ int taskId = Integer.valueOf(taskIdStr);
+ String stackIdStr = nextArgRequired();
+ int stackId = Integer.valueOf(stackIdStr);
+ String positionStr = nextArgRequired();
+ int position = Integer.valueOf(positionStr);
+
+ try {
+ mAm.positionTaskInStack(taskId, stackId, position);
+ } catch (RemoteException e) {
+ }
+ }
+
private void runStackList() throws Exception {
try {
List<StackInfo> stacks = mAm.getAllStackInfos();
@@ -2201,7 +2220,7 @@
}
private void runSetInactive() throws Exception {
- int userId = UserHandle.USER_OWNER;
+ int userId = UserHandle.USER_CURRENT;
String opt;
while ((opt=nextOption()) != null) {
@@ -2221,7 +2240,7 @@
}
private void runGetInactive() throws Exception {
- int userId = UserHandle.USER_OWNER;
+ int userId = UserHandle.USER_CURRENT;
String opt;
while ((opt=nextOption()) != null) {
diff --git a/cmds/pm/src/com/android/commands/pm/Pm.java b/cmds/pm/src/com/android/commands/pm/Pm.java
index 8b544ab..964b776 100644
--- a/cmds/pm/src/com/android/commands/pm/Pm.java
+++ b/cmds/pm/src/com/android/commands/pm/Pm.java
@@ -335,7 +335,7 @@
boolean listDisabled = false, listEnabled = false;
boolean listSystem = false, listThirdParty = false;
boolean listInstaller = false;
- int userId = UserHandle.USER_OWNER;
+ int userId = UserHandle.USER_SYSTEM;
try {
String opt;
while ((opt=nextOption()) != null) {
@@ -846,7 +846,7 @@
// pm set-app-link [--user USER_ID] PACKAGE {always|ask|never|undefined}
private int runSetAppLink() {
- int userId = UserHandle.USER_OWNER;
+ int userId = UserHandle.USER_SYSTEM;
String opt;
while ((opt = nextOption()) != null) {
@@ -929,7 +929,7 @@
// pm get-app-link [--user USER_ID] PACKAGE
private int runGetAppLink() {
- int userId = UserHandle.USER_OWNER;
+ int userId = UserHandle.USER_SYSTEM;
String opt;
while ((opt = nextOption()) != null) {
@@ -1090,7 +1090,7 @@
}
if (userId == UserHandle.USER_ALL) {
- userId = UserHandle.USER_OWNER;
+ userId = UserHandle.USER_SYSTEM;
installFlags |= PackageManager.INSTALL_ALL_USERS;
}
@@ -1216,7 +1216,7 @@
}
if (userId == UserHandle.USER_ALL) {
- userId = UserHandle.USER_OWNER;
+ userId = UserHandle.USER_SYSTEM;
params.installFlags |= PackageManager.INSTALL_ALL_USERS;
}
@@ -1547,7 +1547,7 @@
}
if (userId == UserHandle.USER_ALL) {
- userId = UserHandle.USER_OWNER;
+ userId = UserHandle.USER_SYSTEM;
flags |= PackageManager.DELETE_ALL_USERS;
} else {
PackageInfo info;
@@ -1758,7 +1758,7 @@
}
private int runGrantRevokePermission(boolean grant) {
- int userId = UserHandle.USER_OWNER;
+ int userId = UserHandle.USER_SYSTEM;
String opt = null;
while ((opt = nextOption()) != null) {
diff --git a/cmds/svc/src/com/android/commands/svc/PowerCommand.java b/cmds/svc/src/com/android/commands/svc/PowerCommand.java
index 2754f2d..6ce29cb 100644
--- a/cmds/svc/src/com/android/commands/svc/PowerCommand.java
+++ b/cmds/svc/src/com/android/commands/svc/PowerCommand.java
@@ -93,7 +93,7 @@
} else if ("shutdown".equals(args[1])) {
try {
// no confirm, wait till device is off
- pm.shutdown(false, true);
+ pm.shutdown(false, null, true);
} catch (RemoteException e) {
System.err.println("Failed to shutdown.");
}
diff --git a/core/java/android/accounts/AbstractAccountAuthenticator.java b/core/java/android/accounts/AbstractAccountAuthenticator.java
index 3e4a66d..9c401c7f 100644
--- a/core/java/android/accounts/AbstractAccountAuthenticator.java
+++ b/core/java/android/accounts/AbstractAccountAuthenticator.java
@@ -138,7 +138,9 @@
new AccountAuthenticatorResponse(response),
accountType, authTokenType, features, options);
if (Log.isLoggable(TAG, Log.VERBOSE)) {
- result.keySet(); // force it to be unparcelled
+ if (result != null) {
+ result.keySet(); // force it to be unparcelled
+ }
Log.v(TAG, "addAccount: result " + AccountManager.sanitizeResult(result));
}
if (result != null) {
@@ -160,7 +162,9 @@
final Bundle result = AbstractAccountAuthenticator.this.confirmCredentials(
new AccountAuthenticatorResponse(response), account, options);
if (Log.isLoggable(TAG, Log.VERBOSE)) {
- result.keySet(); // force it to be unparcelled
+ if (result != null) {
+ result.keySet(); // force it to be unparcelled
+ }
Log.v(TAG, "confirmCredentials: result "
+ AccountManager.sanitizeResult(result));
}
@@ -185,7 +189,9 @@
result.putString(AccountManager.KEY_AUTH_TOKEN_LABEL,
AbstractAccountAuthenticator.this.getAuthTokenLabel(authTokenType));
if (Log.isLoggable(TAG, Log.VERBOSE)) {
- result.keySet(); // force it to be unparcelled
+ if (result != null) {
+ result.keySet(); // force it to be unparcelled
+ }
Log.v(TAG, "getAuthTokenLabel: result "
+ AccountManager.sanitizeResult(result));
}
@@ -209,7 +215,9 @@
new AccountAuthenticatorResponse(response), account,
authTokenType, loginOptions);
if (Log.isLoggable(TAG, Log.VERBOSE)) {
- result.keySet(); // force it to be unparcelled
+ if (result != null) {
+ result.keySet(); // force it to be unparcelled
+ }
Log.v(TAG, "getAuthToken: result " + AccountManager.sanitizeResult(result));
}
if (result != null) {
@@ -234,7 +242,10 @@
new AccountAuthenticatorResponse(response), account,
authTokenType, loginOptions);
if (Log.isLoggable(TAG, Log.VERBOSE)) {
- result.keySet(); // force it to be unparcelled
+ // Result may be null.
+ if (result != null) {
+ result.keySet(); // force it to be unparcelled
+ }
Log.v(TAG, "updateCredentials: result "
+ AccountManager.sanitizeResult(result));
}
@@ -490,7 +501,7 @@
* <ul>
* <li> {@link AccountManager#KEY_INTENT}, or
* <li> {@link AccountManager#KEY_ACCOUNT_NAME} and {@link AccountManager#KEY_ACCOUNT_TYPE} of
- * the account that was added, or
+ * the account whose credentials were updated, or
* <li> {@link AccountManager#KEY_ERROR_CODE} and {@link AccountManager#KEY_ERROR_MESSAGE} to
* indicate an error
* </ul>
diff --git a/core/java/android/accounts/AccountManager.java b/core/java/android/accounts/AccountManager.java
index 9394d2c..8c84b4d 100644
--- a/core/java/android/accounts/AccountManager.java
+++ b/core/java/android/accounts/AccountManager.java
@@ -333,7 +333,7 @@
try {
return mService.getPassword(account);
} catch (RemoteException e) {
- // will never happen
+ // won't ever happen
throw new RuntimeException(e);
}
}
@@ -362,7 +362,7 @@
try {
return mService.getUserData(account, key);
} catch (RemoteException e) {
- // will never happen
+ // won't ever happen
throw new RuntimeException(e);
}
}
@@ -415,8 +415,10 @@
*
* <p>It is safe to call this method from the main thread.
*
- * <p>This method requires the caller to hold the permission
- * {@link android.Manifest.permission#GET_ACCOUNTS}.
+ * <p>Clients of this method that have not been granted the
+ * {@link android.Manifest.permission#GET_ACCOUNTS} permission,
+ * will only see those accounts managed by AbstractAccountAuthenticators whose
+ * signature matches the client.
*
* @return An array of {@link Account}, one for each account. Empty
* (never null) if no accounts have been added.
@@ -438,8 +440,10 @@
*
* <p>It is safe to call this method from the main thread.
*
- * <p>This method requires the caller to hold the permission
- * {@link android.Manifest.permission#GET_ACCOUNTS}.
+ * <p>Clients of this method that have not been granted the
+ * {@link android.Manifest.permission#GET_ACCOUNTS} permission,
+ * will only see those accounts managed by AbstractAccountAuthenticators whose
+ * signature matches the client.
*
* @return An array of {@link Account}, one for each account. Empty
* (never null) if no accounts have been added.
@@ -466,7 +470,7 @@
try {
return mService.getAccountsForPackage(packageName, uid);
} catch (RemoteException re) {
- // possible security exception
+ // won't ever happen
throw new RuntimeException(re);
}
}
@@ -483,7 +487,7 @@
try {
return mService.getAccountsByTypeForPackage(type, packageName);
} catch (RemoteException re) {
- // possible security exception
+ // won't ever happen
throw new RuntimeException(re);
}
}
@@ -497,9 +501,10 @@
*
* <p>It is safe to call this method from the main thread.
*
- * <p>This method requires the caller to hold the permission
- * {@link android.Manifest.permission#GET_ACCOUNTS} or share a uid with the
- * authenticator that owns the account type.
+ * <p>Clients of this method that have not been granted the
+ * {@link android.Manifest.permission#GET_ACCOUNTS} permission,
+ * will only see those accounts managed by AbstractAccountAuthenticators whose
+ * signature matches the client.
*
* <p><b>NOTE:</b> If targeting your app to work on API level 22 and before,
* GET_ACCOUNTS permission is needed for those platforms, irrespective of uid
@@ -585,7 +590,8 @@
* {@link AccountManagerFuture} must not be used on the main thread.
*
* <p>This method requires the caller to hold the permission
- * {@link android.Manifest.permission#GET_ACCOUNTS}.
+ * {@link android.Manifest.permission#GET_ACCOUNTS} or be a signature
+ * match with the AbstractAccountAuthenticator that manages the account.
*
* @param account The {@link Account} to test
* @param features An array of the account features to check
@@ -628,9 +634,10 @@
* <p>This method may be called from any thread, but the returned
* {@link AccountManagerFuture} must not be used on the main thread.
*
- * <p>This method requires the caller to hold the permission
- * {@link android.Manifest.permission#GET_ACCOUNTS} or share a uid with the
- * authenticator that owns the account type.
+ * <p>Clients of this method that have not been granted the
+ * {@link android.Manifest.permission#GET_ACCOUNTS} permission,
+ * will only see those accounts managed by AbstractAccountAuthenticators whose
+ * signature matches the client.
*
* @param type The type of accounts to return, must not be null
* @param features An array of the account features to require,
@@ -701,7 +708,7 @@
try {
return mService.addAccountExplicitly(account, password, userdata);
} catch (RemoteException e) {
- // won't ever happen
+ // Can happen if there was a SecurityException was thrown.
throw new RuntimeException(e);
}
}
@@ -966,7 +973,7 @@
try {
return mService.removeAccountExplicitly(account);
} catch (RemoteException e) {
- // won't ever happen
+ // May happen if the caller doesn't match the signature of the authenticator.
throw new RuntimeException(e);
}
}
@@ -1114,7 +1121,7 @@
try {
mService.setUserData(account, key, value);
} catch (RemoteException e) {
- // won't ever happen
+ // Will happen if there is not signature match.
throw new RuntimeException(e);
}
}
@@ -1733,7 +1740,7 @@
* with these fields if an activity was supplied and the account
* credentials were successfully updated:
* <ul>
- * <li> {@link #KEY_ACCOUNT_NAME} - the name of the account created
+ * <li> {@link #KEY_ACCOUNT_NAME} - the name of the account
* <li> {@link #KEY_ACCOUNT_TYPE} - the type of the account
* </ul>
*
@@ -2501,10 +2508,12 @@
* listeners are added in an Activity or Service's {@link Activity#onCreate}
* and removed in {@link Activity#onDestroy}.
*
- * <p>It is safe to call this method from the main thread.
+ * <p>The listener will only be informed of accounts that would be returned
+ * to the caller via {@link #getAccounts()}. Typically this means that to
+ * get any accounts, the caller will need to be grated the GET_ACCOUNTS
+ * permission.
*
- * <p>This method requires the caller to hold the permission
- * {@link android.Manifest.permission#GET_ACCOUNTS}.
+ * <p>It is safe to call this method from the main thread.
*
* @param listener The listener to send notifications to
* @param handler {@link Handler} identifying the thread to use
diff --git a/core/java/android/animation/Animator.java b/core/java/android/animation/Animator.java
index aa1be9a..d331c2a 100644
--- a/core/java/android/animation/Animator.java
+++ b/core/java/android/animation/Animator.java
@@ -27,6 +27,11 @@
public abstract class Animator implements Cloneable {
/**
+ * The value used to indicate infinite duration (e.g. when Animators repeat infinitely).
+ * @hide
+ */
+ public static final long DURATION_INFINITE = -1;
+ /**
* The set of listeners to be sent events through the life of an animation.
*/
ArrayList<AnimatorListener> mListeners = null;
@@ -184,6 +189,16 @@
public abstract long getDuration();
/**
+ * Gets the total duration of the animation, accounting for animation sequences, start delay,
+ * and repeating. Return {@link #DURATION_INFINITE} if the duration is infinite.
+ * @hide
+ * TODO: Unhide
+ */
+ public long getTotalDuration() {
+ return getStartDelay() + getDuration();
+ }
+
+ /**
* The time interpolator used in calculating the elapsed fraction of the
* animation. The interpolator determines whether the animation runs with
* linear or non-linear motion, such as acceleration and deceleration. The
diff --git a/core/java/android/animation/AnimatorSet.java b/core/java/android/animation/AnimatorSet.java
index 951fe49..1065ed8 100644
--- a/core/java/android/animation/AnimatorSet.java
+++ b/core/java/android/animation/AnimatorSet.java
@@ -17,6 +17,7 @@
package android.animation;
import android.util.ArrayMap;
+import android.util.Log;
import java.util.ArrayList;
import java.util.Collection;
@@ -50,6 +51,7 @@
*/
public final class AnimatorSet extends Animator {
+ private static final String TAG = "AnimatorSet";
/**
* Internal variables
* NOTE: This object implements the clone() method, making a deep copy of any referenced
@@ -79,20 +81,10 @@
private ArrayList<Node> mNodes = new ArrayList<Node>();
/**
- * The sorted list of nodes. This is the order in which the animations will
- * be played. The details about when exactly they will be played depend
- * on the dependency relationships of the nodes.
+ * Animator Listener that tracks the lifecycle of each Animator in the set. It will be added
+ * to each Animator before they start and removed after they end.
*/
- private ArrayList<Node> mSortedNodes = new ArrayList<Node>();
-
- /**
- * Flag indicating whether the nodes should be sorted prior to playing. This
- * flag allows us to cache the previous sorted nodes so that if the sequence
- * is replayed with no changes, it does not have to re-sort the nodes again.
- */
- private boolean mNeedsSort = true;
-
- private AnimatorSetListener mSetListener = null;
+ private AnimatorSetListener mSetListener = new AnimatorSetListener(this);
/**
* Flag indicating that the AnimatorSet has been manually
@@ -101,7 +93,13 @@
* child animations of this AnimatorSet end. It also determines whether cancel/end
* notifications are sent out via the normal AnimatorSetListener mechanism.
*/
- boolean mTerminated = false;
+ private boolean mTerminated = false;
+
+ /**
+ * Tracks whether any change has been made to the AnimatorSet, which is then used to
+ * determine whether the dependency graph should be re-constructed.
+ */
+ private boolean mDependencyDirty = false;
/**
* Indicates whether an AnimatorSet has been start()'d, whether or
@@ -113,8 +111,13 @@
private long mStartDelay = 0;
// Animator used for a nonzero startDelay
- private ValueAnimator mDelayAnim = null;
+ private ValueAnimator mDelayAnim = ValueAnimator.ofFloat(0f, 1f).setDuration(0);
+ // Root of the dependency tree of all the animators in the set. In this tree, parent-child
+ // relationship captures the order of animation (i.e. parent and child will play sequentially),
+ // and sibling relationship indicates "with" relationship, as sibling animators start at the
+ // same time.
+ private Node mRootNode = new Node(mDelayAnim);
// How long the child animations should last in ms. The default value is negative, which
// simply means that there is no duration set on the AnimatorSet. When a real duration is
@@ -125,7 +128,17 @@
// was set on this AnimatorSet, so it should not be passed down to the children.
private TimeInterpolator mInterpolator = null;
+ // Whether the AnimatorSet can be reversed.
private boolean mReversible = true;
+ // The total duration of finishing all the Animators in the set.
+ private long mTotalDuration = 0;
+
+ public AnimatorSet() {
+ super();
+ mNodeMap.put(mDelayAnim, mRootNode);
+ mNodes.add(mRootNode);
+ }
+
/**
* Sets up this AnimatorSet to play all of the supplied animations at the same time.
* This is equivalent to calling {@link #play(Animator)} with the first animator in the
@@ -139,7 +152,6 @@
*/
public void playTogether(Animator... items) {
if (items != null) {
- mNeedsSort = true;
Builder builder = play(items[0]);
for (int i = 1; i < items.length; ++i) {
builder.with(items[i]);
@@ -154,7 +166,6 @@
*/
public void playTogether(Collection<Animator> items) {
if (items != null && items.size() > 0) {
- mNeedsSort = true;
Builder builder = null;
for (Animator anim : items) {
if (builder == null) {
@@ -174,13 +185,12 @@
*/
public void playSequentially(Animator... items) {
if (items != null) {
- mNeedsSort = true;
if (items.length == 1) {
play(items[0]);
} else {
mReversible = false;
for (int i = 0; i < items.length - 1; ++i) {
- play(items[i]).before(items[i+1]);
+ play(items[i]).before(items[i + 1]);
}
}
}
@@ -194,13 +204,12 @@
*/
public void playSequentially(List<Animator> items) {
if (items != null && items.size() > 0) {
- mNeedsSort = true;
if (items.size() == 1) {
play(items.get(0));
} else {
mReversible = false;
for (int i = 0; i < items.size() - 1; ++i) {
- play(items.get(i)).before(items.get(i+1));
+ play(items.get(i)).before(items.get(i + 1));
}
}
}
@@ -216,8 +225,12 @@
*/
public ArrayList<Animator> getChildAnimations() {
ArrayList<Animator> childList = new ArrayList<Animator>();
- for (Node node : mNodes) {
- childList.add(node.animation);
+ int size = mNodes.size();
+ for (int i = 0; i < size; i++) {
+ Node node = mNodes.get(i);
+ if (node != mRootNode) {
+ childList.add(node.mAnimation);
+ }
}
return childList;
}
@@ -231,8 +244,10 @@
*/
@Override
public void setTarget(Object target) {
- for (Node node : mNodes) {
- Animator animation = node.animation;
+ int size = mNodes.size();
+ for (int i = 0; i < size; i++) {
+ Node node = mNodes.get(i);
+ Animator animation = node.mAnimation;
if (animation instanceof AnimatorSet) {
((AnimatorSet)animation).setTarget(target);
} else if (animation instanceof ObjectAnimator) {
@@ -249,7 +264,7 @@
int conf = super.getChangingConfigurations();
final int nodeCount = mNodes.size();
for (int i = 0; i < nodeCount; i ++) {
- conf |= mNodes.get(i).animation.getChangingConfigurations();
+ conf |= mNodes.get(i).mAnimation.getChangingConfigurations();
}
return conf;
}
@@ -303,7 +318,6 @@
*/
public Builder play(Animator anim) {
if (anim != null) {
- mNeedsSort = true;
return new Builder(anim);
}
return null;
@@ -323,22 +337,20 @@
ArrayList<AnimatorListener> tmpListeners = null;
if (mListeners != null) {
tmpListeners = (ArrayList<AnimatorListener>) mListeners.clone();
- for (AnimatorListener listener : tmpListeners) {
- listener.onAnimationCancel(this);
+ int size = tmpListeners.size();
+ for (int i = 0; i < size; i++) {
+ tmpListeners.get(i).onAnimationCancel(this);
}
}
- if (mDelayAnim != null && mDelayAnim.isRunning()) {
- // If we're currently in the startDelay period, just cancel that animator and
- // send out the end event to all listeners
- mDelayAnim.cancel();
- } else if (mSortedNodes.size() > 0) {
- for (Node node : mSortedNodes) {
- node.animation.cancel();
- }
+ ArrayList<Animator> playingSet = new ArrayList<>(mPlayingSet);
+ int setSize = playingSet.size();
+ for (int i = 0; i < setSize; i++) {
+ playingSet.get(i).cancel();
}
if (tmpListeners != null) {
- for (AnimatorListener listener : tmpListeners) {
- listener.onAnimationEnd(this);
+ int size = tmpListeners.size();
+ for (int i = 0; i < size; i++) {
+ tmpListeners.get(i).onAnimationEnd(this);
}
}
mStarted = false;
@@ -355,35 +367,45 @@
public void end() {
mTerminated = true;
if (isStarted()) {
- if (mSortedNodes.size() != mNodes.size()) {
- // hasn't been started yet - sort the nodes now, then end them
- sortNodes();
- for (Node node : mSortedNodes) {
- if (mSetListener == null) {
- mSetListener = new AnimatorSetListener(this);
+ endRemainingAnimations();
+ }
+ if (mListeners != null) {
+ ArrayList<AnimatorListener> tmpListeners =
+ (ArrayList<AnimatorListener>) mListeners.clone();
+ for (int i = 0; i < tmpListeners.size(); i++) {
+ tmpListeners.get(i).onAnimationEnd(this);
+ }
+ }
+ mStarted = false;
+ }
+
+ /**
+ * Iterate the animations that haven't finished or haven't started, and end them.
+ */
+ private void endRemainingAnimations() {
+ ArrayList<Animator> remainingList = new ArrayList<Animator>(mNodes.size());
+ remainingList.addAll(mPlayingSet);
+
+ int index = 0;
+ while (index < remainingList.size()) {
+ Animator anim = remainingList.get(index);
+ anim.end();
+ index++;
+ Node node = mNodeMap.get(anim);
+ if (node.mChildNodes != null) {
+ int childSize = node.mChildNodes.size();
+ for (int i = 0; i < childSize; i++) {
+ Node child = node.mChildNodes.get(i);
+ if (child.mLatestParent != node) {
+ continue;
}
- node.animation.addListener(mSetListener);
+ remainingList.add(child.mAnimation);
}
}
- if (mDelayAnim != null) {
- mDelayAnim.cancel();
- }
- if (mSortedNodes.size() > 0) {
- for (Node node : mSortedNodes) {
- node.animation.end();
- }
- }
- if (mListeners != null) {
- ArrayList<AnimatorListener> tmpListeners =
- (ArrayList<AnimatorListener>) mListeners.clone();
- for (AnimatorListener listener : tmpListeners) {
- listener.onAnimationEnd(this);
- }
- }
- mStarted = false;
}
}
+
/**
* Returns true if any of the child animations of this AnimatorSet have been started and have
* not yet ended.
@@ -391,8 +413,9 @@
*/
@Override
public boolean isRunning() {
- for (Node node : mNodes) {
- if (node.animation.isRunning()) {
+ int size = mNodes.size();
+ for (int i = 0; i < size; i++) {
+ if (mNodes.get(i).mAnimation.isRunning()) {
return true;
}
}
@@ -426,7 +449,24 @@
if (mStartDelay > 0) {
mReversible = false;
}
+ long delta = startDelay - mStartDelay;
mStartDelay = startDelay;
+ if (!mDependencyDirty) {
+ // Dependency graph already constructed, update all the nodes' start/end time
+ int size = mNodes.size();
+ for (int i = 0; i < size; i++) {
+ Node node = mNodes.get(i);
+ if (node == mRootNode) {
+ node.mEndTime = mStartDelay;
+ } else {
+ node.mStartTime = node.mStartTime == DURATION_INFINITE ?
+ DURATION_INFINITE : node.mStartTime + delta;
+ node.mEndTime = node.mEndTime == DURATION_INFINITE ?
+ DURATION_INFINITE : node.mEndTime + delta;
+
+ }
+ }
+ }
}
/**
@@ -455,6 +495,7 @@
if (duration < 0) {
throw new IllegalArgumentException("duration must be a value of zero or greater");
}
+ mDependencyDirty = true;
// Just record the value for now - it will be used later when the AnimatorSet starts
mDuration = duration;
return this;
@@ -462,15 +503,19 @@
@Override
public void setupStartValues() {
- for (Node node : mNodes) {
- node.animation.setupStartValues();
+ int size = mNodes.size();
+ for (int i = 0; i < size; i++) {
+ Node node = mNodes.get(i);
+ node.mAnimation.setupStartValues();
}
}
@Override
public void setupEndValues() {
- for (Node node : mNodes) {
- node.animation.setupEndValues();
+ int size = mNodes.size();
+ for (int i = 0; i < size; i++) {
+ Node node = mNodes.get(i);
+ node.mAnimation.setupEndValues();
}
}
@@ -482,8 +527,10 @@
if (mDelayAnim != null) {
mDelayAnim.pause();
} else {
- for (Node node : mNodes) {
- node.animation.pause();
+ int size = mNodes.size();
+ for (int i = 0; i < size; i++) {
+ Node node = mNodes.get(i);
+ node.mAnimation.pause();
}
}
}
@@ -497,8 +544,10 @@
if (mDelayAnim != null) {
mDelayAnim.resume();
} else {
- for (Node node : mNodes) {
- node.animation.resume();
+ int size = mNodes.size();
+ for (int i = 0; i < size; i++) {
+ Node node = mNodes.get(i);
+ node.mAnimation.resume();
}
}
}
@@ -518,96 +567,25 @@
mStarted = true;
mPaused = false;
- for (Node node : mNodes) {
- node.animation.setAllowRunningAsynchronously(false);
+ int size = mNodes.size();
+ for (int i = 0; i < size; i++) {
+ Node node = mNodes.get(i);
+ node.mEnded = false;
+ node.mAnimation.setAllowRunningAsynchronously(false);
}
- if (mDuration >= 0) {
- // If the duration was set on this AnimatorSet, pass it along to all child animations
- for (Node node : mNodes) {
- // TODO: don't set the duration of the timing-only nodes created by AnimatorSet to
- // insert "play-after" delays
- node.animation.setDuration(mDuration);
- }
- }
if (mInterpolator != null) {
- for (Node node : mNodes) {
- node.animation.setInterpolator(mInterpolator);
- }
- }
- // First, sort the nodes (if necessary). This will ensure that sortedNodes
- // contains the animation nodes in the correct order.
- sortNodes();
-
- int numSortedNodes = mSortedNodes.size();
- for (int i = 0; i < numSortedNodes; ++i) {
- Node node = mSortedNodes.get(i);
- // First, clear out the old listeners
- ArrayList<AnimatorListener> oldListeners = node.animation.getListeners();
- if (oldListeners != null && oldListeners.size() > 0) {
- final ArrayList<AnimatorListener> clonedListeners = new
- ArrayList<AnimatorListener>(oldListeners);
-
- for (AnimatorListener listener : clonedListeners) {
- if (listener instanceof DependencyListener ||
- listener instanceof AnimatorSetListener) {
- node.animation.removeListener(listener);
- }
- }
+ for (int i = 0; i < size; i++) {
+ Node node = mNodes.get(i);
+ node.mAnimation.setInterpolator(mInterpolator);
}
}
- // nodesToStart holds the list of nodes to be started immediately. We don't want to
- // start the animations in the loop directly because we first need to set up
- // dependencies on all of the nodes. For example, we don't want to start an animation
- // when some other animation also wants to start when the first animation begins.
- final ArrayList<Node> nodesToStart = new ArrayList<Node>();
- for (int i = 0; i < numSortedNodes; ++i) {
- Node node = mSortedNodes.get(i);
- if (mSetListener == null) {
- mSetListener = new AnimatorSetListener(this);
- }
- if (node.dependencies == null || node.dependencies.size() == 0) {
- nodesToStart.add(node);
- } else {
- int numDependencies = node.dependencies.size();
- for (int j = 0; j < numDependencies; ++j) {
- Dependency dependency = node.dependencies.get(j);
- dependency.node.animation.addListener(
- new DependencyListener(this, node, dependency.rule));
- }
- node.tmpDependencies = (ArrayList<Dependency>) node.dependencies.clone();
- }
- node.animation.addListener(mSetListener);
- }
+ updateAnimatorsDuration();
+ createDependencyGraph();
+
// Now that all dependencies are set up, start the animations that should be started.
- if (mStartDelay <= 0) {
- for (Node node : nodesToStart) {
- node.animation.start();
- mPlayingSet.add(node.animation);
- }
- } else {
- mDelayAnim = ValueAnimator.ofFloat(0f, 1f);
- mDelayAnim.setDuration(mStartDelay);
- mDelayAnim.addListener(new AnimatorListenerAdapter() {
- boolean canceled = false;
- public void onAnimationCancel(Animator anim) {
- canceled = true;
- }
- public void onAnimationEnd(Animator anim) {
- if (!canceled) {
- int numNodes = nodesToStart.size();
- for (int i = 0; i < numNodes; ++i) {
- Node node = nodesToStart.get(i);
- node.animation.start();
- mPlayingSet.add(node.animation);
- }
- }
- mDelayAnim = null;
- }
- });
- mDelayAnim.start();
- }
+ start(mRootNode);
if (mListeners != null) {
ArrayList<AnimatorListener> tmpListeners =
(ArrayList<AnimatorListener>) mListeners.clone();
@@ -631,6 +609,27 @@
}
}
+ private void updateAnimatorsDuration() {
+ if (mDuration >= 0) {
+ // If the duration was set on this AnimatorSet, pass it along to all child animations
+ int size = mNodes.size();
+ for (int i = 0; i < size; i++) {
+ Node node = mNodes.get(i);
+ // TODO: don't set the duration of the timing-only nodes created by AnimatorSet to
+ // insert "play-after" delays
+ node.mAnimation.setDuration(mDuration);
+ }
+ }
+ mDelayAnim.setDuration(mStartDelay);
+ }
+
+ void start(final Node node) {
+ final Animator anim = node.mAnimation;
+ mPlayingSet.add(anim);
+ anim.addListener(mSetListener);
+ anim.start();
+ }
+
@Override
public AnimatorSet clone() {
final AnimatorSet anim = (AnimatorSet) super.clone();
@@ -643,15 +642,13 @@
* and will populate any appropriate lists, when it is started.
*/
final int nodeCount = mNodes.size();
- anim.mNeedsSort = true;
anim.mTerminated = false;
anim.mStarted = false;
anim.mPlayingSet = new ArrayList<Animator>();
anim.mNodeMap = new ArrayMap<Animator, Node>();
anim.mNodes = new ArrayList<Node>(nodeCount);
- anim.mSortedNodes = new ArrayList<Node>(nodeCount);
anim.mReversible = mReversible;
- anim.mSetListener = null;
+ anim.mSetListener = new AnimatorSetListener(anim);
// Walk through the old nodes list, cloning each node and adding it to the new nodemap.
// One problem is that the old node dependencies point to nodes in the old AnimatorSet.
@@ -662,16 +659,10 @@
Node nodeClone = node.clone();
node.mTmpClone = nodeClone;
anim.mNodes.add(nodeClone);
- anim.mNodeMap.put(nodeClone.animation, nodeClone);
- // Clear out the dependencies in the clone; we'll set these up manually later
- nodeClone.dependencies = null;
- nodeClone.tmpDependencies = null;
- nodeClone.nodeDependents = null;
- nodeClone.nodeDependencies = null;
+ anim.mNodeMap.put(nodeClone.mAnimation, nodeClone);
- // clear out any listeners that were set up by the AnimatorSet; these will
- // be set up when the clone's nodes are sorted
- final ArrayList<AnimatorListener> cloneListeners = nodeClone.animation.getListeners();
+ // clear out any listeners that were set up by the AnimatorSet
+ final ArrayList<AnimatorListener> cloneListeners = nodeClone.mAnimation.getListeners();
if (cloneListeners != null) {
for (int i = cloneListeners.size() - 1; i >= 0; i--) {
final AnimatorListener listener = cloneListeners.get(i);
@@ -681,127 +672,37 @@
}
}
}
+
+ anim.mRootNode = mRootNode.mTmpClone;
+ anim.mDelayAnim = (ValueAnimator) anim.mRootNode.mAnimation;
+
// Now that we've cloned all of the nodes, we're ready to walk through their
// dependencies, mapping the old dependencies to the new nodes
- for (int n = 0; n < nodeCount; n++) {
- final Node node = mNodes.get(n);
- final Node clone = node.mTmpClone;
- if (node.dependencies != null) {
- clone.dependencies = new ArrayList<Dependency>(node.dependencies.size());
- final int depSize = node.dependencies.size();
- for (int i = 0; i < depSize; i ++) {
- final Dependency dependency = node.dependencies.get(i);
- Dependency cloneDependency = new Dependency(dependency.node.mTmpClone,
- dependency.rule);
- clone.dependencies.add(cloneDependency);
- }
+ for (int i = 0; i < nodeCount; i++) {
+ Node node = mNodes.get(i);
+ // Update dependencies for node's clone
+ node.mTmpClone.mLatestParent = node.mLatestParent == null ?
+ null : node.mLatestParent.mTmpClone;
+ int size = node.mChildNodes == null ? 0 : node.mChildNodes.size();
+ for (int j = 0; j < size; j++) {
+ node.mTmpClone.mChildNodes.set(j, node.mChildNodes.get(j).mTmpClone);
}
- if (node.nodeDependents != null) {
- clone.nodeDependents = new ArrayList<Node>(node.nodeDependents.size());
- for (Node dep : node.nodeDependents) {
- clone.nodeDependents.add(dep.mTmpClone);
- }
+ size = node.mSiblings == null ? 0 : node.mSiblings.size();
+ for (int j = 0; j < size; j++) {
+ node.mTmpClone.mSiblings.set(j, node.mSiblings.get(j).mTmpClone);
}
- if (node.nodeDependencies != null) {
- clone.nodeDependencies = new ArrayList<Node>(node.nodeDependencies.size());
- for (Node dep : node.nodeDependencies) {
- clone.nodeDependencies.add(dep.mTmpClone);
- }
+ size = node.mParents == null ? 0 : node.mParents.size();
+ for (int j = 0; j < size; j++) {
+ node.mTmpClone.mParents.set(j, node.mParents.get(j).mTmpClone);
}
}
+
for (int n = 0; n < nodeCount; n++) {
mNodes.get(n).mTmpClone = null;
}
return anim;
}
- /**
- * This class is the mechanism by which animations are started based on events in other
- * animations. If an animation has multiple dependencies on other animations, then
- * all dependencies must be satisfied before the animation is started.
- */
- private static class DependencyListener implements AnimatorListener {
-
- private AnimatorSet mAnimatorSet;
-
- // The node upon which the dependency is based.
- private Node mNode;
-
- // The Dependency rule (WITH or AFTER) that the listener should wait for on
- // the node
- private int mRule;
-
- public DependencyListener(AnimatorSet animatorSet, Node node, int rule) {
- this.mAnimatorSet = animatorSet;
- this.mNode = node;
- this.mRule = rule;
- }
-
- /**
- * Ignore cancel events for now. We may want to handle this eventually,
- * to prevent follow-on animations from running when some dependency
- * animation is canceled.
- */
- public void onAnimationCancel(Animator animation) {
- }
-
- /**
- * An end event is received - see if this is an event we are listening for
- */
- public void onAnimationEnd(Animator animation) {
- if (mRule == Dependency.AFTER) {
- startIfReady(animation);
- }
- }
-
- /**
- * Ignore repeat events for now
- */
- public void onAnimationRepeat(Animator animation) {
- }
-
- /**
- * A start event is received - see if this is an event we are listening for
- */
- public void onAnimationStart(Animator animation) {
- if (mRule == Dependency.WITH) {
- startIfReady(animation);
- }
- }
-
- /**
- * Check whether the event received is one that the node was waiting for.
- * If so, mark it as complete and see whether it's time to start
- * the animation.
- * @param dependencyAnimation the animation that sent the event.
- */
- private void startIfReady(Animator dependencyAnimation) {
- if (mAnimatorSet.mTerminated) {
- // if the parent AnimatorSet was canceled, then don't start any dependent anims
- return;
- }
- Dependency dependencyToRemove = null;
- int numDependencies = mNode.tmpDependencies.size();
- for (int i = 0; i < numDependencies; ++i) {
- Dependency dependency = mNode.tmpDependencies.get(i);
- if (dependency.rule == mRule &&
- dependency.node.animation == dependencyAnimation) {
- // rule fired - remove the dependency and listener and check to
- // see whether it's time to start the animation
- dependencyToRemove = dependency;
- dependencyAnimation.removeListener(this);
- break;
- }
- }
- mNode.tmpDependencies.remove(dependencyToRemove);
- if (mNode.tmpDependencies.size() == 0) {
- // all dependencies satisfied: start the animation
- mNode.animation.start();
- mAnimatorSet.mPlayingSet.add(mNode.animation);
- }
- }
-
- }
private class AnimatorSetListener implements AnimatorListener {
@@ -812,14 +713,16 @@
}
public void onAnimationCancel(Animator animation) {
+
if (!mTerminated) {
// Listeners are already notified of the AnimatorSet canceling in cancel().
// The logic below only kicks in when animations end normally
- if (mPlayingSet.size() == 0) {
- if (mListeners != null) {
- int numListeners = mListeners.size();
+ if (mAnimatorSet.mPlayingSet.size() == 0) {
+ ArrayList<AnimatorListener> listeners = mAnimatorSet.mListeners;
+ if (listeners != null) {
+ int numListeners = listeners.size();
for (int i = 0; i < numListeners; ++i) {
- mListeners.get(i).onAnimationCancel(mAnimatorSet);
+ listeners.get(i).onAnimationCancel(mAnimatorSet);
}
}
}
@@ -829,17 +732,26 @@
@SuppressWarnings("unchecked")
public void onAnimationEnd(Animator animation) {
animation.removeListener(this);
- mPlayingSet.remove(animation);
+ mAnimatorSet.mPlayingSet.remove(animation);
Node animNode = mAnimatorSet.mNodeMap.get(animation);
- animNode.done = true;
+ animNode.mEnded = true;
+
if (!mTerminated) {
+ List<Node> children = animNode.mChildNodes;
+ // Start children animations, if any.
+ int childrenSize = children == null ? 0 : children.size();
+ for (int i = 0; i < childrenSize; i++) {
+ if (children.get(i).mLatestParent == animNode) {
+ mAnimatorSet.start(children.get(i));
+ }
+ }
// Listeners are already notified of the AnimatorSet ending in cancel() or
// end(); the logic below only kicks in when animations end normally
- ArrayList<Node> sortedNodes = mAnimatorSet.mSortedNodes;
boolean allDone = true;
- int numSortedNodes = sortedNodes.size();
- for (int i = 0; i < numSortedNodes; ++i) {
- if (!sortedNodes.get(i).done) {
+ // Traverse the tree and find if there's any unfinished node
+ int size = mNodes.size();
+ for (int i = 0; i < size; i++) {
+ if (!mNodes.get(i).mEnded) {
allDone = false;
break;
}
@@ -872,79 +784,6 @@
}
/**
- * This method sorts the current set of nodes, if needed. The sort is a simple
- * DependencyGraph sort, which goes like this:
- * - All nodes without dependencies become 'roots'
- * - while roots list is not null
- * - for each root r
- * - add r to sorted list
- * - remove r as a dependency from any other node
- * - any nodes with no dependencies are added to the roots list
- */
- private void sortNodes() {
- if (mNeedsSort) {
- mSortedNodes.clear();
- ArrayList<Node> roots = new ArrayList<Node>();
- int numNodes = mNodes.size();
- for (int i = 0; i < numNodes; ++i) {
- Node node = mNodes.get(i);
- if (node.dependencies == null || node.dependencies.size() == 0) {
- roots.add(node);
- }
- }
- ArrayList<Node> tmpRoots = new ArrayList<Node>();
- while (roots.size() > 0) {
- int numRoots = roots.size();
- for (int i = 0; i < numRoots; ++i) {
- Node root = roots.get(i);
- mSortedNodes.add(root);
- if (root.nodeDependents != null) {
- int numDependents = root.nodeDependents.size();
- for (int j = 0; j < numDependents; ++j) {
- Node node = root.nodeDependents.get(j);
- node.nodeDependencies.remove(root);
- if (node.nodeDependencies.size() == 0) {
- tmpRoots.add(node);
- }
- }
- }
- }
- roots.clear();
- roots.addAll(tmpRoots);
- tmpRoots.clear();
- }
- mNeedsSort = false;
- if (mSortedNodes.size() != mNodes.size()) {
- throw new IllegalStateException("Circular dependencies cannot exist"
- + " in AnimatorSet");
- }
- } else {
- // Doesn't need sorting, but still need to add in the nodeDependencies list
- // because these get removed as the event listeners fire and the dependencies
- // are satisfied
- int numNodes = mNodes.size();
- for (int i = 0; i < numNodes; ++i) {
- Node node = mNodes.get(i);
- if (node.dependencies != null && node.dependencies.size() > 0) {
- int numDependencies = node.dependencies.size();
- for (int j = 0; j < numDependencies; ++j) {
- Dependency dependency = node.dependencies.get(j);
- if (node.nodeDependencies == null) {
- node.nodeDependencies = new ArrayList<Node>();
- }
- if (!node.nodeDependencies.contains(dependency.node)) {
- node.nodeDependencies.add(dependency.node);
- }
- }
- }
- // nodes are 'done' by default; they become un-done when started, and done
- // again when ended
- node.done = false;
- }
- }
- }
-
- /**
* @hide
*/
@Override
@@ -953,8 +792,10 @@
return false;
}
// Loop to make sure all the Nodes can reverse.
- for (Node node : mNodes) {
- if (!node.animation.canReverse() || node.animation.getStartDelay() > 0) {
+ int size = mNodes.size();
+ for (int i = 0; i < size; i++) {
+ Node node = mNodes.get(i);
+ if (!node.mAnimation.canReverse() || node.mAnimation.getStartDelay() > 0) {
return false;
}
}
@@ -967,8 +808,10 @@
@Override
public void reverse() {
if (canReverse()) {
- for (Node node : mNodes) {
- node.animation.reverse();
+ int size = mNodes.size();
+ for (int i = 0; i < size; i++) {
+ Node node = mNodes.get(i);
+ node.mAnimation.reverse();
}
}
}
@@ -976,36 +819,196 @@
@Override
public String toString() {
String returnVal = "AnimatorSet@" + Integer.toHexString(hashCode()) + "{";
- boolean prevNeedsSort = mNeedsSort;
- sortNodes();
- mNeedsSort = prevNeedsSort;
- for (Node node : mSortedNodes) {
- returnVal += "\n " + node.animation.toString();
+ int size = mNodes.size();
+ for (int i = 0; i < size; i++) {
+ Node node = mNodes.get(i);
+ returnVal += "\n " + node.mAnimation.toString();
}
return returnVal + "\n}";
}
- /**
- * Dependency holds information about the node that some other node is
- * dependent upon and the nature of that dependency.
- *
- */
- private static class Dependency {
- static final int WITH = 0; // dependent node must start with this dependency node
- static final int AFTER = 1; // dependent node must start when this dependency node finishes
-
- // The node that the other node with this Dependency is dependent upon
- public Node node;
-
- // The nature of the dependency (WITH or AFTER)
- public int rule;
-
- public Dependency(Node node, int rule) {
- this.node = node;
- this.rule = rule;
+ private void printChildCount() {
+ // Print out the child count through a level traverse.
+ ArrayList<Node> list = new ArrayList<>(mNodes.size());
+ list.add(mRootNode);
+ Log.d(TAG, "Current tree: ");
+ int index = 0;
+ while (index < list.size()) {
+ int listSize = list.size();
+ StringBuilder builder = new StringBuilder();
+ for (; index < listSize; index++) {
+ Node node = list.get(index);
+ int num = 0;
+ if (node.mChildNodes != null) {
+ for (int i = 0; i < node.mChildNodes.size(); i++) {
+ Node child = node.mChildNodes.get(i);
+ if (child.mLatestParent == node) {
+ num++;
+ list.add(child);
+ }
+ }
+ }
+ builder.append(" ");
+ builder.append(num);
+ }
+ Log.d(TAG, builder.toString());
}
}
+ private void createDependencyGraph() {
+ if (!mDependencyDirty) {
+ return;
+ }
+
+ // TODO: In addition to checking the dirty flag, we should also cache the duration for
+ // each animator, so that when the animator's duration is changed, we can detect that and
+ // update the dependency graph.
+
+ mDependencyDirty = false;
+ // Traverse all the siblings and make sure they have all the parents
+ int size = mNodes.size();
+ for (int i = 0; i < size; i++) {
+ mNodes.get(i).mParentsAdded = false;
+ }
+ for (int i = 0; i < size; i++) {
+ Node node = mNodes.get(i);
+ if (node.mParentsAdded) {
+ continue;
+ }
+
+ node.mParentsAdded = true;
+ if (node.mSiblings == null) {
+ continue;
+ }
+
+ // Find all the siblings
+ findSiblings(node, node.mSiblings);
+ node.mSiblings.remove(node);
+
+ // Get parents from all siblings
+ int siblingSize = node.mSiblings.size();
+ for (int j = 0; j < siblingSize; j++) {
+ node.addParents(node.mSiblings.get(j).mParents);
+ }
+
+ // Now make sure all siblings share the same set of parents
+ for (int j = 0; j < siblingSize; j++) {
+ Node sibling = node.mSiblings.get(j);
+ sibling.addParents(node.mParents);
+ sibling.mParentsAdded = true;
+ }
+ }
+
+ for (int i = 0; i < size; i++) {
+ Node node = mNodes.get(i);
+ if (node != mRootNode && node.mParents == null) {
+ node.addParent(mRootNode);
+ }
+ }
+
+ // Do a DFS on the tree
+ ArrayList<Node> visited = new ArrayList<Node>(mNodes.size());
+ // Assign start/end time
+ mRootNode.mStartTime = 0;
+ mRootNode.mEndTime = mDelayAnim.getDuration();
+ updatePlayTime(mRootNode, visited);
+
+ long maxEndTime = 0;
+ for (int i = 0; i < size; i++) {
+ Node node = mNodes.get(i);
+ if (node.mEndTime == DURATION_INFINITE) {
+ maxEndTime = DURATION_INFINITE;
+ break;
+ } else {
+ maxEndTime = node.mEndTime > maxEndTime ? node.mEndTime : maxEndTime;
+ }
+ }
+ mTotalDuration = maxEndTime;
+ }
+
+ /**
+ * Based on parent's start/end time, calculate children's start/end time. If cycle exists in
+ * the graph, all the nodes on the cycle will be marked to start at {@link #DURATION_INFINITE},
+ * meaning they will ever play.
+ */
+ private void updatePlayTime(Node parent, ArrayList<Node> visited) {
+ if (parent.mChildNodes == null) {
+ return;
+ }
+
+ visited.add(parent);
+ int childrenSize = parent.mChildNodes.size();
+ for (int i = 0; i < childrenSize; i++) {
+ Node child = parent.mChildNodes.get(i);
+ int index = visited.indexOf(child);
+ if (index >= 0) {
+ // Child has been visited, cycle found. Mark all the nodes in the cycle.
+ for (int j = index; j < visited.size(); i++) {
+ visited.get(j).mLatestParent = null;
+ visited.get(j).mStartTime = DURATION_INFINITE;
+ visited.get(j).mEndTime = DURATION_INFINITE;
+ }
+ child.mStartTime = DURATION_INFINITE;
+ child.mEndTime = DURATION_INFINITE;
+ child.mLatestParent = null;
+ Log.w(TAG, "Cycle found in AnimatorSet: " + this);
+ continue;
+ }
+
+ if (child.mStartTime != DURATION_INFINITE) {
+ if (parent.mEndTime == DURATION_INFINITE) {
+ child.mLatestParent = parent;
+ child.mStartTime = DURATION_INFINITE;
+ child.mEndTime = DURATION_INFINITE;
+ } else {
+ if (parent.mEndTime >= child.mStartTime) {
+ child.mLatestParent = parent;
+ child.mStartTime = parent.mEndTime;
+ }
+
+ long duration = child.mAnimation.getTotalDuration();
+ child.mEndTime = duration == DURATION_INFINITE ?
+ DURATION_INFINITE : child.mStartTime + duration;
+ }
+ }
+ updatePlayTime(child, visited);
+ }
+ visited.remove(parent);
+ }
+
+ // Recursively find all the siblings
+ private void findSiblings(Node node, ArrayList<Node> siblings) {
+ if (!siblings.contains(node)) {
+ siblings.add(node);
+ if (node.mSiblings == null) {
+ return;
+ }
+ for (int i = 0; i < node.mSiblings.size(); i++) {
+ findSiblings(node.mSiblings.get(i), siblings);
+ }
+ }
+ }
+
+ /**
+ * @hide
+ */
+ @Override
+ public long getTotalDuration() {
+ updateAnimatorsDuration();
+ createDependencyGraph();
+ return mTotalDuration;
+ }
+
+ private Node getNodeForAnimation(Animator anim) {
+ Node node = mNodeMap.get(anim);
+ if (node == null) {
+ node = new Node(anim);
+ mNodeMap.put(anim, node);
+ mNodes.add(node);
+ }
+ return node;
+ }
+
/**
* A Node is an embodiment of both the Animator that it wraps as well as
* any dependencies that are associated with that Animation. This includes
@@ -1013,46 +1016,13 @@
* well as dependencies of other nodes upon this (in the nodeDependents list).
*/
private static class Node implements Cloneable {
- public Animator animation;
+ Animator mAnimation;
/**
- * These are the dependencies that this node's animation has on other
- * nodes. For example, if this node's animation should begin with some
- * other animation ends, then there will be an item in this node's
- * dependencies list for that other animation's node.
+ * Child nodes are the nodes associated with animations that will be played immediately
+ * after current node.
*/
- public ArrayList<Dependency> dependencies = null;
-
- /**
- * tmpDependencies is a runtime detail. We use the dependencies list for sorting.
- * But we also use the list to keep track of when multiple dependencies are satisfied,
- * but removing each dependency as it is satisfied. We do not want to remove
- * the dependency itself from the list, because we need to retain that information
- * if the AnimatorSet is launched in the future. So we create a copy of the dependency
- * list when the AnimatorSet starts and use this tmpDependencies list to track the
- * list of satisfied dependencies.
- */
- public ArrayList<Dependency> tmpDependencies = null;
-
- /**
- * nodeDependencies is just a list of the nodes that this Node is dependent upon.
- * This information is used in sortNodes(), to determine when a node is a root.
- */
- public ArrayList<Node> nodeDependencies = null;
-
- /**
- * nodeDepdendents is the list of nodes that have this node as a dependency. This
- * is a utility field used in sortNodes to facilitate removing this node as a
- * dependency when it is a root node.
- */
- public ArrayList<Node> nodeDependents = null;
-
- /**
- * Flag indicating whether the animation in this node is finished. This flag
- * is used by AnimatorSet to check, as each animation ends, whether all child animations
- * are done and it's time to send out an end event for the entire AnimatorSet.
- */
- public boolean done = false;
+ ArrayList<Node> mChildNodes = null;
/**
* Temporary field to hold the clone in AnimatorSet#clone. Cleaned after clone is complete
@@ -1060,6 +1030,35 @@
private Node mTmpClone = null;
/**
+ * Flag indicating whether the animation in this node is finished. This flag
+ * is used by AnimatorSet to check, as each animation ends, whether all child animations
+ * are mEnded and it's time to send out an end event for the entire AnimatorSet.
+ */
+ boolean mEnded = false;
+
+ /**
+ * Nodes with animations that are defined to play simultaneously with the animation
+ * associated with this current node.
+ */
+ ArrayList<Node> mSiblings;
+
+ /**
+ * Parent nodes are the nodes with animations preceding current node's animation. Parent
+ * nodes here are derived from user defined animation sequence.
+ */
+ ArrayList<Node> mParents;
+
+ /**
+ * Latest parent is the parent node associated with a animation that finishes after all
+ * the other parents' animations.
+ */
+ Node mLatestParent = null;
+
+ boolean mParentsAdded = false;
+ long mStartTime = 0;
+ long mEndTime = 0;
+
+ /**
* Constructs the Node with the animation that it encapsulates. A Node has no
* dependencies by default; dependencies are added via the addDependency()
* method.
@@ -1067,41 +1066,69 @@
* @param animation The animation that the Node encapsulates.
*/
public Node(Animator animation) {
- this.animation = animation;
- }
-
- /**
- * Add a dependency to this Node. The dependency includes information about the
- * node that this node is dependency upon and the nature of the dependency.
- * @param dependency
- */
- public void addDependency(Dependency dependency) {
- if (dependencies == null) {
- dependencies = new ArrayList<Dependency>();
- nodeDependencies = new ArrayList<Node>();
- }
- dependencies.add(dependency);
- if (!nodeDependencies.contains(dependency.node)) {
- nodeDependencies.add(dependency.node);
- }
- Node dependencyNode = dependency.node;
- if (dependencyNode.nodeDependents == null) {
- dependencyNode.nodeDependents = new ArrayList<Node>();
- }
- dependencyNode.nodeDependents.add(this);
+ this.mAnimation = animation;
}
@Override
public Node clone() {
try {
Node node = (Node) super.clone();
- node.animation = animation.clone();
- node.done = false;
+ node.mAnimation = mAnimation.clone();
+ if (mChildNodes != null) {
+ node.mChildNodes = new ArrayList<>(mChildNodes);
+ }
+ if (mSiblings != null) {
+ node.mSiblings = new ArrayList<>(mSiblings);
+ }
+ if (mParents != null) {
+ node.mParents = new ArrayList<>(mParents);
+ }
+ node.mEnded = false;
return node;
} catch (CloneNotSupportedException e) {
throw new AssertionError();
}
}
+
+ void addChild(Node node) {
+ if (mChildNodes == null) {
+ mChildNodes = new ArrayList<>();
+ }
+ if (!mChildNodes.contains(node)) {
+ mChildNodes.add(node);
+ node.addParent(this);
+ }
+ }
+
+ public void addSibling(Node node) {
+ if (mSiblings == null) {
+ mSiblings = new ArrayList<Node>();
+ }
+ if (!mSiblings.contains(node)) {
+ mSiblings.add(node);
+ node.addSibling(this);
+ }
+ }
+
+ public void addParent(Node node) {
+ if (mParents == null) {
+ mParents = new ArrayList<Node>();
+ }
+ if (!mParents.contains(node)) {
+ mParents.add(node);
+ node.addChild(this);
+ }
+ }
+
+ public void addParents(ArrayList<Node> parents) {
+ if (parents == null) {
+ return;
+ }
+ int size = parents.size();
+ for (int i = 0; i < size; i++) {
+ addParent(parents.get(i));
+ }
+ }
}
/**
@@ -1172,12 +1199,8 @@
* the other methods of this Builder object.
*/
Builder(Animator anim) {
- mCurrentNode = mNodeMap.get(anim);
- if (mCurrentNode == null) {
- mCurrentNode = new Node(anim);
- mNodeMap.put(anim, mCurrentNode);
- mNodes.add(mCurrentNode);
- }
+ mDependencyDirty = true;
+ mCurrentNode = getNodeForAnimation(anim);
}
/**
@@ -1188,14 +1211,8 @@
* {@link AnimatorSet#play(Animator)} method starts.
*/
public Builder with(Animator anim) {
- Node node = mNodeMap.get(anim);
- if (node == null) {
- node = new Node(anim);
- mNodeMap.put(anim, node);
- mNodes.add(node);
- }
- Dependency dependency = new Dependency(mCurrentNode, Dependency.WITH);
- node.addDependency(dependency);
+ Node node = getNodeForAnimation(anim);
+ mCurrentNode.addSibling(node);
return this;
}
@@ -1209,14 +1226,8 @@
*/
public Builder before(Animator anim) {
mReversible = false;
- Node node = mNodeMap.get(anim);
- if (node == null) {
- node = new Node(anim);
- mNodeMap.put(anim, node);
- mNodes.add(node);
- }
- Dependency dependency = new Dependency(mCurrentNode, Dependency.AFTER);
- node.addDependency(dependency);
+ Node node = getNodeForAnimation(anim);
+ mCurrentNode.addChild(node);
return this;
}
@@ -1230,14 +1241,8 @@
*/
public Builder after(Animator anim) {
mReversible = false;
- Node node = mNodeMap.get(anim);
- if (node == null) {
- node = new Node(anim);
- mNodeMap.put(anim, node);
- mNodes.add(node);
- }
- Dependency dependency = new Dependency(node, Dependency.AFTER);
- mCurrentNode.addDependency(dependency);
+ Node node = getNodeForAnimation(anim);
+ mCurrentNode.addParent(node);
return this;
}
diff --git a/core/java/android/animation/ValueAnimator.java b/core/java/android/animation/ValueAnimator.java
index a455f8b..35a8816 100644
--- a/core/java/android/animation/ValueAnimator.java
+++ b/core/java/android/animation/ValueAnimator.java
@@ -575,6 +575,18 @@
}
/**
+ * @hide
+ */
+ @Override
+ public long getTotalDuration() {
+ if (mRepeatCount == INFINITE) {
+ return DURATION_INFINITE;
+ } else {
+ return mUnscaledStartDelay + (mUnscaledDuration * (mRepeatCount + 1));
+ }
+ }
+
+ /**
* Sets the position of the animation to the specified point in time. This time should
* be between 0 and the total duration of the animation, including any repetition. If
* the animation has not yet been started, then it will not advance forward after it is
diff --git a/core/java/android/annotation/IntRange.java b/core/java/android/annotation/IntRange.java
index 1e3c072..b489c01 100644
--- a/core/java/android/annotation/IntRange.java
+++ b/core/java/android/annotation/IntRange.java
@@ -18,6 +18,7 @@
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
+import static java.lang.annotation.ElementType.ANNOTATION_TYPE;
import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.ElementType.LOCAL_VARIABLE;
import static java.lang.annotation.ElementType.METHOD;
@@ -38,7 +39,7 @@
* @hide
*/
@Retention(SOURCE)
-@Target({METHOD,PARAMETER,FIELD,LOCAL_VARIABLE})
+@Target({METHOD,PARAMETER,FIELD,LOCAL_VARIABLE,ANNOTATION_TYPE})
public @interface IntRange {
/** Smallest value, inclusive */
long from() default Long.MIN_VALUE;
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index b2fb906..983af2f 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -31,6 +31,7 @@
import android.transition.TransitionManager;
import android.util.ArrayMap;
import android.util.SuperNotCalledException;
+import android.view.Window.WindowStackCallback;
import android.widget.Toolbar;
import com.android.internal.app.IVoiceInteractor;
@@ -672,7 +673,7 @@
implements LayoutInflater.Factory2,
Window.Callback, KeyEvent.Callback,
OnCreateContextMenuListener, ComponentCallbacks2,
- Window.OnWindowDismissedCallback {
+ Window.OnWindowDismissedCallback, WindowStackCallback {
private static final String TAG = "Activity";
private static final boolean DEBUG_LIFECYCLE = false;
@@ -683,6 +684,13 @@
/** Start of user-defined activity results. */
public static final int RESULT_FIRST_USER = 1;
+ /** @hide Task isn't finished when activity is finished */
+ public static final int DONT_FINISH_TASK_WITH_ACTIVITY = 0;
+ /** @hide Task is finished if the finishing activity is the root of the task */
+ public static final int FINISH_TASK_WITH_ROOT_ACTIVITY = 1;
+ /** @hide Task is finished along with the finishing activity*/
+ public static final int FINISH_TASK_WITH_ACTIVITY = 2;
+
static final String FRAGMENTS_TAG = "android:fragments";
private static final String WINDOW_HIERARCHY_TAG = "android:viewHierarchyState";
@@ -1173,6 +1181,16 @@
}
/**
+ * Called when an {@link #onResume} is coming up, prior to other pre-resume callbacks
+ * such as {@link #onNewIntent} and {@link #onActivityResult}. This is primarily intended
+ * to give the activity a hint that its state is no longer saved -- it will generally
+ * be called after {@link #onSaveInstanceState} and prior to the activity being
+ * resumed/started again.
+ */
+ public void onStateNotSaved() {
+ }
+
+ /**
* Called after {@link #onRestoreInstanceState}, {@link #onRestart}, or
* {@link #onPause}, for your activity to start interacting with the user.
* This is a good place to begin animations, open exclusive-access devices
@@ -1230,6 +1248,22 @@
}
/**
+ * Like {@link #isVoiceInteraction}, but only returns true if this is also the root
+ * of a voice interaction. That is, returns true if this activity was directly
+ * started by the voice interaction service as the initiation of a voice interaction.
+ * Otherwise, for example if it was started by another activity while under voice
+ * interaction, returns false.
+ */
+ public boolean isVoiceInteractionRoot() {
+ try {
+ return mVoiceInteractor != null
+ && ActivityManagerNative.getDefault().isRootVoiceInteraction(mToken);
+ } catch (RemoteException e) {
+ }
+ return false;
+ }
+
+ /**
* Retrieve the active {@link VoiceInteractor} that the user is going through to
* interact with this activity.
*/
@@ -2673,8 +2707,30 @@
* @hide
*/
@Override
- public void onWindowDismissed() {
- finish();
+ public void onWindowDismissed(boolean finishTask) {
+ finish(finishTask ? FINISH_TASK_WITH_ACTIVITY : DONT_FINISH_TASK_WITH_ACTIVITY);
+ }
+
+
+ /** Called to move the window and its activity/task to a different stack container.
+ * For example, a window can move between
+ * {@link android.app.ActivityManager#FULLSCREEN_WORKSPACE_STACK_ID} stack and
+ * {@link android.app.ActivityManager#FREEFORM_WORKSPACE_STACK_ID} stack.
+ *
+ * @param stackId stack Id to change to.
+ * @hide
+ */
+ @Override
+ public void changeWindowStack(int stackId) throws RemoteException {
+ ActivityManagerNative.getDefault().moveActivityToStack(mToken, stackId);
+ }
+
+ /** Returns the current stack Id for the window.
+ * @hide
+ */
+ @Override
+ public int getWindowStackId() throws RemoteException {
+ return ActivityManagerNative.getDefault().getActivityStackId(mToken);
}
/**
@@ -4822,7 +4878,7 @@
* Finishes the current activity and specifies whether to remove the task associated with this
* activity.
*/
- private void finish(boolean finishTask) {
+ private void finish(int finishTask) {
if (mParent == null) {
int resultCode;
Intent resultData;
@@ -4853,7 +4909,7 @@
* onActivityResult().
*/
public void finish() {
- finish(false);
+ finish(DONT_FINISH_TASK_WITH_ACTIVITY);
}
/**
@@ -4953,10 +5009,10 @@
/**
* Call this when your activity is done and should be closed and the task should be completely
- * removed as a part of finishing the Activity.
+ * removed as a part of finishing the root activity of the task.
*/
public void finishAndRemoveTask() {
- finish(true);
+ finish(FINISH_TASK_WITH_ROOT_ACTIVITY);
}
/**
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java
index b2f068b..78e1b76 100644
--- a/core/java/android/app/ActivityManager.java
+++ b/core/java/android/app/ActivityManager.java
@@ -404,6 +404,42 @@
*/
public static final int COMPAT_MODE_TOGGLE = 2;
+ /**
+ * First static stack ID.
+ * @hide
+ */
+ public static final int FIRST_STATIC_STACK_ID = 0;
+
+ /**
+ * Home activity stack ID.
+ * @hide
+ */
+ public static final int HOME_STACK_ID = FIRST_STATIC_STACK_ID;
+
+ /**
+ * ID of stack where fullscreen activities are normally launched into.
+ * @hide
+ */
+ public static final int FULLSCREEN_WORKSPACE_STACK_ID = 1;
+
+ /**
+ * ID of stack where freeform/resized activities are normally launched into.
+ * @hide
+ */
+ public static final int FREEFORM_WORKSPACE_STACK_ID = FULLSCREEN_WORKSPACE_STACK_ID + 1;
+
+ /**
+ * Last static stack stack ID.
+ * @hide
+ */
+ public static final int LAST_STATIC_STACK_ID = FREEFORM_WORKSPACE_STACK_ID;
+
+ /**
+ * Start of ID range used by stacks that are created dynamically.
+ * @hide
+ */
+ public static final int FIRST_DYNAMIC_STACK_ID = LAST_STATIC_STACK_ID + 1;
+
/** @hide */
public int getFrontActivityScreenCompatMode() {
try {
@@ -1789,6 +1825,7 @@
public Rect bounds = new Rect();
public int[] taskIds;
public String[] taskNames;
+ public Rect[] taskBounds;
public int displayId;
@Override
@@ -1805,6 +1842,14 @@
dest.writeInt(bounds.bottom);
dest.writeIntArray(taskIds);
dest.writeStringArray(taskNames);
+ final int boundsCount = taskBounds == null ? 0 : taskBounds.length;
+ dest.writeInt(boundsCount);
+ for (int i = 0; i < boundsCount; i++) {
+ dest.writeInt(taskBounds[i].left);
+ dest.writeInt(taskBounds[i].top);
+ dest.writeInt(taskBounds[i].right);
+ dest.writeInt(taskBounds[i].bottom);
+ }
dest.writeInt(displayId);
}
@@ -1814,6 +1859,17 @@
source.readInt(), source.readInt(), source.readInt(), source.readInt());
taskIds = source.createIntArray();
taskNames = source.createStringArray();
+ final int boundsCount = source.readInt();
+ if (boundsCount > 0) {
+ taskBounds = new Rect[boundsCount];
+ for (int i = 0; i < boundsCount; i++) {
+ taskBounds[i] = new Rect();
+ taskBounds[i].set(
+ source.readInt(), source.readInt(), source.readInt(), source.readInt());
+ }
+ } else {
+ taskBounds = null;
+ }
displayId = source.readInt();
}
@@ -1844,7 +1900,11 @@
prefix = prefix + " ";
for (int i = 0; i < taskIds.length; ++i) {
sb.append(prefix); sb.append("taskId="); sb.append(taskIds[i]);
- sb.append(": "); sb.append(taskNames[i]); sb.append("\n");
+ sb.append(": "); sb.append(taskNames[i]);
+ if (taskBounds != null) {
+ sb.append(" bounds="); sb.append(taskBounds[i].toShortString());
+ }
+ sb.append("\n");
}
return sb.toString();
}
diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java
index e83d635..4232db4 100644
--- a/core/java/android/app/ActivityManagerNative.java
+++ b/core/java/android/app/ActivityManagerNative.java
@@ -346,7 +346,7 @@
if (data.readInt() != 0) {
resultData = Intent.CREATOR.createFromParcel(data);
}
- boolean finishTask = (data.readInt() != 0);
+ int finishTask = data.readInt();
boolean res = finishActivity(token, resultCode, resultData, finishTask);
reply.writeNoException();
reply.writeInt(res ? 1 : 0);
@@ -752,6 +752,16 @@
return true;
}
+ case POSITION_TASK_IN_STACK_TRANSACTION: {
+ data.enforceInterface(IActivityManager.descriptor);
+ int taskId = data.readInt();
+ int stackId = data.readInt();
+ int position = data.readInt();
+ positionTaskInStack(taskId, stackId, position);
+ reply.writeNoException();
+ return true;
+ }
+
case GET_ALL_STACK_INFOS_TRANSACTION: {
data.enforceInterface(IActivityManager.descriptor);
List<StackInfo> list = getAllStackInfos();
@@ -799,6 +809,14 @@
return true;
}
+ case SET_FOCUSED_TASK_TRANSACTION: {
+ data.enforceInterface(IActivityManager.descriptor);
+ int taskId = data.readInt();
+ setFocusedStack(taskId);
+ reply.writeNoException();
+ return true;
+ }
+
case REGISTER_TASK_STACK_LISTENER_TRANSACTION: {
data.enforceInterface(IActivityManager.descriptor);
IBinder token = data.readStrongBinder();
@@ -2429,6 +2447,15 @@
return true;
}
+ case GET_TASK_BOUNDS_TRANSACTION: {
+ data.enforceInterface(IActivityManager.descriptor);
+ int taskId = data.readInt();
+ Rect r = getTaskBounds(taskId);
+ reply.writeNoException();
+ r.writeToParcel(reply, 0);
+ return true;
+ }
+
case GET_TASK_DESCRIPTION_ICON_TRANSACTION: {
data.enforceInterface(IActivityManager.descriptor);
String filename = data.readString();
@@ -2583,6 +2610,15 @@
return true;
}
+ case IS_ROOT_VOICE_INTERACTION_TRANSACTION: {
+ data.enforceInterface(IActivityManager.descriptor);
+ IBinder token = data.readStrongBinder();
+ boolean res = isRootVoiceInteraction(token);
+ reply.writeNoException();
+ reply.writeInt(res ? 1 : 0);
+ return true;
+ }
+
case START_BINDER_TRACKING_TRANSACTION: {
data.enforceInterface(IActivityManager.descriptor);
boolean res = startBinderTracking();
@@ -2600,6 +2636,22 @@
reply.writeInt(res ? 1 : 0);
return true;
}
+ case GET_ACTIVITY_STACK_ID_TRANSACTION: {
+ data.enforceInterface(IActivityManager.descriptor);
+ IBinder token = data.readStrongBinder();
+ int stackId = getActivityStackId(token);
+ reply.writeNoException();
+ reply.writeInt(stackId);
+ return true;
+ }
+ case MOVE_ACTIVITY_TO_STACK_TRANSACTION: {
+ data.enforceInterface(IActivityManager.descriptor);
+ IBinder token = data.readStrongBinder();
+ int stackId = data.readInt();
+ moveActivityToStack(token, stackId);
+ reply.writeNoException();
+ return true;
+ }
}
return super.onTransact(code, data, reply, flags);
@@ -2913,7 +2965,7 @@
data.recycle();
return result;
}
- public boolean finishActivity(IBinder token, int resultCode, Intent resultData, boolean finishTask)
+ public boolean finishActivity(IBinder token, int resultCode, Intent resultData, int finishTask)
throws RemoteException {
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
@@ -2926,7 +2978,7 @@
} else {
data.writeInt(0);
}
- data.writeInt(finishTask ? 1 : 0);
+ data.writeInt(finishTask);
mRemote.transact(FINISH_ACTIVITY_TRANSACTION, data, reply, 0);
reply.readException();
boolean res = reply.readInt() != 0;
@@ -3452,6 +3504,20 @@
reply.recycle();
}
@Override
+ public void positionTaskInStack(int taskId, int stackId, int position) throws RemoteException
+ {
+ Parcel data = Parcel.obtain();
+ Parcel reply = Parcel.obtain();
+ data.writeInterfaceToken(IActivityManager.descriptor);
+ data.writeInt(taskId);
+ data.writeInt(stackId);
+ data.writeInt(position);
+ mRemote.transact(POSITION_TASK_IN_STACK_TRANSACTION, data, reply, 0);
+ reply.readException();
+ data.recycle();
+ reply.recycle();
+ }
+ @Override
public List<StackInfo> getAllStackInfos() throws RemoteException
{
Parcel data = Parcel.obtain();
@@ -3520,6 +3586,18 @@
return focusedStackId;
}
@Override
+ public void setFocusedTask(int taskId) throws RemoteException
+ {
+ Parcel data = Parcel.obtain();
+ Parcel reply = Parcel.obtain();
+ data.writeInterfaceToken(IActivityManager.descriptor);
+ data.writeInt(taskId);
+ mRemote.transact(SET_FOCUSED_TASK_TRANSACTION, data, reply, 0);
+ reply.readException();
+ data.recycle();
+ reply.recycle();
+ }
+ @Override
public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException
{
Parcel data = Parcel.obtain();
@@ -5790,6 +5868,21 @@
}
@Override
+ public Rect getTaskBounds(int taskId) throws RemoteException
+ {
+ Parcel data = Parcel.obtain();
+ Parcel reply = Parcel.obtain();
+ data.writeInterfaceToken(IActivityManager.descriptor);
+ data.writeInt(taskId);
+ mRemote.transact(GET_TASK_BOUNDS_TRANSACTION, data, reply, 0);
+ reply.readException();
+ Rect rect = Rect.CREATOR.createFromParcel(reply);
+ data.recycle();
+ reply.recycle();
+ return rect;
+ }
+
+ @Override
public Bitmap getTaskDescriptionIcon(String filename) throws RemoteException {
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
@@ -6010,5 +6103,46 @@
return res != 0;
}
+ @Override
+ public boolean isRootVoiceInteraction(IBinder token) throws RemoteException {
+ Parcel data = Parcel.obtain();
+ Parcel reply = Parcel.obtain();
+ data.writeInterfaceToken(IActivityManager.descriptor);
+ data.writeStrongBinder(token);
+ mRemote.transact(IS_ROOT_VOICE_INTERACTION_TRANSACTION, data, reply, 0);
+ reply.readException();
+ int res = reply.readInt();
+ data.recycle();
+ reply.recycle();
+ return res != 0;
+ }
+
+ @Override
+ public void moveActivityToStack(IBinder token, int stackId) throws RemoteException {
+ Parcel data = Parcel.obtain();
+ Parcel reply = Parcel.obtain();
+ data.writeInterfaceToken(IActivityManager.descriptor);
+ data.writeStrongBinder(token);
+ data.writeInt(stackId);
+ mRemote.transact(MOVE_ACTIVITY_TO_STACK_TRANSACTION, data, reply, 0);
+ reply.readException();
+ data.recycle();
+ reply.recycle();
+ }
+
+ @Override
+ public int getActivityStackId(IBinder token) throws RemoteException {
+ Parcel data = Parcel.obtain();
+ Parcel reply = Parcel.obtain();
+ data.writeInterfaceToken(IActivityManager.descriptor);
+ data.writeStrongBinder(token);
+ mRemote.transact(GET_ACTIVITY_STACK_ID_TRANSACTION, data, reply, 0);
+ reply.readException();
+ int stackId = reply.readInt();
+ data.recycle();
+ reply.recycle();
+ return stackId;
+ }
+
private IBinder mRemote;
}
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 4474c75..594ec41 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -2555,7 +2555,8 @@
// manager to stop us.
try {
ActivityManagerNative.getDefault()
- .finishActivity(r.token, Activity.RESULT_CANCELED, null, false);
+ .finishActivity(r.token, Activity.RESULT_CANCELED, null,
+ Activity.DONT_FINISH_TASK_WITH_ACTIVITY);
} catch (RemoteException ex) {
// Ignore
}
@@ -3120,6 +3121,7 @@
r.activity.mStartedActivity = false;
}
try {
+ r.activity.onStateNotSaved();
r.activity.mFragments.noteStateNotSaved();
if (r.pendingIntents != null) {
deliverNewIntents(r, r.pendingIntents);
@@ -3280,7 +3282,8 @@
// just end this activity.
try {
ActivityManagerNative.getDefault()
- .finishActivity(token, Activity.RESULT_CANCELED, null, false);
+ .finishActivity(token, Activity.RESULT_CANCELED, null,
+ Activity.DONT_FINISH_TASK_WITH_ACTIVITY);
} catch (RemoteException ex) {
}
}
diff --git a/core/java/android/app/AlarmManager.java b/core/java/android/app/AlarmManager.java
index 1de8f98..fb03b62 100644
--- a/core/java/android/app/AlarmManager.java
+++ b/core/java/android/app/AlarmManager.java
@@ -720,7 +720,7 @@
}
// Reject this timezone if it isn't an Olson zone we recognize.
- if (mTargetSdkVersion >= Build.VERSION_CODES.MNC) {
+ if (mTargetSdkVersion >= Build.VERSION_CODES.M) {
boolean hasTimeZone = false;
try {
hasTimeZone = ZoneInfoDB.getInstance().hasTimeZone(timeZone);
diff --git a/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java
index 862d235..42ac67c 100644
--- a/core/java/android/app/AppOpsManager.java
+++ b/core/java/android/app/AppOpsManager.java
@@ -1234,6 +1234,14 @@
}
/** @hide */
+ public void setUidMode(int code, int uid, int mode) {
+ try {
+ mService.setUidMode(code, uid, mode);
+ } catch (RemoteException e) {
+ }
+ }
+
+ /** @hide */
public void setMode(int code, int uid, String packageName, int mode) {
try {
mService.setMode(code, uid, packageName, mode);
diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java
index dbe91f9..0adce5d 100644
--- a/core/java/android/app/ApplicationPackageManager.java
+++ b/core/java/android/app/ApplicationPackageManager.java
@@ -777,7 +777,9 @@
public List<ProviderInfo> queryContentProviders(String processName,
int uid, int flags) {
try {
- return mPM.queryContentProviders(processName, uid, flags);
+ ParceledListSlice<ProviderInfo> slice
+ = mPM.queryContentProviders(processName, uid, flags);
+ return slice != null ? slice.getList() : null;
} catch (RemoteException e) {
throw new RuntimeException("Package manager has died", e);
}
diff --git a/core/java/android/app/Dialog.java b/core/java/android/app/Dialog.java
index f6e0e1e..6e8e2c4 100644
--- a/core/java/android/app/Dialog.java
+++ b/core/java/android/app/Dialog.java
@@ -721,29 +721,29 @@
public void onContentChanged() {
}
-
+
public void onWindowFocusChanged(boolean hasFocus) {
}
public void onAttachedToWindow() {
}
-
+
public void onDetachedFromWindow() {
}
/** @hide */
@Override
- public void onWindowDismissed() {
+ public void onWindowDismissed(boolean finishTask) {
dismiss();
}
-
+
/**
- * Called to process key events. You can override this to intercept all
- * key events before they are dispatched to the window. Be sure to call
+ * Called to process key events. You can override this to intercept all
+ * key events before they are dispatched to the window. Be sure to call
* this implementation for key events that should be handled normally.
- *
+ *
* @param event The key event.
- *
+ *
* @return boolean Return true if this event was consumed.
*/
public boolean dispatchKeyEvent(KeyEvent event) {
diff --git a/core/java/android/app/ExitTransitionCoordinator.java b/core/java/android/app/ExitTransitionCoordinator.java
index 7fbb99a..4b670cd 100644
--- a/core/java/android/app/ExitTransitionCoordinator.java
+++ b/core/java/android/app/ExitTransitionCoordinator.java
@@ -240,7 +240,7 @@
getWindow().setBackgroundDrawable(new ColorDrawable(Color.BLACK));
}
final boolean targetsM = decorView == null || decorView.getContext()
- .getApplicationInfo().targetSdkVersion >= VERSION_CODES.MNC;
+ .getApplicationInfo().targetSdkVersion >= VERSION_CODES.M;
ArrayList<String> sharedElementNames = targetsM ? mSharedElementNames :
mAllSharedElementNames;
ActivityOptions options = ActivityOptions.makeSceneTransitionAnimation(mActivity, this,
diff --git a/core/java/android/app/IActivityManager.java b/core/java/android/app/IActivityManager.java
index 55cf3462..00e397d 100644
--- a/core/java/android/app/IActivityManager.java
+++ b/core/java/android/app/IActivityManager.java
@@ -93,7 +93,7 @@
public boolean startNextMatchingActivity(IBinder callingActivity,
Intent intent, Bundle options) throws RemoteException;
public int startActivityFromRecents(int taskId, Bundle options) throws RemoteException;
- public boolean finishActivity(IBinder token, int code, Intent data, boolean finishTask)
+ public boolean finishActivity(IBinder token, int code, Intent data, int finishTask)
throws RemoteException;
public void finishSubActivity(IBinder token, String resultWho, int requestCode) throws RemoteException;
public boolean finishActivityAffinity(IBinder token) throws RemoteException;
@@ -139,11 +139,13 @@
public void moveTaskBackwards(int task) throws RemoteException;
public void moveTaskToStack(int taskId, int stackId, boolean toTop) throws RemoteException;
public void resizeStack(int stackId, Rect bounds) throws RemoteException;
+ public void positionTaskInStack(int taskId, int stackId, int position) throws RemoteException;
public List<StackInfo> getAllStackInfos() throws RemoteException;
public StackInfo getStackInfo(int stackId) throws RemoteException;
public boolean isInHomeStack(int taskId) throws RemoteException;
public void setFocusedStack(int stackId) throws RemoteException;
public int getFocusedStackId() throws RemoteException;
+ public void setFocusedTask(int taskId) throws RemoteException;
public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException;
public int getTaskForActivity(IBinder token, boolean onlyRoot) throws RemoteException;
public ContentProviderHolder getContentProvider(IApplicationThread caller,
@@ -486,6 +488,7 @@
throws RemoteException;
public void setTaskResizeable(int taskId, boolean resizeable) throws RemoteException;
public void resizeTask(int taskId, Rect bounds) throws RemoteException;
+ public Rect getTaskBounds(int taskId) throws RemoteException;
public Bitmap getTaskDescriptionIcon(String filename) throws RemoteException;
public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts)
@@ -515,6 +518,8 @@
public boolean setProcessMemoryTrimLevel(String process, int uid, int level)
throws RemoteException;
+ public boolean isRootVoiceInteraction(IBinder token) throws RemoteException;
+
// Start Binder transaction tracking for all applications.
public boolean startBinderTracking() throws RemoteException;
@@ -522,6 +527,9 @@
// descriptor.
public boolean stopBinderTrackingAndDump(ParcelFileDescriptor fd) throws RemoteException;
+ public int getActivityStackId(IBinder token) throws RemoteException;
+ public void moveActivityToStack(IBinder token, int stackId) throws RemoteException;
+
/*
* Private non-Binder interfaces
*/
@@ -752,7 +760,7 @@
int GET_PACKAGE_ASK_SCREEN_COMPAT_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+127;
int SET_PACKAGE_ASK_SCREEN_COMPAT_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+128;
int SWITCH_USER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+129;
- int ___AVAILABLE_1___ = IBinder.FIRST_CALL_TRANSACTION+130;
+ int SET_FOCUSED_TASK_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+130;
int REMOVE_TASK_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+131;
int REGISTER_PROCESS_OBSERVER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+132;
int UNREGISTER_PROCESS_OBSERVER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+133;
@@ -804,7 +812,7 @@
int RELEASE_PERSISTABLE_URI_PERMISSION_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+180;
int GET_PERSISTED_URI_PERMISSIONS_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+181;
int APP_NOT_RESPONDING_VIA_PROVIDER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+182;
- // Available
+ int GET_TASK_BOUNDS_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+183;
int GET_ACTIVITY_DISPLAY_ID_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+184;
int DELETE_ACTIVITY_CONTAINER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+185;
int SET_PROCESS_MEMORY_TRIM_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+186;
@@ -868,8 +876,12 @@
int IS_SCREEN_CAPTURE_ALLOWED_ON_CURRENT_ACTIVITY_TRANSACTION
= IBinder.FIRST_CALL_TRANSACTION+299;
int SHOW_ASSIST_FROM_ACTIVITY_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+300;
+ int IS_ROOT_VOICE_INTERACTION_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+301;
// Start of N transactions
int START_BINDER_TRACKING_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 340;
int STOP_BINDER_TRACKING_AND_DUMP_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 341;
+ int POSITION_TASK_IN_STACK_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 342;
+ int GET_ACTIVITY_STACK_ID_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 343;
+ int MOVE_ACTIVITY_TO_STACK_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 344;
}
diff --git a/core/java/android/app/Instrumentation.java b/core/java/android/app/Instrumentation.java
index c2d901d..69b8b95 100644
--- a/core/java/android/app/Instrumentation.java
+++ b/core/java/android/app/Instrumentation.java
@@ -1810,9 +1810,14 @@
throw new SecurityException(
"Starting under voice control not allowed for: " + intent);
case ActivityManager.START_NOT_CURRENT_USER_ACTIVITY:
- throw new SecurityException(
- "Not allowed to start background user activity that shouldn't be"
- + " displayed for all users.");
+ // Fail silently for this case so we don't break current apps.
+ // TODO(b/22929608): Instead of failing silently or throwing an exception,
+ // we should properly position the activity in the stack (i.e. behind all current
+ // user activity/task) and not change the positioning of stacks.
+ Log.e(TAG,
+ "Not allowed to start background user activity that shouldn't be displayed"
+ + " for all users. Failing silently...");
+ break;
default:
throw new AndroidRuntimeException("Unknown error code "
+ res + " when starting " + intent);
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index f3f2428..9381327 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -4607,7 +4607,7 @@
* Size value for use with {@link #setCustomSizePreset} to show this notification with
* default sizing.
* <p>For custom display notifications created using {@link #setDisplayIntent},
- * the default is {@link #SIZE_LARGE}. All other notifications size automatically based
+ * the default is {@link #SIZE_MEDIUM}. All other notifications size automatically based
* on their content.
*/
public static final int SIZE_DEFAULT = 0;
diff --git a/core/java/android/app/SystemServiceRegistry.java b/core/java/android/app/SystemServiceRegistry.java
index 01a1c18..3d264c6 100644
--- a/core/java/android/app/SystemServiceRegistry.java
+++ b/core/java/android/app/SystemServiceRegistry.java
@@ -220,11 +220,12 @@
SYSTEM_SERVICE_NAMES.put(android.text.ClipboardManager.class, Context.CLIPBOARD_SERVICE);
registerService(Context.CONNECTIVITY_SERVICE, ConnectivityManager.class,
- new StaticServiceFetcher<ConnectivityManager>() {
+ new StaticOuterContextServiceFetcher<ConnectivityManager>() {
@Override
- public ConnectivityManager createService() {
+ public ConnectivityManager createService(Context context) {
IBinder b = ServiceManager.getService(Context.CONNECTIVITY_SERVICE);
- return new ConnectivityManager(IConnectivityManager.Stub.asInterface(b));
+ IConnectivityManager service = IConnectivityManager.Stub.asInterface(b);
+ return new ConnectivityManager(context, service);
}});
registerService(Context.COUNTRY_DETECTOR, CountryDetector.class,
@@ -793,4 +794,30 @@
public abstract T createService();
}
+
+ /**
+ * Like StaticServiceFetcher, creates only one instance of the service per process, but when
+ * creating the service for the first time, passes it the outer context of the creating
+ * component.
+ *
+ * TODO: Is this safe in the case where multiple applications share the same process?
+ * TODO: Delete this once its only user (ConnectivityManager) is known to work well in the
+ * case where multiple application components each have their own ConnectivityManager object.
+ */
+ static abstract class StaticOuterContextServiceFetcher<T> implements ServiceFetcher<T> {
+ private T mCachedInstance;
+
+ @Override
+ public final T getService(ContextImpl ctx) {
+ synchronized (StaticOuterContextServiceFetcher.this) {
+ if (mCachedInstance == null) {
+ mCachedInstance = createService(ctx.getOuterContext());
+ }
+ return mCachedInstance;
+ }
+ }
+
+ public abstract T createService(Context applicationContext);
+ }
+
}
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index b2b1727..c505b0b 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -112,7 +112,7 @@
*
* In version {@link android.os.Build.VERSION_CODES#LOLLIPOP}, this intent must contain the
* extra {@link #EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_NAME}.
- * As of {@link android.os.Build.VERSION_CODES#MNC}, it should contain the extra
+ * As of {@link android.os.Build.VERSION_CODES#M}, it should contain the extra
* {@link #EXTRA_PROVISIONING_DEVICE_ADMIN_COMPONENT_NAME} instead, although specifying only
* {@link #EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_NAME} is still supported.
*
@@ -124,6 +124,12 @@
*
* <p> If provisioning fails, the managedProfile is removed so the device returns to its
* previous state.
+ *
+ * <p>If launched with {@link android.app.Activity#startActivityForResult(Intent, int)} a
+ * result code of {@link android.app.Activity#RESULT_OK} implies that the synchronous part of
+ * the provisioning flow was successful, although this doesn't guarantee the full flow will
+ * succeed. Conversely a result code of {@link android.app.Activity#RESULT_CANCELED} implies
+ * that the user backed-out of provisioning, or some precondition for provisioning wasn't met.
*/
@SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
public static final String ACTION_PROVISION_MANAGED_PROFILE
@@ -158,6 +164,10 @@
*
* <p> If provisioning fails, the device is factory reset.
*
+ * <p>A result code of {@link android.app.Activity#RESULT_OK} implies that the synchronous part
+ * of the provisioning flow was successful, although this doesn't guarantee the full flow will
+ * succeed. Conversely a result code of {@link android.app.Activity#RESULT_CANCELED} implies
+ * that the user backed-out of provisioning, or some precondition for provisioning wasn't met.
*/
@SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
public static final String ACTION_PROVISION_MANAGED_DEVICE
@@ -165,13 +175,19 @@
/**
* A {@link android.os.Parcelable} extra of type {@link android.os.PersistableBundle} that
- * allows a mobile device management application which starts managed provisioning to pass data
- * to itself.
+ * allows a mobile device management application or NFC programmer application which starts
+ * managed provisioning to pass data to the management application instance after provisioning.
* <p>
* If used with {@link #ACTION_PROVISION_MANAGED_PROFILE} it can be used by the application that
* sends the intent to pass data to itself on the newly created profile.
* If used with {@link #ACTION_PROVISION_MANAGED_DEVICE} it allows passing data to the same
* instance of the app on the primary user.
+ * Starting from {@link android.os.Build.VERSION_CODES#M}, if used with
+ * {@link #MIME_TYPE_PROVISIONING_NFC} as part of NFC managed device provisioning, the NFC
+ * message should contain a stringified {@link java.util.Properties} instance, whose string
+ * properties will be converted into a {@link android.os.PersistableBundle} and passed to the
+ * management application after provisioning.
+ *
* <p>
* In both cases the application receives the data in
* {@link DeviceAdminReceiver#onProfileProvisioningComplete} via an intent with the action
@@ -417,7 +433,7 @@
*
* <p><strong>Note:</strong> for devices running {@link android.os.Build.VERSION_CODES#LOLLIPOP}
* and {@link android.os.Build.VERSION_CODES#LOLLIPOP_MR1} only SHA-1 hash is supported.
- * Starting from {@link android.os.Build.VERSION_CODES#MNC}, this parameter accepts SHA-256 in
+ * Starting from {@link android.os.Build.VERSION_CODES#M}, this parameter accepts SHA-256 in
* addition to SHA-1. Support for SHA-1 is likely to be removed in future OS releases.
*/
public static final String EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_CHECKSUM
@@ -587,10 +603,12 @@
* <li>{@link #EXTRA_PROVISIONING_WIFI_PROXY_HOST}, optional</li>
* <li>{@link #EXTRA_PROVISIONING_WIFI_PROXY_PORT} (convert to String), optional</li>
* <li>{@link #EXTRA_PROVISIONING_WIFI_PROXY_BYPASS}, optional</li>
- * <li>{@link #EXTRA_PROVISIONING_WIFI_PAC_URL}, optional</li></ul>
+ * <li>{@link #EXTRA_PROVISIONING_WIFI_PAC_URL}, optional</li>
+ * <li>{@link #EXTRA_PROVISIONING_ADMIN_EXTRAS_BUNDLE}, optional, supported from
+ * {@link android.os.Build.VERSION_CODES#M} </li></ul>
*
* <p>
- * As of {@link android.os.Build.VERSION_CODES#MNC}, the properties should contain
+ * As of {@link android.os.Build.VERSION_CODES#M}, the properties should contain
* {@link #EXTRA_PROVISIONING_DEVICE_ADMIN_COMPONENT_NAME} instead of
* {@link #EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_NAME}, (although specifying only
* {@link #EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_NAME} is still supported).
@@ -603,7 +621,7 @@
* @hide
* This MIME type is used for starting the Device Owner provisioning that requires
* new provisioning features introduced in API version
- * {@link android.os.Build.VERSION_CODES#MNC} in addition to those supported in earlier
+ * {@link android.os.Build.VERSION_CODES#M} in addition to those supported in earlier
* versions.
*
* <p>During device owner provisioning a device admin app is set as the owner of the device.
@@ -2415,7 +2433,7 @@
* <p>The calling device admin must be a device or profile owner. If it is not, a
* security exception will be thrown.
*
- * <p>From version {@link android.os.Build.VERSION_CODES#MNC} disabling screen capture also
+ * <p>From version {@link android.os.Build.VERSION_CODES#M} disabling screen capture also
* blocks assist requests for all activities of the relevant user.
*
* @param admin Which {@link DeviceAdminReceiver} this request is associated with.
@@ -2499,9 +2517,9 @@
* this method; if it has not, a security exception will be thrown.
*
* <p>Calling this from a managed profile before version
- * {@link android.os.Build.VERSION_CODES#MNC} will throw a security exception.
+ * {@link android.os.Build.VERSION_CODES#M} will throw a security exception.
*
- * <p>From version {@link android.os.Build.VERSION_CODES#MNC} a profile owner can set:
+ * <p>From version {@link android.os.Build.VERSION_CODES#M} a profile owner can set:
* <ul>
* <li>{@link #KEYGUARD_DISABLE_TRUST_AGENTS}, {@link #KEYGUARD_DISABLE_FINGERPRINT}
* these will affect the profile's parent user.
@@ -3623,7 +3641,7 @@
* @return the {@link android.os.UserHandle} object for the created user, or {@code null} if the
* user could not be created.
*
- * @deprecated From {@link android.os.Build.VERSION_CODES#MNC}
+ * @deprecated From {@link android.os.Build.VERSION_CODES#M}
*/
@Deprecated
public UserHandle createUser(@NonNull ComponentName admin, String name) {
@@ -3660,7 +3678,7 @@
* @return the {@link android.os.UserHandle} object for the created user, or {@code null} if the
* user could not be created.
*
- * @deprecated From {@link android.os.Build.VERSION_CODES#MNC}
+ * @deprecated From {@link android.os.Build.VERSION_CODES#M}
*/
@Deprecated
public UserHandle createAndInitializeUser(@NonNull ComponentName admin, String name,
@@ -3914,7 +3932,7 @@
* <p>Any packages that shares uid with an allowed package will also be allowed
* to activate lock task.
*
- * From {@link android.os.Build.VERSION_CODES#MNC} removing packages from the lock task
+ * From {@link android.os.Build.VERSION_CODES#M} removing packages from the lock task
* package list results in locked tasks belonging to those packages to be finished.
*
* This function can only be called by the device owner.
@@ -3982,14 +4000,14 @@
* <li>{@link Settings.Global#USB_MASS_STORAGE_ENABLED}</li>
* <li>{@link Settings.Global#WIFI_SLEEP_POLICY}</li>
* <li>{@link Settings.Global#STAY_ON_WHILE_PLUGGED_IN}
- * This setting is only available from {@link android.os.Build.VERSION_CODES#MNC} onwards
+ * This setting is only available from {@link android.os.Build.VERSION_CODES#M} onwards
* and can only be set if {@link #setMaximumTimeToLock} is not used to set a timeout.</li>
* <li>{@link Settings.Global#WIFI_DEVICE_OWNER_CONFIGS_LOCKDOWN}</li>
- * This setting is only available from {@link android.os.Build.VERSION_CODES#MNC} onwards.
+ * This setting is only available from {@link android.os.Build.VERSION_CODES#M} onwards.
* </li>
* </ul>
* <p>Changing the following settings has no effect as of
- * {@link android.os.Build.VERSION_CODES#MNC}:
+ * {@link android.os.Build.VERSION_CODES#M}:
* <ul>
* <li>{@link Settings.Global#BLUETOOTH_ON}.
* Use {@link android.bluetooth.BluetoothAdapter#enable()} and
@@ -4344,7 +4362,7 @@
* the permission grant state via {@link #setPermissionGrantState}.
*
* <p/>As this policy only acts on runtime permission requests, it only applies to applications
- * built with a {@code targetSdkVersion} of {@link android.os.Build.VERSION_CODES#MNC} or later.
+ * built with a {@code targetSdkVersion} of {@link android.os.Build.VERSION_CODES#M} or later.
*
* @param admin Which profile or device owner this request is associated with.
* @param policy One of the policy constants {@link #PERMISSION_POLICY_PROMPT},
@@ -4388,7 +4406,7 @@
* revoke the permission. It retains the previous grant, if any.
*
* <p/>Permissions can be granted or revoked only for applications built with a
- * {@code targetSdkVersion} of {@link android.os.Build.VERSION_CODES#MNC} or later.
+ * {@code targetSdkVersion} of {@link android.os.Build.VERSION_CODES#M} or later.
*
* @param admin Which profile or device owner this request is associated with.
* @param packageName The application to grant or revoke a permission to.
diff --git a/core/java/android/app/assist/AssistStructure.java b/core/java/android/app/assist/AssistStructure.java
index e08686c..6b720c0 100644
--- a/core/java/android/app/assist/AssistStructure.java
+++ b/core/java/android/app/assist/AssistStructure.java
@@ -1106,7 +1106,7 @@
@Override
public void setAssistBlocked(boolean state) {
mNode.mFlags = (mNode.mFlags&~ViewNode.FLAGS_ASSIST_BLOCKED)
- | (state ? 0 : ViewNode.FLAGS_ASSIST_BLOCKED);
+ | (state ? ViewNode.FLAGS_ASSIST_BLOCKED : 0);
}
@Override
@@ -1412,6 +1412,9 @@
if (extras != null) {
Log.i(TAG, prefix + " Extras: " + extras);
}
+ if (node.isAssistBlocked()) {
+ Log.i(TAG, prefix + " BLOCKED");
+ }
final int NCHILDREN = node.getChildCount();
if (NCHILDREN > 0) {
Log.i(TAG, prefix + " Children:");
diff --git a/core/java/android/app/backup/BackupTransport.java b/core/java/android/app/backup/BackupTransport.java
index 4d2158f..954ccef 100644
--- a/core/java/android/app/backup/BackupTransport.java
+++ b/core/java/android/app/backup/BackupTransport.java
@@ -415,7 +415,7 @@
* if this method returns TRANSPORT_OK. To avoid storing such payloads the transport
* must recognize this case and return TRANSPORT_PACKAGE_REJECTED.
*
- * Added in MNC (API 23).
+ * Added in {@link android.os.Build.VERSION_CODES#M}.
*
* @param size The estimated size of the full-data payload for this app. This includes
* manifest and archive format overhead, but is not guaranteed to be precise.
diff --git a/core/java/android/bluetooth/BluetoothAdapter.java b/core/java/android/bluetooth/BluetoothAdapter.java
index 97afafa..1f3ff51 100644
--- a/core/java/android/bluetooth/BluetoothAdapter.java
+++ b/core/java/android/bluetooth/BluetoothAdapter.java
@@ -1002,6 +1002,25 @@
}
/**
+ * Factory reset bluetooth settings.
+ *
+ * <p>Requires the {@link android.Manifest.permission#BLUETOOTH_PRIVILEGED}
+ * permission
+ *
+ * @return true to indicate that the config file was successfully cleared
+ *
+ * @hide
+ */
+ public boolean factoryReset() {
+ try {
+ if (mService != null) {
+ return mService.factoryReset();
+ }
+ } catch (RemoteException e) {Log.e(TAG, "", e);}
+ return false;
+ }
+
+ /**
* Get the UUIDs supported by the local Bluetooth adapter.
*
* <p>Requires {@link android.Manifest.permission#BLUETOOTH}
diff --git a/core/java/android/bluetooth/IBluetooth.aidl b/core/java/android/bluetooth/IBluetooth.aidl
index 7a894ae..66f3418 100644
--- a/core/java/android/bluetooth/IBluetooth.aidl
+++ b/core/java/android/bluetooth/IBluetooth.aidl
@@ -92,6 +92,7 @@
ParcelFileDescriptor createSocketChannel(int type, in String serviceName, in ParcelUuid uuid, int port, int flag);
boolean configHciSnoopLog(boolean enable);
+ boolean factoryReset();
boolean isMultiAdvertisementSupported();
boolean isPeripheralModeSupported();
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index f786d2f..537a2e9 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -658,6 +658,15 @@
public static final String ACTION_DEFAULT = ACTION_VIEW;
/**
+ * Activity Action: Quick view the data.
+ * <p>Input: {@link #getData} is URI from which to retrieve data.
+ * <p>Output: nothing.
+ * @hide
+ */
+ @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
+ public static final String ACTION_QUICK_VIEW = "android.intent.action.QUICK_VIEW";
+
+ /**
* Used to indicate that some piece of data should be attached to some other
* place. For example, image data could be attached to a contact. It is up
* to the recipient to decide where the data should be attached; the intent
@@ -1021,7 +1030,7 @@
* numbers. Applications can <strong>dial</strong> emergency numbers using
* {@link #ACTION_DIAL}, however.
*
- * <p>Note: if you app targets {@link android.os.Build.VERSION_CODES#MNC MNC}
+ * <p>Note: if you app targets {@link android.os.Build.VERSION_CODES#M M}
* and above and declares as using the {@link android.Manifest.permission#CALL_PHONE}
* permission which is not granted, then attempting to use this action will
* result in a {@link java.lang.SecurityException}.
@@ -1782,14 +1791,6 @@
@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
public static final String ACTION_ALARM_CHANGED = "android.intent.action.ALARM_CHANGED";
/**
- * Sync State Changed Action: This is broadcast when the sync starts or stops or when one has
- * been failing for a long time. It is used by the SyncManager and the StatusBar service.
- * @hide
- */
- @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
- public static final String ACTION_SYNC_STATE_CHANGED
- = "android.intent.action.SYNC_STATE_CHANGED";
- /**
* Broadcast Action: This is broadcast once, after the system has finished
* booting. It can be used to perform application-specific initialization,
* such as installing alarms. You must hold the
@@ -2199,7 +2200,9 @@
/**
* Activity Action: Start this activity to request system shutdown.
* The optional boolean extra field {@link #EXTRA_KEY_CONFIRM} can be set to true
- * to request confirmation from the user before shutting down.
+ * to request confirmation from the user before shutting down. The optional boolean
+ * extra field {@link #EXTRA_USER_REQUESTED_SHUTDOWN} can be set to true to
+ * indicate that the shutdown is requested by the user.
*
* <p class="note">This is a protected intent that can only be sent
* by the system.
@@ -3513,6 +3516,15 @@
public static final String EXTRA_KEY_CONFIRM = "android.intent.extra.KEY_CONFIRM";
/**
+ * Set to true in {@link #ACTION_REQUEST_SHUTDOWN} to indicate that the shutdown is
+ * requested by the user.
+ *
+ * {@hide}
+ */
+ public static final String EXTRA_USER_REQUESTED_SHUTDOWN =
+ "android.intent.extra.USER_REQUESTED_SHUTDOWN";
+
+ /**
* Used as a boolean extra field in {@link android.content.Intent#ACTION_PACKAGE_REMOVED} or
* {@link android.content.Intent#ACTION_PACKAGE_CHANGED} intents to override the default action
* of restarting the application.
@@ -3803,6 +3815,9 @@
public static final String EXTRA_SIM_ACTIVATION_RESPONSE =
"android.intent.extra.SIM_ACTIVATION_RESPONSE";
+ /** {@hide} */
+ public static final String EXTRA_INDEX = "android.intent.extra.INDEX";
+
// ---------------------------------------------------------------------
// ---------------------------------------------------------------------
// Intent flags (see mFlags variable).
diff --git a/core/java/android/content/pm/IPackageManager.aidl b/core/java/android/content/pm/IPackageManager.aidl
index 0336645..a5e9faf 100644
--- a/core/java/android/content/pm/IPackageManager.aidl
+++ b/core/java/android/content/pm/IPackageManager.aidl
@@ -203,7 +203,7 @@
void querySyncProviders(inout List<String> outNames,
inout List<ProviderInfo> outInfo);
- List<ProviderInfo> queryContentProviders(
+ ParceledListSlice queryContentProviders(
String processName, int uid, int flags);
InstrumentationInfo getInstrumentationInfo(
diff --git a/core/java/android/content/res/ResourcesKey.java b/core/java/android/content/res/ResourcesKey.java
index 9548d49..2620571 100644
--- a/core/java/android/content/res/ResourcesKey.java
+++ b/core/java/android/content/res/ResourcesKey.java
@@ -16,6 +16,8 @@
package android.content.res;
+import android.annotation.NonNull;
+
import java.util.Objects;
/** @hide */
@@ -25,27 +27,27 @@
private final int mHash;
public final int mDisplayId;
+ @NonNull
public final Configuration mOverrideConfiguration;
public ResourcesKey(String resDir, int displayId, Configuration overrideConfiguration,
float scale) {
mResDir = resDir;
mDisplayId = displayId;
- mOverrideConfiguration = overrideConfiguration;
+ mOverrideConfiguration = overrideConfiguration != null
+ ? overrideConfiguration : Configuration.EMPTY;
mScale = scale;
int hash = 17;
hash = 31 * hash + (mResDir == null ? 0 : mResDir.hashCode());
hash = 31 * hash + mDisplayId;
- hash = 31 * hash + (mOverrideConfiguration != null
- ? mOverrideConfiguration.hashCode() : 0);
+ hash = 31 * hash + mOverrideConfiguration.hashCode();
hash = 31 * hash + Float.floatToIntBits(mScale);
mHash = hash;
}
public boolean hasOverrideConfiguration() {
- return mOverrideConfiguration != null
- && !Configuration.EMPTY.equals(mOverrideConfiguration);
+ return !Configuration.EMPTY.equals(mOverrideConfiguration);
}
@Override
@@ -66,13 +68,8 @@
if (mDisplayId != peer.mDisplayId) {
return false;
}
- if (mOverrideConfiguration != peer.mOverrideConfiguration) {
- if (mOverrideConfiguration == null || peer.mOverrideConfiguration == null) {
- return false;
- }
- if (!mOverrideConfiguration.equals(peer.mOverrideConfiguration)) {
- return false;
- }
+ if (!mOverrideConfiguration.equals(peer.mOverrideConfiguration)) {
+ return false;
}
if (mScale != peer.mScale) {
return false;
diff --git a/core/java/android/hardware/SensorManager.java b/core/java/android/hardware/SensorManager.java
index d456b5e..5d405f9 100644
--- a/core/java/android/hardware/SensorManager.java
+++ b/core/java/android/hardware/SensorManager.java
@@ -19,7 +19,6 @@
import android.annotation.SystemApi;
import android.os.Build;
import android.os.Handler;
-import android.os.SystemClock;
import android.util.Log;
import android.util.SparseArray;
@@ -1632,7 +1631,7 @@
if (values == null) {
throw new IllegalArgumentException("sensor data cannot be null");
}
- int expectedNumValues = Sensor.getMaxLengthValuesArray(sensor, Build.VERSION_CODES.MNC);
+ int expectedNumValues = Sensor.getMaxLengthValuesArray(sensor, Build.VERSION_CODES.M);
if (values.length != expectedNumValues) {
throw new IllegalArgumentException ("Wrong number of values for sensor " +
sensor.getName() + " actual=" + values.length + " expected=" +
diff --git a/core/java/android/hardware/camera2/CameraMetadata.java b/core/java/android/hardware/camera2/CameraMetadata.java
index af1367c..c580083 100644
--- a/core/java/android/hardware/camera2/CameraMetadata.java
+++ b/core/java/android/hardware/camera2/CameraMetadata.java
@@ -173,6 +173,28 @@
}
}
+ ArrayList<TKey> vendorKeys = CameraMetadataNative.getAllVendorKeys(keyClass);
+
+ if (vendorKeys != null) {
+ for (TKey k : vendorKeys) {
+ String keyName;
+ if (k instanceof CaptureRequest.Key<?>) {
+ keyName = ((CaptureRequest.Key<?>) k).getName();
+ } else if (k instanceof CaptureResult.Key<?>) {
+ keyName = ((CaptureResult.Key<?>) k).getName();
+ } else if (k instanceof CameraCharacteristics.Key<?>) {
+ keyName = ((CameraCharacteristics.Key<?>) k).getName();
+ } else {
+ continue;
+ }
+
+ if (filterTags == null || Arrays.binarySearch(filterTags,
+ CameraMetadataNative.getTag(keyName)) >= 0) {
+ keyList.add(k);
+ }
+ }
+ }
+
return keyList;
}
diff --git a/core/java/android/hardware/camera2/impl/CameraMetadataNative.java b/core/java/android/hardware/camera2/impl/CameraMetadataNative.java
index 7e50fd9..12a2910 100644
--- a/core/java/android/hardware/camera2/impl/CameraMetadataNative.java
+++ b/core/java/android/hardware/camera2/impl/CameraMetadataNative.java
@@ -1078,6 +1078,7 @@
private native synchronized void nativeWriteValues(int tag, byte[] src);
private native synchronized void nativeDump() throws IOException; // dump to ALOGD
+ private static native ArrayList nativeGetAllVendorKeys(Class keyClass);
private static native int nativeGetTagFromKey(String keyName)
throws IllegalArgumentException;
private static native int nativeGetTypeFromTag(int tag)
@@ -1113,6 +1114,19 @@
return nativeIsEmpty();
}
+
+ /**
+ * Return a list containing keys of the given key class for all defined vendor tags.
+ *
+ * @hide
+ */
+ public static <K> ArrayList<K> getAllVendorKeys(Class<K> keyClass) {
+ if (keyClass == null) {
+ throw new NullPointerException();
+ }
+ return (ArrayList<K>) nativeGetAllVendorKeys(keyClass);
+ }
+
/**
* Convert a key string into the equivalent native tag.
*
diff --git a/core/java/android/hardware/usb/IUsbManager.aidl b/core/java/android/hardware/usb/IUsbManager.aidl
index 80c7b1a..6e4c9de 100644
--- a/core/java/android/hardware/usb/IUsbManager.aidl
+++ b/core/java/android/hardware/usb/IUsbManager.aidl
@@ -97,9 +97,6 @@
*/
void setUsbDataUnlocked(boolean unlock);
- /* Returns true iff sensitive user data is exposed on the USB connection. */
- boolean isUsbDataUnlocked();
-
/* Allow USB debugging from the attached host. If alwaysAllow is true, add the
* the public key to list of host keys that the user has approved.
*/
diff --git a/core/java/android/hardware/usb/UsbManager.java b/core/java/android/hardware/usb/UsbManager.java
index c88f213..3b3ee52 100644
--- a/core/java/android/hardware/usb/UsbManager.java
+++ b/core/java/android/hardware/usb/UsbManager.java
@@ -520,21 +520,6 @@
}
/**
- * Returns {@code true} iff access to sensitive USB data is currently allowed when
- * in device mode.
- *
- * {@hide}
- */
- public boolean isUsbDataUnlocked() {
- try {
- return mService.isUsbDataUnlocked();
- } catch (RemoteException e) {
- Log.e(TAG, "RemoteException in isUsbDataUnlocked", e);
- }
- return false;
- }
-
- /**
* Returns a list of physical USB ports on the device.
* <p>
* This list is guaranteed to contain all dual-role USB Type C ports but it might
diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java
index 7748fcf..f2cbe98 100644
--- a/core/java/android/net/ConnectivityManager.java
+++ b/core/java/android/net/ConnectivityManager.java
@@ -22,6 +22,7 @@
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
+import android.content.pm.PackageManager;
import android.net.NetworkUtils;
import android.os.Binder;
import android.os.Build.VERSION_CODES;
@@ -33,6 +34,7 @@
import android.os.Looper;
import android.os.Message;
import android.os.Messenger;
+import android.os.Process;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.provider.Settings;
@@ -490,6 +492,8 @@
*/
private static ConnectivityManager sInstance;
+ private final Context mContext;
+
private INetworkManagementService mNMService;
/**
@@ -892,8 +896,11 @@
*
* @deprecated Deprecated in favor of the cleaner
* {@link #requestNetwork(NetworkRequest, NetworkCallback)} API.
+ * In {@link VERSION_CODES#M}, and above, this method is unsupported and will
+ * throw {@code UnsupportedOperationException} if called.
*/
public int startUsingNetworkFeature(int networkType, String feature) {
+ checkLegacyRoutingApiAccess();
NetworkCapabilities netCap = networkCapabilitiesForFeature(networkType, feature);
if (netCap == null) {
Log.d(TAG, "Can't satisfy startUsingNetworkFeature for " + networkType + ", " +
@@ -939,8 +946,11 @@
* always indicates failure.
*
* @deprecated Deprecated in favor of the cleaner {@link #unregisterNetworkCallback} API.
+ * In {@link VERSION_CODES#M}, and above, this method is unsupported and will
+ * throw {@code UnsupportedOperationException} if called.
*/
public int stopUsingNetworkFeature(int networkType, String feature) {
+ checkLegacyRoutingApiAccess();
NetworkCapabilities netCap = networkCapabilitiesForFeature(networkType, feature);
if (netCap == null) {
Log.d(TAG, "Can't satisfy stopUsingNetworkFeature for " + networkType + ", " +
@@ -954,41 +964,6 @@
return 1;
}
- /**
- * Removes the NET_CAPABILITY_NOT_RESTRICTED capability from the given
- * NetworkCapabilities object if all the capabilities it provides are
- * typically provided by restricted networks.
- *
- * TODO: consider:
- * - Moving to NetworkCapabilities
- * - Renaming it to guessRestrictedCapability and make it set the
- * restricted capability bit in addition to clearing it.
- * @hide
- */
- public static void maybeMarkCapabilitiesRestricted(NetworkCapabilities nc) {
- for (int capability : nc.getCapabilities()) {
- switch (capability) {
- case NetworkCapabilities.NET_CAPABILITY_CBS:
- case NetworkCapabilities.NET_CAPABILITY_DUN:
- case NetworkCapabilities.NET_CAPABILITY_EIMS:
- case NetworkCapabilities.NET_CAPABILITY_FOTA:
- case NetworkCapabilities.NET_CAPABILITY_IA:
- case NetworkCapabilities.NET_CAPABILITY_IMS:
- case NetworkCapabilities.NET_CAPABILITY_RCS:
- case NetworkCapabilities.NET_CAPABILITY_XCAP:
- case NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED: //there by default
- continue;
- default:
- // At least one capability usually provided by unrestricted
- // networks. Conclude that this network is unrestricted.
- return;
- }
- }
- // All the capabilities are typically provided by restricted networks.
- // Conclude that this network is restricted.
- nc.removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED);
- }
-
private NetworkCapabilities networkCapabilitiesForFeature(int networkType, String feature) {
if (networkType == TYPE_MOBILE) {
int cap = -1;
@@ -1011,14 +986,14 @@
}
NetworkCapabilities netCap = new NetworkCapabilities();
netCap.addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR).addCapability(cap);
- maybeMarkCapabilitiesRestricted(netCap);
+ netCap.maybeMarkCapabilitiesRestricted();
return netCap;
} else if (networkType == TYPE_WIFI) {
if ("p2p".equals(feature)) {
NetworkCapabilities netCap = new NetworkCapabilities();
netCap.addTransportType(NetworkCapabilities.TRANSPORT_WIFI);
netCap.addCapability(NetworkCapabilities.NET_CAPABILITY_WIFI_P2P);
- maybeMarkCapabilitiesRestricted(netCap);
+ netCap.maybeMarkCapabilitiesRestricted();
return netCap;
}
}
@@ -1354,6 +1329,8 @@
* @deprecated Deprecated in favor of the
* {@link #requestNetwork(NetworkRequest, NetworkCallback)},
* {@link #bindProcessToNetwork} and {@link Network#getSocketFactory} API.
+ * In {@link VERSION_CODES#M}, and above, this method is unsupported and will
+ * throw {@code UnsupportedOperationException} if called.
*/
public boolean requestRouteToHost(int networkType, int hostAddress) {
return requestRouteToHostAddress(networkType, NetworkUtils.intToInetAddress(hostAddress));
@@ -1374,6 +1351,7 @@
* {@link #bindProcessToNetwork} API.
*/
public boolean requestRouteToHostAddress(int networkType, InetAddress hostAddress) {
+ checkLegacyRoutingApiAccess();
try {
return mService.requestRouteToHostAddress(networkType, hostAddress.getAddress());
} catch (RemoteException e) {
@@ -1552,7 +1530,8 @@
/**
* {@hide}
*/
- public ConnectivityManager(IConnectivityManager service) {
+ public ConnectivityManager(Context context, IConnectivityManager service) {
+ mContext = checkNotNull(context, "missing context");
mService = checkNotNull(service, "missing IConnectivityManager");
sInstance = this;
}
@@ -2839,6 +2818,34 @@
return new Network(netId);
}
+ private void unsupportedStartingFrom(int version) {
+ if (Process.myUid() == Process.SYSTEM_UID) {
+ // The getApplicationInfo() call we make below is not supported in system context, and
+ // we want to allow the system to use these APIs anyway.
+ return;
+ }
+
+ if (mContext.getApplicationInfo().targetSdkVersion >= version) {
+ throw new UnsupportedOperationException(
+ "This method is not supported in target SDK version " + version + " and above");
+ }
+ }
+
+ // Checks whether the calling app can use the legacy routing API (startUsingNetworkFeature,
+ // stopUsingNetworkFeature, requestRouteToHost), and if not throw UnsupportedOperationException.
+ // TODO: convert the existing system users (Tethering, GpsLocationProvider) to the new APIs and
+ // remove these exemptions. Note that this check is not secure, and apps can still access these
+ // functions by accessing ConnectivityService directly. However, it should be clear that doing
+ // so is unsupported and may break in the future. http://b/22728205
+ private void checkLegacyRoutingApiAccess() {
+ if (mContext.checkCallingOrSelfPermission("com.android.permission.INJECT_OMADM_SETTINGS")
+ == PackageManager.PERMISSION_GRANTED) {
+ return;
+ }
+
+ unsupportedStartingFrom(VERSION_CODES.M);
+ }
+
/**
* Binds host resolutions performed by this process to {@code network}.
* {@link #bindProcessToNetwork} takes precedence over this setting.
diff --git a/core/java/android/net/NetworkCapabilities.java b/core/java/android/net/NetworkCapabilities.java
index af2068c..a6d477f 100644
--- a/core/java/android/net/NetworkCapabilities.java
+++ b/core/java/android/net/NetworkCapabilities.java
@@ -216,6 +216,20 @@
(1 << NET_CAPABILITY_NOT_VPN);
/**
+ * Capabilities that suggest that a network is restricted.
+ * {@see #maybeMarkCapabilitiesRestricted}.
+ */
+ private static final long RESTRICTED_CAPABILITIES =
+ (1 << NET_CAPABILITY_CBS) |
+ (1 << NET_CAPABILITY_DUN) |
+ (1 << NET_CAPABILITY_EIMS) |
+ (1 << NET_CAPABILITY_FOTA) |
+ (1 << NET_CAPABILITY_IA) |
+ (1 << NET_CAPABILITY_IMS) |
+ (1 << NET_CAPABILITY_RCS) |
+ (1 << NET_CAPABILITY_XCAP);
+
+ /**
* Adds the given capability to this {@code NetworkCapability} instance.
* Multiple capabilities may be applied sequentially. Note that when searching
* for a network to satisfy a request, all capabilities requested must be satisfied.
@@ -326,6 +340,22 @@
}
/**
+ * Removes the NET_CAPABILITY_NOT_RESTRICTED capability if all the capabilities it provides are
+ * typically provided by restricted networks.
+ *
+ * TODO: consider:
+ * - Renaming it to guessRestrictedCapability and make it set the
+ * restricted capability bit in addition to clearing it.
+ * @hide
+ */
+ public void maybeMarkCapabilitiesRestricted() {
+ // If all the capabilities are typically provided by restricted networks, conclude that this
+ // network is restricted.
+ if ((mNetworkCapabilities & ~(DEFAULT_CAPABILITIES | RESTRICTED_CAPABILITIES)) == 0)
+ removeCapability(NET_CAPABILITY_NOT_RESTRICTED);
+ }
+
+ /**
* Representing the transport type. Apps should generally not care about transport. A
* request for a fast internet connection could be satisfied by a number of different
* transports. If any are specified here it will be satisfied a Network that matches
diff --git a/core/java/android/net/NetworkRequest.java b/core/java/android/net/NetworkRequest.java
index 4f570dc..7da4818 100644
--- a/core/java/android/net/NetworkRequest.java
+++ b/core/java/android/net/NetworkRequest.java
@@ -83,7 +83,13 @@
* Build {@link NetworkRequest} give the current set of capabilities.
*/
public NetworkRequest build() {
- return new NetworkRequest(mNetworkCapabilities, ConnectivityManager.TYPE_NONE,
+ // Make a copy of mNetworkCapabilities so we don't inadvertently remove NOT_RESTRICTED
+ // when later an unrestricted capability could be added to mNetworkCapabilities, in
+ // which case NOT_RESTRICTED should be returned to mNetworkCapabilities, which
+ // maybeMarkCapabilitiesRestricted() doesn't add back.
+ final NetworkCapabilities nc = new NetworkCapabilities(mNetworkCapabilities);
+ nc.maybeMarkCapabilitiesRestricted();
+ return new NetworkRequest(nc, ConnectivityManager.TYPE_NONE,
ConnectivityManager.REQUEST_ID_UNSET);
}
diff --git a/core/java/android/os/BatteryStats.java b/core/java/android/os/BatteryStats.java
index ecb7f5a..80169a9 100644
--- a/core/java/android/os/BatteryStats.java
+++ b/core/java/android/os/BatteryStats.java
@@ -2615,7 +2615,9 @@
getMobileRadioActiveAdjustedTime(which) / 1000, interactiveTime / 1000,
powerSaveModeEnabledTime / 1000, connChanges, deviceIdleModeEnabledTime / 1000,
getDeviceIdleModeEnabledCount(which), deviceIdlingTime / 1000,
- getDeviceIdlingCount(which));
+ getDeviceIdlingCount(which),
+ getMobileRadioActiveCount(which),
+ getMobileRadioActiveUnknownTime(which) / 1000);
// Dump screen brightness stats
Object[] args = new Object[NUM_SCREEN_BRIGHTNESS_BINS];
diff --git a/core/java/android/os/Build.java b/core/java/android/os/Build.java
index b2ced7f..a0162f7 100644
--- a/core/java/android/os/Build.java
+++ b/core/java/android/os/Build.java
@@ -622,7 +622,7 @@
/**
* M comes after L.
*/
- public static final int MNC = 23;
+ public static final int M = 23;
}
/** The type of build, like "user" or "eng". */
diff --git a/core/java/android/os/INetworkManagementService.aidl b/core/java/android/os/INetworkManagementService.aidl
index 8114155..cd84c8f 100644
--- a/core/java/android/os/INetworkManagementService.aidl
+++ b/core/java/android/os/INetworkManagementService.aidl
@@ -388,8 +388,10 @@
/**
* Setup a new physical network.
+ * @param permission null if no permissions required to access this network. PERMISSION_NETWORK
+ * or PERMISSION_SYSTEM to set respective permission.
*/
- void createPhysicalNetwork(int netId);
+ void createPhysicalNetwork(int netId, String permission);
/**
* Setup a new VPN.
@@ -416,6 +418,13 @@
void setDefaultNetId(int netId);
void clearDefaultNetId();
+ /**
+ * Set permission for a network.
+ * @param permission null to clear permissions. PERMISSION_NETWORK or PERMISSION_SYSTEM to set
+ * permission.
+ */
+ void setNetworkPermission(int netId, String permission);
+
void setPermission(String permission, in int[] uids);
void clearPermission(in int[] uids);
diff --git a/core/java/android/os/IPowerManager.aidl b/core/java/android/os/IPowerManager.aidl
index 0f37ac7..c4f62ba 100644
--- a/core/java/android/os/IPowerManager.aidl
+++ b/core/java/android/os/IPowerManager.aidl
@@ -46,7 +46,7 @@
boolean isDeviceIdleMode();
void reboot(boolean confirm, String reason, boolean wait);
- void shutdown(boolean confirm, boolean wait);
+ void shutdown(boolean confirm, String reason, boolean wait);
void crash(String message);
void setStayOnSetting(int val);
diff --git a/core/java/android/os/NullVibrator.java b/core/java/android/os/NullVibrator.java
index f14d965..19b452f 100644
--- a/core/java/android/os/NullVibrator.java
+++ b/core/java/android/os/NullVibrator.java
@@ -43,7 +43,6 @@
*/
@Override
public void vibrate(int uid, String opPkg, long milliseconds, AudioAttributes attributes) {
- vibrate(milliseconds);
}
/**
diff --git a/core/java/android/os/PowerManager.java b/core/java/android/os/PowerManager.java
index 9a1a03e..69974fa 100644
--- a/core/java/android/os/PowerManager.java
+++ b/core/java/android/os/PowerManager.java
@@ -387,7 +387,13 @@
* @hide
*/
public static final String REBOOT_RECOVERY = "recovery";
-
+
+ /**
+ * The value to pass as the 'reason' argument to android_reboot().
+ * @hide
+ */
+ public static final String SHUTDOWN_USER_REQUESTED = "userrequested";
+
final Context mContext;
final IPowerManager mService;
final Handler mHandler;
@@ -926,13 +932,14 @@
* Turn off the device.
*
* @param confirm If true, shows a shutdown confirmation dialog.
+ * @param reason code to pass to android_reboot() (e.g. "userrequested"), or null.
* @param wait If true, this call waits for the shutdown to complete and does not return.
*
* @hide
*/
- public void shutdown(boolean confirm, boolean wait) {
+ public void shutdown(boolean confirm, String reason, boolean wait) {
try {
- mService.shutdown(confirm, wait);
+ mService.shutdown(confirm, reason, wait);
} catch (RemoteException e) {
}
}
diff --git a/core/java/android/os/Trace.java b/core/java/android/os/Trace.java
index 31b5849..4da88ee 100644
--- a/core/java/android/os/Trace.java
+++ b/core/java/android/os/Trace.java
@@ -75,6 +75,8 @@
public static final long TRACE_TAG_BIONIC = 1L << 16;
/** @hide */
public static final long TRACE_TAG_POWER = 1L << 17;
+ /** @hide */
+ public static final long TRACE_TAG_PACKAGE_MANAGER = 1L << 18;
private static final long TRACE_TAG_NOT_READY = 1L << 63;
private static final int MAX_SECTION_NAME_LEN = 127;
diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java
index 7915a76..b7c049a 100644
--- a/core/java/android/os/UserManager.java
+++ b/core/java/android/os/UserManager.java
@@ -181,7 +181,7 @@
* Specifies if a user is disallowed from configuring VPN.
* The default value is <code>false</code>.
* This restriction has an effect in a managed profile only from
- * {@link android.os.Build.VERSION_CODES#MNC}
+ * {@link android.os.Build.VERSION_CODES#M}
*
* <p/>Key for user restrictions.
* <p/>Type: Boolean
@@ -595,14 +595,24 @@
public boolean isSystemUser() {
return UserHandle.myUserId() == UserHandle.USER_SYSTEM;
}
+
/**
* @hide
* Returns whether the caller is running as an admin user. There can be more than one admin
* user.
*/
public boolean isAdminUser() {
- UserInfo user = getUserInfo(UserHandle.myUserId());
- return user != null ? user.isAdmin() : false;
+ return isUserAdmin(UserHandle.myUserId());
+ }
+
+ /**
+ * @hide
+ * Returns whether the provided user is an admin user. There can be more than one admin
+ * user.
+ */
+ public boolean isUserAdmin(int userId) {
+ UserInfo user = getUserInfo(userId);
+ return user != null && user.isAdmin();
}
/**
@@ -1070,7 +1080,7 @@
*/
public List<UserHandle> getUserProfiles() {
ArrayList<UserHandle> profiles = new ArrayList<UserHandle>();
- List<UserInfo> users = new ArrayList<UserInfo>();
+ List<UserInfo> users;
try {
users = mService.getProfiles(UserHandle.myUserId(), true /* enabledOnly */);
} catch (RemoteException re) {
diff --git a/core/java/android/provider/CallLog.java b/core/java/android/provider/CallLog.java
index 23555d6..4f880b1 100644
--- a/core/java/android/provider/CallLog.java
+++ b/core/java/android/provider/CallLog.java
@@ -421,7 +421,7 @@
int presentation, int callType, int features, PhoneAccountHandle accountHandle,
long start, int duration, Long dataUsage) {
return addCall(ci, context, number, presentation, callType, features, accountHandle,
- start, duration, dataUsage, false);
+ start, duration, dataUsage, false, false);
}
@@ -450,8 +450,41 @@
* {@hide}
*/
public static Uri addCall(CallerInfo ci, Context context, String number,
+ int presentation, int callType, int features, PhoneAccountHandle accountHandle,
+ long start, int duration, Long dataUsage, boolean addForAllUsers) {
+ return addCall(ci, context, number, presentation, callType, features, accountHandle,
+ start, duration, dataUsage, addForAllUsers, false);
+ }
+
+ /**
+ * Adds a call to the call log.
+ *
+ * @param ci the CallerInfo object to get the target contact from. Can be null
+ * if the contact is unknown.
+ * @param context the context used to get the ContentResolver
+ * @param number the phone number to be added to the calls db
+ * @param presentation enum value from PhoneConstants.PRESENTATION_xxx, which
+ * is set by the network and denotes the number presenting rules for
+ * "allowed", "payphone", "restricted" or "unknown"
+ * @param callType enumerated values for "incoming", "outgoing", or "missed"
+ * @param features features of the call (e.g. Video).
+ * @param accountHandle The accountHandle object identifying the provider of the call
+ * @param start time stamp for the call in milliseconds
+ * @param duration call duration in seconds
+ * @param dataUsage data usage for the call in bytes, null if data usage was not tracked for
+ * the call.
+ * @param addForAllUsers If true, the call is added to the call log of all currently
+ * running users. The caller must have the MANAGE_USERS permission if this is true.
+ * @param is_read Flag to show if the missed call log has been read by the user or not.
+ * Used for call log restore of missed calls.
+ *
+ * @result The URI of the call log entry belonging to the user that made or received this
+ * call.
+ * {@hide}
+ */
+ public static Uri addCall(CallerInfo ci, Context context, String number,
int presentation, int callType, int features, PhoneAccountHandle accountHandle,
- long start, int duration, Long dataUsage, boolean addForAllUsers) {
+ long start, int duration, Long dataUsage, boolean addForAllUsers, boolean is_read) {
final ContentResolver resolver = context.getContentResolver();
int numberPresentation = PRESENTATION_ALLOWED;
@@ -516,7 +549,7 @@
values.put(NEW, Integer.valueOf(1));
if (callType == MISSED_TYPE) {
- values.put(IS_READ, Integer.valueOf(0));
+ values.put(IS_READ, Integer.valueOf(is_read ? 1 : 0));
}
if ((ci != null) && (ci.contactIdOrZero > 0)) {
diff --git a/core/java/android/provider/MediaStore.java b/core/java/android/provider/MediaStore.java
index e63fb04..9babf43 100644
--- a/core/java/android/provider/MediaStore.java
+++ b/core/java/android/provider/MediaStore.java
@@ -284,7 +284,7 @@
* If you don't set a ClipData, it will be copied there for you when calling
* {@link Context#startActivity(Intent)}.
*
- * <p>Note: if you app targets {@link android.os.Build.VERSION_CODES#MNC MNC} and above
+ * <p>Note: if you app targets {@link android.os.Build.VERSION_CODES#M M} and above
* and declares as using the {@link android.Manifest.permission#CAMERA} permission which
* is not granted, then atempting to use this action will result in a {@link
* java.lang.SecurityException}.
@@ -338,7 +338,7 @@
* If you don't set a ClipData, it will be copied there for you when calling
* {@link Context#startActivity(Intent)}.
*
- * <p>Note: if you app targets {@link android.os.Build.VERSION_CODES#MNC MNC} and above
+ * <p>Note: if you app targets {@link android.os.Build.VERSION_CODES#M M} and above
* and declares as using the {@link android.Manifest.permission#CAMERA} permission which
* is not granted, then atempting to use this action will result in a {@link
* java.lang.SecurityException}.
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 04f1e04..601403c 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -4434,7 +4434,7 @@
*
* @deprecated Use {@link android.app.KeyguardManager} to determine the state and security
* level of the keyguard. Accessing this setting from an app that is targeting
- * {@link VERSION_CODES#MNC} or later throws a {@code SecurityException}.
+ * {@link VERSION_CODES#M} or later throws a {@code SecurityException}.
*/
@Deprecated
public static final String LOCK_PATTERN_ENABLED = "lock_pattern_autolock";
@@ -4443,7 +4443,7 @@
* Whether lock pattern is visible as user enters (0 = false, 1 = true)
*
* @deprecated Accessing this setting from an app that is targeting
- * {@link VERSION_CODES#MNC} or later throws a {@code SecurityException}.
+ * {@link VERSION_CODES#M} or later throws a {@code SecurityException}.
*/
@Deprecated
public static final String LOCK_PATTERN_VISIBLE = "lock_pattern_visible_pattern";
@@ -4456,7 +4456,7 @@
* lockscreen uses
* {@link Settings.System#HAPTIC_FEEDBACK_ENABLED}.
* Accessing this setting from an app that is targeting
- * {@link VERSION_CODES#MNC} or later throws a {@code SecurityException}.
+ * {@link VERSION_CODES#M} or later throws a {@code SecurityException}.
*/
@Deprecated
public static final String
@@ -7567,6 +7567,13 @@
}
/**
+ * Value of the ringer before entering zen mode.
+ *
+ * @hide
+ */
+ public static final String ZEN_MODE_RINGER_LEVEL = "zen_mode_ringer_level";
+
+ /**
* Opaque value, changes when persisted zen mode configuration changes.
*
* @hide
@@ -8346,9 +8353,9 @@
return true;
case AppOpsManager.MODE_DEFAULT:
// this is the default operating mode after an app's installation
- if (!throwException) {
- return context.checkCallingOrSelfPermission(permissionName) ==
- PackageManager.PERMISSION_GRANTED;
+ if(context.checkCallingOrSelfPermission(permissionName) == PackageManager
+ .PERMISSION_GRANTED) {
+ return true;
}
default:
// this is for all other cases trickled down here...
diff --git a/core/java/android/speech/tts/TextToSpeechService.java b/core/java/android/speech/tts/TextToSpeechService.java
index fa015b2..c3aed75 100644
--- a/core/java/android/speech/tts/TextToSpeechService.java
+++ b/core/java/android/speech/tts/TextToSpeechService.java
@@ -40,6 +40,7 @@
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.MissingResourceException;
@@ -247,7 +248,7 @@
* @return A list of features supported for the given language.
*/
protected Set<String> onGetFeaturesForLanguage(String lang, String country, String variant) {
- return null;
+ return new HashSet<String>();
}
private int getExpectedLanguageAvailableStatus(Locale locale) {
diff --git a/core/java/android/view/IWindowManager.aidl b/core/java/android/view/IWindowManager.aidl
index 5994d4f..0a4b982 100644
--- a/core/java/android/view/IWindowManager.aidl
+++ b/core/java/android/view/IWindowManager.aidl
@@ -80,10 +80,37 @@
void setEventDispatching(boolean enabled);
void addWindowToken(IBinder token, int type);
void removeWindowToken(IBinder token);
- void addAppToken(int addPos, IApplicationToken token, int groupId, int stackId,
+ /**
+ * Adds an application token to the specified task Id.
+ * @param addPos The position to add the token to in the task.
+ * @param token The token to add.
+ * @param taskId The Id of the task we are adding the token to.
+ * @param stackId Stack Id to create a new Task with the input task Id on
+ * if the task doesn't exist yet.
+ * @param requestedOrientation Orientation to use.
+ * @param fullscreen True if the application token is fullscreen.
+ * @param showWhenLocked True if the application token should be shown when locked.
+ * @param userId Id of user to associate the token with.
+ * @param configChanges Input configuration changes.
+ * @param voiceInteraction True if the token is in voice interaction mode.
+ * @param launchTaskBehind True if the token is been launched from behind.
+ * @param taskBounds Bounds to use when creating a new Task with the input task Id if
+ * the task doesn't exist yet.
+ * @return The configuration of the task if it was newly created. null otherwise.
+ */
+ Configuration addAppToken(int addPos, IApplicationToken token, int taskId, int stackId,
int requestedOrientation, boolean fullscreen, boolean showWhenLocked, int userId,
- int configChanges, boolean voiceInteraction, boolean launchTaskBehind);
- void setAppTask(IBinder token, int taskId);
+ int configChanges, boolean voiceInteraction, boolean launchTaskBehind,
+ in Rect taskBounds);
+ /**
+ *
+ * @param token The token we are adding to the input task Id.
+ * @param taskId The Id of the task we are adding the token to.
+ * @param taskBounds Bounds to use when creating a new Task with the input task Id if
+ * the task doesn't exist yet.
+ * @return The configuration of the task if it was newly created. null otherwise.
+ */
+ Configuration setAppTask(IBinder token, int taskId, in Rect taskBounds);
void setAppOrientation(IApplicationToken token, int requestedOrientation);
int getAppOrientation(IApplicationToken token);
void setFocusedApp(IBinder token, boolean moveFocusNow);
diff --git a/core/java/android/view/RenderNodeAnimator.java b/core/java/android/view/RenderNodeAnimator.java
index 379796d..2a3756d 100644
--- a/core/java/android/view/RenderNodeAnimator.java
+++ b/core/java/android/view/RenderNodeAnimator.java
@@ -336,6 +336,14 @@
return mUnscaledDuration;
}
+ /**
+ * @hide
+ */
+ @Override
+ public long getTotalDuration() {
+ return mUnscaledDuration + mUnscaledStartDelay;
+ }
+
@Override
public boolean isRunning() {
return mState == STATE_DELAYED || mState == STATE_RUNNING;
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 6de9cc7..17a9741 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -56,7 +56,6 @@
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.hardware.display.DisplayManagerGlobal;
-import android.os.Build;
import android.os.Build.VERSION_CODES;
import android.os.Bundle;
import android.os.Handler;
@@ -3809,14 +3808,14 @@
// of whether a layout was requested on that View.
sIgnoreMeasureCache = targetSdkVersion < KITKAT;
- Canvas.sCompatibilityRestore = targetSdkVersion < MNC;
+ Canvas.sCompatibilityRestore = targetSdkVersion < M;
- // In MNC and newer, our widgets can pass a "hint" value in the size
+ // In M and newer, our widgets can pass a "hint" value in the size
// for UNSPECIFIED MeasureSpecs. This lets child views of scrolling containers
// know what the expected parent size is going to be, so e.g. list items can size
// themselves at 1/3 the size of their container. It breaks older apps though,
// specifically apps that use some popular open source libraries.
- sUseZeroUnspecifiedMeasureSpec = targetSdkVersion < MNC;
+ sUseZeroUnspecifiedMeasureSpec = targetSdkVersion < M;
sCompatibilityDone = true;
}
@@ -4284,27 +4283,27 @@
PROVIDER_BACKGROUND));
break;
case R.styleable.View_foreground:
- if (targetSdkVersion >= VERSION_CODES.MNC || this instanceof FrameLayout) {
+ if (targetSdkVersion >= VERSION_CODES.M || this instanceof FrameLayout) {
setForeground(a.getDrawable(attr));
}
break;
case R.styleable.View_foregroundGravity:
- if (targetSdkVersion >= VERSION_CODES.MNC || this instanceof FrameLayout) {
+ if (targetSdkVersion >= VERSION_CODES.M || this instanceof FrameLayout) {
setForegroundGravity(a.getInt(attr, Gravity.NO_GRAVITY));
}
break;
case R.styleable.View_foregroundTintMode:
- if (targetSdkVersion >= VERSION_CODES.MNC || this instanceof FrameLayout) {
+ if (targetSdkVersion >= VERSION_CODES.M || this instanceof FrameLayout) {
setForegroundTintMode(Drawable.parseTintMode(a.getInt(attr, -1), null));
}
break;
case R.styleable.View_foregroundTint:
- if (targetSdkVersion >= VERSION_CODES.MNC || this instanceof FrameLayout) {
+ if (targetSdkVersion >= VERSION_CODES.M || this instanceof FrameLayout) {
setForegroundTintList(a.getColorStateList(attr));
}
break;
case R.styleable.View_foregroundInsidePadding:
- if (targetSdkVersion >= VERSION_CODES.MNC || this instanceof FrameLayout) {
+ if (targetSdkVersion >= VERSION_CODES.M || this instanceof FrameLayout) {
if (mForegroundInfo == null) {
mForegroundInfo = new ForegroundInfo();
}
@@ -11424,10 +11423,10 @@
* strongly recommended for performance reasons to either override
* {@link #hasOverlappingRendering()} to return <code>false</code> if appropriate, or setting a
* {@link #setLayerType(int, android.graphics.Paint) layer type} on the view for the duration
- * of the animation. On versions {@link android.os.Build.VERSION_CODES#MNC} and below,
+ * of the animation. On versions {@link android.os.Build.VERSION_CODES#M} and below,
* the default path for rendering an unlayered View with alpha could add multiple milliseconds
* of rendering cost, even for simple or small views. Starting with
- * {@link android.os.Build.VERSION_CODES#MNC}, {@link #LAYER_TYPE_HARDWARE} is automatically
+ * {@link android.os.Build.VERSION_CODES#M}, {@link #LAYER_TYPE_HARDWARE} is automatically
* applied to the view at the rendering level.</p>
*
* <p>If this view overrides {@link #onSetAlpha(int)} to return true, then this view is
@@ -11438,7 +11437,7 @@
* associated with a {@link #setLayerPaint(android.graphics.Paint) layer paint}, setting an
* alpha value less than 1.0 will supersede the alpha of the layer paint.</p>
*
- * <p>Starting with {@link android.os.Build.VERSION_CODES#MNC}, setting a translucent alpha
+ * <p>Starting with {@link android.os.Build.VERSION_CODES#M}, setting a translucent alpha
* value will clip a View to its bounds, unless the View returns <code>false</code> from
* {@link #hasOverlappingRendering}.</p>
*
@@ -18780,22 +18779,17 @@
long key = (long) widthMeasureSpec << 32 | (long) heightMeasureSpec & 0xffffffffL;
if (mMeasureCache == null) mMeasureCache = new LongSparseLongArray(2);
- final boolean forceLayout = (mPrivateFlags & PFLAG_FORCE_LAYOUT) == PFLAG_FORCE_LAYOUT;
- final boolean isExactly = MeasureSpec.getMode(widthMeasureSpec) == MeasureSpec.EXACTLY &&
- MeasureSpec.getMode(heightMeasureSpec) == MeasureSpec.EXACTLY;
- final boolean matchingSize = isExactly &&
- getMeasuredWidth() == MeasureSpec.getSize(widthMeasureSpec) &&
- getMeasuredHeight() == MeasureSpec.getSize(heightMeasureSpec);
- if (forceLayout || !matchingSize &&
- (widthMeasureSpec != mOldWidthMeasureSpec ||
- heightMeasureSpec != mOldHeightMeasureSpec)) {
+ if ((mPrivateFlags & PFLAG_FORCE_LAYOUT) == PFLAG_FORCE_LAYOUT ||
+ widthMeasureSpec != mOldWidthMeasureSpec ||
+ heightMeasureSpec != mOldHeightMeasureSpec) {
// first clears the measured dimension flag
mPrivateFlags &= ~PFLAG_MEASURED_DIMENSION_SET;
resolveRtlPropertiesIfNeeded();
- int cacheIndex = forceLayout ? -1 : mMeasureCache.indexOfKey(key);
+ int cacheIndex = (mPrivateFlags & PFLAG_FORCE_LAYOUT) == PFLAG_FORCE_LAYOUT ? -1 :
+ mMeasureCache.indexOfKey(key);
if (cacheIndex < 0 || sIgnoreMeasureCache) {
// measure ourselves, this should set the measured dimension flag back
onMeasure(widthMeasureSpec, heightMeasureSpec);
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index a6639d5..bc19b40 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -5488,7 +5488,7 @@
* @see #setAnimationCacheEnabled(boolean)
* @see View#setDrawingCacheEnabled(boolean)
*
- * @deprecated As of {@link android.os.Build.VERSION_CODES#MNC}, this property is ignored.
+ * @deprecated As of {@link android.os.Build.VERSION_CODES#M}, this property is ignored.
* Caching behavior of children may be controlled through {@link View#setLayerType(int, Paint)}.
*/
public boolean isAnimationCacheEnabled() {
@@ -5506,7 +5506,7 @@
* @see #isAnimationCacheEnabled()
* @see View#setDrawingCacheEnabled(boolean)
*
- * @deprecated As of {@link android.os.Build.VERSION_CODES#MNC}, this property is ignored.
+ * @deprecated As of {@link android.os.Build.VERSION_CODES#M}, this property is ignored.
* Caching behavior of children may be controlled through {@link View#setLayerType(int, Paint)}.
*/
public void setAnimationCacheEnabled(boolean enabled) {
@@ -5523,7 +5523,7 @@
* @see #setChildrenDrawnWithCacheEnabled(boolean)
* @see View#setDrawingCacheEnabled(boolean)
*
- * @deprecated As of {@link android.os.Build.VERSION_CODES#MNC}, this property is ignored.
+ * @deprecated As of {@link android.os.Build.VERSION_CODES#M}, this property is ignored.
* Child views may no longer have their caching behavior disabled by parents.
*/
public boolean isAlwaysDrawnWithCacheEnabled() {
@@ -5547,7 +5547,7 @@
* @see View#setDrawingCacheEnabled(boolean)
* @see View#setDrawingCacheQuality(int)
*
- * @deprecated As of {@link android.os.Build.VERSION_CODES#MNC}, this property is ignored.
+ * @deprecated As of {@link android.os.Build.VERSION_CODES#M}, this property is ignored.
* Child views may no longer have their caching behavior disabled by parents.
*/
public void setAlwaysDrawnWithCacheEnabled(boolean always) {
@@ -5563,7 +5563,7 @@
* @see #setAlwaysDrawnWithCacheEnabled(boolean)
* @see #setChildrenDrawnWithCacheEnabled(boolean)
*
- * @deprecated As of {@link android.os.Build.VERSION_CODES#MNC}, this property is ignored.
+ * @deprecated As of {@link android.os.Build.VERSION_CODES#M}, this property is ignored.
* Child views may no longer be forced to cache their rendering state by their parents.
* Use {@link View#setLayerType(int, Paint)} on individual Views instead.
*/
@@ -5584,7 +5584,7 @@
* @see #setAlwaysDrawnWithCacheEnabled(boolean)
* @see #isChildrenDrawnWithCacheEnabled()
*
- * @deprecated As of {@link android.os.Build.VERSION_CODES#MNC}, this property is ignored.
+ * @deprecated As of {@link android.os.Build.VERSION_CODES#M}, this property is ignored.
* Child views may no longer be forced to cache their rendering state by their parents.
* Use {@link View#setLayerType(int, Paint)} on individual Views instead.
*/
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index fdfc48a5..aa20dfb 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -79,7 +79,6 @@
import com.android.internal.R;
import com.android.internal.os.SomeArgs;
import com.android.internal.policy.PhoneFallbackEventHandler;
-import com.android.internal.util.ScreenShapeHelper;
import com.android.internal.view.BaseSurfaceHolder;
import com.android.internal.view.RootViewSurfaceTaker;
@@ -3058,6 +3057,17 @@
return (theParent instanceof ViewGroup) && isViewDescendantOf((View) theParent, parent);
}
+ private static void forceLayout(View view) {
+ view.forceLayout();
+ if (view instanceof ViewGroup) {
+ ViewGroup group = (ViewGroup) view;
+ final int count = group.getChildCount();
+ for (int i = 0; i < count; i++) {
+ forceLayout(group.getChildAt(i));
+ }
+ }
+ }
+
private final static int MSG_INVALIDATE = 1;
private final static int MSG_INVALIDATE_RECT = 2;
private final static int MSG_DIE = 3;
@@ -3196,6 +3206,10 @@
mReportNextDraw = true;
}
+ if (mView != null) {
+ forceLayout(mView);
+ }
+
requestLayout();
}
break;
@@ -3210,6 +3224,9 @@
mWinFrame.top = t;
mWinFrame.bottom = t + h;
+ if (mView != null) {
+ forceLayout(mView);
+ }
requestLayout();
}
break;
@@ -5821,7 +5838,7 @@
}
private void adjustInputEventForCompatibility(InputEvent e) {
- if (mTargetSdkVersion < Build.VERSION_CODES.MNC && e instanceof MotionEvent) {
+ if (mTargetSdkVersion < Build.VERSION_CODES.M && e instanceof MotionEvent) {
MotionEvent motion = (MotionEvent) e;
final int mask =
MotionEvent.BUTTON_STYLUS_PRIMARY | MotionEvent.BUTTON_STYLUS_SECONDARY;
diff --git a/core/java/android/view/Window.java b/core/java/android/view/Window.java
index 07984e9..4fc2ad3 100644
--- a/core/java/android/view/Window.java
+++ b/core/java/android/view/Window.java
@@ -34,6 +34,7 @@
import android.net.Uri;
import android.os.Bundle;
import android.os.IBinder;
+import android.os.RemoteException;
import android.os.SystemProperties;
import android.transition.Scene;
import android.transition.Transition;
@@ -471,8 +472,24 @@
/**
* Called when a window is dismissed. This informs the callback that the
* window is gone, and it should finish itself.
+ * @param finishTask True if the task should also be finished.
*/
- public void onWindowDismissed();
+ void onWindowDismissed(boolean finishTask);
+ }
+
+ /** @hide */
+ public interface WindowStackCallback {
+ /** Called to move the window and its activity/task to a different stack container.
+ * For example, a window can move between
+ * {@link android.app.ActivityManager#FULLSCREEN_WORKSPACE_STACK_ID} stack and
+ * {@link android.app.ActivityManager#FREEFORM_WORKSPACE_STACK_ID} stack.
+ *
+ * @param stackId stack Id to change to.
+ */
+ void changeWindowStack(int stackId) throws RemoteException;
+
+ /** Returns the current stack Id for the window. */
+ int getWindowStackId() throws RemoteException;
}
public Window(Context context) {
@@ -659,7 +676,7 @@
/** @hide */
public final void dispatchOnWindowDismissed() {
if (mOnWindowDismissedCallback != null) {
- mOnWindowDismissedCallback.onWindowDismissed();
+ mOnWindowDismissedCallback.onWindowDismissed(false);
}
}
diff --git a/core/java/android/view/inputmethod/EditorInfo.java b/core/java/android/view/inputmethod/EditorInfo.java
index 76c8fbd..6130fd5 100644
--- a/core/java/android/view/inputmethod/EditorInfo.java
+++ b/core/java/android/view/inputmethod/EditorInfo.java
@@ -303,10 +303,12 @@
* {@link android.os.Build.VERSION_CODES#LOLLIPOP_MR1} and prior, do not trust this package
* name. The system had not verified the consistency between the package name here and
* application's uid. Consider to use {@link InputBinding#getUid()}, which is trustworthy.
- * Starting from Android MNC, the system verifies the consistency between this package name
- * and application uid before {@link EditorInfo} is passed to the input method.</p>
+ * Starting from {@link android.os.Build.VERSION_CODES#M}, the system verifies the consistency
+ * between this package name and application uid before {@link EditorInfo} is passed to the
+ * input method.</p>
*
- * <p><strong>Editor authors:</strong> Starting from Android MNC, the application is no longer
+ * <p><strong>Editor authors:</strong> Starting from {@link android.os.Build.VERSION_CODES#M},
+ * the application is no longer
* able to establish input connections if the package name provided here is inconsistent with
* application's uid.</p>
*/
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index aa72eb3..057b701 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -1470,11 +1470,12 @@
}
/**
- * Pauses any extra processing associated with this WebView and its
- * associated DOM, plugins, JavaScript etc. For example, if this WebView is
- * taken offscreen, this could be called to reduce unnecessary CPU or
- * network traffic. When this WebView is again "active", call onResume().
- * Note that this differs from pauseTimers(), which affects all WebViews.
+ * Does a best-effort attempt to pause any processing that can be paused
+ * safely, such as animations and geolocation. Note that this call
+ * does not pause JavaScript. To pause JavaScript globally, use
+ * {@link #pauseTimers}.
+ *
+ * To resume WebView, call {@link #onResume}.
*/
public void onPause() {
checkThread();
@@ -1482,7 +1483,7 @@
}
/**
- * Resumes a WebView after a previous call to onPause().
+ * Resumes a WebView after a previous call to {@link #onPause}.
*/
public void onResume() {
checkThread();
diff --git a/core/java/android/widget/DateTimeView.java b/core/java/android/widget/DateTimeView.java
index dcb2437..d20b924 100644
--- a/core/java/android/widget/DateTimeView.java
+++ b/core/java/android/widget/DateTimeView.java
@@ -16,6 +16,7 @@
package android.widget;
+import android.app.ActivityThread;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
@@ -259,7 +260,7 @@
static final Context getApplicationContextIfAvailable(Context context) {
final Context ac = context.getApplicationContext();
- return ac != null ? ac : context;
+ return ac != null ? ac : ActivityThread.currentApplication().getApplicationContext();
}
void register(Context context) {
diff --git a/core/java/android/widget/ImageView.java b/core/java/android/widget/ImageView.java
index 8364951..20fe61d 100644
--- a/core/java/android/widget/ImageView.java
+++ b/core/java/android/widget/ImageView.java
@@ -384,6 +384,10 @@
assigned.
*/
public Drawable getDrawable() {
+ if (mDrawable == mRecycleableBitmapDrawable) {
+ // Consider our cached version dirty since app code now has a reference to it
+ mRecycleableBitmapDrawable = null;
+ }
return mDrawable;
}
diff --git a/core/java/android/widget/LinearLayout.java b/core/java/android/widget/LinearLayout.java
index 47e894a..b5e08ca 100644
--- a/core/java/android/widget/LinearLayout.java
+++ b/core/java/android/widget/LinearLayout.java
@@ -686,7 +686,6 @@
int weightedMaxWidth = 0;
boolean allFillParent = true;
float totalWeight = 0;
- int usedExcessSpace = 0;
final int count = getVirtualChildCount();
@@ -722,10 +721,8 @@
LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) child.getLayoutParams();
totalWeight += lp.weight;
-
- final boolean fillExcessSpace = lp.weight > 0;
- final boolean hasZeroHeight = lp.height == 0;
- if (heightMode == MeasureSpec.EXACTLY && fillExcessSpace && hasZeroHeight) {
+
+ if (heightMode == MeasureSpec.EXACTLY && lp.height == 0 && lp.weight > 0) {
// Optimization: don't bother measuring children who are going to use
// leftover space. These views will get measured again down below if
// there is any leftover space.
@@ -733,12 +730,14 @@
mTotalLength = Math.max(totalLength, totalLength + lp.topMargin + lp.bottomMargin);
skippedMeasure = true;
} else {
- if (fillExcessSpace && hasZeroHeight) {
- // The LinearLayout's heightMode is either UNSPECIFIED or
- // AT_MOST, and this child wanted to stretch to fill
- // available space. Translate the explicit height of 0 to
- // WRAP_CONTENT so that we can measure the view's ideal
- // height.
+ int oldHeight = Integer.MIN_VALUE;
+
+ if (lp.height == 0 && lp.weight > 0) {
+ // heightMode is either UNSPECIFIED or AT_MOST, and this
+ // child wanted to stretch to fill available space.
+ // Translate that to WRAP_CONTENT so that it does not end up
+ // with a height of 0
+ oldHeight = 0;
lp.height = LayoutParams.WRAP_CONTENT;
}
@@ -750,16 +749,11 @@
child, i, widthMeasureSpec, 0, heightMeasureSpec,
totalWeight == 0 ? mTotalLength : 0);
- final int childHeight = child.getMeasuredHeight();
- if (fillExcessSpace) {
- usedExcessSpace += childHeight;
-
- // Restore original layout height.
- if (hasZeroHeight) {
- lp.height = 0;
- }
+ if (oldHeight != Integer.MIN_VALUE) {
+ lp.height = oldHeight;
}
+ final int childHeight = child.getMeasuredHeight();
final int totalLength = mTotalLength;
mTotalLength = Math.max(totalLength, totalLength + childHeight + lp.topMargin +
lp.bottomMargin + getNextLocationOffset(child));
@@ -863,7 +857,7 @@
// Either expand children with weight to take up available space or
// shrink them if they extend beyond our current bounds. If we skipped
// measurement on any children, we need to measure them now.
- final int delta = heightSize - mTotalLength + usedExcessSpace;
+ int delta = heightSize - mTotalLength;
if (skippedMeasure || delta != 0 && totalWeight > 0.0f) {
float weightSum = mWeightSum > 0.0f ? mWeightSum : totalWeight;
@@ -880,14 +874,34 @@
float childExtra = lp.weight;
if (childExtra > 0) {
- // Distribute excess space to child.
- final int childHeight = Math.max(0, (int) (childExtra * delta / weightSum));
- final int childHeightMeasureSpec = MeasureSpec.makeMeasureSpec(childHeight,
- MeasureSpec.EXACTLY);
+ // Child said it could absorb extra space -- give him his share
+ int share = (int) (childExtra * delta / weightSum);
+ weightSum -= childExtra;
+ delta -= share;
+
final int childWidthMeasureSpec = getChildMeasureSpec(widthMeasureSpec,
- mPaddingLeft + mPaddingRight + lp.leftMargin + lp.rightMargin,
- lp.width);
- child.measure(childWidthMeasureSpec, childHeightMeasureSpec);
+ mPaddingLeft + mPaddingRight +
+ lp.leftMargin + lp.rightMargin, lp.width);
+
+ // TODO: Use a field like lp.isMeasured to figure out if this
+ // child has been previously measured
+ if ((lp.height != 0) || (heightMode != MeasureSpec.EXACTLY)) {
+ // child was measured once already above...
+ // base new measurement on stored values
+ int childHeight = child.getMeasuredHeight() + share;
+ if (childHeight < 0) {
+ childHeight = 0;
+ }
+
+ child.measure(childWidthMeasureSpec,
+ MeasureSpec.makeMeasureSpec(childHeight, MeasureSpec.EXACTLY));
+ } else {
+ // child was skipped in the loop above.
+ // Measure for this first time here
+ child.measure(childWidthMeasureSpec,
+ MeasureSpec.makeMeasureSpec(share > 0 ? share : 0,
+ MeasureSpec.EXACTLY));
+ }
// Child may now not fit in vertical dimension.
childState = combineMeasuredStates(childState, child.getMeasuredState()
@@ -1003,7 +1017,6 @@
int weightedMaxHeight = 0;
boolean allFillParent = true;
float totalWeight = 0;
- int usedExcessSpace = 0;
final int count = getVirtualChildCount();
@@ -1053,10 +1066,8 @@
child.getLayoutParams();
totalWeight += lp.weight;
-
- final boolean fillExcessSpace = lp.weight > 0;
- final boolean hasZeroWidth = lp.width == 0;
- if (widthMode == MeasureSpec.EXACTLY && fillExcessSpace && hasZeroWidth) {
+
+ if (widthMode == MeasureSpec.EXACTLY && lp.width == 0 && lp.weight > 0) {
// Optimization: don't bother measuring children who are going to use
// leftover space. These views will get measured again down below if
// there is any leftover space.
@@ -1083,12 +1094,14 @@
skippedMeasure = true;
}
} else {
- if (fillExcessSpace && hasZeroWidth) {
- // The LinearLayout's widthMode is either UNSPECIFIED or
- // AT_MOST, and this child wanted to stretch to fill
- // available space. Translate the explicit height of 0 to
- // WRAP_CONTENT so that we can measure the view's ideal
- // width.
+ int oldWidth = Integer.MIN_VALUE;
+
+ if (lp.width == 0 && lp.weight > 0) {
+ // widthMode is either UNSPECIFIED or AT_MOST, and this
+ // child
+ // wanted to stretch to fill available space. Translate that to
+ // WRAP_CONTENT so that it does not end up with a width of 0
+ oldWidth = 0;
lp.width = LayoutParams.WRAP_CONTENT;
}
@@ -1100,16 +1113,11 @@
totalWeight == 0 ? mTotalLength : 0,
heightMeasureSpec, 0);
- final int childWidth = child.getMeasuredWidth();
- if (fillExcessSpace) {
- usedExcessSpace += childWidth;
-
- // Restore the original layout width.
- if (hasZeroWidth) {
- lp.width = 0;
- }
+ if (oldWidth != Integer.MIN_VALUE) {
+ lp.width = oldWidth;
}
+ final int childWidth = child.getMeasuredWidth();
if (isExactly) {
mTotalLength += childWidth + lp.leftMargin + lp.rightMargin +
getNextLocationOffset(child);
@@ -1234,7 +1242,7 @@
// Either expand children with weight to take up available space or
// shrink them if they extend beyond our current bounds. If we skipped
// measurement on any children, we need to measure them now.
- final int delta = widthSize - mTotalLength + usedExcessSpace;
+ int delta = widthSize - mTotalLength;
if (skippedMeasure || delta != 0 && totalWeight > 0.0f) {
float weightSum = mWeightSum > 0.0f ? mWeightSum : totalWeight;
@@ -1257,13 +1265,34 @@
float childExtra = lp.weight;
if (childExtra > 0) {
// Child said it could absorb extra space -- give him his share
- final int childWidth = Math.max(0, (int) (childExtra * delta / weightSum));
- final int childWidthMeasureSpec = MeasureSpec.makeMeasureSpec(childWidth,
- MeasureSpec.EXACTLY);
- final int childHeightMeasureSpec = getChildMeasureSpec(heightMeasureSpec,
+ int share = (int) (childExtra * delta / weightSum);
+ weightSum -= childExtra;
+ delta -= share;
+
+ final int childHeightMeasureSpec = getChildMeasureSpec(
+ heightMeasureSpec,
mPaddingTop + mPaddingBottom + lp.topMargin + lp.bottomMargin,
lp.height);
- child.measure(childWidthMeasureSpec, childHeightMeasureSpec);
+
+ // TODO: Use a field like lp.isMeasured to figure out if this
+ // child has been previously measured
+ if ((lp.width != 0) || (widthMode != MeasureSpec.EXACTLY)) {
+ // child was measured once already above ... base new measurement
+ // on stored values
+ int childWidth = child.getMeasuredWidth() + share;
+ if (childWidth < 0) {
+ childWidth = 0;
+ }
+
+ child.measure(
+ MeasureSpec.makeMeasureSpec(childWidth, MeasureSpec.EXACTLY),
+ childHeightMeasureSpec);
+ } else {
+ // child was skipped in the loop above. Measure for this first time here
+ child.measure(MeasureSpec.makeMeasureSpec(
+ share > 0 ? share : 0, MeasureSpec.EXACTLY),
+ childHeightMeasureSpec);
+ }
// Child may now not fit in horizontal dimension.
childState = combineMeasuredStates(childState,
diff --git a/core/java/android/widget/OverScroller.java b/core/java/android/widget/OverScroller.java
index 98bfd7d..50569d7 100644
--- a/core/java/android/widget/OverScroller.java
+++ b/core/java/android/widget/OverScroller.java
@@ -678,7 +678,7 @@
void startScroll(int start, int distance, int duration) {
mFinished = false;
- mStart = start;
+ mCurrentPosition = mStart = start;
mFinal = start + distance;
mStartTime = AnimationUtils.currentAnimationTimeMillis();
@@ -712,7 +712,7 @@
boolean springback(int start, int min, int max) {
mFinished = true;
- mStart = mFinal = start;
+ mCurrentPosition = mStart = mFinal = start;
mVelocity = 0;
mStartTime = AnimationUtils.currentAnimationTimeMillis();
@@ -804,7 +804,7 @@
final float totalDuration = (float) Math.sqrt(
2.0 * (distanceToApex + distanceToEdge) / Math.abs(mDeceleration));
mStartTime -= (int) (1000.0f * (totalDuration - durationToApex));
- mStart = end;
+ mCurrentPosition = mStart = end;
mVelocity = (int) (- mDeceleration * totalDuration);
}
@@ -873,7 +873,7 @@
// Duration from start to null velocity
if (mDuration < mSplineDuration) {
// If the animation was clamped, we reached the edge
- mStart = mFinal;
+ mCurrentPosition = mStart = mFinal;
// TODO Better compute speed when edge was reached
mVelocity = (int) mCurrVelocity;
mDeceleration = getDeceleration(mVelocity);
diff --git a/core/java/android/widget/RemoteViews.java b/core/java/android/widget/RemoteViews.java
index d158313..7ca3339 100644
--- a/core/java/android/widget/RemoteViews.java
+++ b/core/java/android/widget/RemoteViews.java
@@ -2746,6 +2746,10 @@
public Resources.Theme getTheme() {
return contextForResources.getTheme();
}
+ @Override
+ public String getPackageName() {
+ return contextForResources.getPackageName();
+ }
};
LayoutInflater inflater = (LayoutInflater)
diff --git a/core/java/android/widget/ScrollView.java b/core/java/android/widget/ScrollView.java
index 58a94b9..529d295 100644
--- a/core/java/android/widget/ScrollView.java
+++ b/core/java/android/widget/ScrollView.java
@@ -356,7 +356,7 @@
final int heightPadding;
final FrameLayout.LayoutParams lp = (LayoutParams) child.getLayoutParams();
final int targetSdkVersion = getContext().getApplicationInfo().targetSdkVersion;
- if (targetSdkVersion >= VERSION_CODES.MNC) {
+ if (targetSdkVersion >= VERSION_CODES.M) {
widthPadding = mPaddingLeft + mPaddingRight + lp.leftMargin + lp.rightMargin;
heightPadding = mPaddingTop + mPaddingBottom + lp.topMargin + lp.bottomMargin;
} else {
diff --git a/core/java/com/android/internal/app/ChooserActivity.java b/core/java/com/android/internal/app/ChooserActivity.java
index 6af2e8b..d9faece 100644
--- a/core/java/com/android/internal/app/ChooserActivity.java
+++ b/core/java/com/android/internal/app/ChooserActivity.java
@@ -517,6 +517,7 @@
private final ResolveInfo mBackupResolveInfo;
private final ChooserTarget mChooserTarget;
private Drawable mBadgeIcon = null;
+ private CharSequence mBadgeContentDescription;
private Drawable mDisplayIcon;
private final Intent mFillInIntent;
private final int mFillInFlags;
@@ -532,7 +533,9 @@
if (ri != null) {
final ActivityInfo ai = ri.activityInfo;
if (ai != null && ai.applicationInfo != null) {
- mBadgeIcon = getPackageManager().getApplicationIcon(ai.applicationInfo);
+ final PackageManager pm = getPackageManager();
+ mBadgeIcon = pm.getApplicationIcon(ai.applicationInfo);
+ mBadgeContentDescription = pm.getApplicationLabel(ai.applicationInfo);
}
}
}
@@ -555,6 +558,7 @@
mBackupResolveInfo = other.mBackupResolveInfo;
mChooserTarget = other.mChooserTarget;
mBadgeIcon = other.mBadgeIcon;
+ mBadgeContentDescription = other.mBadgeContentDescription;
mDisplayIcon = other.mDisplayIcon;
mFillInIntent = fillInIntent;
mFillInFlags = flags;
@@ -647,6 +651,11 @@
}
@Override
+ public CharSequence getBadgeContentDescription() {
+ return mBadgeContentDescription;
+ }
+
+ @Override
public TargetInfo cloneFilledIn(Intent fillInIntent, int flags) {
return new ChooserTargetInfo(this, fillInIntent, flags);
}
diff --git a/core/java/com/android/internal/app/IAppOpsService.aidl b/core/java/com/android/internal/app/IAppOpsService.aidl
index 73c4833..9fa2c23 100644
--- a/core/java/com/android/internal/app/IAppOpsService.aidl
+++ b/core/java/com/android/internal/app/IAppOpsService.aidl
@@ -38,6 +38,7 @@
int checkPackage(int uid, String packageName);
List<AppOpsManager.PackageOps> getPackagesForOps(in int[] ops);
List<AppOpsManager.PackageOps> getOpsForPackage(int uid, String packageName, in int[] ops);
+ void setUidMode(int code, int uid, int mode);
void setMode(int code, int uid, String packageName, int mode);
void resetAllModes(int reqUserId, String reqPackageName);
int checkAudioOperation(int code, int usage, int uid, String packageName);
diff --git a/core/java/com/android/internal/app/ResolverActivity.java b/core/java/com/android/internal/app/ResolverActivity.java
index 89599e0..7dd3bed 100644
--- a/core/java/com/android/internal/app/ResolverActivity.java
+++ b/core/java/com/android/internal/app/ResolverActivity.java
@@ -932,6 +932,11 @@
}
@Override
+ public CharSequence getBadgeContentDescription() {
+ return null;
+ }
+
+ @Override
public TargetInfo cloneFilledIn(Intent fillInIntent, int flags) {
return new DisplayResolveInfo(this, fillInIntent, flags);
}
@@ -1072,6 +1077,11 @@
public Drawable getBadgeIcon();
/**
+ * @return The content description for the badge icon
+ */
+ public CharSequence getBadgeContentDescription();
+
+ /**
* Clone this target with the given fill-in information.
*/
public TargetInfo cloneFilledIn(Intent fillInIntent, int flags);
@@ -1542,6 +1552,7 @@
final Drawable badge = info.getBadgeIcon();
if (badge != null) {
holder.badge.setImageDrawable(badge);
+ holder.badge.setContentDescription(info.getBadgeContentDescription());
holder.badge.setVisibility(View.VISIBLE);
} else {
holder.badge.setVisibility(View.GONE);
diff --git a/core/java/com/android/internal/app/ShutdownActivity.java b/core/java/com/android/internal/app/ShutdownActivity.java
index 97521cf..745d28f 100644
--- a/core/java/com/android/internal/app/ShutdownActivity.java
+++ b/core/java/com/android/internal/app/ShutdownActivity.java
@@ -21,6 +21,7 @@
import android.content.Intent;
import android.os.Bundle;
import android.os.IPowerManager;
+import android.os.PowerManager;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.util.Slog;
@@ -30,6 +31,7 @@
private static final String TAG = "ShutdownActivity";
private boolean mReboot;
private boolean mConfirm;
+ private boolean mUserRequested;
@Override
protected void onCreate(Bundle savedInstanceState) {
@@ -38,6 +40,7 @@
Intent intent = getIntent();
mReboot = Intent.ACTION_REBOOT.equals(intent.getAction());
mConfirm = intent.getBooleanExtra(Intent.EXTRA_KEY_CONFIRM, false);
+ mUserRequested = intent.getBooleanExtra(Intent.EXTRA_USER_REQUESTED_SHUTDOWN, false);
Slog.i(TAG, "onCreate(): confirm=" + mConfirm);
Thread thr = new Thread("ShutdownActivity") {
@@ -49,7 +52,9 @@
if (mReboot) {
pm.reboot(mConfirm, null, false);
} else {
- pm.shutdown(mConfirm, false);
+ pm.shutdown(mConfirm,
+ mUserRequested ? PowerManager.SHUTDOWN_USER_REQUESTED : null,
+ false);
}
} catch (RemoteException e) {
}
diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java
index e7c58f4..6c7e298 100644
--- a/core/java/com/android/internal/os/BatteryStatsImpl.java
+++ b/core/java/com/android/internal/os/BatteryStatsImpl.java
@@ -7674,6 +7674,7 @@
final long totalTimeMs = txTimeMs + rxTimeMs + idleTimeMs;
long leftOverRxTimeMs = rxTimeMs;
+ long leftOverTxTimeMs = txTimeMs;
if (DEBUG_ENERGY) {
Slog.d(TAG, "------ BEGIN WiFi power blaming ------");
@@ -7705,6 +7706,10 @@
Slog.d(TAG, " !Estimated scan time > Actual rx time (" + totalScanTimeMs + " ms > "
+ rxTimeMs + " ms). Normalizing scan time.");
}
+ if (DEBUG_ENERGY && totalScanTimeMs > txTimeMs) {
+ Slog.d(TAG, " !Estimated scan time > Actual tx time (" + totalScanTimeMs + " ms > "
+ + txTimeMs + " ms). Normalizing scan time.");
+ }
// Actually assign and distribute power usage to apps.
for (int i = 0; i < uidStatsSize; i++) {
@@ -7716,23 +7721,34 @@
// Set the new mark so that next time we get new data since this point.
uid.mWifiScanTimer.setMark(elapsedRealtimeMs);
+ long scanRxTimeSinceMarkMs = scanTimeSinceMarkMs;
+ long scanTxTimeSinceMarkMs = scanTimeSinceMarkMs;
+
+ // Our total scan time is more than the reported Tx/Rx time.
+ // This is possible because the cost of a scan is approximate.
+ // Let's normalize the result so that we evenly blame each app
+ // scanning.
+ //
+ // This means that we may have apps that transmitted/received packets not be
+ // blamed for this, but this is fine as scans are relatively more expensive.
if (totalScanTimeMs > rxTimeMs) {
- // Our total scan time is more than the reported Rx time.
- // This is possible because the cost of a scan is approximate.
- // Let's normalize the result so that we evenly blame each app
- // scanning.
- //
- // This means that we may have apps that received packets not be blamed
- // for this, but this is fine as scans are relatively more expensive.
- scanTimeSinceMarkMs = (rxTimeMs * scanTimeSinceMarkMs) / totalScanTimeMs;
+ scanRxTimeSinceMarkMs = (rxTimeMs * scanRxTimeSinceMarkMs) /
+ totalScanTimeMs;
+ }
+ if (totalScanTimeMs > txTimeMs) {
+ scanTxTimeSinceMarkMs = (txTimeMs * scanTxTimeSinceMarkMs) /
+ totalScanTimeMs;
}
if (DEBUG_ENERGY) {
- Slog.d(TAG, " ScanTime for UID " + uid.getUid() + ": "
- + scanTimeSinceMarkMs + " ms)");
+ Slog.d(TAG, " ScanTime for UID " + uid.getUid() + ": Rx:"
+ + scanRxTimeSinceMarkMs + " ms Tx:"
+ + scanTxTimeSinceMarkMs + " ms)");
}
- uid.noteWifiControllerActivityLocked(CONTROLLER_RX_TIME, scanTimeSinceMarkMs);
- leftOverRxTimeMs -= scanTimeSinceMarkMs;
+ uid.noteWifiControllerActivityLocked(CONTROLLER_RX_TIME, scanRxTimeSinceMarkMs);
+ uid.noteWifiControllerActivityLocked(CONTROLLER_TX_TIME, scanTxTimeSinceMarkMs);
+ leftOverRxTimeMs -= scanRxTimeSinceMarkMs;
+ leftOverTxTimeMs -= scanTxTimeSinceMarkMs;
}
// Distribute evenly the power consumed while Idle to each app holding a WiFi
@@ -7755,12 +7771,14 @@
if (DEBUG_ENERGY) {
Slog.d(TAG, " New RxPower: " + leftOverRxTimeMs + " ms");
+ Slog.d(TAG, " New TxPower: " + leftOverTxTimeMs + " ms");
}
- // Distribute the Tx power appropriately between all apps that transmitted packets.
+ // Distribute the remaining Tx power appropriately between all apps that transmitted
+ // packets.
for (int i = 0; i < txPackets.size(); i++) {
final Uid uid = getUidStatsLocked(txPackets.keyAt(i));
- final long myTxTimeMs = (txPackets.valueAt(i) * txTimeMs) / totalTxPackets;
+ final long myTxTimeMs = (txPackets.valueAt(i) * leftOverTxTimeMs) / totalTxPackets;
if (DEBUG_ENERGY) {
Slog.d(TAG, " TxTime for UID " + uid.getUid() + ": " + myTxTimeMs + " ms");
}
@@ -7915,6 +7933,8 @@
return;
}
+ // Record whether we've seen a non-zero time (for debugging b/22716723).
+ boolean seenNonZeroTime = false;
for (Map.Entry<String, KernelWakelockStats.Entry> ent : wakelockStats.entrySet()) {
String name = ent.getKey();
KernelWakelockStats.Entry kws = ent.getValue();
@@ -7928,17 +7948,31 @@
kwlt.updateCurrentReportedCount(kws.mCount);
kwlt.updateCurrentReportedTotalTime(kws.mTotalTime);
kwlt.setUpdateVersion(kws.mVersion);
+
+ if (kws.mVersion != wakelockStats.kernelWakelockVersion)
+ seenNonZeroTime |= kws.mTotalTime > 0;
}
+ int numWakelocksSetStale = 0;
if (wakelockStats.size() != mKernelWakelockStats.size()) {
// Set timers to stale if they didn't appear in /proc/wakelocks this time.
for (Map.Entry<String, SamplingTimer> ent : mKernelWakelockStats.entrySet()) {
SamplingTimer st = ent.getValue();
if (st.getUpdateVersion() != wakelockStats.kernelWakelockVersion) {
st.setStale();
+ numWakelocksSetStale++;
}
}
}
+
+ if (!seenNonZeroTime) {
+ Slog.wtf(TAG, "All kernel wakelocks had time of zero");
+ }
+
+ if (numWakelocksSetStale == mKernelWakelockStats.size()) {
+ Slog.wtf(TAG, "All kernel wakelocks were set stale. new version=" +
+ wakelockStats.kernelWakelockVersion);
+ }
}
// We use an anonymous class to access these variables,
diff --git a/core/java/com/android/internal/os/KernelWakelockReader.java b/core/java/com/android/internal/os/KernelWakelockReader.java
index 0369c3f..6654ea5 100644
--- a/core/java/com/android/internal/os/KernelWakelockReader.java
+++ b/core/java/com/android/internal/os/KernelWakelockReader.java
@@ -75,6 +75,8 @@
is = new FileInputStream(sWakeupSourceFile);
wakeup_sources = true;
} catch (java.io.FileNotFoundException e2) {
+ Slog.wtf(TAG, "neither " + sWakelockFile + " nor " +
+ sWakeupSourceFile + " exists");
return null;
}
}
@@ -82,6 +84,7 @@
len = is.read(buffer);
is.close();
} catch (java.io.IOException e) {
+ Slog.wtf(TAG, "failed to read kernel wakelocks", e);
return null;
}
@@ -171,6 +174,13 @@
numUpdatedWlNames++;
}
}
+ } else if (!parsed) {
+ try {
+ Slog.wtf(TAG, "Failed to parse proc line: " +
+ new String(wlBuffer, startIndex, endIndex - startIndex));
+ } catch (Exception e) {
+ Slog.wtf(TAG, "Failed to parse proc line!");
+ }
}
startIndex = endIndex;
}
diff --git a/core/java/com/android/internal/os/WifiPowerCalculator.java b/core/java/com/android/internal/os/WifiPowerCalculator.java
index da98a67..146c0f8 100644
--- a/core/java/com/android/internal/os/WifiPowerCalculator.java
+++ b/core/java/com/android/internal/os/WifiPowerCalculator.java
@@ -57,6 +57,11 @@
statsType);
app.wifiTxBytes = u.getNetworkActivityBytes(BatteryStats.NETWORK_WIFI_TX_DATA,
statsType);
+
+ if (DEBUG && app.wifiPowerMah != 0) {
+ Log.d(TAG, "UID " + u.getUid() + ": idle=" + idleTime + "ms rx=" + rxTime + "ms tx=" +
+ txTime + "ms power=" + BatteryStatsHelper.makemAh(app.wifiPowerMah));
+ }
}
@Override
diff --git a/core/java/com/android/internal/os/WifiPowerEstimator.java b/core/java/com/android/internal/os/WifiPowerEstimator.java
index c4e2ef6..3bd79f7e 100644
--- a/core/java/com/android/internal/os/WifiPowerEstimator.java
+++ b/core/java/com/android/internal/os/WifiPowerEstimator.java
@@ -16,11 +16,14 @@
package com.android.internal.os;
import android.os.BatteryStats;
+import android.util.Log;
/**
* Estimates WiFi power usage based on timers in BatteryStats.
*/
public class WifiPowerEstimator extends PowerCalculator {
+ private static final boolean DEBUG = BatteryStatsHelper.DEBUG;
+ private static final String TAG = "WifiPowerEstimator";
private final double mWifiPowerPerPacket;
private final double mWifiPowerOn;
private final double mWifiPowerScan;
@@ -75,6 +78,10 @@
}
app.wifiPowerMah = wifiPacketPower + wifiLockPower + wifiScanPower + wifiBatchScanPower;
+ if (DEBUG && app.wifiPowerMah != 0) {
+ Log.d(TAG, "UID " + u.getUid() + ": power=" +
+ BatteryStatsHelper.makemAh(app.wifiPowerMah));
+ }
}
@Override
diff --git a/core/java/com/android/internal/policy/PhoneWindow.java b/core/java/com/android/internal/policy/PhoneWindow.java
index 43f7ebc..0bd8d85 100644
--- a/core/java/com/android/internal/policy/PhoneWindow.java
+++ b/core/java/com/android/internal/policy/PhoneWindow.java
@@ -32,7 +32,6 @@
import android.view.ActionMode;
import android.view.ContextThemeWrapper;
-import android.view.Display;
import android.view.Gravity;
import android.view.IRotationWatcher.Stub;
import android.view.IWindowManager;
@@ -73,6 +72,7 @@
import com.android.internal.widget.BackgroundFallback;
import com.android.internal.widget.DecorContentParent;
import com.android.internal.widget.FloatingToolbar;
+import com.android.internal.widget.NonClientDecorView;
import com.android.internal.widget.SwipeDismissLayout;
import android.app.ActivityManager;
@@ -1271,7 +1271,7 @@
* @param st The panel being initialized.
*/
protected boolean initializePanelDecor(PanelFeatureState st) {
- st.decorView = new DecorView(getContext(), st.featureId);
+ st.decorView = generateDecor(st.featureId);
st.gravity = Gravity.CENTER | Gravity.BOTTOM;
st.setStyle(getContext());
TypedArray a = getContext().obtainStyledAttributes(null,
@@ -2205,6 +2205,9 @@
private final Rect mFrameOffsets = new Rect();
+ // True if a non client area decor exists.
+ private boolean mHasNonClientDecor = false;
+
private boolean mChanging;
private Drawable mMenuBackground;
@@ -3149,53 +3152,59 @@
return;
}
- setPadding(mFramePadding.left + mBackgroundPadding.left, mFramePadding.top
- + mBackgroundPadding.top, mFramePadding.right + mBackgroundPadding.right,
+ setPadding(mFramePadding.left + mBackgroundPadding.left,
+ mFramePadding.top + mBackgroundPadding.top,
+ mFramePadding.right + mBackgroundPadding.right,
mFramePadding.bottom + mBackgroundPadding.bottom);
requestLayout();
invalidate();
int opacity = PixelFormat.OPAQUE;
- // Note: if there is no background, we will assume opaque. The
- // common case seems to be that an application sets there to be
- // no background so it can draw everything itself. For that,
- // we would like to assume OPAQUE and let the app force it to
- // the slower TRANSLUCENT mode if that is really what it wants.
- Drawable bg = getBackground();
- Drawable fg = getForeground();
- if (bg != null) {
- if (fg == null) {
- opacity = bg.getOpacity();
- } else if (mFramePadding.left <= 0 && mFramePadding.top <= 0
- && mFramePadding.right <= 0 && mFramePadding.bottom <= 0) {
- // If the frame padding is zero, then we can be opaque
- // if either the frame -or- the background is opaque.
- int fop = fg.getOpacity();
- int bop = bg.getOpacity();
- if (false)
- Log.v(TAG, "Background opacity: " + bop + ", Frame opacity: " + fop);
- if (fop == PixelFormat.OPAQUE || bop == PixelFormat.OPAQUE) {
- opacity = PixelFormat.OPAQUE;
- } else if (fop == PixelFormat.UNKNOWN) {
- opacity = bop;
- } else if (bop == PixelFormat.UNKNOWN) {
- opacity = fop;
+ if (windowHasShadow()) {
+ // If the window has a shadow, it must be translucent.
+ opacity = PixelFormat.TRANSLUCENT;
+ } else{
+ // Note: If there is no background, we will assume opaque. The
+ // common case seems to be that an application sets there to be
+ // no background so it can draw everything itself. For that,
+ // we would like to assume OPAQUE and let the app force it to
+ // the slower TRANSLUCENT mode if that is really what it wants.
+ Drawable bg = getBackground();
+ Drawable fg = getForeground();
+ if (bg != null) {
+ if (fg == null) {
+ opacity = bg.getOpacity();
+ } else if (mFramePadding.left <= 0 && mFramePadding.top <= 0
+ && mFramePadding.right <= 0 && mFramePadding.bottom <= 0) {
+ // If the frame padding is zero, then we can be opaque
+ // if either the frame -or- the background is opaque.
+ int fop = fg.getOpacity();
+ int bop = bg.getOpacity();
+ if (false)
+ Log.v(TAG, "Background opacity: " + bop + ", Frame opacity: " + fop);
+ if (fop == PixelFormat.OPAQUE || bop == PixelFormat.OPAQUE) {
+ opacity = PixelFormat.OPAQUE;
+ } else if (fop == PixelFormat.UNKNOWN) {
+ opacity = bop;
+ } else if (bop == PixelFormat.UNKNOWN) {
+ opacity = fop;
+ } else {
+ opacity = Drawable.resolveOpacity(fop, bop);
+ }
} else {
- opacity = Drawable.resolveOpacity(fop, bop);
+ // For now we have to assume translucent if there is a
+ // frame with padding... there is no way to tell if the
+ // frame and background together will draw all pixels.
+ if (false)
+ Log.v(TAG, "Padding: " + mFramePadding);
+ opacity = PixelFormat.TRANSLUCENT;
}
- } else {
- // For now we have to assume translucent if there is a
- // frame with padding... there is no way to tell if the
- // frame and background together will draw all pixels.
- if (false)
- Log.v(TAG, "Padding: " + mFramePadding);
- opacity = PixelFormat.TRANSLUCENT;
}
+ if (false)
+ Log.v(TAG, "Background: " + bg + ", Frame: " + fg);
}
if (false)
- Log.v(TAG, "Background: " + bg + ", Frame: " + fg);
- if (false)
Log.v(TAG, "Selected default opacity: " + opacity);
mDefaultOpacity = opacity;
@@ -3402,8 +3411,7 @@
}
};
} else {
- ViewStub stub = (ViewStub) findViewById(
- R.id.action_mode_bar_stub);
+ ViewStub stub = (ViewStub) findViewById(R.id.action_mode_bar_stub);
if (stub != null) {
mPrimaryActionModeView = (ActionBarContextView) stub.inflate();
}
@@ -3491,6 +3499,28 @@
.addOnPreDrawListener(mFloatingToolbarPreDrawListener);
}
+ // Set when the window is free floating and a non client decor frame was added.
+ void enableNonClientDecor(boolean enable) {
+ if (mHasNonClientDecor != enable) {
+ mHasNonClientDecor = enable;
+ if (getForeground() != null) {
+ drawableChanged();
+ }
+ }
+ }
+
+ // Returns true if the window has a non client decor.
+ private boolean windowHasNonClientDecor() {
+ return mHasNonClientDecor;
+ }
+
+ // Returns true if the Window is free floating and has a shadow. Note that non overlapping
+ // windows do not have a shadow since it could not be seen anyways (a small screen / tablet
+ // "tiles" the windows side by side but does not overlap them).
+ private boolean windowHasShadow() {
+ return windowHasNonClientDecor() && getElevation() > 0;
+ }
+
/**
* Clears out internal references when the action mode is destroyed.
*/
@@ -3517,7 +3547,7 @@
public void onDestroyActionMode(ActionMode mode) {
mWrapped.onDestroyActionMode(mode);
final boolean isMncApp = mContext.getApplicationInfo().targetSdkVersion
- >= Build.VERSION_CODES.MNC;
+ >= Build.VERSION_CODES.M;
final boolean isPrimary;
final boolean isFloating;
if (isMncApp) {
@@ -3600,8 +3630,8 @@
}
}
- protected DecorView generateDecor() {
- return new DecorView(getContext(), -1);
+ protected DecorView generateDecor(int featureId) {
+ return new DecorView(getContext(), featureId);
}
protected void setFeatureFromAttrs(int featureId, TypedArray attrs,
@@ -3880,8 +3910,15 @@
mDecor.startChanging();
+ NonClientDecorView nonClientDecorView = createNonClientDecorView();
View in = mLayoutInflater.inflate(layoutResource, null);
- decor.addView(in, new ViewGroup.LayoutParams(MATCH_PARENT, MATCH_PARENT));
+ if (nonClientDecorView != null) {
+ decor.addView(nonClientDecorView,
+ new ViewGroup.LayoutParams(MATCH_PARENT, MATCH_PARENT));
+ nonClientDecorView.addView(in, new ViewGroup.LayoutParams(MATCH_PARENT, MATCH_PARENT));
+ } else {
+ decor.addView(in, new ViewGroup.LayoutParams(MATCH_PARENT, MATCH_PARENT));
+ }
mContentRoot = (ViewGroup) in;
ViewGroup contentParent = (ViewGroup)findViewById(ID_ANDROID_CONTENT);
@@ -3937,6 +3974,54 @@
return contentParent;
}
+ // Free floating overlapping windows require a non client decor with a caption and shadow..
+ private NonClientDecorView createNonClientDecorView() {
+ boolean needsDecor = true;
+ NonClientDecorView nonClientDecorView = null;
+
+ final WindowManager.LayoutParams attrs = getAttributes();
+ // TODO(skuhne): Use the associated stack to figure out if the window is on the free style
+ // desktop, the side by side desktop or the full screen desktop. With that informations the
+ // choice is fairly easy to decide.
+ // => This is only a kludge for now to suppress fullscreen windows, recents, launcher, etc..
+ boolean isFullscreen =
+ 0 != ((mDecor.getWindowSystemUiVisibility() | mDecor.getSystemUiVisibility()) &
+ (View.SYSTEM_UI_FLAG_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION));
+ boolean isApplication = attrs.type != TYPE_BASE_APPLICATION &&
+ attrs.type != TYPE_APPLICATION;
+
+ // We do not show the non client decor if...
+ // - this is a floating dialog (which is not a real window, e.g. it cannot be maximized).
+ // - it is not an application (special windows have special functions, e.g text selector).
+ // - the application is full screen, drawing everything (since the decor would be out of the
+ // screen in that case and could not be seen).
+ if (isFloating() || isFullscreen || isApplication) {
+ needsDecor = false;
+ }
+
+ if (needsDecor) {
+ // TODO(skuhne): If running in side by side mode on a device - turn off the shadow.
+ boolean windowHasShadow = true;
+ // Dependent on the brightness of the used title we either use the
+ // dark or the light button frame.
+ TypedValue value = new TypedValue();
+ getContext().getTheme().resolveAttribute(R.attr.colorPrimary, value, true);
+ if (Color.brightness(value.data) < 0.5) {
+ nonClientDecorView = (NonClientDecorView) mLayoutInflater.inflate(
+ R.layout.non_client_decor_dark, null);
+ } else {
+ nonClientDecorView = (NonClientDecorView) mLayoutInflater.inflate(
+ R.layout.non_client_decor_light, null);
+ }
+ nonClientDecorView.setPhoneWindow(this, windowHasShadow);
+ }
+
+ // Tell the Decor if it has a non client decor.
+ mDecor.enableNonClientDecor(needsDecor);
+
+ return nonClientDecorView;
+ }
+
/** @hide */
public void alwaysReadCloseOnTouchAttr() {
mAlwaysReadCloseOnTouchAttr = true;
@@ -3944,7 +4029,7 @@
private void installDecor() {
if (mDecor == null) {
- mDecor = generateDecor();
+ mDecor = generateDecor(-1);
mDecor.setDescendantFocusability(ViewGroup.FOCUS_AFTER_DESCENDANTS);
mDecor.setIsRootNamespace(true);
if (!mInvalidatePanelMenuPosted && mInvalidatePanelMenuFeatures != 0) {
diff --git a/core/java/com/android/internal/util/StateMachine.java b/core/java/com/android/internal/util/StateMachine.java
index 916f19d..229407e 100644
--- a/core/java/com/android/internal/util/StateMachine.java
+++ b/core/java/com/android/internal/util/StateMachine.java
@@ -43,38 +43,38 @@
* The enter/exit methods are equivalent to the construction and destruction
* in Object Oriented programming and are used to perform initialization and
* cleanup of the state respectively. The <code>getName</code> method returns the
- * name of the state the default implementation returns the class name it may be
- * desirable to have this return the name of the state instance name instead.
- * In particular if a particular state class has multiple instances.</p>
+ * name of the state; the default implementation returns the class name. It may be
+ * desirable to have <code>getName</code> return the the state instance name instead,
+ * in particular if a particular state class has multiple instances.</p>
*
- * <p>When a state machine is created <code>addState</code> is used to build the
+ * <p>When a state machine is created, <code>addState</code> is used to build the
* hierarchy and <code>setInitialState</code> is used to identify which of these
* is the initial state. After construction the programmer calls <code>start</code>
* which initializes and starts the state machine. The first action the StateMachine
* is to the invoke <code>enter</code> for all of the initial state's hierarchy,
* starting at its eldest parent. The calls to enter will be done in the context
- * of the StateMachines Handler not in the context of the call to start and they
+ * of the StateMachine's Handler, not in the context of the call to start, and they
* will be invoked before any messages are processed. For example, given the simple
- * state machine below mP1.enter will be invoked and then mS1.enter. Finally,
- * messages sent to the state machine will be processed by the current state,
+ * state machine below, mP1.enter will be invoked and then mS1.enter. Finally,
+ * messages sent to the state machine will be processed by the current state;
* in our simple state machine below that would initially be mS1.processMessage.</p>
-<code>
+<pre>
mP1
/ \
- mS2 mS1 ----> initial state
-</code>
+ mS2 mS1 ----> initial state
+</pre>
* <p>After the state machine is created and started, messages are sent to a state
* machine using <code>sendMessage</code> and the messages are created using
* <code>obtainMessage</code>. When the state machine receives a message the
* current state's <code>processMessage</code> is invoked. In the above example
* mS1.processMessage will be invoked first. The state may use <code>transitionTo</code>
- * to change the current state to a new state</p>
+ * to change the current state to a new state.</p>
*
- * <p>Each state in the state machine may have a zero or one parent states and if
+ * <p>Each state in the state machine may have a zero or one parent states. If
* a child state is unable to handle a message it may have the message processed
- * by its parent by returning false or NOT_HANDLED. If a message is never processed
- * <code>unhandledMessage</code> will be invoked to give one last chance for the state machine
- * to process the message.</p>
+ * by its parent by returning false or NOT_HANDLED. If a message is not handled by
+ * a child state or any of its ancestors, <code>unhandledMessage</code> will be invoked
+ * to give one last chance for the state machine to process the message.</p>
*
* <p>When all processing is completed a state machine may choose to call
* <code>transitionToHaltingState</code>. When the current <code>processingMessage</code>
@@ -84,10 +84,10 @@
*
* <p>If it is desirable to completely stop the state machine call <code>quit</code> or
* <code>quitNow</code>. These will call <code>exit</code> of the current state and its parents,
- * call <code>onQuiting</code> and then exit Thread/Loopers.</p>
+ * call <code>onQuitting</code> and then exit Thread/Loopers.</p>
*
* <p>In addition to <code>processMessage</code> each <code>State</code> has
- * an <code>enter</code> method and <code>exit</exit> method which may be overridden.</p>
+ * an <code>enter</code> method and <code>exit</code> method which may be overridden.</p>
*
* <p>Since the states are arranged in a hierarchy transitioning to a new state
* causes current states to be exited and new states to be entered. To determine
@@ -110,15 +110,15 @@
*
* <p>To illustrate some of these properties we'll use state machine with an 8
* state hierarchy:</p>
-<code>
+<pre>
mP0
/ \
mP1 mS0
/ \
mS2 mS1
/ \ \
- mS3 mS4 mS5 ---> initial state
-</code>
+ mS3 mS4 mS5 ---> initial state
+</pre>
* <p>After starting mS5 the list of active states is mP0, mP1, mS1 and mS5.
* So the order of calling processMessage when a message is received is mS5,
* mS1, mP1, mP0 assuming each processMessage indicates it can't handle this
@@ -134,7 +134,7 @@
*
* <p>Now for some concrete examples, here is the canonical HelloWorld as a state machine.
* It responds with "Hello World" being printed to the log for every message.</p>
-<code>
+<pre>
class HelloWorld extends StateMachine {
HelloWorld(String name) {
super(name);
@@ -161,16 +161,16 @@
HelloWorld hw = makeHelloWorld();
hw.sendMessage(hw.obtainMessage());
}
-</code>
+</pre>
* <p>A more interesting state machine is one with four states
* with two independent parent states.</p>
-<code>
+<pre>
mP1 mP2
/ \
mS2 mS1
-</code>
+</pre>
* <p>Here is a description of this state machine using pseudo code.</p>
- <code>
+ <pre>
state mP1 {
enter { log("mP1.enter"); }
exit { log("mP1.exit"); }
@@ -178,7 +178,7 @@
CMD_2 {
send(CMD_3);
defer(msg);
- transitonTo(mS2);
+ transitionTo(mS2);
return HANDLED;
}
return NOT_HANDLED;
@@ -230,9 +230,9 @@
return NOT_HANDLED;
}
}
-</code>
+</pre>
* <p>The implementation is below and also in StateMachineTest:</p>
-<code>
+<pre>
class Hsm1 extends StateMachine {
public static final int CMD_1 = 1;
public static final int CMD_2 = 2;
@@ -374,10 +374,10 @@
S2 mS2 = new S2();
P2 mP2 = new P2();
}
-</code>
+</pre>
* <p>If this is executed by sending two messages CMD_1 and CMD_2
* (Note the synchronize is only needed because we use hsm.wait())</p>
-<code>
+<pre>
Hsm1 hsm = makeHsm1();
synchronize(hsm) {
hsm.sendMessage(obtainMessage(hsm.CMD_1));
@@ -389,9 +389,9 @@
loge("exception while waiting " + e.getMessage());
}
}
-</code>
+</pre>
* <p>The output is:</p>
-<code>
+<pre>
D/hsm1 ( 1999): makeHsm1 E
D/hsm1 ( 1999): ctor E
D/hsm1 ( 1999): ctor X
@@ -415,7 +415,7 @@
D/hsm1 ( 1999): mP2.processMessage what=5
D/hsm1 ( 1999): mP2.exit
D/hsm1 ( 1999): halting
-</code>
+</pre>
*/
public class StateMachine {
// Name of the state machine and used as logging tag
diff --git a/core/java/com/android/internal/widget/NonClientDecorView.java b/core/java/com/android/internal/widget/NonClientDecorView.java
new file mode 100644
index 0000000..57039b7
--- /dev/null
+++ b/core/java/com/android/internal/widget/NonClientDecorView.java
@@ -0,0 +1,219 @@
+/*
+ * 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.internal.widget;
+
+import android.app.ActivityManager;
+import android.app.ActivityManager.RunningTaskInfo;
+import android.app.ActivityManagerNative;
+import android.content.Context;
+import android.os.RemoteException;
+import android.util.AttributeSet;
+import android.view.View;
+import android.view.ViewGroup;
+import android.util.Log;
+import android.util.TypedValue;
+
+import android.view.ViewOutlineProvider;
+import android.view.WindowInsets;
+import com.android.internal.R;
+import com.android.internal.policy.PhoneWindow;
+
+import java.util.List;
+
+/**
+ * This class represents the special screen elements to control a window on free form
+ * environment. All thse screen elements are added in the "non client area" which is the area of
+ * the window which is handled by the OS and not the application.
+ * As such this class handles the following things:
+ * <ul>
+ * <li>The caption, containing the system buttons like maximize, close and such as well as
+ * allowing the user to drag the window around.</li>
+ * <li>The shadow - which is changing dependent on the window focus.</li>
+ * <li>The border around the client area (if there is one).</li>
+ * <li>The resize handles which allow to resize the window.</li>
+ * </ul>
+ * After creating the view, the function
+ * {@link #setPhoneWindow(PhoneWindow owner, boolean windowHasShadow)} needs to be called to make
+ * the connection to it's owning PhoneWindow.
+ * Note: At this time the application can change various attributes of the DecorView which
+ * will break things (in settle/unexpected ways):
+ * <ul>
+ * <li>setElevation</li>
+ * <li>setOutlineProvider</li>
+ * <li>setSurfaceFormat</li>
+ * <li>..</li>
+ * </ul>
+ * This will be mitigated once b/22527834 will be addressed.
+ */
+public class NonClientDecorView extends ViewGroup implements View.OnClickListener {
+ private final static String TAG = "NonClientDecorView";
+ // The height of a window which has focus in DIP.
+ private final int DECOR_SHADOW_FOCUSED_HEIGHT_IN_DIP = 20;
+ // The height of a window which has not in DIP.
+ private final int DECOR_SHADOW_UNFOCUSED_HEIGHT_IN_DIP = 5;
+
+ private PhoneWindow mOwner = null;
+ boolean mWindowHasShadow = false;
+
+ // The current focus state of the window for updating the window elevation.
+ boolean mWindowHasFocus = true;
+
+ // Cludge to address b/22668382: Set the shadow size to the maximum so that the layer
+ // size calculation takes the shadow size into account. We set the elevation currently
+ // to max until the first layout command has been executed.
+ boolean mAllowUpdateElevation = false;
+
+ public NonClientDecorView(Context context) {
+ super(context);
+ }
+
+ public NonClientDecorView(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ public NonClientDecorView(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+ }
+
+ public void setPhoneWindow(PhoneWindow owner, boolean windowHasShadow) {
+ mOwner = owner;
+ mWindowHasShadow = windowHasShadow;
+ if (mWindowHasShadow) {
+ // TODO(skuhne): Call setMaxElevation here as soon as b/22668382 got fixed.
+ updateElevation();
+ }
+ // By changing the outline provider to BOUNDS, the window can remove its
+ // background without removing the shadow.
+ mOwner.getDecorView().setOutlineProvider(ViewOutlineProvider.BOUNDS);
+ findViewById(R.id.maximize_window).setOnClickListener(this);
+ findViewById(R.id.close_window).setOnClickListener(this);
+ }
+
+ @Override
+ public void onClick(View view) {
+ if (view.getId() == R.id.maximize_window) {
+ // TODO(skuhne): Add code to maximize window.
+ } else if (view.getId() == R.id.close_window) {
+ // TODO(skuhne): This is not the right way to kill an app and we should add a high level
+ // function for it.
+ final ActivityManager m =
+ (ActivityManager) getContext().getSystemService(Context.ACTIVITY_SERVICE);
+ List<RunningTaskInfo> runningTaskInfoList = m.getRunningTasks(1);
+ if (!runningTaskInfoList.isEmpty()) {
+ try {
+ ActivityManagerNative.getDefault().removeTask(runningTaskInfoList.get(0).id);
+ } catch (RemoteException ex) {
+ Log.e(TAG, "Couldn't close task with the close button.");
+ }
+ }
+ }
+ }
+
+ @Override
+ public void onWindowFocusChanged(boolean hasWindowFocus) {
+ mWindowHasFocus = hasWindowFocus;
+ updateElevation();
+ super.onWindowFocusChanged(hasWindowFocus);
+ }
+
+ @Override
+ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+ measureChildren(widthMeasureSpec, heightMeasureSpec);
+ final int width = MeasureSpec.getSize(widthMeasureSpec);
+ final int height = MeasureSpec.getSize(heightMeasureSpec);
+ setMeasuredDimension(width, height);
+ }
+
+ @Override
+ protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
+ // The system inset needs only to be applied to the caption. The client area of
+ // the window will automatically be adjusted by the the DecorView.
+ WindowInsets insets = getRootWindowInsets();
+ int systemMargin = insets.getSystemWindowInsetTop();
+
+ final int leftPos = getPaddingLeft();
+ final int rightPos = right - left - getPaddingRight();
+ final int topPos = getPaddingTop();
+ final int bottomPos = bottom - top - getPaddingBottom();
+
+ // On top we have the caption which has to fill left to right with a fixed height.
+ final int width = rightPos - leftPos;
+ final View caption = getChildAt(0);
+
+ // If the application changed its SystemUI metrics, we might also have to adapt
+ // our shadow elevation.
+ updateElevation();
+ mAllowUpdateElevation = true;
+
+ // Remove the decor temporarily if the window entered a full screen/immersive mode.
+ final int captionHeight = isFillingScreen() ? 0 : caption.getMeasuredHeight();
+ caption.layout(leftPos, topPos + systemMargin, leftPos + width,
+ topPos + systemMargin + captionHeight);
+
+ // Note: We should never have more then 1 additional item in here.
+ if (getChildCount() > 1) {
+ getChildAt(1).layout(leftPos, topPos + captionHeight, leftPos + width, bottomPos);
+ }
+ }
+
+ // Make sure that we never get more then one client area in our view.
+ @Override
+ public void addView(View child, int index, LayoutParams params) {
+ if (index >= 2 || getChildCount() >= 2) {
+ throw new IllegalStateException("NonClientDecorView can only handle 1 client view");
+ }
+ super.addView(child, index, params);
+ }
+
+ // Returns true when the window is filling the entire screen and the non client area
+ // should not be shown.
+ private boolean isFillingScreen() {
+ return (0 != ((getWindowSystemUiVisibility() | getSystemUiVisibility()) &
+ (View.SYSTEM_UI_FLAG_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION |
+ View.SYSTEM_UI_FLAG_IMMERSIVE | View.SYSTEM_UI_FLAG_LOW_PROFILE)));
+ }
+
+ // The shadow height gets controlled by the focus to visualize highlighted windows.
+ // Note: This will overwrite application elevation properties.
+ // Note: Windows which have (temporarily) changed their attributes to cover the SystemUI
+ // will get no shadow as they are expected to be "full screen".
+ private void updateElevation() {
+ float elevation = 0;
+ if (mWindowHasShadow) {
+ boolean fill = isFillingScreen();
+ elevation = fill ? 0 :
+ (mWindowHasFocus ? DECOR_SHADOW_FOCUSED_HEIGHT_IN_DIP :
+ DECOR_SHADOW_UNFOCUSED_HEIGHT_IN_DIP);
+ if (!mAllowUpdateElevation && !fill) {
+ // TODO(skuhne): Change this to setMaxElevation as soon as b/22668382 got fixed
+ // and remove this cludge.
+ elevation = DECOR_SHADOW_FOCUSED_HEIGHT_IN_DIP;
+ }
+ // Convert the DP elevation into physical pixels.
+ elevation = dipToPx(elevation);
+ }
+ // Don't change the elevation if it didn't change since it can require some time.
+ if (mOwner.getDecorView().getElevation() != elevation) {
+ mOwner.setElevation(elevation);
+ }
+ }
+
+ private float dipToPx(float dip) {
+ return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dip,
+ getResources().getDisplayMetrics());
+ }
+}
diff --git a/core/java/com/android/internal/widget/ResolverDrawerLayout.java b/core/java/com/android/internal/widget/ResolverDrawerLayout.java
index fc9a1a5..7679624 100644
--- a/core/java/com/android/internal/widget/ResolverDrawerLayout.java
+++ b/core/java/com/android/internal/widget/ResolverDrawerLayout.java
@@ -34,6 +34,7 @@
import android.view.ViewTreeObserver;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityNodeInfo;
+import android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction;
import android.view.animation.AnimationUtils;
import android.widget.AbsListView;
import android.widget.OverScroller;
@@ -609,19 +610,37 @@
}
@Override
- public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
- super.onInitializeAccessibilityNodeInfo(info);
+ public CharSequence getAccessibilityClassName() {
+ // Since we support scrolling, make this ViewGroup look like a
+ // ScrollView. This is kind of a hack until we have support for
+ // specifying auto-scroll behavior.
+ return android.widget.ScrollView.class.getName();
+ }
+
+ @Override
+ public void onInitializeAccessibilityNodeInfoInternal(AccessibilityNodeInfo info) {
+ super.onInitializeAccessibilityNodeInfoInternal(info);
+
if (isEnabled()) {
if (mCollapseOffset != 0) {
info.addAction(AccessibilityNodeInfo.ACTION_SCROLL_FORWARD);
info.setScrollable(true);
}
}
+
+ // This view should never get accessibility focus, but it's interactive
+ // via nested scrolling, so we can't hide it completely.
+ info.removeAction(AccessibilityAction.ACTION_ACCESSIBILITY_FOCUS);
}
@Override
- public boolean performAccessibilityAction(int action, Bundle arguments) {
- if (super.performAccessibilityAction(action, arguments)) {
+ public boolean performAccessibilityActionInternal(int action, Bundle arguments) {
+ if (action == AccessibilityAction.ACTION_ACCESSIBILITY_FOCUS.getId()) {
+ // This view should never get accessibility focus.
+ return false;
+ }
+
+ if (super.performAccessibilityActionInternal(action, arguments)) {
return true;
}
@@ -629,6 +648,7 @@
smoothScrollTo(0, 0);
return true;
}
+
return false;
}
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 670d3c0..fbe3ece 100755
--- a/core/jni/android/graphics/Bitmap.cpp
+++ b/core/jni/android/graphics/Bitmap.cpp
@@ -218,7 +218,6 @@
}
const SkImageInfo& Bitmap::info() const {
- assertValid();
return mPixelRef->info();
}
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_CameraMetadata.cpp b/core/jni/android_hardware_camera2_CameraMetadata.cpp
index 7c8769d..fb22689 100644
--- a/core/jni/android_hardware_camera2_CameraMetadata.cpp
+++ b/core/jni/android_hardware_camera2_CameraMetadata.cpp
@@ -23,7 +23,9 @@
#include <utils/Vector.h>
#include <utils/SortedVector.h>
#include <utils/KeyedVector.h>
+#include <stdio.h>
#include <string.h>
+#include <vector>
#include "jni.h"
#include "JNIHelp.h"
@@ -45,9 +47,30 @@
// fully-qualified class name
#define CAMERA_METADATA_CLASS_NAME "android/hardware/camera2/impl/CameraMetadataNative"
+#define CHARACTERISTICS_KEY_CLASS_NAME "android/hardware/camera2/CameraCharacteristics$Key"
+#define REQUEST_KEY_CLASS_NAME "android/hardware/camera2/CaptureRequest$Key"
+#define RESULT_KEY_CLASS_NAME "android/hardware/camera2/CaptureResult$Key"
using namespace android;
+static struct metadata_java_key_offsets_t {
+ jclass mCharacteristicsKey;
+ jclass mResultKey;
+ jclass mRequestKey;
+ jmethodID mCharacteristicsConstr;
+ jmethodID mResultConstr;
+ jmethodID mRequestConstr;
+ jclass mByteArray;
+ jclass mInt32Array;
+ jclass mFloatArray;
+ jclass mInt64Array;
+ jclass mDoubleArray;
+ jclass mRationalArray;
+ jclass mArrayList;
+ jmethodID mArrayListConstr;
+ jmethodID mArrayListAdd;
+} gMetadataOffsets;
+
struct fields_t {
jfieldID metadata_ptr;
};
@@ -141,6 +164,7 @@
extern "C" {
static void CameraMetadata_classInit(JNIEnv *env, jobject thiz);
+static jobject CameraMetadata_getAllVendorKeys(JNIEnv* env, jobject thiz, jclass keyType);
static jint CameraMetadata_getTagFromKey(JNIEnv *env, jobject thiz, jstring keyName);
static jint CameraMetadata_getTypeFromTag(JNIEnv *env, jobject thiz, jint tag);
static jint CameraMetadata_setupGlobalVendorTagDescriptor(JNIEnv *env, jobject thiz);
@@ -510,6 +534,9 @@
{ "nativeClassInit",
"()V",
(void *)CameraMetadata_classInit },
+ { "nativeGetAllVendorKeys",
+ "(Ljava/lang/Class;)Ljava/util/ArrayList;",
+ (void *)CameraMetadata_getAllVendorKeys},
{ "nativeGetTagFromKey",
"(Ljava/lang/String;)I",
(void *)CameraMetadata_getTagFromKey },
@@ -588,6 +615,44 @@
// Get all the required offsets in java class and register native functions
int register_android_hardware_camera2_CameraMetadata(JNIEnv *env)
{
+
+ // Store global references to Key-related classes and methods used natively
+ jclass characteristicsKeyClazz = FindClassOrDie(env, CHARACTERISTICS_KEY_CLASS_NAME);
+ jclass requestKeyClazz = FindClassOrDie(env, REQUEST_KEY_CLASS_NAME);
+ jclass resultKeyClazz = FindClassOrDie(env, RESULT_KEY_CLASS_NAME);
+ gMetadataOffsets.mCharacteristicsKey = MakeGlobalRefOrDie(env, characteristicsKeyClazz);
+ gMetadataOffsets.mRequestKey = MakeGlobalRefOrDie(env, requestKeyClazz);
+ gMetadataOffsets.mResultKey = MakeGlobalRefOrDie(env, resultKeyClazz);
+ gMetadataOffsets.mCharacteristicsConstr = GetMethodIDOrDie(env,
+ gMetadataOffsets.mCharacteristicsKey, "<init>",
+ "(Ljava/lang/String;Ljava/lang/Class;)V");
+ gMetadataOffsets.mRequestConstr = GetMethodIDOrDie(env,
+ gMetadataOffsets.mRequestKey, "<init>", "(Ljava/lang/String;Ljava/lang/Class;)V");
+ gMetadataOffsets.mResultConstr = GetMethodIDOrDie(env,
+ gMetadataOffsets.mResultKey, "<init>", "(Ljava/lang/String;Ljava/lang/Class;)V");
+
+ // Store global references for primitive array types used by Keys
+ jclass byteClazz = FindClassOrDie(env, "[B");
+ jclass int32Clazz = FindClassOrDie(env, "[I");
+ jclass floatClazz = FindClassOrDie(env, "[F");
+ jclass int64Clazz = FindClassOrDie(env, "[J");
+ jclass doubleClazz = FindClassOrDie(env, "[D");
+ jclass rationalClazz = FindClassOrDie(env, "[Landroid/util/Rational;");
+ gMetadataOffsets.mByteArray = MakeGlobalRefOrDie(env, byteClazz);
+ gMetadataOffsets.mInt32Array = MakeGlobalRefOrDie(env, int32Clazz);
+ gMetadataOffsets.mFloatArray = MakeGlobalRefOrDie(env, floatClazz);
+ gMetadataOffsets.mInt64Array = MakeGlobalRefOrDie(env, int64Clazz);
+ gMetadataOffsets.mDoubleArray = MakeGlobalRefOrDie(env, doubleClazz);
+ gMetadataOffsets.mRationalArray = MakeGlobalRefOrDie(env, rationalClazz);
+
+ // Store global references for ArrayList methods used
+ jclass arrayListClazz = FindClassOrDie(env, "java/util/ArrayList");
+ gMetadataOffsets.mArrayList = MakeGlobalRefOrDie(env, arrayListClazz);
+ gMetadataOffsets.mArrayListConstr = GetMethodIDOrDie(env, gMetadataOffsets.mArrayList,
+ "<init>", "(I)V");
+ gMetadataOffsets.mArrayListAdd = GetMethodIDOrDie(env, gMetadataOffsets.mArrayList,
+ "add", "(Ljava/lang/Object;)Z");
+
// Register native functions
return RegisterMethodsOrDie(env,
CAMERA_METADATA_CLASS_NAME,
@@ -596,6 +661,7 @@
}
extern "C" {
+
static void CameraMetadata_classInit(JNIEnv *env, jobject thiz) {
// XX: Why do this separately instead of doing it in the register function?
ALOGV("%s", __FUNCTION__);
@@ -612,6 +678,107 @@
env->FindClass(CAMERA_METADATA_CLASS_NAME);
}
+static jobject CameraMetadata_getAllVendorKeys(JNIEnv* env, jobject thiz, jclass keyType) {
+
+ // Get all vendor tags
+ sp<VendorTagDescriptor> vTags = VendorTagDescriptor::getGlobalVendorTagDescriptor();
+ if (vTags.get() == nullptr) {
+ // No vendor tags.
+ return NULL;
+ }
+
+ int count = vTags->getTagCount();
+ if (count <= 0) {
+ // No vendor tags.
+ return NULL;
+ }
+
+ std::vector<uint32_t> tagIds(count, /*initializer value*/0);
+ vTags->getTagArray(&tagIds[0]);
+
+ // Which key class/constructor should we use?
+ jclass keyClazz;
+ jmethodID keyConstr;
+ if (env->IsSameObject(keyType, gMetadataOffsets.mCharacteristicsKey)) {
+ keyClazz = gMetadataOffsets.mCharacteristicsKey;
+ keyConstr = gMetadataOffsets.mCharacteristicsConstr;
+ } else if (env->IsSameObject(keyType, gMetadataOffsets.mResultKey)) {
+ keyClazz = gMetadataOffsets.mResultKey;
+ keyConstr = gMetadataOffsets.mResultConstr;
+ } else if (env->IsSameObject(keyType, gMetadataOffsets.mRequestKey)) {
+ keyClazz = gMetadataOffsets.mRequestKey;
+ keyConstr = gMetadataOffsets.mRequestConstr;
+ } else {
+ jniThrowException(env, "java/lang/IllegalArgumentException",
+ "Invalid key class given as argument.");
+ return NULL;
+ }
+
+ // Allocate arrayList to return
+ jobject arrayList = env->NewObject(gMetadataOffsets.mArrayList,
+ gMetadataOffsets.mArrayListConstr, static_cast<jint>(count));
+ if (env->ExceptionCheck()) {
+ return NULL;
+ }
+
+ for (uint32_t id : tagIds) {
+ const char* section = vTags->getSectionName(id);
+ const char* tag = vTags->getTagName(id);
+ int type = vTags->getTagType(id);
+
+ size_t totalLen = strlen(section) + strlen(tag) + 2;
+ std::vector<char> fullName(totalLen, 0);
+ snprintf(&fullName[0], totalLen, "%s.%s", section, tag);
+
+ jstring name = env->NewStringUTF(&fullName[0]);
+
+ if (env->ExceptionCheck()) {
+ return NULL;
+ }
+
+ jclass valueClazz;
+ switch (type) {
+ case TYPE_BYTE:
+ valueClazz = gMetadataOffsets.mByteArray;
+ break;
+ case TYPE_INT32:
+ valueClazz = gMetadataOffsets.mInt32Array;
+ break;
+ case TYPE_FLOAT:
+ valueClazz = gMetadataOffsets.mFloatArray;
+ break;
+ case TYPE_INT64:
+ valueClazz = gMetadataOffsets.mInt64Array;
+ break;
+ case TYPE_DOUBLE:
+ valueClazz = gMetadataOffsets.mDoubleArray;
+ break;
+ case TYPE_RATIONAL:
+ valueClazz = gMetadataOffsets.mRationalArray;
+ break;
+ default:
+ jniThrowExceptionFmt(env, "java/lang/IllegalStateException",
+ "Invalid type %d given for key %s", type, &fullName[0]);
+ return NULL;
+ }
+
+ jobject key = env->NewObject(keyClazz, keyConstr, name, valueClazz);
+ if (env->ExceptionCheck()) {
+ return NULL;
+ }
+
+ env->CallBooleanMethod(arrayList, gMetadataOffsets.mArrayListAdd, key);
+ if (env->ExceptionCheck()) {
+ return NULL;
+ }
+
+ env->DeleteLocalRef(name);
+ env->DeleteLocalRef(key);
+ }
+
+ return arrayList;
+}
+
static jint CameraMetadata_getTagFromKey(JNIEnv *env, jobject thiz, jstring keyName) {
ScopedUtfChars keyScoped(env, keyName);
diff --git a/core/jni/com_android_internal_os_Zygote.cpp b/core/jni/com_android_internal_os_Zygote.cpp
index db88962..dbf63b5 100644
--- a/core/jni/com_android_internal_os_Zygote.cpp
+++ b/core/jni/com_android_internal_os_Zygote.cpp
@@ -408,6 +408,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
+
// Utility routine to fork zygote and specialize the child process.
static pid_t ForkAndSpecializeCommon(JNIEnv* env, uid_t uid, gid_t gid, jintArray javaGids,
jint debug_flags, jobjectArray javaRlimits,
@@ -418,6 +439,10 @@
jstring instructionSet, jstring dataDir) {
SetSigChldHandler();
+#ifdef ENABLE_SCHED_BOOST
+ SetForkLoad(true);
+#endif
+
pid_t pid = fork();
if (pid == 0) {
@@ -558,6 +583,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 d6d932f..2fbf6bf 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -971,9 +971,7 @@
android:label="@string/permlab_changeWimaxState"
android:protectionLevel="normal" />
- <!--@SystemApi Allows applications to the the local WiFi and Bluetooth MAC address.
- @hide
- -->
+ <!-- Allows applications to act as network scorers. @hide @SystemApi-->
<permission android:name="android.permission.SCORE_NETWORKS"
android:protectionLevel="signature|privileged" />
@@ -2593,10 +2591,16 @@
<permission android:name="android.permission.KILL_UID"
android:protectionLevel="signature|installer" />
- <!-- Allows applications to act as network scorers. @hide @SystemApi-->
+ <!-- @SystemApi Allows applications to read the local WiFi and Bluetooth MAC address.
+ @hide -->
<permission android:name="android.permission.LOCAL_MAC_ADDRESS"
android:protectionLevel="signature|privileged" />
+ <!-- @SystemApi Allows access to MAC addresses of WiFi and Bluetooth peer devices.
+ @hide -->
+ <permission android:name="android.permission.PEERS_MAC_ADDRESS"
+ android:protectionLevel="signature" />
+
<!-- Allows the Nfc stack to dispatch Nfc messages to applications. Applications
can use this permission to ensure incoming Nfc messages are from the Nfc stack
and not simulated by another application.
diff --git a/core/res/res/drawable/decor_close_button_dark.xml b/core/res/res/drawable/decor_close_button_dark.xml
new file mode 100644
index 0000000..e5ea1f3
--- /dev/null
+++ b/core/res/res/drawable/decor_close_button_dark.xml
@@ -0,0 +1,22 @@
+<?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.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:state_window_focused="true"
+ android:drawable="@drawable/ic_decor_close_button_dark_focused" />
+ <item android:drawable="@drawable/ic_decor_close_button_dark_unfocused" />
+</selector>
+
diff --git a/core/res/res/drawable/decor_close_button_light.xml b/core/res/res/drawable/decor_close_button_light.xml
new file mode 100644
index 0000000..b77b2bd
--- /dev/null
+++ b/core/res/res/drawable/decor_close_button_light.xml
@@ -0,0 +1,22 @@
+<?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.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:state_window_focused="true"
+ android:drawable="@drawable/ic_decor_close_button_light_focused" />
+ <item android:drawable="@drawable/ic_decor_close_button_light_unfocused" />
+</selector>
+
diff --git a/core/res/res/drawable/decor_maximize_button_dark.xml b/core/res/res/drawable/decor_maximize_button_dark.xml
new file mode 100644
index 0000000..5ea372b
--- /dev/null
+++ b/core/res/res/drawable/decor_maximize_button_dark.xml
@@ -0,0 +1,22 @@
+<?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.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:state_window_focused="true"
+ android:drawable="@drawable/ic_decor_maximize_button_dark_focused" />
+ <item android:drawable="@drawable/ic_decor_maximize_button_dark_unfocused" />
+</selector>
+
diff --git a/core/res/res/drawable/decor_maximize_button_light.xml b/core/res/res/drawable/decor_maximize_button_light.xml
new file mode 100644
index 0000000..5bda131
--- /dev/null
+++ b/core/res/res/drawable/decor_maximize_button_light.xml
@@ -0,0 +1,22 @@
+<?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.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:state_window_focused="true"
+ android:drawable="@drawable/ic_decor_maximize_button_light_focused" />
+ <item android:drawable="@drawable/ic_decor_maximize_button_light_unfocused" />
+</selector>
+
diff --git a/core/res/res/drawable/ic_decor_close_button_dark_focused.xml b/core/res/res/drawable/ic_decor_close_button_dark_focused.xml
new file mode 100644
index 0000000..d7b167dd
--- /dev/null
+++ b/core/res/res/drawable/ic_decor_close_button_dark_focused.xml
@@ -0,0 +1,29 @@
+<!--
+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:width="32.0dp"
+ android:height="32.0dp"
+ android:viewportWidth="32.0"
+ android:viewportHeight="32.0">
+ <group android:scaleX="0.5"
+ android:scaleY="0.5"
+ android:translateX="8.0"
+ android:translateY="8.0" >
+ <path
+ android:fillColor="#FFFFFFFF"
+ android:pathData="M6.9,4.0l-2.9,2.9 9.1,9.1 -9.1,9.200001 2.9,2.799999 9.1,-9.1 9.1,9.1 2.9,-2.799999 -9.1,-9.200001 9.1,-9.1 -2.9,-2.9 -9.1,9.2z"/>
+ </group>
+</vector>
diff --git a/core/res/res/drawable/ic_decor_close_button_dark_unfocused.xml b/core/res/res/drawable/ic_decor_close_button_dark_unfocused.xml
new file mode 100644
index 0000000..e2e81b9
--- /dev/null
+++ b/core/res/res/drawable/ic_decor_close_button_dark_unfocused.xml
@@ -0,0 +1,29 @@
+<!--
+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:width="32.0dp"
+ android:height="32.0dp"
+ android:viewportWidth="32.0"
+ android:viewportHeight="32.0">
+ <group android:scaleX="0.5"
+ android:scaleY="0.5"
+ android:translateX="8.0"
+ android:translateY="8.0" >
+ <path
+ android:fillColor="#33FFFFFF"
+ android:pathData="M6.9,4.0l-2.9,2.9 9.1,9.1 -9.1,9.200001 2.9,2.799999 9.1,-9.1 9.1,9.1 2.9,-2.799999 -9.1,-9.200001 9.1,-9.1 -2.9,-2.9 -9.1,9.2z"/>
+ </group>
+</vector>
diff --git a/core/res/res/drawable/ic_decor_close_button_light_focused.xml b/core/res/res/drawable/ic_decor_close_button_light_focused.xml
new file mode 100644
index 0000000..0794ed3
--- /dev/null
+++ b/core/res/res/drawable/ic_decor_close_button_light_focused.xml
@@ -0,0 +1,29 @@
+<!--
+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:width="32.0dp"
+ android:height="32.0dp"
+ android:viewportWidth="32.0"
+ android:viewportHeight="32.0">
+ <group android:scaleX="0.5"
+ android:scaleY="0.5"
+ android:translateX="8.0"
+ android:translateY="8.0" >
+ <path
+ android:fillColor="#ff000000"
+ android:pathData="M6.9,4.0l-2.9,2.9 9.1,9.1 -9.1,9.200001 2.9,2.799999 9.1,-9.1 9.1,9.1 2.9,-2.799999 -9.1,-9.200001 9.1,-9.1 -2.9,-2.9 -9.1,9.2z"/>
+ </group>
+</vector>
diff --git a/core/res/res/drawable/ic_decor_close_button_light_unfocused.xml b/core/res/res/drawable/ic_decor_close_button_light_unfocused.xml
new file mode 100644
index 0000000..bd1db51
--- /dev/null
+++ b/core/res/res/drawable/ic_decor_close_button_light_unfocused.xml
@@ -0,0 +1,29 @@
+<!--
+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:width="32.0dp"
+ android:height="32.0dp"
+ android:viewportWidth="32.0"
+ android:viewportHeight="32.0">
+ <group android:scaleX="0.5"
+ android:scaleY="0.5"
+ android:translateX="8.0"
+ android:translateY="8.0" >
+ <path
+ android:fillColor="#33000000"
+ android:pathData="M6.9,4.0l-2.9,2.9 9.1,9.1 -9.1,9.200001 2.9,2.799999 9.1,-9.1 9.1,9.1 2.9,-2.799999 -9.1,-9.200001 9.1,-9.1 -2.9,-2.9 -9.1,9.2z"/>
+ </group>
+</vector>
diff --git a/core/res/res/drawable/ic_decor_maximize_button_dark_focused.xml b/core/res/res/drawable/ic_decor_maximize_button_dark_focused.xml
new file mode 100644
index 0000000..73d808b
--- /dev/null
+++ b/core/res/res/drawable/ic_decor_maximize_button_dark_focused.xml
@@ -0,0 +1,32 @@
+<!--
+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:width="32.0dp"
+ android:height="32.0dp"
+ android:viewportWidth="32.0"
+ android:viewportHeight="32.0">
+ <group android:scaleX="0.5"
+ android:scaleY="0.5"
+ android:translateX="8.0"
+ android:translateY="8.0" >
+ <path
+ android:fillColor="#FFFFFFFF"
+ android:pathData="M2.0,4.0l0.0,16.0l28.0,0.0L30.0,4.0L2.0,4.0zM26.0,16.0L6.0,16.0L6.0,8.0l20.0,0.0L26.0,16.0z"/>
+ <path
+ android:fillColor="#B2FFFFFF"
+ android:pathData="M2.0,24.0l28.0,0.0l0.0,4.0l-28.0,0.0z"/>
+ </group>
+</vector>
diff --git a/core/res/res/drawable/ic_decor_maximize_button_dark_unfocused.xml b/core/res/res/drawable/ic_decor_maximize_button_dark_unfocused.xml
new file mode 100644
index 0000000..dc79e10
--- /dev/null
+++ b/core/res/res/drawable/ic_decor_maximize_button_dark_unfocused.xml
@@ -0,0 +1,32 @@
+<!--
+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:width="32.0dp"
+ android:height="32.0dp"
+ android:viewportWidth="32.0"
+ android:viewportHeight="32.0">
+ <group android:scaleX="0.5"
+ android:scaleY="0.5"
+ android:translateX="8.0"
+ android:translateY="8.0" >
+ <path
+ android:fillColor="#33FFFFFF"
+ android:pathData="M2.0,4.0l0.0,16.0l28.0,0.0L30.0,4.0L2.0,4.0zM26.0,16.0L6.0,16.0L6.0,8.0l20.0,0.0L26.0,16.0z"/>
+ <path
+ android:fillColor="#33FFFFFF"
+ android:pathData="M2.0,24.0l28.0,0.0l0.0,4.0l-28.0,0.0z"/>
+ </group>
+</vector>
diff --git a/core/res/res/drawable/ic_decor_maximize_button_light_focused.xml b/core/res/res/drawable/ic_decor_maximize_button_light_focused.xml
new file mode 100644
index 0000000..c23390e
--- /dev/null
+++ b/core/res/res/drawable/ic_decor_maximize_button_light_focused.xml
@@ -0,0 +1,32 @@
+<!--
+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:width="32.0dp"
+ android:height="32.0dp"
+ android:viewportWidth="32.0"
+ android:viewportHeight="32.0">
+ <group android:scaleX="0.5"
+ android:scaleY="0.5"
+ android:translateX="8.0"
+ android:translateY="8.0" >
+ <path
+ android:fillColor="#FF000000"
+ android:pathData="M2.0,4.0l0.0,16.0l28.0,0.0L30.0,4.0L2.0,4.0zM26.0,16.0L6.0,16.0L6.0,8.0l20.0,0.0L26.0,16.0z"/>
+ <path
+ android:fillColor="#B2000000"
+ android:pathData="M2.0,24.0l28.0,0.0l0.0,4.0l-28.0,0.0z"/>
+ </group>
+</vector>
diff --git a/core/res/res/drawable/ic_decor_maximize_button_light_unfocused.xml b/core/res/res/drawable/ic_decor_maximize_button_light_unfocused.xml
new file mode 100644
index 0000000..a194a39
--- /dev/null
+++ b/core/res/res/drawable/ic_decor_maximize_button_light_unfocused.xml
@@ -0,0 +1,32 @@
+<!--
+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:width="32.0dp"
+ android:height="32.0dp"
+ android:viewportWidth="32.0"
+ android:viewportHeight="32.0">
+ <group android:scaleX="0.5"
+ android:scaleY="0.5"
+ android:translateX="8.0"
+ android:translateY="8.0" >
+ <path
+ android:fillColor="#33000000"
+ android:pathData="M2.0,4.0l0.0,16.0l28.0,0.0L30.0,4.0L2.0,4.0zM26.0,16.0L6.0,16.0L6.0,8.0l20.0,0.0L26.0,16.0z"/>
+ <path
+ android:fillColor="#33000000"
+ android:pathData="M2.0,24.0l28.0,0.0l0.0,4.0l-28.0,0.0z"/>
+ </group>
+</vector>
diff --git a/core/res/res/drawable/non_client_decor_title.xml b/core/res/res/drawable/non_client_decor_title.xml
new file mode 100644
index 0000000..e50daea
--- /dev/null
+++ b/core/res/res/drawable/non_client_decor_title.xml
@@ -0,0 +1,21 @@
+<?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.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:state_window_focused="true"
+ android:drawable="@drawable/non_client_decor_title_focused" />
+ <item android:drawable="@drawable/non_client_decor_title_unfocused" />
+</selector>
diff --git a/core/res/res/drawable/non_client_decor_title_focused.xml b/core/res/res/drawable/non_client_decor_title_focused.xml
new file mode 100644
index 0000000..7d1c230
--- /dev/null
+++ b/core/res/res/drawable/non_client_decor_title_focused.xml
@@ -0,0 +1,23 @@
+<?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.
+-->
+
+<shape android:shape="rectangle"
+ android:tintMode="multiply"
+ android:tint="#D8D8D8"
+ xmlns:android="http://schemas.android.com/apk/res/android">
+ <!-- Fading the primary color to 85% blackness -->
+ <solid android:color="?android:attr/colorPrimary" />
+</shape>
diff --git a/core/res/res/drawable/non_client_decor_title_unfocused.xml b/core/res/res/drawable/non_client_decor_title_unfocused.xml
new file mode 100644
index 0000000..2846d8ca
--- /dev/null
+++ b/core/res/res/drawable/non_client_decor_title_unfocused.xml
@@ -0,0 +1,23 @@
+<?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.
+-->
+
+<shape android:shape="rectangle"
+ android:tintMode="multiply"
+ android:tint="#F2F2F2"
+ xmlns:android="http://schemas.android.com/apk/res/android">
+ <!-- Fading the primary color to 95% blackness -->
+ <solid android:color="?android:attr/colorPrimary"/>
+</shape>
diff --git a/core/res/res/layout/non_client_decor_dark.xml b/core/res/res/layout/non_client_decor_dark.xml
new file mode 100644
index 0000000..00b4255
--- /dev/null
+++ b/core/res/res/layout/non_client_decor_dark.xml
@@ -0,0 +1,54 @@
+<?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.
+*/
+-->
+
+<com.android.internal.widget.NonClientDecorView xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="vertical"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_gravity="top|start"
+ android:descendantFocusability="beforeDescendants" >
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_gravity="end"
+ android:layout_height="wrap_content"
+ android:background="@drawable/non_client_decor_title" >
+ <TextView
+ android:layout_width="0dp"
+ android:layout_height="match_parent"
+ android:layout_weight="1" />
+ <Button
+ android:id="@+id/maximize_window"
+ android:layout_width="32dp"
+ android:layout_height="32dp"
+ android:layout_margin="5dp"
+ android:padding="4dp"
+ android:layout_gravity="center_vertical|end"
+ android:contentDescription="@string/maximize_button_text"
+ android:background="@drawable/decor_maximize_button_dark" />
+ <Button
+ android:id="@+id/close_window"
+ android:layout_width="32dp"
+ android:layout_height="32dp"
+ android:layout_margin="5dp"
+ android:padding="4dp"
+ android:layout_gravity="center_vertical|end"
+ android:contentDescription="@string/close_button_text"
+ android:background="@drawable/decor_close_button_dark" />
+ </LinearLayout>
+</com.android.internal.widget.NonClientDecorView>
diff --git a/core/res/res/layout/non_client_decor_light.xml b/core/res/res/layout/non_client_decor_light.xml
new file mode 100644
index 0000000..0ce8fa7
--- /dev/null
+++ b/core/res/res/layout/non_client_decor_light.xml
@@ -0,0 +1,54 @@
+<?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.
+*/
+-->
+
+<com.android.internal.widget.NonClientDecorView xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="vertical"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_gravity="top|start"
+ android:descendantFocusability="beforeDescendants" >
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_gravity="end"
+ android:layout_height="wrap_content"
+ android:background="@drawable/non_client_decor_title" >
+ <TextView
+ android:layout_width="0dp"
+ android:layout_height="match_parent"
+ android:layout_weight="1" />
+ <Button
+ android:id="@+id/maximize_window"
+ android:layout_width="32dp"
+ android:layout_height="32dp"
+ android:layout_margin="5dp"
+ android:padding="4dp"
+ android:layout_gravity="center_vertical|end"
+ android:contentDescription="@string/maximize_button_text"
+ android:background="@drawable/decor_maximize_button_light" />
+ <Button
+ android:id="@+id/close_window"
+ android:layout_width="32dp"
+ android:layout_height="32dp"
+ android:layout_margin="5dp"
+ android:padding="4dp"
+ android:layout_gravity="center_vertical|end"
+ android:contentDescription="@string/close_button_text"
+ android:background="@drawable/decor_close_button_light" />
+ </LinearLayout>
+</com.android.internal.widget.NonClientDecorView>
diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml
index ea88d1e..cb7e68b 100644
--- a/core/res/res/values-af/strings.xml
+++ b/core/res/res/values-af/strings.xml
@@ -713,6 +713,7 @@
<string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"Sel bygevoeg"</string>
<string name="lockscreen_access_pattern_cell_added_verbose" msgid="7264580781744026939">"Sel <xliff:g id="CELL_INDEX">%1$s</xliff:g> is bygevoeg"</string>
<string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"Patroon klaar"</string>
+ <string name="lockscreen_access_pattern_area" msgid="400813207572953209">"Patroonarea."</string>
<string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. Legstuk %2$d van %3$d."</string>
<string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"Voeg legstuk by."</string>
<string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"Leeg"</string>
@@ -897,8 +898,7 @@
<string name="aerr_title" msgid="1905800560317137752"></string>
<string name="aerr_application" msgid="932628488013092776">"Ongelukkig het <xliff:g id="APPLICATION">%1$s</xliff:g> gestop."</string>
<string name="aerr_process" msgid="4507058997035697579">"Ongelukkig het die proses <xliff:g id="PROCESS">%1$s</xliff:g> gestop."</string>
- <!-- no translation found for aerr_process_silence (4226685530196000222) -->
- <skip />
+ <string name="aerr_process_silence" msgid="4226685530196000222">"Maak omvalle van <xliff:g id="PROCESS">%1$s</xliff:g> af stil tot herselflaai."</string>
<string name="anr_title" msgid="4351948481459135709"></string>
<string name="anr_activity_application" msgid="1904477189057199066">"<xliff:g id="APPLICATION">%2$s</xliff:g> reageer nie.\n\nWil jy dit sluit?"</string>
<string name="anr_activity_process" msgid="5776209883299089767">"Aktiwiteit <xliff:g id="ACTIVITY">%1$s</xliff:g> reageer nie.\n\nWil jy dit afsluit?"</string>
diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml
index 9ff3f03..440ca50 100644
--- a/core/res/res/values-am/strings.xml
+++ b/core/res/res/values-am/strings.xml
@@ -713,6 +713,7 @@
<string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"ሕዋስ ታክሏል"</string>
<string name="lockscreen_access_pattern_cell_added_verbose" msgid="7264580781744026939">"ሕዋስ <xliff:g id="CELL_INDEX">%1$s</xliff:g> ታክሏል"</string>
<string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"ንድፍ ተጠናቋል"</string>
+ <string name="lockscreen_access_pattern_area" msgid="400813207572953209">"የስርዓተ-ጥለት አካባቢ።"</string>
<string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s። ምግብር %2$d ከ%3$d።"</string>
<string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"ንዑስ ፕሮግራም አክል"</string>
<string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"ባዶ"</string>
@@ -897,8 +898,7 @@
<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>
- <!-- no translation found for aerr_process_silence (4226685530196000222) -->
- <skip />
+ <string name="aerr_process_silence" msgid="4226685530196000222">"ዝምታ ብልሽቶች ከ<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>
diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml
index 80d6cb4..3705a86 100644
--- a/core/res/res/values-ar/strings.xml
+++ b/core/res/res/values-ar/strings.xml
@@ -717,6 +717,7 @@
<string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"تمت إضافة الخلية"</string>
<string name="lockscreen_access_pattern_cell_added_verbose" msgid="7264580781744026939">"تمت إضافة الخلية <xliff:g id="CELL_INDEX">%1$s</xliff:g>"</string>
<string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"اكتمل النمط"</string>
+ <string name="lockscreen_access_pattern_area" msgid="400813207572953209">"منطقة النقش."</string>
<string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. الأداة %2$d من %3$d."</string>
<string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"إضافة أداة."</string>
<string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"فارغة"</string>
@@ -917,8 +918,7 @@
<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>
- <!-- no translation found for aerr_process_silence (4226685530196000222) -->
- <skip />
+ <string name="aerr_process_silence" msgid="4226685530196000222">"يتعطل تطبيق \"Silence\" عند إجراء <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>
diff --git a/core/res/res/values-az-rAZ/strings.xml b/core/res/res/values-az-rAZ/strings.xml
index f0567e3..50bf677 100644
--- a/core/res/res/values-az-rAZ/strings.xml
+++ b/core/res/res/values-az-rAZ/strings.xml
@@ -713,6 +713,7 @@
<string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"Xana əlavə edildi"</string>
<string name="lockscreen_access_pattern_cell_added_verbose" msgid="7264580781744026939">"Xana <xliff:g id="CELL_INDEX">%1$s</xliff:g> əlavə edildi"</string>
<string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"Model tamamlandı"</string>
+ <string name="lockscreen_access_pattern_area" msgid="400813207572953209">"Model sahəsi."</string>
<string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. Widget %2$d of %3$d."</string>
<string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"Widget əlavə edin."</string>
<string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"Boş"</string>
@@ -897,8 +898,7 @@
<string name="aerr_title" msgid="1905800560317137752"></string>
<string name="aerr_application" msgid="932628488013092776">"Təəssüf ki, <xliff:g id="APPLICATION">%1$s</xliff:g> dayandı."</string>
<string name="aerr_process" msgid="4507058997035697579">"Təəssüf ki, <xliff:g id="PROCESS">%1$s</xliff:g> prosesi dayandı."</string>
- <!-- no translation found for aerr_process_silence (4226685530196000222) -->
- <skip />
+ <string name="aerr_process_silence" msgid="4226685530196000222">"<xliff:g id="PROCESS">%1$s</xliff:g> prosesindən yenidən başlatmaya kimi səssiz xətalar."</string>
<string name="anr_title" msgid="4351948481459135709"></string>
<string name="anr_activity_application" msgid="1904477189057199066">"<xliff:g id="APPLICATION">%2$s</xliff:g> cavab vermir.\n\nOnu bağlamaq istəyirsiniz?"</string>
<string name="anr_activity_process" msgid="5776209883299089767">"<xliff:g id="ACTIVITY">%1$s</xliff:g> aktivitisi cavab vermir. \n\nOnu bağlamaq istəyirsiniz?"</string>
diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml
index 5348f13..05cc050 100644
--- a/core/res/res/values-bg/strings.xml
+++ b/core/res/res/values-bg/strings.xml
@@ -713,6 +713,7 @@
<string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"Клетката е добавена"</string>
<string name="lockscreen_access_pattern_cell_added_verbose" msgid="7264580781744026939">"Добавихте точка <xliff:g id="CELL_INDEX">%1$s</xliff:g>"</string>
<string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"Фигурата е завършена"</string>
+ <string name="lockscreen_access_pattern_area" msgid="400813207572953209">"Област на фигурата."</string>
<string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. Приспособление %2$d от %3$d."</string>
<string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"Добавяне на приспособление."</string>
<string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"Празно"</string>
@@ -897,8 +898,7 @@
<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>
- <!-- no translation found for aerr_process_silence (4226685530196000222) -->
- <skip />
+ <string name="aerr_process_silence" msgid="4226685530196000222">"Заглушаване на сривовете от <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>
diff --git a/core/res/res/values-bn-rBD/strings.xml b/core/res/res/values-bn-rBD/strings.xml
index b08928d..5045f46 100644
--- a/core/res/res/values-bn-rBD/strings.xml
+++ b/core/res/res/values-bn-rBD/strings.xml
@@ -628,7 +628,7 @@
<string name="relationTypeFather" msgid="5228034687082050725">"পিতা"</string>
<string name="relationTypeFriend" msgid="7313106762483391262">"বন্ধু"</string>
<string name="relationTypeManager" msgid="6365677861610137895">"ম্যানেজার"</string>
- <string name="relationTypeMother" msgid="4578571352962758304">"মাতা"</string>
+ <string name="relationTypeMother" msgid="4578571352962758304">"মা"</string>
<string name="relationTypeParent" msgid="4755635567562925226">"পিতা ও মাতা"</string>
<string name="relationTypePartner" msgid="7266490285120262781">"অংশীদার"</string>
<string name="relationTypeReferredBy" msgid="101573059844135524">"এর দ্বারা নির্দেশ করা"</string>
@@ -713,6 +713,7 @@
<string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"কক্ষ যোগ করা হযেছে"</string>
<string name="lockscreen_access_pattern_cell_added_verbose" msgid="7264580781744026939">"<xliff:g id="CELL_INDEX">%1$s</xliff:g> কক্ষ যোগ করা হয়েছে"</string>
<string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"প্যাটার্ন সম্পন্ন হয়েছে"</string>
+ <string name="lockscreen_access_pattern_area" msgid="400813207572953209">"প্যাটার্ন এলাকা৷"</string>
<string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s৷ %3$d এর %2$d উইজেট৷"</string>
<string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"উইজেট যোগ করুন"</string>
<string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"খালি"</string>
@@ -897,8 +898,7 @@
<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>
- <!-- no translation found for aerr_process_silence (4226685530196000222) -->
- <skip />
+ <string name="aerr_process_silence" msgid="4226685530196000222">"পুনরায় চালু করা না পর্যন্ত, <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>
diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml
index 4e95915..3f38360 100644
--- a/core/res/res/values-ca/strings.xml
+++ b/core/res/res/values-ca/strings.xml
@@ -713,6 +713,7 @@
<string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"S\'ha afegit una cel·la"</string>
<string name="lockscreen_access_pattern_cell_added_verbose" msgid="7264580781744026939">"S\'ha afegit la cel·la <xliff:g id="CELL_INDEX">%1$s</xliff:g>"</string>
<string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"Patró completat"</string>
+ <string name="lockscreen_access_pattern_area" msgid="400813207572953209">"Àrea del patró."</string>
<string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. Widget %2$d de %3$d."</string>
<string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"Afegeix un widget"</string>
<string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"Buit"</string>
@@ -897,8 +898,7 @@
<string name="aerr_title" msgid="1905800560317137752"></string>
<string name="aerr_application" msgid="932628488013092776">"<xliff:g id="APPLICATION">%1$s</xliff:g> s\'ha aturat."</string>
<string name="aerr_process" msgid="4507058997035697579">"El procés <xliff:g id="PROCESS">%1$s</xliff:g> s\'ha aturat."</string>
- <!-- no translation found for aerr_process_silence (4226685530196000222) -->
- <skip />
+ <string name="aerr_process_silence" msgid="4226685530196000222">"Silencia la informació de bloqueig de l\'aplicació <xliff:g id="PROCESS">%1$s</xliff:g> fins que es reiniciï."</string>
<string name="anr_title" msgid="4351948481459135709"></string>
<string name="anr_activity_application" msgid="1904477189057199066">"<xliff:g id="APPLICATION">%2$s</xliff:g> no respon.\n\nVols tancar-la?"</string>
<string name="anr_activity_process" msgid="5776209883299089767">"L\'activitat <xliff:g id="ACTIVITY">%1$s</xliff:g> no respon.\n\nVols tancar-la?"</string>
diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml
index 77ae216..93f8a2d 100644
--- a/core/res/res/values-cs/strings.xml
+++ b/core/res/res/values-cs/strings.xml
@@ -436,8 +436,7 @@
<string name="fingerprint_name_template" msgid="5870957565512716938">"Prst <xliff:g id="FINGERID">%d</xliff:g>"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
- <!-- no translation found for fingerprint_icon_content_description (2340202869968465936) -->
- <skip />
+ <string name="fingerprint_icon_content_description" msgid="2340202869968465936">"Ikona otisku prstů"</string>
<string name="permlab_readSyncSettings" msgid="6201810008230503052">"čtení nastavení synchronizace"</string>
<string name="permdesc_readSyncSettings" msgid="2706745674569678644">"Umožňuje aplikaci číst nastavení synchronizace v účtu. Může například určit, zda je s účtem synchronizována aplikace Lidé."</string>
<string name="permlab_writeSyncSettings" msgid="5408694875793945314">"vypnutí nebo zapnutí synchronizace"</string>
@@ -716,6 +715,7 @@
<string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"Buňka přidána"</string>
<string name="lockscreen_access_pattern_cell_added_verbose" msgid="7264580781744026939">"Byla přidána buňka <xliff:g id="CELL_INDEX">%1$s</xliff:g>"</string>
<string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"Bezpečnostní gesto dokončeno"</string>
+ <string name="lockscreen_access_pattern_area" msgid="400813207572953209">"Oblast pro zadání bezpečnostního gesta."</string>
<string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. Widget %2$d z %3$d."</string>
<string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"Přidat widget"</string>
<string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"Prázdné"</string>
@@ -908,8 +908,7 @@
<string name="aerr_title" msgid="1905800560317137752"></string>
<string name="aerr_application" msgid="932628488013092776">"Aplikace <xliff:g id="APPLICATION">%1$s</xliff:g> bohužel přestala pracovat."</string>
<string name="aerr_process" msgid="4507058997035697579">"Proces <xliff:g id="PROCESS">%1$s</xliff:g> byl bohužel ukončen."</string>
- <!-- no translation found for aerr_process_silence (4226685530196000222) -->
- <skip />
+ <string name="aerr_process_silence" msgid="4226685530196000222">"Selhání aplikace Silence kvůli procesu <xliff:g id="PROCESS">%1$s</xliff:g> potrvá do restartování."</string>
<string name="anr_title" msgid="4351948481459135709"></string>
<string name="anr_activity_application" msgid="1904477189057199066">"Aplikace <xliff:g id="APPLICATION">%2$s</xliff:g> nereaguje.\n\nChcete ji ukončit?"</string>
<string name="anr_activity_process" msgid="5776209883299089767">"Aktivita <xliff:g id="ACTIVITY">%1$s</xliff:g> nereaguje.\n\nChcete ji ukončit?"</string>
diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml
index 9649fbf..7c884c4 100644
--- a/core/res/res/values-da/strings.xml
+++ b/core/res/res/values-da/strings.xml
@@ -434,8 +434,7 @@
<string name="fingerprint_name_template" msgid="5870957565512716938">"Fingeraftryk <xliff:g id="FINGERID">%d</xliff:g>"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
- <!-- no translation found for fingerprint_icon_content_description (2340202869968465936) -->
- <skip />
+ <string name="fingerprint_icon_content_description" msgid="2340202869968465936">"Ikon for fingeraftryk"</string>
<string name="permlab_readSyncSettings" msgid="6201810008230503052">"læse indstillinger for synkronisering"</string>
<string name="permdesc_readSyncSettings" msgid="2706745674569678644">"Tillader, at appen kan læse synkroniseringsindstillingerne for en konto. Denne tilladelse kan f.eks. fastslå, om appen Personer er synkroniseret med en konto."</string>
<string name="permlab_writeSyncSettings" msgid="5408694875793945314">"slå synkronisering til og fra"</string>
@@ -714,6 +713,7 @@
<string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"Celle er tilføjet"</string>
<string name="lockscreen_access_pattern_cell_added_verbose" msgid="7264580781744026939">"Celle <xliff:g id="CELL_INDEX">%1$s</xliff:g> blev tilføjet"</string>
<string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"Mønster er fuldført"</string>
+ <string name="lockscreen_access_pattern_area" msgid="400813207572953209">"Mønsterområde."</string>
<string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. Widget %2$d af %3$d."</string>
<string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"Tilføj widget."</string>
<string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"Tom"</string>
@@ -898,8 +898,7 @@
<string name="aerr_title" msgid="1905800560317137752"></string>
<string name="aerr_application" msgid="932628488013092776">"Applikationen <xliff:g id="APPLICATION">%1$s</xliff:g> er desværre stoppet."</string>
<string name="aerr_process" msgid="4507058997035697579">"Processen <xliff:g id="PROCESS">%1$s</xliff:g> er desværre stoppet."</string>
- <!-- no translation found for aerr_process_silence (4226685530196000222) -->
- <skip />
+ <string name="aerr_process_silence" msgid="4226685530196000222">"Appen Silence går ned som følge af <xliff:g id="PROCESS">%1$s</xliff:g>, indtil der genstartes."</string>
<string name="anr_title" msgid="4351948481459135709"></string>
<string name="anr_activity_application" msgid="1904477189057199066">"<xliff:g id="APPLICATION">%2$s</xliff:g> svarer ikke.\n\nVil du lukke den?"</string>
<string name="anr_activity_process" msgid="5776209883299089767">"Aktiviteten <xliff:g id="ACTIVITY">%1$s</xliff:g> svarer ikke.\n\nVil du at lukke den?"</string>
diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml
index 203a948..7af117f 100644
--- a/core/res/res/values-de/strings.xml
+++ b/core/res/res/values-de/strings.xml
@@ -713,6 +713,7 @@
<string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"Zelle hinzugefügt"</string>
<string name="lockscreen_access_pattern_cell_added_verbose" msgid="7264580781744026939">"Punkt <xliff:g id="CELL_INDEX">%1$s</xliff:g> hinzugefügt"</string>
<string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"Muster abgeschlossen"</string>
+ <string name="lockscreen_access_pattern_area" msgid="400813207572953209">"Bereich für Muster"</string>
<string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. Widget %2$d von %3$d."</string>
<string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"Widget hinzufügen"</string>
<string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"Leer"</string>
@@ -897,8 +898,7 @@
<string name="aerr_title" msgid="1905800560317137752"></string>
<string name="aerr_application" msgid="932628488013092776">"\"<xliff:g id="APPLICATION">%1$s</xliff:g>\" wurde beendet."</string>
<string name="aerr_process" msgid="4507058997035697579">"Der Prozess \"<xliff:g id="PROCESS">%1$s</xliff:g>\" wurde beendet."</string>
- <!-- no translation found for aerr_process_silence (4226685530196000222) -->
- <skip />
+ <string name="aerr_process_silence" msgid="4226685530196000222">"Silence stürzt bei <xliff:g id="PROCESS">%1$s</xliff:g> bis zum Neustart ab."</string>
<string name="anr_title" msgid="4351948481459135709"></string>
<string name="anr_activity_application" msgid="1904477189057199066">"<xliff:g id="APPLICATION">%2$s</xliff:g> reagiert nicht.\n\nMöchten Sie die App schließen?"</string>
<string name="anr_activity_process" msgid="5776209883299089767">"Aktivität \"<xliff:g id="ACTIVITY">%1$s</xliff:g>\" reagiert nicht.\n\nMöchten Sie sie beenden?"</string>
diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml
index cdd246a..3d66deb 100644
--- a/core/res/res/values-el/strings.xml
+++ b/core/res/res/values-el/strings.xml
@@ -713,6 +713,7 @@
<string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"Προστέθηκε κελί"</string>
<string name="lockscreen_access_pattern_cell_added_verbose" msgid="7264580781744026939">"Προστέθηκε το κελί <xliff:g id="CELL_INDEX">%1$s</xliff:g>"</string>
<string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"Το μοτίβο ολοκληρώθηκε"</string>
+ <string name="lockscreen_access_pattern_area" msgid="400813207572953209">"Περιοχή μοτίβου."</string>
<string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. Γραφικό στοιχείο %2$d από %3$d."</string>
<string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"Προσθήκη γραφικού στοιχείου"</string>
<string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"Κενή"</string>
@@ -897,8 +898,7 @@
<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>
- <!-- no translation found for aerr_process_silence (4226685530196000222) -->
- <skip />
+ <string name="aerr_process_silence" msgid="4226685530196000222">"Η σίγαση διακόπτεται από <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>
diff --git a/core/res/res/values-en-rAU/strings.xml b/core/res/res/values-en-rAU/strings.xml
index 8bb3cc6..f4fbe40 100644
--- a/core/res/res/values-en-rAU/strings.xml
+++ b/core/res/res/values-en-rAU/strings.xml
@@ -713,6 +713,7 @@
<string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"Cell added"</string>
<string name="lockscreen_access_pattern_cell_added_verbose" msgid="7264580781744026939">"Cell <xliff:g id="CELL_INDEX">%1$s</xliff:g> added"</string>
<string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"Pattern completed"</string>
+ <string name="lockscreen_access_pattern_area" msgid="400813207572953209">"Pattern area."</string>
<string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. Widget %2$d of %3$d."</string>
<string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"Add widget"</string>
<string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"Empty"</string>
@@ -897,8 +898,7 @@
<string name="aerr_title" msgid="1905800560317137752"></string>
<string name="aerr_application" msgid="932628488013092776">"Unfortunately, <xliff:g id="APPLICATION">%1$s</xliff:g> has stopped."</string>
<string name="aerr_process" msgid="4507058997035697579">"Unfortunately, the process <xliff:g id="PROCESS">%1$s</xliff:g> has stopped."</string>
- <!-- no translation found for aerr_process_silence (4226685530196000222) -->
- <skip />
+ <string name="aerr_process_silence" msgid="4226685530196000222">"Silence crashes from <xliff:g id="PROCESS">%1$s</xliff:g> until reboot."</string>
<string name="anr_title" msgid="4351948481459135709"></string>
<string name="anr_activity_application" msgid="1904477189057199066">"<xliff:g id="APPLICATION">%2$s</xliff:g> isn\'t responding.\n\nDo you want to close it?"</string>
<string name="anr_activity_process" msgid="5776209883299089767">"Activity <xliff:g id="ACTIVITY">%1$s</xliff:g> isn\'t responding.\n\nDo you want to close it?"</string>
diff --git a/core/res/res/values-en-rGB/strings.xml b/core/res/res/values-en-rGB/strings.xml
index 8bb3cc6..f4fbe40 100644
--- a/core/res/res/values-en-rGB/strings.xml
+++ b/core/res/res/values-en-rGB/strings.xml
@@ -713,6 +713,7 @@
<string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"Cell added"</string>
<string name="lockscreen_access_pattern_cell_added_verbose" msgid="7264580781744026939">"Cell <xliff:g id="CELL_INDEX">%1$s</xliff:g> added"</string>
<string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"Pattern completed"</string>
+ <string name="lockscreen_access_pattern_area" msgid="400813207572953209">"Pattern area."</string>
<string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. Widget %2$d of %3$d."</string>
<string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"Add widget"</string>
<string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"Empty"</string>
@@ -897,8 +898,7 @@
<string name="aerr_title" msgid="1905800560317137752"></string>
<string name="aerr_application" msgid="932628488013092776">"Unfortunately, <xliff:g id="APPLICATION">%1$s</xliff:g> has stopped."</string>
<string name="aerr_process" msgid="4507058997035697579">"Unfortunately, the process <xliff:g id="PROCESS">%1$s</xliff:g> has stopped."</string>
- <!-- no translation found for aerr_process_silence (4226685530196000222) -->
- <skip />
+ <string name="aerr_process_silence" msgid="4226685530196000222">"Silence crashes from <xliff:g id="PROCESS">%1$s</xliff:g> until reboot."</string>
<string name="anr_title" msgid="4351948481459135709"></string>
<string name="anr_activity_application" msgid="1904477189057199066">"<xliff:g id="APPLICATION">%2$s</xliff:g> isn\'t responding.\n\nDo you want to close it?"</string>
<string name="anr_activity_process" msgid="5776209883299089767">"Activity <xliff:g id="ACTIVITY">%1$s</xliff:g> isn\'t responding.\n\nDo you want to close it?"</string>
diff --git a/core/res/res/values-en-rIN/strings.xml b/core/res/res/values-en-rIN/strings.xml
index 8bb3cc6..f4fbe40 100644
--- a/core/res/res/values-en-rIN/strings.xml
+++ b/core/res/res/values-en-rIN/strings.xml
@@ -713,6 +713,7 @@
<string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"Cell added"</string>
<string name="lockscreen_access_pattern_cell_added_verbose" msgid="7264580781744026939">"Cell <xliff:g id="CELL_INDEX">%1$s</xliff:g> added"</string>
<string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"Pattern completed"</string>
+ <string name="lockscreen_access_pattern_area" msgid="400813207572953209">"Pattern area."</string>
<string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. Widget %2$d of %3$d."</string>
<string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"Add widget"</string>
<string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"Empty"</string>
@@ -897,8 +898,7 @@
<string name="aerr_title" msgid="1905800560317137752"></string>
<string name="aerr_application" msgid="932628488013092776">"Unfortunately, <xliff:g id="APPLICATION">%1$s</xliff:g> has stopped."</string>
<string name="aerr_process" msgid="4507058997035697579">"Unfortunately, the process <xliff:g id="PROCESS">%1$s</xliff:g> has stopped."</string>
- <!-- no translation found for aerr_process_silence (4226685530196000222) -->
- <skip />
+ <string name="aerr_process_silence" msgid="4226685530196000222">"Silence crashes from <xliff:g id="PROCESS">%1$s</xliff:g> until reboot."</string>
<string name="anr_title" msgid="4351948481459135709"></string>
<string name="anr_activity_application" msgid="1904477189057199066">"<xliff:g id="APPLICATION">%2$s</xliff:g> isn\'t responding.\n\nDo you want to close it?"</string>
<string name="anr_activity_process" msgid="5776209883299089767">"Activity <xliff:g id="ACTIVITY">%1$s</xliff:g> isn\'t responding.\n\nDo you want to close it?"</string>
diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml
index 5d09778..0bad8de 100644
--- a/core/res/res/values-es-rUS/strings.xml
+++ b/core/res/res/values-es-rUS/strings.xml
@@ -713,6 +713,7 @@
<string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"Se agregó una celda."</string>
<string name="lockscreen_access_pattern_cell_added_verbose" msgid="7264580781744026939">"Se agregó la celda <xliff:g id="CELL_INDEX">%1$s</xliff:g>"</string>
<string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"Se completó el patrón"</string>
+ <string name="lockscreen_access_pattern_area" msgid="400813207572953209">"Área de patrón"</string>
<string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. Widget %2$d de %3$d"</string>
<string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"Agregar widget"</string>
<string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"Vacío"</string>
@@ -897,8 +898,7 @@
<string name="aerr_title" msgid="1905800560317137752"></string>
<string name="aerr_application" msgid="932628488013092776">"Lamentablemente, la aplicación <xliff:g id="APPLICATION">%1$s</xliff:g> se detuvo."</string>
<string name="aerr_process" msgid="4507058997035697579">"Lamentablemente, el proceso <xliff:g id="PROCESS">%1$s</xliff:g> se detuvo."</string>
- <!-- no translation found for aerr_process_silence (4226685530196000222) -->
- <skip />
+ <string name="aerr_process_silence" msgid="4226685530196000222">"El proceso <xliff:g id="PROCESS">%1$s</xliff:g> produce fallos en la aplicación de silencio hasta que se reinicie."</string>
<string name="anr_title" msgid="4351948481459135709"></string>
<string name="anr_activity_application" msgid="1904477189057199066">"<xliff:g id="APPLICATION">%2$s</xliff:g> no responde.\n\n¿Deseas cerrarla?"</string>
<string name="anr_activity_process" msgid="5776209883299089767">"La actividad <xliff:g id="ACTIVITY">%1$s</xliff:g> no responde.\n\n¿Deseas cerrarla?"</string>
diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml
index b0b242f..9448e39 100644
--- a/core/res/res/values-es/strings.xml
+++ b/core/res/res/values-es/strings.xml
@@ -713,6 +713,7 @@
<string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"Se ha añadido una celda."</string>
<string name="lockscreen_access_pattern_cell_added_verbose" msgid="7264580781744026939">"Se ha añadido la celda <xliff:g id="CELL_INDEX">%1$s</xliff:g>"</string>
<string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"Patrón completado"</string>
+ <string name="lockscreen_access_pattern_area" msgid="400813207572953209">"Área de patrón."</string>
<string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. Widget %2$d de %3$d"</string>
<string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"Añadir widget"</string>
<string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"Vacío"</string>
@@ -897,8 +898,7 @@
<string name="aerr_title" msgid="1905800560317137752"></string>
<string name="aerr_application" msgid="932628488013092776">"Se ha detenido la aplicación <xliff:g id="APPLICATION">%1$s</xliff:g>."</string>
<string name="aerr_process" msgid="4507058997035697579">"Se ha detenido el proceso <xliff:g id="PROCESS">%1$s</xliff:g>."</string>
- <!-- no translation found for aerr_process_silence (4226685530196000222) -->
- <skip />
+ <string name="aerr_process_silence" msgid="4226685530196000222">"Aplicación bloqueada desde el proceso <xliff:g id="PROCESS">%1$s</xliff:g> hasta que se reinicie."</string>
<string name="anr_title" msgid="4351948481459135709"></string>
<string name="anr_activity_application" msgid="1904477189057199066">"La aplicación <xliff:g id="APPLICATION">%2$s</xliff:g> no responde.\n\n¿Quieres cerrarla?"</string>
<string name="anr_activity_process" msgid="5776209883299089767">"La actividad <xliff:g id="ACTIVITY">%1$s</xliff:g> no responde.\n\n¿Quieres cerrarla?"</string>
diff --git a/core/res/res/values-et-rEE/strings.xml b/core/res/res/values-et-rEE/strings.xml
index ca1bb7f..fef448a 100644
--- a/core/res/res/values-et-rEE/strings.xml
+++ b/core/res/res/values-et-rEE/strings.xml
@@ -713,6 +713,7 @@
<string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"Lahter on lisatud"</string>
<string name="lockscreen_access_pattern_cell_added_verbose" msgid="7264580781744026939">"Lisati lahter <xliff:g id="CELL_INDEX">%1$s</xliff:g>"</string>
<string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"Muster on valmis"</string>
+ <string name="lockscreen_access_pattern_area" msgid="400813207572953209">"Mustri ala."</string>
<string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. Vidin %2$d/%3$d."</string>
<string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"Vidina lisamine."</string>
<string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"Tühi"</string>
@@ -897,8 +898,7 @@
<string name="aerr_title" msgid="1905800560317137752"></string>
<string name="aerr_application" msgid="932628488013092776">"Kahjuks on rakendus <xliff:g id="APPLICATION">%1$s</xliff:g> peatunud."</string>
<string name="aerr_process" msgid="4507058997035697579">"Kahjuks on protsess <xliff:g id="PROCESS">%1$s</xliff:g> peatunud."</string>
- <!-- no translation found for aerr_process_silence (4226685530196000222) -->
- <skip />
+ <string name="aerr_process_silence" msgid="4226685530196000222">"Protsessi <xliff:g id="PROCESS">%1$s</xliff:g> krahhid vaigistatakse taaskäivitamiseni."</string>
<string name="anr_title" msgid="4351948481459135709"></string>
<string name="anr_activity_application" msgid="1904477189057199066">"<xliff:g id="APPLICATION">%2$s</xliff:g> ei vasta.\n\nKas soovite selle sulgeda?"</string>
<string name="anr_activity_process" msgid="5776209883299089767">"Tegevus <xliff:g id="ACTIVITY">%1$s</xliff:g> ei vasta.\n\nKas soovite selle sulgeda?"</string>
diff --git a/core/res/res/values-eu-rES/strings.xml b/core/res/res/values-eu-rES/strings.xml
index 81dfbe0..b0a85a4 100644
--- a/core/res/res/values-eu-rES/strings.xml
+++ b/core/res/res/values-eu-rES/strings.xml
@@ -713,6 +713,7 @@
<string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"Gelaxka gehitu da"</string>
<string name="lockscreen_access_pattern_cell_added_verbose" msgid="7264580781744026939">"Gehitu da <xliff:g id="CELL_INDEX">%1$s</xliff:g> puntua"</string>
<string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"Eredua osatu da"</string>
+ <string name="lockscreen_access_pattern_area" msgid="400813207572953209">"Eredua marrazteko eremua."</string>
<string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. %2$d/%3$d widgeta."</string>
<string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"Gehitu widgeta."</string>
<string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"Hutsik"</string>
@@ -897,8 +898,7 @@
<string name="aerr_title" msgid="1905800560317137752"></string>
<string name="aerr_application" msgid="932628488013092776">"Zoritxarrez, <xliff:g id="APPLICATION">%1$s</xliff:g> aplikazioa gelditu egin da."</string>
<string name="aerr_process" msgid="4507058997035697579">"Zoritxarrez, <xliff:g id="PROCESS">%1$s</xliff:g> prozesua gelditu egin da."</string>
- <!-- no translation found for aerr_process_silence (4226685530196000222) -->
- <skip />
+ <string name="aerr_process_silence" msgid="4226685530196000222">"Blokeatu egin da aplikazioa <xliff:g id="PROCESS">%1$s</xliff:g> prozesutik berrabiarazten den arte."</string>
<string name="anr_title" msgid="4351948481459135709"></string>
<string name="anr_activity_application" msgid="1904477189057199066">"<xliff:g id="APPLICATION">%2$s</xliff:g> aplikazioak ez du erantzuten.\n\nItxi egin nahi duzu?"</string>
<string name="anr_activity_process" msgid="5776209883299089767">"<xliff:g id="ACTIVITY">%1$s</xliff:g> jarduerak ez du erantzuten.\n\nItxi egin nahi duzu?"</string>
diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml
index 345f16a..5d63d35 100644
--- a/core/res/res/values-fa/strings.xml
+++ b/core/res/res/values-fa/strings.xml
@@ -465,8 +465,8 @@
<string name="permdesc_control_incall_experience" msgid="915159066039828124">"به برنامه امکان میدهد تجربه کاربر در حال تماس را ارائه دهد."</string>
<string name="permlab_readNetworkUsageHistory" msgid="7862593283611493232">"خواندن سابقه استفاده از شبکه"</string>
<string name="permdesc_readNetworkUsageHistory" msgid="7689060749819126472">"به برنامه اجازه میدهد تا کاربرد شبکه را در طول زمان برای برنامهها و شبکههای خاص بخواند."</string>
- <string name="permlab_manageNetworkPolicy" msgid="2562053592339859990">"مدیریت خط مشی شبکه"</string>
- <string name="permdesc_manageNetworkPolicy" msgid="7537586771559370668">"به برنامه اجازه میدهد تا خط مشیهای شبکه را مدیریت کند و قوانین خاص برنامه را تعیین کند."</string>
+ <string name="permlab_manageNetworkPolicy" msgid="2562053592339859990">"مدیریت خطمشی شبکه"</string>
+ <string name="permdesc_manageNetworkPolicy" msgid="7537586771559370668">"به برنامه اجازه میدهد تا خطمشیهای شبکه را مدیریت کند و قوانین خاص برنامه را تعیین کند."</string>
<string name="permlab_modifyNetworkAccounting" msgid="5088217309088729650">"اصلاح محاسبه استفاده از شبکه"</string>
<string name="permdesc_modifyNetworkAccounting" msgid="5443412866746198123">"به برنامه اجازه میدهد تا نحوه محاسبه کاربرد شبکه در برنامه را تغییر دهد. برای استفاده برنامههای عادی نیست."</string>
<string name="permlab_accessNotifications" msgid="7673416487873432268">"اعلانهای دسترسی"</string>
@@ -668,7 +668,7 @@
<string name="lockscreen_missing_sim_instructions" msgid="5372787138023272615">"سیم کارت را وارد کنید."</string>
<string name="lockscreen_missing_sim_instructions_long" msgid="3526573099019319472">"سیم کارت موجود نیست یا قابل خواندن نیست. یک سیم کارت وارد کنید."</string>
<string name="lockscreen_permanent_disabled_sim_message_short" msgid="5096149665138916184">"سیم کارت غیرقابل استفاده است."</string>
- <string name="lockscreen_permanent_disabled_sim_instructions" msgid="910904643433151371">"سیم کارت شما به طور دائم غیر فعال شده است. \nبرای داشتن سیم کارت دیگر با ارائهدهنده سرویس بیسیم خود تماس بگیرید."</string>
+ <string name="lockscreen_permanent_disabled_sim_instructions" msgid="910904643433151371">"سیم کارت شما بهطور دائم غیر فعال شده است. \nبرای داشتن سیم کارت دیگر با ارائهدهنده سرویس بیسیم خود تماس بگیرید."</string>
<string name="lockscreen_transport_prev_description" msgid="6300840251218161534">"آهنگ قبلی"</string>
<string name="lockscreen_transport_next_description" msgid="573285210424377338">"آهنگ بعدی"</string>
<string name="lockscreen_transport_pause_description" msgid="3980308465056173363">"توقف موقت"</string>
@@ -713,6 +713,7 @@
<string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"سلول اضافه شد"</string>
<string name="lockscreen_access_pattern_cell_added_verbose" msgid="7264580781744026939">"سلول <xliff:g id="CELL_INDEX">%1$s</xliff:g> اضافه شد"</string>
<string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"الگو تکمیل شد"</string>
+ <string name="lockscreen_access_pattern_area" msgid="400813207572953209">"ناحیه الگو"</string>
<string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. ابزارک %2$d از %3$d."</string>
<string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"ابزارک اضافه کنید."</string>
<string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"خالی"</string>
@@ -841,9 +842,9 @@
<item quantity="one"><xliff:g id="COUNT">%d</xliff:g> ساعت</item>
<item quantity="other"><xliff:g id="COUNT">%d</xliff:g> ساعت</item>
</plurals>
- <string name="VideoView_error_title" msgid="3534509135438353077">"مشکل در ویدئو"</string>
- <string name="VideoView_error_text_invalid_progressive_playback" msgid="3186670335938670444">"متأسفیم، این ویدئو برای پخش جریانی با این دستگاه معتبر نیست."</string>
- <string name="VideoView_error_text_unknown" msgid="3450439155187810085">"پخش این ویدئو ممکن نیست."</string>
+ <string name="VideoView_error_title" msgid="3534509135438353077">"مشکل در ویدیو"</string>
+ <string name="VideoView_error_text_invalid_progressive_playback" msgid="3186670335938670444">"متأسفیم، این ویدیو برای پخش جریانی با این دستگاه معتبر نیست."</string>
+ <string name="VideoView_error_text_unknown" msgid="3450439155187810085">"پخش این ویدیو ممکن نیست."</string>
<string name="VideoView_error_button" msgid="2822238215100679592">"تأیید"</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">"ظهر"</string>
@@ -865,7 +866,7 @@
<string name="deleteText" msgid="6979668428458199034">"حذف"</string>
<string name="inputMethod" msgid="1653630062304567879">"روش ورودی"</string>
<string name="editTextMenuTitle" msgid="4909135564941815494">"عملکردهای متنی"</string>
- <string name="low_internal_storage_view_title" msgid="5576272496365684834">"فضای ذخیرهسازی رو به اتمام است"</string>
+ <string name="low_internal_storage_view_title" msgid="5576272496365684834">"حافظه درحال پر شدن است"</string>
<string name="low_internal_storage_view_text" msgid="6640505817617414371">"برخی از عملکردهای سیستم ممکن است کار نکنند"</string>
<string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"فضای ذخیرهسازی سیستم کافی نیست. اطمینان حاصل کنید که دارای ۲۵۰ مگابایت فضای خالی هستید و سیستم را راهاندازی مجدد کنید."</string>
<string name="app_running_notification_title" msgid="8718335121060787914">"<xliff:g id="APP_NAME">%1$s</xliff:g> در حال اجرا است"</string>
@@ -897,8 +898,7 @@
<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>
- <!-- no translation found for aerr_process_silence (4226685530196000222) -->
- <skip />
+ <string name="aerr_process_silence" msgid="4226685530196000222">"تا راهاندازی مجدد، خرابیها از <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>
@@ -914,8 +914,8 @@
<string name="screen_compat_mode_scale" msgid="3202955667675944499">"مقیاس"</string>
<string name="screen_compat_mode_show" msgid="4013878876486655892">"همیشه نشان داده شود"</string>
<string name="screen_compat_mode_hint" msgid="1064524084543304459">"در تنظیمات سیستم >برنامهها > مورد دانلود شده آن را دوباره فعال کنید."</string>
- <string name="smv_application" msgid="3307209192155442829">"برنامه <xliff:g id="APPLICATION">%1$s</xliff:g> (پردازش <xliff:g id="PROCESS">%2$s</xliff:g>) خط مشی StrictMode اجرایی خود را نقض کرده است."</string>
- <string name="smv_process" msgid="5120397012047462446">"فرآیند <xliff:g id="PROCESS">%1$s</xliff:g> خط مشی StrictMode اجرای خودکار خود را نقض کرده است."</string>
+ <string name="smv_application" msgid="3307209192155442829">"برنامه <xliff:g id="APPLICATION">%1$s</xliff:g> (پردازش <xliff:g id="PROCESS">%2$s</xliff:g>) خطمشی StrictMode اجرایی خود را نقض کرده است."</string>
+ <string name="smv_process" msgid="5120397012047462446">"فرآیند <xliff:g id="PROCESS">%1$s</xliff:g> خطمشی StrictMode اجرای خودکار خود را نقض کرده است."</string>
<string name="android_upgrading_title" msgid="1584192285441405746">"Android در حال ارتقا است..."</string>
<string name="android_start_title" msgid="8418054686415318207">"Android در حال راهاندازی است..."</string>
<string name="android_upgrading_fstrim" msgid="8036718871534640010">"بهینهسازی فضای ذخیرهسازی."</string>
@@ -1044,7 +1044,7 @@
<string name="ext_media_unmountable_notification_message" msgid="1586311304430052169">"<xliff:g id="NAME">%s</xliff:g> خراب است. برای اصلاح لمس کنید."</string>
<string name="ext_media_unsupported_notification_title" msgid="3797642322958803257">"<xliff:g id="NAME">%s</xliff:g> پشتیبانی نشده"</string>
<string name="ext_media_unsupported_notification_message" msgid="8789610369456474891">"این دستگاه از این <xliff:g id="NAME">%s</xliff:g> پشتیبانی نمیکند. برای نصب آن در یک قالب پشتیبانی شده، لمس کنید."</string>
- <string name="ext_media_badremoval_notification_title" msgid="3206248947375505416">"<xliff:g id="NAME">%s</xliff:g> به طور غیرمنتظره جدا شد"</string>
+ <string name="ext_media_badremoval_notification_title" msgid="3206248947375505416">"<xliff:g id="NAME">%s</xliff:g> بهطور غیرمنتظره جدا شد"</string>
<string name="ext_media_badremoval_notification_message" msgid="380176703346946313">"قبل از جدا کردن، برای جلوگیری از از دست رفتن اطلاعات، ارتباط <xliff:g id="NAME">%s</xliff:g> را قطع کنید."</string>
<string name="ext_media_nomedia_notification_title" msgid="1704840188641749091">"<xliff:g id="NAME">%s</xliff:g> جدا شده است"</string>
<string name="ext_media_nomedia_notification_message" msgid="6471542972147056586">"<xliff:g id="NAME">%s</xliff:g> جدا شد؛ رسانه جدیدی وارد کنید"</string>
diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml
index 368b8d2..e7be0a1 100644
--- a/core/res/res/values-fi/strings.xml
+++ b/core/res/res/values-fi/strings.xml
@@ -713,6 +713,7 @@
<string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"Solu lisätty"</string>
<string name="lockscreen_access_pattern_cell_added_verbose" msgid="7264580781744026939">"Solu <xliff:g id="CELL_INDEX">%1$s</xliff:g> lisätty"</string>
<string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"Kuvio valmis"</string>
+ <string name="lockscreen_access_pattern_area" msgid="400813207572953209">"Kuvioalue."</string>
<string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. Widget %2$d/%3$d."</string>
<string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"Lisää widget."</string>
<string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"Tyhjä"</string>
@@ -897,8 +898,7 @@
<string name="aerr_title" msgid="1905800560317137752"></string>
<string name="aerr_application" msgid="932628488013092776">"<xliff:g id="APPLICATION">%1$s</xliff:g> on pysähtynyt."</string>
<string name="aerr_process" msgid="4507058997035697579">"Prosessi <xliff:g id="PROCESS">%1$s</xliff:g> on pysähtynyt."</string>
- <!-- no translation found for aerr_process_silence (4226685530196000222) -->
- <skip />
+ <string name="aerr_process_silence" msgid="4226685530196000222">"Silencen kaatumiset prosessista <xliff:g id="PROCESS">%1$s</xliff:g> uudelleenkäynnistykseen asti."</string>
<string name="anr_title" msgid="4351948481459135709"></string>
<string name="anr_activity_application" msgid="1904477189057199066">"<xliff:g id="APPLICATION">%2$s</xliff:g> ei vastaa.\n\nHaluatko sulkea sen?"</string>
<string name="anr_activity_process" msgid="5776209883299089767">"Toiminto <xliff:g id="ACTIVITY">%1$s</xliff:g> ei vastaa.\n\nHaluatko sulkea sen?"</string>
diff --git a/core/res/res/values-fr-rCA/strings.xml b/core/res/res/values-fr-rCA/strings.xml
index eaf6162..18c52b1 100644
--- a/core/res/res/values-fr-rCA/strings.xml
+++ b/core/res/res/values-fr-rCA/strings.xml
@@ -434,8 +434,7 @@
<string name="fingerprint_name_template" msgid="5870957565512716938">"Doigt <xliff:g id="FINGERID">%d</xliff:g>"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
- <!-- no translation found for fingerprint_icon_content_description (2340202869968465936) -->
- <skip />
+ <string name="fingerprint_icon_content_description" msgid="2340202869968465936">"Icône d\'empreinte digitale"</string>
<string name="permlab_readSyncSettings" msgid="6201810008230503052">"lire les paramètres de synchronisation"</string>
<string name="permdesc_readSyncSettings" msgid="2706745674569678644">"Permet à l\'application d\'accéder aux paramètres de synchronisation d\'un compte. Par exemple, cette autorisation peut permettre de déterminer si l\'application Contacts est synchronisée avec un compte ou non."</string>
<string name="permlab_writeSyncSettings" msgid="5408694875793945314">"activer ou désactiver la synchronisation"</string>
@@ -714,6 +713,7 @@
<string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"Cellule ajoutée."</string>
<string name="lockscreen_access_pattern_cell_added_verbose" msgid="7264580781744026939">"Cellule <xliff:g id="CELL_INDEX">%1$s</xliff:g> ajoutée"</string>
<string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"Schéma terminé."</string>
+ <string name="lockscreen_access_pattern_area" msgid="400813207572953209">"Zone du motif"</string>
<string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. Widget %2$d sur %3$d."</string>
<string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"Ajouter un widget"</string>
<string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"Vide"</string>
@@ -898,8 +898,7 @@
<string name="aerr_title" msgid="1905800560317137752"></string>
<string name="aerr_application" msgid="932628488013092776">"L\'application \"<xliff:g id="APPLICATION">%1$s</xliff:g>\" s\'est arrêtée."</string>
<string name="aerr_process" msgid="4507058997035697579">"Le processus <xliff:g id="PROCESS">%1$s</xliff:g> s\'est interrompu."</string>
- <!-- no translation found for aerr_process_silence (4226685530196000222) -->
- <skip />
+ <string name="aerr_process_silence" msgid="4226685530196000222">"Plantage de Silence lors du processus « <xliff:g id="PROCESS">%1$s</xliff:g> » avant le redémarrage"</string>
<string name="anr_title" msgid="4351948481459135709"></string>
<string name="anr_activity_application" msgid="1904477189057199066">"L\'application <xliff:g id="APPLICATION">%2$s</xliff:g> ne répond pas.\n\nVoulez-vous quitter?"</string>
<string name="anr_activity_process" msgid="5776209883299089767">"L\'activité <xliff:g id="ACTIVITY">%1$s</xliff:g> ne répond pas.\n\nVoulez-vous quitter?"</string>
diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml
index cab9099..e2c94e4 100644
--- a/core/res/res/values-fr/strings.xml
+++ b/core/res/res/values-fr/strings.xml
@@ -713,6 +713,7 @@
<string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"Cellule ajoutée."</string>
<string name="lockscreen_access_pattern_cell_added_verbose" msgid="7264580781744026939">"Le point <xliff:g id="CELL_INDEX">%1$s</xliff:g> a bien été ajouté."</string>
<string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"Schéma terminé."</string>
+ <string name="lockscreen_access_pattern_area" msgid="400813207572953209">"Zone du schéma"</string>
<string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. Widget %2$d sur %3$d."</string>
<string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"Ajouter un widget"</string>
<string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"Vide"</string>
@@ -897,8 +898,7 @@
<string name="aerr_title" msgid="1905800560317137752"></string>
<string name="aerr_application" msgid="932628488013092776">"\"<xliff:g id="APPLICATION">%1$s</xliff:g>\" s\'est arrêté."</string>
<string name="aerr_process" msgid="4507058997035697579">"Le processus <xliff:g id="PROCESS">%1$s</xliff:g> s\'est interrompu."</string>
- <!-- no translation found for aerr_process_silence (4226685530196000222) -->
- <skip />
+ <string name="aerr_process_silence" msgid="4226685530196000222">"Suspendre l\'affichage des informations de plantage de <xliff:g id="PROCESS">%1$s</xliff:g> jusqu\'au redémarrage"</string>
<string name="anr_title" msgid="4351948481459135709"></string>
<string name="anr_activity_application" msgid="1904477189057199066">"L\'application <xliff:g id="APPLICATION">%2$s</xliff:g> ne répond pas.\n\nVoulez-vous quitter ?"</string>
<string name="anr_activity_process" msgid="5776209883299089767">"L\'activité <xliff:g id="ACTIVITY">%1$s</xliff:g> ne répond pas.\n\nVoulez-vous quitter ?"</string>
diff --git a/core/res/res/values-gl-rES/strings.xml b/core/res/res/values-gl-rES/strings.xml
index 4f20a7a..82d8452 100644
--- a/core/res/res/values-gl-rES/strings.xml
+++ b/core/res/res/values-gl-rES/strings.xml
@@ -713,6 +713,7 @@
<string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"Engadiuse un móbil"</string>
<string name="lockscreen_access_pattern_cell_added_verbose" msgid="7264580781744026939">"Engadiuse a cela <xliff:g id="CELL_INDEX">%1$s</xliff:g>"</string>
<string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"Completouse o padrón"</string>
+ <string name="lockscreen_access_pattern_area" msgid="400813207572953209">"Zona do padrón"</string>
<string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. Widget %2$d de %3$d."</string>
<string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"Engadir widget."</string>
<string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"Baleiro"</string>
@@ -897,8 +898,7 @@
<string name="aerr_title" msgid="1905800560317137752"></string>
<string name="aerr_application" msgid="932628488013092776">"Detívose a aplicación <xliff:g id="APPLICATION">%1$s</xliff:g>."</string>
<string name="aerr_process" msgid="4507058997035697579">"Detívose o proceso <xliff:g id="PROCESS">%1$s</xliff:g>."</string>
- <!-- no translation found for aerr_process_silence (4226685530196000222) -->
- <skip />
+ <string name="aerr_process_silence" msgid="4226685530196000222">"O proceso <xliff:g id="PROCESS">%1$s</xliff:g> producirá fallos na aplicación Silence ata que se reinicie."</string>
<string name="anr_title" msgid="4351948481459135709"></string>
<string name="anr_activity_application" msgid="1904477189057199066">"<xliff:g id="APPLICATION">%2$s</xliff:g> non responde.\n\nQueres pechala?"</string>
<string name="anr_activity_process" msgid="5776209883299089767">"A actividade <xliff:g id="ACTIVITY">%1$s</xliff:g> non responde.\n\nQueres pechala?"</string>
@@ -1026,7 +1026,7 @@
<string name="usb_accessory_notification_title" msgid="7848236974087653666">"Conectado a un accesorio USB"</string>
<string name="usb_notification_message" msgid="7347368030849048437">"Toca para ver máis opcións."</string>
<string name="adb_active_notification_title" msgid="6729044778949189918">"Depuración USB conectada"</string>
- <string name="adb_active_notification_message" msgid="1016654627626476142">"Toca para desactivar a depuración de erros de USB."</string>
+ <string name="adb_active_notification_message" msgid="1016654627626476142">"Toca aquí para desactivala"</string>
<string name="select_input_method" msgid="8547250819326693584">"Cambiar teclado"</string>
<string name="configure_input_methods" msgid="4769971288371946846">"Seleccionar teclados"</string>
<string name="show_ime" msgid="9157568568695230830">"Mostra método de entrada"</string>
diff --git a/core/res/res/values-gu-rIN/strings.xml b/core/res/res/values-gu-rIN/strings.xml
index 76ca425..6e2356a 100644
--- a/core/res/res/values-gu-rIN/strings.xml
+++ b/core/res/res/values-gu-rIN/strings.xml
@@ -713,6 +713,7 @@
<string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"કોષ ઉમેર્યો"</string>
<string name="lockscreen_access_pattern_cell_added_verbose" msgid="7264580781744026939">"<xliff:g id="CELL_INDEX">%1$s</xliff:g> કોષ ઉમેર્યો"</string>
<string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"પેટર્ન પૂર્ણ કરી"</string>
+ <string name="lockscreen_access_pattern_area" msgid="400813207572953209">"પેટર્ન ક્ષેત્ર."</string>
<string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. %3$d માંથી %2$d વિજેટ."</string>
<string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"વિજેટ ઉમેરો."</string>
<string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"ખાલી"</string>
@@ -897,8 +898,7 @@
<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>
- <!-- no translation found for aerr_process_silence (4226685530196000222) -->
- <skip />
+ <string name="aerr_process_silence" msgid="4226685530196000222">"રીબૂટ ન કરવામાં આવે ત્યાં સુધી <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>
diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml
index 5c965bd..fd87a65 100644
--- a/core/res/res/values-hi/strings.xml
+++ b/core/res/res/values-hi/strings.xml
@@ -713,6 +713,7 @@
<string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"कक्ष जोड़ा गया"</string>
<string name="lockscreen_access_pattern_cell_added_verbose" msgid="7264580781744026939">"सेल <xliff:g id="CELL_INDEX">%1$s</xliff:g> जोड़ा गया"</string>
<string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"आकार पूरा किया गया"</string>
+ <string name="lockscreen_access_pattern_area" msgid="400813207572953209">"प्रतिमान क्षेत्र."</string>
<string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. %3$d विजेट में से %2$d."</string>
<string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"विजेट जोड़ें"</string>
<string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"खाली"</string>
@@ -876,7 +877,7 @@
<string name="no" msgid="5141531044935541497">"अभी नहीं"</string>
<string name="dialog_alert_title" msgid="2049658708609043103">"ध्यान दें"</string>
<string name="loading" msgid="7933681260296021180">"लोड हो रहे हैं..."</string>
- <string name="capital_on" msgid="1544682755514494298">"चालू"</string>
+ <string name="capital_on" msgid="1544682755514494298">"ऑन"</string>
<string name="capital_off" msgid="6815870386972805832">"बंद"</string>
<string name="whichApplication" msgid="4533185947064773386">"इसका उपयोग करके क्रिया पूर्ण करें"</string>
<string name="whichApplicationNamed" msgid="8260158865936942783">"%1$s का उपयोग करके कार्रवाई पूर्ण करें"</string>
@@ -897,8 +898,7 @@
<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>
- <!-- no translation found for aerr_process_silence (4226685530196000222) -->
- <skip />
+ <string name="aerr_process_silence" msgid="4226685530196000222">"रीबूट होने तक <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>
@@ -1027,7 +1027,7 @@
<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="select_input_method" msgid="8547250819326693584">"कीबोर्ड बदलें"</string>
<string name="configure_input_methods" msgid="4769971288371946846">"कीबोर्ड चुनें"</string>
<string name="show_ime" msgid="9157568568695230830">"इनपुट विधि दिखाएं"</string>
<string name="hardware" msgid="7517821086888990278">"हार्डवेयर"</string>
diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml
index 6f470c6..e224d4c 100644
--- a/core/res/res/values-hr/strings.xml
+++ b/core/res/res/values-hr/strings.xml
@@ -435,8 +435,7 @@
<string name="fingerprint_name_template" msgid="5870957565512716938">"Prst <xliff:g id="FINGERID">%d</xliff:g>"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
- <!-- no translation found for fingerprint_icon_content_description (2340202869968465936) -->
- <skip />
+ <string name="fingerprint_icon_content_description" msgid="2340202869968465936">"Ikona otiska prsta"</string>
<string name="permlab_readSyncSettings" msgid="6201810008230503052">"čitanje postavki sinkronizacije"</string>
<string name="permdesc_readSyncSettings" msgid="2706745674569678644">"Aplikaciji omogućuje čitanje postavki sinkronizacije za račun. Time se, primjerice, može utvrditi je li aplikacija Osobe sinkronizirana s računom."</string>
<string name="permlab_writeSyncSettings" msgid="5408694875793945314">"uključivanje/isključivanje sinkronizacije"</string>
@@ -715,6 +714,7 @@
<string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"Dodan je mobitel"</string>
<string name="lockscreen_access_pattern_cell_added_verbose" msgid="7264580781744026939">"Dodana je ćelija <xliff:g id="CELL_INDEX">%1$s</xliff:g>"</string>
<string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"Uzorak je dovršen"</string>
+ <string name="lockscreen_access_pattern_area" msgid="400813207572953209">"Područje uzorka."</string>
<string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. Widget %2$d od %3$d."</string>
<string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"Dodavanje widgeta."</string>
<string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"Prazno"</string>
@@ -903,8 +903,7 @@
<string name="aerr_title" msgid="1905800560317137752"></string>
<string name="aerr_application" msgid="932628488013092776">"Nažalost, aplikacija <xliff:g id="APPLICATION">%1$s</xliff:g> prekinula je s radom."</string>
<string name="aerr_process" msgid="4507058997035697579">"Nažalost, zaustavljen je proces <xliff:g id="PROCESS">%1$s</xliff:g>."</string>
- <!-- no translation found for aerr_process_silence (4226685530196000222) -->
- <skip />
+ <string name="aerr_process_silence" msgid="4226685530196000222">"Utišavanje se ruši od postupka <xliff:g id="PROCESS">%1$s</xliff:g> do ponovnog pokretanja."</string>
<string name="anr_title" msgid="4351948481459135709"></string>
<string name="anr_activity_application" msgid="1904477189057199066">"Aplikacija <xliff:g id="APPLICATION">%2$s</xliff:g> ne reagira.\n\nŽelite li je zatvoriti?"</string>
<string name="anr_activity_process" msgid="5776209883299089767">"Aktivnost <xliff:g id="ACTIVITY">%1$s</xliff:g> ne reagira.\n\nŽelite li je zatvoriti?"</string>
diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml
index 509b725..1a806a2 100644
--- a/core/res/res/values-hu/strings.xml
+++ b/core/res/res/values-hu/strings.xml
@@ -713,6 +713,7 @@
<string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"Cella hozzáadva"</string>
<string name="lockscreen_access_pattern_cell_added_verbose" msgid="7264580781744026939">"<xliff:g id="CELL_INDEX">%1$s</xliff:g>. pont hozzáadva"</string>
<string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"Minta befejezve"</string>
+ <string name="lockscreen_access_pattern_area" msgid="400813207572953209">"Mintaterület"</string>
<string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. Modul %3$d/%2$d"</string>
<string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"Modul hozzáadása."</string>
<string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"Üres"</string>
@@ -897,8 +898,7 @@
<string name="aerr_title" msgid="1905800560317137752"></string>
<string name="aerr_application" msgid="932628488013092776">"A(z) <xliff:g id="APPLICATION">%1$s</xliff:g> alkalmazás sajnos leállt."</string>
<string name="aerr_process" msgid="4507058997035697579">"Sajnos a <xliff:g id="PROCESS">%1$s</xliff:g> alkalmazás leállt."</string>
- <!-- no translation found for aerr_process_silence (4226685530196000222) -->
- <skip />
+ <string name="aerr_process_silence" msgid="4226685530196000222">"A(z) <xliff:g id="PROCESS">%1$s</xliff:g> összeomlásainak elnémítása az újraindításig."</string>
<string name="anr_title" msgid="4351948481459135709"></string>
<string name="anr_activity_application" msgid="1904477189057199066">"A(z) <xliff:g id="APPLICATION">%2$s</xliff:g> nem válaszol.\n\nSzeretné bezárni?"</string>
<string name="anr_activity_process" msgid="5776209883299089767">"A(z) <xliff:g id="ACTIVITY">%1$s</xliff:g> tevékenység nem válaszol.\n\nSzeretné bezárni?"</string>
diff --git a/core/res/res/values-hy-rAM/strings.xml b/core/res/res/values-hy-rAM/strings.xml
index 83dfdcb..6543a99 100644
--- a/core/res/res/values-hy-rAM/strings.xml
+++ b/core/res/res/values-hy-rAM/strings.xml
@@ -434,8 +434,7 @@
<string name="fingerprint_name_template" msgid="5870957565512716938">"Մատնահետք <xliff:g id="FINGERID">%d</xliff:g>"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
- <!-- no translation found for fingerprint_icon_content_description (2340202869968465936) -->
- <skip />
+ <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="permlab_writeSyncSettings" msgid="5408694875793945314">"համաժամեցումը փոխարկել միացվածի և անջատվածի"</string>
@@ -714,6 +713,7 @@
<string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"Ավելացվել է վանդակ"</string>
<string name="lockscreen_access_pattern_cell_added_verbose" msgid="7264580781744026939">"<xliff:g id="CELL_INDEX">%1$s</xliff:g> դասիչով բջիջը ավելացված է"</string>
<string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"Սխեմայի հավաքումն ավարտված է"</string>
+ <string name="lockscreen_access_pattern_area" msgid="400813207572953209">"Սխեմայի տարածք:"</string>
<string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. Վիջեթ %2$d of %3$d:"</string>
<string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"Ավելացնել վիջեթ:"</string>
<string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"Դատարկ"</string>
@@ -898,8 +898,7 @@
<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>
- <!-- no translation found for aerr_process_silence (4226685530196000222) -->
- <skip />
+ <string name="aerr_process_silence" msgid="4226685530196000222">"Խափանում է տեղի ունենում <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>
diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml
index d1e843c..9e4647e 100644
--- a/core/res/res/values-in/strings.xml
+++ b/core/res/res/values-in/strings.xml
@@ -713,6 +713,7 @@
<string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"Sel ditambahkan"</string>
<string name="lockscreen_access_pattern_cell_added_verbose" msgid="7264580781744026939">"Sel <xliff:g id="CELL_INDEX">%1$s</xliff:g> ditambahkan"</string>
<string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"Pola selesai"</string>
+ <string name="lockscreen_access_pattern_area" msgid="400813207572953209">"Area pola."</string>
<string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. Widget %2$d dari %3$d."</string>
<string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"Tambahkan widget."</string>
<string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"Kosong"</string>
@@ -897,8 +898,7 @@
<string name="aerr_title" msgid="1905800560317137752"></string>
<string name="aerr_application" msgid="932628488013092776">"Sayangnya, <xliff:g id="APPLICATION">%1$s</xliff:g> telah berhenti."</string>
<string name="aerr_process" msgid="4507058997035697579">"Sayangnya, proses <xliff:g id="PROCESS">%1$s</xliff:g> telah berhenti."</string>
- <!-- no translation found for aerr_process_silence (4226685530196000222) -->
- <skip />
+ <string name="aerr_process_silence" msgid="4226685530196000222">"Fitur bisu rusak akibat <xliff:g id="PROCESS">%1$s</xliff:g> hingga boot ulang."</string>
<string name="anr_title" msgid="4351948481459135709"></string>
<string name="anr_activity_application" msgid="1904477189057199066">"<xliff:g id="APPLICATION">%2$s</xliff:g> tidak menanggapi.\n\nAnda ingin menutupnya?"</string>
<string name="anr_activity_process" msgid="5776209883299089767">"Aktivitas <xliff:g id="ACTIVITY">%1$s</xliff:g> tidak menanggapi.\n\nAnda ingin menutupnya?"</string>
diff --git a/core/res/res/values-is-rIS/strings.xml b/core/res/res/values-is-rIS/strings.xml
index d0bcd5c..97f5adf 100644
--- a/core/res/res/values-is-rIS/strings.xml
+++ b/core/res/res/values-is-rIS/strings.xml
@@ -434,8 +434,7 @@
<string name="fingerprint_name_template" msgid="5870957565512716938">"Fingur <xliff:g id="FINGERID">%d</xliff:g>"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
- <!-- no translation found for fingerprint_icon_content_description (2340202869968465936) -->
- <skip />
+ <string name="fingerprint_icon_content_description" msgid="2340202869968465936">"Fingrafaratákn"</string>
<string name="permlab_readSyncSettings" msgid="6201810008230503052">"lesa samstillingar"</string>
<string name="permdesc_readSyncSettings" msgid="2706745674569678644">"Leyfir forriti að lesa kosti samstillingar fyrir reikning. Þetta er til dæmis hægt að nota til að komast að því hvort forritið Fólk er samstillt við reikning."</string>
<string name="permlab_writeSyncSettings" msgid="5408694875793945314">"kveikja og slökkva á samstillingu"</string>
@@ -714,6 +713,7 @@
<string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"Hólfi bætt við"</string>
<string name="lockscreen_access_pattern_cell_added_verbose" msgid="7264580781744026939">"Hólfi <xliff:g id="CELL_INDEX">%1$s</xliff:g> bætt við"</string>
<string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"Mynstur teiknað"</string>
+ <string name="lockscreen_access_pattern_area" msgid="400813207572953209">"Svæði mynsturs."</string>
<string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. Græja %2$d af %3$d."</string>
<string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"Bæta græju við."</string>
<string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"Autt"</string>
@@ -898,8 +898,7 @@
<string name="aerr_title" msgid="1905800560317137752"></string>
<string name="aerr_application" msgid="932628488013092776">"<xliff:g id="APPLICATION">%1$s</xliff:g> lokaðist því miður."</string>
<string name="aerr_process" msgid="4507058997035697579">"Forritið <xliff:g id="PROCESS">%1$s</xliff:g> lokaðist því miður."</string>
- <!-- no translation found for aerr_process_silence (4226685530196000222) -->
- <skip />
+ <string name="aerr_process_silence" msgid="4226685530196000222">"Þagga hrun frá <xliff:g id="PROCESS">%1$s</xliff:g> fram að endurræsingu."</string>
<string name="anr_title" msgid="4351948481459135709"></string>
<string name="anr_activity_application" msgid="1904477189057199066">"<xliff:g id="APPLICATION">%2$s</xliff:g> svarar ekki.\n\nViltu loka því?"</string>
<string name="anr_activity_process" msgid="5776209883299089767">"Aðgerðin <xliff:g id="ACTIVITY">%1$s</xliff:g> svarar ekki.\n\nViltu loka henni?"</string>
diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml
index 0c5dcb5..e9e8864 100644
--- a/core/res/res/values-it/strings.xml
+++ b/core/res/res/values-it/strings.xml
@@ -434,8 +434,7 @@
<string name="fingerprint_name_template" msgid="5870957565512716938">"Dito <xliff:g id="FINGERID">%d</xliff:g>"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
- <!-- no translation found for fingerprint_icon_content_description (2340202869968465936) -->
- <skip />
+ <string name="fingerprint_icon_content_description" msgid="2340202869968465936">"Icona dell\'impronta digitale"</string>
<string name="permlab_readSyncSettings" msgid="6201810008230503052">"lettura impostazioni di sincronizz."</string>
<string name="permdesc_readSyncSettings" msgid="2706745674569678644">"Consente all\'applicazione di leggere le impostazioni di sincronizzazione per un account. Ad esempio, questa autorizzazione può determinare se l\'applicazione Persone è sincronizzata con un account."</string>
<string name="permlab_writeSyncSettings" msgid="5408694875793945314">"attivazione e disattivazione della sincronizzazione"</string>
@@ -714,6 +713,7 @@
<string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"Cella aggiunta"</string>
<string name="lockscreen_access_pattern_cell_added_verbose" msgid="7264580781744026939">"È stata aggiunta la cella <xliff:g id="CELL_INDEX">%1$s</xliff:g>"</string>
<string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"Sequenza completata"</string>
+ <string name="lockscreen_access_pattern_area" msgid="400813207572953209">"Area sequenza."</string>
<string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. Widget %2$d di %3$d."</string>
<string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"Aggiungi widget."</string>
<string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"Vuoto"</string>
@@ -898,8 +898,7 @@
<string name="aerr_title" msgid="1905800560317137752"></string>
<string name="aerr_application" msgid="932628488013092776">"L\'applicazione <xliff:g id="APPLICATION">%1$s</xliff:g> si è bloccata in modo anomalo."</string>
<string name="aerr_process" msgid="4507058997035697579">"Il processo <xliff:g id="PROCESS">%1$s</xliff:g> si è interrotto."</string>
- <!-- no translation found for aerr_process_silence (4226685530196000222) -->
- <skip />
+ <string name="aerr_process_silence" msgid="4226685530196000222">"Arresti anomali di Silence da <xliff:g id="PROCESS">%1$s</xliff:g> fino al riavvio."</string>
<string name="anr_title" msgid="4351948481459135709"></string>
<string name="anr_activity_application" msgid="1904477189057199066">"<xliff:g id="APPLICATION">%2$s</xliff:g> non risponde.\n\nVuoi chiuderla?"</string>
<string name="anr_activity_process" msgid="5776209883299089767">"L\'attività <xliff:g id="ACTIVITY">%1$s</xliff:g> non risponde.\n\nVuoi chiuderla?"</string>
diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml
index ffd65de..e39c52f 100644
--- a/core/res/res/values-iw/strings.xml
+++ b/core/res/res/values-iw/strings.xml
@@ -436,8 +436,7 @@
<string name="fingerprint_name_template" msgid="5870957565512716938">"אצבע <xliff:g id="FINGERID">%d</xliff:g>"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
- <!-- no translation found for fingerprint_icon_content_description (2340202869968465936) -->
- <skip />
+ <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="permlab_writeSyncSettings" msgid="5408694875793945314">"הפעלת וכיבוי סנכרון"</string>
@@ -716,6 +715,7 @@
<string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"התא נוסף"</string>
<string name="lockscreen_access_pattern_cell_added_verbose" msgid="7264580781744026939">"תא <xliff:g id="CELL_INDEX">%1$s</xliff:g> נוסף"</string>
<string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"התבנית הושלמה"</string>
+ <string name="lockscreen_access_pattern_area" msgid="400813207572953209">"אזור ציור קו."</string>
<string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. Widget %2$d מתוך %3$d."</string>
<string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"הוסף Widget."</string>
<string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"ריק"</string>
@@ -908,8 +908,7 @@
<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>
- <!-- no translation found for aerr_process_silence (4226685530196000222) -->
- <skip />
+ <string name="aerr_process_silence" msgid="4226685530196000222">"השתק קריסות מ-<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>
@@ -1040,8 +1039,8 @@
<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="adb_active_notification_title" msgid="6729044778949189918">"ניקוי באגים של USB מחובר"</string>
- <string name="adb_active_notification_message" msgid="1016654627626476142">"גע כדי להשבית ניקוי באגים בהתקן ה-USB."</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>
diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml
index 454ae881..70a248d 100644
--- a/core/res/res/values-ja/strings.xml
+++ b/core/res/res/values-ja/strings.xml
@@ -713,6 +713,7 @@
<string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"セルを追加しました"</string>
<string name="lockscreen_access_pattern_cell_added_verbose" msgid="7264580781744026939">"セル<xliff:g id="CELL_INDEX">%1$s</xliff:g>を追加しました"</string>
<string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"パターンの描画が完了しました"</string>
+ <string name="lockscreen_access_pattern_area" msgid="400813207572953209">"パターンエリアです。"</string>
<string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s。ウィジェット%2$d/%3$d。"</string>
<string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"ウィジェットを追加します。"</string>
<string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"なし"</string>
@@ -897,8 +898,7 @@
<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>
- <!-- no translation found for aerr_process_silence (4226685530196000222) -->
- <skip />
+ <string name="aerr_process_silence" msgid="4226685530196000222">"再起動するまで「<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>
diff --git a/core/res/res/values-ka-rGE/strings.xml b/core/res/res/values-ka-rGE/strings.xml
index 851100d..b45c4fed 100644
--- a/core/res/res/values-ka-rGE/strings.xml
+++ b/core/res/res/values-ka-rGE/strings.xml
@@ -434,8 +434,7 @@
<string name="fingerprint_name_template" msgid="5870957565512716938">"თითი <xliff:g id="FINGERID">%d</xliff:g>"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
- <!-- no translation found for fingerprint_icon_content_description (2340202869968465936) -->
- <skip />
+ <string name="fingerprint_icon_content_description" msgid="2340202869968465936">"თითის ანაბეჭდის ხატულა"</string>
<string name="permlab_readSyncSettings" msgid="6201810008230503052">"სინქრონიზაციის პარამეტრების წაკითხვა"</string>
<string name="permdesc_readSyncSettings" msgid="2706745674569678644">"აპს შეეძლება, წაიკითხოს ანგარიშის სინქრონიზაციის პარამეტრები. მაგალითად, მას შეეძლება განსაზღვროს, არის თუ არა People აპი სინქრონიზებული ანგარიშთან."</string>
<string name="permlab_writeSyncSettings" msgid="5408694875793945314">"სინქრონიზაციის ჩართვა და გამორთვა"</string>
@@ -714,6 +713,7 @@
<string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"უჯრედი დაემატა."</string>
<string name="lockscreen_access_pattern_cell_added_verbose" msgid="7264580781744026939">"უჯრედი <xliff:g id="CELL_INDEX">%1$s</xliff:g> დამატებულია"</string>
<string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"ნიმუშის შექმნა დასრულებულია"</string>
+ <string name="lockscreen_access_pattern_area" msgid="400813207572953209">"ნიმუშების სივრცე."</string>
<string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. ვიჯეტი %2$d of %3$d."</string>
<string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"ვიჯეტის დამატება"</string>
<string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"ცარიელი"</string>
@@ -898,8 +898,7 @@
<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>
- <!-- no translation found for aerr_process_silence (4226685530196000222) -->
- <skip />
+ <string name="aerr_process_silence" msgid="4226685530196000222">"აპლიკაციის ჩუმი ავარიული გათიშვები <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>
diff --git a/core/res/res/values-kk-rKZ/strings.xml b/core/res/res/values-kk-rKZ/strings.xml
index 6fb9e01..e50e17b 100644
--- a/core/res/res/values-kk-rKZ/strings.xml
+++ b/core/res/res/values-kk-rKZ/strings.xml
@@ -713,6 +713,7 @@
<string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"Тор қосылды"</string>
<string name="lockscreen_access_pattern_cell_added_verbose" msgid="7264580781744026939">"<xliff:g id="CELL_INDEX">%1$s</xliff:g> ұяшығы қосылды"</string>
<string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"Кескін аяқталды"</string>
+ <string name="lockscreen_access_pattern_area" msgid="400813207572953209">"Өрнек аумағы."</string>
<string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. %2$d виджет, барлығы %3$d."</string>
<string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"Виджет қосу."</string>
<string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"Бос"</string>
@@ -897,8 +898,7 @@
<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>
- <!-- no translation found for aerr_process_silence (4226685530196000222) -->
- <skip />
+ <string name="aerr_process_silence" msgid="4226685530196000222">"Қайта жүктеуге дейін <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>
diff --git a/core/res/res/values-km-rKH/strings.xml b/core/res/res/values-km-rKH/strings.xml
index 2b57759..4c85e93 100644
--- a/core/res/res/values-km-rKH/strings.xml
+++ b/core/res/res/values-km-rKH/strings.xml
@@ -713,6 +713,7 @@
<string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"បានបន្ថែមក្រឡា"</string>
<string name="lockscreen_access_pattern_cell_added_verbose" msgid="7264580781744026939">"បានបន្ថែមក្រឡាទី <xliff:g id="CELL_INDEX">%1$s</xliff:g>"</string>
<string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"បានបញ្ចប់លំនាំ"</string>
+ <string name="lockscreen_access_pattern_area" msgid="400813207572953209">"ផ្ទៃលំនាំ"</string>
<string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. ធាតុក្រាហ្វិក %2$d នៃ %3$d ។"</string>
<string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"បន្ថែមធាតុក្រាហ្វិក។"</string>
<string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"ទទេ"</string>
@@ -899,8 +900,7 @@
<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>
- <!-- no translation found for aerr_process_silence (4226685530196000222) -->
- <skip />
+ <string name="aerr_process_silence" msgid="4226685530196000222">"ការគាំងស្ងាត់ៗពី <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>
diff --git a/core/res/res/values-kn-rIN/strings.xml b/core/res/res/values-kn-rIN/strings.xml
index 14c8855..bde8e04 100644
--- a/core/res/res/values-kn-rIN/strings.xml
+++ b/core/res/res/values-kn-rIN/strings.xml
@@ -713,6 +713,7 @@
<string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"ಸೆಲ್ ಸೇರಿಸಲಾಗಿದೆ"</string>
<string name="lockscreen_access_pattern_cell_added_verbose" msgid="7264580781744026939">"<xliff:g id="CELL_INDEX">%1$s</xliff:g> ಸೆಲ್ ಸೇರಿಸಲಾಗಿದೆ"</string>
<string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"ಪ್ಯಾಟರ್ನ್ ಪೂರ್ಣಗೊಂಡಿದೆ"</string>
+ <string name="lockscreen_access_pattern_area" msgid="400813207572953209">"ಪ್ಯಾಟರ್ನ್ ಪ್ರದೇಶ."</string>
<string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s.%3$d ರಲ್ಲಿ %2$d ವಿಜೆಟ್."</string>
<string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"ವಿಜೆಟ್ ಸೇರಿಸು."</string>
<string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"ಖಾಲಿ"</string>
@@ -897,8 +898,7 @@
<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>
- <!-- no translation found for aerr_process_silence (4226685530196000222) -->
- <skip />
+ <string name="aerr_process_silence" msgid="4226685530196000222">"ರೀಬೂಟ್ ಮಾಡುವವರೆಗೆ <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>
diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml
index 19a5dac..d30fb4a 100644
--- a/core/res/res/values-ko/strings.xml
+++ b/core/res/res/values-ko/strings.xml
@@ -713,6 +713,7 @@
<string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"셀 추가됨"</string>
<string name="lockscreen_access_pattern_cell_added_verbose" msgid="7264580781744026939">"셀 <xliff:g id="CELL_INDEX">%1$s</xliff:g> 추가됨"</string>
<string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"패턴 완료"</string>
+ <string name="lockscreen_access_pattern_area" msgid="400813207572953209">"패턴을 그리는 부분입니다."</string>
<string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. %3$d의 위젯 %2$d."</string>
<string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"위젯 추가"</string>
<string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"비어 있음"</string>
@@ -897,8 +898,7 @@
<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>
- <!-- no translation found for aerr_process_silence (4226685530196000222) -->
- <skip />
+ <string name="aerr_process_silence" msgid="4226685530196000222">"재부팅할 때까지 <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>
diff --git a/core/res/res/values-ky-rKG/strings.xml b/core/res/res/values-ky-rKG/strings.xml
index 1b6e428d..c410d19 100644
--- a/core/res/res/values-ky-rKG/strings.xml
+++ b/core/res/res/values-ky-rKG/strings.xml
@@ -20,18 +20,12 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <!-- no translation found for byteShort (8340973892742019101) -->
- <skip />
- <!-- no translation found for kilobyteShort (5973789783504771878) -->
- <skip />
- <!-- no translation found for megabyteShort (6355851576770428922) -->
- <skip />
- <!-- no translation found for gigabyteShort (3259882455212193214) -->
- <skip />
- <!-- no translation found for terabyteShort (231613018159186962) -->
- <skip />
- <!-- no translation found for petabyteShort (5637816680144990219) -->
- <skip />
+ <string name="byteShort" msgid="8340973892742019101">"Б"</string>
+ <string name="kilobyteShort" msgid="5973789783504771878">"Кб"</string>
+ <string name="megabyteShort" msgid="6355851576770428922">"Мб"</string>
+ <string name="gigabyteShort" msgid="3259882455212193214">"Гб"</string>
+ <string name="terabyteShort" msgid="231613018159186962">"ТБ"</string>
+ <string name="petabyteShort" msgid="5637816680144990219">"ПБ"</string>
<string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
<string name="durationDays" msgid="6652371460511178259">"<xliff:g id="DAYS">%1$d</xliff:g> күн"</string>
<string name="durationDayHours" msgid="2713107458736744435">"<xliff:g id="DAYS">%1$d</xliff:g> күн <xliff:g id="HOURS">%2$d</xliff:g> с"</string>
@@ -46,42 +40,26 @@
<string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> сек"</string>
<string name="durationSecond" msgid="985669622276420331">"<xliff:g id="SECONDS">%1$d</xliff:g> сек"</string>
<string name="untitled" msgid="4638956954852782576">"<Баш аты жок>"</string>
- <!-- no translation found for emptyPhoneNumber (7694063042079676517) -->
- <skip />
+ <string name="emptyPhoneNumber" msgid="7694063042079676517">"(Телефон номери жок)"</string>
<string name="unknownName" msgid="6867811765370350269">"Белгисиз"</string>
- <!-- no translation found for defaultVoiceMailAlphaTag (2660020990097733077) -->
- <skip />
- <!-- no translation found for defaultMsisdnAlphaTag (2850889754919584674) -->
- <skip />
- <!-- no translation found for mmiError (5154499457739052907) -->
- <skip />
- <!-- no translation found for mmiFdnError (5224398216385316471) -->
- <skip />
- <!-- no translation found for serviceEnabled (8147278346414714315) -->
- <skip />
- <!-- no translation found for serviceEnabledFor (6856228140453471041) -->
- <skip />
- <!-- no translation found for serviceDisabled (1937553226592516411) -->
- <skip />
- <!-- no translation found for serviceRegistered (6275019082598102493) -->
- <skip />
- <!-- no translation found for serviceErased (1288584695297200972) -->
- <skip />
- <!-- no translation found for passwordIncorrect (7612208839450128715) -->
- <skip />
- <!-- no translation found for mmiComplete (8232527495411698359) -->
- <skip />
+ <string name="defaultVoiceMailAlphaTag" msgid="2660020990097733077">"Үн почтасы"</string>
+ <string name="defaultMsisdnAlphaTag" msgid="2850889754919584674">"MSISDN1"</string>
+ <string name="mmiError" msgid="5154499457739052907">"Туташууда көйгөй чыкты же MMI коду жараксыз."</string>
+ <string name="mmiFdnError" msgid="5224398216385316471">"Иш-аракет туруктуу терүү номерлери менен гана чектелет."</string>
+ <string name="serviceEnabled" msgid="8147278346414714315">"Кызмат иштетилди."</string>
+ <string name="serviceEnabledFor" msgid="6856228140453471041">"Кызмат төмөнкү үчүн иштетилди:"</string>
+ <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="mmiComplete" msgid="8232527495411698359">"MMI аткарылды."</string>
<string name="badPin" msgid="9015277645546710014">"Терилген эски PIN код туура эмес."</string>
<string name="badPuk" msgid="5487257647081132201">"Терилген PUK код туура эмес."</string>
<string name="mismatchPin" msgid="609379054496863419">"Терилген PIN\'дер дал келбейт."</string>
- <!-- no translation found for invalidPin (3850018445187475377) -->
- <skip />
- <!-- no translation found for invalidPuk (8761456210898036513) -->
- <skip />
- <!-- no translation found for needPuk (919668385956251611) -->
- <skip />
- <!-- no translation found for needPuk2 (4526033371987193070) -->
- <skip />
+ <string name="invalidPin" msgid="3850018445187475377">"Узундугу 4төн 8ге чейинки сандан турган PIN-кодду териңиз."</string>
+ <string name="invalidPuk" msgid="8761456210898036513">"Узундугу 8 же көбүрөөк сандан турган PUK-кодду териңиз."</string>
+ <string name="needPuk" msgid="919668385956251611">"SIM-картаңыз PUK менен кулпуланган. Кулпусун ачуу үчүн PUK-кодду териңиз."</string>
+ <string name="needPuk2" msgid="4526033371987193070">"SIM-картаны бөгөттөн чыгаруу үчүн PUK2 кодун териңиз."</string>
<string name="enablePin" msgid="209412020907207950">"Оңунан чыкпады, SIM/RUIM бөгөттөөсүн жандырыңыз."</string>
<plurals name="pinpuk_attempts" formatted="false" msgid="1251012001539225582">
<item quantity="other">Сизде SIM кулпуланганга чейин <xliff:g id="NUMBER_1">%d</xliff:g> аракет калды.</item>
@@ -89,108 +67,62 @@
</plurals>
<string name="imei" msgid="2625429890869005782">"IMEI"</string>
<string name="meid" msgid="4841221237681254195">"MEID"</string>
- <!-- no translation found for ClipMmi (6952821216480289285) -->
- <skip />
- <!-- no translation found for ClirMmi (7784673673446833091) -->
- <skip />
+ <string name="ClipMmi" msgid="6952821216480289285">"Кирүүчү номурду аныктоо"</string>
+ <string name="ClirMmi" msgid="7784673673446833091">"Чыгуучу номурду аныктоо"</string>
<string name="ColpMmi" msgid="3065121483740183974">"Туташкан линия ID-си"</string>
<string name="ColrMmi" msgid="4996540314421889589">"Туташкан линия ID-син Чектөө"</string>
- <!-- no translation found for CfMmi (5123218989141573515) -->
- <skip />
- <!-- no translation found for CwMmi (9129678056795016867) -->
- <skip />
- <!-- no translation found for BaMmi (455193067926770581) -->
- <skip />
- <!-- no translation found for PwdMmi (7043715687905254199) -->
- <skip />
- <!-- no translation found for PinMmi (3113117780361190304) -->
- <skip />
- <!-- no translation found for CnipMmi (3110534680557857162) -->
- <skip />
- <!-- no translation found for CnirMmi (3062102121430548731) -->
- <skip />
- <!-- no translation found for ThreeWCMmi (9051047170321190368) -->
- <skip />
- <!-- no translation found for RuacMmi (7827887459138308886) -->
- <skip />
- <!-- no translation found for CndMmi (3116446237081575808) -->
- <skip />
- <!-- no translation found for DndMmi (1265478932418334331) -->
- <skip />
- <!-- no translation found for CLIRDefaultOnNextCallOn (429415409145781923) -->
- <skip />
- <!-- no translation found for CLIRDefaultOnNextCallOff (3092918006077864624) -->
- <skip />
- <!-- no translation found for CLIRDefaultOffNextCallOn (6179425182856418465) -->
- <skip />
- <!-- no translation found for CLIRDefaultOffNextCallOff (2567998633124408552) -->
- <skip />
- <!-- no translation found for serviceNotProvisioned (8614830180508686666) -->
- <skip />
+ <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="PinMmi" msgid="3113117780361190304">"PIN өзгөртүү"</string>
+ <string name="CnipMmi" msgid="3110534680557857162">"Чалуучу номер бар"</string>
+ <string name="CnirMmi" msgid="3062102121430548731">"Чалуучу номер чектелген"</string>
+ <string name="ThreeWCMmi" msgid="9051047170321190368">"Үч тараптуу чалуу"</string>
+ <string name="RuacMmi" msgid="7827887459138308886">"Жагымсыз, тажатма чалууларды четке кагуу"</string>
+ <string name="CndMmi" msgid="3116446237081575808">"Чалуучу номерди жеткирүү"</string>
+ <string name="DndMmi" msgid="1265478932418334331">"Тынчымды алба"</string>
+ <string name="CLIRDefaultOnNextCallOn" msgid="429415409145781923">"Номурду аныктоонун демейки абалы \"чектелген\" деп коюлган. Кийинки чалуу: Чектелген"</string>
+ <string name="CLIRDefaultOnNextCallOff" msgid="3092918006077864624">"Номурду аныктоонун демейки абалы \"чектелген\" деп коюлган. Кийинки чалуу: Чектелбейт"</string>
+ <string name="CLIRDefaultOffNextCallOn" msgid="6179425182856418465">"Номурду аныктоонун демейки абалы \"чектелбейт\" деп коюлган. Кийинки чалуу: Чектелген"</string>
+ <string name="CLIRDefaultOffNextCallOff" msgid="2567998633124408552">"Номурду аныктоонун демейки абалы \"чектелбейт\" деп коюлган. Кийинки чалуу: Чектелбейт"</string>
+ <string name="serviceNotProvisioned" msgid="8614830180508686666">"Кызмат камсыздалган эмес."</string>
<string name="CLIRPermanent" msgid="3377371145926835671">"Чалуучунун далдаштырма дайындары жөндөөлөрүн өзгөртө албайсыз."</string>
- <!-- no translation found for RestrictedChangedTitle (5592189398956187498) -->
- <skip />
- <!-- no translation found for RestrictedOnData (8653794784690065540) -->
- <skip />
- <!-- no translation found for RestrictedOnEmergency (6581163779072833665) -->
- <skip />
- <!-- no translation found for RestrictedOnNormal (4953867011389750673) -->
- <skip />
+ <string name="RestrictedChangedTitle" msgid="5592189398956187498">"Чектелген мүмкүнчүлүк өзгөртүлдү"</string>
+ <string name="RestrictedOnData" msgid="8653794784690065540">"Мобилдик Интернет бөгөттөлгөн."</string>
+ <string name="RestrictedOnEmergency" msgid="6581163779072833665">"Өзгөчө кырдаал кызматы бөгөттөлгөн."</string>
+ <string name="RestrictedOnNormal" msgid="4953867011389750673">"Үн кызматы бөгөттөлгөн."</string>
<string name="RestrictedOnAllVoice" msgid="3396963652108151260">"Бардык үн кызматтары бөгөттөлдү."</string>
- <!-- no translation found for RestrictedOnSms (8314352327461638897) -->
- <skip />
+ <string name="RestrictedOnSms" msgid="8314352327461638897">"SMS кызматы бөгөттөлгөн."</string>
<string name="RestrictedOnVoiceData" msgid="996636487106171320">"Үн/берилиштер кызматтары бөгөттөлдү."</string>
- <!-- no translation found for RestrictedOnVoiceSms (1888588152792023873) -->
- <skip />
+ <string name="RestrictedOnVoiceSms" msgid="1888588152792023873">"Үн/SMS кызматтары бөгөттөлгөн."</string>
<string name="RestrictedOnAll" msgid="5643028264466092821">"Бардык үн/берилиштер/SMS кызматтары бөгөттөлдү."</string>
<string name="peerTtyModeFull" msgid="6165351790010341421">"Peer TTY режимин FULL кылууну суранды"</string>
<string name="peerTtyModeHco" msgid="5728602160669216784">"Peer TTY режимин HCO кылууну суранды"</string>
<string name="peerTtyModeVco" msgid="1742404978686538049">"Peer TTY режимин VCO кылууну суранды"</string>
<string name="peerTtyModeOff" msgid="3280819717850602205">"Peer TTY режимин OFF кылууну суранды"</string>
- <!-- no translation found for serviceClassVoice (1258393812335258019) -->
- <skip />
- <!-- no translation found for serviceClassData (872456782077937893) -->
- <skip />
- <!-- no translation found for serviceClassFAX (5566624998840486475) -->
- <skip />
- <!-- no translation found for serviceClassSMS (2015460373701527489) -->
- <skip />
- <!-- no translation found for serviceClassDataAsync (4523454783498551468) -->
- <skip />
- <!-- no translation found for serviceClassDataSync (7530000519646054776) -->
- <skip />
- <!-- no translation found for serviceClassPacket (6991006557993423453) -->
- <skip />
- <!-- no translation found for serviceClassPAD (3235259085648271037) -->
- <skip />
- <!-- no translation found for roamingText0 (7170335472198694945) -->
- <skip />
- <!-- no translation found for roamingText1 (5314861519752538922) -->
- <skip />
- <!-- no translation found for roamingText2 (8969929049081268115) -->
- <skip />
- <!-- no translation found for roamingText3 (5148255027043943317) -->
- <skip />
- <!-- no translation found for roamingText4 (8808456682550796530) -->
- <skip />
- <!-- no translation found for roamingText5 (7604063252850354350) -->
- <skip />
- <!-- no translation found for roamingText6 (2059440825782871513) -->
- <skip />
- <!-- no translation found for roamingText7 (7112078724097233605) -->
- <skip />
- <!-- no translation found for roamingText8 (5989569778604089291) -->
- <skip />
- <!-- no translation found for roamingText9 (7969296811355152491) -->
- <skip />
- <!-- no translation found for roamingText10 (3992906999815316417) -->
- <skip />
- <!-- no translation found for roamingText11 (4154476854426920970) -->
- <skip />
- <!-- no translation found for roamingText12 (1189071119992726320) -->
- <skip />
- <!-- no translation found for roamingTextSearching (8360141885972279963) -->
- <skip />
+ <string name="serviceClassVoice" msgid="1258393812335258019">"Үн"</string>
+ <string name="serviceClassData" msgid="872456782077937893">"Дайындар"</string>
+ <string name="serviceClassFAX" msgid="5566624998840486475">"ФАКС"</string>
+ <string name="serviceClassSMS" msgid="2015460373701527489">"SMS"</string>
+ <string name="serviceClassDataAsync" msgid="4523454783498551468">"Шайкештирилбеген"</string>
+ <string name="serviceClassDataSync" msgid="7530000519646054776">"Шайкештирилген"</string>
+ <string name="serviceClassPacket" msgid="6991006557993423453">"Таңгак"</string>
+ <string name="serviceClassPAD" msgid="3235259085648271037">"PAD"</string>
+ <string name="roamingText0" msgid="7170335472198694945">"Роуминг индикатору күйгүзүлгөн"</string>
+ <string name="roamingText1" msgid="5314861519752538922">"Роуминг индикатору өчүрүлгөн"</string>
+ <string name="roamingText2" msgid="8969929049081268115">"Роуминг индикатору жаркылдап жатат"</string>
+ <string name="roamingText3" msgid="5148255027043943317">"Айлана-тегеректе жок"</string>
+ <string name="roamingText4" msgid="8808456682550796530">"Имарат сыртында"</string>
+ <string name="roamingText5" msgid="7604063252850354350">"Роуминг – Тандалган тутум"</string>
+ <string name="roamingText6" msgid="2059440825782871513">"Роуминг – Жеткиликтүү тутум"</string>
+ <string name="roamingText7" msgid="7112078724097233605">"Роуминг – Бирикме өнөктөшү"</string>
+ <string name="roamingText8" msgid="5989569778604089291">"Роуминг – Негизги өнөктөш"</string>
+ <string name="roamingText9" msgid="7969296811355152491">"Роуминг – Толук кызмат функциясы"</string>
+ <string name="roamingText10" msgid="3992906999815316417">"Роуминг – Жарым-жартылай кызмат функциясы"</string>
+ <string name="roamingText11" msgid="4154476854426920970">"Роуминг баннери күйгүзүлгөн"</string>
+ <string name="roamingText12" msgid="1189071119992726320">"Роуминг баннери өчүрүлгөн"</string>
+ <string name="roamingTextSearching" msgid="8360141885972279963">"Кызмат изделүүдө"</string>
<string name="wfcRegErrorTitle" msgid="2301376280632110664">"Wi-Fi Чалуу"</string>
<string-array name="wfcOperatorErrorAlertMessages">
</string-array>
@@ -202,48 +134,33 @@
<string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Wi-Fi тандалган"</string>
<string name="wfc_mode_cellular_preferred_summary" msgid="5920549484600758786">"Уюлдук тармак тандалган"</string>
<string name="wfc_mode_wifi_only_summary" msgid="2379919155237869320">"Wi-Fi гана"</string>
- <!-- no translation found for cfTemplateNotForwarded (1683685883841272560) -->
- <skip />
- <!-- no translation found for cfTemplateForwarded (1302922117498590521) -->
- <skip />
- <!-- no translation found for cfTemplateForwardedTime (9206251736527085256) -->
- <skip />
- <!-- no translation found for cfTemplateRegistered (5073237827620166285) -->
- <skip />
- <!-- no translation found for cfTemplateRegisteredTime (6781621964320635172) -->
- <skip />
- <!-- no translation found for fcComplete (3118848230966886575) -->
- <skip />
- <!-- no translation found for fcError (3327560126588500777) -->
- <skip />
- <!-- no translation found for httpErrorOk (1191919378083472204) -->
- <skip />
+ <string name="cfTemplateNotForwarded" msgid="1683685883841272560">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: Багытталган эмес"</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> <xliff:g id="TIME_DELAY">{2}</xliff:g> секунддан кийин"</string>
+ <string name="cfTemplateRegistered" msgid="5073237827620166285">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: Багытталган эмес"</string>
+ <string name="cfTemplateRegisteredTime" msgid="6781621964320635172">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: Багытталган эмес"</string>
+ <string name="fcComplete" msgid="3118848230966886575">"Функция коду аткарылды."</string>
+ <string name="fcError" msgid="3327560126588500777">"Туташууда көйгөй чыкты же функция коду жараксыз."</string>
+ <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="httpErrorAuth" msgid="1435065629438044534">"Аутентификация кыйрады."</string>
- <!-- no translation found for httpErrorProxyAuth (1788207010559081331) -->
- <skip />
+ <string name="httpErrorProxyAuth" msgid="1788207010559081331">"Прокси сервер аркылуу аныктыгын текшерүү ийгиликсиз аяктады."</string>
<string name="httpErrorConnect" msgid="8714273236364640549">"Сервер менен байланышуу мүмкүн болбоду."</string>
<string name="httpErrorIO" msgid="2340558197489302188">"Сервер менен байланыш түзүү мүмкүн болбоду. Кийинчерээк кайрадан аракеттениңиз."</string>
- <!-- no translation found for httpErrorTimeout (4743403703762883954) -->
- <skip />
- <!-- no translation found for httpErrorRedirectLoop (8679596090392779516) -->
- <skip />
+ <string name="httpErrorTimeout" msgid="4743403703762883954">"Серверге туташуу убакыты кечиктирилди."</string>
+ <string name="httpErrorRedirectLoop" msgid="8679596090392779516">"Баракта серверге багыттоолор өтө көп."</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>
<string name="httpErrorFileNotFound" msgid="6203856612042655084">"Талап кылынган файлга жетүү мүмкүн болбоду."</string>
- <!-- no translation found for httpErrorTooManyRequests (1235396927087188253) -->
- <skip />
+ <string name="httpErrorTooManyRequests" msgid="1235396927087188253">"Өтө көп талаптар иштетилүүдө. Кайта аракеттениңиз."</string>
<string name="notification_title" msgid="8967710025036163822">"<xliff:g id="ACCOUNT">%1$s</xliff:g> менен кирүүдө ката кетти"</string>
- <!-- no translation found for contentServiceSync (8353523060269335667) -->
- <skip />
- <!-- no translation found for contentServiceSyncNotificationTitle (397743349191901458) -->
- <skip />
- <!-- no translation found for contentServiceTooManyDeletesNotificationDesc (8100981435080696431) -->
- <skip />
+ <string name="contentServiceSync" msgid="8353523060269335667">"Шайкештирүү"</string>
+ <string name="contentServiceSyncNotificationTitle" msgid="397743349191901458">"Шайкештирүү"</string>
+ <string name="contentServiceTooManyDeletesNotificationDesc" msgid="8100981435080696431">"Өтө көп <xliff:g id="CONTENT_TYPE">%s</xliff:g> жок кылынды."</string>
<string name="low_memory" product="tablet" msgid="6494019234102154896">"Планшеттин сактагычы толуп калды. Орун бошотуш үчүн кээ бир файлдарды өчүрүңүз."</string>
<string name="low_memory" product="watch" msgid="4415914910770005166">"Саат сактагычы толуп калды. Орун бошотуу үчүн айрым файлдарды жок кылыңыз."</string>
<string name="low_memory" product="tv" msgid="516619861191025923">"Сыналгынын сактагычы толуп калды. Айрым файлдарды жок кылып орун бошотуңуз."</string>
@@ -258,23 +175,15 @@
<string name="work_profile_deleted_description_dpm_wipe" msgid="6019770344820507579">"Жумуш профилиңиз бул түзмөктө жеткиликтүү болбой калды."</string>
<string name="factory_reset_warning" msgid="5423253125642394387">"Түзмөгүңүз тазаланат"</string>
<string name="factory_reset_message" msgid="4905025204141900666">"Администратор колдонмосунун курамдары жок же бузулгандыктан, аны колдонуу мүмкүн эмес. Түзмөгүңүз азыр тазаланат. Жардам алуу үчүн администраторуңузга кайрылыңыз."</string>
- <!-- no translation found for me (6545696007631404292) -->
- <skip />
- <!-- no translation found for power_dialog (8545351420865202853) -->
- <skip />
+ <string name="me" msgid="6545696007631404292">"Мен"</string>
+ <string name="power_dialog" product="tablet" msgid="8545351420865202853">"Планшет мүмкүнчүлүктөрү"</string>
<string name="power_dialog" product="tv" msgid="6153888706430556356">"Сыналгы параметрлери"</string>
- <!-- no translation found for power_dialog (1319919075463988638) -->
- <skip />
- <!-- no translation found for silent_mode (7167703389802618663) -->
- <skip />
- <!-- no translation found for turn_on_radio (3912793092339962371) -->
- <skip />
- <!-- no translation found for turn_off_radio (8198784949987062346) -->
- <skip />
- <!-- no translation found for screen_lock (799094655496098153) -->
- <skip />
- <!-- no translation found for power_off (4266614107412865048) -->
- <skip />
+ <string name="power_dialog" product="default" msgid="1319919075463988638">"Телефон мүмкүнчүлүктөрү"</string>
+ <string name="silent_mode" msgid="7167703389802618663">"Үнсүз режим"</string>
+ <string name="turn_on_radio" msgid="3912793092339962371">"Радиону күйгүзүү"</string>
+ <string name="turn_off_radio" msgid="8198784949987062346">"Радиону өчүрүү"</string>
+ <string name="screen_lock" msgid="799094655496098153">"Экран кулпусу"</string>
+ <string name="power_off" msgid="4266614107412865048">"Кубатын өчүрүү"</string>
<string name="silent_mode_silent" msgid="319298163018473078">"Коңгуроо өчүк"</string>
<string name="silent_mode_vibrate" msgid="7072043388581551395">"Чалганда титирөө"</string>
<string name="silent_mode_ring" msgid="8592241816194074353">"Коңгуроо жандырылган"</string>
@@ -284,54 +193,37 @@
<string name="reboot_to_update_reboot" msgid="6428441000951565185">"Өчүрүлүп күйгүзүлүүдө…"</string>
<string name="reboot_to_reset_title" msgid="4142355915340627490">"Баштапкы абалга кайтаруу"</string>
<string name="reboot_to_reset_message" msgid="2432077491101416345">"Өчүрүлүп күйгүзүлүүдө…"</string>
- <!-- no translation found for shutdown_progress (2281079257329981203) -->
- <skip />
- <!-- no translation found for shutdown_confirm (3385745179555731470) -->
- <skip />
+ <string name="shutdown_progress" msgid="2281079257329981203">"Жабылууда…"</string>
+ <string name="shutdown_confirm" product="tablet" msgid="3385745179555731470">"Планшетиңиз өчүрүлөт."</string>
<string name="shutdown_confirm" product="tv" msgid="476672373995075359">"Сыналгыңыз жабылат."</string>
<string name="shutdown_confirm" product="watch" msgid="3490275567476369184">"Саатыңыз жабылат."</string>
- <!-- no translation found for shutdown_confirm (649792175242821353) -->
- <skip />
+ <string name="shutdown_confirm" product="default" msgid="649792175242821353">"Телефонуңуз өчүрүлөт."</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>
- <!-- no translation found for recent_tasks_title (3691764623638127888) -->
- <skip />
+ <string name="recent_tasks_title" msgid="3691764623638127888">"Акыркы"</string>
<string name="no_recent_tasks" msgid="8794906658732193473">"Акыркы колдонмолор жок"</string>
- <!-- no translation found for global_actions (408477140088053665) -->
- <skip />
+ <string name="global_actions" product="tablet" msgid="408477140088053665">"Планшет мүмкүнчүлүктөрү"</string>
<string name="global_actions" product="tv" msgid="7240386462508182976">"Сыналгы параметрлери"</string>
- <!-- no translation found for global_actions (2406416831541615258) -->
- <skip />
- <!-- no translation found for global_action_lock (2844945191792119712) -->
- <skip />
- <!-- no translation found for global_action_power_off (4471879440839879722) -->
- <skip />
+ <string name="global_actions" product="default" msgid="2406416831541615258">"Телефон мүмкүнчүлүктөрү"</string>
+ <string name="global_action_lock" msgid="2844945191792119712">"Экран кулпусу"</string>
+ <string name="global_action_power_off" msgid="4471879440839879722">"Кубатын өчүрүү"</string>
<string name="global_action_bug_report" msgid="7934010578922304799">"Ката тууралуу билдирүү"</string>
<string name="bugreport_title" msgid="2667494803742548533">"Ката тууралуу билдирүү түзүү"</string>
<string name="bugreport_message" msgid="398447048750350456">"Бул сиздин түзмөгүңүздүн учурдагы абалын эмейл билдирүүсү катары жөнөтүш максатында маалымат чогултат. Ката тууралуу билдирүү түзүлүп башталып, жөнөтүлгөнгө чейин бир аз убакыт керек болот; сураныч, бир аз күтө туруңуз."</string>
- <!-- no translation found for global_action_toggle_silent_mode (8219525344246810925) -->
- <skip />
- <!-- no translation found for global_action_silent_mode_on_status (3289841937003758806) -->
- <skip />
- <!-- no translation found for global_action_silent_mode_off_status (1506046579177066419) -->
- <skip />
- <!-- no translation found for global_actions_toggle_airplane_mode (5884330306926307456) -->
- <skip />
- <!-- no translation found for global_actions_airplane_mode_on_status (2719557982608919750) -->
- <skip />
- <!-- no translation found for global_actions_airplane_mode_off_status (5075070442854490296) -->
- <skip />
+ <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"Үнсүз режим"</string>
+ <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"Добушу ӨЧҮК"</string>
+ <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"Добушу КҮЙҮК"</string>
+ <string name="global_actions_toggle_airplane_mode" msgid="5884330306926307456">"Учак режими"</string>
+ <string name="global_actions_airplane_mode_on_status" msgid="2719557982608919750">"Учак режими КҮЙҮК"</string>
+ <string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"Учак режими ӨЧҮК"</string>
<string name="global_action_settings" msgid="1756531602592545966">"Жөндөөлөр"</string>
<string name="global_action_assist" msgid="3892832961594295030">"Жардам"</string>
<string name="global_action_voice_assist" msgid="7751191495200504480">"Үн жардамчысы"</string>
<string name="global_action_lockdown" msgid="8751542514724332873">"Азыр кулпулоо"</string>
- <!-- no translation found for status_bar_notification_info_overflow (5301981741705354993) -->
- <skip />
- <!-- no translation found for safeMode (2788228061547930246) -->
- <skip />
- <!-- no translation found for android_system_label (6577375335728551336) -->
- <skip />
+ <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="user_owner_label" msgid="2804351898001038951">"Жеке"</string>
<string name="managed_profile_label" msgid="6260850669674791528">"Жумуш"</string>
<string name="permgrouplab_contacts" msgid="3657758145679177612">"Байланыштар"</string>
@@ -342,8 +234,7 @@
<string name="permgroupdesc_calendar" msgid="3889615280211184106">"жылнаамаңызды пайдалануу"</string>
<string name="permgrouplab_sms" msgid="228308803364967808">"SMS"</string>
<string name="permgroupdesc_sms" msgid="4656988620100940350">"SMS билдирүүлөрдү жиберүү жана көрсөтүү"</string>
- <!-- no translation found for permgrouplab_storage (1971118770546336966) -->
- <skip />
+ <string name="permgrouplab_storage" msgid="1971118770546336966">"Сактагыч"</string>
<string name="permgroupdesc_storage" msgid="637758554581589203">"түзмөгүңүздөгү сүрөттөр, медиа жана файлдарга кирүү"</string>
<string name="permgrouplab_microphone" msgid="171539900250043464">"Микрофон"</string>
<string name="permgroupdesc_microphone" msgid="4988812113943554584">"аудио жаздыруу"</string>
@@ -361,14 +252,11 @@
<string name="capability_desc_canRequestEnhancedWebAccessibility" msgid="7881063961507511765">"Колдонмонун мазмунун жеткиликтүүрөөк кылыш үчүн скрипттер орнотулушу мүмкүн."</string>
<string name="capability_title_canRequestFilterKeyEvents" msgid="2103440391902412174">"Терип жаткан текстти текшерүү"</string>
<string name="capability_desc_canRequestFilterKeyEvents" msgid="7463135292204152818">"Кредиттик карта номурлары жана сырсөздөр сыяктуу өздүк берилиштерди камтыйт."</string>
- <!-- no translation found for permlab_statusBar (7417192629601890791) -->
- <skip />
+ <string name="permlab_statusBar" msgid="7417192629601890791">"абал тилкесин өчүрүү же өзгөртүү"</string>
<string name="permdesc_statusBar" msgid="8434669549504290975">"Колдонмого абал тилкесин өчүрүү же тутум сүрөтчөлөрүн кошуу же алып салуу мүмкүнчүлүгүн берет."</string>
- <!-- no translation found for permlab_statusBarService (7247281911387931485) -->
- <skip />
+ <string name="permlab_statusBarService" msgid="7247281911387931485">"абал тилкеси"</string>
<string name="permdesc_statusBarService" msgid="716113660795976060">"Колдонмого абал тилкеси болуу мүмкүнчүлүгүн берет."</string>
- <!-- no translation found for permlab_expandStatusBar (1148198785937489264) -->
- <skip />
+ <string name="permlab_expandStatusBar" msgid="1148198785937489264">"абал тилкесин жайып көрсөтүү/жыйнап коюу"</string>
<string name="permdesc_expandStatusBar" msgid="6917549437129401132">"Колдонмого абал тилкесин жайып көрсөтүү же жыйнап коюу мүмкүнчүлүгүн берет."</string>
<string name="permlab_install_shortcut" msgid="4279070216371564234">"тез чакырма орнотуу"</string>
<string name="permdesc_install_shortcut" msgid="8341295916286736996">"Колдонмого үй экранга колдонуучунун катышуусусуз тез чакырма кошууга мүмкүнчүлүк берет."</string>
@@ -382,8 +270,7 @@
<string name="permdesc_receiveMms" msgid="533019437263212260">"Колдонмого MMS билдирүүлөрүн кабыл алууга жана аларды иштетип чыгууга уруксат берет. Бул, колдонмо сизге билгизбестен түзмөгүңүзгө жөнөтүлгөн билдирүүлөрдү мониторлой же жок кыла алат дегенди билдирет."</string>
<string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"уюктук берүү билдирүүлөрүн окуу"</string>
<string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"Колдонмого түзмөгүңүз кабыл алган уюк берүүнүн билдирүүлөрүн окууга жол берет. Шашылыш эскертүү билдирүүлөрү кээ бир жерлердеги өзгөчө кырдаалдар тууралу сизди эскертүү үчүн жөнөтүлөт. Зыяндуу колдономолор шашылыш эскертүүлөр берилип жатканда, сиздин түзмөктүн иштешине жолтоо болушу мүмкүн."</string>
- <!-- no translation found for permlab_subscribedFeedsRead (4756609637053353318) -->
- <skip />
+ <string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"жазылган түрмөктөрдү окуу"</string>
<string name="permdesc_subscribedFeedsRead" msgid="5557058907906144505">"Колдонмого учурда шайкештештирилген каналдардын чоо-жайларын алуу мүмкүнчүлүгүн берет."</string>
<string name="permlab_sendSms" msgid="7544599214260982981">"SMS билдирүүлөрдү жиберүү жана көрсөтүү"</string>
<string name="permdesc_sendSms" msgid="7094729298204937667">"Колдонмого SMS билдирүүлөрүн жөнөтүү уруксатын берет. Бул сиз күтпөгөн чыгымдарга алып келиши мүмкүн. Зыяндуу колдонмолор сиздин ырастооңузсуз билдирүүлөрдү жөнөтүп, көп чыгымдарга себепкер болушу мүмкүн."</string>
@@ -399,8 +286,7 @@
<string name="permdesc_manageProfileAndDeviceOwners" msgid="106894851498657169">"Колдонмолорго профиль ээлерин жана түзмөк ээсин орнотуу мүмкүнчүлүгүн берет."</string>
<string name="permlab_reorderTasks" msgid="2018575526934422779">"иштеп жаткан колдонмолорду иреттештирүү"</string>
<string name="permdesc_reorderTasks" msgid="7734217754877439351">"Колдонмо процесстерди фонго же алдыңкы планга жылдыруу уруксатын алат. Колдонмо муну сиздин ырастооңузсуз кыла алат."</string>
- <!-- no translation found for permlab_enableCarMode (5684504058192921098) -->
- <skip />
+ <string name="permlab_enableCarMode" msgid="5684504058192921098">"унаа режимин иштетүү"</string>
<string name="permdesc_enableCarMode" msgid="4853187425751419467">"Колдонмого унаа режимин иштетүү мүмкүнчүлүгүн берет."</string>
<string name="permlab_killBackgroundProcesses" msgid="3914026687420177202">"башка колдонмолорду жабуу"</string>
<string name="permdesc_killBackgroundProcesses" msgid="4593353235959733119">"Колдонмого башка колдонмолордун фондо иштеп жаткан процесстерин токтотуу уруксатын берет. Бул башка колдонмолордун иштебей калышына алып келиши мүмкүн."</string>
@@ -418,8 +304,7 @@
<string name="permdesc_receiveBootCompleted" product="tablet" msgid="7390304664116880704">"Колдонмого тутум жүктөлүп бүтөөрү менен өзүн-өзү иштетүү мүмкүнчүлүгүн берет. Бул планшеттин ишке киргизилишин кыйла создуктуруп, планшеттин үзгүлтүксүз иштешин жайлатып салышы мүмкүн."</string>
<string name="permdesc_receiveBootCompleted" product="tv" msgid="4525890122209673621">"Тутум күйгүзүлүп бүтөөрү менен, колдонмо өз алдынча иштеп баштайт. Ушуну менен, сыналгы кечирээк күйгүзүлүп, колдонмо такай иштеп тургандыктан, планшет жайыраак иштеп калышы мүмкүн."</string>
<string name="permdesc_receiveBootCompleted" product="default" msgid="513950589102617504">"Колдонмого тутум жүктөлүп бүтөөрү менен өзүн-өзү иштетүү мүмкүнчүлүгүн берет. Бул телефондун ишке киргизилишин кыйла создуктуруп, телефондун үзгүлтүксүз иштешин жайлатып салышы мүмкүн."</string>
- <!-- no translation found for permlab_broadcastSticky (7919126372606881614) -->
- <skip />
+ <string name="permlab_broadcastSticky" msgid="7919126372606881614">"жабышчаак таркатманы жөнөтүү"</string>
<string name="permdesc_broadcastSticky" product="tablet" msgid="7749760494399915651">"Колдонмого берүү токтогондон кийин улантыла берүүчү жабышкак берүүлөрдү жөнөтүү уруксатын берет. Муну ашыкча колдонуу, эстутумду өтө көп пайдаланууга алып келип, планшеттин жай же туруксуз иштөөсүнүнө себепкер болушу мүмкүн."</string>
<string name="permdesc_broadcastSticky" product="tv" msgid="6839285697565389467">"Колдонмого жайылтуу аяктагандан кийинки жабышчаак жайылтууларды жөнөтүү мүмкүнчүлүгүн берет. Ашыкча колдонулганда, сыналгы өтө жай же туруксуз иштеп, эстутумда өтө көп орунду ээлеши мүмкүн."</string>
<string name="permdesc_broadcastSticky" product="default" msgid="2825803764232445091">"Колдонмого берүү токтогондон кийин улантыла берүүчү жабышкак берүүлөрдү жөнөтүү уруксатын берет. Муну ашыкча колдонуу, эстутумду өтө көп пайдаланууга алып келип, телефондун жай же туруксуз иштөөсүнүнө себепкер болушу мүмкүн."</string>
@@ -449,41 +334,33 @@
<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>
- <!-- no translation found for permlab_accessLocationExtraCommands (2836308076720553837) -->
- <skip />
+ <string name="permlab_accessLocationExtraCommands" msgid="2836308076720553837">"жайгашкан жерди аныктагычтын кошумча буйруктарын пайдалануу"</string>
<string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"Колдонмого жайгашкан жерди табуучу кошумча жабдуучулардын буйруктарын колдонуу мүмкүнчүлүгүн берет. Ушуну менен колдонмо GPS\'тин ишине жана башка жайгашкан жерлерди аныктоо кызматтарына кийлигише алат."</string>
<string name="permlab_accessFineLocation" msgid="1191898061965273372">"так жайгаштыруу (GPS жана түйүн негизинде)"</string>
<string name="permdesc_accessFineLocation" msgid="5295047563564981250">"Колдонмого Глобалдык Позициялоо Системасын (GPS), же базалык станциялар жана Wi-Fi сыяктуу түйүндүк булактардын жайгашуусунун пайдалануу аркылуу сиздин так жайгашууңузду аныктоого уруксат берет. Колдонмолор муну пайдалана алышы үчүн, жайгаштыруу кызматтары жандырылган жана түзмөгүңүзгө жеткиликтүү болушу керек. Колдонмолор муну сиздин жайгашкан жериңизди аныкташ үчүн пайдаланышы жана кошумча батарей кубаты сарпталышы мүмкүн."</string>
<string name="permlab_accessCoarseLocation" msgid="4887895362354239628">"божомолдуу жайгаштыруу (түйүн негизинде)"</string>
<string name="permdesc_accessCoarseLocation" msgid="2538200184373302295">"Колдонмого сиздин болжолдуу жайгашууңузду аныктоо уруксаты берет. Мындай жайгаштыруу базалык станциялар жана Wi-Fi сыяктуу түйүндүк булактардын жайгашуусу аркылуу аныкталат. Колдонмоңуз буларды пайдалана алышы үчүн, мындай жайгаштыруу кызматтары жандырылган жана түзмөгүңүзгө жеткиликтүү болушу керек. Колдонмолор муну сиздин жайгашкан жериңизди болжолдош үчүн пайдаланышы мүмкүн."</string>
- <!-- no translation found for permlab_modifyAudioSettings (6095859937069146086) -->
- <skip />
+ <string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"аудио жөндөөлөрүңүздү өзгөртүңүз"</string>
<string name="permdesc_modifyAudioSettings" msgid="3522565366806248517">"Колдонмого үн деңгээли жана кайсы динамик аркылуу үн чыгарылышы керек сыяктуу түзмөктүн аудио тууралоолорун өзгөртүүгө уруксат берет."</string>
- <!-- no translation found for permlab_recordAudio (3876049771427466323) -->
- <skip />
+ <string name="permlab_recordAudio" msgid="3876049771427466323">"аудио жаздыруу"</string>
<string name="permdesc_recordAudio" msgid="4906839301087980680">"Колдонмого микрофон аркылуу аудио жаздыруу уруксатын берет. Бул уруксат колдонмого сиздин ырастооңузсуз, каалаган убакта аудио жаздыруу уруксатын берет."</string>
<string name="permlab_sim_communication" msgid="1180265879464893029">"sim-карта менен байланышуу"</string>
<string name="permdesc_sim_communication" msgid="5725159654279639498">"Колдонмого SIM-картага буйруктарды жөнөтүү мүмкүнчүлүгүн берет. Бул абдан кооптуу."</string>
- <!-- no translation found for permlab_camera (3616391919559751192) -->
- <skip />
+ <string name="permlab_camera" msgid="3616391919559751192">"сүрөт жана видео тартуу"</string>
<string name="permdesc_camera" msgid="8497216524735535009">"Колдонмого камера аркылуу видео жана сүрөт тартуу уруксатын берет. Бул уруксат, камераны каалаган убакта, сиздин ырастооңузсуз колдонуу уруксатын берет."</string>
<string name="permlab_vibrate" msgid="7696427026057705834">"титирөөнү башкаруу"</string>
<string name="permdesc_vibrate" msgid="6284989245902300945">"Колдонмого дирилдегичти көзөмөлдөө мүмкүнчүлүгүн берет."</string>
- <!-- no translation found for permlab_flashlight (2155920810121984215) -->
- <skip />
+ <string name="permlab_flashlight" msgid="2155920810121984215">"кол чыракты көзөмөлдөө"</string>
<string name="permdesc_flashlight" msgid="6522284794568368310">"Колдонмого колчыракты көзөмөлдөө мүмкүнчүлүгүн берет."</string>
- <!-- no translation found for permlab_callPhone (3925836347681847954) -->
- <skip />
+ <string name="permlab_callPhone" msgid="3925836347681847954">"телефон номерлерине түз чалуу"</string>
<string name="permdesc_callPhone" msgid="3740797576113760827">"Колдонмого сиздин катышууңузсуз телефон номурларга чалуу уруксатын берет. Бул сиз күтпөгөн чыгымдарга же чалууларга алып келиши мүмкүн. Бул куткаруучулардын номурларына чалууга уруксат бербей тургандыгын эске алыңыз. Зыяндуу колдонмолор, сиздин ырастооңузсуз чалууларды аткарып, көп чыгымдарга себепкер болушу мүмкүн."</string>
<string name="permlab_accessImsCallService" msgid="3574943847181793918">"IMS чалуу кызматына мүмкүнчүлүк алуу"</string>
<string name="permdesc_accessImsCallService" msgid="8992884015198298775">"Колдонмого сизди катыштырбай туруп, IMS кызматынын жардамы менен чалууларды жасоо мүмкүнчүлүгүн берет."</string>
<string name="permlab_readPhoneState" msgid="9178228524507610486">"телефондун абалын жана аныктыгын окуу"</string>
<string name="permdesc_readPhoneState" msgid="1639212771826125528">"Колдонмого түзмөктүн чалуу мүмкүнчүлүктөрүнө жетки алуу уруксатын берет. Бул уруксат колдонмого, телефондун номурун, түзмөктүн ID-син, чалуунун абалын жана байланышта чыккан номурду аныктоого жол берет."</string>
- <!-- no translation found for permlab_wakeLock (1531731435011495015) -->
- <skip />
+ <string name="permlab_wakeLock" product="tablet" msgid="1531731435011495015">"планшетти уктатпай сактоо"</string>
<string name="permlab_wakeLock" product="tv" msgid="2601193288949154131">"сыналгыны көшүтпөө"</string>
- <!-- no translation found for permlab_wakeLock (573480187941496130) -->
- <skip />
+ <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"телефонду уктатпай сактоо"</string>
<string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"Колдонмого планшетти көшүтпөө мүмкүнчүлүгүн берет."</string>
<string name="permdesc_wakeLock" product="tv" msgid="3208534859208996974">"Колдонмого сыналгыны уктатпай ойгоо кармап туруу мүмкүнчүлүгүн берет."</string>
<string name="permdesc_wakeLock" product="default" msgid="8559100677372928754">"Колдонмого телефонду көшүтпөө мүмкүнчүлүгүн берет."</string>
@@ -491,13 +368,11 @@
<string name="permdesc_transmitIr" product="tablet" msgid="5358308854306529170">"Колдонмого планшеттин инфракызыл өткөргүчүн колдонуу мүмкүнчүлүгүн берет."</string>
<string name="permdesc_transmitIr" product="tv" msgid="3926790828514867101">"Колдонмого сыналгынын инфракызыл өткөргүчүн пайдалануу мүмкүнчүлүгүн берет."</string>
<string name="permdesc_transmitIr" product="default" msgid="7957763745020300725">"Колдонмого телефондун инфракызыл өткөргүчүн колдонуу мүмкүнчүлүгүн берет."</string>
- <!-- no translation found for permlab_setWallpaper (6627192333373465143) -->
- <skip />
+ <string name="permlab_setWallpaper" msgid="6627192333373465143">"тушкагаз коюу"</string>
<string name="permdesc_setWallpaper" msgid="7373447920977624745">"Колдонмого тутумдун тушкагазын коюу мүмкүнчүлүгүн берет."</string>
<string name="permlab_setWallpaperHints" msgid="3278608165977736538">"тушкагазыңыздын өлчөмүн өзгөртүү"</string>
<string name="permdesc_setWallpaperHints" msgid="8235784384223730091">"Колдонмого тутум тушкагазынын өлчөмдөрүн коюу мүмкүнчүлүгүн берет."</string>
- <!-- no translation found for permlab_setTimeZone (2945079801013077340) -->
- <skip />
+ <string name="permlab_setTimeZone" msgid="2945079801013077340">"убакыт алкагын коюу"</string>
<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>
@@ -509,8 +384,7 @@
<string name="permdesc_accessNetworkState" msgid="8318964424675960975">"Колдонмого желелердин бардыгы жана байланыштар сыяктуу желе маалыматтарын көргөнгө уруксат берет."</string>
<string name="permlab_createNetworkSockets" msgid="8018758136404323658">"желеге толук жетки алуу"</string>
<string name="permdesc_createNetworkSockets" msgid="3403062187779724185">"Колдонмого түйүн сокеттерин түзүү жана ылайыкташтырылган түйүн протоколдорун пайдалануу уруксаттарын берет. Серепчи жана башка колдонмолорго интернетке берилиштерди жөнөтүү жолдорун берет, ошондуктан, интернетке берилиштерди жөнөтүү үчүн, бул уруксатты алуу талап кылынбай."</string>
- <!-- no translation found for permlab_changeNetworkState (958884291454327309) -->
- <skip />
+ <string name="permlab_changeNetworkState" msgid="958884291454327309">"тармак туташымдуулугун өзгөртүү"</string>
<string name="permdesc_changeNetworkState" msgid="6789123912476416214">"Колдонмого тармактык туташуунун абалын өзгөртүү мүмкүнчүлүгүн берет."</string>
<string name="permlab_changeTetherState" msgid="5952584964373017960">"интернет бөлүшүү байланышын өзгөртүү"</string>
<string name="permdesc_changeTetherState" msgid="1524441344412319780">"Колдонмого тетеринг тармактык туташуусунун абалын өзгөртүү мүмкүнчүлүгүн берет."</string>
@@ -518,8 +392,7 @@
<string name="permdesc_accessWifiState" msgid="5002798077387803726">"Колдонмого Wi-Fi жандырылгандыгы жана туташкан Wi-Fi түзмөктөрдүн аттары сыяктуу, Wi-Fi түйүндөрүнүн маалыматтарын көрүүгө уруксаты берет."</string>
<string name="permlab_changeWifiState" msgid="6550641188749128035">"Wi-Fi менен туташуу жана ажыратуу"</string>
<string name="permdesc_changeWifiState" msgid="7137950297386127533">"Колдонмого Wi-Fi түйүндөрүнө туташуу жана алардан ажыроо жана түзмөктүн Wi-Fi конфигурацияларына өзгөртүү уруксаттары берилет."</string>
- <!-- no translation found for permlab_changeWifiMulticastState (1368253871483254784) -->
- <skip />
+ <string name="permlab_changeWifiMulticastState" msgid="1368253871483254784">"Wi-Fi Multicast кабыл алууга уруксат берүү"</string>
<string name="permdesc_changeWifiMulticastState" product="tablet" msgid="7969774021256336548">"Колдонмого мультикаст даректерди колдонуп, бир гана сиздин планшетиңиз эмес, Wi-Fi түйүнүндөгү бардык түзмөктөргө жөнөтүлгөн пакеттерди алууга уруксат берет. Бул мультикаст эмес абалдагыдан көбүрөөк кубат сарптайт."</string>
<string name="permdesc_changeWifiMulticastState" product="tv" msgid="9031975661145014160">"Колдонмого топтук өткөрүү даректери аркылуу Wi-Fi тармагындагы сыналгыңызга гана эмес, бардык түзмөктөргө жөнөтүлгөн топтомдорду алуу мүмкүнчүлүгүн берет. Ушуну менен топтук эмес өткөрүү режимине караганда көбүрөөк кубат пайдаланат."</string>
<string name="permdesc_changeWifiMulticastState" product="default" msgid="6851949706025349926">"Колдонмого мультикаст даректерди колдонуп, бир гана сиздин телефонуңуз эмес, Wi-Fi түйүнүндөгү бардык түзмөктөргө жөнөтүлгөн пакеттерди алууга уруксат берет. Бул мультикаст эмес абалдагыдан көбүрөөк кубат сарптайт."</string>
@@ -537,8 +410,7 @@
<string name="permdesc_bluetooth" product="tablet" msgid="3480722181852438628">"Колдонмого планшеттин Bluetooth конфигурацияларын көрүү, жупталган түзмөктөр менен байланыш түзүү жана кабыл алуу уруксатын берет."</string>
<string name="permdesc_bluetooth" product="tv" msgid="3974124940101104206">"Колдонмого сыналгыдагы Bluetooth конфигурациясын көрүп, жупташтырылган түзмөктөргө туташуу жана кабыл алуу мүмкүнчүлүгүн берет."</string>
<string name="permdesc_bluetooth" product="default" msgid="3207106324452312739">"Колдонмого телефондун Bluetooth конфигурацияларын көрүү, жупташкан түзмөктөр менен туташуу түзүү жана кабыл алуу уруксатын берет."</string>
- <!-- no translation found for permlab_nfc (4423351274757876953) -->
- <skip />
+ <string name="permlab_nfc" msgid="4423351274757876953">"Near Field Communication көзөмөлү"</string>
<string name="permdesc_nfc" msgid="7120611819401789907">"Колдонмого Жакынкы аралыкта байланышуу (NFC) белгилери, карталары жана окугучтары менен байланышуу мүмкүнчүлүгүн берет."</string>
<string name="permlab_disableKeyguard" msgid="3598496301486439258">"экранды бөгөттөөнү өчүрүү"</string>
<string name="permdesc_disableKeyguard" msgid="6034203065077122992">"Колдонмого экрандын бөгөттөөчү жана ага байланыштуу сырсөз коргоосун өчүрүү уруксатын берет. Мисалы, чалуу келгенде экрандын бөгөтүн алып салат, чалуу бүткөндө кайрадан орнотот."</string>
@@ -562,15 +434,12 @@
<string name="fingerprint_name_template" msgid="5870957565512716938">"<xliff:g id="FINGERID">%d</xliff:g> манжасы"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
- <!-- no translation found for fingerprint_icon_content_description (2340202869968465936) -->
- <skip />
- <!-- no translation found for permlab_readSyncSettings (6201810008230503052) -->
- <skip />
+ <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="permlab_writeSyncSettings" msgid="5408694875793945314">"синхрондоштурууну өчүрүү/жандыруу"</string>
<string name="permdesc_writeSyncSettings" msgid="8956262591306369868">"Колдонмого эсеп менен синхрондошуу тууралоолорун өзгөртүү уруксатын берет. Мисалы, бул Кишилер колдонмосун эсеп менен синхрондошуусун иштете алат."</string>
- <!-- no translation found for permlab_readSyncStats (7396577451360202448) -->
- <skip />
+ <string name="permlab_readSyncStats" msgid="7396577451360202448">"шайкештирүү статистикасын окуу"</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>
@@ -594,14 +463,11 @@
<string name="permdesc_bind_connection_service" msgid="4008754499822478114">"Колдонмого чалууларды жасоо/кабыл алуу үчүн телефония кызматтары менен байланышууга уруксат берет."</string>
<string name="permlab_control_incall_experience" msgid="9061024437607777619">"чалуу ичиндеги колдонуучу тажрыйбасын камсыз кылуу"</string>
<string name="permdesc_control_incall_experience" msgid="915159066039828124">"Колдонмого чалуу учурундагы колдонуучу тажрыйбасын камсыз кылуу мүмкүнчүлүгүн берет."</string>
- <!-- no translation found for permlab_readNetworkUsageHistory (7862593283611493232) -->
- <skip />
+ <string name="permlab_readNetworkUsageHistory" msgid="7862593283611493232">"тармактын колдонулуш таржымалын окуу"</string>
<string name="permdesc_readNetworkUsageHistory" msgid="7689060749819126472">"Колдонмого белгилүү бир тармактарга жана колдонмолорго байланыштуу тармактын колдонулушу жөнүндө таржымалды окуу мүмкүнчүлүгүн берет."</string>
- <!-- no translation found for permlab_manageNetworkPolicy (2562053592339859990) -->
- <skip />
+ <string name="permlab_manageNetworkPolicy" msgid="2562053592339859990">"тармак саясатын башкаруу"</string>
<string name="permdesc_manageNetworkPolicy" msgid="7537586771559370668">"Колдонмого тармак саясаттарын башкаруу жана колдонмого мүнөздүү эрежелерди белгилөө мүмкүнчүлүгүн берет."</string>
- <!-- no translation found for permlab_modifyNetworkAccounting (5088217309088729650) -->
- <skip />
+ <string name="permlab_modifyNetworkAccounting" msgid="5088217309088729650">"тармактын колдонулуш эсеп-кысабын өзгөртүү"</string>
<string name="permdesc_modifyNetworkAccounting" msgid="5443412866746198123">"Колдонмого желени башка колдонмолордун пайдалануусун башкарган тууралоолорду киргизүү уруксатын берет. Жөнөкөй колдонмолор үчүн эмес."</string>
<string name="permlab_accessNotifications" msgid="7673416487873432268">"эскертүүлөр менен иштөө"</string>
<string name="permdesc_accessNotifications" msgid="458457742683431387">"Колдонмого (башка колдонмолор жайгаштырган дагы) эскертүүлөрдү алуу, изилдөө, жана аларды тазалоо мүмкүнчүлүгүн берет."</string>
@@ -629,11 +495,9 @@
<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>
- <!-- no translation found for policylab_limitPassword (4497420728857585791) -->
- <skip />
+ <string name="policylab_limitPassword" msgid="4497420728857585791">"Сырсөз эрежелерин коюу"</string>
<string name="policydesc_limitPassword" msgid="2502021457917874968">"Экран кулпусунун сырсөздөрү менен PIN\'дерине уруксат берилген узундук менен белгилерди көзөмөлдөө."</string>
- <!-- no translation found for policylab_watchLogin (914130646942199503) -->
- <skip />
+ <string name="policylab_watchLogin" msgid="914130646942199503">"Экран кулпусун ачуу аракеттерин көзөмөлдөө"</string>
<string name="policydesc_watchLogin" product="tablet" msgid="3215729294215070072">"Экрандын кулпусу ачылып жатканда туура эмес терилген сырсөздөрдүн санын текшерип, эгер алардын саны өтө эле көп болсо, планшетти кулпулаңыз же планшеттеги бардык дайындарды тазалап салыңыз."</string>
<string name="policydesc_watchLogin" product="TV" msgid="2707817988309890256">"Экрандын кулпусун ачуу учурунда туура эмес терилген сырсөздөрдү тескөө жана сырсөз өтө көп жолу туура эмес терилген болсо, сыналгыны кулпулап же бардык сыналгы дайындарын тазалап салуу."</string>
<string name="policydesc_watchLogin" product="default" msgid="5712323091846761073">"Экрандын кулпусу ачылып жатканда туура эмес терилген сырсөздөрдүн санын текшерип, эгер алардын саны өтө эле көп болсо, телефонду кулпулаңыз же телефондогу бардык дайындарды тазалап салыңыз."</string>
@@ -642,11 +506,9 @@
<string name="policydesc_watchLogin_secondaryUser" product="default" msgid="2185480427217127147">"Экрандын кулпусун ачуу учурунда туура эмес терилген сырсөздөрдү тескөө жана сырсөз өтө көп жолу туура эмес терилген болсо, телефонду кулпулап же бул колдонуучунун бардык дайындарын тазалап салуу."</string>
<string name="policylab_resetPassword" msgid="4934707632423915395">"Экран кулпусун өзгөртүү"</string>
<string name="policydesc_resetPassword" msgid="1278323891710619128">"Экран кулпусун өзгөртүү."</string>
- <!-- no translation found for policylab_forceLock (2274085384704248431) -->
- <skip />
+ <string name="policylab_forceLock" msgid="2274085384704248431">"Экранды кулпулоо"</string>
<string name="policydesc_forceLock" msgid="1141797588403827138">"Экран качан жана кантип бөгөттөлөөрүн башкаруу."</string>
- <!-- no translation found for policylab_wipeData (3910545446758639713) -->
- <skip />
+ <string name="policylab_wipeData" msgid="3910545446758639713">"Бардык дайындарды тазалоо"</string>
<string name="policydesc_wipeData" product="tablet" msgid="4306184096067756876">"Баштапкы абалга кайтарууну колдонуп, планшеттин бардык берилиштерин эскертүүсүз тазалоо."</string>
<string name="policydesc_wipeData" product="tv" msgid="5816221315214527028">"Сыналгынын дайындарын баштапкы абалга кайтарып, алдын-ала эскертпестен өчүрүп салуу."</string>
<string name="policydesc_wipeData" product="default" msgid="5096895604574188391">"Баштапкы абалга кайтарууну колдонуп, телефондун бардык берилиштерин эскертүүсүз тазалоо."</string>
@@ -654,226 +516,155 @@
<string name="policydesc_wipeData_secondaryUser" product="tablet" msgid="6336255514635308054">"Бул колдонуучунун ушул планшеттеги дайындарын эскертүүсүз тазалоо."</string>
<string name="policydesc_wipeData_secondaryUser" product="tv" msgid="2086473496848351810">"Бул колдонуучунун ушул сыналгыдагы дайындарын эскертүүсүз тазалоо."</string>
<string name="policydesc_wipeData_secondaryUser" product="default" msgid="6787904546711590238">"Бул колдонуучунун ушул телефондогу дайындарын эскертүүсүз тазалоо."</string>
- <!-- no translation found for policylab_setGlobalProxy (2784828293747791446) -->
- <skip />
+ <string name="policylab_setGlobalProxy" msgid="2784828293747791446">"Түзмөктүн глобалдык проксисин коюу"</string>
<string name="policydesc_setGlobalProxy" msgid="8459859731153370499">"Саясат иштетилгенде түзмөктүн глобалдык проксиси колдонулгудай кылып коюңуз. Түзмөк ээси гана глобалдык проксини коё алат."</string>
<string name="policylab_expirePassword" msgid="5610055012328825874">"Экран кулпснн сырсөзнн мөөнөтү"</string>
<string name="policydesc_expirePassword" msgid="5367525762204416046">"Экран кулпусунун сырсөзү, PIN же үлгүсү канча убакыт аралыгында өзгөртүлүшү керектигин өзгөртүү."</string>
- <!-- no translation found for policylab_encryptedStorage (8901326199909132915) -->
- <skip />
+ <string name="policylab_encryptedStorage" msgid="8901326199909132915">"Сактагыч шифрлөөсүн коюу"</string>
<string name="policydesc_encryptedStorage" msgid="2637732115325316992">"Колдонмонун сакталган берилиштери шифрленишин талап кылуу."</string>
- <!-- no translation found for policylab_disableCamera (6395301023152297826) -->
- <skip />
+ <string name="policylab_disableCamera" msgid="6395301023152297826">"Камераларды өчүрүү"</string>
<string name="policydesc_disableCamera" msgid="2306349042834754597">"Түзмөктүн бардык камераларын колдонууга тыюу салуу."</string>
<string name="policylab_disableKeyguardFeatures" msgid="8552277871075367771">"Экрн клпснн айрм функцялрн өчр"</string>
<string name="policydesc_disableKeyguardFeatures" msgid="2044755691354158439">"Экранды кулпулоо функцияларынын айрымдарын колдонууга тыюу салуу"</string>
- <!-- no translation found for phoneTypes:0 (8901098336658710359) -->
- <!-- no translation found for phoneTypes:1 (869923650527136615) -->
- <!-- no translation found for phoneTypes:2 (7897544654242874543) -->
- <!-- no translation found for phoneTypes:3 (1103601433382158155) -->
- <!-- no translation found for phoneTypes:4 (1735177144948329370) -->
- <!-- no translation found for phoneTypes:5 (603878674477207394) -->
- <!-- no translation found for phoneTypes:6 (1650824275177931637) -->
- <!-- no translation found for phoneTypes:7 (9192514806975898961) -->
- <!-- no translation found for emailAddressTypes:0 (8073994352956129127) -->
- <!-- no translation found for emailAddressTypes:1 (7084237356602625604) -->
- <!-- no translation found for emailAddressTypes:2 (1112044410659011023) -->
- <!-- no translation found for emailAddressTypes:3 (2374913952870110618) -->
- <!-- no translation found for postalAddressTypes:0 (6880257626740047286) -->
- <!-- no translation found for postalAddressTypes:1 (5629153956045109251) -->
- <!-- no translation found for postalAddressTypes:2 (4966604264500343469) -->
- <!-- no translation found for postalAddressTypes:3 (4932682847595299369) -->
- <!-- no translation found for imAddressTypes:0 (1738585194601476694) -->
- <!-- no translation found for imAddressTypes:1 (1359644565647383708) -->
- <!-- no translation found for imAddressTypes:2 (7868549401053615677) -->
- <!-- no translation found for imAddressTypes:3 (3145118944639869809) -->
- <!-- no translation found for organizationTypes:0 (7546335612189115615) -->
- <!-- no translation found for organizationTypes:1 (4378074129049520373) -->
- <!-- no translation found for organizationTypes:2 (3455047468583965104) -->
- <!-- no translation found for imProtocols:0 (8595261363518459565) -->
- <!-- no translation found for imProtocols:1 (7390473628275490700) -->
- <!-- no translation found for imProtocols:2 (7882877134931458217) -->
- <!-- no translation found for imProtocols:3 (5035376313200585242) -->
- <!-- no translation found for imProtocols:4 (7532363178459444943) -->
- <!-- no translation found for imProtocols:5 (3713441034299660749) -->
- <!-- no translation found for imProtocols:6 (2506857312718630823) -->
- <!-- no translation found for imProtocols:7 (1648797903785279353) -->
- <!-- no translation found for phoneTypeCustom (1644738059053355820) -->
- <skip />
- <!-- no translation found for phoneTypeHome (2570923463033985887) -->
- <skip />
- <!-- no translation found for phoneTypeMobile (6501463557754751037) -->
- <skip />
- <!-- no translation found for phoneTypeWork (8863939667059911633) -->
- <skip />
- <!-- no translation found for phoneTypeFaxWork (3517792160008890912) -->
- <skip />
- <!-- no translation found for phoneTypeFaxHome (2067265972322971467) -->
- <skip />
- <!-- no translation found for phoneTypePager (7582359955394921732) -->
- <skip />
- <!-- no translation found for phoneTypeOther (1544425847868765990) -->
- <skip />
- <!-- no translation found for phoneTypeCallback (2712175203065678206) -->
- <skip />
- <!-- no translation found for phoneTypeCar (8738360689616716982) -->
- <skip />
- <!-- no translation found for phoneTypeCompanyMain (540434356461478916) -->
- <skip />
- <!-- no translation found for phoneTypeIsdn (8022453193171370337) -->
- <skip />
- <!-- no translation found for phoneTypeMain (6766137010628326916) -->
- <skip />
- <!-- no translation found for phoneTypeOtherFax (8587657145072446565) -->
- <skip />
- <!-- no translation found for phoneTypeRadio (4093738079908667513) -->
- <skip />
- <!-- no translation found for phoneTypeTelex (3367879952476250512) -->
- <skip />
- <!-- no translation found for phoneTypeTtyTdd (8606514378585000044) -->
- <skip />
- <!-- no translation found for phoneTypeWorkMobile (1311426989184065709) -->
- <skip />
- <!-- no translation found for phoneTypeWorkPager (649938731231157056) -->
- <skip />
- <!-- no translation found for phoneTypeAssistant (5596772636128562884) -->
- <skip />
- <!-- no translation found for phoneTypeMms (7254492275502768992) -->
- <skip />
- <!-- no translation found for eventTypeCustom (7837586198458073404) -->
- <skip />
- <!-- no translation found for eventTypeBirthday (2813379844211390740) -->
- <skip />
- <!-- no translation found for eventTypeAnniversary (3876779744518284000) -->
- <skip />
- <!-- no translation found for eventTypeOther (7388178939010143077) -->
- <skip />
- <!-- no translation found for emailTypeCustom (8525960257804213846) -->
- <skip />
- <!-- no translation found for emailTypeHome (449227236140433919) -->
- <skip />
- <!-- no translation found for emailTypeWork (3548058059601149973) -->
- <skip />
- <!-- no translation found for emailTypeOther (2923008695272639549) -->
- <skip />
- <!-- no translation found for emailTypeMobile (119919005321166205) -->
- <skip />
- <!-- no translation found for postalTypeCustom (8903206903060479902) -->
- <skip />
- <!-- no translation found for postalTypeHome (8165756977184483097) -->
- <skip />
- <!-- no translation found for postalTypeWork (5268172772387694495) -->
- <skip />
- <!-- no translation found for postalTypeOther (2726111966623584341) -->
- <skip />
- <!-- no translation found for imTypeCustom (2074028755527826046) -->
- <skip />
- <!-- no translation found for imTypeHome (6241181032954263892) -->
- <skip />
- <!-- no translation found for imTypeWork (1371489290242433090) -->
- <skip />
- <!-- no translation found for imTypeOther (5377007495735915478) -->
- <skip />
- <!-- no translation found for imProtocolCustom (6919453836618749992) -->
- <skip />
- <!-- no translation found for imProtocolAim (7050360612368383417) -->
- <skip />
- <!-- no translation found for imProtocolMsn (144556545420769442) -->
- <skip />
- <!-- no translation found for imProtocolYahoo (8271439408469021273) -->
- <skip />
- <!-- no translation found for imProtocolSkype (9019296744622832951) -->
- <skip />
- <!-- no translation found for imProtocolQq (8887484379494111884) -->
- <skip />
+ <string-array name="phoneTypes">
+ <item msgid="8901098336658710359">"Башкы бет"</item>
+ <item msgid="869923650527136615">"Мобилдик"</item>
+ <item msgid="7897544654242874543">"Жумуш"</item>
+ <item msgid="1103601433382158155">"Жумуш факсы"</item>
+ <item msgid="1735177144948329370">"Үй факсы"</item>
+ <item msgid="603878674477207394">"Пейжер"</item>
+ <item msgid="1650824275177931637">"Башка"</item>
+ <item msgid="9192514806975898961">"Ыңгайлаштырылган"</item>
+ </string-array>
+ <string-array name="emailAddressTypes">
+ <item msgid="8073994352956129127">"Башкы бет"</item>
+ <item msgid="7084237356602625604">"Жумуш"</item>
+ <item msgid="1112044410659011023">"Башка"</item>
+ <item msgid="2374913952870110618">"Ыңгайлаштырылган"</item>
+ </string-array>
+ <string-array name="postalAddressTypes">
+ <item msgid="6880257626740047286">"Башкы бет"</item>
+ <item msgid="5629153956045109251">"Жумуш"</item>
+ <item msgid="4966604264500343469">"Башка"</item>
+ <item msgid="4932682847595299369">"Ыңгайлаштырылган"</item>
+ </string-array>
+ <string-array name="imAddressTypes">
+ <item msgid="1738585194601476694">"Башкы бет"</item>
+ <item msgid="1359644565647383708">"Жумуш"</item>
+ <item msgid="7868549401053615677">"Башка"</item>
+ <item msgid="3145118944639869809">"Ыңгайлаштырылган"</item>
+ </string-array>
+ <string-array name="organizationTypes">
+ <item msgid="7546335612189115615">"Жумуш"</item>
+ <item msgid="4378074129049520373">"Башка"</item>
+ <item msgid="3455047468583965104">"Ыңгайлаштырылган"</item>
+ </string-array>
+ <string-array name="imProtocols">
+ <item msgid="8595261363518459565">"AIM"</item>
+ <item msgid="7390473628275490700">"Windows Live"</item>
+ <item msgid="7882877134931458217">"Yahoo"</item>
+ <item msgid="5035376313200585242">"Skype"</item>
+ <item msgid="7532363178459444943">"QQ"</item>
+ <item msgid="3713441034299660749">"Google Talk"</item>
+ <item msgid="2506857312718630823">"ICQ"</item>
+ <item msgid="1648797903785279353">"Jabber"</item>
+ </string-array>
+ <string name="phoneTypeCustom" msgid="1644738059053355820">"Ыңгайлаштырылган"</string>
+ <string name="phoneTypeHome" msgid="2570923463033985887">"Башкы бет"</string>
+ <string name="phoneTypeMobile" msgid="6501463557754751037">"Мобилдик"</string>
+ <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="phoneTypeOther" msgid="1544425847868765990">"Башка"</string>
+ <string name="phoneTypeCallback" msgid="2712175203065678206">"Кайра чалуу"</string>
+ <string name="phoneTypeCar" msgid="8738360689616716982">"Унаа"</string>
+ <string name="phoneTypeCompanyMain" msgid="540434356461478916">"Компаниянын телефону"</string>
+ <string name="phoneTypeIsdn" msgid="8022453193171370337">"ISDN"</string>
+ <string name="phoneTypeMain" msgid="6766137010628326916">"Негизги"</string>
+ <string name="phoneTypeOtherFax" msgid="8587657145072446565">"Башка факс"</string>
+ <string name="phoneTypeRadio" msgid="4093738079908667513">"Радио"</string>
+ <string name="phoneTypeTelex" msgid="3367879952476250512">"Телекс"</string>
+ <string name="phoneTypeTtyTdd" msgid="8606514378585000044">"Телетайп түзмөгү TDD"</string>
+ <string name="phoneTypeWorkMobile" msgid="1311426989184065709">"Жумуш мобил. телефон"</string>
+ <string name="phoneTypeWorkPager" msgid="649938731231157056">"Жумуш пейжери"</string>
+ <string name="phoneTypeAssistant" msgid="5596772636128562884">"Жардамчы"</string>
+ <string name="phoneTypeMms" msgid="7254492275502768992">"MMS"</string>
+ <string name="eventTypeCustom" msgid="7837586198458073404">"Ыңгайлаштырылган"</string>
+ <string name="eventTypeBirthday" msgid="2813379844211390740">"Туулган күн"</string>
+ <string name="eventTypeAnniversary" msgid="3876779744518284000">"Маараке"</string>
+ <string name="eventTypeOther" msgid="7388178939010143077">"Башка"</string>
+ <string name="emailTypeCustom" msgid="8525960257804213846">"Ыңгайлаштырылган"</string>
+ <string name="emailTypeHome" msgid="449227236140433919">"Башкы бет"</string>
+ <string name="emailTypeWork" msgid="3548058059601149973">"Жумуш"</string>
+ <string name="emailTypeOther" msgid="2923008695272639549">"Башка"</string>
+ <string name="emailTypeMobile" msgid="119919005321166205">"Мобилдик"</string>
+ <string name="postalTypeCustom" msgid="8903206903060479902">"Ыңгайлаштырылган"</string>
+ <string name="postalTypeHome" msgid="8165756977184483097">"Башкы бет"</string>
+ <string name="postalTypeWork" msgid="5268172772387694495">"Жумуш"</string>
+ <string name="postalTypeOther" msgid="2726111966623584341">"Башка"</string>
+ <string name="imTypeCustom" msgid="2074028755527826046">"Ыңгайлаштырылган"</string>
+ <string name="imTypeHome" msgid="6241181032954263892">"Башкы бет"</string>
+ <string name="imTypeWork" msgid="1371489290242433090">"Жумуш"</string>
+ <string name="imTypeOther" msgid="5377007495735915478">"Башка"</string>
+ <string name="imProtocolCustom" msgid="6919453836618749992">"Ыңгайлаштырылган"</string>
+ <string name="imProtocolAim" msgid="7050360612368383417">"AIM"</string>
+ <string name="imProtocolMsn" msgid="144556545420769442">"Windows Live"</string>
+ <string name="imProtocolYahoo" msgid="8271439408469021273">"Yahoo"</string>
+ <string name="imProtocolSkype" msgid="9019296744622832951">"Skype"</string>
+ <string name="imProtocolQq" msgid="8887484379494111884">"QQ"</string>
<string name="imProtocolGoogleTalk" msgid="493902321140277304">"Hangouts"</string>
- <!-- no translation found for imProtocolIcq (1574870433606517315) -->
- <skip />
- <!-- no translation found for imProtocolJabber (2279917630875771722) -->
- <skip />
- <!-- no translation found for imProtocolNetMeeting (8287625655986827971) -->
- <skip />
- <!-- no translation found for orgTypeWork (29268870505363872) -->
- <skip />
- <!-- no translation found for orgTypeOther (3951781131570124082) -->
- <skip />
- <!-- no translation found for orgTypeCustom (225523415372088322) -->
- <skip />
- <!-- no translation found for relationTypeCustom (3542403679827297300) -->
- <skip />
- <!-- no translation found for relationTypeAssistant (6274334825195379076) -->
- <skip />
- <!-- no translation found for relationTypeBrother (8757913506784067713) -->
- <skip />
- <!-- no translation found for relationTypeChild (1890746277276881626) -->
- <skip />
- <!-- no translation found for relationTypeDomesticPartner (6904807112121122133) -->
- <skip />
- <!-- no translation found for relationTypeFather (5228034687082050725) -->
- <skip />
- <!-- no translation found for relationTypeFriend (7313106762483391262) -->
- <skip />
- <!-- no translation found for relationTypeManager (6365677861610137895) -->
- <skip />
- <!-- no translation found for relationTypeMother (4578571352962758304) -->
- <skip />
- <!-- no translation found for relationTypeParent (4755635567562925226) -->
- <skip />
- <!-- no translation found for relationTypePartner (7266490285120262781) -->
- <skip />
- <!-- no translation found for relationTypeReferredBy (101573059844135524) -->
- <skip />
- <!-- no translation found for relationTypeRelative (1799819930085610271) -->
- <skip />
- <!-- no translation found for relationTypeSister (1735983554479076481) -->
- <skip />
- <!-- no translation found for relationTypeSpouse (394136939428698117) -->
- <skip />
- <!-- no translation found for sipAddressTypeCustom (2473580593111590945) -->
- <skip />
- <!-- no translation found for sipAddressTypeHome (6093598181069359295) -->
- <skip />
- <!-- no translation found for sipAddressTypeWork (6920725730797099047) -->
- <skip />
- <!-- no translation found for sipAddressTypeOther (4408436162950119849) -->
- <skip />
+ <string name="imProtocolIcq" msgid="1574870433606517315">"ICQ"</string>
+ <string name="imProtocolJabber" msgid="2279917630875771722">"Jabber"</string>
+ <string name="imProtocolNetMeeting" msgid="8287625655986827971">"NetMeeting"</string>
+ <string name="orgTypeWork" msgid="29268870505363872">"Жумуш"</string>
+ <string name="orgTypeOther" msgid="3951781131570124082">"Башка"</string>
+ <string name="orgTypeCustom" msgid="225523415372088322">"Ыңгайлаштырылган"</string>
+ <string name="relationTypeCustom" msgid="3542403679827297300">"Ыңгайлаштырылган"</string>
+ <string name="relationTypeAssistant" msgid="6274334825195379076">"Жардамчы"</string>
+ <string name="relationTypeBrother" msgid="8757913506784067713">"Ага-ини"</string>
+ <string name="relationTypeChild" msgid="1890746277276881626">"Баласы"</string>
+ <string name="relationTypeDomesticPartner" msgid="6904807112121122133">"Жергиликтүү Өнөктөш"</string>
+ <string name="relationTypeFather" msgid="5228034687082050725">"Атасы"</string>
+ <string name="relationTypeFriend" msgid="7313106762483391262">"Досу"</string>
+ <string name="relationTypeManager" msgid="6365677861610137895">"Менежер"</string>
+ <string name="relationTypeMother" msgid="4578571352962758304">"Энеси"</string>
+ <string name="relationTypeParent" msgid="4755635567562925226">"Ата/эне"</string>
+ <string name="relationTypePartner" msgid="7266490285120262781">"Өнөк"</string>
+ <string name="relationTypeReferredBy" msgid="101573059844135524">"Төмөнкүдөй аталат"</string>
+ <string name="relationTypeRelative" msgid="1799819930085610271">"Тууган"</string>
+ <string name="relationTypeSister" msgid="1735983554479076481">"Эже-сиңди"</string>
+ <string name="relationTypeSpouse" msgid="394136939428698117">"Жубай"</string>
+ <string name="sipAddressTypeCustom" msgid="2473580593111590945">"Ыңгайлаштырылган"</string>
+ <string name="sipAddressTypeHome" msgid="6093598181069359295">"Башкы бет"</string>
+ <string name="sipAddressTypeWork" msgid="6920725730797099047">"Жумуш"</string>
+ <string name="sipAddressTypeOther" msgid="4408436162950119849">"Башка"</string>
<string name="quick_contacts_not_available" msgid="746098007828579688">"Байланышты көрсөтүүчү эч бир колдонмо жок."</string>
<string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"PIN кодду териңиз"</string>
<string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"PUK жана жаңы PIN кодду териңиз"</string>
- <!-- no translation found for keyguard_password_enter_puk_prompt (1341112146710087048) -->
- <skip />
+ <string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"PUK-код"</string>
<string name="keyguard_password_enter_pin_prompt" msgid="8027680321614196258">"Жаңы PIN код"</string>
<string name="keyguard_password_entry_touch_hint" msgid="7858547464982981384"><font size="17">"Сырсөздү терүү үчүн тийип коюңуз"</font></string>
<string name="keyguard_password_enter_password_code" msgid="1054721668279049780">"Кулпуну ачуу үчүн сырсөздү териңиз"</string>
<string name="keyguard_password_enter_pin_password_code" msgid="6391755146112503443">"Кулпуну ачуу үчүн PIN кодду териңиз"</string>
<string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"PIN-код туура эмес."</string>
- <!-- no translation found for keyguard_label_text (861796461028298424) -->
- <skip />
- <!-- no translation found for emergency_call_dialog_number_for_display (696192103195090970) -->
- <skip />
+ <string name="keyguard_label_text" msgid="861796461028298424">"Кулпусун ачуу үчүн, Менюна андан соң 0 баскычын басыңыз."</string>
+ <string name="emergency_call_dialog_number_for_display" msgid="696192103195090970">"Шашылыш чалуу номери"</string>
<string name="lockscreen_carrier_default" msgid="8963839242565653192">"Байланыш жок."</string>
- <!-- no translation found for lockscreen_screen_locked (7288443074806832904) -->
- <skip />
- <!-- no translation found for lockscreen_instructions_when_pattern_enabled (46154051614126049) -->
- <skip />
- <!-- no translation found for lockscreen_instructions_when_pattern_disabled (686260028797158364) -->
- <skip />
- <!-- no translation found for lockscreen_pattern_instructions (7478703254964810302) -->
- <skip />
+ <string name="lockscreen_screen_locked" msgid="7288443074806832904">"Экран кулпуланды."</string>
+ <string name="lockscreen_instructions_when_pattern_enabled" msgid="46154051614126049">"Кулпусун ачып же Шашылыш чалуу аткаруу үчүн менюну басыңыз."</string>
+ <string name="lockscreen_instructions_when_pattern_disabled" msgid="686260028797158364">"Бөгөттөн чыгаруу үчүн Менюну басыңыз."</string>
+ <string name="lockscreen_pattern_instructions" msgid="7478703254964810302">"Кулпуну ачуу үчүн, үлгүнү тартыңыз"</string>
<string name="lockscreen_emergency_call" msgid="5298642613417801888">"Тез жардам"</string>
- <!-- no translation found for lockscreen_return_to_call (5244259785500040021) -->
- <skip />
- <!-- no translation found for lockscreen_pattern_correct (9039008650362261237) -->
- <skip />
+ <string name="lockscreen_return_to_call" msgid="5244259785500040021">"Чалууга кайтуу"</string>
+ <string name="lockscreen_pattern_correct" msgid="9039008650362261237">"Туура!"</string>
<string name="lockscreen_pattern_wrong" msgid="4317955014948108794">"Дагы аракет кылыңыз"</string>
<string name="lockscreen_password_wrong" msgid="5737815393253165301">"Дагы аракет кылыңыз"</string>
<string name="faceunlock_multiple_failures" msgid="754137583022792429">"Жүзүнөн таанып ачуу аракеттеринин чегинен аштыңыз"</string>
<string name="lockscreen_missing_sim_message_short" msgid="5099439277819215399">"SIM-карта жок"</string>
- <!-- no translation found for lockscreen_missing_sim_message (151659196095791474) -->
- <skip />
+ <string name="lockscreen_missing_sim_message" product="tablet" msgid="151659196095791474">"Планшетте SIM-карта жок."</string>
<string name="lockscreen_missing_sim_message" product="tv" msgid="1943633865476989599">"Сыналгыда SIM-карта жок."</string>
- <!-- no translation found for lockscreen_missing_sim_message (2186920585695169078) -->
- <skip />
+ <string name="lockscreen_missing_sim_message" product="default" msgid="2186920585695169078">"Телефондо SIM-карта жок."</string>
<string name="lockscreen_missing_sim_instructions" msgid="5372787138023272615">"SIM-картаны салыңыз."</string>
<string name="lockscreen_missing_sim_instructions_long" msgid="3526573099019319472">"SIM-карта жок же ал окулбайт. SIM-картаны салыңыз."</string>
<string name="lockscreen_permanent_disabled_sim_message_short" msgid="5096149665138916184">"Жараксыз SIM-карта."</string>
@@ -885,18 +676,12 @@
<string name="lockscreen_transport_stop_description" msgid="5907083260651210034">"Токтотуу"</string>
<string name="lockscreen_transport_rew_description" msgid="6944412838651990410">"Артка түрүү"</string>
<string name="lockscreen_transport_ffw_description" msgid="42987149870928985">"Алдыга түрүү"</string>
- <!-- no translation found for emergency_calls_only (6733978304386365407) -->
- <!-- no translation found for emergency_calls_only (2485604591272668370) -->
- <skip />
- <!-- no translation found for lockscreen_network_locked_message (143389224986028501) -->
- <skip />
- <!-- no translation found for lockscreen_sim_puk_locked_message (7441797339976230) -->
- <skip />
+ <string name="emergency_calls_only" msgid="6733978304386365407">"Шашылыш чалуу гана"</string>
+ <string name="lockscreen_network_locked_message" msgid="143389224986028501">"Тармак кулпуланган"</string>
+ <string name="lockscreen_sim_puk_locked_message" msgid="7441797339976230">"SIM-карта PUK-бөгөттө."</string>
<string name="lockscreen_sim_puk_locked_instructions" msgid="8127916255245181063">"Колдонуучунун нускамасын караңыз же Кардарларды тейлөө борборуна кайрылыңыз."</string>
- <!-- no translation found for lockscreen_sim_locked_message (8066660129206001039) -->
- <skip />
- <!-- no translation found for lockscreen_sim_unlock_progress_dialog_message (595323214052881264) -->
- <skip />
+ <string name="lockscreen_sim_locked_message" msgid="8066660129206001039">"SIM-карта бөгөттөлгөн."</string>
+ <string name="lockscreen_sim_unlock_progress_dialog_message" msgid="595323214052881264">"SIM-карта бөгөттөн чыгарылууда…"</string>
<string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"Кулпуну ачуу үлгүсүн <xliff:g id="NUMBER_0">%d</xliff:g> жолу туура эмес тарттыңыз. \n\n <xliff:g id="NUMBER_1">%d</xliff:g> секундадан кийин дагы аракет кылып көрүңүз."</string>
<string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"Сырсөзүңүздү <xliff:g id="NUMBER_0">%d</xliff:g> жолу туура эмес тердиңиз. \n\n <xliff:g id="NUMBER_1">%d</xliff:g> секундадан кийин дагы аракет кылып көрүңүз."</string>
<string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"PIN-кодуңузду <xliff:g id="NUMBER_0">%d</xliff:g> жолу туура эмес тердиңиз. \n\n <xliff:g id="NUMBER_1">%d</xliff:g> секундадан кийин дагы аракет кылып көрүңүз."</string>
@@ -909,35 +694,26 @@
<string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="280873516493934365">"Сиз планшетти бөгөттөн чыгарууга <xliff:g id="NUMBER">%d</xliff:g> жолу туура эмес аракет кылдыңыз. Планшет баштапкы абалына келтирилет."</string>
<string name="lockscreen_failed_attempts_now_wiping" product="tv" msgid="3195755534096192191">"Сыналгыңыздын кулпусун ачууда <xliff:g id="NUMBER">%d</xliff:g>_0 жолу туура эмес аракет кылдыңыз. Сыналгыңыз баштапкы абалга келтирилет."</string>
<string name="lockscreen_failed_attempts_now_wiping" product="default" msgid="3025504721764922246">"Сиз телефонду бөгөттөн чыгарууга <xliff:g id="NUMBER">%d</xliff:g> жолу туура эмес аракет кылдыңыз. Телефон баштапкы абалына келтирилет."</string>
- <!-- no translation found for lockscreen_too_many_failed_attempts_countdown (6251480343394389665) -->
- <skip />
- <!-- no translation found for lockscreen_forgot_pattern_button_text (2626999449610695930) -->
- <skip />
- <!-- no translation found for lockscreen_glogin_forgot_pattern (2588521501166032747) -->
- <skip />
+ <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_too_many_attempts" msgid="2751368605287288808">"Өтө көп үлгү киргизүү аракети болду"</string>
<string name="lockscreen_glogin_instructions" msgid="3931816256100707784">"Бөгөттөн чыгарыш үчүн, Google эсебиңиз менен кириңиз."</string>
- <!-- no translation found for lockscreen_glogin_username_hint (8846881424106484447) -->
- <skip />
- <!-- no translation found for lockscreen_glogin_password_hint (5958028383954738528) -->
- <skip />
- <!-- no translation found for lockscreen_glogin_submit_button (7130893694795786300) -->
- <skip />
- <!-- no translation found for lockscreen_glogin_invalid_input (1364051473347485908) -->
- <skip />
+ <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>
+ <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>
- <!-- no translation found for lockscreen_unlock_label (737440483220667054) -->
- <skip />
- <!-- no translation found for lockscreen_sound_on_label (9068877576513425970) -->
- <skip />
- <!-- no translation found for lockscreen_sound_off_label (996822825154319026) -->
- <skip />
+ <string name="lockscreen_unlock_label" msgid="737440483220667054">"Кулпусун ачуу"</string>
+ <string name="lockscreen_sound_on_label" msgid="9068877576513425970">"Добушу күйүк"</string>
+ <string name="lockscreen_sound_off_label" msgid="996822825154319026">"Добушу өчүк"</string>
<string name="lockscreen_access_pattern_start" msgid="3941045502933142847">"Үлгү башталды"</string>
<string name="lockscreen_access_pattern_cleared" msgid="5583479721001639579">"Үлгү тазаланды"</string>
<string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"Уяча кошулду"</string>
<string name="lockscreen_access_pattern_cell_added_verbose" msgid="7264580781744026939">"<xliff:g id="CELL_INDEX">%1$s</xliff:g> уячасы кошулду"</string>
<string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"Үлгү аягына чыкты"</string>
+ <string name="lockscreen_access_pattern_area" msgid="400813207572953209">"Үлгү аймагы."</string>
<string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. %3$d ичинен %2$d виджет."</string>
<string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"Виджет кошуу."</string>
<string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"Бош"</string>
@@ -959,69 +735,45 @@
<string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"Сырсөз менен ачуу."</string>
<string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"Үлгү аймагы."</string>
<string name="keyguard_accessibility_slide_area" msgid="6736064494019979544">"Жылмыштыруу аймагы."</string>
- <!-- no translation found for password_keyboard_label_symbol_key (992280756256536042) -->
- <skip />
- <!-- no translation found for password_keyboard_label_alpha_key (8001096175167485649) -->
- <skip />
- <!-- no translation found for password_keyboard_label_alt_key (1284820942620288678) -->
- <skip />
+ <string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
+ <string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"АБВ"</string>
+ <string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
<string name="granularity_label_character" msgid="7336470535385009523">"белги"</string>
<string name="granularity_label_word" msgid="7075570328374918660">"сөз"</string>
<string name="granularity_label_link" msgid="5815508880782488267">"шилтеме"</string>
<string name="granularity_label_line" msgid="5764267235026120888">"сап"</string>
<string name="hour_ampm" msgid="4584338083529355982">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%P</xliff:g>"</string>
<string name="hour_cap_ampm" msgid="2083465992940444366">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%p</xliff:g>"</string>
- <!-- no translation found for factorytest_failed (5410270329114212041) -->
- <skip />
- <!-- no translation found for factorytest_not_system (4435201656767276723) -->
- <skip />
- <!-- no translation found for factorytest_no_action (872991874799998561) -->
- <skip />
- <!-- no translation found for factorytest_reboot (6320168203050791643) -->
- <skip />
+ <string name="factorytest_failed" msgid="5410270329114212041">"Заводдук сынак ишке ашкан жок"</string>
+ <string name="factorytest_not_system" msgid="4435201656767276723">"FACTORY_TEST аракети /system/app ичинде орнотулган топтомдор үчүн гана колдоого алынат."</string>
+ <string name="factorytest_no_action" msgid="872991874799998561">"FACTORY_TEST аракетин камсыздаган эч бир топтом табылган жок."</string>
+ <string name="factorytest_reboot" msgid="6320168203050791643">"Өчүрүп-күйгүзүү"</string>
<string name="js_dialog_title" msgid="1987483977834603872">"\"<xliff:g id="TITLE">%s</xliff:g>\" барагы кийинкини кайтарды:"</string>
- <!-- no translation found for js_dialog_title_default (6961903213729667573) -->
- <skip />
+ <string name="js_dialog_title_default" msgid="6961903213729667573">"JavaScript"</string>
<string name="js_dialog_before_unload_title" msgid="2619376555525116593">"Навигацияны ырастоо"</string>
<string name="js_dialog_before_unload_positive_button" msgid="3112752010600484130">"Бул барактан кетүү"</string>
<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>
- <!-- no translation found for save_password_label (6860261758665825069) -->
- <skip />
+ <string name="save_password_label" msgid="6860261758665825069">"Ырастоо"</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>
- <!-- no translation found for autofill_address_summary_name_format (3268041054899214945) -->
- <skip />
- <!-- no translation found for autofill_address_summary_separator (7483307893170324129) -->
- <skip />
- <!-- no translation found for autofill_address_summary_format (4874459455786827344) -->
- <skip />
- <!-- no translation found for autofill_province (2231806553863422300) -->
- <skip />
- <!-- no translation found for autofill_postal_code (4696430407689377108) -->
- <skip />
- <!-- no translation found for autofill_state (6988894195520044613) -->
- <skip />
- <!-- no translation found for autofill_zip_code (8697544592627322946) -->
- <skip />
- <!-- no translation found for autofill_county (237073771020362891) -->
- <skip />
- <!-- no translation found for autofill_island (4020100875984667025) -->
- <skip />
- <!-- no translation found for autofill_district (8400735073392267672) -->
- <skip />
- <!-- no translation found for autofill_department (5343279462564453309) -->
- <skip />
- <!-- no translation found for autofill_prefecture (2028499485065800419) -->
- <skip />
- <!-- no translation found for autofill_parish (8202206105468820057) -->
- <skip />
- <!-- no translation found for autofill_area (3547409050889952423) -->
- <skip />
- <!-- no translation found for autofill_emirate (2893880978835698818) -->
- <skip />
+ <string name="autofill_address_summary_name_format" msgid="3268041054899214945">"$1$2$3"</string>
+ <string name="autofill_address_summary_separator" msgid="7483307893170324129">", "</string>
+ <string name="autofill_address_summary_format" msgid="4874459455786827344">"$1$2$3"</string>
+ <string name="autofill_province" msgid="2231806553863422300">"Провинция"</string>
+ <string name="autofill_postal_code" msgid="4696430407689377108">"Индекс"</string>
+ <string name="autofill_state" msgid="6988894195520044613">"Штат"</string>
+ <string name="autofill_zip_code" msgid="8697544592627322946">"ZIP код"</string>
+ <string name="autofill_county" msgid="237073771020362891">"Округ"</string>
+ <string name="autofill_island" msgid="4020100875984667025">"Арал"</string>
+ <string name="autofill_district" msgid="8400735073392267672">"Район"</string>
+ <string name="autofill_department" msgid="5343279462564453309">"Бөлүм"</string>
+ <string name="autofill_prefecture" msgid="2028499485065800419">"Префектура"</string>
+ <string name="autofill_parish" msgid="8202206105468820057">"Пэриш"</string>
+ <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">"Колдонмого Серепчи ачкан URLдердин тарыхын жана Серепчинин бүктөмөлөрүн окууга уруксат берет. Эскертүү: бул уруксат үчүнчү тараптык интернет-серепчилерге, же интернетке кирүү мүмкүнчүлүгү бар колдонмолорго таасир этпеши мүмкүн."</string>
<string name="permlab_writeHistoryBookmarks" msgid="3714785165273314490">"желе бүктөмөлөрүн жана тарыхын жазуу"</string>
@@ -1034,29 +786,18 @@
<string name="permdesc_addVoicemail" msgid="6604508651428252437">"Колдонмого үн почтаңыздын кирүү кутусуна билдирүүлөрдү кошуу мүмкүнчүлүгүн берет."</string>
<string name="permlab_writeGeolocationPermissions" msgid="5962224158955273932">"Серепчинин гео-жайгашуу уруксаттарын өзгөртүү"</string>
<string name="permdesc_writeGeolocationPermissions" msgid="1083743234522638747">"Колдонмого Серепчинин гео-жайгашуу уруксаттарын өзгөртүү мүмкүнчүлүгүн берет. Кесепеттүү колдонмолор ушундай мүмкүнчүлүктөн пайдаланып ар кайсы вебсайтка жайгашкан жер жөнүндө маалыматтын жөнөтүлүшүнө уруксат берип салышы мүмкүн."</string>
- <!-- no translation found for save_password_message (767344687139195790) -->
- <skip />
- <!-- no translation found for save_password_notnow (6389675316706699758) -->
- <skip />
- <!-- no translation found for save_password_remember (6491879678996749466) -->
- <skip />
- <!-- no translation found for save_password_never (8274330296785855105) -->
- <skip />
+ <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>
- <!-- no translation found for text_copied (4985729524670131385) -->
- <skip />
- <!-- no translation found for more_item_label (4650918923083320495) -->
- <skip />
- <!-- no translation found for prepend_shortcut_label (2572214461676015642) -->
- <skip />
- <!-- no translation found for menu_space_shortcut_label (2410328639272162537) -->
- <skip />
- <!-- no translation found for menu_enter_shortcut_label (2743362785111309668) -->
- <skip />
- <!-- no translation found for menu_delete_shortcut_label (3658178007202748164) -->
- <skip />
- <!-- no translation found for search_go (8298016669822141719) -->
- <skip />
+ <string name="text_copied" msgid="4985729524670131385">"Текст алмашуу буферине көчүрүлдү."</string>
+ <string name="more_item_label" msgid="4650918923083320495">"Дагы"</string>
+ <string name="prepend_shortcut_label" msgid="2572214461676015642">"Меню+"</string>
+ <string name="menu_space_shortcut_label" msgid="2410328639272162537">"боштук"</string>
+ <string name="menu_enter_shortcut_label" msgid="2743362785111309668">"enter"</string>
+ <string name="menu_delete_shortcut_label" msgid="3658178007202748164">"жок кылуу"</string>
+ <string name="search_go" msgid="8298016669822141719">"Издөө"</string>
<string name="search_hint" msgid="1733947260773056054">"Издөө…"</string>
<string name="searchview_description_search" msgid="6749826639098512120">"Издөө"</string>
<string name="searchview_description_query" msgid="5911778593125355124">"Талапты издөө"</string>
@@ -1066,48 +807,29 @@
<string name="enable_explore_by_touch_warning_title" msgid="7460694070309730149">"Сыйпалап изилдөө жандырылсынбы?"</string>
<string name="enable_explore_by_touch_warning_message" product="tablet" msgid="8655887539089910577">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> Сыйпалап изилдөөнү иштеткиси келет. Сыйпалап изилдөө жандырылганда, сиз манжаңыздын астында эмне бар экенин жана угуп же көрө аласыз, же планшетиңиз менен жаңсап иштей аласыз."</string>
<string name="enable_explore_by_touch_warning_message" product="default" msgid="2708199672852373195">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> Сыйпалап изилдөөнү иштеткиси келет. Сыйпалап изилдөө жандырылганда, сиз манжаңыздын астында эмне бар экенин жана угуп же көрө аласыз, же телефонуңуз менен жаңсап иштей аласыз."</string>
- <!-- no translation found for oneMonthDurationPast (7396384508953779925) -->
- <skip />
- <!-- no translation found for beforeOneMonthDurationPast (909134546836499826) -->
- <skip />
+ <string name="oneMonthDurationPast" msgid="7396384508953779925">"1 ай мурун"</string>
+ <string name="beforeOneMonthDurationPast" msgid="909134546836499826">"1 айдан ашык убакыт өттү"</string>
<plurals name="last_num_days" formatted="false" msgid="5104533550723932025">
<item quantity="other">Акыркы <xliff:g id="COUNT_1">%d</xliff:g> күн</item>
<item quantity="one">Акыркы <xliff:g id="COUNT_0">%d</xliff:g> күн</item>
</plurals>
- <!-- no translation found for last_month (3959346739979055432) -->
- <skip />
- <!-- no translation found for older (5211975022815554840) -->
- <skip />
- <!-- no translation found for preposition_for_date (9093949757757445117) -->
- <skip />
- <!-- no translation found for preposition_for_time (5506831244263083793) -->
- <skip />
- <!-- no translation found for preposition_for_year (5040395640711867177) -->
- <skip />
- <!-- no translation found for day (8144195776058119424) -->
- <skip />
- <!-- no translation found for days (4774547661021344602) -->
- <skip />
- <!-- no translation found for hour (2126771916426189481) -->
- <skip />
- <!-- no translation found for hours (894424005266852993) -->
- <skip />
- <!-- no translation found for minute (9148878657703769868) -->
- <skip />
- <!-- no translation found for minutes (5646001005827034509) -->
- <skip />
- <!-- no translation found for second (3184235808021478) -->
- <skip />
- <!-- no translation found for seconds (3161515347216589235) -->
- <skip />
- <!-- no translation found for week (5617961537173061583) -->
- <skip />
- <!-- no translation found for weeks (6509623834583944518) -->
- <skip />
- <!-- no translation found for year (4001118221013892076) -->
- <skip />
- <!-- no translation found for years (6881577717993213522) -->
- <skip />
+ <string name="last_month" msgid="3959346739979055432">"Өткөн ай"</string>
+ <string name="older" msgid="5211975022815554840">"Эскирээк"</string>
+ <string name="preposition_for_date" msgid="9093949757757445117">"<xliff:g id="DATE">%s</xliff:g> күнү"</string>
+ <string name="preposition_for_time" msgid="5506831244263083793">"саат <xliff:g id="TIME">%s</xliff:g>"</string>
+ <string name="preposition_for_year" msgid="5040395640711867177">"<xliff:g id="YEAR">%s</xliff:g>-жылы"</string>
+ <string name="day" msgid="8144195776058119424">"күн"</string>
+ <string name="days" msgid="4774547661021344602">"күн"</string>
+ <string name="hour" msgid="2126771916426189481">"саат"</string>
+ <string name="hours" msgid="894424005266852993">"саат"</string>
+ <string name="minute" msgid="9148878657703769868">"мүн."</string>
+ <string name="minutes" msgid="5646001005827034509">"мүн."</string>
+ <string name="second" msgid="3184235808021478">"сек."</string>
+ <string name="seconds" msgid="3161515347216589235">"сек."</string>
+ <string name="week" msgid="5617961537173061583">"апта"</string>
+ <string name="weeks" msgid="6509623834583944518">"апталар"</string>
+ <string name="year" msgid="4001118221013892076">"жыл"</string>
+ <string name="years" msgid="6881577717993213522">"жылдар"</string>
<plurals name="duration_seconds" formatted="false" msgid="4527986939729687805">
<item quantity="other"><xliff:g id="COUNT">%d</xliff:g> секунд</item>
<item quantity="one">1 секунд</item>
@@ -1123,65 +845,41 @@
<string name="VideoView_error_title" msgid="3534509135438353077">"Видео маселеси"</string>
<string name="VideoView_error_text_invalid_progressive_playback" msgid="3186670335938670444">"Бул видеону ушул түзмөктө агылтып көрсөтүү мүмкүн эмес."</string>
<string name="VideoView_error_text_unknown" msgid="3450439155187810085">"Бул видеону ойнотуу мүмкүн эмес."</string>
- <!-- no translation found for VideoView_error_button (2822238215100679592) -->
- <skip />
- <!-- no translation found for relative_time (1818557177829411417) -->
- <skip />
- <!-- no translation found for noon (7245353528818587908) -->
- <skip />
- <!-- no translation found for Noon (3342127745230013127) -->
- <skip />
- <!-- no translation found for midnight (7166259508850457595) -->
- <skip />
- <!-- no translation found for Midnight (5630806906897892201) -->
- <skip />
- <!-- no translation found for elapsed_time_short_format_mm_ss (4431555943828711473) -->
- <skip />
- <!-- no translation found for elapsed_time_short_format_h_mm_ss (1846071997616654124) -->
- <skip />
- <!-- no translation found for selectAll (6876518925844129331) -->
- <skip />
- <!-- no translation found for cut (3092569408438626261) -->
- <skip />
- <!-- no translation found for copy (2681946229533511987) -->
- <skip />
- <!-- no translation found for paste (5629880836805036433) -->
- <skip />
+ <string name="VideoView_error_button" msgid="2822238215100679592">"Жарайт"</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">"түш"</string>
+ <string name="Noon" msgid="3342127745230013127">"Түш"</string>
+ <string name="midnight" msgid="7166259508850457595">"түн ортосу"</string>
+ <string name="Midnight" msgid="5630806906897892201">"Түн ортосу"</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">"Бардыгын тандоо"</string>
+ <string name="cut" msgid="3092569408438626261">"Кесүү"</string>
+ <string name="copy" msgid="2681946229533511987">"Көчүрүү"</string>
+ <string name="paste" msgid="5629880836805036433">"Чаптоо"</string>
<string name="replace" msgid="5781686059063148930">"Алмаштыруу…"</string>
<string name="delete" msgid="6098684844021697789">"Жок кылуу"</string>
- <!-- no translation found for copyUrl (2538211579596067402) -->
- <skip />
+ <string name="copyUrl" msgid="2538211579596067402">"URL көчүрмөлөө"</string>
<string name="selectTextMode" msgid="1018691815143165326">"Текст тандоо"</string>
- <!-- no translation found for textSelectionCABTitle (5236850394370820357) -->
- <skip />
+ <string name="textSelectionCABTitle" msgid="5236850394370820357">"Текст тандоо"</string>
<string name="addToDictionary" msgid="4352161534510057874">"Сөздүккө кошуу"</string>
<string name="deleteText" msgid="6979668428458199034">"Жок кылуу"</string>
- <!-- no translation found for inputMethod (1653630062304567879) -->
- <skip />
- <!-- no translation found for editTextMenuTitle (4909135564941815494) -->
- <skip />
+ <string name="inputMethod" msgid="1653630062304567879">"Киргизүү ыкмасы"</string>
+ <string name="editTextMenuTitle" msgid="4909135564941815494">"Текст боюнча иштер"</string>
<string name="low_internal_storage_view_title" msgid="5576272496365684834">"Сактагычта орун калбай баратат"</string>
<string name="low_internal_storage_view_text" msgid="6640505817617414371">"Системанын кээ бир функциялары иштебеши мүмкүн"</string>
<string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"Тутумда сактагыч жетишсиз. 250МБ бош орун бар экенин текшерип туруп, өчүрүп күйгүзүңүз."</string>
<string name="app_running_notification_title" msgid="8718335121060787914">"<xliff:g id="APP_NAME">%1$s</xliff:g> иштөөдө"</string>
<string name="app_running_notification_text" msgid="4653586947747330058">"Кенен маалыматтар же колдонмону токтотуш үчүн тийиңиз."</string>
- <!-- no translation found for ok (5970060430562524910) -->
- <skip />
- <!-- no translation found for cancel (6442560571259935130) -->
- <skip />
- <!-- no translation found for yes (5362982303337969312) -->
- <skip />
- <!-- no translation found for no (5141531044935541497) -->
- <skip />
- <!-- no translation found for dialog_alert_title (2049658708609043103) -->
- <skip />
+ <string name="ok" msgid="5970060430562524910">"Жарайт"</string>
+ <string name="cancel" msgid="6442560571259935130">"Жокко чыгаруу"</string>
+ <string name="yes" msgid="5362982303337969312">"Жарайт"</string>
+ <string name="no" msgid="5141531044935541497">"Жокко чыгаруу"</string>
+ <string name="dialog_alert_title" msgid="2049658708609043103">"Көңүл буруңуз"</string>
<string name="loading" msgid="7933681260296021180">"Жүктөлүүдө…"</string>
- <!-- no translation found for capital_on (1544682755514494298) -->
- <skip />
- <!-- no translation found for capital_off (6815870386972805832) -->
- <skip />
- <!-- no translation found for whichApplication (4533185947064773386) -->
- <skip />
+ <string name="capital_on" msgid="1544682755514494298">"ЖАНДЫРЫЛГАН"</string>
+ <string name="capital_off" msgid="6815870386972805832">"ӨЧҮК"</string>
+ <string name="whichApplication" msgid="4533185947064773386">"Аракет колдонууну бүтүрүү"</string>
<string name="whichApplicationNamed" msgid="8260158865936942783">"%1$s аркылуу аракетти аягына чейин чыгаруу"</string>
<string name="whichViewApplication" msgid="3272778576700572102">"Төмөнкү менен ачуу"</string>
<string name="whichViewApplicationNamed" msgid="2286418824011249620">"%1$s менен ачуу"</string>
@@ -1191,8 +889,7 @@
<string name="whichSendApplicationNamed" msgid="2799370240005424391">"%1$s менен бөлүшүү"</string>
<string name="whichHomeApplication" msgid="4307587691506919691">"Башкы бет колдонмосун тандаңыз"</string>
<string name="whichHomeApplicationNamed" msgid="4493438593214760979">"Башкы бет колдонмосу катары %1$s пайдалануу"</string>
- <!-- no translation found for alwaysUse (4583018368000610438) -->
- <skip />
+ <string name="alwaysUse" msgid="4583018368000610438">"Бул аракет үчүн демейки боюнча колдонулсун."</string>
<string name="use_a_different_app" msgid="8134926230585710243">"Башка колдонмону пайдалануу"</string>
<string name="clearDefaultHintMsg" msgid="3252584689512077257">"Тутум жөндөөлөрүндөгү демейкини тазалоо > Колдонмолор > Жүктөлүп алынды."</string>
<string name="chooseActivity" msgid="7486876147751803333">"Аракет тандаңыз"</string>
@@ -1201,32 +898,24 @@
<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>
- <!-- no translation found for aerr_process_silence (4226685530196000222) -->
- <skip />
+ <string name="aerr_process_silence" msgid="4226685530196000222">"Жымжырттык режиминде <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="force_close" msgid="8346072094521265605">"OK"</string>
- <!-- no translation found for report (4060218260984795706) -->
- <skip />
- <!-- no translation found for wait (7147118217226317732) -->
- <skip />
+ <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>
- <!-- no translation found for launch_warning_replace (6202498949970281412) -->
- <skip />
- <!-- no translation found for launch_warning_original (188102023021668683) -->
- <skip />
- <!-- no translation found for screen_compat_mode_scale (3202955667675944499) -->
- <skip />
- <!-- no translation found for screen_compat_mode_show (4013878876486655892) -->
- <skip />
+ <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>
+ <string name="screen_compat_mode_scale" msgid="3202955667675944499">"Шкала"</string>
+ <string name="screen_compat_mode_show" msgid="4013878876486655892">"Ар дайым көрсөтүлсүн"</string>
<string name="screen_compat_mode_hint" msgid="1064524084543304459">"Муну тутум жөндөөлөрүнөн кайра иштетүү > Колдонмолор > Жүктөлүп алынган."</string>
<string name="smv_application" msgid="3307209192155442829">"<xliff:g id="APPLICATION">%1$s</xliff:g> колдонмосу (<xliff:g id="PROCESS">%2$s</xliff:g> процесси) өз алдынча иштеткен StrictMode саясатын бузду."</string>
- <!-- no translation found for smv_process (5120397012047462446) -->
- <skip />
+ <string name="smv_process" msgid="5120397012047462446">"<xliff:g id="PROCESS">%1$s</xliff:g> процесси өзүнүн мажбурланган StrictMode саясатын бузуп койду."</string>
<string name="android_upgrading_title" msgid="1584192285441405746">"Android жаңыртылууда…"</string>
<string name="android_start_title" msgid="8418054686415318207">"Android жүргүзүлүүдө…"</string>
<string name="android_upgrading_fstrim" msgid="8036718871534640010">"Сактагыч ыңгайлаштырылууда."</string>
@@ -1234,53 +923,38 @@
<string name="android_preparing_apk" msgid="8162599310274079154">"<xliff:g id="APPNAME">%1$s</xliff:g> даярдалууда."</string>
<string name="android_upgrading_starting_apps" msgid="451464516346926713">"Колдонмолорду иштетип баштоо"</string>
<string name="android_upgrading_complete" msgid="1405954754112999229">"Жүктөө аякталууда."</string>
- <!-- no translation found for heavy_weight_notification (9087063985776626166) -->
- <skip />
+ <string name="heavy_weight_notification" msgid="9087063985776626166">"<xliff:g id="APP">%1$s</xliff:g> иштеп жатат"</string>
<string name="heavy_weight_notification_detail" msgid="1721681741617898865">"Колдонмого которулуу үчүн тийип коюңуз"</string>
<string name="heavy_weight_switcher_title" msgid="7153167085403298169">"Колдонмолор которуштурулсунбу?"</string>
<string name="heavy_weight_switcher_text" msgid="7022631924534406403">"Жаңы колдонмону иштетээрден мурун, учурда иштеп жатканын өчүрүшүңүз керек."</string>
- <!-- no translation found for old_app_action (493129172238566282) -->
- <skip />
+ <string name="old_app_action" msgid="493129172238566282">"<xliff:g id="OLD_APP">%1$s</xliff:g> колдонмосуна кайтуу"</string>
<string name="old_app_description" msgid="2082094275580358049">"Жаңы колдонмо башталбасын"</string>
- <!-- no translation found for new_app_action (5472756926945440706) -->
- <skip />
+ <string name="new_app_action" msgid="5472756926945440706">"<xliff:g id="OLD_APP">%1$s</xliff:g> колдонмосун жүргүзүү"</string>
<string name="new_app_description" msgid="1932143598371537340">"Эски колдонмону сактабастан токтотуу."</string>
<string name="dump_heap_notification" msgid="2618183274836056542">"<xliff:g id="PROC">%1$s</xliff:g> эстутум чегинен ашып кетти"</string>
<string name="dump_heap_notification_detail" msgid="2075673362317481664">"үймө дамп топтолду; бөлүшүү үчүн тийип коюңуз"</string>
<string name="dump_heap_title" msgid="5864292264307651673">"Үймө дамп бөлүшүлсүнбү?"</string>
<string name="dump_heap_text" msgid="4809417337240334941">"<xliff:g id="PROC">%1$s</xliff:g> процесси өзүнүн <xliff:g id="SIZE">%2$s</xliff:g> процесс чегинен ашып кетти. Үймө дамп сиз үчүн иштеп чыгуучу менен бөлүшүүгө даяр. Абайлаңыз: бул үймө дампта колдонмонун уруксаты бар жеке маалыматыңыз камтылышы мүмкүн."</string>
<string name="sendText" msgid="5209874571959469142">"Текст үчүн аракет тандаңыз"</string>
- <!-- no translation found for volume_ringtone (6885421406845734650) -->
- <skip />
- <!-- no translation found for volume_music (5421651157138628171) -->
- <skip />
- <!-- no translation found for volume_music_hint_playing_through_bluetooth (9165984379394601533) -->
- <skip />
+ <string name="volume_ringtone" msgid="6885421406845734650">"Коңгуроонун үн көлөмү"</string>
+ <string name="volume_music" msgid="5421651157138628171">"Медианын үн көлөмү"</string>
+ <string name="volume_music_hint_playing_through_bluetooth" msgid="9165984379394601533">"Bluetooth аркылуу ойнотулууда"</string>
<string name="volume_music_hint_silent_ringtone_selected" msgid="8310739960973156272">"Үнсүз рингтон орнотулду"</string>
- <!-- no translation found for volume_call (3941680041282788711) -->
- <skip />
- <!-- no translation found for volume_bluetooth_call (2002891926351151534) -->
- <skip />
- <!-- no translation found for volume_alarm (1985191616042689100) -->
- <skip />
- <!-- no translation found for volume_notification (2422265656744276715) -->
- <skip />
- <!-- no translation found for volume_unknown (1400219669770445902) -->
- <skip />
+ <string name="volume_call" msgid="3941680041282788711">"Чалуудагы үн көлөмү"</string>
+ <string name="volume_bluetooth_call" msgid="2002891926351151534">"Bluetooth чалуудагы үн көлөмү"</string>
+ <string name="volume_alarm" msgid="1985191616042689100">"Ойготкучтун үн көлөмү"</string>
+ <string name="volume_notification" msgid="2422265656744276715">"Эскертме үн көлөмү"</string>
+ <string name="volume_unknown" msgid="1400219669770445902">"Үн көлөмү"</string>
<string name="volume_icon_description_bluetooth" msgid="6538894177255964340">"Bluetooth үнүнүн деңгээли"</string>
<string name="volume_icon_description_ringer" msgid="3326003847006162496">"Коңгуроо үнүнүн деңгээли"</string>
<string name="volume_icon_description_incall" msgid="8890073218154543397">"Чалуунун үн деңгээли"</string>
<string name="volume_icon_description_media" msgid="4217311719665194215">"Медиа үнүнүн деңгээли"</string>
<string name="volume_icon_description_notification" msgid="7044986546477282274">"Эскертме үнүнүн деңгээли"</string>
- <!-- no translation found for ringtone_default (3789758980357696936) -->
- <skip />
- <!-- no translation found for ringtone_default_with_actual (8129563480895990372) -->
- <skip />
+ <string name="ringtone_default" msgid="3789758980357696936">"Демейки рингтон"</string>
+ <string name="ringtone_default_with_actual" msgid="8129563480895990372">"Демейки рингтон (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
<string name="ringtone_silent" msgid="7937634392408977062">"Эч бир"</string>
- <!-- no translation found for ringtone_picker_title (3515143939175119094) -->
- <skip />
- <!-- no translation found for ringtone_unknown (5477919988701784788) -->
- <skip />
+ <string name="ringtone_picker_title" msgid="3515143939175119094">"Ринтондор"</string>
+ <string name="ringtone_unknown" msgid="5477919988701784788">"Белгисиз рингтон"</string>
<plurals name="wifi_available" formatted="false" msgid="7900333017752027322">
<item quantity="other">Wi-Fi тармагы жеткиликтүү</item>
<item quantity="one">Wi-Fi тармагы жеткиликтүү</item>
@@ -1316,10 +990,8 @@
<string name="wifi_p2p_frequency_conflict_message" product="tablet" msgid="8012981257742232475">"Планшет <xliff:g id="DEVICE_NAME">%1$s</xliff:g> менен байланышып турганда, Wi-Fi\'дан убактылуу ажыратылат"</string>
<string name="wifi_p2p_frequency_conflict_message" product="tv" msgid="3087858235069421128">"Сыналгы <xliff:g id="DEVICE_NAME">%1$s</xliff:g> менен туташып турган учурда ал Wi-Fi\'дан убактылуу ажыратылат"</string>
<string name="wifi_p2p_frequency_conflict_message" product="default" msgid="7363907213787469151">"Телефон <xliff:g id="DEVICE_NAME">%1$s</xliff:g> менен байланышып турганда, Wi-Fi\'дан убактылуу ажыратылат"</string>
- <!-- no translation found for select_character (3365550120617701745) -->
- <skip />
- <!-- no translation found for sms_control_title (7296612781128917719) -->
- <skip />
+ <string name="select_character" msgid="3365550120617701745">"Символ киргизүү"</string>
+ <string name="sms_control_title" msgid="7296612781128917719">"SMS билдирүүлөр жөнөтүлүүдө"</string>
<string name="sms_control_message" msgid="3867899169651496433">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> көп SMS билдирүүлөрдү жөнөтүп жатат. Бул колдонмо билдирүүлөрдү жөнөтө берсинби?"</string>
<string name="sms_control_yes" msgid="3663725993855816807">"Ооба"</string>
<string name="sms_control_no" msgid="625438561395534982">"Жок"</string>
@@ -1332,38 +1004,28 @@
<string name="sms_short_code_remember_undo_instruction" msgid="4960944133052287484">"Муну кийин Тууралоолор > Колдонмолордон өзгөртө аласыз"</string>
<string name="sms_short_code_confirm_always_allow" msgid="3241181154869493368">"Дайыма уруксат берүү"</string>
<string name="sms_short_code_confirm_never_allow" msgid="446992765774269673">"Эч качан уруксат берилбесин"</string>
- <!-- no translation found for sim_removed_title (6227712319223226185) -->
- <skip />
+ <string name="sim_removed_title" msgid="6227712319223226185">"SIM-карта алынып салынды"</string>
<string name="sim_removed_message" msgid="5450336489923274918">"Уюктук тармакты колдонуу үчүн, жарактуу SIM картаны салып, түзмөктү өчүрүп күйгүзүңүз."</string>
- <!-- no translation found for sim_done_button (827949989369963775) -->
- <skip />
- <!-- no translation found for sim_added_title (3719670512889674693) -->
- <skip />
+ <string name="sim_done_button" msgid="827949989369963775">"Даяр"</string>
+ <string name="sim_added_title" msgid="3719670512889674693">"SIM-карта кошулду"</string>
<string name="sim_added_message" msgid="7797975656153714319">"Уюктук тармакка кирүү үчүн түзмөгүңүздү өчүрүп күйгүзүңүз."</string>
- <!-- no translation found for sim_restart_button (4722407842815232347) -->
- <skip />
- <!-- no translation found for time_picker_dialog_title (8349362623068819295) -->
- <skip />
- <!-- no translation found for date_picker_dialog_title (5879450659453782278) -->
- <skip />
- <!-- no translation found for date_time_set (5777075614321087758) -->
- <skip />
+ <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="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>
- <!-- no translation found for no_permissions (7283357728219338112) -->
- <skip />
+ <string name="no_permissions" msgid="7283357728219338112">"Эч уруксаттын кереги жок"</string>
<string name="perm_costs_money" msgid="4902470324142151116">"бул үчүн акы алынышы мүмкүн"</string>
- <!-- no translation found for dlg_ok (7376953167039865701) -->
- <skip />
+ <string name="dlg_ok" msgid="7376953167039865701">"Жарайт"</string>
<string name="usb_charging_notification_title" msgid="4004114449249406402">"Кубаттоо үчүн USB"</string>
<string name="usb_mtp_notification_title" msgid="8396264943589760855">"Файл өткөрүү үчүн USB"</string>
<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>
- <!-- no translation found for adb_active_notification_title (6729044778949189918) -->
- <skip />
+ <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>
@@ -1371,12 +1033,9 @@
<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>
- <!-- no translation found for fast_scroll_alphabet (5433275485499039199) -->
- <skip />
- <!-- no translation found for fast_scroll_numeric_alphabet (4030170524595123610) -->
- <skip />
- <!-- no translation found for candidates_style (4333913089637062257) -->
- <skip />
+ <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>"талапкерлер"</u></string>
<string name="ext_media_checking_notification_title" msgid="5734005953288045806">"<xliff:g id="NAME">%s</xliff:g> даярдалууда"</string>
<string name="ext_media_checking_notification_message" msgid="4747432538578886744">"Каталар текшерилүүдө"</string>
<string name="ext_media_new_notification_message" msgid="7589986898808506239">"Жаңы <xliff:g id="NAME">%s</xliff:g> аныкталды"</string>
@@ -1422,109 +1081,70 @@
<string name="permdesc_requestInstallPackages" msgid="5740101072486783082">"Колдонмо топтомдорду орнотууга уруксат сурай алат."</string>
<string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"Чен өлчөмүн көзөмөлдөө үчүн эки жолу тийип коюңуз"</string>
<string name="gadget_host_error_inflating" msgid="4882004314906466162">"Виджетти кошуу мүмкүн болбоду."</string>
- <!-- no translation found for ime_action_go (8320845651737369027) -->
- <skip />
- <!-- no translation found for ime_action_search (658110271822807811) -->
- <skip />
- <!-- no translation found for ime_action_send (2316166556349314424) -->
- <skip />
- <!-- no translation found for ime_action_next (3138843904009813834) -->
- <skip />
- <!-- no translation found for ime_action_done (8971516117910934605) -->
- <skip />
- <!-- no translation found for ime_action_previous (1443550039250105948) -->
- <skip />
- <!-- no translation found for ime_action_default (2840921885558045721) -->
- <skip />
- <!-- no translation found for dial_number_using (5789176425167573586) -->
- <skip />
- <!-- no translation found for create_contact_using (4947405226788104538) -->
- <skip />
+ <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_previous" msgid="1443550039250105948">"Мурунку"</string>
+ <string name="ime_action_default" msgid="2840921885558045721">"Аткаруу"</string>
+ <string name="dial_number_using" msgid="5789176425167573586">"<xliff:g id="NUMBER">%s</xliff:g> менен\nномерди терүү"</string>
+ <string name="create_contact_using" msgid="4947405226788104538">"<xliff:g id="NUMBER">%s</xliff:g> менен\nбайланыш түзүү"</string>
<string name="grant_credentials_permission_message_header" msgid="2106103817937859662">"Төмөнкү бир же бир нече колдонмо каттоо эсебиңизге азыр жана кийинчерээк кирүү мүмкүнчүлүгүн сурап жатат."</string>
- <!-- no translation found for grant_credentials_permission_message_footer (3125211343379376561) -->
- <skip />
+ <string name="grant_credentials_permission_message_footer" msgid="3125211343379376561">"Бул өтүнүчкө уруксат бересизби?"</string>
<string name="grant_permissions_header_text" msgid="6874497408201826708">"Жетки талабы"</string>
- <!-- no translation found for allow (7225948811296386551) -->
- <skip />
- <!-- no translation found for deny (2081879885755434506) -->
- <skip />
+ <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">"Кийинки эсепке\nуруксат талап кылынууда: <xliff:g id="ACCOUNT">%s</xliff:g>."</string>
<string name="forward_intent_to_owner" msgid="1207197447013960896">"Бул колдонмо жумуш профилиңиздин сыртында колдонулуп жатат"</string>
<string name="forward_intent_to_work" msgid="621480743856004612">"Бул колдонмону жумуш профилиңизде пайдаланып жатасыз"</string>
- <!-- no translation found for input_method_binding_label (1283557179944992649) -->
- <skip />
- <!-- no translation found for sync_binding_label (3687969138375092423) -->
- <skip />
- <!-- no translation found for accessibility_binding_label (4148120742096474641) -->
- <skip />
- <!-- no translation found for wallpaper_binding_label (1240087844304687662) -->
- <skip />
- <!-- no translation found for chooser_wallpaper (7873476199295190279) -->
- <skip />
+ <string name="input_method_binding_label" msgid="1283557179944992649">"Киргизүү ыкмасы"</string>
+ <string name="sync_binding_label" msgid="3687969138375092423">"Шайкештирүү"</string>
+ <string name="accessibility_binding_label" msgid="4148120742096474641">"Атайын мүмкүнчүлүктөр"</string>
+ <string name="wallpaper_binding_label" msgid="1240087844304687662">"Тушкагаз"</string>
+ <string name="chooser_wallpaper" msgid="7873476199295190279">"Тушкагазды өзгөртүү"</string>
<string name="notification_listener_binding_label" msgid="2014162835481906429">"Эскертүү тыңшагычы"</string>
<string name="condition_provider_service_binding_label" msgid="1321343352906524564">"Шарт түзүүчү"</string>
<string name="vpn_title" msgid="19615213552042827">"VPN иштетилди"</string>
- <!-- no translation found for vpn_title_long (6400714798049252294) -->
- <skip />
+ <string name="vpn_title_long" msgid="6400714798049252294">"VPN <xliff:g id="APP">%s</xliff:g> аркылуу жандырылды"</string>
<string name="vpn_text" msgid="3011306607126450322">"желени башкаруу үчүн басыңыз."</string>
<string name="vpn_text_long" msgid="6407351006249174473">"<xliff:g id="SESSION">%s</xliff:g> менен туташып турат. желени башкаруу үчүн басыңыз."</string>
<string name="vpn_lockdown_connecting" msgid="6443438964440960745">"Дайым иштеген VPN туташууда…"</string>
<string name="vpn_lockdown_connected" msgid="8202679674819213931">"Дайым иштеген VPN туташтырылды"</string>
<string name="vpn_lockdown_error" msgid="6009249814034708175">"Дайым иштеген VPN\'де ката кетти"</string>
<string name="vpn_lockdown_config" msgid="6415899150671537970">"Тийип, тууралаңыз"</string>
- <!-- no translation found for upload_file (2897957172366730416) -->
- <skip />
- <!-- no translation found for no_file_chosen (6363648562170759465) -->
- <skip />
- <!-- no translation found for reset (2448168080964209908) -->
- <skip />
- <!-- no translation found for submit (1602335572089911941) -->
- <skip />
- <!-- no translation found for car_mode_disable_notification_title (3164768212003864316) -->
- <skip />
+ <string name="upload_file" msgid="2897957172366730416">"Файл тандоо"</string>
+ <string name="no_file_chosen" msgid="6363648562170759465">"Эч файл тандалган жок"</string>
+ <string name="reset" msgid="2448168080964209908">"Баштапкы абалга келтирүү"</string>
+ <string name="submit" msgid="1602335572089911941">"Тапшыруу"</string>
+ <string name="car_mode_disable_notification_title" msgid="3164768212003864316">"Унаа режими иштетилген"</string>
<string name="car_mode_disable_notification_message" msgid="8035230537563503262">"Унаа тартибинен чыгуу үчүн басыңыз."</string>
- <!-- no translation found for tethered_notification_title (3146694234398202601) -->
- <skip />
+ <string name="tethered_notification_title" msgid="3146694234398202601">"Жалгаштыруу же хотспот жандырылган"</string>
<string name="tethered_notification_message" msgid="6857031760103062982">"Тууралаш үчүн басыңыз."</string>
- <!-- no translation found for back_button_label (2300470004503343439) -->
- <skip />
- <!-- no translation found for next_button_label (1080555104677992408) -->
- <skip />
- <!-- no translation found for skip_button_label (1275362299471631819) -->
- <skip />
- <!-- no translation found for no_matches (8129421908915840737) -->
- <skip />
- <!-- no translation found for find_on_page (1946799233822820384) -->
- <skip />
+ <string name="back_button_label" msgid="2300470004503343439">"Артка"</string>
+ <string name="next_button_label" msgid="1080555104677992408">"Кийинки"</string>
+ <string name="skip_button_label" msgid="1275362299471631819">"Өткөрүп жиберүү"</string>
+ <string name="no_matches" msgid="8129421908915840737">"Дал келүүлөр жок"</string>
+ <string name="find_on_page" msgid="1946799233822820384">"Барактан табуу"</string>
<plurals name="matches_found" formatted="false" msgid="1210884353962081884">
<item quantity="other"><xliff:g id="TOTAL">%d</xliff:g> ичинен <xliff:g id="INDEX">%d</xliff:g></item>
<item quantity="one">1 дал келүү</item>
</plurals>
- <!-- no translation found for action_mode_done (7217581640461922289) -->
- <skip />
+ <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>
- <!-- no translation found for share (1778686618230011964) -->
- <skip />
- <!-- no translation found for find (4808270900322985960) -->
- <skip />
- <!-- no translation found for websearch (4337157977400211589) -->
- <skip />
+ <string name="share" msgid="1778686618230011964">"Бөлүшүү"</string>
+ <string name="find" msgid="4808270900322985960">"Табуу"</string>
+ <string name="websearch" msgid="4337157977400211589">"Интернеттен издөө"</string>
<string name="find_next" msgid="5742124618942193978">"Кийинкиси"</string>
<string name="find_previous" msgid="2196723669388360506">"Мурункусу"</string>
- <!-- no translation found for gpsNotifTicker (5622683912616496172) -->
- <skip />
- <!-- no translation found for gpsNotifTitle (5446858717157416839) -->
- <skip />
- <!-- no translation found for gpsNotifMessage (1374718023224000702) -->
- <skip />
- <!-- no translation found for gpsVerifYes (2346566072867213563) -->
- <skip />
- <!-- no translation found for gpsVerifNo (1146564937346454865) -->
- <skip />
- <!-- no translation found for sync_too_many_deletes (5296321850662746890) -->
- <skip />
+ <string name="gpsNotifTicker" msgid="5622683912616496172">"<xliff:g id="NAME">%s</xliff:g> колдонуучусу жайгашкан жердин маалыматын сурады"</string>
+ <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="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_really_delete" msgid="2572600103122596243">"Элементтерди жок кылуу"</string>
<string name="sync_undo_deletes" msgid="2941317360600338602">"Жок кылынганды кайтаруу"</string>
@@ -1565,12 +1185,9 @@
<string name="description_target_unlock_tablet" msgid="3833195335629795055">"Бөгөттөн чыгарыш үчүн сүртүңүз."</string>
<string name="keyboard_headset_required_to_hear_password" msgid="7011927352267668657">"Айтылган сырсөз белгилерин угуш үчүн, кулакчын туташтырыңыз."</string>
<string name="keyboard_password_character_no_headset" msgid="2859873770886153678">"Чекит."</string>
- <!-- no translation found for action_bar_home_description (5293600496601490216) -->
- <skip />
- <!-- no translation found for action_bar_up_description (2237496562952152589) -->
- <skip />
- <!-- no translation found for action_menu_overflow_description (2295659037509008453) -->
- <skip />
+ <string name="action_bar_home_description" msgid="5293600496601490216">"Башкы бетке чабыттоо"</string>
+ <string name="action_bar_up_description" msgid="2237496562952152589">"Жогору чабыттоо"</string>
+ <string name="action_menu_overflow_description" msgid="2295659037509008453">"Дагы параметрлер"</string>
<string name="action_bar_home_description_format" msgid="7965984360903693903">"%1$s, %2$s"</string>
<string name="action_bar_home_subtitle_description_format" msgid="6985546530471780727">"%1$s, %2$s, %3$s"</string>
<string name="storage_internal" msgid="4891916833657929263">"Ички сактагыч"</string>
@@ -1578,11 +1195,9 @@
<string name="storage_sd_card_label" msgid="6347111320774379257">"<xliff:g id="MANUFACTURER">%s</xliff:g> SD карта"</string>
<string name="storage_usb_drive" msgid="6261899683292244209">"USB түзмөк"</string>
<string name="storage_usb_drive_label" msgid="4501418548927759953">"<xliff:g id="MANUFACTURER">%s</xliff:g> USB түзмөгү"</string>
- <!-- no translation found for storage_usb (3017954059538517278) -->
- <skip />
+ <string name="storage_usb" msgid="3017954059538517278">"USB эстутуму"</string>
<string name="extract_edit_menu_button" msgid="8940478730496610137">"Өзгөртүү"</string>
- <!-- no translation found for data_usage_warning_title (1955638862122232342) -->
- <skip />
+ <string name="data_usage_warning_title" msgid="1955638862122232342">"Дайындарды колдонуу боюнча эскрт"</string>
<string name="data_usage_warning_body" msgid="2814673551471969954">"Колдонууну көрүш үчүн басыңыз."</string>
<string name="data_usage_3g_limit_title" msgid="4361523876818447683">"2G-3G дайындар чегине жетти"</string>
<string name="data_usage_4g_limit_title" msgid="4609566827219442376">"4G дайындар чегине жетти"</string>
@@ -1596,34 +1211,20 @@
<string name="data_usage_limit_snoozed_body" msgid="7035490278298441767">"Орнотулган чектөөдөн <xliff:g id="SIZE">%s</xliff:g> ашты."</string>
<string name="data_usage_restricted_title" msgid="5965157361036321914">"Фондук трафик чектелген"</string>
<string name="data_usage_restricted_body" msgid="6741521330997452990">"Чектөөнү алыш үчүн басыңыз."</string>
- <!-- no translation found for ssl_certificate (6510040486049237639) -->
- <skip />
- <!-- no translation found for ssl_certificate_is_valid (6825263250774569373) -->
- <skip />
- <!-- no translation found for issued_to (454239480274921032) -->
- <skip />
- <!-- no translation found for common_name (2233209299434172646) -->
- <skip />
- <!-- no translation found for org_name (6973561190762085236) -->
- <skip />
- <!-- no translation found for org_unit (7265981890422070383) -->
- <skip />
- <!-- no translation found for issued_by (2647584988057481566) -->
- <skip />
- <!-- no translation found for validity_period (8818886137545983110) -->
- <skip />
- <!-- no translation found for issued_on (5895017404361397232) -->
- <skip />
- <!-- no translation found for expires_on (3676242949915959821) -->
- <skip />
- <!-- no translation found for serial_number (758814067660862493) -->
- <skip />
- <!-- no translation found for fingerprints (4516019619850763049) -->
- <skip />
- <!-- no translation found for sha256_fingerprint (4391271286477279263) -->
- <skip />
- <!-- no translation found for sha1_fingerprint (7930330235269404581) -->
- <skip />
+ <string name="ssl_certificate" msgid="6510040486049237639">"Коопсуздук тастыктамасы"</string>
+ <string name="ssl_certificate_is_valid" msgid="6825263250774569373">"Бул тастыктама жарактуу."</string>
+ <string name="issued_to" msgid="454239480274921032">"Берилди:"</string>
+ <string name="common_name" msgid="2233209299434172646">"Жалпы аталышы:"</string>
+ <string name="org_name" msgid="6973561190762085236">"Ишкана:"</string>
+ <string name="org_unit" msgid="7265981890422070383">"Ишкана бөлүмү:"</string>
+ <string name="issued_by" msgid="2647584988057481566">"Чыгарган тарап:"</string>
+ <string name="validity_period" msgid="8818886137545983110">"Жарактуу мөөнөтү:"</string>
+ <string name="issued_on" msgid="5895017404361397232">"Берилген күнү:"</string>
+ <string name="expires_on" msgid="3676242949915959821">"Жарактуулук мөөнөтү аяктайт:"</string>
+ <string name="serial_number" msgid="758814067660862493">"Сериялык номери:"</string>
+ <string name="fingerprints" msgid="4516019619850763049">"Манжа издери:"</string>
+ <string name="sha256_fingerprint" msgid="4391271286477279263">"SHA-256 манжа изи:"</string>
+ <string name="sha1_fingerprint" msgid="7930330235269404581">"SHA-1 манжа изи:"</string>
<string name="activity_chooser_view_see_all" msgid="4292569383976636200">"Бардыгын көрүү"</string>
<string name="activity_chooser_view_dialog_title_default" msgid="4710013864974040615">"Аракетти тандаңыз"</string>
<string name="share_action_provider_share_with" msgid="5247684435979149216">"Төмөнкү менен бөлүшүү"</string>
diff --git a/core/res/res/values-lo-rLA/strings.xml b/core/res/res/values-lo-rLA/strings.xml
index 3aee5de..7d673ff 100644
--- a/core/res/res/values-lo-rLA/strings.xml
+++ b/core/res/res/values-lo-rLA/strings.xml
@@ -713,6 +713,7 @@
<string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"ຕາລາງຖືກເພີ່ມແລ້ວ"</string>
<string name="lockscreen_access_pattern_cell_added_verbose" msgid="7264580781744026939">"ເພີ່ມ <xliff:g id="CELL_INDEX">%1$s</xliff:g> ເຊລເຂົ້າແລ້ວ"</string>
<string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"ຮູບແບບສຳເລັດແລ້ວ"</string>
+ <string name="lockscreen_access_pattern_area" msgid="400813207572953209">"ພື້ນທີ່ຮູບແບບ."</string>
<string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. ວິດເຈັດ %2$d ຈາກທັງໝົດ %3$d."</string>
<string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"ເພີ່ມວິດເຈັດ"</string>
<string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"ຫວ່າງເປົ່າ"</string>
@@ -897,8 +898,7 @@
<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>
- <!-- no translation found for aerr_process_silence (4226685530196000222) -->
- <skip />
+ <string name="aerr_process_silence" msgid="4226685530196000222">"ຄວາມງຽບຂັດຂ້ອງຈາກ <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>
diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml
index 70bdcb8..3efcd84 100644
--- a/core/res/res/values-lt/strings.xml
+++ b/core/res/res/values-lt/strings.xml
@@ -715,6 +715,7 @@
<string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"Pridėtas langelis"</string>
<string name="lockscreen_access_pattern_cell_added_verbose" msgid="7264580781744026939">"Pridėtas <xliff:g id="CELL_INDEX">%1$s</xliff:g> taškas"</string>
<string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"Šablonas užbaigtas"</string>
+ <string name="lockscreen_access_pattern_area" msgid="400813207572953209">"Atrakinimo pagal piešinį sritis."</string>
<string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. %2$d valdiklis iš %3$d."</string>
<string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"Pridėti valdiklį."</string>
<string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"Tuščia"</string>
@@ -907,8 +908,7 @@
<string name="aerr_title" msgid="1905800560317137752"></string>
<string name="aerr_application" msgid="932628488013092776">"Deja, <xliff:g id="APPLICATION">%1$s</xliff:g> sustojo."</string>
<string name="aerr_process" msgid="4507058997035697579">"Deja, <xliff:g id="PROCESS">%1$s</xliff:g> sustojo."</string>
- <!-- no translation found for aerr_process_silence (4226685530196000222) -->
- <skip />
+ <string name="aerr_process_silence" msgid="4226685530196000222">"Nutildyti „<xliff:g id="PROCESS">%1$s</xliff:g>“ strigtis iki paleidimo iš naujo."</string>
<string name="anr_title" msgid="4351948481459135709"></string>
<string name="anr_activity_application" msgid="1904477189057199066">"„<xliff:g id="APPLICATION">%2$s</xliff:g>“ neatsako.\n\nAr norite ją uždaryti?"</string>
<string name="anr_activity_process" msgid="5776209883299089767">"Veiksmas „<xliff:g id="ACTIVITY">%1$s</xliff:g>“ neatsako.\n\nAr norite jį uždaryti?"</string>
diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml
index 1a3745f..c91041e 100644
--- a/core/res/res/values-lv/strings.xml
+++ b/core/res/res/values-lv/strings.xml
@@ -435,8 +435,7 @@
<string name="fingerprint_name_template" msgid="5870957565512716938">"<xliff:g id="FINGERID">%d</xliff:g>. pirksts"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
- <!-- no translation found for fingerprint_icon_content_description (2340202869968465936) -->
- <skip />
+ <string name="fingerprint_icon_content_description" msgid="2340202869968465936">"Pirksta nospieduma ikona"</string>
<string name="permlab_readSyncSettings" msgid="6201810008230503052">"lasīt sinhronizācijas iestatījumus"</string>
<string name="permdesc_readSyncSettings" msgid="2706745674569678644">"Ļauj lietotnei lasīt konta sinhronizācijas iestatījumus. Piemēram, šādi var noteikt, vai lietotne Personas ir sinhronizēta ar kontu."</string>
<string name="permlab_writeSyncSettings" msgid="5408694875793945314">"ieslēgt un izslēgt sinhronizāciju"</string>
@@ -715,6 +714,7 @@
<string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"Šūna pievienota"</string>
<string name="lockscreen_access_pattern_cell_added_verbose" msgid="7264580781744026939">"Pievienota <xliff:g id="CELL_INDEX">%1$s</xliff:g>. šūna"</string>
<string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"Kombinācija pabeigta"</string>
+ <string name="lockscreen_access_pattern_area" msgid="400813207572953209">"Kombinācijas ievades apgabals."</string>
<string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. %2$d. logrīks no %3$d."</string>
<string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"Pievienot logrīku."</string>
<string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"Tukšs"</string>
@@ -903,8 +903,7 @@
<string name="aerr_title" msgid="1905800560317137752"></string>
<string name="aerr_application" msgid="932628488013092776">"Diemžēl lietojumprogrammas <xliff:g id="APPLICATION">%1$s</xliff:g> darbība ir apturēta."</string>
<string name="aerr_process" msgid="4507058997035697579">"Diemžēl process <xliff:g id="PROCESS">%1$s</xliff:g> ir apturēts."</string>
- <!-- no translation found for aerr_process_silence (4226685530196000222) -->
- <skip />
+ <string name="aerr_process_silence" msgid="4226685530196000222">"Lietojumprogramma Silence avarē no procesa <xliff:g id="PROCESS">%1$s</xliff:g>, kamēr netiek atkārtoti palaista."</string>
<string name="anr_title" msgid="4351948481459135709"></string>
<string name="anr_activity_application" msgid="1904477189057199066">"Lietojumprogramma <xliff:g id="APPLICATION">%2$s</xliff:g> nereaģē.\n\nVai vēlaties to aizvērt?"</string>
<string name="anr_activity_process" msgid="5776209883299089767">"Darbība <xliff:g id="ACTIVITY">%1$s</xliff:g> nereaģē.\n\nVai vēlaties to aizvērt?"</string>
diff --git a/core/res/res/values-mcc202-mnc05/config.xml b/core/res/res/values-mcc202-mnc05/config.xml
deleted file mode 100644
index c74f2d7..0000000
--- a/core/res/res/values-mcc202-mnc05/config.xml
+++ /dev/null
@@ -1,43 +0,0 @@
-<?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">
-
- <!-- 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>Vf Tethering,internet.vodafone.gr,,,,,,,,,202,05,,DUN</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 3408df7..9716807 100644
--- a/core/res/res/values-mk-rMK/strings.xml
+++ b/core/res/res/values-mk-rMK/strings.xml
@@ -713,6 +713,7 @@
<string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"Додадена е ќелија"</string>
<string name="lockscreen_access_pattern_cell_added_verbose" msgid="7264580781744026939">"Додадена е ќелија <xliff:g id="CELL_INDEX">%1$s</xliff:g>"</string>
<string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"Шемата е целосна"</string>
+ <string name="lockscreen_access_pattern_area" msgid="400813207572953209">"Место за шема."</string>
<string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. Виџет %2$d од %3$d."</string>
<string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"Додај виџет."</string>
<string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"Празно"</string>
@@ -897,8 +898,7 @@
<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>
- <!-- no translation found for aerr_process_silence (4226685530196000222) -->
- <skip />
+ <string name="aerr_process_silence" msgid="4226685530196000222">"Silence паѓа од <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>
diff --git a/core/res/res/values-ml-rIN/strings.xml b/core/res/res/values-ml-rIN/strings.xml
index a615e3e..5c7a43f 100644
--- a/core/res/res/values-ml-rIN/strings.xml
+++ b/core/res/res/values-ml-rIN/strings.xml
@@ -713,6 +713,7 @@
<string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"സെൽ ചേർത്തു"</string>
<string name="lockscreen_access_pattern_cell_added_verbose" msgid="7264580781744026939">"കളം <xliff:g id="CELL_INDEX">%1$s</xliff:g> ചേർത്തു"</string>
<string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"പാറ്റേൺ പൂർത്തിയാക്കി"</string>
+ <string name="lockscreen_access_pattern_area" msgid="400813207572953209">"പാറ്റേൺ ഏരിയ."</string>
<string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. വിജറ്റ് %2$d / %3$d."</string>
<string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"വിജറ്റ് ചേർക്കുക."</string>
<string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"ശൂന്യം"</string>
@@ -897,8 +898,7 @@
<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>
- <!-- no translation found for aerr_process_silence (4226685530196000222) -->
- <skip />
+ <string name="aerr_process_silence" msgid="4226685530196000222">"റീബൂട്ട് വരെ <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>
diff --git a/core/res/res/values-mn-rMN/strings.xml b/core/res/res/values-mn-rMN/strings.xml
index 9aafcf1..c457247 100644
--- a/core/res/res/values-mn-rMN/strings.xml
+++ b/core/res/res/values-mn-rMN/strings.xml
@@ -713,6 +713,7 @@
<string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"Нүд нэмэгдсэн"</string>
<string name="lockscreen_access_pattern_cell_added_verbose" msgid="7264580781744026939">"<xliff:g id="CELL_INDEX">%1$s</xliff:g> нүд нэмсэн"</string>
<string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"Хээ дуусав"</string>
+ <string name="lockscreen_access_pattern_area" msgid="400813207572953209">"Зурган түгжээсийн хэсэг."</string>
<string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. %3$d. -н %2$d виджет"</string>
<string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"Виджет нэмэх."</string>
<string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"Хоосон"</string>
@@ -897,8 +898,7 @@
<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>
- <!-- no translation found for aerr_process_silence (4226685530196000222) -->
- <skip />
+ <string name="aerr_process_silence" msgid="4226685530196000222">"Дахин эхлүүлэхгүй бол <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>
diff --git a/core/res/res/values-mr-rIN/strings.xml b/core/res/res/values-mr-rIN/strings.xml
index 4a130ee..9cce231 100644
--- a/core/res/res/values-mr-rIN/strings.xml
+++ b/core/res/res/values-mr-rIN/strings.xml
@@ -713,6 +713,7 @@
<string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"सेल जोडला"</string>
<string name="lockscreen_access_pattern_cell_added_verbose" msgid="7264580781744026939">"<xliff:g id="CELL_INDEX">%1$s</xliff:g> सेल जोडला"</string>
<string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"नमुना पूर्ण केला"</string>
+ <string name="lockscreen_access_pattern_area" msgid="400813207572953209">"नमुना क्षेत्र."</string>
<string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. %3$d पैकी %2$d विजेट."</string>
<string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"विजेट जोडा."</string>
<string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"रिक्त"</string>
@@ -897,8 +898,7 @@
<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>
- <!-- no translation found for aerr_process_silence (4226685530196000222) -->
- <skip />
+ <string name="aerr_process_silence" msgid="4226685530196000222">"रीबूट होईपर्यंत <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>
diff --git a/core/res/res/values-ms-rMY/strings.xml b/core/res/res/values-ms-rMY/strings.xml
index b951ba2..0017f2b 100644
--- a/core/res/res/values-ms-rMY/strings.xml
+++ b/core/res/res/values-ms-rMY/strings.xml
@@ -434,8 +434,7 @@
<string name="fingerprint_name_template" msgid="5870957565512716938">"Jari <xliff:g id="FINGERID">%d</xliff:g>"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
- <!-- no translation found for fingerprint_icon_content_description (2340202869968465936) -->
- <skip />
+ <string name="fingerprint_icon_content_description" msgid="2340202869968465936">"Ikon cap jari"</string>
<string name="permlab_readSyncSettings" msgid="6201810008230503052">"membaca tetapan penyegerakan"</string>
<string name="permdesc_readSyncSettings" msgid="2706745674569678644">"Membenarkan apl membaca tetapan segerak untuk akaun. Sebagai contoh, ini boleh menentukan sama ada apl Orang disegerakkan dengan akaun."</string>
<string name="permlab_writeSyncSettings" msgid="5408694875793945314">"togol segerak hidup dan mati"</string>
@@ -714,6 +713,7 @@
<string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"Sel ditambahkan"</string>
<string name="lockscreen_access_pattern_cell_added_verbose" msgid="7264580781744026939">"Sel <xliff:g id="CELL_INDEX">%1$s</xliff:g> ditambahkan"</string>
<string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"Corak siap"</string>
+ <string name="lockscreen_access_pattern_area" msgid="400813207572953209">"Kawasan corak."</string>
<string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. Widget %2$d dari %3$d."</string>
<string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"Tambah widget."</string>
<string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"Kosong"</string>
@@ -898,8 +898,7 @@
<string name="aerr_title" msgid="1905800560317137752"></string>
<string name="aerr_application" msgid="932628488013092776">"Malangnya, <xliff:g id="APPLICATION">%1$s</xliff:g> telah berhenti."</string>
<string name="aerr_process" msgid="4507058997035697579">"Malangnya, proses <xliff:g id="PROCESS">%1$s</xliff:g> telah berhenti."</string>
- <!-- no translation found for aerr_process_silence (4226685530196000222) -->
- <skip />
+ <string name="aerr_process_silence" msgid="4226685530196000222">"Senyapkan ranap daripada <xliff:g id="PROCESS">%1$s</xliff:g> sehingga but semula."</string>
<string name="anr_title" msgid="4351948481459135709"></string>
<string name="anr_activity_application" msgid="1904477189057199066">"<xliff:g id="APPLICATION">%2$s</xliff:g> tidak bertindak balas.\n\nAdakah anda mahu menutupnya?"</string>
<string name="anr_activity_process" msgid="5776209883299089767">"Aktiviti <xliff:g id="ACTIVITY">%1$s</xliff:g> tidak bertindak balas. \n\n Adakah anda mahu menutupnya?"</string>
diff --git a/core/res/res/values-my-rMM/strings.xml b/core/res/res/values-my-rMM/strings.xml
index 46c2a45..4ba2827 100644
--- a/core/res/res/values-my-rMM/strings.xml
+++ b/core/res/res/values-my-rMM/strings.xml
@@ -713,6 +713,7 @@
<string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"အကွက်တိုးခြင်း"</string>
<string name="lockscreen_access_pattern_cell_added_verbose" msgid="7264580781744026939">"ဆဲလ် <xliff:g id="CELL_INDEX">%1$s</xliff:g> ပေါင်းထည့်ပြီးပါပြီ"</string>
<string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"ပုံစံပြီးဆုံးခြင်း"</string>
+ <string name="lockscreen_access_pattern_area" msgid="400813207572953209">"ပုံစံနေရာ"</string>
<string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. %3$d ရဲ့ဝဒ်ဂျက် %2$d"</string>
<string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"ဝဒ်ဂျက်ထည့်ရန်"</string>
<string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"အလွတ်"</string>
@@ -897,8 +898,7 @@
<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>
- <!-- no translation found for aerr_process_silence (4226685530196000222) -->
- <skip />
+ <string name="aerr_process_silence" msgid="4226685530196000222">"စက်ကို ပြန်ဖွင့်ပေးခဲ့သည့် အထိ <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>
diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml
index 67b9385..56e2cf2 100644
--- a/core/res/res/values-nb/strings.xml
+++ b/core/res/res/values-nb/strings.xml
@@ -434,8 +434,7 @@
<string name="fingerprint_name_template" msgid="5870957565512716938">"Finger <xliff:g id="FINGERID">%d</xliff:g>"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
- <!-- no translation found for fingerprint_icon_content_description (2340202869968465936) -->
- <skip />
+ <string name="fingerprint_icon_content_description" msgid="2340202869968465936">"Ikon for fingeravtrykk"</string>
<string name="permlab_readSyncSettings" msgid="6201810008230503052">"lese synkroniseringsinnstillinger"</string>
<string name="permdesc_readSyncSettings" msgid="2706745674569678644">"Lar appen lese synkroniseringsinnstillingene for en konto. For eksempel kan den finne ut om Personer-appen er synkronisert med en konto."</string>
<string name="permlab_writeSyncSettings" msgid="5408694875793945314">"slå synkronisering av og på"</string>
@@ -714,6 +713,7 @@
<string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"Celle er lagt til"</string>
<string name="lockscreen_access_pattern_cell_added_verbose" msgid="7264580781744026939">"Celle <xliff:g id="CELL_INDEX">%1$s</xliff:g> er lagt til"</string>
<string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"Mønsteret er fullført"</string>
+ <string name="lockscreen_access_pattern_area" msgid="400813207572953209">"Mønsterområde."</string>
<string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. Modul %2$d av %3$d."</string>
<string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"Legg til modul."</string>
<string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"Tom"</string>
@@ -898,8 +898,7 @@
<string name="aerr_title" msgid="1905800560317137752"></string>
<string name="aerr_application" msgid="932628488013092776">"<xliff:g id="APPLICATION">%1$s</xliff:g> har dessverre stoppet."</string>
<string name="aerr_process" msgid="4507058997035697579">"Prosessen <xliff:g id="PROCESS">%1$s</xliff:g> har dessverre stoppet."</string>
- <!-- no translation found for aerr_process_silence (4226685530196000222) -->
- <skip />
+ <string name="aerr_process_silence" msgid="4226685530196000222">"Appen Silence kræsjer som følge av <xliff:g id="PROCESS">%1$s</xliff:g>, frem til omstart."</string>
<string name="anr_title" msgid="4351948481459135709"></string>
<string name="anr_activity_application" msgid="1904477189057199066">"<xliff:g id="APPLICATION">%2$s</xliff:g> svarer ikke.\n\nVil du lukke appen?"</string>
<string name="anr_activity_process" msgid="5776209883299089767">"Aktiviteten <xliff:g id="ACTIVITY">%1$s</xliff:g> svarer ikke.\n\nVil du lukke den?"</string>
diff --git a/core/res/res/values-ne-rNP/strings.xml b/core/res/res/values-ne-rNP/strings.xml
index 496d425..0f10385 100644
--- a/core/res/res/values-ne-rNP/strings.xml
+++ b/core/res/res/values-ne-rNP/strings.xml
@@ -713,6 +713,7 @@
<string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"सेल थप गरियो"</string>
<string name="lockscreen_access_pattern_cell_added_verbose" msgid="7264580781744026939">"कक्ष <xliff:g id="CELL_INDEX">%1$s</xliff:g> थपियो"</string>
<string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"ढाँचा पुरा भयो"</string>
+ <string name="lockscreen_access_pattern_area" msgid="400813207572953209">"ढाँचा क्षेत्र।"</string>
<string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. विजेट %2$d of %3$d।"</string>
<string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"विजेट थप गर्नुहोस्।"</string>
<string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"खाली"</string>
@@ -903,8 +904,7 @@
<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>
- <!-- no translation found for aerr_process_silence (4226685530196000222) -->
- <skip />
+ <string name="aerr_process_silence" msgid="4226685530196000222">"साइलेन्स पुनःबुट नभएसम्म <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>
diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml
index e9c9ba2..6ca7c5f 100644
--- a/core/res/res/values-nl/strings.xml
+++ b/core/res/res/values-nl/strings.xml
@@ -434,8 +434,7 @@
<string name="fingerprint_name_template" msgid="5870957565512716938">"Vinger <xliff:g id="FINGERID">%d</xliff:g>"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
- <!-- no translation found for fingerprint_icon_content_description (2340202869968465936) -->
- <skip />
+ <string name="fingerprint_icon_content_description" msgid="2340202869968465936">"Vingerafdruk-pictogram"</string>
<string name="permlab_readSyncSettings" msgid="6201810008230503052">"synchronisatie-instellingen lezen"</string>
<string name="permdesc_readSyncSettings" msgid="2706745674569678644">"Hiermee kan de app de synchronisatie-instellingen voor een account lezen. Dit kan bijvoorbeeld bepalen of de app Personen wordt gesynchroniseerd met een account."</string>
<string name="permlab_writeSyncSettings" msgid="5408694875793945314">"synchronisatie in- en uitschakelen"</string>
@@ -714,6 +713,7 @@
<string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"Cel toegevoegd"</string>
<string name="lockscreen_access_pattern_cell_added_verbose" msgid="7264580781744026939">"Cel <xliff:g id="CELL_INDEX">%1$s</xliff:g> toegevoegd"</string>
<string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"Patroon voltooid"</string>
+ <string name="lockscreen_access_pattern_area" msgid="400813207572953209">"Tekengebied voor patroon."</string>
<string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. Widget %2$d van %3$d."</string>
<string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"Widget toevoegen."</string>
<string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"Leeg"</string>
@@ -898,8 +898,7 @@
<string name="aerr_title" msgid="1905800560317137752"></string>
<string name="aerr_application" msgid="932628488013092776">"<xliff:g id="APPLICATION">%1$s</xliff:g> is gestopt."</string>
<string name="aerr_process" msgid="4507058997035697579">"Het proces <xliff:g id="PROCESS">%1$s</xliff:g> is gestopt."</string>
- <!-- no translation found for aerr_process_silence (4226685530196000222) -->
- <skip />
+ <string name="aerr_process_silence" msgid="4226685530196000222">"Crashes van <xliff:g id="PROCESS">%1$s</xliff:g> negeren tot opnieuw opstarten."</string>
<string name="anr_title" msgid="4351948481459135709"></string>
<string name="anr_activity_application" msgid="1904477189057199066">"<xliff:g id="APPLICATION">%2$s</xliff:g> reageert niet.\n\nWilt u deze app sluiten?"</string>
<string name="anr_activity_process" msgid="5776209883299089767">"Activiteit <xliff:g id="ACTIVITY">%1$s</xliff:g> reageert niet.\n\nWilt u deze activiteit sluiten?"</string>
diff --git a/core/res/res/values-pa-rIN/strings.xml b/core/res/res/values-pa-rIN/strings.xml
index faafe85..dd039d9 100644
--- a/core/res/res/values-pa-rIN/strings.xml
+++ b/core/res/res/values-pa-rIN/strings.xml
@@ -713,6 +713,7 @@
<string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"ਸੈਲ ਜੋੜਿਆ ਗਿਆ"</string>
<string name="lockscreen_access_pattern_cell_added_verbose" msgid="7264580781744026939">"ਸੈਲ <xliff:g id="CELL_INDEX">%1$s</xliff:g> ਜੋੜਿਆ ਗਿਆ"</string>
<string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"ਪੈਟਰਨ ਪੂਰਾ ਕੀਤਾ"</string>
+ <string name="lockscreen_access_pattern_area" msgid="400813207572953209">"ਪੈਟਰਨ ਖੇਤਰ।"</string>
<string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s। %3$d ਦਾ ਵਿਜੇਟ %2$d।"</string>
<string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"ਵਿਜੇਟ ਜੋੜੋ।"</string>
<string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"ਖਾਲੀ"</string>
@@ -897,8 +898,7 @@
<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>
- <!-- no translation found for aerr_process_silence (4226685530196000222) -->
- <skip />
+ <string name="aerr_process_silence" msgid="4226685530196000222">"ਜਦੋਂ ਤੱਕ ਰੀਬੂਟ ਨਹੀਂ ਹੁੰਦਾ ਤਾਂ <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>
diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml
index 070ba9d..5a8bd6a 100644
--- a/core/res/res/values-pl/strings.xml
+++ b/core/res/res/values-pl/strings.xml
@@ -715,6 +715,7 @@
<string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"Dodano komórkę."</string>
<string name="lockscreen_access_pattern_cell_added_verbose" msgid="7264580781744026939">"Dodano komórkę <xliff:g id="CELL_INDEX">%1$s</xliff:g>"</string>
<string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"Wzór ukończony"</string>
+ <string name="lockscreen_access_pattern_area" msgid="400813207572953209">"Obszar wzoru."</string>
<string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. Widżet %2$d z %3$d."</string>
<string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"Dodaj widżet."</string>
<string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"Puste"</string>
@@ -907,8 +908,7 @@
<string name="aerr_title" msgid="1905800560317137752"></string>
<string name="aerr_application" msgid="932628488013092776">"Niestety, aplikacja <xliff:g id="APPLICATION">%1$s</xliff:g> została zatrzymana."</string>
<string name="aerr_process" msgid="4507058997035697579">"Niestety, proces <xliff:g id="PROCESS">%1$s</xliff:g> został zatrzymany."</string>
- <!-- no translation found for aerr_process_silence (4226685530196000222) -->
- <skip />
+ <string name="aerr_process_silence" msgid="4226685530196000222">"Ignoruj awarie aplikacji <xliff:g id="PROCESS">%1$s</xliff:g> do czasu zrestartowania."</string>
<string name="anr_title" msgid="4351948481459135709"></string>
<string name="anr_activity_application" msgid="1904477189057199066">"Aplikacja <xliff:g id="APPLICATION">%2$s</xliff:g> nie reaguje.\n\nCzy chcesz ją zamknąć?"</string>
<string name="anr_activity_process" msgid="5776209883299089767">"Działanie <xliff:g id="ACTIVITY">%1$s</xliff:g> nie odpowiada.\n\nCzy chcesz je zakończyć?"</string>
diff --git a/core/res/res/values-pt-rBR/strings.xml b/core/res/res/values-pt-rBR/strings.xml
index 41dd5e2..0fd4f5e 100644
--- a/core/res/res/values-pt-rBR/strings.xml
+++ b/core/res/res/values-pt-rBR/strings.xml
@@ -713,6 +713,7 @@
<string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"Célula adicionada"</string>
<string name="lockscreen_access_pattern_cell_added_verbose" msgid="7264580781744026939">"Célula <xliff:g id="CELL_INDEX">%1$s</xliff:g> adicionada"</string>
<string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"Padrão concluído"</string>
+ <string name="lockscreen_access_pattern_area" msgid="400813207572953209">"Área do padrão."</string>
<string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. Widget %2$d de %3$d."</string>
<string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"Adicionar widget"</string>
<string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"Vazio"</string>
@@ -897,8 +898,7 @@
<string name="aerr_title" msgid="1905800560317137752"></string>
<string name="aerr_application" msgid="932628488013092776">"O <xliff:g id="APPLICATION">%1$s</xliff:g> parou."</string>
<string name="aerr_process" msgid="4507058997035697579">"O processo <xliff:g id="PROCESS">%1$s</xliff:g> parou."</string>
- <!-- no translation found for aerr_process_silence (4226685530196000222) -->
- <skip />
+ <string name="aerr_process_silence" msgid="4226685530196000222">"Silenciar falhas de <xliff:g id="PROCESS">%1$s</xliff:g> até a reinicialização."</string>
<string name="anr_title" msgid="4351948481459135709"></string>
<string name="anr_activity_application" msgid="1904477189057199066">"<xliff:g id="APPLICATION">%2$s</xliff:g> não está respondendo.\n\nDeseja fechá-lo?"</string>
<string name="anr_activity_process" msgid="5776209883299089767">"A atividade <xliff:g id="ACTIVITY">%1$s</xliff:g> não está respondendo.\n\nDeseja fechá-la?"</string>
diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml
index ff741f6..a056ea9 100644
--- a/core/res/res/values-pt-rPT/strings.xml
+++ b/core/res/res/values-pt-rPT/strings.xml
@@ -713,6 +713,7 @@
<string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"Célula adicionada"</string>
<string name="lockscreen_access_pattern_cell_added_verbose" msgid="7264580781744026939">"Célula <xliff:g id="CELL_INDEX">%1$s</xliff:g> adicionada"</string>
<string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"Sequência concluída"</string>
+ <string name="lockscreen_access_pattern_area" msgid="400813207572953209">"Área da sequência."</string>
<string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. Widget %2$d de %3$d."</string>
<string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"Adicionar widget."</string>
<string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"Vazio"</string>
@@ -897,8 +898,7 @@
<string name="aerr_title" msgid="1905800560317137752"></string>
<string name="aerr_application" msgid="932628488013092776">"Lamentamos, o <xliff:g id="APPLICATION">%1$s</xliff:g> foi interrompido."</string>
<string name="aerr_process" msgid="4507058997035697579">"Lamentamos, o processo <xliff:g id="PROCESS">%1$s</xliff:g> foi interrompido."</string>
- <!-- no translation found for aerr_process_silence (4226685530196000222) -->
- <skip />
+ <string name="aerr_process_silence" msgid="4226685530196000222">"Silenciar falhas de <xliff:g id="PROCESS">%1$s</xliff:g> até reiniciar."</string>
<string name="anr_title" msgid="4351948481459135709"></string>
<string name="anr_activity_application" msgid="1904477189057199066">"<xliff:g id="APPLICATION">%2$s</xliff:g> não está a responder. \n\nPretende fechá-la?"</string>
<string name="anr_activity_process" msgid="5776209883299089767">"A atividade <xliff:g id="ACTIVITY">%1$s</xliff:g> não está a responder. \n\n Pretende fechá-la?"</string>
diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml
index 41dd5e2..0fd4f5e 100644
--- a/core/res/res/values-pt/strings.xml
+++ b/core/res/res/values-pt/strings.xml
@@ -713,6 +713,7 @@
<string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"Célula adicionada"</string>
<string name="lockscreen_access_pattern_cell_added_verbose" msgid="7264580781744026939">"Célula <xliff:g id="CELL_INDEX">%1$s</xliff:g> adicionada"</string>
<string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"Padrão concluído"</string>
+ <string name="lockscreen_access_pattern_area" msgid="400813207572953209">"Área do padrão."</string>
<string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. Widget %2$d de %3$d."</string>
<string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"Adicionar widget"</string>
<string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"Vazio"</string>
@@ -897,8 +898,7 @@
<string name="aerr_title" msgid="1905800560317137752"></string>
<string name="aerr_application" msgid="932628488013092776">"O <xliff:g id="APPLICATION">%1$s</xliff:g> parou."</string>
<string name="aerr_process" msgid="4507058997035697579">"O processo <xliff:g id="PROCESS">%1$s</xliff:g> parou."</string>
- <!-- no translation found for aerr_process_silence (4226685530196000222) -->
- <skip />
+ <string name="aerr_process_silence" msgid="4226685530196000222">"Silenciar falhas de <xliff:g id="PROCESS">%1$s</xliff:g> até a reinicialização."</string>
<string name="anr_title" msgid="4351948481459135709"></string>
<string name="anr_activity_application" msgid="1904477189057199066">"<xliff:g id="APPLICATION">%2$s</xliff:g> não está respondendo.\n\nDeseja fechá-lo?"</string>
<string name="anr_activity_process" msgid="5776209883299089767">"A atividade <xliff:g id="ACTIVITY">%1$s</xliff:g> não está respondendo.\n\nDeseja fechá-la?"</string>
diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml
index 1da95b3..9bfa8e3 100644
--- a/core/res/res/values-ro/strings.xml
+++ b/core/res/res/values-ro/strings.xml
@@ -149,7 +149,7 @@
<string name="httpErrorAuth" msgid="1435065629438044534">"Nu s-a realizat autentificarea."</string>
<string name="httpErrorProxyAuth" msgid="1788207010559081331">"Autentificarea prin intermediul serverului proxy nu a reuşit."</string>
<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="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="httpErrorUnsupportedScheme" msgid="5015730812906192208">"Protocolul nu este acceptat."</string>
@@ -157,7 +157,7 @@
<string name="httpErrorBadUrl" msgid="3636929722728881972">"Pagina nu a putut fi deschisă, deoarece adresa URL nu este validă."</string>
<string name="httpErrorFile" msgid="2170788515052558676">"Fişierul nu a putut fi accesat."</string>
<string name="httpErrorFileNotFound" msgid="6203856612042655084">"Nu s-a putut găsi fişierul solicitat."</string>
- <string name="httpErrorTooManyRequests" msgid="1235396927087188253">"Există prea multe solicitări în curs de procesare. Încercaţi din nou mai târziu."</string>
+ <string name="httpErrorTooManyRequests" msgid="1235396927087188253">"Există prea multe solicitări în curs de procesare. Încercați din nou mai târziu."</string>
<string name="notification_title" msgid="8967710025036163822">"Eroare de conectare pentru <xliff:g id="ACCOUNT">%1$s</xliff:g>"</string>
<string name="contentServiceSync" msgid="8353523060269335667">"Sincronizare"</string>
<string name="contentServiceSyncNotificationTitle" msgid="397743349191901458">"Sincronizare"</string>
@@ -182,7 +182,7 @@
<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="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>
@@ -435,8 +435,7 @@
<string name="fingerprint_name_template" msgid="5870957565512716938">"Degetul <xliff:g id="FINGERID">%d</xliff:g>"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
- <!-- no translation found for fingerprint_icon_content_description (2340202869968465936) -->
- <skip />
+ <string name="fingerprint_icon_content_description" msgid="2340202869968465936">"Pictograma amprentă"</string>
<string name="permlab_readSyncSettings" msgid="6201810008230503052">"citire setări sincronizare"</string>
<string name="permdesc_readSyncSettings" msgid="2706745674569678644">"Permite aplicației să citească setările de sincronizare ale unui cont. De exemplu, cu această permisiune aplicația poate determina dacă aplicația Persoane este sincronizată cu un anumit cont."</string>
<string name="permlab_writeSyncSettings" msgid="5408694875793945314">"activează/dezactivează sincronizarea"</string>
@@ -660,8 +659,8 @@
<string name="lockscreen_emergency_call" msgid="5298642613417801888">"Urgență"</string>
<string name="lockscreen_return_to_call" msgid="5244259785500040021">"Reveniţi la apel"</string>
<string name="lockscreen_pattern_correct" msgid="9039008650362261237">"Corect!"</string>
- <string name="lockscreen_pattern_wrong" msgid="4317955014948108794">"Încercaţi din nou"</string>
- <string name="lockscreen_password_wrong" msgid="5737815393253165301">"Încercaţi din nou"</string>
+ <string name="lockscreen_pattern_wrong" msgid="4317955014948108794">"Încercați din nou"</string>
+ <string name="lockscreen_password_wrong" msgid="5737815393253165301">"Încercați din nou"</string>
<string name="faceunlock_multiple_failures" msgid="754137583022792429">"S-a depăşit numărul maxim de încercări pentru Deblocare facială"</string>
<string name="lockscreen_missing_sim_message_short" msgid="5099439277819215399">"Niciun card SIM"</string>
<string name="lockscreen_missing_sim_message" product="tablet" msgid="151659196095791474">"Nu există card SIM în computerul tablet PC."</string>
@@ -684,19 +683,19 @@
<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>
<string name="lockscreen_sim_unlock_progress_dialog_message" msgid="595323214052881264">"Se deblochează cardul SIM..."</string>
- <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"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="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"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="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"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="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"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 datelor de conectare la Google.\n\n Încercaţi din nou peste <xliff:g id="NUMBER_2">%d</xliff:g> (de) secunde."</string>
+ <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"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="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"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="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"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="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"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 datelor de conectare la Google.\n\n Încercați din nou peste <xliff:g id="NUMBER_2">%d</xliff:g> (de) secunde."</string>
<string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="5316664559603394684">"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 televizorul cu ajutorul datelor de conectare la Google.\n\n Încercați din nou peste <xliff:g id="NUMBER_2">%d</xliff:g> (de) secunde."</string>
- <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"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 datelor de conectare la Google.\n\n Încercaţi din nou peste <xliff:g id="NUMBER_2">%d</xliff:g> (de) secunde."</string>
+ <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"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 datelor de conectare la Google.\n\n Încercați din nou peste <xliff:g id="NUMBER_2">%d</xliff:g> (de) secunde."</string>
<string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"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, aceasta va fi resetată la setările prestabilite din fabrică, iar toate datele de utilizator vor fi pierdute."</string>
<string name="lockscreen_failed_attempts_almost_at_wipe" product="tv" msgid="950408382418270260">"Ați efectuat <xliff:g id="NUMBER_0">%d</xliff:g> încercări incorecte de deblocare a televizorului. După încă <xliff:g id="NUMBER_1">%d</xliff:g> încercări nereușite, televizorul va reveni la setările prestabilite din fabrică, iar toate datele de utilizator se vor pierde."</string>
<string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"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, acesta va fi resetat la setările prestabilite din fabrică, iar toate datele de utilizator vor fi pierdute."</string>
<string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="280873516493934365">"Aţi efectuat <xliff:g id="NUMBER">%d</xliff:g> încercări incorecte de deblocare a tabletei. Tableta va fi acum resetată la setările prestabilite din fabrică."</string>
<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_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_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>
@@ -715,6 +714,7 @@
<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_widget_empty_slot" msgid="1281505703307930757">"Gol"</string>
@@ -805,7 +805,7 @@
<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_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>
@@ -903,8 +903,7 @@
<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>
- <!-- no translation found for aerr_process_silence (4226685530196000222) -->
- <skip />
+ <string name="aerr_process_silence" msgid="4226685530196000222">"Nu mai afișa blocările aplicației <xliff:g id="PROCESS">%1$s</xliff:g> până la repornire."</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>
@@ -1224,7 +1223,7 @@
<string name="ssl_certificate_is_valid" msgid="6825263250774569373">"Certificatul este valid."</string>
<string name="issued_to" msgid="454239480274921032">"Emis către:"</string>
<string name="common_name" msgid="2233209299434172646">"Nume comun:"</string>
- <string name="org_name" msgid="6973561190762085236">"Organizaţie:"</string>
+ <string name="org_name" msgid="6973561190762085236">"Organizație:"</string>
<string name="org_unit" msgid="7265981890422070383">"Unitate organizatorică:"</string>
<string name="issued_by" msgid="2647584988057481566">"Emis de:"</string>
<string name="validity_period" msgid="8818886137545983110">"Validitate:"</string>
@@ -1273,7 +1272,7 @@
<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">%1$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">%1$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_pin_instructions" msgid="2377242233495111557">"Introduceţi codul PIN"</string>
@@ -1295,18 +1294,18 @@
<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_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>
- <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="1575557200627128949">"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, aceasta va fi resetată la setările prestabilite din fabrică, iar toate datele de utilizator se vor pierde."</string>
<string name="kg_failed_attempts_almost_at_wipe" product="tv" msgid="5621231220154419413">"Ați efectuat <xliff:g id="NUMBER_0">%d</xliff:g> încercări incorecte de deblocare a televizorului. După încă <xliff:g id="NUMBER_1">%d</xliff:g> încercări nereușite, televizorul va reveni la setările prestabilite din fabrică, iar toate datele de utilizator se vor pierde."</string>
<string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"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, acesta va fi resetat la setările prestabilite din fabrică, iar toate datele de utilizator se vor pierde."</string>
<string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"Aţi efectuat <xliff:g id="NUMBER">%d</xliff:g> încercări incorecte de deblocare a tabletei. Tableta va fi acum resetată la setările prestabilite din fabrică."</string>
<string name="kg_failed_attempts_now_wiping" product="tv" msgid="4987878286750741463">"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="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"Aţi efectuat <xliff:g id="NUMBER">%d</xliff:g> încercări incorecte de deblocare a telefonului. Telefonul va fi acum resetat la setările prestabilite din fabrică."</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="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="tv" msgid="4224651132862313471">"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 televizorul 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="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_text_message_separator" product="default" msgid="4160700433287233771">" — "</string>
<string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"Eliminaţi"</string>
<string name="safe_media_volume_warning" product="default" msgid="2276318909314492312">"Ridicați volumul mai sus de nivelul recomandat?\n\nAscultarea la volum ridicat pe perioade lungi de timp vă poate afecta auzul."</string>
diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml
index 7d2dd4e..9fe29e1 100644
--- a/core/res/res/values-ru/strings.xml
+++ b/core/res/res/values-ru/strings.xml
@@ -436,8 +436,7 @@
<string name="fingerprint_name_template" msgid="5870957565512716938">"Палец <xliff:g id="FINGERID">%d</xliff:g>"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
- <!-- no translation found for fingerprint_icon_content_description (2340202869968465936) -->
- <skip />
+ <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="permlab_writeSyncSettings" msgid="5408694875793945314">"Включение/выключение синхронизации"</string>
@@ -716,6 +715,7 @@
<string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"Ячейка добавлена"</string>
<string name="lockscreen_access_pattern_cell_added_verbose" msgid="7264580781744026939">"Ячейка <xliff:g id="CELL_INDEX">%1$s</xliff:g> добавлена"</string>
<string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"Графический ключ введен"</string>
+ <string name="lockscreen_access_pattern_area" msgid="400813207572953209">"Область ввода графического ключа."</string>
<string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. Виджет %2$d из %3$d."</string>
<string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"Добавить виджет"</string>
<string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"Пусто"</string>
@@ -908,8 +908,7 @@
<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>
- <!-- no translation found for aerr_process_silence (4226685530196000222) -->
- <skip />
+ <string name="aerr_process_silence" msgid="4226685530196000222">"В режиме полной тишины происходят сбои при запуске приложения \"<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>
diff --git a/core/res/res/values-si-rLK/strings.xml b/core/res/res/values-si-rLK/strings.xml
index 762b8e9..f13a69e 100644
--- a/core/res/res/values-si-rLK/strings.xml
+++ b/core/res/res/values-si-rLK/strings.xml
@@ -713,6 +713,7 @@
<string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"කොටුවක් එකතු කරන ලදි"</string>
<string name="lockscreen_access_pattern_cell_added_verbose" msgid="7264580781744026939">"<xliff:g id="CELL_INDEX">%1$s</xliff:g> කොටුව එකතු කරන ලදි"</string>
<string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"රටාව සම්පූර්ණයි"</string>
+ <string name="lockscreen_access_pattern_area" msgid="400813207572953209">"රටා ප්රදේශය."</string>
<!-- String.format failed for translation -->
<!-- no translation found for keyguard_accessibility_widget_changed (5678624624681400191) -->
<skip />
@@ -899,8 +900,7 @@
<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>
- <!-- no translation found for aerr_process_silence (4226685530196000222) -->
- <skip />
+ <string name="aerr_process_silence" msgid="4226685530196000222">"නැවත පණ ගන්වන තෙක් <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>
diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml
index 0d482e1..27258cf 100644
--- a/core/res/res/values-sk/strings.xml
+++ b/core/res/res/values-sk/strings.xml
@@ -715,6 +715,7 @@
<string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"Bunka bola pridaná"</string>
<string name="lockscreen_access_pattern_cell_added_verbose" msgid="7264580781744026939">"Bola pridaná bunka <xliff:g id="CELL_INDEX">%1$s</xliff:g>"</string>
<string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"Bezpečnostný vzor bol dokončený"</string>
+ <string name="lockscreen_access_pattern_area" msgid="400813207572953209">"Oblasť na zadanie bezpečnostného vzoru."</string>
<string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. Miniaplikácia %2$d z %3$d."</string>
<string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"Pridať miniaplikáciu."</string>
<string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"Prázdne"</string>
@@ -907,8 +908,7 @@
<string name="aerr_title" msgid="1905800560317137752"></string>
<string name="aerr_application" msgid="932628488013092776">"Aplikácia <xliff:g id="APPLICATION">%1$s</xliff:g> bohužiaľ prestala pracovať."</string>
<string name="aerr_process" msgid="4507058997035697579">"Proces <xliff:g id="PROCESS">%1$s</xliff:g> bohužiaľ prestal pracovať."</string>
- <!-- no translation found for aerr_process_silence (4226685530196000222) -->
- <skip />
+ <string name="aerr_process_silence" msgid="4226685530196000222">"Stíšenie zlyháva od procesu <xliff:g id="PROCESS">%1$s</xliff:g> až po reštartovanie."</string>
<string name="anr_title" msgid="4351948481459135709"></string>
<string name="anr_activity_application" msgid="1904477189057199066">"Aplikácia <xliff:g id="APPLICATION">%2$s</xliff:g> neodpovedá.\n\nChcete ju zavrieť?"</string>
<string name="anr_activity_process" msgid="5776209883299089767">"Aktivita <xliff:g id="ACTIVITY">%1$s</xliff:g> neodpovedá.\n\nChcete ju zavrieť?"</string>
diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml
index bb14329..5f38419 100644
--- a/core/res/res/values-sl/strings.xml
+++ b/core/res/res/values-sl/strings.xml
@@ -715,6 +715,7 @@
<string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"Celica je dodana"</string>
<string name="lockscreen_access_pattern_cell_added_verbose" msgid="7264580781744026939">"Dodana <xliff:g id="CELL_INDEX">%1$s</xliff:g>. celica"</string>
<string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"Vzorec je končan"</string>
+ <string name="lockscreen_access_pattern_area" msgid="400813207572953209">"Območje vzorca."</string>
<string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. Pripomoček %2$d za %3$d."</string>
<string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"Dodajanje pripomočka."</string>
<string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"Prazno"</string>
@@ -907,8 +908,7 @@
<string name="aerr_title" msgid="1905800560317137752"></string>
<string name="aerr_application" msgid="932628488013092776">"Žal se je aplikacija <xliff:g id="APPLICATION">%1$s</xliff:g> ustavila."</string>
<string name="aerr_process" msgid="4507058997035697579">"Žal se je postopek <xliff:g id="PROCESS">%1$s</xliff:g> ustavil."</string>
- <!-- no translation found for aerr_process_silence (4226685530196000222) -->
- <skip />
+ <string name="aerr_process_silence" msgid="4226685530196000222">"Utišanje obvestil o zrušitvah procesa <xliff:g id="PROCESS">%1$s</xliff:g> do vnovičnega zagona."</string>
<string name="anr_title" msgid="4351948481459135709"></string>
<string name="anr_activity_application" msgid="1904477189057199066">"Aplikacija <xliff:g id="APPLICATION">%2$s</xliff:g> se ne odziva.\n\nAli jo želite zapreti?"</string>
<string name="anr_activity_process" msgid="5776209883299089767">"Dejavnost <xliff:g id="ACTIVITY">%1$s</xliff:g> se ne odziva.\n\nAli jo želite zapreti?"</string>
diff --git a/core/res/res/values-sq-rAL/strings.xml b/core/res/res/values-sq-rAL/strings.xml
index d5c4e82..370bc9a 100644
--- a/core/res/res/values-sq-rAL/strings.xml
+++ b/core/res/res/values-sq-rAL/strings.xml
@@ -713,6 +713,7 @@
<string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"Qeliza u shtua"</string>
<string name="lockscreen_access_pattern_cell_added_verbose" msgid="7264580781744026939">"Qeliza <xliff:g id="CELL_INDEX">%1$s</xliff:g> u shtua"</string>
<string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"Modeli përfundoi"</string>
+ <string name="lockscreen_access_pattern_area" msgid="400813207572953209">"Zona e motivit."</string>
<string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. Miniaplikacioni %2$d nga %3$d."</string>
<string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"Shto miniaplikacion."</string>
<string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"Bosh"</string>
@@ -897,8 +898,7 @@
<string name="aerr_title" msgid="1905800560317137752"></string>
<string name="aerr_application" msgid="932628488013092776">"Fatkeqësisht, <xliff:g id="APPLICATION">%1$s</xliff:g> ka ndaluar."</string>
<string name="aerr_process" msgid="4507058997035697579">"Fatkeqësisht, procesi <xliff:g id="PROCESS">%1$s</xliff:g> ka ndaluar."</string>
- <!-- no translation found for aerr_process_silence (4226685530196000222) -->
- <skip />
+ <string name="aerr_process_silence" msgid="4226685530196000222">"Ka një heshtje të <xliff:g id="PROCESS">%1$s</xliff:g> deri në rindezje."</string>
<string name="anr_title" msgid="4351948481459135709"></string>
<string name="anr_activity_application" msgid="1904477189057199066">"<xliff:g id="APPLICATION">%2$s</xliff:g> nuk po përgjigjet.\n\nDëshiron ta mbyllësh?"</string>
<string name="anr_activity_process" msgid="5776209883299089767">"Aktiviteti <xliff:g id="ACTIVITY">%1$s</xliff:g> nuk përgjigjet.\n\nDëshiron ta mbyllësh?"</string>
diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml
index a29faa3..8f19379 100644
--- a/core/res/res/values-sr/strings.xml
+++ b/core/res/res/values-sr/strings.xml
@@ -435,8 +435,7 @@
<string name="fingerprint_name_template" msgid="5870957565512716938">"Прст <xliff:g id="FINGERID">%d</xliff:g>"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
- <!-- no translation found for fingerprint_icon_content_description (2340202869968465936) -->
- <skip />
+ <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="permlab_writeSyncSettings" msgid="5408694875793945314">"укључивање и искључивање синхронизације"</string>
@@ -715,6 +714,7 @@
<string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"Ћелија је додата"</string>
<string name="lockscreen_access_pattern_cell_added_verbose" msgid="7264580781744026939">"Ћелија <xliff:g id="CELL_INDEX">%1$s</xliff:g> је додата"</string>
<string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"Образац је довршен"</string>
+ <string name="lockscreen_access_pattern_area" msgid="400813207572953209">"Област шаблона."</string>
<string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. Виџет %2$d од %3$d."</string>
<string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"Додај виџет."</string>
<string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"Празно"</string>
@@ -903,8 +903,7 @@
<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>
- <!-- no translation found for aerr_process_silence (4226685530196000222) -->
- <skip />
+ <string name="aerr_process_silence" msgid="4226685530196000222">"Нечујна отказивања од процеса <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> не рeагује.\n\nДа ли желите да је затворите?"</string>
diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml
index 4986d82..467c3dc 100644
--- a/core/res/res/values-sv/strings.xml
+++ b/core/res/res/values-sv/strings.xml
@@ -713,6 +713,7 @@
<string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"En cell har lagts till"</string>
<string name="lockscreen_access_pattern_cell_added_verbose" msgid="7264580781744026939">"Cell <xliff:g id="CELL_INDEX">%1$s</xliff:g> har lagts till"</string>
<string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"Grafiskt lösenord har slutförts"</string>
+ <string name="lockscreen_access_pattern_area" msgid="400813207572953209">"Fält för grafiskt lösenord."</string>
<string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. Widget %2$d av %3$d."</string>
<string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"Lägg till en widget."</string>
<string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"Tom"</string>
@@ -897,8 +898,7 @@
<string name="aerr_title" msgid="1905800560317137752"></string>
<string name="aerr_application" msgid="932628488013092776">"<xliff:g id="APPLICATION">%1$s</xliff:g> har tyvärr stoppats."</string>
<string name="aerr_process" msgid="4507058997035697579">"Processen <xliff:g id="PROCESS">%1$s</xliff:g> har tyvärr stoppats."</string>
- <!-- no translation found for aerr_process_silence (4226685530196000222) -->
- <skip />
+ <string name="aerr_process_silence" msgid="4226685530196000222">"Ignorera krascher från <xliff:g id="PROCESS">%1$s</xliff:g> fram till omstart."</string>
<string name="anr_title" msgid="4351948481459135709"></string>
<string name="anr_activity_application" msgid="1904477189057199066">"<xliff:g id="APPLICATION">%2$s</xliff:g> svarar inte.\n\nVill du stänga den?"</string>
<string name="anr_activity_process" msgid="5776209883299089767">"Aktiviteten <xliff:g id="ACTIVITY">%1$s</xliff:g> svarar inte.\n \nVill du stänga den?"</string>
diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml
index 0ce1e53..25f8ded 100644
--- a/core/res/res/values-sw/strings.xml
+++ b/core/res/res/values-sw/strings.xml
@@ -715,6 +715,7 @@
<string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"Kiini kimeongezwa"</string>
<string name="lockscreen_access_pattern_cell_added_verbose" msgid="7264580781744026939">"Kisanduku <xliff:g id="CELL_INDEX">%1$s</xliff:g> kimeongezwa"</string>
<string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"Ruwaza imekamilika"</string>
+ <string name="lockscreen_access_pattern_area" msgid="400813207572953209">"Eneo la ruwaza."</string>
<string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. Wijeti %2$d ya %3$d."</string>
<string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"Ongeza wijeti."</string>
<string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"Tupu"</string>
@@ -899,8 +900,7 @@
<string name="aerr_title" msgid="1905800560317137752"></string>
<string name="aerr_application" msgid="932628488013092776">"Kwa bahati mbaya, <xliff:g id="APPLICATION">%1$s</xliff:g> imeacha kufanya kazi."</string>
<string name="aerr_process" msgid="4507058997035697579">"Kwa bahati mbaya, mchakato wa <xliff:g id="PROCESS">%1$s</xliff:g> umekoma."</string>
- <!-- no translation found for aerr_process_silence (4226685530196000222) -->
- <skip />
+ <string name="aerr_process_silence" msgid="4226685530196000222">"Programu imekoma kufanya kazi kuanzia <xliff:g id="PROCESS">%1$s</xliff:g> mpaka iwashwe tena."</string>
<string name="anr_title" msgid="4351948481459135709"></string>
<string name="anr_activity_application" msgid="1904477189057199066">"<xliff:g id="APPLICATION">%2$s</xliff:g> haifanyi kazi.\n\nUnataka kuifunga?"</string>
<string name="anr_activity_process" msgid="5776209883299089767">"Shughuli ya <xliff:g id="ACTIVITY">%1$s</xliff:g> haifanyi kazi.\n\nJe, ungependa kuifunga?"</string>
diff --git a/core/res/res/values-ta-rIN/strings.xml b/core/res/res/values-ta-rIN/strings.xml
index c548188..7795025 100644
--- a/core/res/res/values-ta-rIN/strings.xml
+++ b/core/res/res/values-ta-rIN/strings.xml
@@ -713,6 +713,7 @@
<string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"கலம் சேர்க்கப்பட்டது"</string>
<string name="lockscreen_access_pattern_cell_added_verbose" msgid="7264580781744026939">"கலம் <xliff:g id="CELL_INDEX">%1$s</xliff:g> சேர்க்கப்பட்டது"</string>
<string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"வடிவம் நிறைவடைந்தது"</string>
+ <string name="lockscreen_access_pattern_area" msgid="400813207572953209">"வடிவப் பகுதி."</string>
<string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. விட்ஜெட் %2$d / %3$d."</string>
<string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"விட்ஜெட்டைச் சேர்க்கவும்."</string>
<string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"காலியானது"</string>
@@ -897,8 +898,7 @@
<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>
- <!-- no translation found for aerr_process_silence (4226685530196000222) -->
- <skip />
+ <string name="aerr_process_silence" msgid="4226685530196000222">"<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>
diff --git a/core/res/res/values-te-rIN/strings.xml b/core/res/res/values-te-rIN/strings.xml
index 8dd6070..860738a 100644
--- a/core/res/res/values-te-rIN/strings.xml
+++ b/core/res/res/values-te-rIN/strings.xml
@@ -713,6 +713,7 @@
<string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"గడి జోడించబడింది"</string>
<string name="lockscreen_access_pattern_cell_added_verbose" msgid="7264580781744026939">"<xliff:g id="CELL_INDEX">%1$s</xliff:g>వ సెల్ను జోడించారు"</string>
<string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"నమూనా పూర్తయింది"</string>
+ <string name="lockscreen_access_pattern_area" msgid="400813207572953209">"నమూనా ప్రాంతం."</string>
<string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. %3$dలో విడ్జెట్ %2$d."</string>
<string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"విడ్జెట్ను జోడించండి."</string>
<string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"ఖాళీ"</string>
@@ -897,8 +898,7 @@
<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>
- <!-- no translation found for aerr_process_silence (4226685530196000222) -->
- <skip />
+ <string name="aerr_process_silence" msgid="4226685530196000222">"రీబూట్ చేసే వరకు <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>
diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml
index 8e51472..27a1e9a 100644
--- a/core/res/res/values-th/strings.xml
+++ b/core/res/res/values-th/strings.xml
@@ -713,6 +713,7 @@
<string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"เพิ่มเซลแล้ว"</string>
<string name="lockscreen_access_pattern_cell_added_verbose" msgid="7264580781744026939">"เพิ่มแล้ว <xliff:g id="CELL_INDEX">%1$s</xliff:g> เซลล์"</string>
<string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"วาดรูปแบบเสร็จสิ้น"</string>
+ <string name="lockscreen_access_pattern_area" msgid="400813207572953209">"พื้นที่สำหรับรูปแบบ"</string>
<string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s วิดเจ็ต %2$d ของ %3$d"</string>
<string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"เพิ่มวิดเจ็ต"</string>
<string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"ว่าง"</string>
@@ -897,8 +898,7 @@
<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>
- <!-- no translation found for aerr_process_silence (4226685530196000222) -->
- <skip />
+ <string name="aerr_process_silence" msgid="4226685530196000222">"เกิดข้อขัดข้องกับ Silence จากขั้นตอน <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>
diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml
index 3a5f7d7..b33e498 100644
--- a/core/res/res/values-tl/strings.xml
+++ b/core/res/res/values-tl/strings.xml
@@ -713,6 +713,7 @@
<string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"Idinagdag ang cell"</string>
<string name="lockscreen_access_pattern_cell_added_verbose" msgid="7264580781744026939">"Idinagdag ang cell <xliff:g id="CELL_INDEX">%1$s</xliff:g>"</string>
<string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"Nakumpleto ang pattern"</string>
+ <string name="lockscreen_access_pattern_area" msgid="400813207572953209">"Bahagi ng pattern."</string>
<string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. Widget %2$d ng %3$d."</string>
<string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"Magdagdag ng widget."</string>
<string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"Walang laman"</string>
@@ -897,8 +898,7 @@
<string name="aerr_title" msgid="1905800560317137752"></string>
<string name="aerr_application" msgid="932628488013092776">"Sa kasamaang palad, huminto ang <xliff:g id="APPLICATION">%1$s</xliff:g>."</string>
<string name="aerr_process" msgid="4507058997035697579">"Sa kasamaang palad, nahinto ang prosesong <xliff:g id="PROCESS">%1$s</xliff:g>."</string>
- <!-- no translation found for aerr_process_silence (4226685530196000222) -->
- <skip />
+ <string name="aerr_process_silence" msgid="4226685530196000222">"Nag-crash ang Silence mula sa <xliff:g id="PROCESS">%1$s</xliff:g> hanggang sa pag-reboot."</string>
<string name="anr_title" msgid="4351948481459135709"></string>
<string name="anr_activity_application" msgid="1904477189057199066">"Hindi tumutugon ang <xliff:g id="APPLICATION">%2$s</xliff:g>.\n\nNais mo ba itong isara?"</string>
<string name="anr_activity_process" msgid="5776209883299089767">"Hindi tumutugon ang aktibidad na <xliff:g id="ACTIVITY">%1$s</xliff:g>.\n\nNais mo ba itong isara?"</string>
diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml
index eaf0d3e..223fdb1 100644
--- a/core/res/res/values-tr/strings.xml
+++ b/core/res/res/values-tr/strings.xml
@@ -434,8 +434,7 @@
<string name="fingerprint_name_template" msgid="5870957565512716938">"<xliff:g id="FINGERID">%d</xliff:g>. parmak"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
- <!-- no translation found for fingerprint_icon_content_description (2340202869968465936) -->
- <skip />
+ <string name="fingerprint_icon_content_description" msgid="2340202869968465936">"Parmak izi simgesi"</string>
<string name="permlab_readSyncSettings" msgid="6201810008230503052">"senk. ayarlarını okuma"</string>
<string name="permdesc_readSyncSettings" msgid="2706745674569678644">"Uygulamaya bir hesaba ait senkronizasyon ayarlarını okuma izni verir. Örneğin, bu izne sahip bir uygulama Kişiler uygulamasının bir hesapla senkronize olup olmadığını belirleyebilir."</string>
<string name="permlab_writeSyncSettings" msgid="5408694875793945314">"senkronizasyonu açma/kapatma"</string>
@@ -714,6 +713,7 @@
<string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"Hücre eklendi"</string>
<string name="lockscreen_access_pattern_cell_added_verbose" msgid="7264580781744026939">"<xliff:g id="CELL_INDEX">%1$s</xliff:g>. hücre eklendi"</string>
<string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"Desen tamamlandı"</string>
+ <string name="lockscreen_access_pattern_area" msgid="400813207572953209">"Desen alanı."</string>
<string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. Widget %2$d / %3$d."</string>
<string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"Widget ekleyin."</string>
<string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"Boş"</string>
@@ -898,8 +898,7 @@
<string name="aerr_title" msgid="1905800560317137752"></string>
<string name="aerr_application" msgid="932628488013092776">"Maalesef <xliff:g id="APPLICATION">%1$s</xliff:g> durdu."</string>
<string name="aerr_process" msgid="4507058997035697579">"Maalesef <xliff:g id="PROCESS">%1$s</xliff:g> işlemi durdu."</string>
- <!-- no translation found for aerr_process_silence (4226685530196000222) -->
- <skip />
+ <string name="aerr_process_silence" msgid="4226685530196000222">"Yeniden başlatılana kadar <xliff:g id="PROCESS">%1$s</xliff:g> kilitlenmelerini yoksay."</string>
<string name="anr_title" msgid="4351948481459135709"></string>
<string name="anr_activity_application" msgid="1904477189057199066">"<xliff:g id="APPLICATION">%2$s</xliff:g> yanıt vermiyor.\n\nKapatmak ister misiniz?"</string>
<string name="anr_activity_process" msgid="5776209883299089767">"<xliff:g id="ACTIVITY">%1$s</xliff:g> yanıt vermiyor.\n\nKapatmak ister misiniz?"</string>
diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml
index 70c366b..4e17662 100644
--- a/core/res/res/values-uk/strings.xml
+++ b/core/res/res/values-uk/strings.xml
@@ -715,6 +715,7 @@
<string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"Телефон додано"</string>
<string name="lockscreen_access_pattern_cell_added_verbose" msgid="7264580781744026939">"Додано крапку <xliff:g id="CELL_INDEX">%1$s</xliff:g>"</string>
<string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"Малювання ключа закінчено"</string>
+ <string name="lockscreen_access_pattern_area" msgid="400813207572953209">"Область ключа."</string>
<string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. Віджет %2$d з %3$d."</string>
<string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"Додати віджет."</string>
<string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"Порожня область"</string>
@@ -907,8 +908,7 @@
<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>
- <!-- no translation found for aerr_process_silence (4226685530196000222) -->
- <skip />
+ <string name="aerr_process_silence" msgid="4226685530196000222">"Не показувати інформацію про збої додатка <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>
diff --git a/core/res/res/values-ur-rPK/strings.xml b/core/res/res/values-ur-rPK/strings.xml
index 68b49f58..2a5c5ea 100644
--- a/core/res/res/values-ur-rPK/strings.xml
+++ b/core/res/res/values-ur-rPK/strings.xml
@@ -434,8 +434,7 @@
<string name="fingerprint_name_template" msgid="5870957565512716938">"انگلی <xliff:g id="FINGERID">%d</xliff:g>"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
- <!-- no translation found for fingerprint_icon_content_description (2340202869968465936) -->
- <skip />
+ <string name="fingerprint_icon_content_description" msgid="2340202869968465936">"فنگر پرنٹ آئیکن"</string>
<string name="permlab_readSyncSettings" msgid="6201810008230503052">"مطابقت پذیری کی ترتیبات پڑھیں"</string>
<string name="permdesc_readSyncSettings" msgid="2706745674569678644">"ایپ کو کسی اکاؤنٹ کیلئے مطابقت پذیری کی ترتیبات پڑھنے کی اجازت دیتا ہے۔ مثلا، یہ تعین کرسکتا ہے کہ آیا People ایپ کسی اکاؤنٹ کے ساتھ مطابقت پذیر ہے۔"</string>
<string name="permlab_writeSyncSettings" msgid="5408694875793945314">"مطابقت پذیری آن اور آف ٹوگل کریں"</string>
@@ -714,6 +713,7 @@
<string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"سیل شامل کر دیا گیا"</string>
<string name="lockscreen_access_pattern_cell_added_verbose" msgid="7264580781744026939">"سیل <xliff:g id="CELL_INDEX">%1$s</xliff:g> شامل ہو گيا"</string>
<string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"پیٹرن مکمل ہو گیا"</string>
+ <string name="lockscreen_access_pattern_area" msgid="400813207572953209">"پیٹرن کا علاقہ۔"</string>
<string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s۔ ویجیٹ %2$d از %3$d۔"</string>
<string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"ویجیٹ شامل کریں"</string>
<string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"خالی"</string>
@@ -898,8 +898,7 @@
<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>
- <!-- no translation found for aerr_process_silence (4226685530196000222) -->
- <skip />
+ <string name="aerr_process_silence" msgid="4226685530196000222">"<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>
diff --git a/core/res/res/values-uz-rUZ/strings.xml b/core/res/res/values-uz-rUZ/strings.xml
index 4d5573f..1345673 100644
--- a/core/res/res/values-uz-rUZ/strings.xml
+++ b/core/res/res/values-uz-rUZ/strings.xml
@@ -434,8 +434,7 @@
<string name="fingerprint_name_template" msgid="5870957565512716938">"Barmoq izi <xliff:g id="FINGERID">%d</xliff:g>"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
- <!-- no translation found for fingerprint_icon_content_description (2340202869968465936) -->
- <skip />
+ <string name="fingerprint_icon_content_description" msgid="2340202869968465936">"Barmoq izi belgisi"</string>
<string name="permlab_readSyncSettings" msgid="6201810008230503052">"sinx-sh sozlamalarini o‘qish"</string>
<string name="permdesc_readSyncSettings" msgid="2706745674569678644">"Ilovaga hisobning sinxronlash sozlamalarini o‘qish uchun ruxsat beradi. Masalan, bu \"Odamlar\" ilovasi hisob bilan sinxronlangan yoki aksini aniqlay oladi."</string>
<string name="permlab_writeSyncSettings" msgid="5408694875793945314">"sinx.ni yoqish/o‘chirish"</string>
@@ -714,6 +713,7 @@
<string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"Katak qo‘shildi"</string>
<string name="lockscreen_access_pattern_cell_added_verbose" msgid="7264580781744026939">"<xliff:g id="CELL_INDEX">%1$s</xliff:g> katak qo‘shildi"</string>
<string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"Chizma namunasi tugatildi"</string>
+ <string name="lockscreen_access_pattern_area" msgid="400813207572953209">"Chizmali kalit hududi."</string>
<string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. Vidjet %2$d / %3$d."</string>
<string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"Vidjet qo‘shish."</string>
<string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"Bo‘sh"</string>
@@ -898,8 +898,7 @@
<string name="aerr_title" msgid="1905800560317137752"></string>
<string name="aerr_application" msgid="932628488013092776">"Baxtga qarshi, <xliff:g id="APPLICATION">%1$s</xliff:g> to‘xtatildi."</string>
<string name="aerr_process" msgid="4507058997035697579">"Baxtga qarshi, <xliff:g id="PROCESS">%1$s</xliff:g> jarayoni to‘xtatildi."</string>
- <!-- no translation found for aerr_process_silence (4226685530196000222) -->
- <skip />
+ <string name="aerr_process_silence" msgid="4226685530196000222">"<xliff:g id="PROCESS">%1$s</xliff:g>: ilova ishlashdan to‘xtadi, qurilmani o‘chirib yoqing."</string>
<string name="anr_title" msgid="4351948481459135709"></string>
<string name="anr_activity_application" msgid="1904477189057199066">"<xliff:g id="APPLICATION">%2$s</xliff:g> javob bermayapti.\n\nUni yopishni xohlaysizmi?"</string>
<string name="anr_activity_process" msgid="5776209883299089767">"<xliff:g id="ACTIVITY">%1$s</xliff:g> harakati javob bermayapti.\n\nUni yopishni xohlaysizmi?"</string>
diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml
index 062b210..3d19a45 100644
--- a/core/res/res/values-vi/strings.xml
+++ b/core/res/res/values-vi/strings.xml
@@ -713,6 +713,7 @@
<string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"Đã thêm ô"</string>
<string name="lockscreen_access_pattern_cell_added_verbose" msgid="7264580781744026939">"Đã thêm ô <xliff:g id="CELL_INDEX">%1$s</xliff:g>"</string>
<string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"Đã vẽ xong hình"</string>
+ <string name="lockscreen_access_pattern_area" msgid="400813207572953209">"Khu vực mẫu."</string>
<string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. Tiện ích %2$d trong số %3$d."</string>
<string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"Thêm tiện ích."</string>
<string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"Trống"</string>
@@ -897,8 +898,7 @@
<string name="aerr_title" msgid="1905800560317137752"></string>
<string name="aerr_application" msgid="932628488013092776">"Rất tiếc, <xliff:g id="APPLICATION">%1$s</xliff:g> đã dừng lại."</string>
<string name="aerr_process" msgid="4507058997035697579">"Rất tiếc, quá trình <xliff:g id="PROCESS">%1$s</xliff:g> đã dừng lại."</string>
- <!-- no translation found for aerr_process_silence (4226685530196000222) -->
- <skip />
+ <string name="aerr_process_silence" msgid="4226685530196000222">"Chế độ Im lặng gặp sự cố từ <xliff:g id="PROCESS">%1$s</xliff:g> cho tới khi khởi động lại."</string>
<string name="anr_title" msgid="4351948481459135709"></string>
<string name="anr_activity_application" msgid="1904477189057199066">"<xliff:g id="APPLICATION">%2$s</xliff:g> hiện không phản hồi.\n\nBạn có muốn đóng ứng dụng này không?"</string>
<string name="anr_activity_process" msgid="5776209883299089767">"Hoạt động <xliff:g id="ACTIVITY">%1$s</xliff:g> không phản hồi.\n\nBạn có muốn đóng ứng dụng này không?"</string>
diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml
index 72a7736..d271b36 100644
--- a/core/res/res/values-zh-rCN/strings.xml
+++ b/core/res/res/values-zh-rCN/strings.xml
@@ -713,6 +713,7 @@
<string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"已添加单元格"</string>
<string name="lockscreen_access_pattern_cell_added_verbose" msgid="7264580781744026939">"已添加圆点 <xliff:g id="CELL_INDEX">%1$s</xliff:g>"</string>
<string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"图案绘制完成"</string>
+ <string name="lockscreen_access_pattern_area" msgid="400813207572953209">"图案区域。"</string>
<string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s。%3$d的小部件%2$d。"</string>
<string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"添加小部件。"</string>
<string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"空白"</string>
@@ -897,8 +898,7 @@
<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>
- <!-- no translation found for aerr_process_silence (4226685530196000222) -->
- <skip />
+ <string name="aerr_process_silence" msgid="4226685530196000222">"关闭“<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>
diff --git a/core/res/res/values-zh-rHK/strings.xml b/core/res/res/values-zh-rHK/strings.xml
index f366548..d3eb587 100644
--- a/core/res/res/values-zh-rHK/strings.xml
+++ b/core/res/res/values-zh-rHK/strings.xml
@@ -713,6 +713,7 @@
<string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"已加入一格"</string>
<string name="lockscreen_access_pattern_cell_added_verbose" msgid="7264580781744026939">"已加入 <xliff:g id="CELL_INDEX">%1$s</xliff:g> 點"</string>
<string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"已畫出解鎖圖案"</string>
+ <string name="lockscreen_access_pattern_area" msgid="400813207572953209">"圖案區域。"</string>
<string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s。第 %2$d 個小工具,共 %3$d 個。"</string>
<string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"新增小工具。"</string>
<string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"空白"</string>
@@ -897,8 +898,7 @@
<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>
- <!-- no translation found for aerr_process_silence (4226685530196000222) -->
- <skip />
+ <string name="aerr_process_silence" msgid="4226685530196000222">"停止顯示「<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>
diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml
index e296fa5..c674255 100644
--- a/core/res/res/values-zh-rTW/strings.xml
+++ b/core/res/res/values-zh-rTW/strings.xml
@@ -713,6 +713,7 @@
<string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"已加入 1 格"</string>
<string name="lockscreen_access_pattern_cell_added_verbose" msgid="7264580781744026939">"已加入圓點 <xliff:g id="CELL_INDEX">%1$s</xliff:g>"</string>
<string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"已畫出解鎖圖形"</string>
+ <string name="lockscreen_access_pattern_area" msgid="400813207572953209">"解鎖圖形區域。"</string>
<string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s。第 %2$d 個小工具,共 %3$d 個。"</string>
<string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"新增小工具。"</string>
<string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"空白"</string>
@@ -897,8 +898,7 @@
<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>
- <!-- no translation found for aerr_process_silence (4226685530196000222) -->
- <skip />
+ <string name="aerr_process_silence" msgid="4226685530196000222">"Silence 執行<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>
diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml
index e5ef695..07edb0c 100644
--- a/core/res/res/values-zu/strings.xml
+++ b/core/res/res/values-zu/strings.xml
@@ -713,6 +713,7 @@
<string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"Kwengezwe"</string>
<string name="lockscreen_access_pattern_cell_added_verbose" msgid="7264580781744026939">"Iseli <xliff:g id="CELL_INDEX">%1$s</xliff:g> lingeziwe"</string>
<string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"Iphethini isiphelile"</string>
+ <string name="lockscreen_access_pattern_area" msgid="400813207572953209">"Indawo yephethini."</string>
<string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. iwijethi %2$d ye-%3$d."</string>
<string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"Engeza iwijethi."</string>
<string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"Akunalutho"</string>
@@ -897,8 +898,7 @@
<string name="aerr_title" msgid="1905800560317137752"></string>
<string name="aerr_application" msgid="932628488013092776">"Ngeshwa, <xliff:g id="APPLICATION">%1$s</xliff:g> kumile."</string>
<string name="aerr_process" msgid="4507058997035697579">"Ngeshwa, uhlelo <xliff:g id="PROCESS">%1$s</xliff:g> luvele lwama."</string>
- <!-- no translation found for aerr_process_silence (4226685530196000222) -->
- <skip />
+ <string name="aerr_process_silence" msgid="4226685530196000222">"Ukuphahlazeka okuthulile kusukela ku-<xliff:g id="PROCESS">%1$s</xliff:g> kuze kuqalise."</string>
<string name="anr_title" msgid="4351948481459135709"></string>
<string name="anr_activity_application" msgid="1904477189057199066">"<xliff:g id="APPLICATION">%2$s</xliff:g> ayiphenduli.\n\nIngabe ufuna ukuyivala?"</string>
<string name="anr_activity_process" msgid="5776209883299089767">"Uhlelo <xliff:g id="ACTIVITY">%1$s</xliff:g> aluphenduli.\n\nIngabe ufuna ukuluvala?"</string>
diff --git a/core/res/res/values/attrs_manifest.xml b/core/res/res/values/attrs_manifest.xml
index 1515703..de16f20 100644
--- a/core/res/res/values/attrs_manifest.xml
+++ b/core/res/res/values/attrs_manifest.xml
@@ -219,7 +219,7 @@
<flag name="appop" value="0x40" />
<!-- Additional flag from base permission type: this permission can be automatically
granted to apps that target API levels below
- {@link android.os.Build.VERSION_CODES#MNC} (before runtime permissions
+ {@link android.os.Build.VERSION_CODES#M} (before runtime permissions
were introduced). -->
<flag name="pre23" value="0x80" />
<!-- Additional flag from base permission type: this permission can be automatically
@@ -1059,7 +1059,7 @@
at the same time.
<p>The default value is <code>false</code> for applications with
- <code>targetSdkVersion</code> lesser than {@link android.os.Build.VERSION_CODES#MNC} and
+ <code>targetSdkVersion</code> lesser than {@link android.os.Build.VERSION_CODES#M} and
<code>true</code> otherwise.
<p>NOTE: A task's root activity value is applied to all additional activities launched in
diff --git a/core/res/res/values/colors_material.xml b/core/res/res/values/colors_material.xml
index 1cb39f0..7399fa9 100644
--- a/core/res/res/values/colors_material.xml
+++ b/core/res/res/values/colors_material.xml
@@ -41,9 +41,6 @@
<color name="switch_thumb_disabled_material_dark">#ff616161</color>
<color name="switch_thumb_disabled_material_light">#ffbdbdbd</color>
- <color name="link_text_material_light">@color/material_deep_teal_500</color>
- <color name="link_text_material_dark">@color/material_deep_teal_200</color>
-
<!-- Text & foreground colors -->
<eat-comment />
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index aa15b5a..398c584 100755
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -505,16 +505,16 @@
<bool translatable="false" name="config_wifi_ssid_white_list_enable">true</bool>
<!-- Idle Receive current for wifi radio. 0 by default-->
- <integer translatable="false" name="config_wifi_idle_receive_cur_ma">1</integer>
+ <integer translatable="false" name="config_wifi_idle_receive_cur_ma">0</integer>
<!-- Rx current for wifi radio. 0 by default-->
- <integer translatable="false" name="config_wifi_active_rx_cur_ma">2</integer>
+ <integer translatable="false" name="config_wifi_active_rx_cur_ma">0</integer>
<!-- Tx current for wifi radio. 0 by default-->
- <integer translatable="false" name="config_wifi_tx_cur_ma">3</integer>
+ <integer translatable="false" name="config_wifi_tx_cur_ma">0</integer>
<!-- Operating volatage for wifi radio. 0 by default-->
- <integer translatable="false" name="config_wifi_operating_voltage_mv">4</integer>
+ <integer translatable="false" name="config_wifi_operating_voltage_mv">0</integer>
<!-- Flag indicating whether the we should enable the automatic brightness in Settings.
Software implementation will be used if config_hardware_auto_brightness_available is not set -->
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index 3c838b2a..cabb56c 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -2604,7 +2604,7 @@
<public type="style" name="Theme.DeviceDefault.Light.Dialog.Alert" />
<!-- ===============================================================
- Resources added in version MNC of the platform
+ Resources added in version M of the platform
=============================================================== -->
<eat-comment />
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 7cdad4b..ac6204d 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -4056,6 +4056,12 @@
<!-- Content description for the button that closes the floating toolbar overflow. [CHAR LIMIT=NONE] -->
<string name="floating_toolbar_close_overflow_description">Close overflow</string>
+ <!-- Free style window strings -->
+ <!-- Accessibility text for the maximize window button -->
+ <string name="maximize_button_text">Maximize</string>
+ <!-- Accessibility text for the close window button -->
+ <string name="close_button_text">Close</string>
+
<!-- Ellipsis character to appear in notification templates, e.g.
notification_template_material_inbox.xml.
DO NOT TRANSLATE -->
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 5303d5f..a45d907 100755
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -1939,6 +1939,10 @@
<!-- From Phone -->
<java-symbol type="bool" name="config_built_in_sip_phone" />
+ <java-symbol type="id" name="maximize_window" />
+ <java-symbol type="id" name="close_window" />
+ <java-symbol type="layout" name="non_client_decor_light" />
+ <java-symbol type="layout" name="non_client_decor_dark" />
<!-- From TelephonyProvider -->
<java-symbol type="xml" name="apns" />
diff --git a/core/res/res/values/themes_material.xml b/core/res/res/values/themes_material.xml
index 295b453..e406ae0 100644
--- a/core/res/res/values/themes_material.xml
+++ b/core/res/res/values/themes_material.xml
@@ -67,8 +67,8 @@
<item name="textColorHintInverse">@color/hint_foreground_material_light</item>
<item name="textColorHighlight">@color/highlighted_text_material</item>
<item name="textColorHighlightInverse">@color/highlighted_text_material</item>
- <item name="textColorLink">@color/link_text_material_dark</item>
- <item name="textColorLinkInverse">@color/link_text_material_light</item>
+ <item name="textColorLink">?attr/colorAccent</item>
+ <item name="textColorLinkInverse">?attr/colorAccent</item>
<item name="textColorSearchUrl">@color/search_url_text_material_dark</item>
<item name="textColorAlertDialogListItem">@color/primary_text_material_dark</item>
@@ -422,8 +422,8 @@
<item name="textColorHintInverse">@color/hint_foreground_material_dark</item>
<item name="textColorHighlight">@color/highlighted_text_material</item>
<item name="textColorHighlightInverse">@color/highlighted_text_material</item>
- <item name="textColorLink">@color/link_text_material_light</item>
- <item name="textColorLinkInverse">@color/link_text_material_dark</item>
+ <item name="textColorLink">?attr/colorAccent</item>
+ <item name="textColorLinkInverse">?attr/colorAccent</item>
<item name="textColorSearchUrl">@color/search_url_text_material_light</item>
<item name="textColorAlertDialogListItem">@color/primary_text_material_light</item>
@@ -793,8 +793,6 @@
<item name="textColorHintInverse">@color/hint_foreground_material_dark</item>
<item name="textColorHighlight">@color/highlighted_text_material</item>
<item name="textColorHighlightInverse">@color/highlighted_text_material</item>
- <item name="textColorLink">@color/link_text_material_light</item>
- <item name="textColorLinkInverse">@color/link_text_material_dark</item>
<item name="textColorSearchUrl">@color/search_url_text_material_light</item>
<item name="textColorAlertDialogListItem">@color/primary_text_material_light</item>
@@ -827,8 +825,6 @@
<item name="textColorHintInverse">@color/hint_foreground_material_light</item>
<item name="textColorHighlight">@color/highlighted_text_material</item>
<item name="textColorHighlightInverse">@color/highlighted_text_material</item>
- <item name="textColorLink">@color/link_text_material_dark</item>
- <item name="textColorLinkInverse">@color/link_text_material_light</item>
<item name="textColorSearchUrl">@color/search_url_text_material_dark</item>
<item name="textColorAlertDialogListItem">@color/primary_text_material_dark</item>
diff --git a/core/tests/coretests/src/android/app/DownloadManagerFunctionalTest.java b/core/tests/coretests/src/android/app/DownloadManagerFunctionalTest.java
index aa9f69d..7019980 100644
--- a/core/tests/coretests/src/android/app/DownloadManagerFunctionalTest.java
+++ b/core/tests/coretests/src/android/app/DownloadManagerFunctionalTest.java
@@ -24,6 +24,7 @@
import android.os.ParcelFileDescriptor;
import android.test.suitebuilder.annotation.LargeTest;
+import android.test.suitebuilder.annotation.Suppress;
import com.google.mockwebserver.MockResponse;
import java.io.File;
@@ -33,6 +34,7 @@
/**
* Integration tests of the DownloadManager API.
*/
+@Suppress // Failing.
public class DownloadManagerFunctionalTest extends DownloadManagerBaseTest {
private static final String TAG = "DownloadManagerFunctionalTest";
private final static String CACHE_DIR =
diff --git a/core/tests/coretests/src/android/app/DownloadManagerStressTest.java b/core/tests/coretests/src/android/app/DownloadManagerStressTest.java
index 864b2d6..9fa9131 100644
--- a/core/tests/coretests/src/android/app/DownloadManagerStressTest.java
+++ b/core/tests/coretests/src/android/app/DownloadManagerStressTest.java
@@ -24,6 +24,7 @@
import android.os.ParcelFileDescriptor;
import android.os.StatFs;
import android.test.suitebuilder.annotation.LargeTest;
+import android.test.suitebuilder.annotation.Suppress;
import android.util.Log;
import java.io.File;
@@ -34,6 +35,7 @@
/**
* Integration tests of the DownloadManager API.
*/
+@Suppress // Failing.
public class DownloadManagerStressTest extends DownloadManagerBaseTest {
private static final String TAG = "DownloadManagerStressTest";
private final static String CACHE_DIR =
diff --git a/core/tests/coretests/src/android/app/activity/LaunchTest.java b/core/tests/coretests/src/android/app/activity/LaunchTest.java
index 5893fd0..5b86dce 100644
--- a/core/tests/coretests/src/android/app/activity/LaunchTest.java
+++ b/core/tests/coretests/src/android/app/activity/LaunchTest.java
@@ -18,7 +18,9 @@
import android.content.ComponentName;
import android.test.suitebuilder.annotation.LargeTest;
+import android.test.suitebuilder.annotation.Suppress;
+@Suppress // Flaky.
public class LaunchTest extends ActivityTestsBase {
@LargeTest
diff --git a/core/tests/coretests/src/android/content/ContentQueryMapTest.java b/core/tests/coretests/src/android/content/ContentQueryMapTest.java
index d1b8c24..f47bfdb 100644
--- a/core/tests/coretests/src/android/content/ContentQueryMapTest.java
+++ b/core/tests/coretests/src/android/content/ContentQueryMapTest.java
@@ -25,11 +25,13 @@
import android.provider.Settings;
import android.test.AndroidTestCase;
import android.test.suitebuilder.annotation.MediumTest;
+import android.test.suitebuilder.annotation.Suppress;
import java.util.Observable;
import java.util.Observer;
/** Test of {@link ContentQueryMap} */
+@Suppress // Failing.
public class ContentQueryMapTest extends AndroidTestCase {
/** Helper class to run test code in a new thread with a Looper. */
private abstract class LooperThread extends Thread {
diff --git a/core/tests/coretests/src/android/content/ContentResolverTest.java b/core/tests/coretests/src/android/content/ContentResolverTest.java
index 2b6dee8b..6256d08 100644
--- a/core/tests/coretests/src/android/content/ContentResolverTest.java
+++ b/core/tests/coretests/src/android/content/ContentResolverTest.java
@@ -19,7 +19,9 @@
import android.provider.ContactsContract;
import android.test.AndroidTestCase;
import android.test.suitebuilder.annotation.LargeTest;
+import android.test.suitebuilder.annotation.Suppress;
+@Suppress // Failing.
public class ContentResolverTest extends AndroidTestCase {
private ContentResolver mContentResolver;
diff --git a/core/tests/coretests/src/android/content/pm/AppCacheTest.java b/core/tests/coretests/src/android/content/pm/AppCacheTest.java
index 54316d5..1567046 100644
--- a/core/tests/coretests/src/android/content/pm/AppCacheTest.java
+++ b/core/tests/coretests/src/android/content/pm/AppCacheTest.java
@@ -29,6 +29,7 @@
import android.test.suitebuilder.annotation.LargeTest;
import android.test.suitebuilder.annotation.MediumTest;
import android.test.suitebuilder.annotation.SmallTest;
+import android.test.suitebuilder.annotation.Suppress;
import android.util.Log;
import java.io.File;
@@ -120,6 +121,7 @@
}
@LargeTest
+ @Suppress // Failing.
public void testFreeApplicationCacheAllFiles() throws Exception {
boolean TRACKING = true;
StatFs st = new StatFs("/data");
diff --git a/core/tests/coretests/src/android/content/pm/ComponentTest.java b/core/tests/coretests/src/android/content/pm/ComponentTest.java
index f1a2a9b..cc75641 100644
--- a/core/tests/coretests/src/android/content/pm/ComponentTest.java
+++ b/core/tests/coretests/src/android/content/pm/ComponentTest.java
@@ -21,6 +21,7 @@
import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_ENABLED;
import static android.content.pm.PackageManager.GET_DISABLED_COMPONENTS;
+import android.test.suitebuilder.annotation.Suppress;
import com.android.frameworks.coretests.enabled_app.DisabledActivity;
import com.android.frameworks.coretests.enabled_app.DisabledProvider;
import com.android.frameworks.coretests.enabled_app.DisabledReceiver;
@@ -45,7 +46,7 @@
* package settings file to get written out by the PackageManagerService. Better, more unit-y test
* would fix this.
*/
-
+@Suppress // Failing.
public class ComponentTest extends AndroidTestCase {
private PackageManager mPackageManager;
diff --git a/core/tests/coretests/src/android/content/pm/PackageManagerTests.java b/core/tests/coretests/src/android/content/pm/PackageManagerTests.java
index baa772e..0fee6c3 100644
--- a/core/tests/coretests/src/android/content/pm/PackageManagerTests.java
+++ b/core/tests/coretests/src/android/content/pm/PackageManagerTests.java
@@ -58,6 +58,7 @@
import android.test.AndroidTestCase;
import android.test.suitebuilder.annotation.LargeTest;
import android.test.suitebuilder.annotation.SmallTest;
+import android.test.suitebuilder.annotation.Suppress;
import android.util.Log;
import com.android.frameworks.coretests.R;
@@ -72,6 +73,7 @@
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
+@Suppress // Failing.
public class PackageManagerTests extends AndroidTestCase {
private static final boolean localLOGV = true;
diff --git a/core/tests/coretests/src/android/database/DatabaseCursorTest.java b/core/tests/coretests/src/android/database/DatabaseCursorTest.java
index 08cd027..3507223 100644
--- a/core/tests/coretests/src/android/database/DatabaseCursorTest.java
+++ b/core/tests/coretests/src/android/database/DatabaseCursorTest.java
@@ -31,6 +31,7 @@
import android.test.PerformanceTestCase;
import android.test.suitebuilder.annotation.LargeTest;
import android.test.suitebuilder.annotation.MediumTest;
+import android.test.suitebuilder.annotation.Suppress;
import android.util.Log;
import java.io.File;
@@ -483,6 +484,7 @@
* This test is for that scenario.
*/
@LargeTest
+ @Suppress // Failing.
public void testCursorWindowFailureWhenTooManyCursorWindowsLeftOpen() {
mDatabase.execSQL("CREATE TABLE test (_id INTEGER PRIMARY KEY, data TEXT);");
mDatabase.execSQL("INSERT INTO test values(1, 'test');");
diff --git a/core/tests/coretests/src/android/net/LinkPropertiesTest.java b/core/tests/coretests/src/android/net/LinkPropertiesTest.java
index ea444a4..075ceaa 100644
--- a/core/tests/coretests/src/android/net/LinkPropertiesTest.java
+++ b/core/tests/coretests/src/android/net/LinkPropertiesTest.java
@@ -23,6 +23,7 @@
import android.net.RouteInfo;
import android.system.OsConstants;
import android.test.suitebuilder.annotation.SmallTest;
+import android.test.suitebuilder.annotation.Suppress;
import junit.framework.TestCase;
import java.net.InetAddress;
@@ -572,6 +573,7 @@
}
@SmallTest
+ @Suppress // Failing.
public void testIsReachable() {
final LinkProperties v4lp = new LinkProperties();
assertFalse(v4lp.isReachable(DNS1));
diff --git a/core/tests/coretests/src/android/os/MessageQueueTest.java b/core/tests/coretests/src/android/os/MessageQueueTest.java
index f82bfce..1cd1020 100644
--- a/core/tests/coretests/src/android/os/MessageQueueTest.java
+++ b/core/tests/coretests/src/android/os/MessageQueueTest.java
@@ -20,8 +20,10 @@
import android.os.Message;
import android.os.SystemClock;
import android.test.suitebuilder.annotation.MediumTest;
+import android.test.suitebuilder.annotation.Suppress;
import junit.framework.TestCase;
+@Suppress // Failing.
public class MessageQueueTest extends TestCase {
private static class BaseTestHandler extends TestHandlerThread {
diff --git a/core/tests/coretests/src/android/os/TraceTest.java b/core/tests/coretests/src/android/os/TraceTest.java
index 7a788ee..1541553 100644
--- a/core/tests/coretests/src/android/os/TraceTest.java
+++ b/core/tests/coretests/src/android/os/TraceTest.java
@@ -68,6 +68,7 @@
native void nativeMethodAndStartTracing();
@LargeTest
+ @Suppress // Failing.
public void testMethodTracing()
{
long start = System.currentTimeMillis();
diff --git a/core/tests/coretests/src/android/os/storage/StorageManagerIntegrationTest.java b/core/tests/coretests/src/android/os/storage/StorageManagerIntegrationTest.java
index 71772d9..37f0007 100644
--- a/core/tests/coretests/src/android/os/storage/StorageManagerIntegrationTest.java
+++ b/core/tests/coretests/src/android/os/storage/StorageManagerIntegrationTest.java
@@ -20,6 +20,7 @@
import android.os.Environment;
import android.test.InstrumentationTestCase;
import android.test.suitebuilder.annotation.LargeTest;
+import android.test.suitebuilder.annotation.Suppress;
import android.util.Log;
import com.android.frameworks.coretests.R;
@@ -126,6 +127,7 @@
* Tests mounting a single encrypted OBB file using an invalid password.
*/
@LargeTest
+ @Suppress // Failing.
public void testMountSingleEncryptedObbInvalidPassword() {
mFile = createObbFile("bad password@$%#@^*(!&)", R.raw.obb_enc_file100_orig3);
String filePath = mFile.getAbsolutePath();
diff --git a/core/tests/coretests/src/android/provider/SearchRecentSuggestionsProviderTest.java b/core/tests/coretests/src/android/provider/SearchRecentSuggestionsProviderTest.java
index 1512eab..7458de5 100644
--- a/core/tests/coretests/src/android/provider/SearchRecentSuggestionsProviderTest.java
+++ b/core/tests/coretests/src/android/provider/SearchRecentSuggestionsProviderTest.java
@@ -21,7 +21,9 @@
import android.database.Cursor;
import android.net.Uri;
import android.test.ProviderTestCase2;
+import android.test.suitebuilder.annotation.LargeTest;
import android.test.suitebuilder.annotation.MediumTest;
+import android.test.suitebuilder.annotation.Suppress;
/**
* ProviderTestCase that performs unit tests of SearchRecentSuggestionsProvider.
@@ -69,6 +71,7 @@
/**
* Simple test to see if we can write and read back a single query
*/
+ @Suppress // Failing.
public void testOneQuery() {
final String TEST_LINE1 = "test line 1";
final String TEST_LINE2 = "test line 2";
@@ -92,6 +95,7 @@
/**
* Simple test to see if we can write and read back a diverse set of queries
*/
+ @Suppress // Failing.
public void testMixedQueries() {
// we'll make 10 queries named "query x" and 10 queries named "test x"
final String TEST_GROUP_1 = "query ";
@@ -115,6 +119,7 @@
* Test that the reordering code works properly. The most recently injected queries
* should replace existing queries and be sorted to the top of the list.
*/
+ @Suppress // Failing.
public void testReordering() {
// first we'll make 10 queries named "group1 x"
final int GROUP_1_COUNT = 10;
@@ -196,6 +201,7 @@
*
* TODO: This is a slow test, do we have annotation for that?
*/
+ @Suppress // Failing.
public void testPruning() {
// first we'll make 50 queries named "group1 x"
final int GROUP_1_COUNT = 50;
@@ -238,6 +244,7 @@
/**
* Test that the clear history code works properly.
*/
+ @Suppress // Failing.
public void testClear() {
// first we'll make 10 queries named "group1 x"
final int GROUP_1_COUNT = 10;
diff --git a/core/tests/coretests/src/android/provider/SettingsProviderTest.java b/core/tests/coretests/src/android/provider/SettingsProviderTest.java
index 131651a..2615a28 100644
--- a/core/tests/coretests/src/android/provider/SettingsProviderTest.java
+++ b/core/tests/coretests/src/android/provider/SettingsProviderTest.java
@@ -32,10 +32,12 @@
import android.test.AndroidTestCase;
import android.test.suitebuilder.annotation.MediumTest;
import android.test.suitebuilder.annotation.SmallTest;
+import android.test.suitebuilder.annotation.Suppress;
import java.util.List;
/** Unit test for SettingsProvider. */
+@Suppress // Failing.
public class SettingsProviderTest extends AndroidTestCase {
@MediumTest
public void testNameValueCache() {
diff --git a/core/tests/coretests/src/android/provider/SmsProviderTest.java b/core/tests/coretests/src/android/provider/SmsProviderTest.java
index c8ed728..af4d1a6 100644
--- a/core/tests/coretests/src/android/provider/SmsProviderTest.java
+++ b/core/tests/coretests/src/android/provider/SmsProviderTest.java
@@ -23,9 +23,11 @@
import android.provider.Telephony.Sms;
import android.test.AndroidTestCase;
import android.test.suitebuilder.annotation.LargeTest;
+import android.test.suitebuilder.annotation.Suppress;
import java.util.GregorianCalendar;
+@Suppress // Failing.
public class SmsProviderTest extends AndroidTestCase {
@LargeTest
diff --git a/core/tests/coretests/src/android/util/PatternsTest.java b/core/tests/coretests/src/android/util/PatternsTest.java
index ebdbb0e..253eb25 100644
--- a/core/tests/coretests/src/android/util/PatternsTest.java
+++ b/core/tests/coretests/src/android/util/PatternsTest.java
@@ -16,6 +16,7 @@
package android.util;
import android.test.suitebuilder.annotation.SmallTest;
+import android.test.suitebuilder.annotation.Suppress;
import android.util.Patterns;
import java.util.regex.Matcher;
@@ -54,6 +55,7 @@
}
@SmallTest
+ @Suppress // Failing.
public void testUrlPattern() throws Exception {
boolean t;
@@ -117,6 +119,7 @@
}
@SmallTest
+ @Suppress // Failing.
public void testDomainPattern() throws Exception {
boolean t;
diff --git a/core/tests/coretests/src/android/view/GlobalFocusChangeTest.java b/core/tests/coretests/src/android/view/GlobalFocusChangeTest.java
index 89e32e4..dab7b90 100644
--- a/core/tests/coretests/src/android/view/GlobalFocusChangeTest.java
+++ b/core/tests/coretests/src/android/view/GlobalFocusChangeTest.java
@@ -21,10 +21,12 @@
import android.test.suitebuilder.annotation.LargeTest;
import android.test.suitebuilder.annotation.MediumTest;
import android.test.TouchUtils;
+import android.test.suitebuilder.annotation.Suppress;
import android.view.View;
import android.view.KeyEvent;
import com.android.frameworks.coretests.R;
+@Suppress // Flaky
public class GlobalFocusChangeTest extends ActivityInstrumentationTestCase<GlobalFocusChange> {
private GlobalFocusChange mActivity;
private View mLeft;
diff --git a/core/tests/coretests/src/android/view/VelocityTest.java b/core/tests/coretests/src/android/view/VelocityTest.java
index 12abf3e..7f32208 100644
--- a/core/tests/coretests/src/android/view/VelocityTest.java
+++ b/core/tests/coretests/src/android/view/VelocityTest.java
@@ -16,6 +16,7 @@
package android.view;
+import android.test.suitebuilder.annotation.Suppress;
import junit.framework.Assert;
import android.test.InstrumentationTestCase;
@@ -81,6 +82,7 @@
}
@MediumTest
+ @Suppress // Failing.
public void testDragLinearHorizontal() {
long t = System.currentTimeMillis();
VelocityTracker vt = VelocityTracker.obtain();
@@ -93,6 +95,7 @@
}
@MediumTest
+ @Suppress // Failing.
public void testDragLinearVertical() {
long t = System.currentTimeMillis();
VelocityTracker vt = VelocityTracker.obtain();
@@ -109,6 +112,7 @@
* (velocity must be an exact value)
*/
@MediumTest
+ @Suppress // Failing.
public void testDragWith2Points () {
long t = System.currentTimeMillis();
VelocityTracker vt = VelocityTracker.obtain();
@@ -125,6 +129,7 @@
* the same interval
*/
@MediumTest
+ @Suppress // Failing.
public void testStabilityInNbPoints () {
long t = System.currentTimeMillis();
VelocityTracker vt = VelocityTracker.obtain();
diff --git a/core/tests/coretests/src/android/widget/ListViewTest.java b/core/tests/coretests/src/android/widget/ListViewTest.java
index 94b19f0..449b696 100644
--- a/core/tests/coretests/src/android/widget/ListViewTest.java
+++ b/core/tests/coretests/src/android/widget/ListViewTest.java
@@ -16,6 +16,7 @@
package android.widget;
+import android.test.suitebuilder.annotation.Suppress;
import com.google.android.collect.Lists;
import junit.framework.Assert;
@@ -32,6 +33,7 @@
import java.util.List;
+@Suppress // Failing.
public class ListViewTest extends InstrumentationTestCase {
/**
diff --git a/core/tests/coretests/src/android/widget/SimpleCursorAdapterTest.java b/core/tests/coretests/src/android/widget/SimpleCursorAdapterTest.java
index 62466f1..1731c08 100644
--- a/core/tests/coretests/src/android/widget/SimpleCursorAdapterTest.java
+++ b/core/tests/coretests/src/android/widget/SimpleCursorAdapterTest.java
@@ -16,6 +16,7 @@
package android.widget;
+import android.test.suitebuilder.annotation.Suppress;
import com.google.android.collect.Lists;
import android.content.Context;
@@ -34,6 +35,7 @@
* NOTE: This contract holds for underlying cursor types too and these should
* be extracted into a set of tests that can be run on any descendant of CursorAdapter.
*/
+@Suppress // Failing.
public class SimpleCursorAdapterTest extends AndroidTestCase {
String[] mFrom;
diff --git a/core/tests/coretests/src/android/widget/TextViewWordLimitsTest.java b/core/tests/coretests/src/android/widget/TextViewWordLimitsTest.java
index 20305bf..4b66164 100644
--- a/core/tests/coretests/src/android/widget/TextViewWordLimitsTest.java
+++ b/core/tests/coretests/src/android/widget/TextViewWordLimitsTest.java
@@ -18,6 +18,7 @@
import android.test.AndroidTestCase;
import android.test.suitebuilder.annotation.LargeTest;
+import android.test.suitebuilder.annotation.Suppress;
import android.text.InputType;
import android.text.Selection;
import android.text.Spannable;
@@ -32,6 +33,7 @@
* verifies word limits to be in strings containing different kinds of
* characters.
*/
+@Suppress // Failing.
public class TextViewWordLimitsTest extends AndroidTestCase {
TextView mTv = null;
diff --git a/core/tests/coretests/src/android/widget/focus/ListOfButtonsTest.java b/core/tests/coretests/src/android/widget/focus/ListOfButtonsTest.java
index 1968a32..bec6f80 100644
--- a/core/tests/coretests/src/android/widget/focus/ListOfButtonsTest.java
+++ b/core/tests/coretests/src/android/widget/focus/ListOfButtonsTest.java
@@ -16,6 +16,7 @@
package android.widget.focus;
+import android.test.suitebuilder.annotation.Suppress;
import android.widget.focus.ListOfButtons;
import com.android.frameworks.coretests.R;
@@ -31,6 +32,7 @@
* Tests that focus works as expected when navigating into and out of
* a {@link ListView} that has buttons in it.
*/
+@Suppress // Flaky
public class ListOfButtonsTest extends ActivityInstrumentationTestCase2<ListOfButtons> {
private ListAdapter mListAdapter;
diff --git a/core/tests/coretests/src/android/widget/layout/linear/WeightTest.java b/core/tests/coretests/src/android/widget/layout/linear/WeightTest.java
index 0349d7f..1c42e7c 100644
--- a/core/tests/coretests/src/android/widget/layout/linear/WeightTest.java
+++ b/core/tests/coretests/src/android/widget/layout/linear/WeightTest.java
@@ -20,11 +20,13 @@
import android.test.ActivityInstrumentationTestCase;
import android.test.suitebuilder.annotation.MediumTest;
import android.test.ViewAsserts;
+import android.test.suitebuilder.annotation.Suppress;
import android.view.View;
import com.android.frameworks.coretests.R;
import android.widget.layout.linear.Weight;
+@Suppress // Failing.
public class WeightTest extends ActivityInstrumentationTestCase<Weight> {
private View mChild;
private View mContainer;
diff --git a/core/tests/coretests/src/android/widget/listview/ListItemRequestRectAboveThinFirstItemTest.java b/core/tests/coretests/src/android/widget/listview/ListItemRequestRectAboveThinFirstItemTest.java
index 072ac6c..73eb0a8 100644
--- a/core/tests/coretests/src/android/widget/listview/ListItemRequestRectAboveThinFirstItemTest.java
+++ b/core/tests/coretests/src/android/widget/listview/ListItemRequestRectAboveThinFirstItemTest.java
@@ -20,6 +20,7 @@
import android.test.ActivityInstrumentationTestCase;
import android.test.suitebuilder.annotation.LargeTest;
import android.test.suitebuilder.annotation.MediumTest;
+import android.test.suitebuilder.annotation.Suppress;
import android.view.View;
import android.view.KeyEvent;
import android.widget.ListView;
@@ -39,6 +40,7 @@
}
@MediumTest
+ @Suppress // Failing.
public void testPreconditions() {
assertTrue("first child needs to be within fading edge height",
diff --git a/core/tests/coretests/src/android/widget/listview/arrowscroll/ListItemsExpandOnSelectionTest.java b/core/tests/coretests/src/android/widget/listview/arrowscroll/ListItemsExpandOnSelectionTest.java
index e4b5c18..91a1eba 100644
--- a/core/tests/coretests/src/android/widget/listview/arrowscroll/ListItemsExpandOnSelectionTest.java
+++ b/core/tests/coretests/src/android/widget/listview/arrowscroll/ListItemsExpandOnSelectionTest.java
@@ -19,6 +19,7 @@
import android.test.ActivityInstrumentationTestCase;
import android.test.suitebuilder.annotation.LargeTest;
import android.test.suitebuilder.annotation.MediumTest;
+import android.test.suitebuilder.annotation.Suppress;
import android.widget.ListView;
import android.view.KeyEvent;
import android.widget.listview.ListItemsExpandOnSelection;
@@ -79,6 +80,7 @@
}
@MediumTest
+ @Suppress // Failing.
public void testMoveSelectionDownRequiringScroll() {
int lastItemIndex = mListView.getChildCount() - 1;
@@ -95,6 +97,7 @@
}
@LargeTest
+ @Suppress // Failing.
public void testMoveSelectionUpRequiringScroll() {
int childrenPerScreen = mListView.getChildCount();
diff --git a/core/tests/coretests/src/android/widget/listview/arrowscroll/ListOfItemsShorterThanScreenTest.java b/core/tests/coretests/src/android/widget/listview/arrowscroll/ListOfItemsShorterThanScreenTest.java
index eacde5b..bda71d0 100644
--- a/core/tests/coretests/src/android/widget/listview/arrowscroll/ListOfItemsShorterThanScreenTest.java
+++ b/core/tests/coretests/src/android/widget/listview/arrowscroll/ListOfItemsShorterThanScreenTest.java
@@ -18,6 +18,7 @@
import android.test.ActivityInstrumentationTestCase;
import android.test.suitebuilder.annotation.MediumTest;
+import android.test.suitebuilder.annotation.Suppress;
import android.view.KeyEvent;
import android.view.View;
import android.widget.ListView;
@@ -73,6 +74,7 @@
}
@MediumTest
+ @Suppress // Failing.
public void testMoveDownToItemRequiringScrolling() {
final int lastOnScreenItemIndex = mListView.getChildCount() - 1;
final View lastItem = mListView.getChildAt(lastOnScreenItemIndex);
@@ -101,6 +103,7 @@
}
@MediumTest
+ @Suppress // Failing.
public void testMoveUpToItemRequiringScrolling() {
// go down to one past last item, then back up to the second item. this will
// require scrolling to get it back on screen, and will need a peeking edge
diff --git a/core/tests/coretests/src/android/widget/listview/arrowscroll/ListOfItemsTallerThanScreenTest.java b/core/tests/coretests/src/android/widget/listview/arrowscroll/ListOfItemsTallerThanScreenTest.java
index 6805b72..2135445 100644
--- a/core/tests/coretests/src/android/widget/listview/arrowscroll/ListOfItemsTallerThanScreenTest.java
+++ b/core/tests/coretests/src/android/widget/listview/arrowscroll/ListOfItemsTallerThanScreenTest.java
@@ -18,6 +18,7 @@
import android.test.ActivityInstrumentationTestCase2;
import android.test.suitebuilder.annotation.MediumTest;
+import android.test.suitebuilder.annotation.Suppress;
import android.view.KeyEvent;
import android.view.View;
import android.widget.ListView;
@@ -105,6 +106,7 @@
}
@MediumTest
+ @Suppress // Failing.
public void testScrollFirstItemOffScreen() {
int numDownsToGetFirstItemOffScreen =
(mListView.getSelectedView().getHeight() / mListView.getMaxScrollAmount()) + 1;
diff --git a/core/tests/coretests/src/android/widget/listview/arrowscroll/ListOfShortShortTallShortShortTest.java b/core/tests/coretests/src/android/widget/listview/arrowscroll/ListOfShortShortTallShortShortTest.java
index 5aa27b2..ef70b5a 100644
--- a/core/tests/coretests/src/android/widget/listview/arrowscroll/ListOfShortShortTallShortShortTest.java
+++ b/core/tests/coretests/src/android/widget/listview/arrowscroll/ListOfShortShortTallShortShortTest.java
@@ -18,6 +18,7 @@
import android.test.ActivityInstrumentationTestCase2;
import android.test.suitebuilder.annotation.MediumTest;
+import android.test.suitebuilder.annotation.Suppress;
import android.util.ListUtil;
import android.view.KeyEvent;
import android.widget.ListView;
@@ -39,6 +40,7 @@
}
@MediumTest
+ @Suppress // Failing.
public void testPreconditions() {
assertEquals("list item count", 5, mListView.getCount());
assertEquals("list visible child count", 3, mListView.getChildCount());
@@ -68,6 +70,7 @@
}
@MediumTest
+ @Suppress // Failing.
public void testFadeInTwoBottomItems() {
// put 2nd item selected
sendKeys(KeyEvent.KEYCODE_DPAD_DOWN);
@@ -110,6 +113,7 @@
}
@MediumTest
+ @Suppress // Failing.
public void testFadeInTopTwoItems() throws Exception {
mListUtil.arrowScrollToSelectedPosition(4);
diff --git a/core/tests/coretests/src/android/widget/listview/arrowscroll/ListOfThinItemsTest.java b/core/tests/coretests/src/android/widget/listview/arrowscroll/ListOfThinItemsTest.java
index 17c1e03..9b1cc0a 100644
--- a/core/tests/coretests/src/android/widget/listview/arrowscroll/ListOfThinItemsTest.java
+++ b/core/tests/coretests/src/android/widget/listview/arrowscroll/ListOfThinItemsTest.java
@@ -19,6 +19,7 @@
import android.test.ActivityInstrumentationTestCase;
import android.test.suitebuilder.annotation.LargeTest;
import android.test.suitebuilder.annotation.MediumTest;
+import android.test.suitebuilder.annotation.Suppress;
import android.view.KeyEvent;
import android.view.View;
import android.widget.ListView;
@@ -38,6 +39,7 @@
}
@MediumTest
+ @Suppress // Failing.
public void testPreconditions() {
assertNotNull(mListView);
assertTrue("need item height less than fading edge length",
diff --git a/core/tests/coretests/src/android/widget/listview/arrowscroll/ListWithOffScreenNextSelectableTest.java b/core/tests/coretests/src/android/widget/listview/arrowscroll/ListWithOffScreenNextSelectableTest.java
index 610b890..cf319d1 100644
--- a/core/tests/coretests/src/android/widget/listview/arrowscroll/ListWithOffScreenNextSelectableTest.java
+++ b/core/tests/coretests/src/android/widget/listview/arrowscroll/ListWithOffScreenNextSelectableTest.java
@@ -18,12 +18,14 @@
import android.test.ActivityInstrumentationTestCase;
import android.test.suitebuilder.annotation.MediumTest;
+import android.test.suitebuilder.annotation.Suppress;
import android.view.KeyEvent;
import android.view.View;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.listview.ListWithOffScreenNextSelectable;
+@Suppress // Failing.
public class ListWithOffScreenNextSelectableTest
extends ActivityInstrumentationTestCase<ListWithOffScreenNextSelectable> {
private ListView mListView;
diff --git a/core/tests/coretests/src/android/widget/listview/arrowscroll/ListWithScreenOfNoSelectablesTest.java b/core/tests/coretests/src/android/widget/listview/arrowscroll/ListWithScreenOfNoSelectablesTest.java
index b68631a..211c8c8 100644
--- a/core/tests/coretests/src/android/widget/listview/arrowscroll/ListWithScreenOfNoSelectablesTest.java
+++ b/core/tests/coretests/src/android/widget/listview/arrowscroll/ListWithScreenOfNoSelectablesTest.java
@@ -18,6 +18,7 @@
import android.test.ActivityInstrumentationTestCase2;
import android.test.suitebuilder.annotation.MediumTest;
+import android.test.suitebuilder.annotation.Suppress;
import android.view.KeyEvent;
import android.view.View;
import android.widget.ListView;
@@ -77,6 +78,7 @@
}
@MediumTest
+ @Suppress // Failing.
public void testGoFromNoSelectionToSelectionExists() {
// go down untile first (and only selectable) item is off screen
View first = mListView.getChildAt(0);
diff --git a/core/tests/coretests/src/android/widget/listview/focus/AdjacentListsWithAdjacentISVsInsideTest.java b/core/tests/coretests/src/android/widget/listview/focus/AdjacentListsWithAdjacentISVsInsideTest.java
index 461f83d..6a7466b 100644
--- a/core/tests/coretests/src/android/widget/listview/focus/AdjacentListsWithAdjacentISVsInsideTest.java
+++ b/core/tests/coretests/src/android/widget/listview/focus/AdjacentListsWithAdjacentISVsInsideTest.java
@@ -16,6 +16,7 @@
package android.widget.listview.focus;
+import android.test.suitebuilder.annotation.Suppress;
import android.widget.listview.AdjacentListsWithAdjacentISVsInside;
import android.util.InternalSelectionView;
@@ -75,6 +76,7 @@
}
@MediumTest
+ @Suppress // Failing.
public void testFocusTransfersOutsideOfListWhenNoCandidateInsideHorizontal() {
sendKeys(KeyEvent.KEYCODE_DPAD_DOWN, KeyEvent.KEYCODE_DPAD_DOWN, KeyEvent.KEYCODE_DPAD_RIGHT);
diff --git a/core/tests/coretests/src/android/widget/listview/focus/ListWithEditTextHeaderTest.java b/core/tests/coretests/src/android/widget/listview/focus/ListWithEditTextHeaderTest.java
index 532b9d1..b449b61 100644
--- a/core/tests/coretests/src/android/widget/listview/focus/ListWithEditTextHeaderTest.java
+++ b/core/tests/coretests/src/android/widget/listview/focus/ListWithEditTextHeaderTest.java
@@ -21,6 +21,7 @@
import android.test.TouchUtils;
import android.test.suitebuilder.annotation.LargeTest;
import android.test.suitebuilder.annotation.MediumTest;
+import android.test.suitebuilder.annotation.Suppress;
import android.view.KeyEvent;
import android.view.View;
import android.widget.AbsListView;
@@ -57,6 +58,7 @@
}
@LargeTest
+ @Suppress // Failing.
public void testClickingHeaderWhenOtherItemHasFocusGivesHeaderFocus() {
sendKeys(KeyEvent.KEYCODE_DPAD_DOWN);
assertEquals("selected position", 1, mListView.getSelectedItemPosition());
diff --git a/core/tests/coretests/src/android/widget/listview/touch/ListSetSelectionTest.java b/core/tests/coretests/src/android/widget/listview/touch/ListSetSelectionTest.java
index b7733d1..aed513a 100644
--- a/core/tests/coretests/src/android/widget/listview/touch/ListSetSelectionTest.java
+++ b/core/tests/coretests/src/android/widget/listview/touch/ListSetSelectionTest.java
@@ -20,6 +20,7 @@
import android.test.suitebuilder.annotation.LargeTest;
import android.test.suitebuilder.annotation.MediumTest;
import android.test.TouchUtils;
+import android.test.suitebuilder.annotation.Suppress;
import android.view.View;
import android.widget.ListView;
@@ -28,6 +29,7 @@
/**
* Tests setting the selection in touch mode
*/
+@Suppress // Flaky.
public class ListSetSelectionTest extends ActivityInstrumentationTestCase<ListSimple> {
private ListSimple mActivity;
private ListView mListView;
diff --git a/core/tests/coretests/src/android/widget/scroll/ButtonAboveTallInternalSelectionViewTest.java b/core/tests/coretests/src/android/widget/scroll/ButtonAboveTallInternalSelectionViewTest.java
index 41123280..8123228 100644
--- a/core/tests/coretests/src/android/widget/scroll/ButtonAboveTallInternalSelectionViewTest.java
+++ b/core/tests/coretests/src/android/widget/scroll/ButtonAboveTallInternalSelectionViewTest.java
@@ -16,6 +16,7 @@
package android.widget.scroll;
+import android.test.suitebuilder.annotation.Suppress;
import android.widget.scroll.ButtonAboveTallInternalSelectionView;
import android.util.InternalSelectionView;
@@ -23,6 +24,7 @@
import android.test.suitebuilder.annotation.MediumTest;
import android.view.KeyEvent;
+@Suppress // Failing.
public class ButtonAboveTallInternalSelectionViewTest extends
ActivityInstrumentationTestCase<ButtonAboveTallInternalSelectionView> {
diff --git a/core/tests/coretests/src/android/widget/scroll/RequestRectangleVisibleTest.java b/core/tests/coretests/src/android/widget/scroll/RequestRectangleVisibleTest.java
index 95fb00b..f8abdb2 100644
--- a/core/tests/coretests/src/android/widget/scroll/RequestRectangleVisibleTest.java
+++ b/core/tests/coretests/src/android/widget/scroll/RequestRectangleVisibleTest.java
@@ -16,6 +16,7 @@
package android.widget.scroll;
+import android.test.suitebuilder.annotation.Suppress;
import android.widget.scroll.RequestRectangleVisible;
import com.android.frameworks.coretests.R;
@@ -33,6 +34,7 @@
* {@link RequestRectangleVisible} is set up to exercise the cases of moving a
* rectangle that is either off screen or not entirely on the screen onto the screen.
*/
+@Suppress // Flaky.
public class RequestRectangleVisibleTest extends ActivityInstrumentationTestCase<RequestRectangleVisible> {
private ScrollView mScrollView;
diff --git a/core/tests/coretests/src/android/widget/scroll/ScrollViewButtonsAndLabelsTest.java b/core/tests/coretests/src/android/widget/scroll/ScrollViewButtonsAndLabelsTest.java
index 7efb9aa..078cde0 100644
--- a/core/tests/coretests/src/android/widget/scroll/ScrollViewButtonsAndLabelsTest.java
+++ b/core/tests/coretests/src/android/widget/scroll/ScrollViewButtonsAndLabelsTest.java
@@ -16,6 +16,7 @@
package android.widget.scroll;
+import android.test.suitebuilder.annotation.Suppress;
import android.widget.scroll.ScrollViewButtonsAndLabels;
import android.test.ActivityInstrumentationTestCase;
@@ -53,6 +54,7 @@
}
@MediumTest
+ @Suppress // Failing.
public void testPreconditions() {
assertTrue("vertical fading edge width needs to be non-zero for this "
+ "test to be worth anything",
diff --git a/core/tests/coretests/src/android/widget/scroll/arrowscroll/MultiPageTextWithPaddingTest.java b/core/tests/coretests/src/android/widget/scroll/arrowscroll/MultiPageTextWithPaddingTest.java
index ddde48f..6ce4c15 100644
--- a/core/tests/coretests/src/android/widget/scroll/arrowscroll/MultiPageTextWithPaddingTest.java
+++ b/core/tests/coretests/src/android/widget/scroll/arrowscroll/MultiPageTextWithPaddingTest.java
@@ -16,6 +16,7 @@
package android.widget.scroll.arrowscroll;
+import android.test.suitebuilder.annotation.Suppress;
import android.widget.scroll.arrowscroll.MultiPageTextWithPadding;
import android.test.ActivityInstrumentationTestCase;
import android.test.suitebuilder.annotation.LargeTest;
@@ -24,6 +25,7 @@
import android.widget.TextView;
import android.widget.ScrollView;
+@Suppress // Flaky
public class MultiPageTextWithPaddingTest extends
ActivityInstrumentationTestCase<MultiPageTextWithPadding> {
diff --git a/core/tests/coretests/src/com/android/internal/policy/PhoneWindowActionModeTest.java b/core/tests/coretests/src/com/android/internal/policy/PhoneWindowActionModeTest.java
index b860c20..48590c1 100644
--- a/core/tests/coretests/src/com/android/internal/policy/PhoneWindowActionModeTest.java
+++ b/core/tests/coretests/src/com/android/internal/policy/PhoneWindowActionModeTest.java
@@ -18,6 +18,7 @@
import android.test.ActivityInstrumentationTestCase2;
import android.test.UiThreadTest;
+import android.test.suitebuilder.annotation.SmallTest;
import android.view.ActionMode;
import android.view.ActionMode.Callback;
import android.view.KeyEvent;
@@ -34,6 +35,7 @@
/**
* Tests {@link PhoneWindow}'s {@link ActionMode} related methods.
*/
+@SmallTest
public final class PhoneWindowActionModeTest
extends ActivityInstrumentationTestCase2<PhoneWindowActionModeTestActivity> {
diff --git a/core/tests/coretests/src/com/android/internal/util/StateMachineTest.java b/core/tests/coretests/src/com/android/internal/util/StateMachineTest.java
index 2a2c24e..302aa87 100644
--- a/core/tests/coretests/src/com/android/internal/util/StateMachineTest.java
+++ b/core/tests/coretests/src/com/android/internal/util/StateMachineTest.java
@@ -25,6 +25,7 @@
import android.os.Message;
import android.os.SystemClock;
+import android.test.suitebuilder.annotation.Suppress;
import com.android.internal.util.State;
import com.android.internal.util.StateMachine;
import com.android.internal.util.StateMachine.LogRec;
@@ -38,6 +39,7 @@
/**
* Test for StateMachine.
*/
+@Suppress // Failing
public class StateMachineTest extends TestCase {
private static final String ENTER = "enter";
private static final String EXIT = "exit";
diff --git a/data/fonts/Android.mk b/data/fonts/Android.mk
index 3181017..39458f9 100644
--- a/data/fonts/Android.mk
+++ b/data/fonts/Android.mk
@@ -17,10 +17,13 @@
LOCAL_PATH := $(call my-dir)
-# Use full Noto Sans Japanese font on non-smaller footprints
+# Use full Noto Sans Japanese font on the normal footprints, but
+# exclude it from SMALLER and use a subset on the CONSTRAINED ones.
ifneq ($(SMALLER_FONT_FOOTPRINT),true)
+ifneq ($(CONSTRAINED_FONT_FOOTPRINT),true)
FONT_NOTOSANS_JP_FULL := true
endif
+endif
##########################################
# create symlink for given font
@@ -82,19 +85,32 @@
extra_font_files :=
################################
-# Include the DroidSansFallback subset on SMALLER_FONT_FOOTPRINT build
+# Include the DroidSansFallback subset on SMALLER_FONT_FOOTPRINT builds,
+# and the full font on CONSTRAINED_FONT_FOOTPRINT ones.
ifeq ($(SMALLER_FONT_FOOTPRINT),true)
+droidsans_fallback_src := DroidSansFallback.ttf
+build_droidsans_fallback := true
+endif # SMALLER_FONT_FOOTPRINT
+
+ifeq ($(CONSTRAINED_FONT_FOOTPRINT),true)
+droidsans_fallback_src := DroidSansFallbackFull.ttf
+build_droidsans_fallback := true
+endif # CONSTRAINED_FONT_FOOTPRINT
+
+ifeq ($(build_droidsans_fallback),true)
include $(CLEAR_VARS)
LOCAL_MODULE := DroidSansFallback.ttf
-LOCAL_SRC_FILES := $(LOCAL_MODULE)
+LOCAL_SRC_FILES := $(droidsans_fallback_src)
LOCAL_MODULE_CLASS := ETC
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE_PATH := $(TARGET_OUT)/fonts
include $(BUILD_PREBUILT)
droidsans_fallback_src :=
-endif # SMALLER_FONT_FOOTPRINT
+endif # build_droidsans_fallback
+
+build_droidsans_fallback :=
################################
# Build the rest of font files as prebuilt.
diff --git a/graphics/java/android/graphics/Bitmap.java b/graphics/java/android/graphics/Bitmap.java
index 7efbc0f..1add3b85 100644
--- a/graphics/java/android/graphics/Bitmap.java
+++ b/graphics/java/android/graphics/Bitmap.java
@@ -23,6 +23,7 @@
import android.os.Parcelable;
import android.os.Trace;
import android.util.DisplayMetrics;
+import android.util.Log;
import dalvik.system.VMRuntime;
@@ -33,6 +34,8 @@
import java.nio.ShortBuffer;
public final class Bitmap implements Parcelable {
+ private static final String TAG = "Bitmap";
+
/**
* Indicates that the bitmap was created for an unknown pixel density.
*
@@ -159,6 +162,9 @@
* @see #DENSITY_NONE
*/
public int getDensity() {
+ if (mRecycled) {
+ Log.w(TAG, "Called getDensity() on a recycle()'d bitmap! This is undefined behavior!");
+ }
return mDensity;
}
@@ -348,7 +354,9 @@
* @return The current generation ID for this bitmap.
*/
public int getGenerationId() {
- if (mRecycled) return 0;
+ if (mRecycled) {
+ Log.w(TAG, "Called getGenerationId() on a recycle()'d bitmap! This is undefined behavior!");
+ }
return nativeGenerationId(mFinalizer.mNativeBitmap);
}
@@ -1075,7 +1083,9 @@
* @see BitmapFactory.Options#inPremultiplied
*/
public final boolean isPremultiplied() {
- if (mRecycled) return false;
+ if (mRecycled) {
+ Log.w(TAG, "Called isPremultiplied() on a recycle()'d bitmap! This is undefined behavior!");
+ }
return nativeIsPremultiplied(mFinalizer.mNativeBitmap);
}
@@ -1107,11 +1117,17 @@
/** Returns the bitmap's width */
public final int getWidth() {
+ if (mRecycled) {
+ Log.w(TAG, "Called getWidth() on a recycle()'d bitmap! This is undefined behavior!");
+ }
return mWidth;
}
/** Returns the bitmap's height */
public final int getHeight() {
+ if (mRecycled) {
+ Log.w(TAG, "Called getHeight() on a recycle()'d bitmap! This is undefined behavior!");
+ }
return mHeight;
}
@@ -1194,7 +1210,9 @@
* @return number of bytes between rows of the native bitmap pixels.
*/
public final int getRowBytes() {
- if (mRecycled) return 0;
+ if (mRecycled) {
+ Log.w(TAG, "Called getRowBytes() on a recycle()'d bitmap! This is undefined behavior!");
+ }
return nativeRowBytes(mFinalizer.mNativeBitmap);
}
@@ -1238,7 +1256,9 @@
* that config, otherwise return null.
*/
public final Config getConfig() {
- if (mRecycled) return Config.ARGB_8888;
+ if (mRecycled) {
+ Log.w(TAG, "Called getConfig() on a recycle()'d bitmap! This is undefined behavior!");
+ }
return Config.nativeToConfig(nativeConfig(mFinalizer.mNativeBitmap));
}
@@ -1251,7 +1271,9 @@
* it will return true by default.
*/
public final boolean hasAlpha() {
- if (mRecycled) return false;
+ if (mRecycled) {
+ Log.w(TAG, "Called hasAlpha() on a recycle()'d bitmap! This is undefined behavior!");
+ }
return nativeHasAlpha(mFinalizer.mNativeBitmap);
}
@@ -1288,7 +1310,9 @@
* @see #setHasMipMap(boolean)
*/
public final boolean hasMipMap() {
- if (mRecycled) return false;
+ if (mRecycled) {
+ Log.w(TAG, "Called hasMipMap() on a recycle()'d bitmap! This is undefined behavior!");
+ }
return nativeHasMipMap(mFinalizer.mNativeBitmap);
}
diff --git a/keystore/java/android/security/keystore/AndroidKeyStoreRSACipherSpi.java b/keystore/java/android/security/keystore/AndroidKeyStoreRSACipherSpi.java
index 94ed8b4..56cc44c 100644
--- a/keystore/java/android/security/keystore/AndroidKeyStoreRSACipherSpi.java
+++ b/keystore/java/android/security/keystore/AndroidKeyStoreRSACipherSpi.java
@@ -18,16 +18,11 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
-import android.os.IBinder;
import android.security.KeyStore;
-import android.security.KeyStoreException;
import android.security.keymaster.KeyCharacteristics;
import android.security.keymaster.KeymasterArguments;
import android.security.keymaster.KeymasterDefs;
-import libcore.util.EmptyArray;
-
-import java.io.ByteArrayOutputStream;
import java.security.AlgorithmParameters;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
@@ -103,91 +98,6 @@
protected final int getAdditionalEntropyAmountForFinish() {
return 0;
}
-
- @Override
- @NonNull
- protected KeyStoreCryptoOperationStreamer createMainDataStreamer(
- KeyStore keyStore, IBinder operationToken) {
- if (isEncrypting()) {
- // KeyStore's RSA encryption without padding expects the input to be of the same
- // length as the modulus. We thus have to buffer all input to pad it with leading
- // zeros.
- return new ZeroPaddingEncryptionStreamer(
- super.createMainDataStreamer(keyStore, operationToken),
- getModulusSizeBytes());
- } else {
- return super.createMainDataStreamer(keyStore, operationToken);
- }
- }
-
- /**
- * Streamer which buffers all plaintext input, then pads it with leading zeros to match
- * modulus size, and then sends it into KeyStore to obtain ciphertext.
- */
- private static class ZeroPaddingEncryptionStreamer
- implements KeyStoreCryptoOperationStreamer {
-
- private final KeyStoreCryptoOperationStreamer mDelegate;
- private final int mModulusSizeBytes;
- private final ByteArrayOutputStream mInputBuffer = new ByteArrayOutputStream();
- private long mConsumedInputSizeBytes;
-
- private ZeroPaddingEncryptionStreamer(
- KeyStoreCryptoOperationStreamer delegate,
- int modulusSizeBytes) {
- mDelegate = delegate;
- mModulusSizeBytes = modulusSizeBytes;
- }
-
- @Override
- public byte[] update(byte[] input, int inputOffset, int inputLength)
- throws KeyStoreException {
- if (inputLength > 0) {
- mInputBuffer.write(input, inputOffset, inputLength);
- mConsumedInputSizeBytes += inputLength;
- }
- return EmptyArray.BYTE;
- }
-
- @Override
- public byte[] doFinal(byte[] input, int inputOffset, int inputLength,
- byte[] signature, byte[] additionalEntropy) throws KeyStoreException {
- if (inputLength > 0) {
- mConsumedInputSizeBytes += inputLength;
- mInputBuffer.write(input, inputOffset, inputLength);
- }
- byte[] bufferedInput = mInputBuffer.toByteArray();
- mInputBuffer.reset();
- byte[] paddedInput;
- if (bufferedInput.length < mModulusSizeBytes) {
- // Pad input with leading zeros
- paddedInput = new byte[mModulusSizeBytes];
- System.arraycopy(
- bufferedInput, 0,
- paddedInput,
- paddedInput.length - bufferedInput.length,
- bufferedInput.length);
- } else {
- // RI throws BadPaddingException in this scenario. INVALID_ARGUMENT below will
- // be translated into BadPaddingException.
- throw new KeyStoreException(KeymasterDefs.KM_ERROR_INVALID_ARGUMENT,
- "Message size (" + bufferedInput.length + " bytes) must be smaller than"
- + " modulus (" + mModulusSizeBytes + " bytes)");
- }
- return mDelegate.doFinal(paddedInput, 0, paddedInput.length, signature,
- additionalEntropy);
- }
-
- @Override
- public long getConsumedInputSizeBytes() {
- return mConsumedInputSizeBytes;
- }
-
- @Override
- public long getProducedOutputSizeBytes() {
- return mDelegate.getProducedOutputSizeBytes();
- }
- }
}
/**
diff --git a/libs/androidfw/AssetManager.cpp b/libs/androidfw/AssetManager.cpp
index 2dc1c96..1c39ffe 100644
--- a/libs/androidfw/AssetManager.cpp
+++ b/libs/androidfw/AssetManager.cpp
@@ -1545,7 +1545,7 @@
*/
int dirNameLen = dirName.length();
void *iterationCookie;
- if (!pZip->startIteration(&iterationCookie)) {
+ if (!pZip->startIteration(&iterationCookie, dirName.string(), NULL)) {
ALOGW("ZipFileRO::startIteration returned false");
return false;
}
@@ -1560,9 +1560,7 @@
continue;
}
//printf("Comparing %s in %s?\n", nameBuf, dirName.string());
- if (dirNameLen == 0 ||
- (strncmp(nameBuf, dirName.string(), dirNameLen) == 0 &&
- nameBuf[dirNameLen] == '/'))
+ if (dirNameLen == 0 || nameBuf[dirNameLen] == '/')
{
const char* cp;
const char* nextSlash;
diff --git a/libs/hwui/Android.common.mk b/libs/hwui/Android.common.mk
index ed88237..7b2bba1 100644
--- a/libs/hwui/Android.common.mk
+++ b/libs/hwui/Android.common.mk
@@ -19,11 +19,11 @@
renderthread/RenderTask.cpp \
renderthread/RenderThread.cpp \
renderthread/TimeLord.cpp \
+ renderthread/DirtyHistory.cpp \
thread/TaskManager.cpp \
utils/Blur.cpp \
utils/GLUtils.cpp \
utils/LinearAllocator.cpp \
- utils/SortedListImpl.cpp \
AmbientShadow.cpp \
AnimationContext.cpp \
Animator.cpp \
diff --git a/libs/hwui/AnimatorManager.cpp b/libs/hwui/AnimatorManager.cpp
index 0dababd..cd30b18 100644
--- a/libs/hwui/AnimatorManager.cpp
+++ b/libs/hwui/AnimatorManager.cpp
@@ -124,8 +124,6 @@
}
void AnimatorManager::animateNoDamage(TreeInfo& info) {
- if (!mAnimators.size()) return;
-
animateCommon(info);
}
@@ -169,7 +167,7 @@
};
void AnimatorManager::endAllActiveAnimators() {
- ALOGD("endAllStagingAnimators on %p (%s) with handle %p",
+ ALOGD("endAllActiveAnimators on %p (%s) with handle %p",
&mParent, mParent.getName(), mAnimationHandle);
EndActiveAnimatorsFunctor functor(mAnimationHandle->context());
for_each(mAnimators.begin(), mAnimators.end(), functor);
diff --git a/libs/hwui/Extensions.cpp b/libs/hwui/Extensions.cpp
index b6feea5..814bada 100644
--- a/libs/hwui/Extensions.cpp
+++ b/libs/hwui/Extensions.cpp
@@ -56,6 +56,7 @@
mHasTiledRendering = hasGlExtension("GL_QCOM_tiled_rendering");
mHas1BitStencil = hasGlExtension("GL_OES_stencil1");
mHas4BitStencil = hasGlExtension("GL_OES_stencil4");
+ mHasUnpackSubImage = hasGlExtension("GL_EXT_unpack_subimage");
// Query EGL extensions
findExtensions(eglQueryString(eglGetCurrentDisplay(), EGL_EXTENSIONS), mEglExtensionList);
diff --git a/libs/hwui/Extensions.h b/libs/hwui/Extensions.h
index e7d317d..a4eef0f 100644
--- a/libs/hwui/Extensions.h
+++ b/libs/hwui/Extensions.h
@@ -44,7 +44,7 @@
inline bool has1BitStencil() const { return mHas1BitStencil; }
inline bool has4BitStencil() const { return mHas4BitStencil; }
inline bool hasNvSystemTime() const { return mHasNvSystemTime; }
- inline bool hasUnpackRowLength() const { return mVersionMajor >= 3; }
+ inline bool hasUnpackRowLength() const { return mVersionMajor >= 3 || mHasUnpackSubImage; }
inline bool hasPixelBufferObjects() const { return mVersionMajor >= 3; }
inline bool hasOcclusionQueries() const { return mVersionMajor >= 3; }
inline bool hasFloatTextures() const { return mVersionMajor >= 3; }
@@ -71,6 +71,7 @@
bool mHas1BitStencil;
bool mHas4BitStencil;
bool mHasNvSystemTime;
+ bool mHasUnpackSubImage;
int mVersionMajor;
int mVersionMinor;
diff --git a/libs/hwui/LayerCache.cpp b/libs/hwui/LayerCache.cpp
index ade2ac7..33f40b0 100644
--- a/libs/hwui/LayerCache.cpp
+++ b/libs/hwui/LayerCache.cpp
@@ -87,9 +87,8 @@
}
void LayerCache::clear() {
- size_t count = mCache.size();
- for (size_t i = 0; i < count; i++) {
- deleteLayer(mCache.itemAt(i).mLayer);
+ for (auto entry : mCache) {
+ deleteLayer(entry.mLayer);
}
mCache.clear();
}
@@ -98,11 +97,11 @@
Layer* layer = nullptr;
LayerEntry entry(width, height);
- ssize_t index = mCache.indexOf(entry);
+ auto iter = mCache.find(entry);
- if (index >= 0) {
- entry = mCache.itemAt(index);
- mCache.removeAt(index);
+ if (iter != mCache.end()) {
+ entry = *iter;
+ mCache.erase(iter);
layer = entry.mLayer;
layer->state = Layer::kState_RemovedFromCache;
@@ -129,9 +128,7 @@
}
void LayerCache::dump() {
- size_t size = mCache.size();
- for (size_t i = 0; i < size; i++) {
- const LayerEntry& entry = mCache.itemAt(i);
+ for (auto entry : mCache) {
ALOGD(" Layer size %dx%d", entry.mWidth, entry.mHeight);
}
}
@@ -144,13 +141,9 @@
if (size < mMaxSize) {
// TODO: Use an LRU
while (mSize + size > mMaxSize) {
- size_t position = 0;
-#if LAYER_REMOVE_BIGGEST_FIRST
- position = mCache.size() - 1;
-#endif
- Layer* victim = mCache.itemAt(position).mLayer;
+ Layer* victim = mCache.begin()->mLayer;
deleteLayer(victim);
- mCache.removeAt(position);
+ mCache.erase(mCache.begin());
LAYER_LOGD(" Deleting layer %.2fx%.2f", victim->layer.getWidth(),
victim->layer.getHeight());
@@ -160,7 +153,7 @@
LayerEntry entry(layer);
- mCache.add(entry);
+ mCache.insert(entry);
mSize += size;
layer->state = Layer::kState_InCache;
diff --git a/libs/hwui/LayerCache.h b/libs/hwui/LayerCache.h
index 7d17b9b..6fe7b3a 100644
--- a/libs/hwui/LayerCache.h
+++ b/libs/hwui/LayerCache.h
@@ -19,7 +19,8 @@
#include "Debug.h"
#include "Layer.h"
-#include "utils/SortedList.h"
+
+#include <set>
namespace android {
namespace uirenderer {
@@ -118,12 +119,8 @@
return compare(*this, other) != 0;
}
- friend inline int strictly_order_type(const LayerEntry& lhs, const LayerEntry& rhs) {
- return LayerEntry::compare(lhs, rhs) < 0;
- }
-
- friend inline int compare_type(const LayerEntry& lhs, const LayerEntry& rhs) {
- return LayerEntry::compare(lhs, rhs);
+ bool operator<(const LayerEntry& other) const {
+ return LayerEntry::compare(*this, other) < 0;
}
Layer* mLayer;
@@ -133,7 +130,7 @@
void deleteLayer(Layer* layer);
- SortedList<LayerEntry> mCache;
+ std::multiset<LayerEntry> mCache;
uint32_t mSize;
uint32_t mMaxSize;
diff --git a/libs/hwui/RenderBufferCache.cpp b/libs/hwui/RenderBufferCache.cpp
index 39e0dbf..8beed25 100644
--- a/libs/hwui/RenderBufferCache.cpp
+++ b/libs/hwui/RenderBufferCache.cpp
@@ -98,9 +98,8 @@
}
void RenderBufferCache::clear() {
- size_t count = mCache.size();
- for (size_t i = 0; i < count; i++) {
- deleteBuffer(mCache.itemAt(i).mBuffer);
+ for (auto entry : mCache) {
+ deleteBuffer(entry.mBuffer);
}
mCache.clear();
}
@@ -109,11 +108,11 @@
RenderBuffer* buffer = nullptr;
RenderBufferEntry entry(format, width, height);
- ssize_t index = mCache.indexOf(entry);
+ auto iter = mCache.find(entry);
- if (index >= 0) {
- entry = mCache.itemAt(index);
- mCache.removeAt(index);
+ if (iter != mCache.end()) {
+ entry = *iter;
+ mCache.erase(iter);
buffer = entry.mBuffer;
mSize -= buffer->getSize();
@@ -139,16 +138,14 @@
const uint32_t size = buffer->getSize();
if (size < mMaxSize) {
while (mSize + size > mMaxSize) {
- size_t position = 0;
-
- RenderBuffer* victim = mCache.itemAt(position).mBuffer;
+ RenderBuffer* victim = mCache.begin()->mBuffer;
deleteBuffer(victim);
- mCache.removeAt(position);
+ mCache.erase(mCache.begin());
}
RenderBufferEntry entry(buffer);
- mCache.add(entry);
+ mCache.insert(entry);
mSize += size;
RENDER_BUFFER_LOGD("Added %s render buffer (%dx%d)",
diff --git a/libs/hwui/RenderBufferCache.h b/libs/hwui/RenderBufferCache.h
index 6c668b0..7f59ec1 100644
--- a/libs/hwui/RenderBufferCache.h
+++ b/libs/hwui/RenderBufferCache.h
@@ -20,7 +20,8 @@
#include <GLES2/gl2.h>
#include "RenderBuffer.h"
-#include "utils/SortedList.h"
+
+#include <set>
namespace android {
namespace uirenderer {
@@ -100,14 +101,8 @@
return compare(*this, other) != 0;
}
- friend inline int strictly_order_type(const RenderBufferEntry& lhs,
- const RenderBufferEntry& rhs) {
- return RenderBufferEntry::compare(lhs, rhs) < 0;
- }
-
- friend inline int compare_type(const RenderBufferEntry& lhs,
- const RenderBufferEntry& rhs) {
- return RenderBufferEntry::compare(lhs, rhs);
+ bool operator<(const RenderBufferEntry& other) const {
+ return RenderBufferEntry::compare(*this, other) < 0;
}
RenderBuffer* mBuffer;
@@ -118,7 +113,7 @@
void deleteBuffer(RenderBuffer* buffer);
- SortedList<RenderBufferEntry> mCache;
+ std::multiset<RenderBufferEntry> mCache;
uint32_t mSize;
uint32_t mMaxSize;
diff --git a/libs/hwui/SkiaCanvasProxy.cpp b/libs/hwui/SkiaCanvasProxy.cpp
index 811a3b0..0e51325 100644
--- a/libs/hwui/SkiaCanvasProxy.cpp
+++ b/libs/hwui/SkiaCanvasProxy.cpp
@@ -18,7 +18,11 @@
#include <cutils/log.h>
#include <SkPatchUtils.h>
+#include <SkPaint.h>
+#include <SkPath.h>
#include <SkPixelRef.h>
+#include <SkRect.h>
+#include <SkRRect.h>
namespace android {
namespace uirenderer {
diff --git a/libs/hwui/renderstate/RenderState.cpp b/libs/hwui/renderstate/RenderState.cpp
index 3ebd57b..1e39bfa 100644
--- a/libs/hwui/renderstate/RenderState.cpp
+++ b/libs/hwui/renderstate/RenderState.cpp
@@ -124,9 +124,15 @@
}
void RenderState::invokeFunctor(Functor* functor, DrawGlInfo::Mode mode, DrawGlInfo* info) {
- interruptForFunctorInvoke();
- (*functor)(mode, info);
- resumeFromFunctorInvoke();
+ if (mode == DrawGlInfo::kModeProcessNoContext) {
+ // If there's no context we don't need to interrupt as there's
+ // no gl state to save/restore
+ (*functor)(mode, info);
+ } else {
+ interruptForFunctorInvoke();
+ (*functor)(mode, info);
+ resumeFromFunctorInvoke();
+ }
}
void RenderState::interruptForFunctorInvoke() {
diff --git a/libs/hwui/renderstate/Stencil.cpp b/libs/hwui/renderstate/Stencil.cpp
index 92a057d..319cfe4 100644
--- a/libs/hwui/renderstate/Stencil.cpp
+++ b/libs/hwui/renderstate/Stencil.cpp
@@ -60,8 +60,14 @@
}
void Stencil::clear() {
+ glStencilMask(0xff);
glClearStencil(0);
glClear(GL_STENCIL_BUFFER_BIT);
+
+ if (mState == kTest) {
+ // reset to test state, with immutable stencil
+ glStencilMask(0);
+ }
}
void Stencil::enableTest(int incrementThreshold) {
@@ -104,17 +110,17 @@
// We only want to test, let's keep everything
glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
mState = kTest;
+ glStencilMask(0);
}
void Stencil::enableDebugWrite() {
- if (mState != kWrite) {
- enable();
- glStencilFunc(GL_ALWAYS, 0x1, 0xffffffff);
- // The test always passes so the first two values are meaningless
- glStencilOp(GL_KEEP, GL_KEEP, GL_INCR);
- glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
- mState = kWrite;
- }
+ enable();
+ glStencilFunc(GL_ALWAYS, 0x1, 0xffffffff);
+ // The test always passes so the first two values are meaningless
+ glStencilOp(GL_KEEP, GL_KEEP, GL_INCR);
+ glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
+ mState = kWrite;
+ glStencilMask(0xff);
}
void Stencil::enable() {
diff --git a/libs/hwui/renderthread/CanvasContext.cpp b/libs/hwui/renderthread/CanvasContext.cpp
index e472e93..ea73387 100644
--- a/libs/hwui/renderthread/CanvasContext.cpp
+++ b/libs/hwui/renderthread/CanvasContext.cpp
@@ -98,6 +98,9 @@
setSurface(nullptr);
}
mHaveNewSurface = false;
+ if (mEglManager.useBufferAgeExt()) {
+ mDirtyHistory.prepend(Rect(dirty));
+ }
}
void CanvasContext::requireSurface() {
@@ -227,21 +230,30 @@
"drawRenderNode called on a context with no canvas or surface!");
SkRect dirty;
+ bool useBufferAgeExt = mEglManager.useBufferAgeExt();
+ Rect patchedDirty;
mDamageAccumulator.finish(&dirty);
- if (dirty.isEmpty() && Properties::skipEmptyFrames) {
- mCurrentFrameInfo->addFlag(FrameInfoFlags::SkippedFrame);
- return;
- }
+ // TODO: Re-enable after figuring out cause of b/22592975
+// if (dirty.isEmpty() && Properties::skipEmptyFrames) {
+// mCurrentFrameInfo->addFlag(FrameInfoFlags::SkippedFrame);
+// return;
+// }
mCurrentFrameInfo->markIssueDrawCommandsStart();
- EGLint width, height;
- mEglManager.beginFrame(mEglSurface, &width, &height);
+ EGLint width, height, framebufferAge;
+ mEglManager.beginFrame(mEglSurface, &width, &height, &framebufferAge);
+
+ if (useBufferAgeExt && mHaveNewSurface) {
+ mDirtyHistory.clear();
+ }
+
if (width != mCanvas->getViewportWidth() || height != mCanvas->getViewportHeight()) {
mCanvas->setViewport(width, height);
dirty.setEmpty();
} else if (!mBufferPreserved || mHaveNewSurface) {
+ mDirtyHistory.clear();
dirty.setEmpty();
} else {
if (!dirty.isEmpty() && !dirty.intersect(0, 0, width, height)) {
@@ -252,9 +264,14 @@
profiler().unionDirty(&dirty);
}
- if (!dirty.isEmpty()) {
- mCanvas->prepareDirty(dirty.fLeft, dirty.fTop,
- dirty.fRight, dirty.fBottom, mOpaque);
+ patchedDirty = dirty;
+ if (useBufferAgeExt && !dirty.isEmpty()) {
+ patchedDirty = mDirtyHistory.unionWith(Rect(dirty), framebufferAge-1);
+ }
+
+ if (!patchedDirty.isEmpty()) {
+ mCanvas->prepareDirty(patchedDirty.left, patchedDirty.top,
+ patchedDirty.right, patchedDirty.bottom, mOpaque);
} else {
mCanvas->prepare(mOpaque);
}
diff --git a/libs/hwui/renderthread/CanvasContext.h b/libs/hwui/renderthread/CanvasContext.h
index 88c18a5..59f9c3a 100644
--- a/libs/hwui/renderthread/CanvasContext.h
+++ b/libs/hwui/renderthread/CanvasContext.h
@@ -25,6 +25,7 @@
#include "utils/RingBuffer.h"
#include "renderthread/RenderTask.h"
#include "renderthread/RenderThread.h"
+#include "renderthread/DirtyHistory.h"
#include <cutils/compiler.h>
#include <EGL/egl.h>
@@ -146,6 +147,8 @@
FrameInfoVisualizer mProfiler;
std::set<RenderNode*> mPrefetechedLayers;
+
+ DirtyHistory mDirtyHistory;
};
} /* namespace renderthread */
diff --git a/libs/hwui/renderthread/DirtyHistory.cpp b/libs/hwui/renderthread/DirtyHistory.cpp
new file mode 100644
index 0000000..1419e84
--- /dev/null
+++ b/libs/hwui/renderthread/DirtyHistory.cpp
@@ -0,0 +1,69 @@
+/*
+ * 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.
+ */
+#include "DirtyHistory.h"
+
+namespace android {
+namespace uirenderer {
+namespace renderthread {
+
+DirtyHistory::DirtyHistory()
+ : mBack(DIRTY_HISTORY_SIZE - 1) {
+ clear();
+}
+
+void DirtyHistory::clear()
+{
+ for (int i = 0; i < DIRTY_HISTORY_SIZE; i++) {
+ mHistory[i].clear();
+ }
+}
+
+Rect DirtyHistory::get(int index) {
+ if (index >= DIRTY_HISTORY_SIZE || index < 0)
+ return Rect();
+ return mHistory[(1 + mBack + index) % DIRTY_HISTORY_SIZE];
+}
+
+Rect DirtyHistory::unionWith(Rect rect, int count) {
+ if (rect.isEmpty() || count > DIRTY_HISTORY_SIZE || count < 0)
+ return Rect();
+
+ for (int i = 0; i < count; i++) {
+ Rect ith = get(i);
+ if (ith.isEmpty())
+ return Rect();
+
+ // rect union
+ rect.left = fminf(rect.left, ith.left);
+ rect.top = fminf(rect.top, ith.top);
+ rect.right = fmaxf(rect.right, ith.right);
+ rect.bottom = fmaxf(rect.bottom, ith.bottom);
+ }
+ return rect;
+}
+
+void DirtyHistory::prepend(Rect rect) {
+ if (rect.isEmpty()) {
+ mHistory[mBack].clear();
+ } else {
+ mHistory[mBack].set(rect);
+ }
+ mBack = (mBack + DIRTY_HISTORY_SIZE - 1) % DIRTY_HISTORY_SIZE;
+}
+
+} /* namespace renderthread */
+} /* namespace uirenderer */
+} /* namespace android */
diff --git a/libs/hwui/renderthread/DirtyHistory.h b/libs/hwui/renderthread/DirtyHistory.h
new file mode 100644
index 0000000..d5ea597
--- /dev/null
+++ b/libs/hwui/renderthread/DirtyHistory.h
@@ -0,0 +1,45 @@
+/*
+ * 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.
+ */
+#ifndef DIRTYHISTORY_H
+#define DIRTYHISTORY_H
+
+#include <Rect.h>
+
+namespace android {
+namespace uirenderer {
+namespace renderthread {
+
+#define DIRTY_HISTORY_SIZE 4
+
+class DirtyHistory {
+public:
+ DirtyHistory();
+ ~DirtyHistory() {}
+
+ Rect get(int index);
+ Rect unionWith(Rect rect, int count);
+ void prepend(Rect rect);
+ void clear();
+private:
+ Rect mHistory[DIRTY_HISTORY_SIZE];
+ int mBack;
+};
+
+} /* namespace renderthread */
+} /* namespace uirenderer */
+} /* namespace android */
+
+#endif /* DIRTYHISTORY_H */
diff --git a/libs/hwui/renderthread/EglManager.cpp b/libs/hwui/renderthread/EglManager.cpp
index eb332d5..ac36f53 100644
--- a/libs/hwui/renderthread/EglManager.cpp
+++ b/libs/hwui/renderthread/EglManager.cpp
@@ -76,6 +76,7 @@
, mEglContext(EGL_NO_CONTEXT)
, mPBufferSurface(EGL_NO_SURFACE)
, mAllowPreserveBuffer(load_dirty_regions_property())
+ , mHasBufferAgeExt(false)
, mCurrentSurface(EGL_NO_SURFACE)
, mAtlasMap(nullptr)
, mAtlasMapSize(0) {
@@ -98,7 +99,10 @@
ALOGI("Initialized EGL, version %d.%d", (int)major, (int)minor);
- loadConfig();
+ findExtensions(eglQueryString(mEglDisplay, EGL_EXTENSIONS), mEglExtensionList);
+ mHasBufferAgeExt = hasEglExtension("EGL_EXT_buffer_age");
+
+ loadConfig(mHasBufferAgeExt);
createContext();
createPBufferSurface();
makeCurrent(mPBufferSurface);
@@ -110,8 +114,13 @@
return mEglDisplay != EGL_NO_DISPLAY;
}
-void EglManager::loadConfig() {
- EGLint swapBehavior = mCanSetPreserveBuffer ? EGL_SWAP_BEHAVIOR_PRESERVED_BIT : 0;
+bool EglManager::hasEglExtension(const char* extension) const {
+ const std::string s(extension);
+ return mEglExtensionList.find(s) != mEglExtensionList.end();
+}
+
+void EglManager::loadConfig(bool useBufferAgeExt) {
+ EGLint swapBehavior = (!useBufferAgeExt && mCanSetPreserveBuffer) ? EGL_SWAP_BEHAVIOR_PRESERVED_BIT : 0;
EGLint attribs[] = {
EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
EGL_RED_SIZE, 8,
@@ -133,7 +142,7 @@
ALOGW("Failed to choose config with EGL_SWAP_BEHAVIOR_PRESERVED, retrying without...");
// Try again without dirty regions enabled
mCanSetPreserveBuffer = false;
- loadConfig();
+ loadConfig(useBufferAgeExt);
} else {
LOG_ALWAYS_FATAL("Failed to choose config, error = %s", egl_error_str());
}
@@ -238,7 +247,7 @@
return true;
}
-void EglManager::beginFrame(EGLSurface surface, EGLint* width, EGLint* height) {
+void EglManager::beginFrame(EGLSurface surface, EGLint* width, EGLint* height, EGLint* framebufferAge) {
LOG_ALWAYS_FATAL_IF(surface == EGL_NO_SURFACE,
"Tried to beginFrame on EGL_NO_SURFACE!");
makeCurrent(surface);
@@ -248,6 +257,9 @@
if (height) {
eglQuerySurface(mEglDisplay, surface, EGL_HEIGHT, height);
}
+ if (useBufferAgeExt()) {
+ eglQuerySurface(mEglDisplay, surface, EGL_BUFFER_AGE_EXT, framebufferAge);
+ }
eglBeginFrame(mEglDisplay, surface);
}
@@ -304,6 +316,10 @@
return false;
}
+bool EglManager::useBufferAgeExt() {
+ return mAllowPreserveBuffer && mHasBufferAgeExt;
+}
+
void EglManager::fence() {
EGLSyncKHR fence = eglCreateSyncKHR(mEglDisplay, EGL_SYNC_FENCE_KHR, NULL);
eglClientWaitSyncKHR(mEglDisplay, fence,
@@ -314,6 +330,9 @@
bool EglManager::setPreserveBuffer(EGLSurface surface, bool preserve) {
if (CC_UNLIKELY(!mAllowPreserveBuffer)) return false;
+ // Use EGL_EXT_buffer_age instead if supported
+ if (mHasBufferAgeExt) return true;
+
bool preserved = false;
if (mCanSetPreserveBuffer) {
preserved = eglSurfaceAttrib(mEglDisplay, surface, EGL_SWAP_BEHAVIOR,
@@ -337,6 +356,19 @@
return preserved;
}
+void EglManager::findExtensions(const char* extensions, std::set<std::string>& list) const {
+ const char* current = extensions;
+ const char* head = current;
+ do {
+ head = strchr(current, ' ');
+ std::string s(current, head ? head - current : strlen(current));
+ if (s.length()) {
+ list.insert(s);
+ }
+ current = head + 1;
+ } while (head);
+}
+
} /* namespace renderthread */
} /* namespace uirenderer */
} /* namespace android */
diff --git a/libs/hwui/renderthread/EglManager.h b/libs/hwui/renderthread/EglManager.h
index 0a8cfd3..bb5d24b 100644
--- a/libs/hwui/renderthread/EglManager.h
+++ b/libs/hwui/renderthread/EglManager.h
@@ -21,6 +21,7 @@
#include <SkRect.h>
#include <ui/GraphicBuffer.h>
#include <utils/StrongPointer.h>
+#include <set>
namespace android {
namespace uirenderer {
@@ -37,6 +38,8 @@
bool hasEglContext();
+ bool hasEglExtension(const char* extension) const;
+
EGLSurface createSurface(EGLNativeWindowType window);
void destroySurface(EGLSurface surface);
@@ -45,12 +48,14 @@
bool isCurrent(EGLSurface surface) { return mCurrentSurface == surface; }
// Returns true if the current surface changed, false if it was already current
bool makeCurrent(EGLSurface surface, EGLint* errOut = nullptr);
- void beginFrame(EGLSurface surface, EGLint* width, EGLint* height);
+ void beginFrame(EGLSurface surface, EGLint* width, EGLint* height, EGLint* framebufferAge);
bool swapBuffers(EGLSurface surface, const SkRect& dirty, EGLint width, EGLint height);
// Returns true iff the surface is now preserving buffers.
bool setPreserveBuffer(EGLSurface surface, bool preserve);
+ bool useBufferAgeExt();
+
void setTextureAtlas(const sp<GraphicBuffer>& buffer, int64_t* map, size_t mapSize);
void fence();
@@ -63,10 +68,12 @@
~EglManager();
void createPBufferSurface();
- void loadConfig();
+ void loadConfig(bool useBufferAgeExt);
void createContext();
void initAtlas();
+ void findExtensions(const char* extensions, std::set<std::string>& list) const;
+
RenderThread& mRenderThread;
EGLDisplay mEglDisplay;
@@ -77,11 +84,15 @@
const bool mAllowPreserveBuffer;
bool mCanSetPreserveBuffer;
+ bool mHasBufferAgeExt;
+
EGLSurface mCurrentSurface;
sp<GraphicBuffer> mAtlasBuffer;
int64_t* mAtlasMap;
size_t mAtlasMapSize;
+
+ std::set<std::string> mEglExtensionList;
};
} /* namespace renderthread */
diff --git a/libs/hwui/utils/LinearAllocator.cpp b/libs/hwui/utils/LinearAllocator.cpp
index 59b12cf..01cf5d2 100644
--- a/libs/hwui/utils/LinearAllocator.cpp
+++ b/libs/hwui/utils/LinearAllocator.cpp
@@ -32,7 +32,7 @@
// The ideal size of a page allocation (these need to be multiples of 8)
-#define INITIAL_PAGE_SIZE ((size_t)4096) // 4kb
+#define INITIAL_PAGE_SIZE ((size_t)512) // 512b
#define MAX_PAGE_SIZE ((size_t)131072) // 128kb
// The maximum amount of wasted space we can have per page
@@ -40,7 +40,7 @@
// If this is too low, we will malloc too much
// Too high, and we may waste too much space
// Must be smaller than INITIAL_PAGE_SIZE
-#define MAX_WASTE_SIZE ((size_t)1024)
+#define MAX_WASTE_RATIO (0.5f)
#if ALIGN_DOUBLE
#define ALIGN_SZ (sizeof(double))
@@ -114,7 +114,7 @@
LinearAllocator::LinearAllocator()
: mPageSize(INITIAL_PAGE_SIZE)
- , mMaxAllocSize(MAX_WASTE_SIZE)
+ , mMaxAllocSize(INITIAL_PAGE_SIZE * MAX_WASTE_RATIO)
, mNext(0)
, mCurrentPage(0)
, mPages(0)
@@ -156,6 +156,7 @@
if (mCurrentPage && mPageSize < MAX_PAGE_SIZE) {
mPageSize = min(MAX_PAGE_SIZE, mPageSize * 2);
+ mMaxAllocSize = mPageSize * MAX_WASTE_RATIO;
mPageSize = ALIGN(mPageSize);
}
mWastedSpace += mPageSize;
diff --git a/libs/hwui/utils/SortedList.h b/libs/hwui/utils/SortedList.h
deleted file mode 100644
index a2c8c52..0000000
--- a/libs/hwui/utils/SortedList.h
+++ /dev/null
@@ -1,242 +0,0 @@
-/*
- * 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.
- */
-
-#ifndef ANDROID_HWUI_SORTED_LIST_H
-#define ANDROID_HWUI_SORTED_LIST_H
-
-#include <stdint.h>
-#include <sys/types.h>
-
-#include <utils/Vector.h>
-#include <utils/TypeHelpers.h>
-
-#include "SortedListImpl.h"
-
-namespace android {
-namespace uirenderer {
-
-///////////////////////////////////////////////////////////////////////////////
-// Sorted list
-///////////////////////////////////////////////////////////////////////////////
-
-template<class TYPE>
-class SortedList: private SortedListImpl {
-public:
- typedef TYPE value_type;
-
- SortedList();
- SortedList(const SortedList<TYPE>& rhs);
- virtual ~SortedList();
-
- const SortedList<TYPE>& operator =(const SortedList<TYPE>& rhs) const;
- SortedList<TYPE>& operator =(const SortedList<TYPE>& rhs);
-
- inline void clear() {
- VectorImpl::clear();
- }
-
- inline size_t size() const {
- return VectorImpl::size();
- }
-
- inline bool isEmpty() const {
- return VectorImpl::isEmpty();
- }
-
- inline size_t capacity() const {
- return VectorImpl::capacity();
- }
-
- inline ssize_t setCapacity(size_t size) {
- return VectorImpl::setCapacity(size);
- }
-
- inline const TYPE* array() const;
-
- TYPE* editArray();
-
- ssize_t indexOf(const TYPE& item) const;
- size_t orderOf(const TYPE& item) const;
-
- inline const TYPE& operator [](size_t index) const;
- inline const TYPE& itemAt(size_t index) const;
- const TYPE& top() const;
- const TYPE& mirrorItemAt(ssize_t index) const;
-
- ssize_t add(const TYPE& item);
-
- TYPE& editItemAt(size_t index) {
- return *(static_cast<TYPE *> (VectorImpl::editItemLocation(index)));
- }
-
- ssize_t merge(const Vector<TYPE>& vector);
- ssize_t merge(const SortedList<TYPE>& vector);
-
- ssize_t remove(const TYPE&);
-
- inline ssize_t removeItemsAt(size_t index, size_t count = 1);
- inline ssize_t removeAt(size_t index) {
- return removeItemsAt(index);
- }
-
-protected:
- virtual void do_construct(void* storage, size_t num) const override;
- virtual void do_destroy(void* storage, size_t num) const override;
- virtual void do_copy(void* dest, const void* from, size_t num) const override;
- virtual void do_splat(void* dest, const void* item, size_t num) const override;
- virtual void do_move_forward(void* dest, const void* from, size_t num) const override;
- virtual void do_move_backward(void* dest, const void* from, size_t num) const override;
- virtual int do_compare(const void* lhs, const void* rhs) const override;
-}; // class SortedList
-
-///////////////////////////////////////////////////////////////////////////////
-// Implementation
-///////////////////////////////////////////////////////////////////////////////
-
-template<class TYPE>
-inline SortedList<TYPE>::SortedList():
- SortedListImpl(sizeof(TYPE), ((traits<TYPE>::has_trivial_ctor ? HAS_TRIVIAL_CTOR : 0)
- | (traits<TYPE>::has_trivial_dtor ? HAS_TRIVIAL_DTOR : 0)
- | (traits<TYPE>::has_trivial_copy ? HAS_TRIVIAL_COPY : 0))) {
-}
-
-template<class TYPE>
-inline SortedList<TYPE>::SortedList(const SortedList<TYPE>& rhs): SortedListImpl(rhs) {
-}
-
-template<class TYPE> inline SortedList<TYPE>::~SortedList() {
- finish_vector();
-}
-
-template<class TYPE>
-inline SortedList<TYPE>& SortedList<TYPE>::operator =(const SortedList<TYPE>& rhs) {
- SortedListImpl::operator =(rhs);
- return *this;
-}
-
-template<class TYPE>
-inline const SortedList<TYPE>& SortedList<TYPE>::operator =(
- const SortedList<TYPE>& rhs) const {
- SortedListImpl::operator =(rhs);
- return *this;
-}
-
-template<class TYPE>
-inline const TYPE* SortedList<TYPE>::array() const {
- return static_cast<const TYPE *> (arrayImpl());
-}
-
-template<class TYPE>
-inline TYPE* SortedList<TYPE>::editArray() {
- return static_cast<TYPE *> (editArrayImpl());
-}
-
-template<class TYPE>
-inline const TYPE& SortedList<TYPE>::operator[](size_t index) const {
- assert( index<size() );
- return *(array() + index);
-}
-
-template<class TYPE>
-inline const TYPE& SortedList<TYPE>::itemAt(size_t index) const {
- return operator[](index);
-}
-
-template<class TYPE>
-inline const TYPE& SortedList<TYPE>::mirrorItemAt(ssize_t index) const {
- assert( (index>0 ? index : -index)<size() );
- return *(array() + ((index < 0) ? (size() - index) : index));
-}
-
-template<class TYPE>
-inline const TYPE& SortedList<TYPE>::top() const {
- return *(array() + size() - 1);
-}
-
-template<class TYPE>
-inline ssize_t SortedList<TYPE>::add(const TYPE& item) {
- return SortedListImpl::add(&item);
-}
-
-template<class TYPE>
-inline ssize_t SortedList<TYPE>::indexOf(const TYPE& item) const {
- return SortedListImpl::indexOf(&item);
-}
-
-template<class TYPE>
-inline size_t SortedList<TYPE>::orderOf(const TYPE& item) const {
- return SortedListImpl::orderOf(&item);
-}
-
-template<class TYPE>
-inline ssize_t SortedList<TYPE>::merge(const Vector<TYPE>& vector) {
- return SortedListImpl::merge(reinterpret_cast<const VectorImpl&> (vector));
-}
-
-template<class TYPE>
-inline ssize_t SortedList<TYPE>::merge(const SortedList<TYPE>& vector) {
- return SortedListImpl::merge(reinterpret_cast<const SortedListImpl&> (vector));
-}
-
-template<class TYPE>
-inline ssize_t SortedList<TYPE>::remove(const TYPE& item) {
- return SortedListImpl::remove(&item);
-}
-
-template<class TYPE>
-inline ssize_t SortedList<TYPE>::removeItemsAt(size_t index, size_t count) {
- return VectorImpl::removeItemsAt(index, count);
-}
-
-template<class TYPE>
-void SortedList<TYPE>::do_construct(void* storage, size_t num) const {
- construct_type(reinterpret_cast<TYPE*> (storage), num);
-}
-
-template<class TYPE>
-void SortedList<TYPE>::do_destroy(void* storage, size_t num) const {
- destroy_type(reinterpret_cast<TYPE*> (storage), num);
-}
-
-template<class TYPE>
-void SortedList<TYPE>::do_copy(void* dest, const void* from, size_t num) const {
- copy_type(reinterpret_cast<TYPE*> (dest), reinterpret_cast<const TYPE*> (from), num);
-}
-
-template<class TYPE>
-void SortedList<TYPE>::do_splat(void* dest, const void* item, size_t num) const {
- splat_type(reinterpret_cast<TYPE*> (dest), reinterpret_cast<const TYPE*> (item), num);
-}
-
-template<class TYPE>
-void SortedList<TYPE>::do_move_forward(void* dest, const void* from, size_t num) const {
- move_forward_type(reinterpret_cast<TYPE*> (dest), reinterpret_cast<const TYPE*> (from), num);
-}
-
-template<class TYPE>
-void SortedList<TYPE>::do_move_backward(void* dest, const void* from, size_t num) const {
- move_backward_type(reinterpret_cast<TYPE*> (dest), reinterpret_cast<const TYPE*> (from), num);
-}
-
-template<class TYPE>
-int SortedList<TYPE>::do_compare(const void* lhs, const void* rhs) const {
- return compare_type(*reinterpret_cast<const TYPE*> (lhs), *reinterpret_cast<const TYPE*> (rhs));
-}
-
-}; // namespace uirenderer
-}; // namespace android
-
-#endif // ANDROID_HWUI_SORTED_LIST_H
diff --git a/libs/hwui/utils/SortedListImpl.cpp b/libs/hwui/utils/SortedListImpl.cpp
deleted file mode 100644
index 35171d5..0000000
--- a/libs/hwui/utils/SortedListImpl.cpp
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
- * 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.
- */
-
-#include "SortedListImpl.h"
-
-namespace android {
-namespace uirenderer {
-
-///////////////////////////////////////////////////////////////////////////////
-// Sorted list implementation, not for direct use
-///////////////////////////////////////////////////////////////////////////////
-
-SortedListImpl::SortedListImpl(size_t itemSize, uint32_t flags): VectorImpl(itemSize, flags) {
-}
-
-SortedListImpl::SortedListImpl(const VectorImpl& rhs): VectorImpl(rhs) {
-}
-
-SortedListImpl::~SortedListImpl() {
-}
-
-SortedListImpl& SortedListImpl::operator =(const SortedListImpl& rhs) {
- return static_cast<SortedListImpl&>
- (VectorImpl::operator =(static_cast<const VectorImpl&> (rhs)));
-}
-
-ssize_t SortedListImpl::indexOf(const void* item) const {
- return _indexOrderOf(item);
-}
-
-size_t SortedListImpl::orderOf(const void* item) const {
- size_t o;
- _indexOrderOf(item, &o);
- return o;
-}
-
-ssize_t SortedListImpl::_indexOrderOf(const void* item, size_t* order) const {
- // binary search
- ssize_t err = NAME_NOT_FOUND;
- ssize_t l = 0;
- ssize_t h = size() - 1;
- ssize_t mid;
- const void* a = arrayImpl();
- const size_t s = itemSize();
- while (l <= h) {
- mid = l + (h - l) / 2;
- const void* const curr = reinterpret_cast<const char *> (a) + (mid * s);
- const int c = do_compare(curr, item);
- if (c == 0) {
- err = l = mid;
- break;
- } else if (c < 0) {
- l = mid + 1;
- } else {
- h = mid - 1;
- }
- }
- if (order) {
- *order = l;
- }
- return err;
-}
-
-ssize_t SortedListImpl::add(const void* item) {
- size_t order;
- ssize_t index = _indexOrderOf(item, &order);
- index = VectorImpl::insertAt(item, order, 1);
- return index;
-}
-
-ssize_t SortedListImpl::merge(const VectorImpl& vector) {
- // naive merge...
- if (!vector.isEmpty()) {
- const void* buffer = vector.arrayImpl();
- const size_t is = itemSize();
- size_t s = vector.size();
- for (size_t i = 0; i < s; i++) {
- ssize_t err = add(reinterpret_cast<const char*> (buffer) + i * is);
- if (err < 0) {
- return err;
- }
- }
- }
- return NO_ERROR;
-}
-
-ssize_t SortedListImpl::merge(const SortedListImpl& vector) {
- // we've merging a sorted vector... nice!
- ssize_t err = NO_ERROR;
- if (!vector.isEmpty()) {
- // first take care of the case where the vectors are sorted together
- if (do_compare(vector.itemLocation(vector.size() - 1), arrayImpl()) <= 0) {
- err = VectorImpl::insertVectorAt(static_cast<const VectorImpl&> (vector), 0);
- } else if (do_compare(vector.arrayImpl(), itemLocation(size() - 1)) >= 0) {
- err = VectorImpl::appendVector(static_cast<const VectorImpl&> (vector));
- } else {
- // this could be made a little better
- err = merge(static_cast<const VectorImpl&> (vector));
- }
- }
- return err;
-}
-
-ssize_t SortedListImpl::remove(const void* item) {
- ssize_t i = indexOf(item);
- if (i >= 0) {
- VectorImpl::removeItemsAt(i, 1);
- }
- return i;
-}
-
-}; // namespace uirenderer
-}; // namespace android
diff --git a/libs/hwui/utils/SortedListImpl.h b/libs/hwui/utils/SortedListImpl.h
deleted file mode 100644
index b101826..0000000
--- a/libs/hwui/utils/SortedListImpl.h
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * 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.
- */
-
-#ifndef ANDROID_HWUI_SORTED_LIST_IMPL_H
-#define ANDROID_HWUI_SORTED_LIST_IMPL_H
-
-#include <utils/VectorImpl.h>
-
-namespace android {
-namespace uirenderer {
-
-class SortedListImpl: public VectorImpl {
-public:
- SortedListImpl(size_t itemSize, uint32_t flags);
- SortedListImpl(const VectorImpl& rhs);
- virtual ~SortedListImpl();
-
- SortedListImpl& operator =(const SortedListImpl& rhs);
-
- ssize_t indexOf(const void* item) const;
- size_t orderOf(const void* item) const;
- ssize_t add(const void* item);
- ssize_t merge(const VectorImpl& vector);
- ssize_t merge(const SortedListImpl& vector);
- ssize_t remove(const void* item);
-
-protected:
- virtual int do_compare(const void* lhs, const void* rhs) const = 0;
-
-private:
- ssize_t _indexOrderOf(const void* item, size_t* order = nullptr) const;
-
- // these are made private, because they can't be used on a SortedVector
- // (they don't have an implementation either)
- ssize_t add();
- void pop();
- void push();
- void push(const void* item);
- ssize_t insertVectorAt(const VectorImpl& vector, size_t index);
- ssize_t appendVector(const VectorImpl& vector);
- ssize_t insertArrayAt(const void* array, size_t index, size_t length);
- ssize_t appendArray(const void* array, size_t length);
- ssize_t insertAt(size_t where, size_t numItems = 1);
- ssize_t insertAt(const void* item, size_t where, size_t numItems = 1);
- ssize_t replaceAt(size_t index);
- ssize_t replaceAt(const void* item, size_t index);
-};
-
-}; // namespace uirenderer
-}; // namespace android
-
-#endif // ANDROID_HWUI_SORTED_LIST_IMPL_H
diff --git a/media/java/android/media/AudioDeviceInfo.java b/media/java/android/media/AudioDeviceInfo.java
index bdb1f58..6104264 100644
--- a/media/java/android/media/AudioDeviceInfo.java
+++ b/media/java/android/media/AudioDeviceInfo.java
@@ -156,6 +156,8 @@
/**
* @return An array of sample rates supported by the audio device.
+ *
+ * Note: an empty array indicates that the device supports arbitrary rates.
*/
public @NonNull int[] getSampleRates() {
return mPort.samplingRates();
@@ -166,6 +168,8 @@
* {@link AudioFormat#CHANNEL_OUT_7POINT1}) for which this audio device can be configured.
*
* @see AudioFormat
+ *
+ * Note: an empty array indicates that the device supports arbitrary channel masks.
*/
public @NonNull int[] getChannelMasks() {
return mPort.channelMasks();
@@ -175,6 +179,8 @@
* @return An array of channel index masks for which this audio device can be configured.
*
* @see AudioFormat
+ *
+ * Note: an empty array indicates that the device supports arbitrary channel index masks.
*/
public @NonNull int[] getChannelIndexMasks() {
return mPort.channelIndexMasks();
@@ -183,6 +189,8 @@
/**
* @return An array of channel counts (1, 2, 4, ...) for which this audio device
* can be configured.
+ *
+ * Note: an empty array indicates that the device supports arbitrary channel counts.
*/
public @NonNull int[] getChannelCounts() {
int[] masks = getChannelMasks();
@@ -205,6 +213,8 @@
* integer precision to that device.
*
* @see AudioFormat
+ *
+ * Note: an empty array indicates that the device supports arbitrary encodings.
*/
public @NonNull int[] getEncodings() {
return AudioFormat.filterPublicFormats(mPort.formats());
diff --git a/media/java/android/media/AudioFormat.java b/media/java/android/media/AudioFormat.java
index c29ec0d..bde3d19 100644
--- a/media/java/android/media/AudioFormat.java
+++ b/media/java/android/media/AudioFormat.java
@@ -54,7 +54,7 @@
* can be played on a device operating at a sample rate of 48000Hz; the sample rate conversion is
* automatically handled by the platform, it will not play at 6x speed.
*
- * <p>As of API {@link android.os.Build.VERSION_CODES#MNC},
+ * <p>As of API {@link android.os.Build.VERSION_CODES#M},
* sample rates up to 192kHz are supported
* for <code>AudioRecord</code> and <code>AudioTrack</code>, with sample rate conversion
* performed as needed.
@@ -99,7 +99,7 @@
* Floats are efficiently manipulated by modern CPUs,
* have greater precision than 24 bit signed integers,
* and have greater dynamic range than 32 bit signed integers.
- * <code>AudioRecord</code> as of API {@link android.os.Build.VERSION_CODES#MNC} and
+ * <code>AudioRecord</code> as of API {@link android.os.Build.VERSION_CODES#M} and
* <code>AudioTrack</code> as of API {@link android.os.Build.VERSION_CODES#LOLLIPOP}
* support <code>ENCODING_PCM_FLOAT</code>.
* </li>
@@ -123,7 +123,7 @@
* the samples and their arrangement in the audio frame. They are also used in the endpoint (e.g.
* a USB audio interface, a DAC connected to headphones) to specify allowable configurations of a
* particular device.
- * <br>As of API {@link android.os.Build.VERSION_CODES#MNC}, there are two types of channel masks:
+ * <br>As of API {@link android.os.Build.VERSION_CODES#M}, there are two types of channel masks:
* channel position masks and channel index masks.
*
* <h5 id="channelPositionMask">Channel position masks</h5>
@@ -152,7 +152,7 @@
* {@link #CHANNEL_OUT_FRONT_RIGHT}.
*
* <h5 id="channelIndexMask">Channel index masks</h5>
- * Channel index masks are introduced in API {@link android.os.Build.VERSION_CODES#MNC}. They allow
+ * Channel index masks are introduced in API {@link android.os.Build.VERSION_CODES#M}. They allow
* the selection of a particular channel from the source or sink endpoint by number, i.e. the first
* channel, the second channel, and so forth. This avoids problems with artificially assigning
* positions to channels of an endpoint, or figuring what the i<sup>th</sup> position bit is within
diff --git a/media/java/android/media/AudioSystem.java b/media/java/android/media/AudioSystem.java
index acdadd7..e99a37a 100644
--- a/media/java/android/media/AudioSystem.java
+++ b/media/java/android/media/AudioSystem.java
@@ -604,6 +604,10 @@
public static final int SYNC_EVENT_NONE = 0;
public static final int SYNC_EVENT_PRESENTATION_COMPLETE = 1;
+ /**
+ * @return command completion status, one of {@link #AUDIO_STATUS_OK},
+ * {@link #AUDIO_STATUS_ERROR} or {@link #AUDIO_STATUS_SERVER_DIED}
+ */
public static native int setDeviceConnectionState(int device, int state,
String device_address, String device_name);
public static native int getDeviceConnectionState(int device, String device_address);
diff --git a/media/java/android/media/AudioTrack.java b/media/java/android/media/AudioTrack.java
index 62810c6..8880dad 100644
--- a/media/java/android/media/AudioTrack.java
+++ b/media/java/android/media/AudioTrack.java
@@ -27,7 +27,6 @@
import android.annotation.IntDef;
import android.annotation.NonNull;
-import android.annotation.SystemApi;
import android.app.ActivityThread;
import android.app.AppOpsManager;
import android.content.Context;
@@ -1174,9 +1173,12 @@
* Poll for a timestamp on demand.
* <p>
* If you need to track timestamps during initial warmup or after a routing or mode change,
- * you should request a new timestamp once per second until the reported timestamps
- * show that the audio clock is stable.
- * Thereafter, query for a new timestamp approximately once every 10 seconds to once per minute.
+ * you should request a new timestamp periodically until the reported timestamps
+ * show that the frame position is advancing, or until it becomes clear that
+ * timestamps are unavailable for this route.
+ * <p>
+ * After the clock is advancing at a stable rate,
+ * query for a new timestamp approximately once every 10 seconds to once per minute.
* Calling this method more often is inefficient.
* It is also counter-productive to call this method more often than recommended,
* because the short-term differences between successive timestamp reports are not meaningful.
@@ -1199,6 +1201,11 @@
* In the case that no timestamp is available, any supplied instance is left unaltered.
* A timestamp may be temporarily unavailable while the audio clock is stabilizing,
* or during and immediately after a route change.
+ * A timestamp is permanently unavailable for a given route if the route does not support
+ * timestamps. In this case, the approximate frame position can be obtained
+ * using {@link #getPlaybackHeadPosition}.
+ * However, it may be useful to continue to query for
+ * timestamps occasionally, to recover after a route change.
*/
// Add this text when the "on new timestamp" API is added:
// Use if you need to get the most recent timestamp outside of the event callback handler.
@@ -1409,7 +1416,7 @@
* <br>
* If looping is currently enabled and the new position is greater than or equal to the
* loop end marker, the behavior varies by API level:
- * as of {@link android.os.Build.VERSION_CODES#MNC},
+ * as of {@link android.os.Build.VERSION_CODES#M},
* the looping is first disabled and then the position is set.
* For earlier API levels, the behavior is unspecified.
* @return error code or success, see {@link #SUCCESS}, {@link #ERROR_BAD_VALUE},
@@ -1446,7 +1453,7 @@
* {@link #ERROR_BAD_VALUE} is returned.
* The loop range is the interval [startInFrames, endInFrames).
* <br>
- * As of {@link android.os.Build.VERSION_CODES#MNC}, the position is left unchanged,
+ * As of {@link android.os.Build.VERSION_CODES#M}, the position is left unchanged,
* unless it is greater than or equal to the loop end marker, in which case
* it is forced to the loop start marker.
* For earlier API levels, the effect on position is unspecified.
@@ -2077,7 +2084,7 @@
* The track must be stopped or paused, and
* the track's creation mode must be {@link #MODE_STATIC}.
* <p>
- * As of {@link android.os.Build.VERSION_CODES#MNC}, also resets the value returned by
+ * As of {@link android.os.Build.VERSION_CODES#M}, also resets the value returned by
* {@link #getPlaybackHeadPosition()} to zero.
* For earlier API levels, the reset behavior is unspecified.
* <p>
diff --git a/media/java/android/media/MediaCodec.java b/media/java/android/media/MediaCodec.java
index 5f60891..6c224e5 100644
--- a/media/java/android/media/MediaCodec.java
+++ b/media/java/android/media/MediaCodec.java
@@ -21,12 +21,8 @@
import android.annotation.Nullable;
import android.graphics.ImageFormat;
import android.graphics.Rect;
-import android.media.Image;
-import android.media.MediaCodecInfo;
+import android.graphics.SurfaceTexture;
import android.media.MediaCodecInfo.CodecCapabilities;
-import android.media.MediaCodecList;
-import android.media.MediaCrypto;
-import android.media.MediaFormat;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
@@ -37,6 +33,7 @@
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
import java.nio.ReadOnlyBufferException;
import java.util.Arrays;
import java.util.HashMap;
@@ -233,8 +230,9 @@
data and submit it as a single codec-config buffer.
<p>
Android uses the following codec-specific data buffers. These are also required to be set in
- the track format for proper {@link MediaMuxer} track configuration. Each parameter set and
- codec-specific-data must start with a start code of {@code "\x00\x00\x00\x01"}.
+ the track format for proper {@link MediaMuxer} track configuration. Each parameter set and the
+ codec-specific-data sections marked with (<sup>*</sup>) must start with a start code of
+ {@code "\x00\x00\x00\x01"}.
<p>
<style>td.NA { background: #ccc; } .mid > tr > td { vertical-align: middle; }</style>
<table>
@@ -242,28 +240,48 @@
<th>Format</th>
<th>CSD buffer #0</th>
<th>CSD buffer #1</th>
+ <th>CSD buffer #2</th>
</thead>
<tbody class=mid>
<tr>
<td>AAC</td>
- <td>Decoder-specific information from ESDS</td>
+ <td>Decoder-specific information from ESDS<sup>*</sup></td>
+ <td class=NA>Not Used</td>
<td class=NA>Not Used</td>
</tr>
<tr>
+ <td>VORBIS</td>
+ <td>Identification header</td>
+ <td>Setup header</td>
+ <td class=NA>Not Used</td>
+ </tr>
+ <tr>
+ <td>OPUS</td>
+ <td>Identification header</td>
+ <td>Pre-skip in nanosecs<br>
+ (unsigned 64-bit {@linkplain ByteOrder#nativeOrder native-order} integer.)<br>
+ This overrides the pre-skip value in the identification header.</td>
+ <td>Seek Pre-roll in nanosecs<br>
+ (unsigned 64-bit {@linkplain ByteOrder#nativeOrder native-order} integer.)</td>
+ </tr>
+ <tr>
<td>MPEG-4</td>
- <td>Decoder-specific information from ESDS</td>
+ <td>Decoder-specific information from ESDS<sup>*</sup></td>
+ <td class=NA>Not Used</td>
<td class=NA>Not Used</td>
</tr>
<tr>
<td>H.264 AVC</td>
- <td>SPS (Sequence Parameter Sets)</td>
- <td>PPS (Picture Parameter Sets)</td>
+ <td>SPS (Sequence Parameter Sets<sup>*</sup>)</td>
+ <td>PPS (Picture Parameter Sets<sup>*</sup>)</td>
+ <td class=NA>Not Used</td>
</tr>
<tr>
<td>H.265 HEVC</td>
- <td>VPS (Video Parameter Sets) +<br>
- SPS (Sequence Parameter Sets) +<br>
- PPS (Picture Parameter Sets)</td>
+ <td>VPS (Video Parameter Sets<sup>*</sup>) +<br>
+ SPS (Sequence Parameter Sets<sup>*</sup>) +<br>
+ PPS (Picture Parameter Sets<sup>*</sup>)</td>
+ <td class=NA>Not Used</td>
<td class=NA>Not Used</td>
</tr>
</tbody>
@@ -302,10 +320,10 @@
releaseOutputBuffer} methods to return the buffer to the codec.
<p>
While you are not required to resubmit/release buffers immediately to the codec, holding onto
- input and/or output buffers may stall the codec, and this behavior is device dependent. E.g. it
- is possible that a codec may hold off on generating output buffers until all outstanding buffers
- have been released/resubmitted. Therefore, try to hold onto to available buffers as little as
- possible.
+ input and/or output buffers may stall the codec, and this behavior is device dependent.
+ <strong>Specifically, it is possible that a codec may hold off on generating output buffers until
+ <em>all</em> outstanding buffers have been released/resubmitted.</strong> Therefore, try to
+ hold onto to available buffers as little as possible.
<p>
Depending on the API version, you can process data in three ways:
<table>
@@ -351,7 +369,7 @@
<p>
MediaCodec is typically used like this in asynchronous mode:
<pre class=prettyprint>
- MediaCodec codec = MediaCodec.createCodecByName(name);
+ MediaCodec codec = MediaCodec.createByCodecName(name);
MediaFormat mOutputFormat; // member variable
codec.setCallback(new MediaCodec.Callback() {
{@literal @Override}
@@ -408,7 +426,7 @@
<p>
MediaCodec is typically used like this in synchronous mode:
<pre>
- MediaCodec codec = MediaCodec.createCodecByName(name);
+ MediaCodec codec = MediaCodec.createByCodecName(name);
codec.configure(format, …);
MediaFormat outputFormat = codec.getOutputFormat(); // option B
codec.start();
@@ -447,7 +465,7 @@
between the size of the arrays and the number of input and output buffers used by the system,
although the array size provides an upper bound.
<pre>
- MediaCodec codec = MediaCodec.createCodecByName(name);
+ MediaCodec codec = MediaCodec.createByCodecName(name);
codec.configure(format, …);
codec.start();
ByteBuffer[] inputBuffers = codec.getInputBuffers();
@@ -510,11 +528,11 @@
#releaseOutputBuffer(int, long) releaseOutputBuffer(bufferId, timestamp)}.</li>
</ul>
<p>
- Since {@link android.os.Build.VERSION_CODES#MNC}, the default timestamp is the {@linkplain
+ Since {@link android.os.Build.VERSION_CODES#M}, the default timestamp is the {@linkplain
BufferInfo#presentationTimeUs presentation timestamp} of the buffer (converted to nanoseconds).
It was not defined prior to that.
<p>
- Also since {@link android.os.Build.VERSION_CODES#MNC}, you can change the output Surface
+ Also since {@link android.os.Build.VERSION_CODES#M}, you can change the output Surface
dynamically using {@link #setOutputSurface setOutputSurface}.
<h4>Using an Input Surface</h4>
@@ -648,10 +666,10 @@
class. For API version numbers, see {@link android.os.Build.VERSION_CODES}.
<style>
- .api > tr > th, td { text-align: center; padding: 4px 4px; }
+ .api > tr > th, .api > tr > td { text-align: center; padding: 4px 4px; }
.api > tr > th { vertical-align: bottom; }
.api > tr > td { vertical-align: middle; }
- .sml > tr > th, td { text-align: center; padding: 2px 4px; }
+ .sml > tr > th, .sml > tr > td { text-align: center; padding: 2px 4px; }
.fn { text-align: left; }
.fn > code > a { font: 14px/19px Roboto Condensed, sans-serif; }
.deg45 {
@@ -1566,7 +1584,7 @@
private boolean mHasSurface = false;
/**
- * Instantiate a decoder supporting input data of the given mime type.
+ * Instantiate the preferred decoder supporting input data of the given mime type.
*
* The following is a partial list of defined mime types and their semantics:
* <ul>
@@ -1585,6 +1603,10 @@
* <li>"audio/g711-mlaw" - G.711 ulaw audio
* </ul>
*
+ * <strong>Note:</strong> It is preferred to use {@link MediaCodecList#findDecoderForFormat}
+ * and {@link #createByCodecName} to ensure that the resulting codec can handle a
+ * given format.
+ *
* @param type The mime type of the input data.
* @throws IOException if the codec cannot be created.
* @throws IllegalArgumentException if type is not a valid mime type.
@@ -1597,7 +1619,12 @@
}
/**
- * Instantiate an encoder supporting output data of the given mime type.
+ * Instantiate the preferred encoder supporting output data of the given mime type.
+ *
+ * <strong>Note:</strong> It is preferred to use {@link MediaCodecList#findEncoderForFormat}
+ * and {@link #createByCodecName} to ensure that the resulting codec can handle a
+ * given format.
+ *
* @param type The desired mime type of the output data.
* @throws IOException if the codec cannot be created.
* @throws IllegalArgumentException if type is not a valid mime type.
@@ -1666,6 +1693,8 @@
private native final void native_reset();
/**
+ * Free up resources used by the codec instance.
+ *
* Make sure you call this when you're done to free up any opened
* component instance instead of relying on the garbage collector
* to do this for you at some point in the future.
@@ -1886,17 +1915,25 @@
private native final void native_stop();
/**
- * Flush both input and output ports of the component, all indices
- * previously returned in calls to {@link #dequeueInputBuffer} and
- * {@link #dequeueOutputBuffer} become invalid.
+ * Flush both input and output ports of the component.
* <p>
- * If codec is configured in asynchronous mode, call {@link #start}
- * after {@code flush} has returned to resume codec operations. The
- * codec will not request input buffers until this has happened.
+ * Upon return, all indices previously returned in calls to {@link #dequeueInputBuffer
+ * dequeueInputBuffer} and {@link #dequeueOutputBuffer dequeueOutputBuffer} — or obtained
+ * via {@link Callback#onInputBufferAvailable onInputBufferAvailable} or
+ * {@link Callback#onOutputBufferAvailable onOutputBufferAvailable} callbacks — become
+ * invalid, and all buffers are owned by the codec.
* <p>
- * If codec is configured in synchronous mode, codec will resume
- * automatically if an input surface was created. Otherwise, it
- * will resume when {@link #dequeueInputBuffer} is called.
+ * If the codec is configured in asynchronous mode, call {@link #start}
+ * after {@code flush} has returned to resume codec operations. The codec
+ * will not request input buffers until this has happened.
+ * <strong>Note, however, that there may still be outstanding {@code onOutputBufferAvailable}
+ * callbacks that were not handled prior to calling {@code flush}.
+ * The indices returned via these callbacks also become invalid upon calling {@code flush} and
+ * should be discarded.</strong>
+ * <p>
+ * If the codec is configured in synchronous mode, codec will resume
+ * automatically if it is configured with an input surface. Otherwise, it
+ * will resume when {@link #dequeueInputBuffer dequeueInputBuffer} is called.
*
* @throws IllegalStateException if not in the Executing state.
* @throws MediaCodec.CodecException upon codec error.
@@ -2087,6 +2124,15 @@
* To indicate that this is the final piece of input data (or rather that
* no more input data follows unless the decoder is subsequently flushed)
* specify the flag {@link #BUFFER_FLAG_END_OF_STREAM}.
+ * <p class=note>
+ * <strong>Note:</strong> Prior to {@link android.os.Build.VERSION_CODES#M},
+ * {@code presentationTimeUs} was not propagated to the frame timestamp of (rendered)
+ * Surface output buffers, and the resulting frame timestamp was undefined.
+ * Use {@link #releaseOutputBuffer(int, long)} to ensure a specific frame timestamp is set.
+ * Similarly, since frame timestamps can be used by the destination surface for rendering
+ * synchronization, <strong>care must be taken to normalize presentationTimeUs so as to not be
+ * mistaken for a system time. (See {@linkplain #releaseOutputBuffer(int, long)
+ * SurfaceView specifics}).</strong>
*
* @param index The index of a client-owned input buffer previously returned
* in a call to {@link #dequeueInputBuffer}.
@@ -2094,7 +2140,10 @@
* @param size The number of bytes of valid input data.
* @param presentationTimeUs The presentation timestamp in microseconds for this
* buffer. This is normally the media time at which this
- * buffer should be presented (rendered).
+ * buffer should be presented (rendered). When using an output
+ * surface, this will be propagated as the {@link
+ * SurfaceTexture#getTimestamp timestamp} for the frame (after
+ * conversion to nanoseconds).
* @param flags A bitmask of flags
* {@link #BUFFER_FLAG_CODEC_CONFIG} and {@link #BUFFER_FLAG_END_OF_STREAM}.
* While not prohibited, most codecs do not use the
@@ -2207,8 +2256,10 @@
};
/**
- * Similar to {@link #queueInputBuffer} but submits a buffer that is
+ * Similar to {@link #queueInputBuffer queueInputBuffer} but submits a buffer that is
* potentially encrypted.
+ * <strong>Check out further notes at {@link #queueInputBuffer queueInputBuffer}.</strong>
+ *
* @param index The index of a client-owned input buffer previously returned
* in a call to {@link #dequeueInputBuffer}.
* @param offset The byte offset into the input buffer at which the data starts.
@@ -2315,7 +2366,7 @@
/**
* Dequeue an output buffer, block at most "timeoutUs" microseconds.
* Returns the index of an output buffer that has been successfully
- * decoded or one of the INFO_* constants below.
+ * decoded or one of the INFO_* constants.
* @param info Will be filled with buffer meta data.
* @param timeoutUs The timeout in microseconds, a negative timeout indicates "infinite".
* @throws IllegalStateException if not in the Executing state,
@@ -2343,9 +2394,11 @@
@NonNull BufferInfo info, long timeoutUs);
/**
- * If you are done with a buffer, use this call to return the buffer to
- * the codec. If you previously specified a surface when configuring this
- * video decoder you can optionally render the buffer.
+ * If you are done with a buffer, use this call to return the buffer to the codec
+ * or to render it on the output surface. If you configured the codec with an
+ * output surface, setting {@code render} to {@code true} will first send the buffer
+ * to that output surface. The surface will release the buffer back to the codec once
+ * it is no longer used/displayed.
*
* Once an output buffer is released to the codec, it MUST NOT
* be used until it is later retrieved by {@link #getOutputBuffer} in response
@@ -2679,6 +2732,8 @@
* <b>Note:</b> As of API 21, dequeued input buffers are
* automatically {@link java.nio.Buffer#clear cleared}.
*
+ * <em>Do not use this method if using an input surface.</em>
+ *
* @throws IllegalStateException if not in the Executing state,
* or codec is configured in asynchronous mode.
* @throws MediaCodec.CodecException upon codec error.
@@ -2708,6 +2763,8 @@
* buffers that are dequeued will be set to the valid data
* range.
*
+ * <em>Do not use this method if using an output surface.</em>
+ *
* @throws IllegalStateException if not in the Executing state,
* or codec is configured in asynchronous mode.
* @throws MediaCodec.CodecException upon codec error.
@@ -2993,6 +3050,10 @@
/**
* Called when an output frame has rendered on the output surface.
+ * <p>
+ * <strong>Note:</strong> This callback is for informational purposes only: to get precise
+ * render timing samples, and can be significantly delayed and batched. Some frames may have
+ * been rendered even if there was no callback generated.
*
* @param codec the MediaCodec instance
* @param presentationTimeUs the presentation time (media time) of the frame rendered.
@@ -3009,10 +3070,14 @@
}
/**
- * Register a callback to be invoked when an output frame is rendered on the output surface.
+ * Registers a callback to be invoked when an output frame is rendered on the output surface.
* <p>
* This method can be called in any codec state, but will only have an effect in the
* Executing state for codecs that render buffers to the output surface.
+ * <p>
+ * <strong>Note:</strong> This callback is for informational purposes only: to get precise
+ * render timing samples, and can be significantly delayed and batched. Some frames may have
+ * been rendered even if there was no callback generated.
*
* @param listener the callback that will be run
* @param handler the callback will be run on the handler's thread. If {@code null},
diff --git a/media/java/android/media/MediaCodecInfo.java b/media/java/android/media/MediaCodecInfo.java
index 65d0450..4101935 100644
--- a/media/java/android/media/MediaCodecInfo.java
+++ b/media/java/android/media/MediaCodecInfo.java
@@ -525,6 +525,14 @@
/**
* Query whether codec supports a given {@link MediaFormat}.
+ *
+ * <p class=note>
+ * <strong>Note:</strong> On {@link android.os.Build.VERSION_CODES#LOLLIPOP},
+ * {@code format} must not contain a {@linkplain MediaFormat#KEY_FRAME_RATE
+ * frame rate}. Use
+ * <code class=prettyprint>format.setString(MediaFormat.KEY_FRAME_RATE, null)</code>
+ * to clear any existing frame rate setting in the format.
+ *
* @param format media format with optional feature directives.
* @throws IllegalArgumentException if format is not a valid media format.
* @return whether the codec capabilities support the given format
@@ -1198,15 +1206,20 @@
(double) mFrameRateRange.getUpper()));
}
+ private int getBlockCount(int width, int height) {
+ return Utils.divUp(width, mBlockWidth) * Utils.divUp(height, mBlockHeight);
+ }
+
@NonNull
private Size findClosestSize(int width, int height) {
- int targetPixels = width * height;
+ int targetBlockCount = getBlockCount(width, height);
Size closestSize = null;
- int mimPixelsDiff = Integer.MAX_VALUE;
+ int minDiff = Integer.MAX_VALUE;
for (Size size : mMeasuredFrameRates.keySet()) {
- int pixelsDiff = Math.abs(targetPixels - size.getWidth() * size.getHeight());
- if (pixelsDiff < mimPixelsDiff) {
- mimPixelsDiff = pixelsDiff;
+ int diff = Math.abs(targetBlockCount -
+ getBlockCount(size.getWidth(), size.getHeight()));
+ if (diff < minDiff) {
+ minDiff = diff;
closestSize = size;
}
}
@@ -1225,8 +1238,22 @@
* May return {@code null}, if the codec did not publish any measurement
* data.
* <p>
- * This is a performance estimate, based on full-speed decoding
- * and encoding measurements of common video sizes supported by the codec.
+ * This is a performance estimate provided by the device manufacturer
+ * based on full-speed decoding and encoding measurements in various configurations
+ * of common video sizes supported by the codec. As such it should only be used to
+ * compare individual codecs on the device. The value is not suitable for comparing
+ * different devices or even different android releases for the same device.
+ * <p>
+ * The returned range corresponds to the fastest frame rates achieved in the tested
+ * configurations. It is interpolated from the nearest frame size(s) tested. Codec
+ * performance is severely impacted by other activity on the device, and can vary
+ * significantly.
+ * <p class=note>
+ * Use this method in cases where only codec performance matters, e.g. to evaluate if
+ * a codec has any chance of meeting a performance target. Codecs are listed
+ * in {@link MediaCodecList} in the preferred order as defined by the device
+ * manufacturer. As such, applications should use the first suitable codec in the
+ * list to achieve the best balance between power use and performance.
*
* @param width the width of the video
* @param height the height of the video
diff --git a/media/java/android/media/MediaCodecList.java b/media/java/android/media/MediaCodecList.java
index f44e048..cd7b3d3 100644
--- a/media/java/android/media/MediaCodecList.java
+++ b/media/java/android/media/MediaCodecList.java
@@ -190,6 +190,13 @@
* Find a decoder supporting a given {@link MediaFormat} in the list
* of media-codecs.
*
+ * <p class=note>
+ * <strong>Note:</strong> On {@link android.os.Build.VERSION_CODES#LOLLIPOP},
+ * {@code format} must not contain a {@linkplain MediaFormat#KEY_FRAME_RATE
+ * frame rate}. Use
+ * <code class=prettyprint>format.setString(MediaFormat.KEY_FRAME_RATE, null)</code>
+ * to clear any existing frame rate setting in the format.
+ *
* @param format A decoder media format with optional feature directives.
* @throws IllegalArgumentException if format is not a valid media format.
* @throws NullPointerException if format is null.
@@ -204,6 +211,13 @@
* Find an encoder supporting a given {@link MediaFormat} in the list
* of media-codecs.
*
+ * <p class=note>
+ * <strong>Note:</strong> On {@link android.os.Build.VERSION_CODES#LOLLIPOP},
+ * {@code format} must not contain a {@linkplain MediaFormat#KEY_FRAME_RATE
+ * frame rate}. Use
+ * <code class=prettyprint>format.setString(MediaFormat.KEY_FRAME_RATE, null)</code>
+ * to clear any existing frame rate setting in the format.
+ *
* @param format An encoder media format with optional feature directives.
* @throws IllegalArgumentException if format is not a valid media format.
* @throws NullPointerException if format is null.
diff --git a/media/java/android/media/Ringtone.java b/media/java/android/media/Ringtone.java
index 9e9d602..c2bcd93 100644
--- a/media/java/android/media/Ringtone.java
+++ b/media/java/android/media/Ringtone.java
@@ -52,7 +52,8 @@
MediaStore.Audio.Media.TITLE
};
/** Selection that limits query results to just audio files */
- private static final String MEDIA_SELECTION = MediaColumns.MIME_TYPE + " LIKE 'audio/%'";
+ private static final String MEDIA_SELECTION = MediaColumns.MIME_TYPE + " LIKE 'audio/%' OR "
+ + MediaColumns.MIME_TYPE + " IN ('application/ogg', 'application/x-flac')";
// keep references on active Ringtones until stopped or completion listener called.
private static final ArrayList<Ringtone> sActiveRingtones = new ArrayList<Ringtone>();
diff --git a/media/java/android/media/midi/MidiDevice.java b/media/java/android/media/midi/MidiDevice.java
index 93fb6d2..e1990cd 100644
--- a/media/java/android/media/midi/MidiDevice.java
+++ b/media/java/android/media/midi/MidiDevice.java
@@ -113,8 +113,13 @@
/**
* Called to open a {@link MidiInputPort} for the specified port number.
*
+ * An input port can only be used by one sender at a time.
+ * Opening an input port will fail if another application has already opened it for use.
+ * A {@link MidiDeviceStatus} can be used to determine if an input port is already open.
+ *
* @param portNumber the number of the input port to open
- * @return the {@link MidiInputPort}
+ * @return the {@link MidiInputPort} if the open is successful,
+ * or null in case of failure.
*/
public MidiInputPort openInputPort(int portNumber) {
try {
@@ -133,8 +138,11 @@
/**
* Called to open a {@link MidiOutputPort} for the specified port number.
*
+ * An output port may be opened by multiple applications.
+ *
* @param portNumber the number of the output port to open
- * @return the {@link MidiOutputPort}
+ * @return the {@link MidiOutputPort} if the open is successful,
+ * or null in case of failure.
*/
public MidiOutputPort openOutputPort(int portNumber) {
try {
diff --git a/media/java/android/media/midi/MidiManager.java b/media/java/android/media/midi/MidiManager.java
index 89230fe..7197dc0 100644
--- a/media/java/android/media/midi/MidiManager.java
+++ b/media/java/android/media/midi/MidiManager.java
@@ -24,7 +24,7 @@
import android.os.RemoteException;
import android.util.Log;
-import java.util.HashMap;
+import java.util.concurrent.ConcurrentHashMap;
/**
* This class is the public application interface to the MIDI service.
@@ -61,8 +61,8 @@
private final IMidiManager mService;
private final IBinder mToken = new Binder();
- private HashMap<DeviceCallback,DeviceListener> mDeviceListeners =
- new HashMap<DeviceCallback,DeviceListener>();
+ private ConcurrentHashMap<DeviceCallback,DeviceListener> mDeviceListeners =
+ new ConcurrentHashMap<DeviceCallback,DeviceListener>();
// Binder stub for receiving device notifications from MidiService
private class DeviceListener extends IMidiDeviceListener.Stub {
diff --git a/media/java/android/media/midi/package.html b/media/java/android/media/midi/package.html
index 673c4ba9b..7baa5bc 100644
--- a/media/java/android/media/midi/package.html
+++ b/media/java/android/media/midi/package.html
@@ -31,7 +31,7 @@
<li> Timestamps to avoid jitter.</li>
<li> Support creation of <em>virtual MIDI devices</em> that can be connected to other devices.
An example might be a synthesizer app that can be controlled by a composing app.</li>
- <li> Support direction connection or “patching” of devices for lower latency.</li>
+ <li> Support direct connection or “patching” of devices for lower latency.</li>
</ul>
<h2 id=transports_supported>Transports Supported</h2>
@@ -75,6 +75,18 @@
<uses-feature android:name="android.software.midi" android:required="true"/>
</pre>
+<h2 id=check_feature>Check for Feature Support</h2>
+
+<p>An app can also check at run-time whether the MIDI feature is supported on a platform.
+This is particularly useful during development when you install apps directly on a device.
+</p>
+
+<pre class=prettyprint>
+if (context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_MIDI)) {
+ // do MIDI stuff
+}
+</pre>
+
<h2 id=the_midimanager>The MidiManager</h2>
@@ -338,5 +350,54 @@
}
}
</pre>
+
+<h1 id=using_midi_btle>Using MIDI Over Bluetooth LE</h1>
+
+<p>MIDI devices can be connected to Android using Bluetooth LE.</p>
+
+<p>Before using the device, the app must scan for available BTLE devices and then allow
+the user to connect. An example program
+will be provided so look for it on the Android developer website.</p>
+
+<h2 id=btle_location_permissions>Request Location Permission for BTLE</h2>
+
+<p>Applications that scan for Bluetooth devices must request permission in the
+manifest file. This LOCATION permission is required because it may be possible to
+guess the location of an Android device by seeing which BTLE devices are nearby.</p>
+
+<pre class=prettyprint>
+<uses-permission android:name="android.permission.BLUETOOTH"/>
+<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
+<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
+</pre>
+
+<p>Apps must also request location permission from the user at run-time.
+See the documentation for <code>Activity.requestPermissions()</code> for details and an example.
+</p>
+
+<h2 id=btle_scan_devices>Scan for MIDI Devices</h2>
+
+<p>The app will only want to see MIDI devices and not mice or other non-MIDI devices.
+So construct a ScanFilter using the UUID for standard MIDI over BTLE.</p>
+
+<pre class=prettyprint>
+MIDI over BTLE UUID = "03B80E5A-EDE8-4B33-A751-6CE34EC4C700"
+</pre>
+
+<h2 id=btle_open_device>Open a MIDI Bluetooth Device</h2>
+
+<p>See the documentation for <code>android.bluetooth.le.BluetoothLeScanner.startScan()</code>
+method for details. When the user selects a MIDI/BTLE device then you can open it
+using the MidiManager.</p>
+
+<pre class=prettyprint>
+m.openBluetoothDevice(bluetoothDevice, callback, handler);
+</pre>
+
+<p>Once the MIDI/BTLE device has been opened by one app then it will also become available to other
+apps using the
+<a href="#get_list_of_already_plugged_in_entities">MIDI device discovery calls described above</a>.
+</p>
+
</body>
</html>
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/DocumentsUI/res/drawable/item_root_background.xml b/packages/DocumentsUI/res/drawable/item_root_background.xml
index 93c965f..c403159 100644
--- a/packages/DocumentsUI/res/drawable/item_root_background.xml
+++ b/packages/DocumentsUI/res/drawable/item_root_background.xml
@@ -21,5 +21,4 @@
<item android:state_focused="false" android:state_activated="true">
<color android:color="@color/material_grey_300" />
</item>
- <item android:drawable="@android:color/transparent" />
</selector>
diff --git a/packages/DocumentsUI/res/layout/fragment_roots.xml b/packages/DocumentsUI/res/layout/fragment_roots.xml
index 2d624d8..f3de3b4 100644
--- a/packages/DocumentsUI/res/layout/fragment_roots.xml
+++ b/packages/DocumentsUI/res/layout/fragment_roots.xml
@@ -19,4 +19,5 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingTop="8dp"
+ android:drawSelectorOnTop="true"
android:divider="@null" />
diff --git a/packages/DocumentsUI/res/layout/item_root.xml b/packages/DocumentsUI/res/layout/item_root.xml
index bd83923..90b1ff6 100644
--- a/packages/DocumentsUI/res/layout/item_root.xml
+++ b/packages/DocumentsUI/res/layout/item_root.xml
@@ -28,7 +28,8 @@
<FrameLayout
android:layout_width="@dimen/icon_size"
android:layout_height="@dimen/icon_size"
- android:layout_marginEnd="16dp"
+ android:layout_marginStart="@dimen/root_icon_margin"
+ android:layout_marginEnd="@dimen/root_icon_margin"
android:duplicateParentState="true">
<ImageView
diff --git a/packages/DocumentsUI/res/values-af/strings.xml b/packages/DocumentsUI/res/values-af/strings.xml
index 4c31766..6aa41e0 100644
--- a/packages/DocumentsUI/res/values-af/strings.xml
+++ b/packages/DocumentsUI/res/values-af/strings.xml
@@ -17,8 +17,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="2783841764617238354">"Dokumente"</string>
- <!-- no translation found for files_label (6051402950202690279) -->
- <skip />
+ <string name="files_label" msgid="6051402950202690279">"Lêers"</string>
<string name="title_open" msgid="4353228937663917801">"Maak oop vanuit"</string>
<string name="title_save" msgid="2433679664882857999">"Stoor na"</string>
<string name="menu_create_dir" msgid="5947289605844398389">"Skep vouer"</string>
diff --git a/packages/DocumentsUI/res/values-am/strings.xml b/packages/DocumentsUI/res/values-am/strings.xml
index a17b22b..9a2051e 100644
--- a/packages/DocumentsUI/res/values-am/strings.xml
+++ b/packages/DocumentsUI/res/values-am/strings.xml
@@ -17,8 +17,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="2783841764617238354">"ሰነዶች"</string>
- <!-- no translation found for files_label (6051402950202690279) -->
- <skip />
+ <string name="files_label" msgid="6051402950202690279">"ፋይሎች"</string>
<string name="title_open" msgid="4353228937663917801">"ክፈት ከ"</string>
<string name="title_save" msgid="2433679664882857999">"አስቀምጥ ወደ"</string>
<string name="menu_create_dir" msgid="5947289605844398389">"አቃፊ ፍጠር"</string>
diff --git a/packages/DocumentsUI/res/values-ar/strings.xml b/packages/DocumentsUI/res/values-ar/strings.xml
index 230a9b84..18d8f41 100644
--- a/packages/DocumentsUI/res/values-ar/strings.xml
+++ b/packages/DocumentsUI/res/values-ar/strings.xml
@@ -17,8 +17,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="2783841764617238354">"مستندات"</string>
- <!-- no translation found for files_label (6051402950202690279) -->
- <skip />
+ <string name="files_label" msgid="6051402950202690279">"الملفات"</string>
<string name="title_open" msgid="4353228937663917801">"فتح من"</string>
<string name="title_save" msgid="2433679664882857999">"حفظ في"</string>
<string name="menu_create_dir" msgid="5947289605844398389">"إنشاء مجلد"</string>
diff --git a/packages/DocumentsUI/res/values-az-rAZ/strings.xml b/packages/DocumentsUI/res/values-az-rAZ/strings.xml
index 1e31961..8c6c502 100644
--- a/packages/DocumentsUI/res/values-az-rAZ/strings.xml
+++ b/packages/DocumentsUI/res/values-az-rAZ/strings.xml
@@ -17,8 +17,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="2783841764617238354">"Sənədlər"</string>
- <!-- no translation found for files_label (6051402950202690279) -->
- <skip />
+ <string name="files_label" msgid="6051402950202690279">"Fayllar"</string>
<string name="title_open" msgid="4353228937663917801">"Vasitəsilə açın"</string>
<string name="title_save" msgid="2433679664882857999">"buraya saxlayın"</string>
<string name="menu_create_dir" msgid="5947289605844398389">"Qovluq yaradın"</string>
diff --git a/packages/DocumentsUI/res/values-bg/strings.xml b/packages/DocumentsUI/res/values-bg/strings.xml
index 8127f6c..bd14ea5 100644
--- a/packages/DocumentsUI/res/values-bg/strings.xml
+++ b/packages/DocumentsUI/res/values-bg/strings.xml
@@ -17,8 +17,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="2783841764617238354">"Документи"</string>
- <!-- no translation found for files_label (6051402950202690279) -->
- <skip />
+ <string name="files_label" msgid="6051402950202690279">"Файлове"</string>
<string name="title_open" msgid="4353228937663917801">"Отваряне от"</string>
<string name="title_save" msgid="2433679664882857999">"Запазване във:"</string>
<string name="menu_create_dir" msgid="5947289605844398389">"Създаване на папка"</string>
diff --git a/packages/DocumentsUI/res/values-bn-rBD/strings.xml b/packages/DocumentsUI/res/values-bn-rBD/strings.xml
index 97dd5c4..ded6042 100644
--- a/packages/DocumentsUI/res/values-bn-rBD/strings.xml
+++ b/packages/DocumentsUI/res/values-bn-rBD/strings.xml
@@ -17,8 +17,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="2783841764617238354">"দস্তাবেজগুলি"</string>
- <!-- no translation found for files_label (6051402950202690279) -->
- <skip />
+ <string name="files_label" msgid="6051402950202690279">"ফাইলগুলি"</string>
<string name="title_open" msgid="4353228937663917801">"এখান থেকে খুলুন"</string>
<string name="title_save" msgid="2433679664882857999">"এতে সংরক্ষণ করুন"</string>
<string name="menu_create_dir" msgid="5947289605844398389">"ফোল্ডার তৈরি করুন"</string>
diff --git a/packages/DocumentsUI/res/values-ca/strings.xml b/packages/DocumentsUI/res/values-ca/strings.xml
index fb4060b..336e71b 100644
--- a/packages/DocumentsUI/res/values-ca/strings.xml
+++ b/packages/DocumentsUI/res/values-ca/strings.xml
@@ -17,8 +17,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="2783841764617238354">"Documents"</string>
- <!-- no translation found for files_label (6051402950202690279) -->
- <skip />
+ <string name="files_label" msgid="6051402950202690279">"Fitxers"</string>
<string name="title_open" msgid="4353228937663917801">"Obre des de"</string>
<string name="title_save" msgid="2433679664882857999">"Desa a"</string>
<string name="menu_create_dir" msgid="5947289605844398389">"Crea una carpeta"</string>
diff --git a/packages/DocumentsUI/res/values-cs/strings.xml b/packages/DocumentsUI/res/values-cs/strings.xml
index 033bbb0..6f969ba 100644
--- a/packages/DocumentsUI/res/values-cs/strings.xml
+++ b/packages/DocumentsUI/res/values-cs/strings.xml
@@ -17,8 +17,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="2783841764617238354">"Dokumenty"</string>
- <!-- no translation found for files_label (6051402950202690279) -->
- <skip />
+ <string name="files_label" msgid="6051402950202690279">"Soubory"</string>
<string name="title_open" msgid="4353228937663917801">"Otevřít"</string>
<string name="title_save" msgid="2433679664882857999">"Uložit do"</string>
<string name="menu_create_dir" msgid="5947289605844398389">"Vytvořit složku"</string>
diff --git a/packages/DocumentsUI/res/values-da/strings.xml b/packages/DocumentsUI/res/values-da/strings.xml
index 890224c..a2b570e 100644
--- a/packages/DocumentsUI/res/values-da/strings.xml
+++ b/packages/DocumentsUI/res/values-da/strings.xml
@@ -17,8 +17,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="2783841764617238354">"Dokumenter"</string>
- <!-- no translation found for files_label (6051402950202690279) -->
- <skip />
+ <string name="files_label" msgid="6051402950202690279">"Filer"</string>
<string name="title_open" msgid="4353228937663917801">"Åbn fra"</string>
<string name="title_save" msgid="2433679664882857999">"Gem i"</string>
<string name="menu_create_dir" msgid="5947289605844398389">"Opret mappe"</string>
diff --git a/packages/DocumentsUI/res/values-el/strings.xml b/packages/DocumentsUI/res/values-el/strings.xml
index 62b5990..c95a8a5 100644
--- a/packages/DocumentsUI/res/values-el/strings.xml
+++ b/packages/DocumentsUI/res/values-el/strings.xml
@@ -17,8 +17,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="2783841764617238354">"Έγγραφα"</string>
- <!-- no translation found for files_label (6051402950202690279) -->
- <skip />
+ <string name="files_label" msgid="6051402950202690279">"Αρχεία"</string>
<string name="title_open" msgid="4353228937663917801">"Άνοιγμα από"</string>
<string name="title_save" msgid="2433679664882857999">"Αποθήκευση σε"</string>
<string name="menu_create_dir" msgid="5947289605844398389">"Δημιουργία φακέλου"</string>
diff --git a/packages/DocumentsUI/res/values-es-rUS/strings.xml b/packages/DocumentsUI/res/values-es-rUS/strings.xml
index 7ddb9f2..4655d67 100644
--- a/packages/DocumentsUI/res/values-es-rUS/strings.xml
+++ b/packages/DocumentsUI/res/values-es-rUS/strings.xml
@@ -17,8 +17,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="2783841764617238354">"Documentos"</string>
- <!-- no translation found for files_label (6051402950202690279) -->
- <skip />
+ <string name="files_label" msgid="6051402950202690279">"Archivos"</string>
<string name="title_open" msgid="4353228937663917801">"Abrir desde"</string>
<string name="title_save" msgid="2433679664882857999">"Guardar en"</string>
<string name="menu_create_dir" msgid="5947289605844398389">"Crear carpeta"</string>
diff --git a/packages/DocumentsUI/res/values-eu-rES/strings.xml b/packages/DocumentsUI/res/values-eu-rES/strings.xml
index 5bab0b7..5808045 100644
--- a/packages/DocumentsUI/res/values-eu-rES/strings.xml
+++ b/packages/DocumentsUI/res/values-eu-rES/strings.xml
@@ -17,8 +17,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="2783841764617238354">"Dokumentuak"</string>
- <!-- no translation found for files_label (6051402950202690279) -->
- <skip />
+ <string name="files_label" msgid="6051402950202690279">"Fitxategiak"</string>
<string name="title_open" msgid="4353228937663917801">"Ireki hemendik"</string>
<string name="title_save" msgid="2433679664882857999">"Gorde hemen"</string>
<string name="menu_create_dir" msgid="5947289605844398389">"Sortu karpeta"</string>
diff --git a/packages/DocumentsUI/res/values-fa/strings.xml b/packages/DocumentsUI/res/values-fa/strings.xml
index 0df4da3..23c75f5 100644
--- a/packages/DocumentsUI/res/values-fa/strings.xml
+++ b/packages/DocumentsUI/res/values-fa/strings.xml
@@ -17,14 +17,13 @@
<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">"اسناد"</string>
- <!-- no translation found for files_label (6051402950202690279) -->
- <skip />
+ <string name="files_label" msgid="6051402950202690279">"فایلها"</string>
<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_list" msgid="7279285939892417279">"نمای فهرستوار"</string>
- <string name="menu_sort" msgid="7677740407158414452">"مرتبسازی بر اساس"</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>
@@ -45,9 +44,9 @@
<string name="button_select" msgid="527196987259139214">"انتخاب"</string>
<string name="button_copy" msgid="8706475544635021302">"کپی"</string>
<string name="button_move" msgid="2202666023104202232">"انتقال"</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-fi/strings.xml b/packages/DocumentsUI/res/values-fi/strings.xml
index 1fce764..df21358a 100644
--- a/packages/DocumentsUI/res/values-fi/strings.xml
+++ b/packages/DocumentsUI/res/values-fi/strings.xml
@@ -17,8 +17,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="2783841764617238354">"Asiakirjat"</string>
- <!-- no translation found for files_label (6051402950202690279) -->
- <skip />
+ <string name="files_label" msgid="6051402950202690279">"Tiedostot"</string>
<string name="title_open" msgid="4353228937663917801">"Avaa sijainnista"</string>
<string name="title_save" msgid="2433679664882857999">"Tallenna kohteeseen"</string>
<string name="menu_create_dir" msgid="5947289605844398389">"Luo kansio"</string>
diff --git a/packages/DocumentsUI/res/values-fr-rCA/strings.xml b/packages/DocumentsUI/res/values-fr-rCA/strings.xml
index 146e245..f86175a 100644
--- a/packages/DocumentsUI/res/values-fr-rCA/strings.xml
+++ b/packages/DocumentsUI/res/values-fr-rCA/strings.xml
@@ -17,8 +17,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="2783841764617238354">"Documents"</string>
- <!-- no translation found for files_label (6051402950202690279) -->
- <skip />
+ <string name="files_label" msgid="6051402950202690279">"Fichiers"</string>
<string name="title_open" msgid="4353228937663917801">"Ouvrir à partir de"</string>
<string name="title_save" msgid="2433679664882857999">"Enregistrer dans"</string>
<string name="menu_create_dir" msgid="5947289605844398389">"Créer un dossier"</string>
diff --git a/packages/DocumentsUI/res/values-fr/strings.xml b/packages/DocumentsUI/res/values-fr/strings.xml
index a96610c..de4a6fc 100644
--- a/packages/DocumentsUI/res/values-fr/strings.xml
+++ b/packages/DocumentsUI/res/values-fr/strings.xml
@@ -17,8 +17,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="2783841764617238354">"Docs"</string>
- <!-- no translation found for files_label (6051402950202690279) -->
- <skip />
+ <string name="files_label" msgid="6051402950202690279">"Fichiers"</string>
<string name="title_open" msgid="4353228937663917801">"Ouvrir à partir de"</string>
<string name="title_save" msgid="2433679664882857999">"Enregistrer sous"</string>
<string name="menu_create_dir" msgid="5947289605844398389">"Créer un dossier"</string>
diff --git a/packages/DocumentsUI/res/values-gl-rES/strings.xml b/packages/DocumentsUI/res/values-gl-rES/strings.xml
index fbd9dcf..c5f46f9 100644
--- a/packages/DocumentsUI/res/values-gl-rES/strings.xml
+++ b/packages/DocumentsUI/res/values-gl-rES/strings.xml
@@ -17,8 +17,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="2783841764617238354">"Documentos"</string>
- <!-- no translation found for files_label (6051402950202690279) -->
- <skip />
+ <string name="files_label" msgid="6051402950202690279">"Ficheiros"</string>
<string name="title_open" msgid="4353228937663917801">"Abrir desde"</string>
<string name="title_save" msgid="2433679664882857999">"Gardar en"</string>
<string name="menu_create_dir" msgid="5947289605844398389">"Crear cartafol"</string>
diff --git a/packages/DocumentsUI/res/values-gu-rIN/strings.xml b/packages/DocumentsUI/res/values-gu-rIN/strings.xml
index ccc41b6..9c48562 100644
--- a/packages/DocumentsUI/res/values-gu-rIN/strings.xml
+++ b/packages/DocumentsUI/res/values-gu-rIN/strings.xml
@@ -17,8 +17,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="2783841764617238354">"દસ્તાવેજો"</string>
- <!-- no translation found for files_label (6051402950202690279) -->
- <skip />
+ <string name="files_label" msgid="6051402950202690279">"ફાઇલો"</string>
<string name="title_open" msgid="4353228937663917801">"અહીંથી ખોલો"</string>
<string name="title_save" msgid="2433679664882857999">"આમાં સાચવો"</string>
<string name="menu_create_dir" msgid="5947289605844398389">"ફોલ્ડર બનાવો"</string>
diff --git a/packages/DocumentsUI/res/values-hr/strings.xml b/packages/DocumentsUI/res/values-hr/strings.xml
index eb2f855..90c050b 100644
--- a/packages/DocumentsUI/res/values-hr/strings.xml
+++ b/packages/DocumentsUI/res/values-hr/strings.xml
@@ -17,8 +17,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="2783841764617238354">"Dokumenti"</string>
- <!-- no translation found for files_label (6051402950202690279) -->
- <skip />
+ <string name="files_label" msgid="6051402950202690279">"Datoteke"</string>
<string name="title_open" msgid="4353228937663917801">"Otvori iz"</string>
<string name="title_save" msgid="2433679664882857999">"Spremi u"</string>
<string name="menu_create_dir" msgid="5947289605844398389">"Izradi mapu"</string>
diff --git a/packages/DocumentsUI/res/values-hu/strings.xml b/packages/DocumentsUI/res/values-hu/strings.xml
index 865d55e..0b9d562 100644
--- a/packages/DocumentsUI/res/values-hu/strings.xml
+++ b/packages/DocumentsUI/res/values-hu/strings.xml
@@ -17,8 +17,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="2783841764617238354">"Dokumentumok"</string>
- <!-- no translation found for files_label (6051402950202690279) -->
- <skip />
+ <string name="files_label" msgid="6051402950202690279">"Fájlok"</string>
<string name="title_open" msgid="4353228937663917801">"Megnyitás innen"</string>
<string name="title_save" msgid="2433679664882857999">"Mentés ide"</string>
<string name="menu_create_dir" msgid="5947289605844398389">"Mappa létrehozása"</string>
diff --git a/packages/DocumentsUI/res/values-hy-rAM/strings.xml b/packages/DocumentsUI/res/values-hy-rAM/strings.xml
index 62c627b8..6b0816d 100644
--- a/packages/DocumentsUI/res/values-hy-rAM/strings.xml
+++ b/packages/DocumentsUI/res/values-hy-rAM/strings.xml
@@ -17,12 +17,11 @@
<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">"Փաստաթղթեր"</string>
- <!-- no translation found for files_label (6051402950202690279) -->
- <skip />
+ <string name="files_label" msgid="6051402950202690279">"Ֆայլեր"</string>
<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-is-rIS/strings.xml b/packages/DocumentsUI/res/values-is-rIS/strings.xml
index d7fae4e..668d2f9 100644
--- a/packages/DocumentsUI/res/values-is-rIS/strings.xml
+++ b/packages/DocumentsUI/res/values-is-rIS/strings.xml
@@ -17,8 +17,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="2783841764617238354">"Skjöl"</string>
- <!-- no translation found for files_label (6051402950202690279) -->
- <skip />
+ <string name="files_label" msgid="6051402950202690279">"Skrár"</string>
<string name="title_open" msgid="4353228937663917801">"Opna frá"</string>
<string name="title_save" msgid="2433679664882857999">"Vista í"</string>
<string name="menu_create_dir" msgid="5947289605844398389">"Búa til möppu"</string>
diff --git a/packages/DocumentsUI/res/values-iw/strings.xml b/packages/DocumentsUI/res/values-iw/strings.xml
index 38c2501..032c545 100644
--- a/packages/DocumentsUI/res/values-iw/strings.xml
+++ b/packages/DocumentsUI/res/values-iw/strings.xml
@@ -17,8 +17,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="2783841764617238354">"מסמכים"</string>
- <!-- no translation found for files_label (6051402950202690279) -->
- <skip />
+ <string name="files_label" msgid="6051402950202690279">"קבצים"</string>
<string name="title_open" msgid="4353228937663917801">"פתח מ-"</string>
<string name="title_save" msgid="2433679664882857999">"שמור ב-"</string>
<string name="menu_create_dir" msgid="5947289605844398389">"צור תיקיה"</string>
diff --git a/packages/DocumentsUI/res/values-ka-rGE/strings.xml b/packages/DocumentsUI/res/values-ka-rGE/strings.xml
index 8fb812d..676476f 100644
--- a/packages/DocumentsUI/res/values-ka-rGE/strings.xml
+++ b/packages/DocumentsUI/res/values-ka-rGE/strings.xml
@@ -17,8 +17,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="2783841764617238354">"დოკუმენტები"</string>
- <!-- no translation found for files_label (6051402950202690279) -->
- <skip />
+ <string name="files_label" msgid="6051402950202690279">"ფაილები"</string>
<string name="title_open" msgid="4353228937663917801">"გახსნა აქედან:"</string>
<string name="title_save" msgid="2433679664882857999">"შენახვა აქ:"</string>
<string name="menu_create_dir" msgid="5947289605844398389">"საქაღალდის შექმნა"</string>
diff --git a/packages/DocumentsUI/res/values-kk-rKZ/strings.xml b/packages/DocumentsUI/res/values-kk-rKZ/strings.xml
index 7651735..7655a2d 100644
--- a/packages/DocumentsUI/res/values-kk-rKZ/strings.xml
+++ b/packages/DocumentsUI/res/values-kk-rKZ/strings.xml
@@ -17,8 +17,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="2783841764617238354">"Құжаттар"</string>
- <!-- no translation found for files_label (6051402950202690279) -->
- <skip />
+ <string name="files_label" msgid="6051402950202690279">"Файлдар"</string>
<string name="title_open" msgid="4353228937663917801">"Мынадан ашу:"</string>
<string name="title_save" msgid="2433679664882857999">"Сақталатын орны"</string>
<string name="menu_create_dir" msgid="5947289605844398389">"Қалта жасақтау"</string>
diff --git a/packages/DocumentsUI/res/values-kn-rIN/strings.xml b/packages/DocumentsUI/res/values-kn-rIN/strings.xml
index f4f13d2..121197e 100644
--- a/packages/DocumentsUI/res/values-kn-rIN/strings.xml
+++ b/packages/DocumentsUI/res/values-kn-rIN/strings.xml
@@ -17,8 +17,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="2783841764617238354">"ಡಾಕ್ಯುಮೆಂಟ್ಗಳು"</string>
- <!-- no translation found for files_label (6051402950202690279) -->
- <skip />
+ <string name="files_label" msgid="6051402950202690279">"ಫೈಲ್ಗಳು"</string>
<string name="title_open" msgid="4353228937663917801">"ಇದರ ಮೂಲಕ ತೆರೆಯಿರಿ"</string>
<string name="title_save" msgid="2433679664882857999">"ಇವುಗಳಲ್ಲಿ ಉಳಿಸಿ"</string>
<string name="menu_create_dir" msgid="5947289605844398389">"ಫೋಲ್ಡರ್ ರಚಿಸು"</string>
diff --git a/packages/DocumentsUI/res/values-ky-rKG/strings.xml b/packages/DocumentsUI/res/values-ky-rKG/strings.xml
index 7eb10d4..1b8b60e 100644
--- a/packages/DocumentsUI/res/values-ky-rKG/strings.xml
+++ b/packages/DocumentsUI/res/values-ky-rKG/strings.xml
@@ -17,8 +17,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="2783841764617238354">"Документтер"</string>
- <!-- no translation found for files_label (6051402950202690279) -->
- <skip />
+ <string name="files_label" msgid="6051402950202690279">"Файлдар"</string>
<string name="title_open" msgid="4353228937663917801">"Кийинкиден ачуу:"</string>
<string name="title_save" msgid="2433679664882857999">"Кийинкиге сактоо:"</string>
<string name="menu_create_dir" msgid="5947289605844398389">"Папка түзүү"</string>
diff --git a/packages/DocumentsUI/res/values-lt/strings.xml b/packages/DocumentsUI/res/values-lt/strings.xml
index 938aaee..df1b98a 100644
--- a/packages/DocumentsUI/res/values-lt/strings.xml
+++ b/packages/DocumentsUI/res/values-lt/strings.xml
@@ -17,8 +17,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="2783841764617238354">"Dokumentai"</string>
- <!-- no translation found for files_label (6051402950202690279) -->
- <skip />
+ <string name="files_label" msgid="6051402950202690279">"Failai"</string>
<string name="title_open" msgid="4353228937663917801">"Atidaryti iš"</string>
<string name="title_save" msgid="2433679664882857999">"Išsaugoti į"</string>
<string name="menu_create_dir" msgid="5947289605844398389">"Kurti aplanką"</string>
diff --git a/packages/DocumentsUI/res/values-lv/strings.xml b/packages/DocumentsUI/res/values-lv/strings.xml
index 54917f7..baf306e 100644
--- a/packages/DocumentsUI/res/values-lv/strings.xml
+++ b/packages/DocumentsUI/res/values-lv/strings.xml
@@ -17,8 +17,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="2783841764617238354">"Dokumenti"</string>
- <!-- no translation found for files_label (6051402950202690279) -->
- <skip />
+ <string name="files_label" msgid="6051402950202690279">"Faili"</string>
<string name="title_open" msgid="4353228937663917801">"Atvēršana no:"</string>
<string name="title_save" msgid="2433679664882857999">"Saglabāšana:"</string>
<string name="menu_create_dir" msgid="5947289605844398389">"Izveidot mapi"</string>
diff --git a/packages/DocumentsUI/res/values-mk-rMK/strings.xml b/packages/DocumentsUI/res/values-mk-rMK/strings.xml
index 39b9a68..93d9bea 100644
--- a/packages/DocumentsUI/res/values-mk-rMK/strings.xml
+++ b/packages/DocumentsUI/res/values-mk-rMK/strings.xml
@@ -17,8 +17,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="2783841764617238354">"Документи"</string>
- <!-- no translation found for files_label (6051402950202690279) -->
- <skip />
+ <string name="files_label" msgid="6051402950202690279">"Датотеки"</string>
<string name="title_open" msgid="4353228937663917801">"Отвори од"</string>
<string name="title_save" msgid="2433679664882857999">"Зачувај во"</string>
<string name="menu_create_dir" msgid="5947289605844398389">"Создади папка"</string>
diff --git a/packages/DocumentsUI/res/values-ml-rIN/strings.xml b/packages/DocumentsUI/res/values-ml-rIN/strings.xml
index 7f165da..162991a 100644
--- a/packages/DocumentsUI/res/values-ml-rIN/strings.xml
+++ b/packages/DocumentsUI/res/values-ml-rIN/strings.xml
@@ -17,8 +17,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="2783841764617238354">"പ്രമാണങ്ങൾ"</string>
- <!-- no translation found for files_label (6051402950202690279) -->
- <skip />
+ <string name="files_label" msgid="6051402950202690279">"ഫയലുകൾ"</string>
<string name="title_open" msgid="4353228937663917801">"ഇതിൽ നിന്നും തുറക്കുക"</string>
<string name="title_save" msgid="2433679664882857999">"ഇതില് സംരക്ഷിക്കുക"</string>
<string name="menu_create_dir" msgid="5947289605844398389">"ഫോൾഡർ സൃഷ്ടിക്കുക"</string>
diff --git a/packages/DocumentsUI/res/values-mr-rIN/strings.xml b/packages/DocumentsUI/res/values-mr-rIN/strings.xml
index 7906fbd..441035d 100644
--- a/packages/DocumentsUI/res/values-mr-rIN/strings.xml
+++ b/packages/DocumentsUI/res/values-mr-rIN/strings.xml
@@ -17,8 +17,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="2783841764617238354">"दस्तऐवज"</string>
- <!-- no translation found for files_label (6051402950202690279) -->
- <skip />
+ <string name="files_label" msgid="6051402950202690279">"फायली"</string>
<string name="title_open" msgid="4353228937663917801">"वरून उघडा"</string>
<string name="title_save" msgid="2433679664882857999">"येथे जतन करा"</string>
<string name="menu_create_dir" msgid="5947289605844398389">"फोल्डर तयार करा"</string>
diff --git a/packages/DocumentsUI/res/values-ms-rMY/strings.xml b/packages/DocumentsUI/res/values-ms-rMY/strings.xml
index be12361..89a738c 100644
--- a/packages/DocumentsUI/res/values-ms-rMY/strings.xml
+++ b/packages/DocumentsUI/res/values-ms-rMY/strings.xml
@@ -17,8 +17,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="2783841764617238354">"Dokumen"</string>
- <!-- no translation found for files_label (6051402950202690279) -->
- <skip />
+ <string name="files_label" msgid="6051402950202690279">"Fail"</string>
<string name="title_open" msgid="4353228937663917801">"Buka dari"</string>
<string name="title_save" msgid="2433679664882857999">"Simpan ke"</string>
<string name="menu_create_dir" msgid="5947289605844398389">"Buat folder"</string>
diff --git a/packages/DocumentsUI/res/values-my-rMM/strings.xml b/packages/DocumentsUI/res/values-my-rMM/strings.xml
index 8efbfa0c..a7d740a 100644
--- a/packages/DocumentsUI/res/values-my-rMM/strings.xml
+++ b/packages/DocumentsUI/res/values-my-rMM/strings.xml
@@ -17,8 +17,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="2783841764617238354">"စာရွက်စာတန်းများ"</string>
- <!-- no translation found for files_label (6051402950202690279) -->
- <skip />
+ <string name="files_label" msgid="6051402950202690279">"ဖိုင်များ"</string>
<string name="title_open" msgid="4353228937663917801">"မှ ဖွင့်ပါ"</string>
<string name="title_save" msgid="2433679664882857999">"သို့ သိမ်းပါ"</string>
<string name="menu_create_dir" msgid="5947289605844398389">"အကန့် တည်ဆောက်ရန်"</string>
diff --git a/packages/DocumentsUI/res/values-nb/strings.xml b/packages/DocumentsUI/res/values-nb/strings.xml
index 622345f..09b75c0 100644
--- a/packages/DocumentsUI/res/values-nb/strings.xml
+++ b/packages/DocumentsUI/res/values-nb/strings.xml
@@ -17,8 +17,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="2783841764617238354">"Dokumenter"</string>
- <!-- no translation found for files_label (6051402950202690279) -->
- <skip />
+ <string name="files_label" msgid="6051402950202690279">"Filer"</string>
<string name="title_open" msgid="4353228937663917801">"Åpne fra"</string>
<string name="title_save" msgid="2433679664882857999">"Lagre i"</string>
<string name="menu_create_dir" msgid="5947289605844398389">"Opprett en mappe"</string>
diff --git a/packages/DocumentsUI/res/values-nl/strings.xml b/packages/DocumentsUI/res/values-nl/strings.xml
index 3f90014..75c35cb 100644
--- a/packages/DocumentsUI/res/values-nl/strings.xml
+++ b/packages/DocumentsUI/res/values-nl/strings.xml
@@ -17,8 +17,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="2783841764617238354">"Documenten"</string>
- <!-- no translation found for files_label (6051402950202690279) -->
- <skip />
+ <string name="files_label" msgid="6051402950202690279">"Bestanden"</string>
<string name="title_open" msgid="4353228937663917801">"Openen vanuit"</string>
<string name="title_save" msgid="2433679664882857999">"Opslaan in"</string>
<string name="menu_create_dir" msgid="5947289605844398389">"Map maken"</string>
diff --git a/packages/DocumentsUI/res/values-pa-rIN/strings.xml b/packages/DocumentsUI/res/values-pa-rIN/strings.xml
index 47c8042..18d9bc3 100644
--- a/packages/DocumentsUI/res/values-pa-rIN/strings.xml
+++ b/packages/DocumentsUI/res/values-pa-rIN/strings.xml
@@ -17,8 +17,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="2783841764617238354">"ਦਸਤਾਵੇਜ਼"</string>
- <!-- no translation found for files_label (6051402950202690279) -->
- <skip />
+ <string name="files_label" msgid="6051402950202690279">"ਫਾਈਲਾਂ"</string>
<string name="title_open" msgid="4353228937663917801">"ਤੋਂ ਖੋਲ੍ਹੋ"</string>
<string name="title_save" msgid="2433679664882857999">"ਇਸ ਵਿੱਚ ਸੁਰੱਖਿਅਤ ਕਰੋ"</string>
<string name="menu_create_dir" msgid="5947289605844398389">"ਫੋਲਡਰ ਬਣਾਓ"</string>
diff --git a/packages/DocumentsUI/res/values-pl/strings.xml b/packages/DocumentsUI/res/values-pl/strings.xml
index 8429399..0d38933 100644
--- a/packages/DocumentsUI/res/values-pl/strings.xml
+++ b/packages/DocumentsUI/res/values-pl/strings.xml
@@ -17,8 +17,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="2783841764617238354">"Dokumenty"</string>
- <!-- no translation found for files_label (6051402950202690279) -->
- <skip />
+ <string name="files_label" msgid="6051402950202690279">"Pliki"</string>
<string name="title_open" msgid="4353228937663917801">"Otwórz z"</string>
<string name="title_save" msgid="2433679664882857999">"Zapisz w"</string>
<string name="menu_create_dir" msgid="5947289605844398389">"Utwórz folder"</string>
diff --git a/packages/DocumentsUI/res/values-pt-rBR/strings.xml b/packages/DocumentsUI/res/values-pt-rBR/strings.xml
index 2c1ec0c..a23ecd0 100644
--- a/packages/DocumentsUI/res/values-pt-rBR/strings.xml
+++ b/packages/DocumentsUI/res/values-pt-rBR/strings.xml
@@ -17,8 +17,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="2783841764617238354">"Documentos"</string>
- <!-- no translation found for files_label (6051402950202690279) -->
- <skip />
+ <string name="files_label" msgid="6051402950202690279">"Arquivos"</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>
diff --git a/packages/DocumentsUI/res/values-pt-rPT/strings.xml b/packages/DocumentsUI/res/values-pt-rPT/strings.xml
index 40d82a7..3b8ec6a 100644
--- a/packages/DocumentsUI/res/values-pt-rPT/strings.xml
+++ b/packages/DocumentsUI/res/values-pt-rPT/strings.xml
@@ -17,8 +17,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="2783841764617238354">"Documentos"</string>
- <!-- no translation found for files_label (6051402950202690279) -->
- <skip />
+ <string name="files_label" msgid="6051402950202690279">"Ficheiros"</string>
<string name="title_open" msgid="4353228937663917801">"Abrir de"</string>
<string name="title_save" msgid="2433679664882857999">"Guardar em"</string>
<string name="menu_create_dir" msgid="5947289605844398389">"Criar pasta"</string>
diff --git a/packages/DocumentsUI/res/values-pt/strings.xml b/packages/DocumentsUI/res/values-pt/strings.xml
index 2c1ec0c..a23ecd0 100644
--- a/packages/DocumentsUI/res/values-pt/strings.xml
+++ b/packages/DocumentsUI/res/values-pt/strings.xml
@@ -17,8 +17,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="2783841764617238354">"Documentos"</string>
- <!-- no translation found for files_label (6051402950202690279) -->
- <skip />
+ <string name="files_label" msgid="6051402950202690279">"Arquivos"</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>
diff --git a/packages/DocumentsUI/res/values-ro/strings.xml b/packages/DocumentsUI/res/values-ro/strings.xml
index 67d2e43..692fd5a 100644
--- a/packages/DocumentsUI/res/values-ro/strings.xml
+++ b/packages/DocumentsUI/res/values-ro/strings.xml
@@ -17,8 +17,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="2783841764617238354">"Documente"</string>
- <!-- no translation found for files_label (6051402950202690279) -->
- <skip />
+ <string name="files_label" msgid="6051402950202690279">"Fișiere"</string>
<string name="title_open" msgid="4353228937663917801">"Deschideți din"</string>
<string name="title_save" msgid="2433679664882857999">"Salvați în"</string>
<string name="menu_create_dir" msgid="5947289605844398389">"Creați un dosar"</string>
diff --git a/packages/DocumentsUI/res/values-ru/strings.xml b/packages/DocumentsUI/res/values-ru/strings.xml
index 35ca741..2e5840d 100644
--- a/packages/DocumentsUI/res/values-ru/strings.xml
+++ b/packages/DocumentsUI/res/values-ru/strings.xml
@@ -17,8 +17,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="2783841764617238354">"Документы"</string>
- <!-- no translation found for files_label (6051402950202690279) -->
- <skip />
+ <string name="files_label" msgid="6051402950202690279">"Файлы"</string>
<string name="title_open" msgid="4353228937663917801">"Открыть"</string>
<string name="title_save" msgid="2433679664882857999">"Сохранить"</string>
<string name="menu_create_dir" msgid="5947289605844398389">"Новая папка"</string>
diff --git a/packages/DocumentsUI/res/values-si-rLK/strings.xml b/packages/DocumentsUI/res/values-si-rLK/strings.xml
index 7eec222..2bd7585 100644
--- a/packages/DocumentsUI/res/values-si-rLK/strings.xml
+++ b/packages/DocumentsUI/res/values-si-rLK/strings.xml
@@ -17,8 +17,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="2783841764617238354">"ලේඛන"</string>
- <!-- no translation found for files_label (6051402950202690279) -->
- <skip />
+ <string name="files_label" msgid="6051402950202690279">"ගොනු"</string>
<string name="title_open" msgid="4353228937663917801">"විවෘත වන්නේ"</string>
<string name="title_save" msgid="2433679664882857999">"සුරකින්නේ"</string>
<string name="menu_create_dir" msgid="5947289605844398389">"ෆෝල්ඩරයක් සාදන්න"</string>
diff --git a/packages/DocumentsUI/res/values-sk/strings.xml b/packages/DocumentsUI/res/values-sk/strings.xml
index 4c1f18f..e14362d 100644
--- a/packages/DocumentsUI/res/values-sk/strings.xml
+++ b/packages/DocumentsUI/res/values-sk/strings.xml
@@ -17,8 +17,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="2783841764617238354">"Dokumenty"</string>
- <!-- no translation found for files_label (6051402950202690279) -->
- <skip />
+ <string name="files_label" msgid="6051402950202690279">"Súbory"</string>
<string name="title_open" msgid="4353228937663917801">"Otvoriť z"</string>
<string name="title_save" msgid="2433679664882857999">"Uložiť do"</string>
<string name="menu_create_dir" msgid="5947289605844398389">"Vytvoriť priečinok"</string>
diff --git a/packages/DocumentsUI/res/values-sl/strings.xml b/packages/DocumentsUI/res/values-sl/strings.xml
index 235bb35..a0b3737 100644
--- a/packages/DocumentsUI/res/values-sl/strings.xml
+++ b/packages/DocumentsUI/res/values-sl/strings.xml
@@ -17,8 +17,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="2783841764617238354">"Dokumenti"</string>
- <!-- no translation found for files_label (6051402950202690279) -->
- <skip />
+ <string name="files_label" msgid="6051402950202690279">"Datoteke"</string>
<string name="title_open" msgid="4353228937663917801">"Odpri iz mape"</string>
<string name="title_save" msgid="2433679664882857999">"Shrani v"</string>
<string name="menu_create_dir" msgid="5947289605844398389">"Ustvarjanje mape"</string>
diff --git a/packages/DocumentsUI/res/values-sq-rAL/strings.xml b/packages/DocumentsUI/res/values-sq-rAL/strings.xml
index 8d63f6d..796c2ea 100644
--- a/packages/DocumentsUI/res/values-sq-rAL/strings.xml
+++ b/packages/DocumentsUI/res/values-sq-rAL/strings.xml
@@ -17,8 +17,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="2783841764617238354">"Dokumente"</string>
- <!-- no translation found for files_label (6051402950202690279) -->
- <skip />
+ <string name="files_label" msgid="6051402950202690279">"Skedarët"</string>
<string name="title_open" msgid="4353228937663917801">"Hap nga"</string>
<string name="title_save" msgid="2433679664882857999">"Ruaje te"</string>
<string name="menu_create_dir" msgid="5947289605844398389">"Krijo dosje"</string>
diff --git a/packages/DocumentsUI/res/values-sr/strings.xml b/packages/DocumentsUI/res/values-sr/strings.xml
index 23297e9..ee8d495 100644
--- a/packages/DocumentsUI/res/values-sr/strings.xml
+++ b/packages/DocumentsUI/res/values-sr/strings.xml
@@ -17,8 +17,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="2783841764617238354">"Документи"</string>
- <!-- no translation found for files_label (6051402950202690279) -->
- <skip />
+ <string name="files_label" msgid="6051402950202690279">"Датотеке"</string>
<string name="title_open" msgid="4353228937663917801">"Отвори са"</string>
<string name="title_save" msgid="2433679664882857999">"Сачувај у"</string>
<string name="menu_create_dir" msgid="5947289605844398389">"Направи директоријум"</string>
diff --git a/packages/DocumentsUI/res/values-sv/strings.xml b/packages/DocumentsUI/res/values-sv/strings.xml
index f3d2eaf..d0a4bbc 100644
--- a/packages/DocumentsUI/res/values-sv/strings.xml
+++ b/packages/DocumentsUI/res/values-sv/strings.xml
@@ -17,8 +17,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="2783841764617238354">"Dokument"</string>
- <!-- no translation found for files_label (6051402950202690279) -->
- <skip />
+ <string name="files_label" msgid="6051402950202690279">"Filer"</string>
<string name="title_open" msgid="4353228937663917801">"Öppna från"</string>
<string name="title_save" msgid="2433679664882857999">"Spara till"</string>
<string name="menu_create_dir" msgid="5947289605844398389">"Skapa mapp"</string>
diff --git a/packages/DocumentsUI/res/values-sw/strings.xml b/packages/DocumentsUI/res/values-sw/strings.xml
index 05f5c9d..ae9503f 100644
--- a/packages/DocumentsUI/res/values-sw/strings.xml
+++ b/packages/DocumentsUI/res/values-sw/strings.xml
@@ -17,8 +17,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="2783841764617238354">"Hati"</string>
- <!-- no translation found for files_label (6051402950202690279) -->
- <skip />
+ <string name="files_label" msgid="6051402950202690279">"Faili"</string>
<string name="title_open" msgid="4353228937663917801">"Fungua kutoka"</string>
<string name="title_save" msgid="2433679664882857999">"Hifadhi kwenye"</string>
<string name="menu_create_dir" msgid="5947289605844398389">"Unda folda"</string>
diff --git a/packages/DocumentsUI/res/values-sw600dp/dimens.xml b/packages/DocumentsUI/res/values-sw600dp/dimens.xml
new file mode 100644
index 0000000..642ff7e
--- /dev/null
+++ b/packages/DocumentsUI/res/values-sw600dp/dimens.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.
+-->
+
+<resources>
+ <dimen name="root_icon_margin">8dp</dimen>
+</resources>
diff --git a/packages/DocumentsUI/res/values-ta-rIN/strings.xml b/packages/DocumentsUI/res/values-ta-rIN/strings.xml
index 828fdd3..30289d0 100644
--- a/packages/DocumentsUI/res/values-ta-rIN/strings.xml
+++ b/packages/DocumentsUI/res/values-ta-rIN/strings.xml
@@ -17,8 +17,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="2783841764617238354">"ஆவணங்கள்"</string>
- <!-- no translation found for files_label (6051402950202690279) -->
- <skip />
+ <string name="files_label" msgid="6051402950202690279">"கோப்புகள்"</string>
<string name="title_open" msgid="4353228937663917801">"இதில் திற"</string>
<string name="title_save" msgid="2433679664882857999">"இதில் சேமி"</string>
<string name="menu_create_dir" msgid="5947289605844398389">"கோப்புறையை உருவாக்கு"</string>
diff --git a/packages/DocumentsUI/res/values-te-rIN/strings.xml b/packages/DocumentsUI/res/values-te-rIN/strings.xml
index 1ce32d8..46a4114 100644
--- a/packages/DocumentsUI/res/values-te-rIN/strings.xml
+++ b/packages/DocumentsUI/res/values-te-rIN/strings.xml
@@ -17,8 +17,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="2783841764617238354">"పత్రాలు"</string>
- <!-- no translation found for files_label (6051402950202690279) -->
- <skip />
+ <string name="files_label" msgid="6051402950202690279">"ఫైల్లు"</string>
<string name="title_open" msgid="4353228937663917801">"ఇక్కడి నుండి తెరువు"</string>
<string name="title_save" msgid="2433679664882857999">"ఇందులో సేవ్ చేయి"</string>
<string name="menu_create_dir" msgid="5947289605844398389">"ఫోల్డర్ను సృష్టించు"</string>
diff --git a/packages/DocumentsUI/res/values-tr/strings.xml b/packages/DocumentsUI/res/values-tr/strings.xml
index 41706c2..15f70b6 100644
--- a/packages/DocumentsUI/res/values-tr/strings.xml
+++ b/packages/DocumentsUI/res/values-tr/strings.xml
@@ -17,8 +17,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="2783841764617238354">"Dokümanlar"</string>
- <!-- no translation found for files_label (6051402950202690279) -->
- <skip />
+ <string name="files_label" msgid="6051402950202690279">"Dosyalar"</string>
<string name="title_open" msgid="4353228937663917801">"Şuradan aç:"</string>
<string name="title_save" msgid="2433679664882857999">"Şuraya kaydet:"</string>
<string name="menu_create_dir" msgid="5947289605844398389">"Klasör oluştur"</string>
diff --git a/packages/DocumentsUI/res/values-uk/strings.xml b/packages/DocumentsUI/res/values-uk/strings.xml
index afc0309c..5bf37f4 100644
--- a/packages/DocumentsUI/res/values-uk/strings.xml
+++ b/packages/DocumentsUI/res/values-uk/strings.xml
@@ -17,8 +17,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="2783841764617238354">"Документи"</string>
- <!-- no translation found for files_label (6051402950202690279) -->
- <skip />
+ <string name="files_label" msgid="6051402950202690279">"Файли"</string>
<string name="title_open" msgid="4353228937663917801">"Відкрити"</string>
<string name="title_save" msgid="2433679664882857999">"Зберегти в"</string>
<string name="menu_create_dir" msgid="5947289605844398389">"Створити папку"</string>
diff --git a/packages/DocumentsUI/res/values-ur-rPK/strings.xml b/packages/DocumentsUI/res/values-ur-rPK/strings.xml
index 6f3dd2f..008366e 100644
--- a/packages/DocumentsUI/res/values-ur-rPK/strings.xml
+++ b/packages/DocumentsUI/res/values-ur-rPK/strings.xml
@@ -17,8 +17,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="2783841764617238354">"دستاویزات"</string>
- <!-- no translation found for files_label (6051402950202690279) -->
- <skip />
+ <string name="files_label" msgid="6051402950202690279">"فائلیں"</string>
<string name="title_open" msgid="4353228937663917801">"کھولیں از"</string>
<string name="title_save" msgid="2433679664882857999">"اس میں محفوظ کریں"</string>
<string name="menu_create_dir" msgid="5947289605844398389">"فولڈر بنائیں"</string>
diff --git a/packages/DocumentsUI/res/values-uz-rUZ/strings.xml b/packages/DocumentsUI/res/values-uz-rUZ/strings.xml
index 54adf97..ad5b115b 100644
--- a/packages/DocumentsUI/res/values-uz-rUZ/strings.xml
+++ b/packages/DocumentsUI/res/values-uz-rUZ/strings.xml
@@ -17,8 +17,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="2783841764617238354">"Hujjatlar"</string>
- <!-- no translation found for files_label (6051402950202690279) -->
- <skip />
+ <string name="files_label" msgid="6051402950202690279">"Fayllar"</string>
<string name="title_open" msgid="4353228937663917801">"Ochish"</string>
<string name="title_save" msgid="2433679664882857999">"Saqlash"</string>
<string name="menu_create_dir" msgid="5947289605844398389">"Jild yaratish"</string>
diff --git a/packages/DocumentsUI/res/values-vi/strings.xml b/packages/DocumentsUI/res/values-vi/strings.xml
index d8c7d42..6c4d2a5 100644
--- a/packages/DocumentsUI/res/values-vi/strings.xml
+++ b/packages/DocumentsUI/res/values-vi/strings.xml
@@ -17,8 +17,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="2783841764617238354">"Tài liệu"</string>
- <!-- no translation found for files_label (6051402950202690279) -->
- <skip />
+ <string name="files_label" msgid="6051402950202690279">"Tệp"</string>
<string name="title_open" msgid="4353228937663917801">"Mở từ"</string>
<string name="title_save" msgid="2433679664882857999">"Lưu vào"</string>
<string name="menu_create_dir" msgid="5947289605844398389">"Tạo thư mục"</string>
diff --git a/packages/DocumentsUI/res/values-zh-rHK/strings.xml b/packages/DocumentsUI/res/values-zh-rHK/strings.xml
index 8a888bf..4970338 100644
--- a/packages/DocumentsUI/res/values-zh-rHK/strings.xml
+++ b/packages/DocumentsUI/res/values-zh-rHK/strings.xml
@@ -17,8 +17,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="2783841764617238354">"文件"</string>
- <!-- no translation found for files_label (6051402950202690279) -->
- <skip />
+ <string name="files_label" msgid="6051402950202690279">"檔案"</string>
<string name="title_open" msgid="4353228937663917801">"開啟檔案"</string>
<string name="title_save" msgid="2433679664882857999">"儲存至"</string>
<string name="menu_create_dir" msgid="5947289605844398389">"建立資料夾"</string>
diff --git a/packages/DocumentsUI/res/values-zh-rTW/strings.xml b/packages/DocumentsUI/res/values-zh-rTW/strings.xml
index 07c308c..42c86dc 100644
--- a/packages/DocumentsUI/res/values-zh-rTW/strings.xml
+++ b/packages/DocumentsUI/res/values-zh-rTW/strings.xml
@@ -17,8 +17,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="2783841764617238354">"文件"</string>
- <!-- no translation found for files_label (6051402950202690279) -->
- <skip />
+ <string name="files_label" msgid="6051402950202690279">"檔案"</string>
<string name="title_open" msgid="4353228937663917801">"開啟檔案"</string>
<string name="title_save" msgid="2433679664882857999">"儲存至"</string>
<string name="menu_create_dir" msgid="5947289605844398389">"建立資料夾"</string>
diff --git a/packages/DocumentsUI/res/values/dimens.xml b/packages/DocumentsUI/res/values/dimens.xml
index fb793a2..f94a00e 100644
--- a/packages/DocumentsUI/res/values/dimens.xml
+++ b/packages/DocumentsUI/res/values/dimens.xml
@@ -17,6 +17,7 @@
<resources>
<dimen name="icon_size">40dp</dimen>
<dimen name="root_icon_size">24dp</dimen>
+ <dimen name="root_icon_margin">0dp</dimen>
<dimen name="grid_width">152dp</dimen>
<dimen name="grid_height">176dp</dimen>
diff --git a/packages/DocumentsUI/res/values/styles.xml b/packages/DocumentsUI/res/values/styles.xml
index a1ad7e4..95c1d9c 100644
--- a/packages/DocumentsUI/res/values/styles.xml
+++ b/packages/DocumentsUI/res/values/styles.xml
@@ -34,6 +34,7 @@
<item name="android:windowNoTitle">true</item>
<item name="android:windowSoftInputMode">stateUnspecified|adjustUnspecified</item>
+ <item name="android:alertDialogTheme">@android:style/Theme.Material.Light.Dialog.Alert</item>
</style>
<style name="DocumentsNonDialogTheme" parent="@android:style/Theme.Material.DayNight.DarkActionBar">
@@ -58,6 +59,10 @@
<item name="android:background">@color/material_grey_600</item>
</style>
+ <style name="AlertDialogTheme" parent="@android:style/Theme.Material.Light.Dialog.Alert">
+ <item name="android:colorAccent">@color/material_blue_700</item>
+ </style>
+
<style name="StandaloneTheme" parent="@android:style/Theme.Material.DayNight.DarkActionBar">
<item name="android:actionBarWidgetTheme">@null</item>
@@ -73,6 +78,7 @@
<item name="android:windowNoTitle">true</item>
<item name="android:windowSoftInputMode">stateUnspecified|adjustUnspecified</item>
+ <item name="android:alertDialogTheme">@style/AlertDialogTheme</item>
</style>
</resources>
diff --git a/packages/DocumentsUI/src/com/android/documentsui/BandSelectManager.java b/packages/DocumentsUI/src/com/android/documentsui/BandSelectManager.java
index aa63837..74170f5 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/BandSelectManager.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/BandSelectManager.java
@@ -16,6 +16,7 @@
package com.android.documentsui;
+import static com.android.documentsui.Events.isMouseEvent;
import static com.android.internal.util.Preconditions.checkState;
import android.graphics.Point;
@@ -24,6 +25,7 @@
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.RecyclerView.ViewHolder;
import android.util.Log;
+import android.util.SparseBooleanArray;
import android.view.MotionEvent;
import android.view.View;
@@ -34,6 +36,9 @@
*/
public class BandSelectManager extends RecyclerView.SimpleOnItemTouchListener {
+ private static final int NOT_SELECTED = -1;
+ private static final int NOT_SET = -1;
+
// For debugging purposes.
private static final String TAG = "BandSelectManager";
private static final boolean DEBUG = false;
@@ -41,10 +46,140 @@
private final RecyclerView mRecyclerView;
private final MultiSelectManager mSelectManager;
private final Drawable mRegionSelectorDrawable;
+ private final SparseBooleanArray mSelectedByBand = new SparseBooleanArray();
private boolean mIsBandSelectActive = false;
private Point mOrigin;
- private Rect mRegionBounds;
+ private Point mPointer;
+ private Rect mBounds;
+
+ // Maintain the last selection made by band, so if bounds shrink back, we can deselect
+ // the respective items.
+ private int mCursorDeltaY = 0;
+ private int mFirstSelected = NOT_SELECTED;
+
+ // The time at which the current band selection-induced scroll began. If no scroll is in
+ // progress, the value is NOT_SET.
+ private long mScrollStartTime = NOT_SET;
+ private final Runnable mScrollRunnable = new Runnable() {
+ /**
+ * The number of milliseconds of scrolling at which scroll speed continues to increase. At
+ * first, the scroll starts slowly; then, the rate of scrolling increases until it reaches
+ * its maximum value at after this many milliseconds.
+ */
+ private static final long SCROLL_ACCELERATION_LIMIT_TIME_MS = 2000;
+
+ @Override
+ public void run() {
+ // Compute the number of pixels the pointer's y-coordinate is past the view. Negative
+ // values mean the pointer is at or before the top of the view, and positive values mean
+ // that the pointer is at or after the bottom of the view. Note that one additional
+ // pixel is added here so that the view still scrolls when the pointer is exactly at the
+ // top or bottom.
+ int pixelsPastView = 0;
+ if (mPointer.y <= 0) {
+ pixelsPastView = mPointer.y - 1;
+ } else if (mPointer.y >= mRecyclerView.getHeight() - 1) {
+ pixelsPastView = mPointer.y - mRecyclerView.getHeight() + 1;
+ }
+
+ if (!mIsBandSelectActive || pixelsPastView == 0) {
+ // If band selection is inactive, or if it is active but not at the edge of the
+ // view, no scrolling is necessary.
+ mScrollStartTime = NOT_SET;
+ return;
+ }
+
+ if (mScrollStartTime == NOT_SET) {
+ // If the pointer was previously not at the edge of the view but now is, set the
+ // start time for the scroll.
+ mScrollStartTime = System.currentTimeMillis();
+ }
+
+ // Compute the number of pixels to scroll, and scroll that many pixels.
+ final int numPixels = computeNumPixelsToScroll(
+ pixelsPastView, System.currentTimeMillis() - mScrollStartTime);
+ mRecyclerView.scrollBy(0, numPixels);
+
+ // Adjust the y-coordinate of the origin the opposite number of pixels so that the
+ // origin remains in the same place relative to the view's items.
+ mOrigin.y -= numPixels;
+ resizeBandSelectRectangle();
+
+ mRecyclerView.removeCallbacks(mScrollRunnable);
+ mRecyclerView.postOnAnimation(this);
+ }
+
+ /**
+ * Computes the number of pixels to scroll based on how far the pointer is past the end of
+ * the view and how long it has been there. Roughly based on ItemTouchHelper's algorithm for
+ * computing the number of pixels to scroll when an item is dragged to the end of a
+ * {@link RecyclerView}.
+ * @param pixelsPastView
+ * @param scrollDuration
+ * @return
+ */
+ private int computeNumPixelsToScroll(int pixelsPastView, long scrollDuration) {
+ final int maxScrollStep = computeMaxScrollStep(mRecyclerView);
+ final int direction = (int) Math.signum(pixelsPastView);
+ final int absPastView = Math.abs(pixelsPastView);
+
+ // Calculate the ratio of how far out of the view the pointer currently resides to the
+ // entire height of the view.
+ final float outOfBoundsRatio = Math.min(
+ 1.0f, (float) absPastView / mRecyclerView.getHeight());
+ // Interpolate this ratio and use it to compute the maximum scroll that should be
+ // possible for this step.
+ final float cappedScrollStep =
+ direction * maxScrollStep * smoothOutOfBoundsRatio(outOfBoundsRatio);
+
+ // Likewise, calculate the ratio of the time spent in the scroll to the limit.
+ final float timeRatio = Math.min(
+ 1.0f, (float) scrollDuration / SCROLL_ACCELERATION_LIMIT_TIME_MS);
+ // Interpolate this ratio and use it to compute the final number of pixels to scroll.
+ final int numPixels = (int) (cappedScrollStep * smoothTimeRatio(timeRatio));
+
+ // If the final number of pixels to scroll ends up being 0, the view should still scroll
+ // at least one pixel.
+ return numPixels != 0 ? numPixels : direction;
+ }
+
+ /**
+ * Computes the maximum scroll allowed for a given animation frame. Currently, this
+ * defaults to the height of the view, but this could be tweaked if this results in scrolls
+ * that are too fast or too slow.
+ * @param rv
+ * @return
+ */
+ private int computeMaxScrollStep(RecyclerView rv) {
+ return rv.getHeight();
+ }
+
+ /**
+ * Interpolates the given out of bounds ratio on a curve which starts at (0,0) and ends at
+ * (1,1) and quickly approaches 1 near the start of that interval. This ensures that drags
+ * that are at the edge or barely past the edge of the view still cause sufficient
+ * scrolling. The equation y=(x-1)^5+1 is used, but this could also be tweaked if needed.
+ * @param ratio A ratio which is in the range [0, 1].
+ * @return A "smoothed" value, also in the range [0, 1].
+ */
+ private float smoothOutOfBoundsRatio(float ratio) {
+ return (float) Math.pow(ratio - 1.0f, 5) + 1.0f;
+ }
+
+ /**
+ * Interpolates the given time ratio on a curve which starts at (0,0) and ends at (1,1) and
+ * stays close to 0 for most input values except those very close to 1. This ensures that
+ * scrolls start out very slowly but speed up drastically after the scroll has been in
+ * progress close to SCROLL_ACCELERATION_LIMIT_TIME_MS. The equation y=x^5 is used, but this
+ * could also be tweaked if needed.
+ * @param ratio A ratio which is in the range [0, 1].
+ * @return A "smoothed" value, also in the range [0, 1].
+ */
+ private float smoothTimeRatio(float ratio) {
+ return (float) Math.pow(ratio, 5);
+ }
+ };
/**
* @param recyclerView
@@ -83,37 +218,50 @@
return;
}
- Point point = new Point((int) e.getX(), (int) e.getY());
+ mPointer = new Point((int) e.getX(), (int) e.getY());
if (!mIsBandSelectActive) {
- startBandSelect(point);
+ startBandSelect();
}
- resizeBandSelectRectangle(point);
+ scrollViewIfNecessary();
+ resizeBandSelectRectangle();
selectChildrenCoveredBySelection();
}
/**
* Starts band select by adding the drawable to the RecyclerView's overlay.
- * @param origin The starting point of the selection.
*/
- private void startBandSelect(Point origin) {
- if (DEBUG) Log.d(TAG, "Starting band select from (" + origin.x + "," + origin.y + ").");
+ private void startBandSelect() {
+ if (DEBUG) Log.d(TAG, "Starting band select from (" + mPointer.x + "," + mPointer.y + ").");
mIsBandSelectActive = true;
- mOrigin = origin;
+ mOrigin = mPointer;
mRecyclerView.getOverlay().add(mRegionSelectorDrawable);
}
/**
+ * Scrolls the view if necessary.
+ */
+ private void scrollViewIfNecessary() {
+ mRecyclerView.removeCallbacks(mScrollRunnable);
+ mScrollRunnable.run();
+ mRecyclerView.invalidate();
+ }
+
+ /**
* Resizes the band select rectangle by using the origin and the current pointer positoin as
* two opposite corners of the selection.
- * @param pointerPosition
*/
- private void resizeBandSelectRectangle(Point pointerPosition) {
- mRegionBounds = new Rect(Math.min(mOrigin.x, pointerPosition.x),
- Math.min(mOrigin.y, pointerPosition.y),
- Math.max(mOrigin.x, pointerPosition.x),
- Math.max(mOrigin.y, pointerPosition.y));
- mRegionSelectorDrawable.setBounds(mRegionBounds);
+ private void resizeBandSelectRectangle() {
+ if (mBounds != null) {
+ mCursorDeltaY = mPointer.y - mBounds.bottom;
+ }
+
+ mBounds = new Rect(Math.min(mOrigin.x, mPointer.x),
+ Math.min(mOrigin.y, mPointer.y),
+ Math.max(mOrigin.x, mPointer.x),
+ Math.max(mOrigin.y, mPointer.y));
+
+ mRegionSelectorDrawable.setBounds(mBounds);
}
/**
@@ -122,14 +270,53 @@
* Final optimized implementation, with support for managing offscreen selection to come.
*/
private void selectChildrenCoveredBySelection() {
+
+ // track top and bottom selections. Details on why this is useful below.
+ int first = NOT_SELECTED;
+ int last = NOT_SELECTED;
+
for (int i = 0; i < mRecyclerView.getChildCount(); i++) {
+
View child = mRecyclerView.getChildAt(i);
ViewHolder holder = mRecyclerView.getChildViewHolder(child);
Rect childRect = new Rect();
child.getHitRect(childRect);
- boolean doRectsOverlap = Rect.intersects(childRect, mRegionBounds);
- mSelectManager.setItemSelected(holder.getAdapterPosition(), doRectsOverlap);
+ boolean shouldSelect = Rect.intersects(childRect, mBounds);
+ int position = holder.getAdapterPosition();
+
+ // This also allows us to clear the selection of elements
+ // that only temporarily entered the bounds of the band.
+ if (mSelectedByBand.get(position) && !shouldSelect) {
+ mSelectManager.setItemSelected(position, false);
+ mSelectedByBand.delete(position);
+ }
+
+ // We need to keep track of the first and last items selected.
+ // We'll use this information along with cursor direction
+ // to determine the starting point of the selection.
+ // We provide this information to selection manager
+ // to enable more natural user interaction when working
+ // with Shift+Click and multiple contiguous selection ranges.
+ if (shouldSelect) {
+ if (first == NOT_SELECTED) {
+ first = position;
+ } else {
+ last = position;
+ }
+ mSelectManager.setItemSelected(position, true);
+ mSelectedByBand.put(position, true);
+ }
+ }
+
+ // Remember which is the last selected item, so we can
+ // share that with selection manager when band select ends.
+ // It'll use that as it's begin selection point when
+ // user SHIFT+Clicks.
+ if (mCursorDeltaY < 0 && last != NOT_SELECTED) {
+ mFirstSelected = last;
+ } else if (mCursorDeltaY > 0 && first != NOT_SELECTED) {
+ mFirstSelected = first;
}
}
@@ -139,16 +326,10 @@
private void endBandSelect() {
if (DEBUG) Log.d(TAG, "Ending band select.");
mIsBandSelectActive = false;
+ mSelectedByBand.clear();
mRecyclerView.getOverlay().remove(mRegionSelectorDrawable);
- }
-
- /**
- * Determines whether the provided event was triggered by a mouse (as opposed to a finger or
- * stylus).
- * @param e
- * @return
- */
- private static boolean isMouseEvent(MotionEvent e) {
- return e.getToolType(0) == MotionEvent.TOOL_TYPE_MOUSE;
+ if (mFirstSelected != NOT_SELECTED) {
+ mSelectManager.setSelectionFocusBegin(mFirstSelected);
+ }
}
}
diff --git a/packages/DocumentsUI/src/com/android/documentsui/BaseActivity.java b/packages/DocumentsUI/src/com/android/documentsui/BaseActivity.java
index 40aa59c..9b8d847 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/BaseActivity.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/BaseActivity.java
@@ -16,10 +16,13 @@
package com.android.documentsui;
+import static com.android.documentsui.DirectoryFragment.ANIM_DOWN;
import static com.android.documentsui.DirectoryFragment.ANIM_NONE;
import static com.android.documentsui.DirectoryFragment.ANIM_SIDE;
import static com.android.documentsui.DirectoryFragment.ANIM_UP;
+import static com.android.internal.util.Preconditions.checkArgument;
+import android.annotation.Nullable;
import android.app.Activity;
import android.app.Fragment;
import android.content.Intent;
@@ -79,8 +82,9 @@
private final String mTag;
public abstract State getDisplayState();
- public abstract void onDocumentPicked(DocumentInfo doc);
+ public abstract void onDocumentPicked(DocumentInfo doc, @Nullable DocumentContext siblings);
public abstract void onDocumentsPicked(List<DocumentInfo> docs);
+
abstract void onTaskFinished(Uri... uris);
abstract void onDirectoryChanged(int anim);
abstract void updateActionBar();
@@ -258,6 +262,17 @@
&& !root.isDownloads();
}
+ void onDirectoryCreated(DocumentInfo doc) {
+ checkArgument(doc.isDirectory());
+ openDirectory(doc);
+ }
+
+ void openDirectory(DocumentInfo doc) {
+ getDisplayState().stack.push(doc);
+ getDisplayState().stackTouched = true;
+ onCurrentDirectoryChanged(ANIM_DOWN);
+ }
+
/**
* Call this when directory changes. Prior to root fragment update
* the (abstract) directoryChanged method will be called.
@@ -605,11 +620,7 @@
if (isDestroyed()) return;
getDisplayState().restored = true;
onCurrentDirectoryChanged(ANIM_NONE);
-
onStackRestored(mRestoredStack, mExternal);
-
- getDisplayState().restored = true;
- onCurrentDirectoryChanged(ANIM_NONE);
}
}
@@ -846,4 +857,17 @@
updateActionBar();
}
}
+
+ /**
+ * Interface providing access to current view of documents
+ * even when all documents are not homed to the same parent.
+ */
+ interface DocumentContext {
+ /**
+ * Returns the cursor for the selected document. The cursor can be used to retrieve
+ * details about a document and its siblings.
+ * @return
+ */
+ Cursor getCursor();
+ }
}
diff --git a/packages/DocumentsUI/src/com/android/documentsui/CreateDirectoryFragment.java b/packages/DocumentsUI/src/com/android/documentsui/CreateDirectoryFragment.java
index 0577bf1..f927595 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/CreateDirectoryFragment.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/CreateDirectoryFragment.java
@@ -60,11 +60,7 @@
final Context context = getActivity();
final ContentResolver resolver = context.getContentResolver();
- // We need to specify android.R.style.Theme_DeviceDefault_Dialog explicitly,
- // because the application theme 'DialogWhenReallyLarge' has
- // fixed window size properties for large screen devices.
- final AlertDialog.Builder builder = new AlertDialog.Builder(
- context, AlertDialog.THEME_DEVICE_DEFAULT_LIGHT);
+ final AlertDialog.Builder builder = new AlertDialog.Builder(context);
final LayoutInflater dialogInflater = LayoutInflater.from(builder.getContext());
final View view = dialogInflater.inflate(R.layout.dialog_create_dir, null, false);
@@ -150,7 +146,7 @@
protected void onPostExecute(DocumentInfo result) {
if (result != null) {
// Navigate into newly created child
- mActivity.onDocumentPicked(result);
+ mActivity.onDirectoryCreated(result);
} else {
Toast.makeText(mActivity, R.string.create_error, Toast.LENGTH_SHORT).show();
}
diff --git a/packages/DocumentsUI/src/com/android/documentsui/DirectoryFragment.java b/packages/DocumentsUI/src/com/android/documentsui/DirectoryFragment.java
index 308375e7..7e6ec8b 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/DirectoryFragment.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/DirectoryFragment.java
@@ -89,6 +89,7 @@
import android.widget.TextView;
import android.widget.Toast;
+import com.android.documentsui.BaseActivity.DocumentContext;
import com.android.documentsui.BaseActivity.State;
import com.android.documentsui.MultiSelectManager.Selection;
import com.android.documentsui.ProviderExecutor.Preemptable;
@@ -286,6 +287,11 @@
public boolean onSingleTapUp(MotionEvent e) {
return DirectoryFragment.this.onSingleTapUp(e);
}
+ @Override
+ public boolean onDoubleTap(MotionEvent e) {
+ Log.d(TAG, "Handling double tap.");
+ return DirectoryFragment.this.onDoubleTap(e);
+ }
};
mSelectionManager = new MultiSelectManager(mRecView, listener);
@@ -425,20 +431,37 @@
}
private boolean onSingleTapUp(MotionEvent e) {
- int position = getEventAdapterPosition(e);
-
- if (position != RecyclerView.NO_POSITION) {
- final Cursor cursor = mAdapter.getItem(position);
- checkNotNull(cursor, "Cursor cannot be null.");
- final String docMimeType = getCursorString(cursor, Document.COLUMN_MIME_TYPE);
- final int docFlags = getCursorInt(cursor, Document.COLUMN_FLAGS);
- if (isDocumentEnabled(docMimeType, docFlags)) {
- final DocumentInfo doc = DocumentInfo.fromDirectoryCursor(cursor);
- ((BaseActivity) getActivity()).onDocumentPicked(doc);
- return true;
+ if (!Events.isMouseEvent(e)) {
+ int position = getEventAdapterPosition(e);
+ if (position != RecyclerView.NO_POSITION) {
+ return handleViewItem(position);
}
}
+ return false;
+ }
+ protected boolean onDoubleTap(MotionEvent e) {
+ if (Events.isMouseEvent(e)) {
+ Log.d(TAG, "Handling double tap from mouse.");
+ int position = getEventAdapterPosition(e);
+ if (position != RecyclerView.NO_POSITION) {
+ return handleViewItem(position);
+ }
+ }
+ return false;
+ }
+
+ private boolean handleViewItem(int position) {
+ final Cursor cursor = mAdapter.getItem(position);
+ checkNotNull(cursor, "Cursor cannot be null.");
+ final String docMimeType = getCursorString(cursor, Document.COLUMN_MIME_TYPE);
+ final int docFlags = getCursorInt(cursor, Document.COLUMN_FLAGS);
+ if (isDocumentEnabled(docMimeType, docFlags)) {
+ final DocumentInfo doc = DocumentInfo.fromDirectoryCursor(cursor);
+ ((BaseActivity) getActivity()).onDocumentPicked(doc, mAdapter);
+ mSelectionManager.clearSelection();
+ return true;
+ }
return false;
}
@@ -927,7 +950,8 @@
}
}
- private final class DocumentsAdapter extends RecyclerView.Adapter<DocumentHolder> {
+ private final class DocumentsAdapter extends RecyclerView.Adapter<DocumentHolder>
+ implements DocumentContext {
private final Context mContext;
private final LayoutInflater mInflater;
@@ -1191,6 +1215,14 @@
}
}
+ @Override
+ public Cursor getCursor() {
+ if (Looper.myLooper() != Looper.getMainLooper()) {
+ throw new IllegalStateException("Can't call getCursor from non-main thread.");
+ }
+ return mCursor;
+ }
+
private Cursor getItem(int position) {
if (position < mCursorCount) {
mCursor.moveToPosition(position);
diff --git a/packages/DocumentsUI/src/com/android/documentsui/DocumentsActivity.java b/packages/DocumentsUI/src/com/android/documentsui/DocumentsActivity.java
index 272700b..2de7fc4 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/DocumentsActivity.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/DocumentsActivity.java
@@ -26,12 +26,8 @@
import static com.android.documentsui.DirectoryFragment.ANIM_DOWN;
import static com.android.documentsui.DirectoryFragment.ANIM_NONE;
import static com.android.documentsui.DirectoryFragment.ANIM_UP;
+import static com.android.internal.util.Preconditions.checkArgument;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
-import android.app.ActionBar;
import android.app.Activity;
import android.app.Fragment;
import android.app.FragmentManager;
@@ -608,12 +604,10 @@
}
@Override
- public void onDocumentPicked(DocumentInfo doc) {
+ public void onDocumentPicked(DocumentInfo doc, DocumentContext context) {
final FragmentManager fm = getFragmentManager();
if (doc.isDirectory()) {
- mState.stack.push(doc);
- mState.stackTouched = true;
- onCurrentDirectoryChanged(ANIM_DOWN);
+ openDirectory(doc);
} else if (mState.action == ACTION_OPEN || mState.action == ACTION_GET_CONTENT) {
// Explicit file picked, return
new ExistingFinishTask(doc.derivedUri).executeOnExecutor(getCurrentExecutor());
diff --git a/packages/DocumentsUI/src/com/android/documentsui/Events.java b/packages/DocumentsUI/src/com/android/documentsui/Events.java
new file mode 100644
index 0000000..2e06903
--- /dev/null
+++ b/packages/DocumentsUI/src/com/android/documentsui/Events.java
@@ -0,0 +1,54 @@
+/*
+ * 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.documentsui;
+
+import android.view.KeyEvent;
+import android.view.MotionEvent;
+
+/**
+ * Utility code for dealing with MotionEvents.
+ */
+final class Events {
+
+ /**
+ * Returns true if event was triggered by a mouse.
+ */
+ static boolean isMouseEvent(MotionEvent e) {
+ return e.getToolType(0) == MotionEvent.TOOL_TYPE_MOUSE;
+ }
+
+ /**
+ * Returns true if event was triggered by a mouse.
+ */
+ static boolean isMouseType(int toolType) {
+ return toolType == MotionEvent.TOOL_TYPE_MOUSE;
+ }
+
+ /**
+ * Returns true if the shift is pressed.
+ */
+ boolean isShiftPressed(MotionEvent e) {
+ return hasShiftBit(e.getMetaState());
+ }
+
+ /**
+ * Returns true if the "SHIFT" bit is set.
+ */
+ static boolean hasShiftBit(int metaState) {
+ return (metaState & KeyEvent.META_SHIFT_ON) != 0;
+ }
+}
diff --git a/packages/DocumentsUI/src/com/android/documentsui/MultiSelectManager.java b/packages/DocumentsUI/src/com/android/documentsui/MultiSelectManager.java
index a962abd..91b4456 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/MultiSelectManager.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/MultiSelectManager.java
@@ -26,13 +26,11 @@
import android.util.Log;
import android.util.SparseBooleanArray;
import android.view.GestureDetector;
+import android.view.GestureDetector.OnDoubleTapListener;
import android.view.GestureDetector.OnGestureListener;
-import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
-import com.android.internal.util.Preconditions;
-
import com.google.common.annotations.VisibleForTesting;
import java.util.ArrayList;
@@ -51,7 +49,7 @@
// Only created when selection is cleared.
private Selection mIntermediateSelection;
- private Ranger mRanger;
+ private Range mRanger;
private final List<MultiSelectManager.Callback> mCallbacks = new ArrayList<>(1);
private Adapter<?> mAdapter;
@@ -60,8 +58,11 @@
/**
* @param recyclerView
* @param gestureDelegate Option delage gesture listener.
+ * @template A gestureDelegate that implements both {@link OnGestureListener}
+ * and {@link OnDoubleTapListener}
*/
- public MultiSelectManager(final RecyclerView recyclerView, OnGestureListener gestureDelegate) {
+ public <L extends OnGestureListener & OnDoubleTapListener> MultiSelectManager(
+ final RecyclerView recyclerView, L gestureDelegate) {
this(
recyclerView.getAdapter(),
new RecyclerViewHelper() {
@@ -86,11 +87,15 @@
}
};
+ CompositeOnGestureListener<? extends Object> compositeListener =
+ new CompositeOnGestureListener<>(listener, gestureDelegate);
final GestureDetector detector = new GestureDetector(
recyclerView.getContext(),
gestureDelegate == null
? listener
- : new CompositeOnGestureListener(listener, gestureDelegate));
+ : compositeListener);
+
+ detector.setOnDoubleTapListener(compositeListener);
recyclerView.addOnItemTouchListener(
new RecyclerView.OnItemTouchListener() {
@@ -236,52 +241,6 @@
}
}
- /**
- * @param e
- * @return true if the event was consumed.
- */
- private boolean onSingleTapUp(MotionEvent e) {
- if (DEBUG) Log.d(TAG, "Handling tap event.");
- if (mSelection.isEmpty()) {
- return false;
- }
-
- return onSingleTapUp(mHelper.findEventPosition(e), e.getMetaState());
- }
-
- /**
- * TODO: Roll this into {@link #onSingleTapUp(MotionEvent)} once MotionEvent
- * can be mocked.
- *
- * @param position
- * @param metaState as returned from {@link MotionEvent#getMetaState()}.
- * @return true if the event was consumed.
- * @hide
- */
- @VisibleForTesting
- boolean onSingleTapUp(int position, int metaState) {
- if (mSelection.isEmpty()) {
- return false;
- }
-
- if (position == RecyclerView.NO_POSITION) {
- if (DEBUG) Log.d(TAG, "View is null. Canceling selection.");
- clearSelection();
- return true;
- }
-
- if (isShiftPressed(metaState) && mRanger != null) {
- mRanger.snapSelection(position);
- } else {
- toggleSelection(position);
- }
- return true;
- }
-
- private static boolean isShiftPressed(int metaState) {
- return (metaState & KeyEvent.META_SHIFT_ON) != 0;
- }
-
private void onLongPress(MotionEvent e) {
if (DEBUG) Log.d(TAG, "Handling long press event.");
@@ -310,6 +269,50 @@
}
/**
+ * @param e
+ * @return true if the event was consumed.
+ */
+ private boolean onSingleTapUp(MotionEvent e) {
+ if (DEBUG) Log.d(TAG, "Handling tap event.");
+ return onSingleTapUp(mHelper.findEventPosition(e), e.getMetaState(), e.getToolType(0));
+ }
+
+ /**
+ * TODO: Roll this into {@link #onSingleTapUp(MotionEvent)} once MotionEvent
+ * can be mocked.
+ *
+ * @param position
+ * @param metaState as returned from {@link MotionEvent#getMetaState()}.
+ * @param toolType
+ * @return true if the event was consumed.
+ * @hide
+ */
+ @VisibleForTesting
+ boolean onSingleTapUp(int position, int metaState, int toolType) {
+ if (mSelection.isEmpty()) {
+ // if this is a mouse click on an item, start selection mode.
+ if (position != RecyclerView.NO_POSITION && Events.isMouseType(toolType)) {
+ toggleSelection(position);
+ }
+ return false;
+ }
+
+ if (position == RecyclerView.NO_POSITION) {
+ if (DEBUG) Log.d(TAG, "View is null. Canceling selection.");
+ clearSelection();
+ return false;
+ }
+
+ if (Events.hasShiftBit(metaState) && mRanger != null) {
+ mRanger.snapSelection(position);
+ } else {
+ toggleSelection(position);
+ }
+
+ return false;
+ }
+
+ /**
* Toggles the selection state at position. If an item does end up selected
* a new Ranger (range selection manager) at that point is created.
*
@@ -334,13 +337,26 @@
// By recreating Ranger at this point, we allow the user to create
// multiple separate contiguous ranges with SHIFT+Click & Click.
if (selected) {
- mRanger = new Ranger(position);
+ setSelectionFocusBegin(position);
}
return selected;
}
}
/**
+ * Sets the magic location at which a selection range begins. This
+ * value is consulted when determining how to extend, and modify
+ * selection ranges.
+ *
+ * @throws IllegalStateException if {@code position} is not already be selected
+ * @param position
+ */
+ void setSelectionFocusBegin(int position) {
+ checkState(mSelection.contains(position));
+ mRanger = new Range(position);
+ }
+
+ /**
* Try to select all elements in range. Not that callbacks can cancel selection
* of specific items, so some or even all items may not reflect the desired
* state after the update is complete.
@@ -420,18 +436,18 @@
/**
* Class providing support for managing range selections.
*/
- private final class Ranger {
+ private final class Range {
private static final int UNDEFINED = -1;
final int mBegin;
int mEnd = UNDEFINED;
- public Ranger(int begin) {
+ public Range(int begin) {
if (DEBUG) Log.d(TAG, String.format("New Ranger(%d) created.", begin));
mBegin = begin;
}
- void snapSelection(int position) {
+ private void snapSelection(int position) {
checkState(mRanger != null);
checkArgument(position != RecyclerView.NO_POSITION);
@@ -720,12 +736,17 @@
/**
* A composite {@code OnGestureDetector} that allows us to delegate unhandled
* events to an outside party (presumably DirectoryFragment).
+ * @template A gestureDelegate that implements both {@link OnGestureListener}
+ * and {@link OnDoubleTapListener}
*/
- private static final class CompositeOnGestureListener implements OnGestureListener {
+ private static final class
+ CompositeOnGestureListener<L extends OnGestureListener & OnDoubleTapListener>
+ implements OnGestureListener, OnDoubleTapListener {
- private OnGestureListener[] mListeners;
+ private L[] mListeners;
- public CompositeOnGestureListener(OnGestureListener... listeners) {
+ @SafeVarargs
+ public CompositeOnGestureListener(L... listeners) {
mListeners = listeners;
}
@@ -782,5 +803,35 @@
}
return false;
}
+
+ @Override
+ public boolean onSingleTapConfirmed(MotionEvent e) {
+ for (int i = 0; i < mListeners.length; i++) {
+ if (mListeners[i].onSingleTapConfirmed(e)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public boolean onDoubleTap(MotionEvent e) {
+ for (int i = 0; i < mListeners.length; i++) {
+ if (mListeners[i].onDoubleTap(e)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public boolean onDoubleTapEvent(MotionEvent e) {
+ for (int i = 0; i < mListeners.length; i++) {
+ if (mListeners[i].onDoubleTapEvent(e)) {
+ return true;
+ }
+ }
+ return false;
+ }
}
}
diff --git a/packages/DocumentsUI/src/com/android/documentsui/QuickViewIntentBuilder.java b/packages/DocumentsUI/src/com/android/documentsui/QuickViewIntentBuilder.java
new file mode 100644
index 0000000..878c4c2
--- /dev/null
+++ b/packages/DocumentsUI/src/com/android/documentsui/QuickViewIntentBuilder.java
@@ -0,0 +1,112 @@
+/*
+ * 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.documentsui;
+
+import static com.android.documentsui.model.DocumentInfo.getCursorString;
+
+import android.annotation.Nullable;
+import android.content.ClipData;
+import android.content.ClipDescription;
+import android.content.ComponentName;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.database.Cursor;
+import android.net.Uri;
+import android.provider.DocumentsContract;
+import android.provider.DocumentsContract.Document;
+import android.util.Log;
+
+import com.android.documentsui.BaseActivity.DocumentContext;
+import com.android.documentsui.model.DocumentInfo;
+
+/**
+ * Provides support for gather a list of quick-viewable files into a quick view intent.
+ */
+final class QuickViewIntentBuilder {
+
+ private static final String TAG = "QvIntentBuilder";
+ private static final boolean DEBUG = false;
+
+ private final DocumentInfo mDocument;
+ private final DocumentContext mContext;
+
+ public ClipData mClipData;
+ public int mDocumentLocation;
+ private PackageManager mPkgManager;
+
+ public QuickViewIntentBuilder(
+ PackageManager pkgManager, DocumentInfo doc, DocumentContext context) {
+ mPkgManager = pkgManager;
+ mDocument = doc;
+ mContext = context;
+ }
+
+ /**
+ * Builds the intent for quick viewing. Short circuits building if a handler cannot
+ * be resolved; in this case {@code null} is returned.
+ */
+ @Nullable Intent build() {
+ if (DEBUG) Log.d(TAG, "Preparing intent for doc:" + mDocument.documentId);
+
+ Intent intent = new Intent(Intent.ACTION_QUICK_VIEW);
+ intent.setDataAndType(mDocument.derivedUri, mDocument.mimeType);
+
+ // Try to resolve the intent. If a matching app isn't installed, it won't resolve.
+ ComponentName handler = intent.resolveActivity(mPkgManager);
+ if (handler == null) {
+ return null;
+ }
+
+ Cursor cursor = mContext.getCursor();
+ for (int i = 0; i < cursor.getCount(); i++) {
+ onNextItem(i, cursor);
+ }
+
+ intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
+ intent.putExtra(Intent.EXTRA_INDEX, mDocumentLocation);
+ intent.setClipData(mClipData);
+
+ return intent;
+ }
+
+ private void onNextItem(int index, Cursor cursor) {
+ cursor.moveToPosition(index);
+
+ String mimeType = getCursorString(cursor, Document.COLUMN_MIME_TYPE);
+ if (Document.MIME_TYPE_DIR.equals(mimeType)) {
+ return;
+ }
+
+ String id = getCursorString(cursor, Document.COLUMN_DOCUMENT_ID);
+ String authority = getCursorString(cursor, RootCursorWrapper.COLUMN_AUTHORITY);
+ Uri uri = DocumentsContract.buildDocumentUri(authority, id);
+ if (DEBUG) Log.d(TAG, "Including file[" + id + "] @ " + uri);
+
+ if (id.equals(mDocument.documentId)) {
+ if (DEBUG) Log.d(TAG, "Found starting point for QV. " + index);
+ mDocumentLocation = index;
+ }
+
+ ClipData.Item item = new ClipData.Item(uri);
+ if (mClipData == null) {
+ mClipData = new ClipData(
+ "URIs", new String[]{ClipDescription.MIMETYPE_TEXT_URILIST}, item);
+ } else {
+ mClipData.addItem(item);
+ }
+ }
+}
diff --git a/packages/DocumentsUI/src/com/android/documentsui/StandaloneActivity.java b/packages/DocumentsUI/src/com/android/documentsui/StandaloneActivity.java
index a972428..1ca277d 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/StandaloneActivity.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/StandaloneActivity.java
@@ -20,6 +20,7 @@
import static com.android.documentsui.DirectoryFragment.ANIM_NONE;
import static com.android.documentsui.DirectoryFragment.ANIM_UP;
+import android.annotation.Nullable;
import android.app.Activity;
import android.app.FragmentManager;
import android.content.ActivityNotFoundException;
@@ -57,7 +58,9 @@
* Standalone file management activity.
*/
public class StandaloneActivity extends BaseActivity {
+
public static final String TAG = "StandaloneFileManagement";
+ static final boolean DEBUG = false;
private Toolbar mToolbar;
private Spinner mToolbarStack;
@@ -281,28 +284,46 @@
}
@Override
- public void onDocumentPicked(DocumentInfo doc) {
- if (doc.isDirectory()) {
- mState.stack.push(doc);
- mState.stackTouched = true;
- onCurrentDirectoryChanged(ANIM_DOWN);
- } else {
- // Fall back to viewing
- final Intent view = new Intent(Intent.ACTION_VIEW);
- view.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
- view.setData(doc.derivedUri);
-
- try {
- startActivity(view);
- } catch (ActivityNotFoundException ex2) {
- Toast.makeText(this, R.string.toast_no_application, Toast.LENGTH_SHORT).show();
- }
- }
+ public void onDocumentsPicked(List<DocumentInfo> docs) {
+ throw new UnsupportedOperationException();
}
@Override
- public void onDocumentsPicked(List<DocumentInfo> docs) {
- // TODO
+ public void onDocumentPicked(DocumentInfo doc, @Nullable DocumentContext siblings) {
+ if (doc.isDirectory()) {
+ openDirectory(doc);
+ } else {
+ openDocument(doc, siblings);
+ }
+ }
+
+ /**
+ * Launches an intent to view the specified document.
+ */
+ private void openDocument(DocumentInfo doc, @Nullable DocumentContext siblings) {
+ Intent intent = null;
+ if (siblings != null) {
+ QuickViewIntentBuilder builder =
+ new QuickViewIntentBuilder(getPackageManager(), doc, siblings);
+ intent = builder.build();
+ }
+
+ // fallback to traditional VIEW action...
+ if (intent == null) {
+ intent = new Intent(Intent.ACTION_VIEW);
+ intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
+ intent.setData(doc.derivedUri);
+ }
+
+ if (DEBUG && intent.getClipData() != null) {
+ Log.d(TAG, "Starting intent w/ clip data: " + intent.getClipData());
+ }
+
+ try {
+ startActivity(intent);
+ } catch (ActivityNotFoundException ex2) {
+ Toast.makeText(this, R.string.toast_no_application, Toast.LENGTH_SHORT).show();
+ }
}
@Override
diff --git a/packages/DocumentsUI/tests/src/com/android/documentsui/MultiSelectManagerTest.java b/packages/DocumentsUI/tests/src/com/android/documentsui/MultiSelectManagerTest.java
index aabec9a..d9f2261 100644
--- a/packages/DocumentsUI/tests/src/com/android/documentsui/MultiSelectManagerTest.java
+++ b/packages/DocumentsUI/tests/src/com/android/documentsui/MultiSelectManagerTest.java
@@ -65,6 +65,35 @@
}
@Test
+ public void mouseClick_StartsSelectionMode() {
+ click(7);
+ assertSelection(7);
+ }
+
+ @Test
+ public void mouseClick_ShiftClickExtendsSelection() {
+ click(7);
+ shiftClick(11);
+ assertRangeSelection(7, 11);
+ }
+
+ @Test
+ public void mouseClick_NoPosition_ClearsSelection() {
+ mManager.onLongPress(7);
+ click(11);
+ click(RecyclerView.NO_POSITION);
+ assertSelection();
+ }
+
+ @Test
+ public void setSelectionFocusBegin() {
+ mManager.setItemSelected(7, true);
+ mManager.setSelectionFocusBegin(7);
+ shiftClick(11);
+ assertRangeSelection(7, 11);
+ }
+
+ @Test
public void longPress_StartsSelectionMode() {
mManager.onLongPress(7);
assertSelection(7);
@@ -78,63 +107,57 @@
}
@Test
- public void singleTapUp_DoesNotSelectBeforeLongPress() {
- mManager.onSingleTapUp(99, 0);
- assertSelection();
- }
-
- @Test
public void singleTapUp_UnselectsSelectedItem() {
mManager.onLongPress(7);
- mManager.onSingleTapUp(7, 0);
+ tap(7);
assertSelection();
}
@Test
- public void singleTapUp_NoPositionClearsSelection() {
+ public void singleTapUp_NoPosition_ClearsSelection() {
mManager.onLongPress(7);
- mManager.onSingleTapUp(11, 0);
- mManager.onSingleTapUp(RecyclerView.NO_POSITION, 0);
+ tap(11);
+ tap(RecyclerView.NO_POSITION);
assertSelection();
}
@Test
public void singleTapUp_ExtendsSelection() {
mManager.onLongPress(99);
- mManager.onSingleTapUp(7, 0);
- mManager.onSingleTapUp(13, 0);
- mManager.onSingleTapUp(129899, 0);
+ tap(7);
+ tap(13);
+ tap(129899);
assertSelection(7, 99, 13, 129899);
}
@Test
public void singleTapUp_ShiftCreatesRangeSelection() {
mManager.onLongPress(7);
- mManager.onSingleTapUp(17, KeyEvent.META_SHIFT_ON);
+ shiftTap(17);
assertRangeSelection(7, 17);
}
@Test
public void singleTapUp_ShiftCreatesRangeSeletion_Backwards() {
mManager.onLongPress(17);
- mManager.onSingleTapUp(7, KeyEvent.META_SHIFT_ON);
+ shiftTap(7);
assertRangeSelection(7, 17);
}
@Test
public void singleTapUp_SecondShiftClickExtendsSelection() {
mManager.onLongPress(7);
- mManager.onSingleTapUp(11, KeyEvent.META_SHIFT_ON);
- mManager.onSingleTapUp(17, KeyEvent.META_SHIFT_ON);
+ shiftTap(11);
+ shiftTap(17);
assertRangeSelection(7, 17);
}
@Test
public void singleTapUp_MultipleContiguousRangesSelected() {
mManager.onLongPress(7);
- mManager.onSingleTapUp(11, KeyEvent.META_SHIFT_ON);
- mManager.onSingleTapUp(20, 0);
- mManager.onSingleTapUp(25, KeyEvent.META_SHIFT_ON);
+ shiftTap(11);
+ tap(20);
+ shiftTap(25);
assertRangeSelected(7, 11);
assertRangeSelected(20, 25);
assertSelectionSize(11);
@@ -143,16 +166,16 @@
@Test
public void singleTapUp_ShiftReducesSelectionRange_FromPreviousShiftClick() {
mManager.onLongPress(7);
- mManager.onSingleTapUp(17, KeyEvent.META_SHIFT_ON);
- mManager.onSingleTapUp(10, KeyEvent.META_SHIFT_ON);
+ shiftTap(17);
+ shiftTap(10);
assertRangeSelection(7, 10);
}
@Test
public void singleTapUp_ShiftReducesSelectionRange_FromPreviousShiftClick_Backwards() {
mManager.onLongPress(17);
- mManager.onSingleTapUp(7, KeyEvent.META_SHIFT_ON);
- mManager.onSingleTapUp(14, KeyEvent.META_SHIFT_ON);
+ shiftTap(7);
+ shiftTap(14);
assertRangeSelection(14, 17);
}
@@ -160,11 +183,27 @@
@Test
public void singleTapUp_ShiftReversesSelectionDirection() {
mManager.onLongPress(7);
- mManager.onSingleTapUp(17, KeyEvent.META_SHIFT_ON);
- mManager.onSingleTapUp(0, KeyEvent.META_SHIFT_ON);
+ shiftTap(17);
+ shiftTap(0);
assertRangeSelection(0, 7);
}
+ private void tap(int position) {
+ mManager.onSingleTapUp(position, 0, MotionEvent.TOOL_TYPE_MOUSE);
+ }
+
+ private void shiftTap(int position) {
+ mManager.onSingleTapUp(position, KeyEvent.META_SHIFT_ON, MotionEvent.TOOL_TYPE_FINGER);
+ }
+
+ private void click(int position) {
+ mManager.onSingleTapUp(position, 0, MotionEvent.TOOL_TYPE_MOUSE);
+ }
+
+ private void shiftClick(int position) {
+ mManager.onSingleTapUp(position, KeyEvent.META_SHIFT_ON, MotionEvent.TOOL_TYPE_MOUSE);
+ }
+
private void assertSelected(int... expected) {
for (int i = 0; i < expected.length; i++) {
Selection selection = mManager.getSelection();
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/src/com/android/externalstorage/ExternalStorageProvider.java b/packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java
index 4f0c6a41..393771a 100644
--- a/packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java
+++ b/packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java
@@ -162,7 +162,11 @@
if (volume.getType() == VolumeInfo.TYPE_PUBLIC) {
root.flags |= Root.FLAG_HAS_SETTINGS;
}
- root.visiblePath = volume.getPathForUser(userId);
+ if (volume.isVisibleForRead(userId)) {
+ root.visiblePath = volume.getPathForUser(userId);
+ } else {
+ root.visiblePath = null;
+ }
root.path = volume.getInternalPathForUser(userId);
root.docId = getDocIdForFile(root.path);
diff --git a/packages/Keyguard/res/values-fa/strings.xml b/packages/Keyguard/res/values-fa/strings.xml
index 58134fe..fc9454da 100644
--- a/packages/Keyguard/res/values-fa/strings.xml
+++ b/packages/Keyguard/res/values-fa/strings.xml
@@ -42,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>
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardAbsKeyInputView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardAbsKeyInputView.java
index 0c6837f..8f792de 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardAbsKeyInputView.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardAbsKeyInputView.java
@@ -53,15 +53,18 @@
super(context, attrs);
}
+ @Override
public void setKeyguardCallback(KeyguardSecurityCallback callback) {
mCallback = callback;
}
+ @Override
public void setLockPatternUtils(LockPatternUtils utils) {
mLockPatternUtils = utils;
mEnableHaptics = mLockPatternUtils.isTactileFeedbackEnabled();
}
+ @Override
public void reset() {
// start fresh
resetPasswordText(false /* animate */);
@@ -95,6 +98,7 @@
}
}
+ @Override
public void onEmergencyButtonClickedWhenInCall() {
mCallback.reset();
}
@@ -115,11 +119,11 @@
mPendingLockCheck.cancel(false);
}
- if (entry.length() < MINIMUM_PASSWORD_LENGTH_BEFORE_REPORT) {
+ if (entry.length() <= MINIMUM_PASSWORD_LENGTH_BEFORE_REPORT) {
// to avoid accidental lockout, only count attempts that are long enough to be a
// real password. This may require some tweaking.
setPasswordEntryInputEnabled(true);
- onPasswordChecked(entry, false, 0);
+ onPasswordChecked(false /* matched */, 0, false /* not valid - too short */);
return;
}
@@ -132,24 +136,27 @@
public void onChecked(boolean matched, int timeoutMs) {
setPasswordEntryInputEnabled(true);
mPendingLockCheck = null;
- onPasswordChecked(entry, matched, timeoutMs);
+ onPasswordChecked(matched, timeoutMs, true /* isValidPassword */);
}
});
}
- private void onPasswordChecked(String entry, boolean matched, int timeoutMs) {
+ private void onPasswordChecked(boolean matched, int timeoutMs, boolean isValidPassword) {
if (matched) {
mCallback.reportUnlockAttempt(true, 0);
mCallback.dismiss(true);
} else {
- mCallback.reportUnlockAttempt(false, timeoutMs);
- int attempts = KeyguardUpdateMonitor.getInstance(mContext).getFailedUnlockAttempts();
- if (timeoutMs > 0) {
- long deadline = mLockPatternUtils.setLockoutAttemptDeadline(
- KeyguardUpdateMonitor.getCurrentUser(), timeoutMs);
- handleAttemptLockout(deadline);
+ if (isValidPassword) {
+ mCallback.reportUnlockAttempt(false, timeoutMs);
+ if (timeoutMs > 0) {
+ long deadline = mLockPatternUtils.setLockoutAttemptDeadline(
+ KeyguardUpdateMonitor.getCurrentUser(), timeoutMs);
+ handleAttemptLockout(deadline);
+ }
}
- mSecurityMessageDisplay.setMessage(getWrongPasswordStringId(), true);
+ if (timeoutMs == 0) {
+ mSecurityMessageDisplay.setMessage(getWrongPasswordStringId(), true);
+ }
}
resetPasswordText(true /* animate */);
}
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardPatternView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardPatternView.java
index b000e26..4bd1a2e 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardPatternView.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardPatternView.java
@@ -82,6 +82,7 @@
* Useful for clearing out the wrong pattern after a delay
*/
private Runnable mCancelPatternRunnable = new Runnable() {
+ @Override
public void run() {
mLockPatternView.clearPattern();
}
@@ -117,10 +118,12 @@
R.dimen.disappear_y_translation);
}
+ @Override
public void setKeyguardCallback(KeyguardSecurityCallback callback) {
mCallback = callback;
}
+ @Override
public void setLockPatternUtils(LockPatternUtils utils) {
mLockPatternUtils = utils;
}
@@ -153,6 +156,7 @@
}
}
+ @Override
public void onEmergencyButtonClickedWhenInCall() {
mCallback.reset();
}
@@ -174,6 +178,7 @@
return result;
}
+ @Override
public void reset() {
// reset lock pattern
mLockPatternView.enableInput();
@@ -207,18 +212,22 @@
private class UnlockPatternListener implements LockPatternView.OnPatternListener {
+ @Override
public void onPatternStart() {
mLockPatternView.removeCallbacks(mCancelPatternRunnable);
mSecurityMessageDisplay.setMessage("", false);
}
+ @Override
public void onPatternCleared() {
}
+ @Override
public void onPatternCellAdded(List<LockPatternView.Cell> pattern) {
mCallback.userActivity();
}
+ @Override
public void onPatternDetected(final List<LockPatternView.Cell> pattern) {
mLockPatternView.disableInput();
if (mPendingLockCheck != null) {
@@ -227,7 +236,7 @@
if (pattern.size() < LockPatternUtils.MIN_PATTERN_REGISTER_FAIL) {
mLockPatternView.enableInput();
- onPatternChecked(pattern, false, 0);
+ onPatternChecked(false, 0, false /* not valid - too short */);
return;
}
@@ -240,29 +249,30 @@
public void onChecked(boolean matched, int timeoutMs) {
mLockPatternView.enableInput();
mPendingLockCheck = null;
- onPatternChecked(pattern, matched, timeoutMs);
+ onPatternChecked(matched, timeoutMs, true);
}
});
+ if (pattern.size() > MIN_PATTERN_BEFORE_POKE_WAKELOCK) {
+ mCallback.userActivity();
+ }
}
- private void onPatternChecked(List<LockPatternView.Cell> pattern, boolean matched,
- int timeoutMs) {
+ private void onPatternChecked(boolean matched, int timeoutMs, boolean isValidPattern) {
if (matched) {
mCallback.reportUnlockAttempt(true, 0);
mLockPatternView.setDisplayMode(LockPatternView.DisplayMode.Correct);
mCallback.dismiss(true);
} else {
- if (pattern.size() > MIN_PATTERN_BEFORE_POKE_WAKELOCK) {
- mCallback.userActivity();
- }
mLockPatternView.setDisplayMode(LockPatternView.DisplayMode.Wrong);
- mCallback.reportUnlockAttempt(false, timeoutMs);
- int attempts = mKeyguardUpdateMonitor.getFailedUnlockAttempts();
- if (timeoutMs > 0) {
- long deadline = mLockPatternUtils.setLockoutAttemptDeadline(
- KeyguardUpdateMonitor.getCurrentUser(), timeoutMs);
- handleAttemptLockout(deadline);
- } else {
+ if (isValidPattern) {
+ mCallback.reportUnlockAttempt(false, timeoutMs);
+ if (timeoutMs > 0) {
+ long deadline = mLockPatternUtils.setLockoutAttemptDeadline(
+ KeyguardUpdateMonitor.getCurrentUser(), timeoutMs);
+ handleAttemptLockout(deadline);
+ }
+ }
+ if (timeoutMs == 0) {
mSecurityMessageDisplay.setMessage(R.string.kg_wrong_pattern, true);
mLockPatternView.postDelayed(mCancelPatternRunnable, PATTERN_CLEAR_TIMEOUT_MS);
}
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java
index 3670683..55d85206 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java
@@ -142,6 +142,8 @@
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;
private static KeyguardUpdateMonitor sInstance;
@@ -248,6 +250,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;
}
}
};
@@ -549,6 +557,7 @@
private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
+ @Override
public void onReceive(Context context, Intent intent) {
final String action = intent.getAction();
if (DEBUG) Log.d(TAG, "received broadcast " + action);
@@ -602,6 +611,7 @@
private final BroadcastReceiver mBroadcastAllReceiver = new BroadcastReceiver() {
+ @Override
public void onReceive(Context context, Intent intent) {
final String action = intent.getAction();
if (AlarmManager.ACTION_NEXT_ALARM_CLOCK_CHANGED.equals(action)) {
@@ -716,6 +726,7 @@
return new SimData(state, slotId, subId);
}
+ @Override
public String toString() {
return "SimData{state=" + simState + ",slotId=" + slotId + ",subId=" + subId + "}";
}
@@ -806,6 +817,26 @@
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.
*/
@@ -911,7 +942,9 @@
}
private boolean shouldListenForFingerprint() {
- return mKeyguardIsVisible && !mSwitchingUser;
+ return mKeyguardIsVisible && !mSwitchingUser &&
+ mTrustManager.hasUserAuthenticatedSinceBoot(
+ ActivityManager.getCurrentUser());
}
private void startListeningForFingerprint() {
@@ -1486,12 +1519,14 @@
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() {
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitorCallback.java b/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitorCallback.java
index 0cdf999..6cda2b7 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitorCallback.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitorCallback.java
@@ -161,6 +161,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) { }
diff --git a/packages/MtpDocumentsProvider/src/com/android/mtp/Identifier.java b/packages/MtpDocumentsProvider/src/com/android/mtp/Identifier.java
index aafe884..bd0c837 100644
--- a/packages/MtpDocumentsProvider/src/com/android/mtp/Identifier.java
+++ b/packages/MtpDocumentsProvider/src/com/android/mtp/Identifier.java
@@ -19,14 +19,58 @@
/**
* Static utilities for ID.
*/
-abstract class Identifier {
- // TODO: Make the ID persistent.
- static String createRootId(long deviceId, long storageId) {
- return String.format("%d:%d", deviceId, storageId);
+class Identifier {
+ final int mDeviceId;
+ final int mStorageId;
+ final int mObjectHandle;
+
+ static Identifier createFromRootId(String rootId) {
+ final String[] components = rootId.split("_");
+ return new Identifier(
+ Integer.parseInt(components[0]),
+ Integer.parseInt(components[1]));
+ }
+
+ static Identifier createFromDocumentId(String documentId) {
+ final String[] components = documentId.split("_");
+ return new Identifier(
+ Integer.parseInt(components[0]),
+ Integer.parseInt(components[1]),
+ Integer.parseInt(components[2]));
+ }
+
+
+ Identifier(int deviceId, int storageId) {
+ this(deviceId, storageId, MtpDocument.DUMMY_HANDLE_FOR_ROOT);
+ }
+
+ Identifier(int deviceId, int storageId, int objectHandle) {
+ mDeviceId = deviceId;
+ mStorageId = storageId;
+ mObjectHandle = objectHandle;
}
// TODO: Make the ID persistent.
- static String createDocumentId(String rootId, long objectHandle) {
- return String.format("%s:%d", rootId, objectHandle);
+ String toRootId() {
+ return String.format("%d_%d", mDeviceId, mStorageId);
+ }
+
+ // TODO: Make the ID persistent.
+ String toDocumentId() {
+ return String.format("%d_%d_%d", mDeviceId, mStorageId, mObjectHandle);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (!(obj instanceof Identifier))
+ return false;
+ final Identifier other = (Identifier)obj;
+ return mDeviceId == other.mDeviceId && mStorageId == other.mStorageId &&
+ mObjectHandle == other.mObjectHandle;
+ }
+
+ @Override
+ public int hashCode() {
+ return (mDeviceId << 16) ^ (mStorageId << 8) ^ mObjectHandle;
}
}
diff --git a/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDocument.java b/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDocument.java
index 12eb91e..f6e4276 100644
--- a/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDocument.java
+++ b/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDocument.java
@@ -16,8 +16,103 @@
package com.android.mtp;
+import android.mtp.MtpObjectInfo;
+import android.provider.DocumentsContract;
+import android.provider.DocumentsContract.Document;
+
+import java.util.Date;
+
class MtpDocument {
static final int DUMMY_HANDLE_FOR_ROOT = 0;
- // TODO: Implement model class for MTP document.
+ private final int mObjectHandle;
+ private final int mFormat;
+ private final String mName;
+ private final Date mDateModified;
+ private final int mSize;
+ private final int mThumbSize;
+
+ /**
+ * Constructor for root document.
+ */
+ MtpDocument(MtpRoot root) {
+ this(DUMMY_HANDLE_FOR_ROOT,
+ 0x3001, // Directory.
+ root.mDescription,
+ null, // Unknown,
+ (int) Math.min(root.mMaxCapacity - root.mFreeSpace, Integer.MAX_VALUE),
+ 0);
+ }
+
+ MtpDocument(MtpObjectInfo objectInfo) {
+ this(objectInfo.getObjectHandle(),
+ objectInfo.getFormat(),
+ objectInfo.getName(),
+ objectInfo.getDateModified() != 0 ? new Date(objectInfo.getDateModified()) : null,
+ objectInfo.getCompressedSize(),
+ objectInfo.getThumbCompressedSize());
+ }
+
+ MtpDocument(int objectHandle,
+ int format,
+ String name,
+ Date dateModified,
+ int size,
+ int thumbSize) {
+ this.mObjectHandle = objectHandle;
+ this.mFormat = format;
+ this.mName = name;
+ this.mDateModified = dateModified;
+ this.mSize = size;
+ this.mThumbSize = thumbSize;
+ }
+
+ int getSize() {
+ return mSize;
+ }
+
+ String getMimeType() {
+ // TODO: Add complete list of mime types.
+ switch (mFormat) {
+ case 0x3001:
+ return DocumentsContract.Document.MIME_TYPE_DIR;
+ case 0x3009:
+ return "audio/mp3";
+ case 0x3801:
+ return "image/jpeg";
+ default:
+ return "";
+ }
+ }
+
+ Object[] getRow(Identifier rootIdentifier, String[] columnNames) {
+ final Object[] rows = new Object[columnNames.length];
+ for (int i = 0; i < columnNames.length; i++) {
+ if (Document.COLUMN_DOCUMENT_ID.equals(columnNames[i])) {
+ final Identifier identifier = new Identifier(
+ rootIdentifier.mDeviceId, rootIdentifier.mStorageId, mObjectHandle);
+ rows[i] = identifier.toDocumentId();
+ } else if (Document.COLUMN_DISPLAY_NAME.equals(columnNames[i])) {
+ rows[i] = mName;
+ } else if (Document.COLUMN_MIME_TYPE.equals(columnNames[i])) {
+ rows[i] = getMimeType();
+ } else if (Document.COLUMN_LAST_MODIFIED.equals(columnNames[i])) {
+ rows[i] = mDateModified != null ? mDateModified.getTime() : null;
+ } else if (Document.COLUMN_FLAGS.equals(columnNames[i])) {
+ int flag = 0;
+ if (mObjectHandle != DUMMY_HANDLE_FOR_ROOT) {
+ flag |= DocumentsContract.Document.FLAG_SUPPORTS_DELETE;
+ if (mThumbSize > 0) {
+ flag |= DocumentsContract.Document.FLAG_SUPPORTS_THUMBNAIL;
+ }
+ }
+ rows[i] = flag;
+ } else if (Document.COLUMN_SIZE.equals(columnNames[i])) {
+ rows[i] = mSize;
+ } else {
+ rows[i] = null;
+ }
+ }
+ return rows;
+ }
}
diff --git a/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDocumentsProvider.java b/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDocumentsProvider.java
index 58203c2..c9db29e 100644
--- a/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDocumentsProvider.java
+++ b/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDocumentsProvider.java
@@ -17,8 +17,10 @@
package com.android.mtp;
import android.content.ContentResolver;
+import android.content.res.AssetFileDescriptor;
import android.database.Cursor;
import android.database.MatrixCursor;
+import android.graphics.Point;
import android.os.CancellationSignal;
import android.os.ParcelFileDescriptor;
import android.provider.DocumentsContract;
@@ -53,6 +55,7 @@
private MtpManager mMtpManager;
private ContentResolver mResolver;
+ private PipeManager mPipeManager;
/**
* Provides singleton instance to MtpDocumentsService.
@@ -66,6 +69,8 @@
sSingleton = this;
mMtpManager = new MtpManager(getContext());
mResolver = getContext().getContentResolver();
+ mPipeManager = new PipeManager();
+
return true;
}
@@ -87,14 +92,14 @@
// TODO: Add retry logic here.
for (final MtpRoot root : roots) {
- final String rootId = Identifier.createRootId(deviceId, root.mStorageId);
+ final Identifier rootIdentifier = new Identifier(deviceId, root.mStorageId);
final MatrixCursor.RowBuilder builder = cursor.newRow();
- builder.add(Root.COLUMN_ROOT_ID, rootId);
+ builder.add(Root.COLUMN_ROOT_ID, rootIdentifier.toRootId());
builder.add(Root.COLUMN_FLAGS, Root.FLAG_SUPPORTS_IS_CHILD);
builder.add(Root.COLUMN_TITLE, root.mDescription);
builder.add(
Root.COLUMN_DOCUMENT_ID,
- Identifier.createDocumentId(rootId, MtpDocument.DUMMY_HANDLE_FOR_ROOT));
+ rootIdentifier.toDocumentId());
builder.add(Root.COLUMN_AVAILABLE_BYTES , root.mFreeSpace);
}
} catch (IOException error) {
@@ -109,20 +114,98 @@
@Override
public Cursor queryDocument(String documentId, String[] projection)
throws FileNotFoundException {
+ if (projection == null) {
+ projection = MtpDocumentsProvider.DEFAULT_DOCUMENT_PROJECTION;
+ }
+ final Identifier identifier = Identifier.createFromDocumentId(documentId);
+
+ MtpDocument document = null;
+ if (identifier.mObjectHandle != MtpDocument.DUMMY_HANDLE_FOR_ROOT) {
+ try {
+ document = mMtpManager.getDocument(identifier.mDeviceId, identifier.mObjectHandle);
+ } catch (IOException e) {
+ throw new FileNotFoundException(e.getMessage());
+ }
+ } else {
+ MtpRoot[] roots;
+ try {
+ roots = mMtpManager.getRoots(identifier.mDeviceId);
+ if (roots != null) {
+ for (final MtpRoot root : roots) {
+ if (identifier.mStorageId == root.mStorageId) {
+ document = new MtpDocument(root);
+ break;
+ }
+ }
+ }
+ if (document == null) {
+ throw new FileNotFoundException();
+ }
+ } catch (IOException e) {
+ throw new FileNotFoundException(e.getMessage());
+ }
+ }
+
+ final MatrixCursor cursor = new MatrixCursor(projection);
+ cursor.addRow(document.getRow(
+ new Identifier(identifier.mDeviceId, identifier.mStorageId),
+ projection));
+ return cursor;
+ }
+
+ @Override
+ public Cursor queryChildDocuments(
+ String parentDocumentId, String[] projection, String sortOrder)
+ throws FileNotFoundException {
throw new FileNotFoundException();
}
@Override
- public Cursor queryChildDocuments(String parentDocumentId,
- String[] projection, String sortOrder)
- throws FileNotFoundException {
- throw new FileNotFoundException();
+ public ParcelFileDescriptor openDocument(
+ String documentId, String mode, CancellationSignal signal)
+ throws FileNotFoundException {
+ if (!"r".equals(mode) && !"w".equals(mode)) {
+ // TODO: Support seekable file.
+ throw new UnsupportedOperationException("The provider does not support seekable file.");
+ }
+ final Identifier identifier = Identifier.createFromDocumentId(documentId);
+ try {
+ final MtpDocument document =
+ mMtpManager.getDocument(identifier.mDeviceId, identifier.mObjectHandle);
+ return mPipeManager.readDocument(mMtpManager, identifier);
+ } catch (IOException error) {
+ throw new FileNotFoundException(error.getMessage());
+ }
}
@Override
- public ParcelFileDescriptor openDocument(String documentId, String mode,
+ public AssetFileDescriptor openDocumentThumbnail(
+ String documentId,
+ Point sizeHint,
CancellationSignal signal) throws FileNotFoundException {
- throw new FileNotFoundException();
+ final Identifier identifier = Identifier.createFromDocumentId(documentId);
+ try {
+ return new AssetFileDescriptor(
+ mPipeManager.readThumbnail(mMtpManager, identifier),
+ 0,
+ AssetFileDescriptor.UNKNOWN_LENGTH);
+ } catch (IOException error) {
+ throw new FileNotFoundException(error.getMessage());
+ }
+ }
+
+ @Override
+ public void deleteDocument(String documentId) throws FileNotFoundException {
+ try {
+ final Identifier identifier = Identifier.createFromDocumentId(documentId);
+ final int parentHandle =
+ mMtpManager.getParent(identifier.mDeviceId, identifier.mObjectHandle);
+ mMtpManager.deleteDocument(identifier.mDeviceId, identifier.mObjectHandle);
+ notifyChildDocumentsChange(new Identifier(
+ identifier.mDeviceId, identifier.mStorageId, parentHandle).toDocumentId());
+ } catch (IOException error) {
+ throw new FileNotFoundException(error.getMessage());
+ }
}
void openDevice(int deviceId) throws IOException {
@@ -156,7 +239,12 @@
private void notifyRootsChange() {
mResolver.notifyChange(
- DocumentsContract.buildRootsUri(MtpDocumentsProvider.AUTHORITY),
+ DocumentsContract.buildRootsUri(MtpDocumentsProvider.AUTHORITY), null, false);
+ }
+
+ private void notifyChildDocumentsChange(String parentDocumentId) {
+ mResolver.notifyChange(
+ DocumentsContract.buildChildDocumentsUri(AUTHORITY, parentDocumentId),
null,
false);
}
diff --git a/packages/MtpDocumentsProvider/src/com/android/mtp/MtpManager.java b/packages/MtpDocumentsProvider/src/com/android/mtp/MtpManager.java
index 05e3a72..d4ee668 100644
--- a/packages/MtpDocumentsProvider/src/com/android/mtp/MtpManager.java
+++ b/packages/MtpDocumentsProvider/src/com/android/mtp/MtpManager.java
@@ -21,8 +21,10 @@
import android.hardware.usb.UsbDeviceConnection;
import android.hardware.usb.UsbManager;
import android.mtp.MtpDevice;
+import android.os.ParcelFileDescriptor;
import android.util.SparseArray;
+import java.io.FileNotFoundException;
import java.io.IOException;
/**
@@ -98,6 +100,43 @@
return results;
}
+ synchronized MtpDocument getDocument(int deviceId, int objectHandle) throws IOException {
+ final MtpDevice device = getDevice(deviceId);
+ return new MtpDocument(device.getObjectInfo(objectHandle));
+ }
+
+ synchronized byte[] getObject(int deviceId, int objectHandle, int expectedSize)
+ throws IOException {
+ final MtpDevice device = getDevice(deviceId);
+ return device.getObject(objectHandle, expectedSize);
+ }
+
+ synchronized byte[] getThumbnail(int deviceId, int objectHandle) throws IOException {
+ final MtpDevice device = getDevice(deviceId);
+ return device.getThumbnail(objectHandle);
+ }
+
+ synchronized void deleteDocument(int deviceId, int objectHandle) throws IOException {
+ final MtpDevice device = getDevice(deviceId);
+ if (!device.deleteObject(objectHandle)) {
+ throw new IOException("Failed to delete document");
+ }
+ }
+
+ synchronized int getParent(int deviceId, int objectHandle) throws IOException {
+ final MtpDevice device = getDevice(deviceId);
+ final int result = (int) device.getParent(objectHandle);
+ if (result < 0) {
+ throw new FileNotFoundException("Not found parent object");
+ }
+ return result;
+ }
+
+ synchronized void importFile(int deviceId, int objectHandle, ParcelFileDescriptor target)
+ throws IOException {
+ throw new UnsupportedOperationException("Importing files is not supported.");
+ }
+
private MtpDevice getDevice(int deviceId) throws IOException {
final MtpDevice device = mDevices.get(deviceId);
if (device == null) {
diff --git a/packages/MtpDocumentsProvider/src/com/android/mtp/MtpRoot.java b/packages/MtpDocumentsProvider/src/com/android/mtp/MtpRoot.java
index ab16882..fb160aa 100644
--- a/packages/MtpDocumentsProvider/src/com/android/mtp/MtpRoot.java
+++ b/packages/MtpDocumentsProvider/src/com/android/mtp/MtpRoot.java
@@ -21,14 +21,14 @@
import com.android.internal.annotations.VisibleForTesting;
class MtpRoot {
- final long mStorageId;
+ final int mStorageId;
final String mDescription;
final long mFreeSpace;
final long mMaxCapacity;
final String mVolumeIdentifier;
@VisibleForTesting
- MtpRoot(long storageId,
+ MtpRoot(int storageId,
String description,
long freeSpace,
long maxCapacity,
diff --git a/packages/MtpDocumentsProvider/src/com/android/mtp/PipeManager.java b/packages/MtpDocumentsProvider/src/com/android/mtp/PipeManager.java
new file mode 100644
index 0000000..7f498f5
--- /dev/null
+++ b/packages/MtpDocumentsProvider/src/com/android/mtp/PipeManager.java
@@ -0,0 +1,112 @@
+/*
+ * 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.mtp;
+
+import android.os.ParcelFileDescriptor;
+import android.util.Log;
+
+import java.io.IOException;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+
+class PipeManager {
+ final ExecutorService mExecutor;
+
+ PipeManager() {
+ this(Executors.newCachedThreadPool());
+ }
+
+ PipeManager(ExecutorService executor) {
+ this.mExecutor = executor;
+ }
+
+ ParcelFileDescriptor readDocument(MtpManager model, Identifier identifier) throws IOException {
+ final Task task = new ImportFileTask(model, identifier);
+ mExecutor.execute(task);
+ return task.getReadingFileDescriptor();
+ }
+
+ ParcelFileDescriptor readThumbnail(MtpManager model, Identifier identifier) throws IOException {
+ final Task task = new GetThumbnailTask(model, identifier);
+ mExecutor.execute(task);
+ return task.getReadingFileDescriptor();
+ }
+
+ private static abstract class Task implements Runnable {
+ protected final MtpManager mModel;
+ protected final Identifier mIdentifier;
+ protected final ParcelFileDescriptor[] mDescriptors;
+
+ Task(MtpManager model, Identifier identifier) throws IOException {
+ mModel = model;
+ mIdentifier = identifier;
+ mDescriptors = ParcelFileDescriptor.createReliablePipe();
+ }
+
+ ParcelFileDescriptor getReadingFileDescriptor() {
+ return mDescriptors[0];
+ }
+ }
+
+ private static class ImportFileTask extends Task {
+ ImportFileTask(MtpManager model, Identifier identifier) throws IOException {
+ super(model, identifier);
+ }
+
+ @Override
+ public void run() {
+ try {
+ mModel.importFile(
+ mIdentifier.mDeviceId, mIdentifier.mObjectHandle, mDescriptors[1]);
+ mDescriptors[1].close();
+ } catch (IOException error) {
+ try {
+ mDescriptors[1].closeWithError("Failed to stream a file.");
+ } catch (IOException closeError) {
+ Log.w(MtpDocumentsProvider.TAG, closeError.getMessage());
+ }
+ }
+ }
+ }
+
+ private static class GetThumbnailTask extends Task {
+ GetThumbnailTask(MtpManager model, Identifier identifier) throws IOException {
+ super(model, identifier);
+ }
+
+ @Override
+ public void run() {
+ try {
+ try (final ParcelFileDescriptor.AutoCloseOutputStream stream =
+ new ParcelFileDescriptor.AutoCloseOutputStream(mDescriptors[1])) {
+ try {
+ stream.write(mModel.getThumbnail(
+ mIdentifier.mDeviceId, mIdentifier.mObjectHandle));
+ } catch (IOException error) {
+ mDescriptors[1].closeWithError("Failed to stream a thumbnail.");
+ }
+ }
+ } catch (IOException closeError) {
+ Log.w(MtpDocumentsProvider.TAG, closeError.getMessage());
+ }
+ }
+ }
+
+ void close() {
+ mExecutor.shutdown();
+ }
+}
diff --git a/packages/MtpDocumentsProvider/tests/src/com/android/mtp/MtpDocumentsProviderTest.java b/packages/MtpDocumentsProvider/tests/src/com/android/mtp/MtpDocumentsProviderTest.java
index b86b2e2..3fad63f 100644
--- a/packages/MtpDocumentsProvider/tests/src/com/android/mtp/MtpDocumentsProviderTest.java
+++ b/packages/MtpDocumentsProvider/tests/src/com/android/mtp/MtpDocumentsProviderTest.java
@@ -19,36 +19,43 @@
import android.database.ContentObserver;
import android.database.Cursor;
import android.net.Uri;
+import android.provider.DocumentsContract;
import android.provider.DocumentsContract.Root;
import android.test.AndroidTestCase;
import android.test.mock.MockContentResolver;
import android.test.suitebuilder.annotation.SmallTest;
+import java.io.FileNotFoundException;
import java.io.IOException;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
@SmallTest
public class MtpDocumentsProviderTest extends AndroidTestCase {
private ContentResolver mResolver;
private MtpDocumentsProvider mProvider;
- private MtpManagerMock mMtpManager;
+ private TestMtpManager mMtpManager;
@Override
public void setUp() {
mResolver = new ContentResolver();
- mMtpManager = new MtpManagerMock(getContext());
+ mMtpManager = new TestMtpManager(getContext());
mProvider = new MtpDocumentsProvider();
mProvider.onCreateForTesting(mMtpManager, mResolver);
}
public void testOpenAndCloseDevice() throws Exception {
+ final Uri uri = DocumentsContract.buildRootsUri(MtpDocumentsProvider.AUTHORITY);
+
mMtpManager.addValidDevice(0);
- assertEquals(0, mResolver.changeCount);
+ assertEquals(0, mResolver.getChangeCount(uri));
mProvider.openDevice(0);
- assertEquals(1, mResolver.changeCount);
+ assertEquals(1, mResolver.getChangeCount(uri));
mProvider.closeDevice(0);
- assertEquals(2, mResolver.changeCount);
+ assertEquals(2, mResolver.getChangeCount(uri));
int exceptionCounter = 0;
try {
@@ -56,28 +63,29 @@
} catch (IOException error) {
exceptionCounter++;
}
- assertEquals(2, mResolver.changeCount);
+ assertEquals(2, mResolver.getChangeCount(uri));
try {
mProvider.closeDevice(1);
} catch (IOException error) {
exceptionCounter++;
}
- assertEquals(2, mResolver.changeCount);
+ assertEquals(2, mResolver.getChangeCount(uri));
assertEquals(2, exceptionCounter);
}
public void testCloseAllDevices() throws IOException {
+ final Uri uri = DocumentsContract.buildRootsUri(MtpDocumentsProvider.AUTHORITY);
+
mMtpManager.addValidDevice(0);
- mProvider.onCreateForTesting(mMtpManager, mResolver);
mProvider.closeAllDevices();
- assertEquals(0, mResolver.changeCount);
+ assertEquals(0, mResolver.getChangeCount(uri));
mProvider.openDevice(0);
- assertEquals(1, mResolver.changeCount);
+ assertEquals(1, mResolver.getChangeCount(uri));
mProvider.closeAllDevices();
- assertEquals(2, mResolver.changeCount);
+ assertEquals(2, mResolver.getChangeCount(uri));
}
public void testQueryRoots() throws Exception {
@@ -99,7 +107,6 @@
4096 /* total space */,
"Identifier B" /* no volume identifier */)
});
- mProvider.onCreateForTesting(mMtpManager, mResolver);
assertEquals(0, mProvider.queryRoots(null).getCount());
{
@@ -107,12 +114,12 @@
final Cursor cursor = mProvider.queryRoots(null);
assertEquals(1, cursor.getCount());
cursor.moveToNext();
- assertEquals("0:1", cursor.getString(0));
+ assertEquals("0_1", cursor.getString(0));
assertEquals(Root.FLAG_SUPPORTS_IS_CHILD, cursor.getInt(1));
// TODO: Add storage icon for MTP devices.
assertTrue(cursor.isNull(2) /* icon */);
assertEquals("Storage A", cursor.getString(3));
- assertEquals("0:1:0", cursor.getString(4));
+ assertEquals("0_1_0", cursor.getString(4));
assertEquals(1024, cursor.getInt(5));
}
@@ -122,12 +129,12 @@
assertEquals(2, cursor.getCount());
cursor.moveToNext();
cursor.moveToNext();
- assertEquals("1:1", cursor.getString(0));
+ assertEquals("1_1", cursor.getString(0));
assertEquals(Root.FLAG_SUPPORTS_IS_CHILD, cursor.getInt(1));
// TODO: Add storage icon for MTP devices.
assertTrue(cursor.isNull(2) /* icon */);
assertEquals("Storage B", cursor.getString(3));
- assertEquals("1:1:0", cursor.getString(4));
+ assertEquals("1_1_0", cursor.getString(4));
assertEquals(2048, cursor.getInt(5));
}
@@ -150,29 +157,108 @@
4096 /* total space */,
"Identifier B" /* no volume identifier */)
});
- mProvider.onCreateForTesting(mMtpManager, mResolver);
{
mProvider.openDevice(0);
mProvider.openDevice(1);
final Cursor cursor = mProvider.queryRoots(null);
assertEquals(1, cursor.getCount());
cursor.moveToNext();
- assertEquals("1:1", cursor.getString(0));
+ assertEquals("1_1", cursor.getString(0));
assertEquals(Root.FLAG_SUPPORTS_IS_CHILD, cursor.getInt(1));
// TODO: Add storage icon for MTP devices.
assertTrue(cursor.isNull(2) /* icon */);
assertEquals("Storage B", cursor.getString(3));
- assertEquals("1:1:0", cursor.getString(4));
+ assertEquals("1_1_0", cursor.getString(4));
assertEquals(2048, cursor.getInt(5));
}
}
+ public void testQueryDocument() throws IOException {
+ mMtpManager.setDocument(0, 2, new MtpDocument(
+ 2 /* object handle */,
+ 0x3801 /* JPEG */,
+ "image.jpg" /* display name */,
+ new Date(1422716400000L) /* modified date */,
+ 1024 * 1024 * 5 /* file size */,
+ 1024 * 50 /* thumbnail size */));
+ final Cursor cursor = mProvider.queryDocument("0_1_2", null);
+ assertEquals(1, cursor.getCount());
+
+ cursor.moveToNext();
+ assertEquals("0_1_2", cursor.getString(0));
+ assertEquals("image/jpeg", cursor.getString(1));
+ assertEquals("image.jpg", cursor.getString(2));
+ assertEquals(1422716400000L, cursor.getLong(3));
+ assertEquals(
+ DocumentsContract.Document.FLAG_SUPPORTS_DELETE |
+ DocumentsContract.Document.FLAG_SUPPORTS_THUMBNAIL,
+ cursor.getInt(4));
+ assertEquals(1024 * 1024 * 5, cursor.getInt(5));
+ }
+
+ public void testQueryDocument_forRoot() throws IOException {
+ mMtpManager.setRoots(0, new MtpRoot[] {
+ new MtpRoot(
+ 1 /* storageId */,
+ "Storage A" /* volume description */,
+ 1024 /* free space */,
+ 4096 /* total space */,
+ "" /* no volume identifier */)
+ });
+ final Cursor cursor = mProvider.queryDocument("0_1_0", null);
+ assertEquals(1, cursor.getCount());
+
+ cursor.moveToNext();
+ assertEquals("0_1_0", cursor.getString(0));
+ assertEquals(DocumentsContract.Document.MIME_TYPE_DIR, cursor.getString(1));
+ assertEquals("Storage A", cursor.getString(2));
+ assertTrue(cursor.isNull(3));
+ assertEquals(0, cursor.getInt(4));
+ assertEquals(3072, cursor.getInt(5));
+ }
+
+ public void testDeleteDocument() throws FileNotFoundException {
+ mMtpManager.setDocument(0, 1, new MtpDocument(
+ 1 /* object handle */,
+ 0x3801 /* JPEG */,
+ "image.jpg" /* display name */,
+ new Date(1422716400000L) /* modified date */,
+ 1024 * 1024 * 5 /* file size */,
+ 1024 * 50 /* thumbnail size */));
+ mMtpManager.setParent(0, 1, 2);
+ mProvider.deleteDocument("0_0_1");
+ assertEquals(1, mResolver.getChangeCount(
+ DocumentsContract.buildChildDocumentsUri(
+ MtpDocumentsProvider.AUTHORITY, "0_0_2")));
+ }
+
+ public void testDeleteDocument_error() throws FileNotFoundException {
+ mMtpManager.setParent(0, 1, 2);
+ try {
+ mProvider.deleteDocument("0_0_1");
+ fail();
+ } catch (Throwable e) {
+ assertTrue(e instanceof IOException);
+ }
+ assertEquals(0, mResolver.getChangeCount(
+ DocumentsContract.buildChildDocumentsUri(
+ MtpDocumentsProvider.AUTHORITY, "0_0_2")));
+ }
+
private static class ContentResolver extends MockContentResolver {
- int changeCount = 0;
+ final Map<Uri, Integer> mChangeCounts = new HashMap<Uri, Integer>();
@Override
public void notifyChange(Uri uri, ContentObserver observer, boolean syncToNetwork) {
- changeCount++;
+ mChangeCounts.put(uri, getChangeCount(uri) + 1);
+ }
+
+ int getChangeCount(Uri uri) {
+ if (mChangeCounts.containsKey(uri)) {
+ return mChangeCounts.get(uri);
+ } else {
+ return 0;
+ }
}
}
}
diff --git a/packages/MtpDocumentsProvider/tests/src/com/android/mtp/MtpManagerMock.java b/packages/MtpDocumentsProvider/tests/src/com/android/mtp/MtpManagerMock.java
deleted file mode 100644
index 82db552..0000000
--- a/packages/MtpDocumentsProvider/tests/src/com/android/mtp/MtpManagerMock.java
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.mtp;
-
-import android.content.Context;
-
-import java.io.IOException;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-import java.util.TreeSet;
-
-public class MtpManagerMock extends MtpManager {
- private final Set<Integer> mValidDevices = new HashSet<Integer>();
- private final Set<Integer> mOpenedDevices = new TreeSet<Integer>();
- private final Map<Integer, MtpRoot[]> mRoots = new HashMap<Integer, MtpRoot[]>();
-
- MtpManagerMock(Context context) {
- super(context);
- }
-
- void addValidDevice(int deviceId) {
- mValidDevices.add(deviceId);
- }
-
- void setRoots(int deviceId, MtpRoot[] roots) {
- mRoots.put(deviceId, roots);
- }
-
- @Override
- void openDevice(int deviceId) throws IOException {
- if (!mValidDevices.contains(deviceId) || mOpenedDevices.contains(deviceId)) {
- throw new IOException();
- }
- mOpenedDevices.add(deviceId);
- }
-
- @Override
- void closeDevice(int deviceId) throws IOException {
- if (!mValidDevices.contains(deviceId) || !mOpenedDevices.contains(deviceId)) {
- throw new IOException();
- }
- mOpenedDevices.remove(deviceId);
- }
-
- @Override
- MtpRoot[] getRoots(int deviceId) throws IOException {
- if (mRoots.containsKey(deviceId)) {
- return mRoots.get(deviceId);
- } else {
- throw new IOException("getRoots error");
- }
- }
-
- @Override
- int[] getOpenedDeviceIds() {
- int i = 0;
- final int[] result = new int[mOpenedDevices.size()];
- for (int deviceId : mOpenedDevices) {
- result[i++] = deviceId;
- }
- return result;
- }
-}
diff --git a/packages/MtpDocumentsProvider/tests/src/com/android/mtp/PipeManagerTest.java b/packages/MtpDocumentsProvider/tests/src/com/android/mtp/PipeManagerTest.java
new file mode 100644
index 0000000..35918e1
--- /dev/null
+++ b/packages/MtpDocumentsProvider/tests/src/com/android/mtp/PipeManagerTest.java
@@ -0,0 +1,92 @@
+/*
+ * 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.mtp;
+
+import android.os.ParcelFileDescriptor;
+import android.test.AndroidTestCase;
+import android.test.suitebuilder.annotation.SmallTest;
+
+import java.io.IOException;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.TimeUnit;
+
+@SmallTest
+public class PipeManagerTest extends AndroidTestCase {
+ private static final byte[] HELLO_BYTES = new byte[] { 'h', 'e', 'l', 'l', 'o' };
+
+ private TestMtpManager mtpManager;
+ private ExecutorService executor;
+ private PipeManager pipeManager;
+
+ @Override
+ public void setUp() {
+ mtpManager = new TestMtpManager(getContext());
+ executor = Executors.newSingleThreadExecutor();
+ pipeManager = new PipeManager(executor);
+ }
+
+ public void testReadDocument_basic() throws Exception {
+ mtpManager.setImportFileBytes(0, 1, HELLO_BYTES);
+ final ParcelFileDescriptor descriptor = pipeManager.readDocument(
+ mtpManager, new Identifier(0, 0, 1));
+ assertDescriptor(descriptor, HELLO_BYTES);
+ }
+
+ public void testReadDocument_error() throws Exception {
+ final ParcelFileDescriptor descriptor =
+ pipeManager.readDocument(mtpManager, new Identifier(0, 0, 1));
+ assertDescriptorError(descriptor);
+ }
+
+ public void testReadThumbnail_basic() throws Exception {
+ mtpManager.setThumbnail(0, 1, HELLO_BYTES);
+ final ParcelFileDescriptor descriptor = pipeManager.readThumbnail(
+ mtpManager, new Identifier(0, 0, 1));
+ assertDescriptor(descriptor, HELLO_BYTES);
+ }
+
+ public void testReadThumbnail_error() throws Exception {
+ final ParcelFileDescriptor descriptor =
+ pipeManager.readThumbnail(mtpManager, new Identifier(0, 0, 1));
+ assertDescriptorError(descriptor);
+ }
+
+ private void assertDescriptor(ParcelFileDescriptor descriptor, byte[] expectedBytes)
+ throws IOException, InterruptedException {
+ executor.awaitTermination(1000, TimeUnit.MILLISECONDS);
+ try (final ParcelFileDescriptor.AutoCloseInputStream stream =
+ new ParcelFileDescriptor.AutoCloseInputStream(descriptor)) {
+ byte[] results = new byte[100];
+ assertEquals(expectedBytes.length, stream.read(results));
+ for (int i = 0; i < expectedBytes.length; i++) {
+ assertEquals(expectedBytes[i], results[i]);
+ }
+ }
+ }
+
+ private void assertDescriptorError(ParcelFileDescriptor descriptor)
+ throws InterruptedException {
+ executor.awaitTermination(1000, TimeUnit.MILLISECONDS);
+ try {
+ descriptor.checkError();
+ fail();
+ } catch (Throwable error) {
+ assertTrue(error instanceof IOException);
+ }
+ }
+}
diff --git a/packages/MtpDocumentsProvider/tests/src/com/android/mtp/TestMtpManager.java b/packages/MtpDocumentsProvider/tests/src/com/android/mtp/TestMtpManager.java
new file mode 100644
index 0000000..725b765
--- /dev/null
+++ b/packages/MtpDocumentsProvider/tests/src/com/android/mtp/TestMtpManager.java
@@ -0,0 +1,153 @@
+/*
+ * 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.mtp;
+
+import android.content.Context;
+import android.os.ParcelFileDescriptor;
+
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeSet;
+
+public class TestMtpManager extends MtpManager {
+ private static String pack(int... args) {
+ return Arrays.toString(args);
+ }
+
+ private final Set<Integer> mValidDevices = new HashSet<Integer>();
+ private final Set<Integer> mOpenedDevices = new TreeSet<Integer>();
+ private final Map<Integer, MtpRoot[]> mRoots = new HashMap<Integer, MtpRoot[]>();
+ private final Map<String, MtpDocument> mDocuments = new HashMap<String, MtpDocument>();
+ private final Map<String, byte[]> mThumbnailBytes = new HashMap<String, byte[]>();
+ private final Map<String, Integer> mParents = new HashMap<String, Integer>();
+ private final Map<String, byte[]> mImportFileBytes = new HashMap<String, byte[]>();
+
+ TestMtpManager(Context context) {
+ super(context);
+ }
+
+ void addValidDevice(int deviceId) {
+ mValidDevices.add(deviceId);
+ }
+
+ void setRoots(int deviceId, MtpRoot[] roots) {
+ mRoots.put(deviceId, roots);
+ }
+
+ void setDocument(int deviceId, int objectHandle, MtpDocument document) {
+ mDocuments.put(pack(deviceId, objectHandle), document);
+ }
+
+ void setImportFileBytes(int deviceId, int objectHandle, byte[] bytes) {
+ mImportFileBytes.put(pack(deviceId, objectHandle), bytes);
+ }
+
+ void setThumbnail(int deviceId, int objectHandle, byte[] bytes) {
+ mThumbnailBytes.put(pack(deviceId, objectHandle), bytes);
+ }
+
+ void setParent(int deviceId, int objectHandle, int parentObjectHandle) {
+ mParents.put(pack(deviceId, objectHandle), parentObjectHandle);
+ }
+
+ @Override
+ void openDevice(int deviceId) throws IOException {
+ if (!mValidDevices.contains(deviceId) || mOpenedDevices.contains(deviceId)) {
+ throw new IOException();
+ }
+ mOpenedDevices.add(deviceId);
+ }
+
+ @Override
+ void closeDevice(int deviceId) throws IOException {
+ if (!mValidDevices.contains(deviceId) || !mOpenedDevices.contains(deviceId)) {
+ throw new IOException();
+ }
+ mOpenedDevices.remove(deviceId);
+ }
+
+ @Override
+ MtpRoot[] getRoots(int deviceId) throws IOException {
+ if (mRoots.containsKey(deviceId)) {
+ return mRoots.get(deviceId);
+ } else {
+ throw new IOException("getRoots error");
+ }
+ }
+
+ @Override
+ MtpDocument getDocument(int deviceId, int objectHandle) {
+ return mDocuments.get(pack(deviceId, objectHandle));
+ }
+
+ @Override
+ void importFile(int deviceId, int storageId, ParcelFileDescriptor target) throws IOException {
+ final String key = pack(deviceId, storageId);
+ if (mImportFileBytes.containsKey(key)) {
+ try (final ParcelFileDescriptor.AutoCloseOutputStream outputStream =
+ new ParcelFileDescriptor.AutoCloseOutputStream(target)) {
+ outputStream.write(mImportFileBytes.get(key));
+ }
+ } else {
+ throw new IOException("importFile error: " + key);
+ }
+ }
+
+ @Override
+ byte[] getThumbnail(int deviceId, int objectHandle) throws IOException {
+ final String key = pack(deviceId, objectHandle);
+ if (mThumbnailBytes.containsKey(key)) {
+ return mThumbnailBytes.get(key);
+ } else {
+ throw new IOException("getThumbnail error: " + key);
+ }
+ }
+
+ @Override
+ void deleteDocument(int deviceId, int objectHandle) throws IOException {
+ final String key = pack(deviceId, objectHandle);
+ if (mDocuments.containsKey(key)) {
+ mDocuments.remove(key);
+ } else {
+ throw new IOException();
+ }
+ }
+
+ @Override
+ synchronized int getParent(int deviceId, int objectHandle) throws IOException {
+ final String key = pack(deviceId, objectHandle);
+ if (mParents.containsKey(key)) {
+ return mParents.get(key);
+ } else {
+ throw new IOException();
+ }
+ }
+
+ @Override
+ int[] getOpenedDeviceIds() {
+ int i = 0;
+ final int[] result = new int[mOpenedDevices.size()];
+ for (int deviceId : mOpenedDevices) {
+ result[i++] = deviceId;
+ }
+ return result;
+ }
+}
diff --git a/packages/PrintSpooler/src/com/android/printspooler/model/PrintSpoolerService.java b/packages/PrintSpooler/src/com/android/printspooler/model/PrintSpoolerService.java
index 49e6740..bafccae 100644
--- a/packages/PrintSpooler/src/com/android/printspooler/model/PrintSpoolerService.java
+++ b/packages/PrintSpooler/src/com/android/printspooler/model/PrintSpoolerService.java
@@ -46,6 +46,7 @@
import android.util.Slog;
import android.util.Xml;
+import com.android.internal.logging.MetricsLogger;
import com.android.internal.os.HandlerCaller;
import com.android.internal.util.FastXmlSerializer;
import com.android.printspooler.R;
@@ -493,6 +494,7 @@
Slog.i(LOG_TAG, "[STATE CHANGED] " + printJob);
}
+ MetricsLogger.histogram(this, "print_job_state", state);
switch (state) {
case PrintJobInfo.STATE_COMPLETED:
case PrintJobInfo.STATE_CANCELED:
diff --git a/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java b/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java
index 6baa4b3..e8a5e43 100644
--- a/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java
+++ b/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java
@@ -72,6 +72,7 @@
import android.widget.Spinner;
import android.widget.TextView;
+import com.android.internal.logging.MetricsLogger;
import com.android.printspooler.R;
import com.android.printspooler.model.MutexFileProvider;
import com.android.printspooler.model.PrintSpoolerProvider;
@@ -325,6 +326,7 @@
if (mState != STATE_INITIALIZING && mCurrentPrinter != null) {
mPrinterRegistry.setTrackedPrinter(mCurrentPrinter.getId());
}
+ MetricsLogger.count(this, "print_preview", 1);
}
@Override
@@ -1074,6 +1076,8 @@
private void confirmPrint() {
setState(STATE_PRINT_CONFIRMED);
+ MetricsLogger.count(this, "print_confirmed", 1);
+
updateOptionsUi();
addCurrentPrinterToHistory();
diff --git a/packages/SettingsLib/src/com/android/settingslib/TetherUtil.java b/packages/SettingsLib/src/com/android/settingslib/TetherUtil.java
index 58e5e29a..096a5c4 100644
--- a/packages/SettingsLib/src/com/android/settingslib/TetherUtil.java
+++ b/packages/SettingsLib/src/com/android/settingslib/TetherUtil.java
@@ -23,7 +23,7 @@
import android.net.ConnectivityManager;
import android.net.wifi.WifiManager;
import android.os.SystemProperties;
-import android.os.UserHandle;
+import android.os.UserManager;
import android.provider.Settings;
public class TetherUtil {
@@ -99,8 +99,9 @@
public static boolean isTetheringSupported(Context context) {
final ConnectivityManager cm =
(ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
- final boolean isSecondaryUser = ActivityManager.getCurrentUser() != UserHandle.USER_OWNER;
- return !isSecondaryUser && cm.isTetheringSupported();
+ final boolean isAdminUser =
+ UserManager.get(context).isUserAdmin(ActivityManager.getCurrentUser());
+ return isAdminUser && cm.isTetheringSupported();
}
}
diff --git a/packages/SettingsLib/src/com/android/settingslib/applications/ApplicationsState.java b/packages/SettingsLib/src/com/android/settingslib/applications/ApplicationsState.java
index 9eb7d0e..c9a5f8f 100644
--- a/packages/SettingsLib/src/com/android/settingslib/applications/ApplicationsState.java
+++ b/packages/SettingsLib/src/com/android/settingslib/applications/ApplicationsState.java
@@ -30,6 +30,7 @@
import android.content.pm.PackageStats;
import android.content.pm.ParceledListSlice;
import android.content.pm.ResolveInfo;
+import android.content.pm.UserInfo;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Handler;
@@ -88,7 +89,7 @@
final PackageManager mPm;
final IPackageManager mIpm;
final UserManager mUm;
- final int mOwnerRetrieveFlags;
+ final int mAdminRetrieveFlags;
final int mRetrieveFlags;
PackageIntentReceiver mPackageIntentReceiver;
@@ -131,7 +132,7 @@
mBackgroundHandler = new BackgroundHandler(mThread.getLooper());
// Only the owner can see all apps.
- mOwnerRetrieveFlags = PackageManager.GET_UNINSTALLED_PACKAGES |
+ mAdminRetrieveFlags = PackageManager.GET_UNINSTALLED_PACKAGES |
PackageManager.GET_DISABLED_COMPONENTS |
PackageManager.GET_DISABLED_UNTIL_USED_COMPONENTS;
mRetrieveFlags = PackageManager.GET_DISABLED_COMPONENTS |
@@ -181,17 +182,17 @@
mPackageIntentReceiver.registerReceiver();
}
mApplications = new ArrayList<ApplicationInfo>();
- for (UserHandle user : mUm.getUserProfiles()) {
+ for (UserInfo user : mUm.getProfiles(UserHandle.myUserId())) {
try {
// If this user is new, it needs a map created.
- if (mEntriesMap.indexOfKey(user.getIdentifier()) < 0) {
- mEntriesMap.put(user.getIdentifier(), new HashMap<String, AppEntry>());
+ if (mEntriesMap.indexOfKey(user.id) < 0) {
+ mEntriesMap.put(user.id, new HashMap<String, AppEntry>());
}
@SuppressWarnings("unchecked")
ParceledListSlice<ApplicationInfo> list =
mIpm.getInstalledApplications(
- user.isOwner() ? mOwnerRetrieveFlags : mRetrieveFlags,
- user.getIdentifier());
+ user.isAdmin() ? mAdminRetrieveFlags : mRetrieveFlags,
+ user.id);
mApplications.addAll(list.getList());
} catch (RemoteException e) {
}
@@ -363,7 +364,7 @@
return;
}
ApplicationInfo info = mIpm.getApplicationInfo(pkgName,
- userId == UserHandle.USER_OWNER ? mOwnerRetrieveFlags : mRetrieveFlags,
+ mUm.isUserAdmin(userId) ? mAdminRetrieveFlags : mRetrieveFlags,
userId);
if (info == null) {
return;
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java
index 249eaa5..b0429ef 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java
@@ -808,7 +808,7 @@
// The pairing dialog now warns of phone-book access for paired devices.
// No separate prompt is displayed after pairing.
if (getPhonebookPermissionChoice() == CachedBluetoothDevice.ACCESS_UNKNOWN) {
- setPhonebookPermissionChoice(CachedBluetoothDevice.ACCESS_REJECTED);
+ setPhonebookPermissionChoice(CachedBluetoothDevice.ACCESS_ALLOWED);
}
}
}
diff --git a/packages/SettingsLib/src/com/android/settingslib/deviceinfo/StorageMeasurement.java b/packages/SettingsLib/src/com/android/settingslib/deviceinfo/StorageMeasurement.java
index 5d3d120..9790e64 100644
--- a/packages/SettingsLib/src/com/android/settingslib/deviceinfo/StorageMeasurement.java
+++ b/packages/SettingsLib/src/com/android/settingslib/deviceinfo/StorageMeasurement.java
@@ -314,7 +314,7 @@
} else {
Intent service = new Intent().setComponent(DEFAULT_CONTAINER_COMPONENT);
mContext.bindServiceAsUser(service, mDefContainerConn,
- Context.BIND_AUTO_CREATE, UserHandle.OWNER);
+ Context.BIND_AUTO_CREATE, UserHandle.SYSTEM);
}
}
break;
diff --git a/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java b/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java
index 348d0ec..632a867 100644
--- a/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java
+++ b/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java
@@ -151,7 +151,7 @@
mScanResultCache.put(result.BSSID, result);
}
}
- update(mInfo, mNetworkInfo);
+ update(mConfig, mInfo, mNetworkInfo);
mRssi = getRssi();
mSeen = getSeen();
}
@@ -629,11 +629,18 @@
return mConfig != null && mConfig.isPasspoint();
}
- /** Return whether the given {@link WifiInfo} is for this access point. */
- private boolean isInfoForThisAccessPoint(WifiInfo info) {
+ /**
+ * Return whether the given {@link WifiInfo} is for this access point.
+ * If the current AP does not have a network Id then the config is used to
+ * match based on SSID and security.
+ */
+ private boolean isInfoForThisAccessPoint(WifiConfiguration config, WifiInfo info) {
if (isPasspoint() == false && networkId != WifiConfiguration.INVALID_NETWORK_ID) {
return networkId == info.getNetworkId();
- } else {
+ } else if (config != null) {
+ return matches(config);
+ }
+ else {
// Might be an ephemeral connection with no WifiConfiguration. Try matching on SSID.
// (Note that we only do this if the WifiConfiguration explicitly equals INVALID).
// TODO: Handle hex string SSIDs.
@@ -705,7 +712,7 @@
}
boolean update(ScanResult result) {
- if (ssid.equals(result.SSID) && security == getSecurity(result)) {
+ if (matches(result)) {
/* Update the LRU timestamp, if BSSID exists */
mScanResultCache.get(result.BSSID);
@@ -735,9 +742,9 @@
return false;
}
- boolean update(WifiInfo info, NetworkInfo networkInfo) {
+ boolean update(WifiConfiguration config, WifiInfo info, NetworkInfo networkInfo) {
boolean reorder = false;
- if (info != null && isInfoForThisAccessPoint(info)) {
+ if (info != null && isInfoForThisAccessPoint(config, info)) {
reorder = (mInfo == null);
mRssi = info.getRssi();
mInfo = info;
diff --git a/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java b/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java
index 33f993e..c28288e 100644
--- a/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java
+++ b/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java
@@ -281,6 +281,19 @@
return mScanResultCache.values();
}
+ private WifiConfiguration getWifiConfigurationForNetworkId(int networkId) {
+ final List<WifiConfiguration> configs = mWifiManager.getConfiguredNetworks();
+ if (configs != null) {
+ for (WifiConfiguration config : configs) {
+ if (mLastInfo != null && networkId == config.networkId &&
+ !(config.selfAdded && config.numAssociation == 0)) {
+ return config;
+ }
+ }
+ }
+ return null;
+ }
+
private void updateAccessPoints() {
// Swap the current access points into a cached list.
List<AccessPoint> cachedAccessPoints = getAccessPoints();
@@ -295,21 +308,21 @@
* correct SSID. Maps SSID -> List of AccessPoints with the given SSID. */
Multimap<String, AccessPoint> apMap = new Multimap<String, AccessPoint>();
WifiConfiguration connectionConfig = null;
+ if (mLastInfo != null) {
+ connectionConfig = getWifiConfigurationForNetworkId(mLastInfo.getNetworkId());
+ }
final List<WifiConfiguration> configs = mWifiManager.getConfiguredNetworks();
if (configs != null) {
mSavedNetworksExist = configs.size() != 0;
for (WifiConfiguration config : configs) {
- if (mLastInfo != null && mLastInfo.getNetworkId() == config.networkId) {
- connectionConfig = config;
- }
if (config.selfAdded && config.numAssociation == 0) {
continue;
}
AccessPoint accessPoint = getCachedOrCreate(config, cachedAccessPoints);
if (mLastInfo != null && mLastNetworkInfo != null) {
if (config.isPasspoint() == false) {
- accessPoint.update(mLastInfo, mLastNetworkInfo);
+ accessPoint.update(connectionConfig, mLastInfo, mLastNetworkInfo);
}
}
if (mIncludeSaved) {
@@ -346,7 +359,7 @@
if (!found && mIncludeScans) {
AccessPoint accessPoint = getCachedOrCreate(result, cachedAccessPoints);
if (mLastInfo != null && mLastNetworkInfo != null) {
- accessPoint.update(mLastInfo, mLastNetworkInfo);
+ accessPoint.update(connectionConfig, mLastInfo, mLastNetworkInfo);
}
if (result.isPasspointNetwork()) {
@@ -437,9 +450,14 @@
mLastNetworkInfo = networkInfo;
}
+ WifiConfiguration connectionConfig = null;
+ if (mLastInfo != null) {
+ connectionConfig = getWifiConfigurationForNetworkId(mLastInfo.getNetworkId());
+ }
+
boolean reorder = false;
for (int i = mAccessPoints.size() - 1; i >= 0; --i) {
- if (mAccessPoints.get(i).update(mLastInfo, mLastNetworkInfo)) {
+ if (mAccessPoints.get(i).update(connectionConfig, mLastInfo, mLastNetworkInfo)) {
reorder = true;
}
}
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
index 3e9b122..73971ad 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
@@ -42,6 +42,9 @@
import android.os.Bundle;
import android.os.DropBoxManager;
import android.os.Environment;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Message;
import android.os.ParcelFileDescriptor;
import android.os.Process;
import android.os.SystemProperties;
@@ -204,9 +207,6 @@
// We have to call in the user manager with no lock held,
private volatile UserManager mUserManager;
- // We have to call in the app ops manager with no lock held,
- private volatile AppOpsManager mAppOpsManager;
-
// We have to call in the package manager with no lock held,
private volatile PackageManager mPackageManager;
@@ -214,7 +214,6 @@
public boolean onCreate() {
synchronized (mLock) {
mUserManager = (UserManager) getContext().getSystemService(Context.USER_SERVICE);
- mAppOpsManager = (AppOpsManager) getContext().getSystemService(Context.APP_OPS_SERVICE);
mPackageManager = getContext().getPackageManager();
mSettingsRegistry = new SettingsRegistry();
}
@@ -532,7 +531,7 @@
} while (cursor.moveToNext());
}
- private static final String toDumpString(String s) {
+ private static String toDumpString(String s) {
if (s != null) {
return s;
}
@@ -1158,18 +1157,6 @@
getCallingPackage());
}
- private void sendNotify(Uri uri, int userId) {
- final long identity = Binder.clearCallingIdentity();
- try {
- getContext().getContentResolver().notifyChange(uri, null, true, userId);
- if (DEBUG) {
- Slog.v(LOG_TAG, "Notifying for " + userId + ": " + uri);
- }
- } finally {
- Binder.restoreCallingIdentity(identity);
- }
- }
-
private static void warnOrThrowForUndesiredSecureSettingsMutationForTargetSdk(
int targetSdkVersion, String name) {
// If the app targets Lollipop MR1 or older SDK we warn, otherwise crash.
@@ -1390,8 +1377,11 @@
private final BackupManager mBackupManager;
+ private final Handler mHandler;
+
public SettingsRegistry() {
mBackupManager = new BackupManager(getContext());
+ mHandler = new MyHandler(getContext().getMainLooper());
migrateAllLegacySettingsIfNeeded();
}
@@ -1733,7 +1723,7 @@
// Inform the backup manager about a data change
if (backedUpDataChanged) {
- mBackupManager.dataChanged();
+ mHandler.obtainMessage(MyHandler.MSG_NOTIFY_DATA_CHANGED).sendToTarget();
}
// Now send the notification through the content framework.
@@ -1741,7 +1731,9 @@
final int userId = getUserIdFromKey(key);
Uri uri = getNotificationUriFor(key, name);
- sendNotify(uri, userId);
+ mHandler.obtainMessage(MyHandler.MSG_NOTIFY_URI_CHANGED,
+ userId, 0, uri).sendToTarget();
+
if (isSecureSettingsKey(key)) {
maybeNotifyProfiles(userId, uri, name, sSecureCloneToManagedSettings);
} else if (isSystemSettingsKey(key)) {
@@ -1758,7 +1750,8 @@
UserInfo profile = profiles.get(i);
// the notification for userId has already been sent.
if (profile.id != userId) {
- sendNotify(uri, profile.id);
+ mHandler.obtainMessage(MyHandler.MSG_NOTIFY_URI_CHANGED,
+ profile.id, 0, uri).sendToTarget();
}
}
}
@@ -1834,6 +1827,33 @@
}
}
+ private final class MyHandler extends Handler {
+ private static final int MSG_NOTIFY_URI_CHANGED = 1;
+ private static final int MSG_NOTIFY_DATA_CHANGED = 2;
+
+ public MyHandler(Looper looper) {
+ super(looper);
+ }
+
+ @Override
+ public void handleMessage(Message msg) {
+ switch (msg.what) {
+ case MSG_NOTIFY_URI_CHANGED: {
+ final int userId = msg.arg1;
+ Uri uri = (Uri) msg.obj;
+ getContext().getContentResolver().notifyChange(uri, null, true, userId);
+ if (DEBUG) {
+ Slog.v(LOG_TAG, "Notifying for " + userId + ": " + uri);
+ }
+ } break;
+
+ case MSG_NOTIFY_DATA_CHANGED: {
+ mBackupManager.dataChanged();
+ } break;
+ }
+ }
+ }
+
private final class UpgradeController {
private static final int SETTINGS_VERSION = 122;
@@ -1963,9 +1983,11 @@
currentVersion = 120;
}
- // Before 121, we used a different string encoding logic. We just bump the version
- // here; SettingsState knows how to handle pre-version 120 files.
- currentVersion = 121;
+ if (currentVersion == 120) {
+ // Before 121, we used a different string encoding logic. We just bump the
+ // version here; SettingsState knows how to handle pre-version 120 files.
+ currentVersion = 121;
+ }
if (currentVersion == 121) {
// Version 122: allow OEMs to set a default payment component in resources.
diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml
index 27dc56f..e4e0f04 100644
--- a/packages/SystemUI/AndroidManifest.xml
+++ b/packages/SystemUI/AndroidManifest.xml
@@ -60,7 +60,7 @@
<uses-permission android:name="android.permission.CONNECTIVITY_INTERNAL" />
<uses-permission android:name="android.permission.READ_NETWORK_USAGE_HISTORY" />
<uses-permission android:name="android.permission.CONTROL_VPN" />
-
+ <uses-permission android:name="android.permission.PEERS_MAC_ADDRESS"/>
<!-- Physical hardware -->
<uses-permission android:name="android.permission.MANAGE_USB" />
<uses-permission android:name="android.permission.DEVICE_POWER" />
diff --git a/packages/SystemUI/res/layout/recents_task_view_header.xml b/packages/SystemUI/res/layout/recents_task_view_header.xml
index 477d9d7..2168e8b 100644
--- a/packages/SystemUI/res/layout/recents_task_view_header.xml
+++ b/packages/SystemUI/res/layout/recents_task_view_header.xml
@@ -63,4 +63,4 @@
android:background="@drawable/recents_button_bg"
android:visibility="invisible"
android:src="@drawable/recents_dismiss_light" />
-</com.android.systemui.recents.views.TaskViewHeader>
\ No newline at end of file
+</com.android.systemui.recents.views.TaskViewHeader>
diff --git a/packages/SystemUI/res/values-af/strings.xml b/packages/SystemUI/res/values-af/strings.xml
index 53d5e05..ffdcd0e 100644
--- a/packages/SystemUI/res/values-af/strings.xml
+++ b/packages/SystemUI/res/values-af/strings.xml
@@ -345,8 +345,7 @@
<string name="guest_notification_text" msgid="335747957734796689">"Verwyder gasgebruiker om programme en data uit te vee"</string>
<string name="guest_notification_remove_action" msgid="8820670703892101990">"VERWYDER GAS"</string>
<string name="user_logout_notification_title" msgid="1453960926437240727">"Meld gebruiker af"</string>
- <!-- no translation found for user_logout_notification_text (3350262809611876284) -->
- <skip />
+ <string name="user_logout_notification_text" msgid="3350262809611876284">"Meld huidige gebruiker af"</string>
<string name="user_logout_notification_action" msgid="1195428991423425062">"MELD GEBRUIKER AF"</string>
<string name="user_add_user_title" msgid="4553596395824132638">"Voeg nuwe gebruiker by?"</string>
<string name="user_add_user_message_short" msgid="2161624834066214559">"Wanneer jy \'n nuwe gebruiker byvoeg, moet daardie persoon hul spasie opstel.\n\nEnige gebruiker kan programme vir al die ander gebruikers opdateer."</string>
@@ -430,6 +429,5 @@
<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>
- <!-- no translation found for activity_not_found (348423244327799974) -->
- <skip />
+ <string name="activity_not_found" msgid="348423244327799974">"Program is nie op jou toestel geïnstalleer nie"</string>
</resources>
diff --git a/packages/SystemUI/res/values-am/strings.xml b/packages/SystemUI/res/values-am/strings.xml
index aa16ec6..87df43b 100644
--- a/packages/SystemUI/res/values-am/strings.xml
+++ b/packages/SystemUI/res/values-am/strings.xml
@@ -345,8 +345,7 @@
<string name="guest_notification_text" msgid="335747957734796689">"መተግበሪያዎችና ውሂብ ለመሰረዝ እንግዳ ተጣቀሚን ያስወግዱ"</string>
<string name="guest_notification_remove_action" msgid="8820670703892101990">"እንግዳን አስወግድ"</string>
<string name="user_logout_notification_title" msgid="1453960926437240727">"ተጠቃሚን አስወጣ"</string>
- <!-- no translation found for user_logout_notification_text (3350262809611876284) -->
- <skip />
+ <string name="user_logout_notification_text" msgid="3350262809611876284">"አሁን ያለውን ተጠቃሚ አስወጣ"</string>
<string name="user_logout_notification_action" msgid="1195428991423425062">"ተጠቃሚን አስወጣ"</string>
<string name="user_add_user_title" msgid="4553596395824132638">"አዲስ ተጠቃሚ ይታከል?"</string>
<string name="user_add_user_message_short" msgid="2161624834066214559">"እርስዎ አንድ አዲስ ተጠቃሚ ሲያክሉ ያ ሰው የራሱ ቦታ ማዘጋጀት አለበት።\n\nማንኛውም ተጠቃሚ መተግበሪያዎችን ለሌሎች ተጠቃሚዎች ሁሉ ሊያዘምን ይችላል።"</string>
@@ -430,6 +429,5 @@
<string name="tuner_toast" msgid="603429811084428439">"እንኳን ደስ ያለዎት! የስርዓት በይነገጽ መቃኛ ወደ ቅንብሮች ታክሏል"</string>
<string name="remove_from_settings" msgid="8389591916603406378">"ከቅንብሮች አስወግድ"</string>
<string name="remove_from_settings_prompt" msgid="6069085993355887748">"ከቅንብሮች ላይ የስርዓት በይነገጽ መቃኛ ተወግዶ ሁሉም ባህሪዎቹን መጠቀም ይቁም?"</string>
- <!-- no translation found for activity_not_found (348423244327799974) -->
- <skip />
+ <string name="activity_not_found" msgid="348423244327799974">"መተግበሪያ በእርስዎ መሣሪያ ላይ አልተጫነም"</string>
</resources>
diff --git a/packages/SystemUI/res/values-ar/strings.xml b/packages/SystemUI/res/values-ar/strings.xml
index 752b3c2..1778fad 100644
--- a/packages/SystemUI/res/values-ar/strings.xml
+++ b/packages/SystemUI/res/values-ar/strings.xml
@@ -349,8 +349,7 @@
<string name="guest_notification_text" msgid="335747957734796689">"لحذف التطبيقات والبيانات، عليك إزالة حساب الضيف"</string>
<string name="guest_notification_remove_action" msgid="8820670703892101990">"إزالة الضيف"</string>
<string name="user_logout_notification_title" msgid="1453960926437240727">"خروج المستخدم"</string>
- <!-- no translation found for user_logout_notification_text (3350262809611876284) -->
- <skip />
+ <string name="user_logout_notification_text" msgid="3350262809611876284">"خروج المستخدم الحالي"</string>
<string name="user_logout_notification_action" msgid="1195428991423425062">"خروج المستخدم"</string>
<string name="user_add_user_title" msgid="4553596395824132638">"هل تريد إضافة مستخدم جديد؟"</string>
<string name="user_add_user_message_short" msgid="2161624834066214559">"عند إضافة مستخدم جديد، يلزمه إعداد مساحته.\n\nعلمًا بأنه يُمكن لأي مستخدم تحديث التطبيقات لجميع المستخدمين الآخرين."</string>
@@ -434,6 +433,5 @@
<string name="tuner_toast" msgid="603429811084428439">"تهانينا! تمت إضافة أداة ضبط واجهة مستخدم النظام إلى الإعدادات"</string>
<string name="remove_from_settings" msgid="8389591916603406378">"إزالة من الإعدادات"</string>
<string name="remove_from_settings_prompt" msgid="6069085993355887748">"هل تريد إزالة أداة ضبط واجهة مستخدم النظام من الإعدادات وإيقاف استخدام كل ميزاتها؟"</string>
- <!-- no translation found for activity_not_found (348423244327799974) -->
- <skip />
+ <string name="activity_not_found" msgid="348423244327799974">"التطبيق غير مثبّت على جهازك"</string>
</resources>
diff --git a/packages/SystemUI/res/values-az-rAZ/strings.xml b/packages/SystemUI/res/values-az-rAZ/strings.xml
index f7fa3ed..5a43bc3 100644
--- a/packages/SystemUI/res/values-az-rAZ/strings.xml
+++ b/packages/SystemUI/res/values-az-rAZ/strings.xml
@@ -345,8 +345,7 @@
<string name="guest_notification_text" msgid="335747957734796689">"Tətbiq və datanı silmək üçün qonaq istifadəçini silin"</string>
<string name="guest_notification_remove_action" msgid="8820670703892101990">"QONAĞI ÇIXARIN"</string>
<string name="user_logout_notification_title" msgid="1453960926437240727">"İstifadəçi çıxışı"</string>
- <!-- no translation found for user_logout_notification_text (3350262809611876284) -->
- <skip />
+ <string name="user_logout_notification_text" msgid="3350262809611876284">"Cari istifadəçidən çıxın"</string>
<string name="user_logout_notification_action" msgid="1195428991423425062">"İSTİFADƏÇİ ÇIXIŞI"</string>
<string name="user_add_user_title" msgid="4553596395824132638">"Yeni istifadəçi əlavə edilsin?"</string>
<string name="user_add_user_message_short" msgid="2161624834066214559">"Yeni istifadəçi əlavə etdiyiniz zaman həmin şəxs öz yerini quraşdırmalıdır. \n\n İstənilən istifadəçi bütün digər istifadəçilərdən olan tətbiqləri güncəlləşdirə bilər."</string>
@@ -430,6 +429,5 @@
<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>
- <!-- no translation found for activity_not_found (348423244327799974) -->
- <skip />
+ <string name="activity_not_found" msgid="348423244327799974">"Tətbiq cihazınızda quraşdırılmayıb"</string>
</resources>
diff --git a/packages/SystemUI/res/values-bg/strings.xml b/packages/SystemUI/res/values-bg/strings.xml
index ba653ef..2b8660e 100644
--- a/packages/SystemUI/res/values-bg/strings.xml
+++ b/packages/SystemUI/res/values-bg/strings.xml
@@ -345,8 +345,7 @@
<string name="guest_notification_text" msgid="335747957734796689">"Премахнете госта, за да се изтрият приложенията и данните"</string>
<string name="guest_notification_remove_action" msgid="8820670703892101990">"ПРЕМАХВАНЕ НА ГОСТА"</string>
<string name="user_logout_notification_title" msgid="1453960926437240727">"Излизане на потребителя"</string>
- <!-- no translation found for user_logout_notification_text (3350262809611876284) -->
- <skip />
+ <string name="user_logout_notification_text" msgid="3350262809611876284">"Излезте от профила на текущия потребител"</string>
<string name="user_logout_notification_action" msgid="1195428991423425062">"ИЗЛИЗАНЕ НА ПОТРЕБИТЕЛЯ"</string>
<string name="user_add_user_title" msgid="4553596395824132638">"Да се добави ли нов потреб.?"</string>
<string name="user_add_user_message_short" msgid="2161624834066214559">"Когато добавите нов потребител, той трябва да настрои работното си пространство.\n\nВсеки потребител може да актуализира приложенията за всички останали потребители."</string>
@@ -430,6 +429,5 @@
<string name="tuner_toast" msgid="603429811084428439">"Поздравления! Тунерът на системния потребителски интерфейс е добавен към „Настройки“"</string>
<string name="remove_from_settings" msgid="8389591916603406378">"Премахване от „Настройки“"</string>
<string name="remove_from_settings_prompt" msgid="6069085993355887748">"Да се премахне ли от „Настройки“ тунерът на системния потребителски интерфейс и да се спре ли използването на всичките му функции?"</string>
- <!-- no translation found for activity_not_found (348423244327799974) -->
- <skip />
+ <string name="activity_not_found" msgid="348423244327799974">"Приложението не е инсталирано на устройството ви"</string>
</resources>
diff --git a/packages/SystemUI/res/values-bn-rBD/strings.xml b/packages/SystemUI/res/values-bn-rBD/strings.xml
index 29206c9..4a0a46c 100644
--- a/packages/SystemUI/res/values-bn-rBD/strings.xml
+++ b/packages/SystemUI/res/values-bn-rBD/strings.xml
@@ -345,8 +345,7 @@
<string name="guest_notification_text" msgid="335747957734796689">"অ্যাপ্লিকেশান এবং ডেটা মুছে ফেলার জন্য অতিথি ব্যবহারকারী সরান।"</string>
<string name="guest_notification_remove_action" msgid="8820670703892101990">"অতিথি সরান"</string>
<string name="user_logout_notification_title" msgid="1453960926437240727">"ব্যবহারকারীকে লগ-আউট করুন"</string>
- <!-- no translation found for user_logout_notification_text (3350262809611876284) -->
- <skip />
+ <string name="user_logout_notification_text" msgid="3350262809611876284">"বর্তমান ব্যবহারকারীকে লগ আউট করুন"</string>
<string name="user_logout_notification_action" msgid="1195428991423425062">"ব্যবহারকারীকে লগ-আউট করুন"</string>
<string name="user_add_user_title" msgid="4553596395824132638">"নতুন ব্যবহারকারীকে যোগ করবেন?"</string>
<string name="user_add_user_message_short" msgid="2161624834066214559">"আপনি একজন নতুন ব্যবহারকারী যোগ করলে তাকে তার জায়গা সেট আপ করে নিতে হবে৷\n\nযেকোনো ব্যবহারকারী অন্য সব ব্যবহারকারীর জন্য অ্যাপ্লিকেশান আপডেট করতে পারবেন৷"</string>
@@ -430,6 +429,5 @@
<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>
- <!-- no translation found for activity_not_found (348423244327799974) -->
- <skip />
+ <string name="activity_not_found" msgid="348423244327799974">"আপনার ডিভাইসে অ্যাপ্লিকেশান ইনস্টল করা নেই"</string>
</resources>
diff --git a/packages/SystemUI/res/values-ca/strings.xml b/packages/SystemUI/res/values-ca/strings.xml
index 9696c55..2b7171a 100644
--- a/packages/SystemUI/res/values-ca/strings.xml
+++ b/packages/SystemUI/res/values-ca/strings.xml
@@ -347,8 +347,7 @@
<string name="guest_notification_text" msgid="335747957734796689">"Per suprimir aplicacions i dades, elimina l\'usuari convidat"</string>
<string name="guest_notification_remove_action" msgid="8820670703892101990">"SUPRIMEIX EL CONVIDAT"</string>
<string name="user_logout_notification_title" msgid="1453960926437240727">"Tanca la sessió de l\'usuari"</string>
- <!-- no translation found for user_logout_notification_text (3350262809611876284) -->
- <skip />
+ <string name="user_logout_notification_text" msgid="3350262809611876284">"Tanca la sessió de l\'usuari actual"</string>
<string name="user_logout_notification_action" msgid="1195428991423425062">"TANCA LA SESSIÓ DE L\'USUARI"</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>
@@ -432,6 +431,5 @@
<string name="tuner_toast" msgid="603429811084428439">"Enhorabona! El Configurador de la IU del sistema 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>
- <!-- no translation found for activity_not_found (348423244327799974) -->
- <skip />
+ <string name="activity_not_found" msgid="348423244327799974">"L\'aplicació no està instal·lada al dispositiu"</string>
</resources>
diff --git a/packages/SystemUI/res/values-cs/strings.xml b/packages/SystemUI/res/values-cs/strings.xml
index 4cacce1..ce1749d 100644
--- a/packages/SystemUI/res/values-cs/strings.xml
+++ b/packages/SystemUI/res/values-cs/strings.xml
@@ -349,8 +349,7 @@
<string name="guest_notification_text" msgid="335747957734796689">"Chcete-li smazat aplikace a data, odeberte hosta"</string>
<string name="guest_notification_remove_action" msgid="8820670703892101990">"ODSTRANIT HOSTA"</string>
<string name="user_logout_notification_title" msgid="1453960926437240727">"Odhlásit uživatele"</string>
- <!-- no translation found for user_logout_notification_text (3350262809611876284) -->
- <skip />
+ <string name="user_logout_notification_text" msgid="3350262809611876284">"Odhlásit aktuálního uživatele"</string>
<string name="user_logout_notification_action" msgid="1195428991423425062">"ODHLÁSIT UŽIVATELE"</string>
<string name="user_add_user_title" msgid="4553596395824132638">"Přidat nového uživatele?"</string>
<string name="user_add_user_message_short" msgid="2161624834066214559">"Když přidáte nového uživatele, musí si nastavit vlastní prostor.\n\nJakýkoli uživatel může aktualizovat aplikace všech ostatních uživatelů."</string>
@@ -434,6 +433,5 @@
<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>
- <!-- no translation found for activity_not_found (348423244327799974) -->
- <skip />
+ <string name="activity_not_found" msgid="348423244327799974">"Aplikace není v zařízení nainstalována."</string>
</resources>
diff --git a/packages/SystemUI/res/values-da/strings.xml b/packages/SystemUI/res/values-da/strings.xml
index 4d8b5c1..6871c46 100644
--- a/packages/SystemUI/res/values-da/strings.xml
+++ b/packages/SystemUI/res/values-da/strings.xml
@@ -345,8 +345,7 @@
<string name="guest_notification_text" msgid="335747957734796689">"Fjern gæstebrugeren for at slette apps og data"</string>
<string name="guest_notification_remove_action" msgid="8820670703892101990">"FJERN GÆST"</string>
<string name="user_logout_notification_title" msgid="1453960926437240727">"Log brugeren ud"</string>
- <!-- no translation found for user_logout_notification_text (3350262809611876284) -->
- <skip />
+ <string name="user_logout_notification_text" msgid="3350262809611876284">"Log den aktuelle bruger ud"</string>
<string name="user_logout_notification_action" msgid="1195428991423425062">"LOG BRUGEREN UD"</string>
<string name="user_add_user_title" msgid="4553596395824132638">"Vil du tilføje den nye bruger?"</string>
<string name="user_add_user_message_short" msgid="2161624834066214559">"Når du tilføjer en ny bruger, skal personen konfigurere sit område.\n\nEnhver bruger kan opdatere apps for alle andre brugere."</string>
@@ -430,6 +429,5 @@
<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>
- <!-- no translation found for activity_not_found (348423244327799974) -->
- <skip />
+ <string name="activity_not_found" msgid="348423244327799974">"Applikationen er ikke installeret på din enhed."</string>
</resources>
diff --git a/packages/SystemUI/res/values-de/strings.xml b/packages/SystemUI/res/values-de/strings.xml
index 409af6cd..a9d2fd4 100644
--- a/packages/SystemUI/res/values-de/strings.xml
+++ b/packages/SystemUI/res/values-de/strings.xml
@@ -347,8 +347,7 @@
<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_logout_notification_title" msgid="1453960926437240727">"Nutzer abmelden"</string>
- <!-- no translation found for user_logout_notification_text (3350262809611876284) -->
- <skip />
+ <string name="user_logout_notification_text" msgid="3350262809611876284">"Aktuellen Nutzer abmelden"</string>
<string name="user_logout_notification_action" msgid="1195428991423425062">"Nutzer abmelden"</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>
@@ -432,6 +431,5 @@
<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>
- <!-- no translation found for activity_not_found (348423244327799974) -->
- <skip />
+ <string name="activity_not_found" msgid="348423244327799974">"Die App ist nicht auf Ihrem Gerät installiert."</string>
</resources>
diff --git a/packages/SystemUI/res/values-el/strings.xml b/packages/SystemUI/res/values-el/strings.xml
index bf88459..82ec24f 100644
--- a/packages/SystemUI/res/values-el/strings.xml
+++ b/packages/SystemUI/res/values-el/strings.xml
@@ -347,8 +347,7 @@
<string name="guest_notification_text" msgid="335747957734796689">"Για διαγρ. εφαρμ. και δεδομένων, καταργ. το χρήστη-επισκέπτη"</string>
<string name="guest_notification_remove_action" msgid="8820670703892101990">"ΚΑΤΑΡΓΗΣΗ ΕΠΙΣΚΕΠΤΗ"</string>
<string name="user_logout_notification_title" msgid="1453960926437240727">"Αποσύνδεση χρήστη"</string>
- <!-- no translation found for user_logout_notification_text (3350262809611876284) -->
- <skip />
+ <string name="user_logout_notification_text" msgid="3350262809611876284">"Αποσύνδεση τρέχοντα χρήστη"</string>
<string name="user_logout_notification_action" msgid="1195428991423425062">"ΑΠΟΣΥΝΔΕΣΗ ΧΡΗΣΤΗ"</string>
<string name="user_add_user_title" msgid="4553596395824132638">"Προσθήκη νέου χρήστη;"</string>
<string name="user_add_user_message_short" msgid="2161624834066214559">"Κατά την προσθήκη ενός νέου χρήστη, αυτός θα πρέπει να ρυθμίσει το χώρο του.\n\nΟποιοσδήποτε χρήστης μπορεί να ενημερώσει τις εφαρμογές για όλους τους άλλους χρήστες."</string>
@@ -432,6 +431,5 @@
<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>
- <!-- no translation found for activity_not_found (348423244327799974) -->
- <skip />
+ <string name="activity_not_found" msgid="348423244327799974">"Η εφαρμογή δεν έχει εγκατασταθεί στη συσκευή σας"</string>
</resources>
diff --git a/packages/SystemUI/res/values-en-rAU/strings.xml b/packages/SystemUI/res/values-en-rAU/strings.xml
index af7328e..b416ab3 100644
--- a/packages/SystemUI/res/values-en-rAU/strings.xml
+++ b/packages/SystemUI/res/values-en-rAU/strings.xml
@@ -345,8 +345,7 @@
<string name="guest_notification_text" msgid="335747957734796689">"To delete apps and data, remove guest user"</string>
<string name="guest_notification_remove_action" msgid="8820670703892101990">"REMOVE GUEST"</string>
<string name="user_logout_notification_title" msgid="1453960926437240727">"Logout user"</string>
- <!-- no translation found for user_logout_notification_text (3350262809611876284) -->
- <skip />
+ <string name="user_logout_notification_text" msgid="3350262809611876284">"Log out current user"</string>
<string name="user_logout_notification_action" msgid="1195428991423425062">"LOGOUT USER"</string>
<string name="user_add_user_title" msgid="4553596395824132638">"Add new user?"</string>
<string name="user_add_user_message_short" msgid="2161624834066214559">"When you add a new user, that person needs to set up their space.\n\nAny user can update apps for all other users."</string>
@@ -430,6 +429,5 @@
<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>
- <!-- no translation found for activity_not_found (348423244327799974) -->
- <skip />
+ <string name="activity_not_found" msgid="348423244327799974">"Application is not installed on your device"</string>
</resources>
diff --git a/packages/SystemUI/res/values-en-rGB/strings.xml b/packages/SystemUI/res/values-en-rGB/strings.xml
index af7328e..b416ab3 100644
--- a/packages/SystemUI/res/values-en-rGB/strings.xml
+++ b/packages/SystemUI/res/values-en-rGB/strings.xml
@@ -345,8 +345,7 @@
<string name="guest_notification_text" msgid="335747957734796689">"To delete apps and data, remove guest user"</string>
<string name="guest_notification_remove_action" msgid="8820670703892101990">"REMOVE GUEST"</string>
<string name="user_logout_notification_title" msgid="1453960926437240727">"Logout user"</string>
- <!-- no translation found for user_logout_notification_text (3350262809611876284) -->
- <skip />
+ <string name="user_logout_notification_text" msgid="3350262809611876284">"Log out current user"</string>
<string name="user_logout_notification_action" msgid="1195428991423425062">"LOGOUT USER"</string>
<string name="user_add_user_title" msgid="4553596395824132638">"Add new user?"</string>
<string name="user_add_user_message_short" msgid="2161624834066214559">"When you add a new user, that person needs to set up their space.\n\nAny user can update apps for all other users."</string>
@@ -430,6 +429,5 @@
<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>
- <!-- no translation found for activity_not_found (348423244327799974) -->
- <skip />
+ <string name="activity_not_found" msgid="348423244327799974">"Application is not installed on your device"</string>
</resources>
diff --git a/packages/SystemUI/res/values-en-rIN/strings.xml b/packages/SystemUI/res/values-en-rIN/strings.xml
index af7328e..b416ab3 100644
--- a/packages/SystemUI/res/values-en-rIN/strings.xml
+++ b/packages/SystemUI/res/values-en-rIN/strings.xml
@@ -345,8 +345,7 @@
<string name="guest_notification_text" msgid="335747957734796689">"To delete apps and data, remove guest user"</string>
<string name="guest_notification_remove_action" msgid="8820670703892101990">"REMOVE GUEST"</string>
<string name="user_logout_notification_title" msgid="1453960926437240727">"Logout user"</string>
- <!-- no translation found for user_logout_notification_text (3350262809611876284) -->
- <skip />
+ <string name="user_logout_notification_text" msgid="3350262809611876284">"Log out current user"</string>
<string name="user_logout_notification_action" msgid="1195428991423425062">"LOGOUT USER"</string>
<string name="user_add_user_title" msgid="4553596395824132638">"Add new user?"</string>
<string name="user_add_user_message_short" msgid="2161624834066214559">"When you add a new user, that person needs to set up their space.\n\nAny user can update apps for all other users."</string>
@@ -430,6 +429,5 @@
<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>
- <!-- no translation found for activity_not_found (348423244327799974) -->
- <skip />
+ <string name="activity_not_found" msgid="348423244327799974">"Application is not installed on your device"</string>
</resources>
diff --git a/packages/SystemUI/res/values-es-rUS/strings.xml b/packages/SystemUI/res/values-es-rUS/strings.xml
index 56c7c6a..80d2916 100644
--- a/packages/SystemUI/res/values-es-rUS/strings.xml
+++ b/packages/SystemUI/res/values-es-rUS/strings.xml
@@ -347,8 +347,7 @@
<string name="guest_notification_text" msgid="335747957734796689">"Para borrar aplicaciones y datos, quita el usuario invitado"</string>
<string name="guest_notification_remove_action" msgid="8820670703892101990">"QUITAR INVITADO"</string>
<string name="user_logout_notification_title" msgid="1453960926437240727">"Salir de la sesión del usuario"</string>
- <!-- no translation found for user_logout_notification_text (3350262809611876284) -->
- <skip />
+ <string name="user_logout_notification_text" msgid="3350262809611876284">"Salir de la sesión del usuario actual"</string>
<string name="user_logout_notification_action" msgid="1195428991423425062">"SALIR DE SESIÓN DEL USUARIO"</string>
<string name="user_add_user_title" msgid="4553596395824132638">"¿Agregar usuario nuevo?"</string>
<string name="user_add_user_message_short" msgid="2161624834066214559">"Cuando agregas un nuevo usuario, esa persona debe configurar su espacio.\n\nCualquier usuario puede actualizar aplicaciones para todos los usuarios."</string>
@@ -432,6 +431,5 @@
<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>
- <!-- no translation found for activity_not_found (348423244327799974) -->
- <skip />
+ <string name="activity_not_found" msgid="348423244327799974">"La aplicación no está instalada en el dispositivo"</string>
</resources>
diff --git a/packages/SystemUI/res/values-es/strings.xml b/packages/SystemUI/res/values-es/strings.xml
index db34f7e..b44a1f6 100644
--- a/packages/SystemUI/res/values-es/strings.xml
+++ b/packages/SystemUI/res/values-es/strings.xml
@@ -345,8 +345,7 @@
<string name="guest_notification_text" msgid="335747957734796689">"Para eliminar aplicaciones y datos, quita usuario invitado"</string>
<string name="guest_notification_remove_action" msgid="8820670703892101990">"ELIMINAR INVITADO"</string>
<string name="user_logout_notification_title" msgid="1453960926437240727">"Salir de usuario"</string>
- <!-- no translation found for user_logout_notification_text (3350262809611876284) -->
- <skip />
+ <string name="user_logout_notification_text" msgid="3350262809611876284">"Salir de usuario actual"</string>
<string name="user_logout_notification_action" msgid="1195428991423425062">"SALIR DE USUARIO"</string>
<string name="user_add_user_title" msgid="4553596395824132638">"¿Añadir nuevo usuario?"</string>
<string name="user_add_user_message_short" msgid="2161624834066214559">"Al añadir un usuario nuevo, este debe configurar su espacio.\n\nCualquier usuario puede actualizar las aplicaciones del resto de usuarios."</string>
@@ -430,6 +429,5 @@
<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>
- <!-- no translation found for activity_not_found (348423244327799974) -->
- <skip />
+ <string name="activity_not_found" msgid="348423244327799974">"La aplicación no está instalada en tu dispositivo"</string>
</resources>
diff --git a/packages/SystemUI/res/values-et-rEE/strings.xml b/packages/SystemUI/res/values-et-rEE/strings.xml
index e04bb8b..01dfe89 100644
--- a/packages/SystemUI/res/values-et-rEE/strings.xml
+++ b/packages/SystemUI/res/values-et-rEE/strings.xml
@@ -345,8 +345,7 @@
<string name="guest_notification_text" msgid="335747957734796689">"Rakenduste ja andmete kustutamiseks eemaldage külaliskasutaja"</string>
<string name="guest_notification_remove_action" msgid="8820670703892101990">"EEMALDA KÜLALINE"</string>
<string name="user_logout_notification_title" msgid="1453960926437240727">"Kasutaja väljalogimine"</string>
- <!-- no translation found for user_logout_notification_text (3350262809611876284) -->
- <skip />
+ <string name="user_logout_notification_text" msgid="3350262809611876284">"Praeguse kasutaja väljalogimine"</string>
<string name="user_logout_notification_action" msgid="1195428991423425062">"LOGI KASUTAJA VÄLJA"</string>
<string name="user_add_user_title" msgid="4553596395824132638">"Kas lisada uus kasutaja?"</string>
<string name="user_add_user_message_short" msgid="2161624834066214559">"Kui lisate uue kasutaja, siis peab ta seadistama oma ruumi.\n\nIga kasutaja saab värskendada rakendusi kõigi kasutajate jaoks."</string>
@@ -430,6 +429,5 @@
<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>
- <!-- no translation found for activity_not_found (348423244327799974) -->
- <skip />
+ <string name="activity_not_found" msgid="348423244327799974">"Rakendust pole teie seadmesse installitud"</string>
</resources>
diff --git a/packages/SystemUI/res/values-eu-rES/strings.xml b/packages/SystemUI/res/values-eu-rES/strings.xml
index fd8f462..7052b80 100644
--- a/packages/SystemUI/res/values-eu-rES/strings.xml
+++ b/packages/SystemUI/res/values-eu-rES/strings.xml
@@ -345,8 +345,7 @@
<string name="guest_notification_text" msgid="335747957734796689">"Aplikazioak eta datuak ezabatzeko, kendu gonbidatua"</string>
<string name="guest_notification_remove_action" msgid="8820670703892101990">"KENDU GONBIDATUA"</string>
<string name="user_logout_notification_title" msgid="1453960926437240727">"Amaitu erabiltzailearen saioa"</string>
- <!-- no translation found for user_logout_notification_text (3350262809611876284) -->
- <skip />
+ <string name="user_logout_notification_text" msgid="3350262809611876284">"Amaitu uneko erabiltzailearen saioa"</string>
<string name="user_logout_notification_action" msgid="1195428991423425062">"AMAITU ERABILTZAILEAREN SAIOA"</string>
<string name="user_add_user_title" msgid="4553596395824132638">"Beste erabiltzaile bat gehitu?"</string>
<string name="user_add_user_message_short" msgid="2161624834066214559">"Erabiltzaile bat gehitzen duzunean, horrek bere eremua konfiguratu beharko du.\n\nEdozein erabiltzailek egunera ditzake beste erabiltzaile guztien aplikazioak."</string>
@@ -430,6 +429,5 @@
<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>
- <!-- no translation found for activity_not_found (348423244327799974) -->
- <skip />
+ <string name="activity_not_found" msgid="348423244327799974">"Aplikazioa ez dago gailuan instalatuta"</string>
</resources>
diff --git a/packages/SystemUI/res/values-fa/strings.xml b/packages/SystemUI/res/values-fa/strings.xml
index d68704c..ad063c6 100644
--- a/packages/SystemUI/res/values-fa/strings.xml
+++ b/packages/SystemUI/res/values-fa/strings.xml
@@ -55,7 +55,7 @@
<string name="usb_accessory_permission_prompt" msgid="5171775411178865750">"به برنامه <xliff:g id="APPLICATION">%1$s</xliff:g> اجازه میدهد تا به وسیله جانبی USB دسترسی داشته باشد؟"</string>
<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>
+ <string name="usb_accessory_uri_prompt" msgid="513450621413733343">"هیچ برنامه نصب شدهای با این وسیله جانبی USB کار نمیکند. در <xliff:g id="URL">%1$s</xliff:g> دربارهٔ این وسیله جانبی اطلاعات بیشتری کسب کنید"</string>
<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>
@@ -345,8 +345,7 @@
<string name="guest_notification_text" msgid="335747957734796689">"برای حذف برنامهها و دادهها، کاربر مهمان را حذف کنید"</string>
<string name="guest_notification_remove_action" msgid="8820670703892101990">"حذف مهمان"</string>
<string name="user_logout_notification_title" msgid="1453960926437240727">"خروج کاربر از سیستم"</string>
- <!-- no translation found for user_logout_notification_text (3350262809611876284) -->
- <skip />
+ <string name="user_logout_notification_text" msgid="3350262809611876284">"خروج کاربر فعلی از سیستم"</string>
<string name="user_logout_notification_action" msgid="1195428991423425062">"خروج کاربر از سیستم"</string>
<string name="user_add_user_title" msgid="4553596395824132638">"کاربر جدیدی اضافه میکنید؟"</string>
<string name="user_add_user_message_short" msgid="2161624834066214559">"وقتی کاربر جدیدی را اضافه میکنید آن فرد باید فضای خودش را تنظیم کند.\n\nهر کاربری میتواند برنامهها را برای همه کاربران دیگر بهروزرسانی کند."</string>
@@ -430,6 +429,5 @@
<string name="tuner_toast" msgid="603429811084428439">"تبریک میگوییم! «تنظیمکننده واسط کاربری سیستم» به «تنظیمات» اضافه شد"</string>
<string name="remove_from_settings" msgid="8389591916603406378">"حذف از تنظیمات"</string>
<string name="remove_from_settings_prompt" msgid="6069085993355887748">"«تنظیمکننده واسط کاربری سیستم» از تنظیمات حذف شود و همه ویژگیهای آن متوقف شوند؟"</string>
- <!-- no translation found for activity_not_found (348423244327799974) -->
- <skip />
+ <string name="activity_not_found" msgid="348423244327799974">"برنامه در دستگاه شما نصب نیست"</string>
</resources>
diff --git a/packages/SystemUI/res/values-fi/strings.xml b/packages/SystemUI/res/values-fi/strings.xml
index 0e25d66..c906e8a 100644
--- a/packages/SystemUI/res/values-fi/strings.xml
+++ b/packages/SystemUI/res/values-fi/strings.xml
@@ -345,8 +345,7 @@
<string name="guest_notification_text" msgid="335747957734796689">"Poista sovellukset ja tiedot poistamalla vieraskäyttäjä."</string>
<string name="guest_notification_remove_action" msgid="8820670703892101990">"POISTA VIERAILIJA"</string>
<string name="user_logout_notification_title" msgid="1453960926437240727">"Kirjaa käyttäjä ulos"</string>
- <!-- no translation found for user_logout_notification_text (3350262809611876284) -->
- <skip />
+ <string name="user_logout_notification_text" msgid="3350262809611876284">"Kirjaa nykyinen käyttäjä ulos."</string>
<string name="user_logout_notification_action" msgid="1195428991423425062">"KIRJAA KÄYTTÄJÄ ULOS"</string>
<string name="user_add_user_title" msgid="4553596395824132638">"Lisätäänkö uusi käyttäjä?"</string>
<string name="user_add_user_message_short" msgid="2161624834066214559">"Kun lisäät uuden käyttäjän, hänen tulee määrittää oman tilansa asetukset.\n\nKaikki käyttäjät voivat päivittää sovelluksia muille käyttäjille."</string>
@@ -430,6 +429,5 @@
<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>
- <!-- no translation found for activity_not_found (348423244327799974) -->
- <skip />
+ <string name="activity_not_found" msgid="348423244327799974">"Sovellusta ei ole asennettu laitteellesi."</string>
</resources>
diff --git a/packages/SystemUI/res/values-fr-rCA/strings.xml b/packages/SystemUI/res/values-fr-rCA/strings.xml
index 5f9489d..eceee64 100644
--- a/packages/SystemUI/res/values-fr-rCA/strings.xml
+++ b/packages/SystemUI/res/values-fr-rCA/strings.xml
@@ -347,8 +347,7 @@
<string name="guest_notification_text" msgid="335747957734796689">"Pour supprimer des applications et des données, retirez l\'utilisateur invité"</string>
<string name="guest_notification_remove_action" msgid="8820670703892101990">"RETIRER L\'INVITÉ"</string>
<string name="user_logout_notification_title" msgid="1453960926437240727">"Déconnecter l\'utilisateur"</string>
- <!-- no translation found for user_logout_notification_text (3350262809611876284) -->
- <skip />
+ <string name="user_logout_notification_text" msgid="3350262809611876284">"Déconnecter l\'utilisateur actuel"</string>
<string name="user_logout_notification_action" msgid="1195428991423425062">"DÉCONNECTER L\'UTILISATEUR"</string>
<string name="user_add_user_title" msgid="4553596395824132638">"Ajouter un utilisateur?"</string>
<string name="user_add_user_message_short" msgid="2161624834066214559">"Lorsque vous ajoutez un utilisateur, celui-ci doit configurer son espace.\n\nN\'importe quel utilisateur peut mettre à jour les applications pour tous les autres utilisateurs."</string>
@@ -432,6 +431,5 @@
<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>
- <!-- no translation found for activity_not_found (348423244327799974) -->
- <skip />
+ <string name="activity_not_found" msgid="348423244327799974">"L\'application n\'est pas installée sur votre appareil"</string>
</resources>
diff --git a/packages/SystemUI/res/values-fr/strings.xml b/packages/SystemUI/res/values-fr/strings.xml
index e25090e..f2bc9d0 100644
--- a/packages/SystemUI/res/values-fr/strings.xml
+++ b/packages/SystemUI/res/values-fr/strings.xml
@@ -347,8 +347,7 @@
<string name="guest_notification_text" msgid="335747957734796689">"Pour supprimer des applis et des données, retirez l\'invité."</string>
<string name="guest_notification_remove_action" msgid="8820670703892101990">"RETIRER L\'INVITÉ"</string>
<string name="user_logout_notification_title" msgid="1453960926437240727">"Déconnecter l\'utilisateur"</string>
- <!-- no translation found for user_logout_notification_text (3350262809611876284) -->
- <skip />
+ <string name="user_logout_notification_text" msgid="3350262809611876284">"Déconnecter l\'utilisateur actuel"</string>
<string name="user_logout_notification_action" msgid="1195428991423425062">"DÉCONNECTER L\'UTILISATEUR"</string>
<string name="user_add_user_title" msgid="4553596395824132638">"Ajouter un utilisateur ?"</string>
<string name="user_add_user_message_short" msgid="2161624834066214559">"Lorsque vous ajoutez un utilisateur, celui-ci doit configurer son espace.\n\nN\'importe quel utilisateur peut mettre à jour les applications pour tous les autres utilisateurs."</string>
@@ -432,6 +431,5 @@
<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>
- <!-- no translation found for activity_not_found (348423244327799974) -->
- <skip />
+ <string name="activity_not_found" msgid="348423244327799974">"L\'application n\'est pas installée sur votre appareil."</string>
</resources>
diff --git a/packages/SystemUI/res/values-gl-rES/strings.xml b/packages/SystemUI/res/values-gl-rES/strings.xml
index 585b1ac..1f80aa7 100644
--- a/packages/SystemUI/res/values-gl-rES/strings.xml
+++ b/packages/SystemUI/res/values-gl-rES/strings.xml
@@ -347,8 +347,7 @@
<string name="guest_notification_text" msgid="335747957734796689">"Para eliminar aplicacións e datos, elimina usuario invitado"</string>
<string name="guest_notification_remove_action" msgid="8820670703892101990">"QUITAR CONVIDADO"</string>
<string name="user_logout_notification_title" msgid="1453960926437240727">"Pechar sesión do usuario"</string>
- <!-- no translation found for user_logout_notification_text (3350262809611876284) -->
- <skip />
+ <string name="user_logout_notification_text" msgid="3350262809611876284">"Pechar sesión do usuario actual"</string>
<string name="user_logout_notification_action" msgid="1195428991423425062">"PECHAR SESIÓN DO USUARIO"</string>
<string name="user_add_user_title" msgid="4553596395824132638">"Engadir un usuario novo?"</string>
<string name="user_add_user_message_short" msgid="2161624834066214559">"Cando engadas un usuario novo, este deberá configurar o seu espazo\n\nCalquera usuario pode actualizar as aplicacións para todos os demais usuarios."</string>
@@ -432,6 +431,5 @@
<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>
- <!-- no translation found for activity_not_found (348423244327799974) -->
- <skip />
+ <string name="activity_not_found" msgid="348423244327799974">"A aplicación non está instalada no teu dispositivo"</string>
</resources>
diff --git a/packages/SystemUI/res/values-gu-rIN/strings.xml b/packages/SystemUI/res/values-gu-rIN/strings.xml
index a5b45ca..39782a2 100644
--- a/packages/SystemUI/res/values-gu-rIN/strings.xml
+++ b/packages/SystemUI/res/values-gu-rIN/strings.xml
@@ -345,8 +345,7 @@
<string name="guest_notification_text" msgid="335747957734796689">"એપ્લિકેશનો અને ડેટા કાઢી નાખવા, અતિથિ વપરાશકર્તાને દૂર કરો"</string>
<string name="guest_notification_remove_action" msgid="8820670703892101990">"અતિથિ દૂર કરો"</string>
<string name="user_logout_notification_title" msgid="1453960926437240727">"વપરાશકર્તાને લૉગઆઉટ કરો"</string>
- <!-- no translation found for user_logout_notification_text (3350262809611876284) -->
- <skip />
+ <string name="user_logout_notification_text" msgid="3350262809611876284">"વર્તમાન વપરાશકર્તાને લૉગઆઉટ કરો"</string>
<string name="user_logout_notification_action" msgid="1195428991423425062">"વપરાશકર્તાને લૉગઆઉટ કરો"</string>
<string name="user_add_user_title" msgid="4553596395824132638">"નવા વપરાશકર્તાને ઉમેરીએ?"</string>
<string name="user_add_user_message_short" msgid="2161624834066214559">"જ્યારે તમે કોઈ નવા વપરાશકર્તાને ઉમેરો છો, ત્યારે તે વ્યક્તિને તેમનું સ્થાન સેટ કરવાની જરૂર પડે છે.\n\nકોઈપણ વપરાશકર્તા બધા અન્ય વપરાશકર્તાઓ માટે એપ્લિકેશન્સને અપડેટ કરી શકે છે."</string>
@@ -430,6 +429,5 @@
<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>
- <!-- no translation found for activity_not_found (348423244327799974) -->
- <skip />
+ <string name="activity_not_found" msgid="348423244327799974">"તમારા ઉપકરણ પર એપ્લિકેશન ઇન્સ્ટોલ થયેલ નથી"</string>
</resources>
diff --git a/packages/SystemUI/res/values-hi/strings.xml b/packages/SystemUI/res/values-hi/strings.xml
index 348eca0..e2ac2b8 100644
--- a/packages/SystemUI/res/values-hi/strings.xml
+++ b/packages/SystemUI/res/values-hi/strings.xml
@@ -41,7 +41,7 @@
<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>
+ <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">"वाई-फ़ाई"</string>
<string name="status_bar_settings_auto_rotation" msgid="3790482541357798421">"स्क्रीन अपनेआप घुमाएं"</string>
@@ -345,8 +345,7 @@
<string name="guest_notification_text" msgid="335747957734796689">"ऐप्स और डेटा हटाने के लिए, अतिथि उपयोगकर्ता को निकालें"</string>
<string name="guest_notification_remove_action" msgid="8820670703892101990">"अतिथि को निकालें"</string>
<string name="user_logout_notification_title" msgid="1453960926437240727">"उपयोगकर्ता को प्रस्थान करवाना"</string>
- <!-- no translation found for user_logout_notification_text (3350262809611876284) -->
- <skip />
+ <string name="user_logout_notification_text" msgid="3350262809611876284">"वर्तमान उपयोगकर्ता से प्रस्थान करें"</string>
<string name="user_logout_notification_action" msgid="1195428991423425062">"उपयोगकर्ता को प्रस्थान करवाएं"</string>
<string name="user_add_user_title" msgid="4553596395824132638">"नया उपयोगकर्ता जोड़ें?"</string>
<string name="user_add_user_message_short" msgid="2161624834066214559">"जब आप कोई नया उपयोगकर्ता जोड़ते हैं तो उस व्यक्ति को अपना स्थान सेट करना होता है.\n\nकोई भी उपयोगकर्ता अन्य सभी उपयोगकर्ताओं के लिए ऐप्स अपडेट कर सकता है."</string>
@@ -430,6 +429,5 @@
<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>
- <!-- no translation found for activity_not_found (348423244327799974) -->
- <skip />
+ <string name="activity_not_found" msgid="348423244327799974">"ऐप्लिकेशन आपके डिवाइस पर इंस्टॉल नहीं है"</string>
</resources>
diff --git a/packages/SystemUI/res/values-hr/strings.xml b/packages/SystemUI/res/values-hr/strings.xml
index 4b7f1cf..27b2e9c 100644
--- a/packages/SystemUI/res/values-hr/strings.xml
+++ b/packages/SystemUI/res/values-hr/strings.xml
@@ -346,8 +346,7 @@
<string name="guest_notification_text" msgid="335747957734796689">"Da biste izbrisali aplikacije i podatke, uklonite gostujućeg korisnika"</string>
<string name="guest_notification_remove_action" msgid="8820670703892101990">"UKLONI GOSTA"</string>
<string name="user_logout_notification_title" msgid="1453960926437240727">"Odjava korisnika"</string>
- <!-- no translation found for user_logout_notification_text (3350262809611876284) -->
- <skip />
+ <string name="user_logout_notification_text" msgid="3350262809611876284">"Odjava trenutačnog korisnika"</string>
<string name="user_logout_notification_action" msgid="1195428991423425062">"ODJAVI KORISNIKA"</string>
<string name="user_add_user_title" msgid="4553596395824132638">"Dodati novog korisnika?"</string>
<string name="user_add_user_message_short" msgid="2161624834066214559">"Kada dodate novog korisnika, ta osoba mora postaviti vlastiti prostor.\n\nBilo koji korisnik može ažurirati aplikacije za sve ostale korisnike."</string>
@@ -431,6 +430,5 @@
<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>
- <!-- no translation found for activity_not_found (348423244327799974) -->
- <skip />
+ <string name="activity_not_found" msgid="348423244327799974">"Aplikacija nije instalirana na vašem uređaju"</string>
</resources>
diff --git a/packages/SystemUI/res/values-hu/strings.xml b/packages/SystemUI/res/values-hu/strings.xml
index 0697bba..634bccc 100644
--- a/packages/SystemUI/res/values-hu/strings.xml
+++ b/packages/SystemUI/res/values-hu/strings.xml
@@ -345,8 +345,7 @@
<string name="guest_notification_text" msgid="335747957734796689">"Távolítsa el a vendéget az alkalmazások és adatok törléséhez"</string>
<string name="guest_notification_remove_action" msgid="8820670703892101990">"VENDÉG ELTÁVOLÍTÁSA"</string>
<string name="user_logout_notification_title" msgid="1453960926437240727">"Felhasználó kijelentkezése"</string>
- <!-- no translation found for user_logout_notification_text (3350262809611876284) -->
- <skip />
+ <string name="user_logout_notification_text" msgid="3350262809611876284">"Aktuális felhasználó kijelentkeztetése"</string>
<string name="user_logout_notification_action" msgid="1195428991423425062">"FELHASZNÁLÓ KIJELENTKEZÉSE"</string>
<string name="user_add_user_title" msgid="4553596395824132638">"Új felhasználó hozzáadása?"</string>
<string name="user_add_user_message_short" msgid="2161624834066214559">"Ha új felhasználót ad hozzá, az illetőnek be kell állítania saját tárterületét.\n\nBármely felhasználó frissítheti az alkalmazásokat valamennyi felhasználó számára."</string>
@@ -430,6 +429,5 @@
<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>
- <!-- no translation found for activity_not_found (348423244327799974) -->
- <skip />
+ <string name="activity_not_found" msgid="348423244327799974">"Az alkalmazás nincs telepítve eszközén."</string>
</resources>
diff --git a/packages/SystemUI/res/values-hy-rAM/strings.xml b/packages/SystemUI/res/values-hy-rAM/strings.xml
index 95e8634..b6d3f35 100644
--- a/packages/SystemUI/res/values-hy-rAM/strings.xml
+++ b/packages/SystemUI/res/values-hy-rAM/strings.xml
@@ -345,8 +345,7 @@
<string name="guest_notification_text" msgid="335747957734796689">"Հավելվածները և տվյալները ջնջելու համար հեռացրեք հյուրին"</string>
<string name="guest_notification_remove_action" msgid="8820670703892101990">"ՀԵՌԱՑՆԵԼ ՀՅՈՒՐԻՆ"</string>
<string name="user_logout_notification_title" msgid="1453960926437240727">"Ընթացիկ օգտվողի դուրս գրում"</string>
- <!-- no translation found for user_logout_notification_text (3350262809611876284) -->
- <skip />
+ <string name="user_logout_notification_text" msgid="3350262809611876284">"Ընթացիկ օգտվողի դուրս գրում"</string>
<string name="user_logout_notification_action" msgid="1195428991423425062">"ԸՆԹԱՑԻԿ ՕԳՏՎՈՂԻ ԴՈՒՐՍ ԳՐՈՒՄ"</string>
<string name="user_add_user_title" msgid="4553596395824132638">"Ավելացնե՞լ նոր պրոֆիլ:"</string>
<string name="user_add_user_message_short" msgid="2161624834066214559">"Երբ նոր օգտվող եք ավելացնում, նա պետք է կարգավորի իր պրոֆիլը:\n\nՑանկացած օգտվող կարող է թարմացնել հավելվածները մյուս բոլոր հաշիվների համար:"</string>
@@ -430,6 +429,5 @@
<string name="tuner_toast" msgid="603429811084428439">"Համակարգի ՕՄ-ի կարգավորիչը ավելացվել է կարգավորումներին"</string>
<string name="remove_from_settings" msgid="8389591916603406378">"Հեռացնել կարգավորումներից"</string>
<string name="remove_from_settings_prompt" msgid="6069085993355887748">"Հեռացնե՞լ Համակարգի ՕՄ-ի կարգավորիչը կարգավորումներից և չօգտվել այլևս նրա գործառույթներից:"</string>
- <!-- no translation found for activity_not_found (348423244327799974) -->
- <skip />
+ <string name="activity_not_found" msgid="348423244327799974">"Հավելվածը տեղադրված չէ սարքի վրա"</string>
</resources>
diff --git a/packages/SystemUI/res/values-in/strings.xml b/packages/SystemUI/res/values-in/strings.xml
index 02e0d6b..832dfcf 100644
--- a/packages/SystemUI/res/values-in/strings.xml
+++ b/packages/SystemUI/res/values-in/strings.xml
@@ -345,8 +345,7 @@
<string name="guest_notification_text" msgid="335747957734796689">"Untuk menghapus aplikasi dan data, hapus pengguna tamu"</string>
<string name="guest_notification_remove_action" msgid="8820670703892101990">"HAPUS TAMU"</string>
<string name="user_logout_notification_title" msgid="1453960926437240727">"Mengeluarkan pengguna"</string>
- <!-- no translation found for user_logout_notification_text (3350262809611876284) -->
- <skip />
+ <string name="user_logout_notification_text" msgid="3350262809611876284">"Keluarkan pengguna saat ini"</string>
<string name="user_logout_notification_action" msgid="1195428991423425062">"KELUARKAN PENGGUNA"</string>
<string name="user_add_user_title" msgid="4553596395824132638">"Tambahkan pengguna baru?"</string>
<string name="user_add_user_message_short" msgid="2161624834066214559">"Saat Anda menambahkan pengguna baru, orang tersebut perlu menyiapkan ruangnya sendiri.\n\n1Pengguna mana pun dapat memperbarui aplikasi untuk semua pengguna lain."</string>
@@ -430,6 +429,5 @@
<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>
- <!-- no translation found for activity_not_found (348423244327799974) -->
- <skip />
+ <string name="activity_not_found" msgid="348423244327799974">"Aplikasi tidak dipasang di perangkat"</string>
</resources>
diff --git a/packages/SystemUI/res/values-is-rIS/strings.xml b/packages/SystemUI/res/values-is-rIS/strings.xml
index 73ba5e2..5636e66 100644
--- a/packages/SystemUI/res/values-is-rIS/strings.xml
+++ b/packages/SystemUI/res/values-is-rIS/strings.xml
@@ -345,8 +345,7 @@
<string name="guest_notification_text" msgid="335747957734796689">"Til að eyða forritum og gögnum skal eyða gestanotanda"</string>
<string name="guest_notification_remove_action" msgid="8820670703892101990">"FJARLÆGJA GEST"</string>
<string name="user_logout_notification_title" msgid="1453960926437240727">"Skrá notanda út"</string>
- <!-- no translation found for user_logout_notification_text (3350262809611876284) -->
- <skip />
+ <string name="user_logout_notification_text" msgid="3350262809611876284">"Skrá núverandi notanda út"</string>
<string name="user_logout_notification_action" msgid="1195428991423425062">"SKRÁ NOTANDA ÚT"</string>
<string name="user_add_user_title" msgid="4553596395824132638">"Bæta nýjum notanda við?"</string>
<string name="user_add_user_message_short" msgid="2161624834066214559">"Þegar þú bætir nýjum notanda við þarf sá notandi að setja upp svæðið sitt.\n\nHvaða notandi sem er getur uppfært forrit fyrir alla aðra notendur."</string>
@@ -430,6 +429,5 @@
<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>
- <!-- no translation found for activity_not_found (348423244327799974) -->
- <skip />
+ <string name="activity_not_found" msgid="348423244327799974">"Forritið er ekki uppsett í tækinu."</string>
</resources>
diff --git a/packages/SystemUI/res/values-it/strings.xml b/packages/SystemUI/res/values-it/strings.xml
index ac8ffad..a98597b 100644
--- a/packages/SystemUI/res/values-it/strings.xml
+++ b/packages/SystemUI/res/values-it/strings.xml
@@ -347,8 +347,7 @@
<string name="guest_notification_text" msgid="335747957734796689">"Per eliminare app e dati, rimuovi l\'utente ospite"</string>
<string name="guest_notification_remove_action" msgid="8820670703892101990">"RIMUOVI OSPITE"</string>
<string name="user_logout_notification_title" msgid="1453960926437240727">"Disconnessione utente"</string>
- <!-- no translation found for user_logout_notification_text (3350262809611876284) -->
- <skip />
+ <string name="user_logout_notification_text" msgid="3350262809611876284">"Disconnetti utente corrente"</string>
<string name="user_logout_notification_action" msgid="1195428991423425062">"DISCONNETTI UTENTE"</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>
@@ -432,6 +431,5 @@
<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>
- <!-- no translation found for activity_not_found (348423244327799974) -->
- <skip />
+ <string name="activity_not_found" msgid="348423244327799974">"Applicazione non installata sul dispositivo"</string>
</resources>
diff --git a/packages/SystemUI/res/values-iw/strings.xml b/packages/SystemUI/res/values-iw/strings.xml
index da3eff8..bf8a41d 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="8572228137833020196">"המשתמש הנוכחי שמחובר למערכת במכשיר לא יכול להפעיל ניקוי באגים ב-USB. כדי להשתמש בתכונה זו, יש להיכנס כמנהל מערכת."</string>
+ <string name="usb_debugging_secondary_user_title" msgid="6353808721761220421">"לא ניתן לבצע ניפוי באגים ב-USB"</string>
+ <string name="usb_debugging_secondary_user_message" msgid="8572228137833020196">"המשתמש הנוכחי שמחובר למערכת במכשיר לא יכול להפעיל ניפוי באגים ב-USB. כדי להשתמש בתכונה זו, יש להיכנס כמנהל מערכת."</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>
@@ -347,8 +347,7 @@
<string name="guest_notification_text" msgid="335747957734796689">"הסר את המשתמש האורח כדי למחוק אפליקציות ונתונים"</string>
<string name="guest_notification_remove_action" msgid="8820670703892101990">"הסר אורח"</string>
<string name="user_logout_notification_title" msgid="1453960926437240727">"ניתוק משתמש"</string>
- <!-- no translation found for user_logout_notification_text (3350262809611876284) -->
- <skip />
+ <string name="user_logout_notification_text" msgid="3350262809611876284">"צא מהמשתמש הנוכחי"</string>
<string name="user_logout_notification_action" msgid="1195428991423425062">"נתק משתמש"</string>
<string name="user_add_user_title" msgid="4553596395824132638">"האם להוסיף משתמש חדש?"</string>
<string name="user_add_user_message_short" msgid="2161624834066214559">"בעת הוספת משתמש חדש, על משתמש זה להגדיר את השטח שלו.\n\nכל משתמש יכול לעדכן אפליקציות עבור כל המשתמשים האחרים."</string>
@@ -432,6 +431,5 @@
<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>
- <!-- no translation found for activity_not_found (348423244327799974) -->
- <skip />
+ <string name="activity_not_found" msgid="348423244327799974">"האפליקציה אינה מותקנת במכשיר"</string>
</resources>
diff --git a/packages/SystemUI/res/values-ja/strings.xml b/packages/SystemUI/res/values-ja/strings.xml
index d704e80..bd14b33 100644
--- a/packages/SystemUI/res/values-ja/strings.xml
+++ b/packages/SystemUI/res/values-ja/strings.xml
@@ -347,8 +347,7 @@
<string name="guest_notification_text" msgid="335747957734796689">"アプリとデータを削除するには、ゲストユーザーを削除します"</string>
<string name="guest_notification_remove_action" msgid="8820670703892101990">"ゲストを削除"</string>
<string name="user_logout_notification_title" msgid="1453960926437240727">"ユーザーのログアウト"</string>
- <!-- no translation found for user_logout_notification_text (3350262809611876284) -->
- <skip />
+ <string name="user_logout_notification_text" msgid="3350262809611876284">"現在のユーザーをログアウト"</string>
<string name="user_logout_notification_action" msgid="1195428991423425062">"ユーザーをログアウト"</string>
<string name="user_add_user_title" msgid="4553596395824132638">"新しいユーザーを追加しますか?"</string>
<string name="user_add_user_message_short" msgid="2161624834066214559">"新しいユーザーを追加したら、そのユーザーは自分のスペースをセットアップする必要があります。\n\nすべてのユーザーは他のユーザーに代わってアプリを更新できます。"</string>
@@ -432,6 +431,5 @@
<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>
- <!-- no translation found for activity_not_found (348423244327799974) -->
- <skip />
+ <string name="activity_not_found" msgid="348423244327799974">"アプリが端末にインストールされていません"</string>
</resources>
diff --git a/packages/SystemUI/res/values-ka-rGE/strings.xml b/packages/SystemUI/res/values-ka-rGE/strings.xml
index 3ddb3eb..6d567cc 100644
--- a/packages/SystemUI/res/values-ka-rGE/strings.xml
+++ b/packages/SystemUI/res/values-ka-rGE/strings.xml
@@ -345,8 +345,7 @@
<string name="guest_notification_text" msgid="335747957734796689">"აპებისა და მონაცემების წასაშლელად ამოშალეთ სტუმარი"</string>
<string name="guest_notification_remove_action" msgid="8820670703892101990">"სტუმრის ამოშლა"</string>
<string name="user_logout_notification_title" msgid="1453960926437240727">"მომხმარებლის გასვლა"</string>
- <!-- no translation found for user_logout_notification_text (3350262809611876284) -->
- <skip />
+ <string name="user_logout_notification_text" msgid="3350262809611876284">"მიმდინარე მომხმარებლის გამოყვანა"</string>
<string name="user_logout_notification_action" msgid="1195428991423425062">"მომხმარებლის გასვლა"</string>
<string name="user_add_user_title" msgid="4553596395824132638">"დაემატოს ახალი მომხმარებელი?"</string>
<string name="user_add_user_message_short" msgid="2161624834066214559">"ახალი მომხმარებლის დამატებისას, ამ მომხმარებელს საკუთარი სივრცის შექმნა მოუწევს.\n\nნებისმიერ მომხმარებელს შეუძლია აპები ყველა სხვა მომხმარებლისათვის განაახლოს."</string>
@@ -430,6 +429,5 @@
<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>
- <!-- no translation found for activity_not_found (348423244327799974) -->
- <skip />
+ <string name="activity_not_found" msgid="348423244327799974">"აპლიკაცია თქვენს მოწყობილობაზე დაყენებული არ არის"</string>
</resources>
diff --git a/packages/SystemUI/res/values-kk-rKZ/strings.xml b/packages/SystemUI/res/values-kk-rKZ/strings.xml
index d39c88e..6903b19 100644
--- a/packages/SystemUI/res/values-kk-rKZ/strings.xml
+++ b/packages/SystemUI/res/values-kk-rKZ/strings.xml
@@ -345,8 +345,7 @@
<string name="guest_notification_text" msgid="335747957734796689">"Қолданбалар мен деректерді жою үшін, қонақ пайдаланушыны алып тастаңыз"</string>
<string name="guest_notification_remove_action" msgid="8820670703892101990">"ҚОНАҚТЫ КЕТІРУ"</string>
<string name="user_logout_notification_title" msgid="1453960926437240727">"Пайдаланушыны шығару"</string>
- <!-- no translation found for user_logout_notification_text (3350262809611876284) -->
- <skip />
+ <string name="user_logout_notification_text" msgid="3350262809611876284">"Ағымдағы пайдаланушыны шығару"</string>
<string name="user_logout_notification_action" msgid="1195428991423425062">"ПАЙДАЛАНУШЫНЫ ШЫҒАРУ"</string>
<string name="user_add_user_title" msgid="4553596395824132638">"Жаңа пайд-ны қосу керек пе?"</string>
<string name="user_add_user_message_short" msgid="2161624834066214559">"Жаңа пайдаланушыны қосқанда сол адам өз кеңістігін реттеуі керек.\n\nКез келген пайдаланушы барлық басқа пайдаланушылар үшін қолданбаларды жаңарта алады."</string>
@@ -430,6 +429,5 @@
<string name="tuner_toast" msgid="603429811084428439">"Құттықтаймыз! Жүйелік пайдаланушылық интерфейс тюнері \"Параметрлер\" тармағына қосылды"</string>
<string name="remove_from_settings" msgid="8389591916603406378">"Параметрлерден жою"</string>
<string name="remove_from_settings_prompt" msgid="6069085993355887748">"Жүйелік пайдаланушылық интерфейс тюнерін \"Параметрлер\" тармағынан жойып, оның барлық мүмкіндіктерін пайдалануды тоқтату керек пе?"</string>
- <!-- no translation found for activity_not_found (348423244327799974) -->
- <skip />
+ <string name="activity_not_found" msgid="348423244327799974">"Қолданба құрылғыда орнатылмаған"</string>
</resources>
diff --git a/packages/SystemUI/res/values-km-rKH/strings.xml b/packages/SystemUI/res/values-km-rKH/strings.xml
index aeeb75b..d24b070 100644
--- a/packages/SystemUI/res/values-km-rKH/strings.xml
+++ b/packages/SystemUI/res/values-km-rKH/strings.xml
@@ -345,8 +345,7 @@
<string name="guest_notification_text" msgid="335747957734796689">"ដើម្បីលុបកម្មវិធី និងទិន្នន័យ សូមយកអ្នកប្រើជាភ្ញៀវចេញ"</string>
<string name="guest_notification_remove_action" msgid="8820670703892101990">"យកភ្ញៀវចេញ"</string>
<string name="user_logout_notification_title" msgid="1453960926437240727">"ចុះឈ្មោះអ្នកប្រើចេញ"</string>
- <!-- no translation found for user_logout_notification_text (3350262809611876284) -->
- <skip />
+ <string name="user_logout_notification_text" msgid="3350262809611876284">"ចុះឈ្មោះអ្នកប្រើបច្ចុប្បន្នចេញ"</string>
<string name="user_logout_notification_action" msgid="1195428991423425062">"ចុះឈ្មោះអ្នកប្រើចេញ"</string>
<string name="user_add_user_title" msgid="4553596395824132638">"បន្ថែមអ្នកប្រើថ្មី?"</string>
<string name="user_add_user_message_short" msgid="2161624834066214559">"ពេលអ្នកបន្ថែមអ្នកប្រើថ្មី អ្នកប្រើនោះត្រូវកំណត់ទំហំផ្ទាល់របស់គេ។\n\nអ្នកប្រើណាមួយក៏អាចធ្វើបច្ចុប្បន្នភាពកម្មវិធីសម្រាប់អ្នកប្រើផ្សេងបានដែរ។"</string>
@@ -430,6 +429,5 @@
<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>
- <!-- no translation found for activity_not_found (348423244327799974) -->
- <skip />
+ <string name="activity_not_found" msgid="348423244327799974">"កម្មវិធីមិនបានដំឡើងនៅលើឧបករណ៍របស់អ្នកទេ"</string>
</resources>
diff --git a/packages/SystemUI/res/values-kn-rIN/strings.xml b/packages/SystemUI/res/values-kn-rIN/strings.xml
index 67d56c7..baaba3c 100644
--- a/packages/SystemUI/res/values-kn-rIN/strings.xml
+++ b/packages/SystemUI/res/values-kn-rIN/strings.xml
@@ -345,8 +345,7 @@
<string name="guest_notification_text" msgid="335747957734796689">"ಅಪ್ಲಿಕೇಶನ್ಗಳು ಮತ್ತು ಡೇಟಾ ಅಳಿಸಲು, ಅತಿಥಿ ಬಳಕೆದಾರರನ್ನು ತೆಗೆದುಹಾಕಿ"</string>
<string name="guest_notification_remove_action" msgid="8820670703892101990">"ಅತಿಥಿಯನ್ನು ತೆಗೆದುಹಾಕಿ"</string>
<string name="user_logout_notification_title" msgid="1453960926437240727">"ಬಳಕೆದಾರರನ್ನು ಲಾಗ್ಔಟ್ ಮಾಡಿ"</string>
- <!-- no translation found for user_logout_notification_text (3350262809611876284) -->
- <skip />
+ <string name="user_logout_notification_text" msgid="3350262809611876284">"ಪ್ರಸ್ತುತ ಬಳಕೆದಾರರನ್ನು ಲಾಗ್ಔಟ್ ಮಾಡಿ"</string>
<string name="user_logout_notification_action" msgid="1195428991423425062">"ಬಳಕೆದಾರರನ್ನು ಲಾಗ್ಔಟ್ ಮಾಡಿ"</string>
<string name="user_add_user_title" msgid="4553596395824132638">"ಹೊಸ ಬಳಕೆದಾರರನ್ನು ಸೇರಿಸುವುದೇ?"</string>
<string name="user_add_user_message_short" msgid="2161624834066214559">"ನೀವು ಒಬ್ಬ ಹೊಸ ಬಳಕೆದಾರರನ್ನು ಸೇರಿಸಿದಾಗ, ಆ ವ್ಯಕ್ತಿಯು ಅವರ ಸ್ಥಳವನ್ನು ಸ್ಥಾಪಿಸಬೇಕಾಗುತ್ತದೆ.\n\nಯಾವುದೇ ಬಳಕೆದಾರರು ಎಲ್ಲಾ ಇತರೆ ಬಳಕೆದಾರರಿಗಾಗಿ ಅಪ್ಲಿಕೇಶನ್ಗಳನ್ನು ನವೀಕರಿಸಬಹುದು."</string>
@@ -430,6 +429,5 @@
<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>
- <!-- no translation found for activity_not_found (348423244327799974) -->
- <skip />
+ <string name="activity_not_found" msgid="348423244327799974">"ನಿಮ್ಮ ಸಾಧನದಲ್ಲಿ ಅಪ್ಲಿಕೇಶನ್ ಅನ್ನು ಸ್ಥಾಪಿಸಲಾಗಿಲ್ಲ"</string>
</resources>
diff --git a/packages/SystemUI/res/values-ko/strings.xml b/packages/SystemUI/res/values-ko/strings.xml
index 582dbfa..e8a19c8 100644
--- a/packages/SystemUI/res/values-ko/strings.xml
+++ b/packages/SystemUI/res/values-ko/strings.xml
@@ -345,8 +345,7 @@
<string name="guest_notification_text" msgid="335747957734796689">"앱 및 데이터를 삭제하려면 게스트 사용자를 삭제하세요."</string>
<string name="guest_notification_remove_action" msgid="8820670703892101990">"게스트 삭제"</string>
<string name="user_logout_notification_title" msgid="1453960926437240727">"사용자 로그아웃"</string>
- <!-- no translation found for user_logout_notification_text (3350262809611876284) -->
- <skip />
+ <string name="user_logout_notification_text" msgid="3350262809611876284">"현재 사용자 로그아웃"</string>
<string name="user_logout_notification_action" msgid="1195428991423425062">"사용자 로그아웃"</string>
<string name="user_add_user_title" msgid="4553596395824132638">"새 사용자를 추가할까요?"</string>
<string name="user_add_user_message_short" msgid="2161624834066214559">"추가된 새로운 사용자는 자신의 공간을 설정해야 합니다.\n\n모든 사용자는 다른 사용자들을 위하여 앱을 업데이트할 수 있습니다."</string>
@@ -430,6 +429,5 @@
<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>
- <!-- no translation found for activity_not_found (348423244327799974) -->
- <skip />
+ <string name="activity_not_found" msgid="348423244327799974">"기기에 애플리케이션이 설치되어 있지 않습니다."</string>
</resources>
diff --git a/packages/SystemUI/res/values-ky-rKG/strings.xml b/packages/SystemUI/res/values-ky-rKG/strings.xml
index fa00137..5f88549 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="8572228137833020196">"Учурда ушул түзмөккө кирген колдонуучу USB мүчүлүштүктөрүн оңдоо функциясын күйгүзө албайт. Бул функцияны урунуу үчүн, администратордун каттоо эсебине которулуңуз."</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>
@@ -370,8 +345,7 @@
<string name="guest_notification_text" msgid="335747957734796689">"Клднмлр ж-а дйндрды жок кылуу ү-н, конок колднчсн алып салңз"</string>
<string name="guest_notification_remove_action" msgid="8820670703892101990">"КОНОКТУ АЛЫП САЛУУ"</string>
<string name="user_logout_notification_title" msgid="1453960926437240727">"Колдонуучуну тутумдан чыгаруу"</string>
- <!-- no translation found for user_logout_notification_text (3350262809611876284) -->
- <skip />
+ <string name="user_logout_notification_text" msgid="3350262809611876284">"Учурдагы колдонуучуну тутумдан чыгаруу"</string>
<string name="user_logout_notification_action" msgid="1195428991423425062">"КОЛДОНУУЧУНУ ТУТУМДАН ЧЫГАРУУ"</string>
<string name="user_add_user_title" msgid="4553596395824132638">"Жаңы колдонуучу кошосузбу?"</string>
<string name="user_add_user_message_short" msgid="2161624834066214559">"Жаңы колдонуучу кошулганда, ал өз мейкиндигин түзүп алышы керек.\n\nКолдонмолорду бир колдонуучу жаңыртканда, ал калган бардык колдонуучулар үчүн да жаңырат."</string>
@@ -455,6 +429,5 @@
<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>
- <!-- no translation found for activity_not_found (348423244327799974) -->
- <skip />
+ <string name="activity_not_found" msgid="348423244327799974">"Колдонмо сиздин түзмөгүңүздө орнотулган эмес"</string>
</resources>
diff --git a/packages/SystemUI/res/values-lo-rLA/strings.xml b/packages/SystemUI/res/values-lo-rLA/strings.xml
index bcafb6f..4a4140d 100644
--- a/packages/SystemUI/res/values-lo-rLA/strings.xml
+++ b/packages/SystemUI/res/values-lo-rLA/strings.xml
@@ -345,8 +345,7 @@
<string name="guest_notification_text" msgid="335747957734796689">"ເພື່ອລຶບແອັບ ແລະຂໍ້ມູນ, ໃຫ້ເອົາຜູ້ໃຊ້ທີ່ເປັນແຂກອອກ"</string>
<string name="guest_notification_remove_action" msgid="8820670703892101990">"ເອົາແຂກອອກ"</string>
<string name="user_logout_notification_title" msgid="1453960926437240727">"ເອົາຜູ້ໃຊ້ອອກຈາກລະບົບ"</string>
- <!-- no translation found for user_logout_notification_text (3350262809611876284) -->
- <skip />
+ <string name="user_logout_notification_text" msgid="3350262809611876284">"ອອກຈາກຜູ້ໃຊ້ປະຈຸບັນ"</string>
<string name="user_logout_notification_action" msgid="1195428991423425062">"ເອົາຜູ້ໃຊ້ອອກຈາກລະບົບ"</string>
<string name="user_add_user_title" msgid="4553596395824132638">"ເພີ່ມຜູ່ໃຊ້ໃໝ່ບໍ?"</string>
<string name="user_add_user_message_short" msgid="2161624834066214559">"ເມື່ອທ່ານເພີ່ມຜູ່ໃຊ້ໃໝ່, ຜູ່ໃຊ້ນັ້ນຈະຕ້ອງຕັ້ງຄ່າພື້ນທີ່ບ່ອນຈັດເກັບຂໍ້ມູນຂອງລາວ.\n\nຜູ່ໃຊ້ທຸກຄົນສາມາດອັບເດດແອັບຯຂອງຜູ່ໃຊ້ຄົນອື່ນທັງໝົດໄດ້."</string>
@@ -430,6 +429,5 @@
<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>
- <!-- no translation found for activity_not_found (348423244327799974) -->
- <skip />
+ <string name="activity_not_found" msgid="348423244327799974">"ແອັບພລິເຄຊັນບໍ່ຖືກຕິດຕັ້ງຢູ່ໃນອຸປະກອນຂອງທ່ານ"</string>
</resources>
diff --git a/packages/SystemUI/res/values-lt/strings.xml b/packages/SystemUI/res/values-lt/strings.xml
index 03898de..39b48b1 100644
--- a/packages/SystemUI/res/values-lt/strings.xml
+++ b/packages/SystemUI/res/values-lt/strings.xml
@@ -347,8 +347,7 @@
<string name="guest_notification_text" msgid="335747957734796689">"Kad būtų ištr. programos ir duom., pašal. naudotoją svečią"</string>
<string name="guest_notification_remove_action" msgid="8820670703892101990">"PAŠALINTI SVEČIĄ"</string>
<string name="user_logout_notification_title" msgid="1453960926437240727">"Naudotojo atjungimas"</string>
- <!-- no translation found for user_logout_notification_text (3350262809611876284) -->
- <skip />
+ <string name="user_logout_notification_text" msgid="3350262809611876284">"Atjungti dabartinį naudotoją"</string>
<string name="user_logout_notification_action" msgid="1195428991423425062">"ATJUNGTI NAUDOTOJĄ"</string>
<string name="user_add_user_title" msgid="4553596395824132638">"Pridėti naują naudotoją?"</string>
<string name="user_add_user_message_short" msgid="2161624834066214559">"Kai pridedate naują naudotoją, šis asmuo turi nustatyti savo erdvę.\n\nBet kuris naudotojas gali atnaujinti visų kitų naudotojų programas."</string>
@@ -432,6 +431,5 @@
<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>
- <!-- no translation found for activity_not_found (348423244327799974) -->
- <skip />
+ <string name="activity_not_found" msgid="348423244327799974">"Programa neįdiegta įrenginyje"</string>
</resources>
diff --git a/packages/SystemUI/res/values-lv/strings.xml b/packages/SystemUI/res/values-lv/strings.xml
index b5863fc..df7a292 100644
--- a/packages/SystemUI/res/values-lv/strings.xml
+++ b/packages/SystemUI/res/values-lv/strings.xml
@@ -346,8 +346,7 @@
<string name="guest_notification_text" msgid="335747957734796689">"Lai dzēstu lietotnes un datus, noņemiet vieslietotāju."</string>
<string name="guest_notification_remove_action" msgid="8820670703892101990">"NOŅEMT VIESI"</string>
<string name="user_logout_notification_title" msgid="1453960926437240727">"Lietotāja atteikšana"</string>
- <!-- no translation found for user_logout_notification_text (3350262809611876284) -->
- <skip />
+ <string name="user_logout_notification_text" msgid="3350262809611876284">"Atsakiet pašreizējo lietotāju"</string>
<string name="user_logout_notification_action" msgid="1195428991423425062">"ATTEIKT LIETOTĀJU"</string>
<string name="user_add_user_title" msgid="4553596395824132638">"Vai pievienot jaunu lietotāju?"</string>
<string name="user_add_user_message_short" msgid="2161624834066214559">"Kad pievienosiet jaunu lietotāju, viņam būs jāizveido savs profils.\n\nIkviens lietotājs var atjaunināt lietotnes citu lietotāju vietā."</string>
@@ -431,6 +430,5 @@
<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>
- <!-- no translation found for activity_not_found (348423244327799974) -->
- <skip />
+ <string name="activity_not_found" msgid="348423244327799974">"Lietojumprogramma nav instalēta jūsu ierīcē."</string>
</resources>
diff --git a/packages/SystemUI/res/values-mk-rMK/strings.xml b/packages/SystemUI/res/values-mk-rMK/strings.xml
index 467a0c8..5743762 100644
--- a/packages/SystemUI/res/values-mk-rMK/strings.xml
+++ b/packages/SystemUI/res/values-mk-rMK/strings.xml
@@ -347,8 +347,7 @@
<string name="guest_notification_text" msgid="335747957734796689">"За да избришете апликации и податоци, отстранете го гостинот"</string>
<string name="guest_notification_remove_action" msgid="8820670703892101990">"ОТСТРАНИ ГОСТИН"</string>
<string name="user_logout_notification_title" msgid="1453960926437240727">"Одјави го корисникот"</string>
- <!-- no translation found for user_logout_notification_text (3350262809611876284) -->
- <skip />
+ <string name="user_logout_notification_text" msgid="3350262809611876284">"Одјавете го тековниот корисник"</string>
<string name="user_logout_notification_action" msgid="1195428991423425062">"ОДЈАВИ ГО КОРИСНИКОТ"</string>
<string name="user_add_user_title" msgid="4553596395824132638">"Да се додаде нов корисник?"</string>
<string name="user_add_user_message_short" msgid="2161624834066214559">"Кога додавате нов корисник, тоа лице треба да го постави својот простор.\n\nСекој корисник може да ажурира апликации за сите други корисници."</string>
@@ -432,6 +431,5 @@
<string name="tuner_toast" msgid="603429811084428439">"Честито! Го додадовте Адаптерот на УИ на системот на Поставки"</string>
<string name="remove_from_settings" msgid="8389591916603406378">"Отстрани од поставки"</string>
<string name="remove_from_settings_prompt" msgid="6069085993355887748">"Да се отстрани Адаптерот на УИ на системот од Поставки и да престанат да се користат сите негови функции?"</string>
- <!-- no translation found for activity_not_found (348423244327799974) -->
- <skip />
+ <string name="activity_not_found" msgid="348423244327799974">"Апликацијата не е инсталирана на уредот"</string>
</resources>
diff --git a/packages/SystemUI/res/values-ml-rIN/strings.xml b/packages/SystemUI/res/values-ml-rIN/strings.xml
index 9a5c352..b7fdeae 100644
--- a/packages/SystemUI/res/values-ml-rIN/strings.xml
+++ b/packages/SystemUI/res/values-ml-rIN/strings.xml
@@ -345,8 +345,7 @@
<string name="guest_notification_text" msgid="335747957734796689">"ആപ്സും വിവരങ്ങളും ഇല്ലാതാക്കാൻ അതിഥി ഉപയോക്താവിനെ നീക്കുക"</string>
<string name="guest_notification_remove_action" msgid="8820670703892101990">"അതിഥിയെ നീക്കംചെയ്യുക"</string>
<string name="user_logout_notification_title" msgid="1453960926437240727">"ഉപയോക്താവിനെ ലോഗൗട്ട് ചെയ്യുക"</string>
- <!-- no translation found for user_logout_notification_text (3350262809611876284) -->
- <skip />
+ <string name="user_logout_notification_text" msgid="3350262809611876284">"നിലവിലെ ഉപയോക്താവിനെ ലോഗൗട്ട് ചെയ്യുക"</string>
<string name="user_logout_notification_action" msgid="1195428991423425062">"ഉപയോക്താവിനെ ലോഗൗട്ട് ചെയ്യുക"</string>
<string name="user_add_user_title" msgid="4553596395824132638">"പുതിയ ഉപയോക്താവിനെ ചേർക്കണോ?"</string>
<string name="user_add_user_message_short" msgid="2161624834066214559">"നിങ്ങൾ ഒരു പുതിയ ഉപയോക്താവിനെ ചേർക്കുമ്പോൾ, ആ വ്യക്തിയ്ക്ക് അവരുടെ ഇടം സജ്ജീകരിക്കേണ്ടതുണ്ട്.\n\nമറ്റ് എല്ലാ ഉപയോക്താക്കൾക്കുമായി ഏതൊരു ഉപയോക്താവിനും അപ്ലിക്കേഷനുകൾ അപ്ഡേറ്റുചെയ്യാനാവും."</string>
@@ -430,6 +429,5 @@
<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>
- <!-- no translation found for activity_not_found (348423244327799974) -->
- <skip />
+ <string name="activity_not_found" msgid="348423244327799974">"നിങ്ങളുടെ ഉപകരണത്തിൽ അപ്ലിക്കേഷൻ ഇൻസ്റ്റാൾ ചെയ്തിട്ടില്ല"</string>
</resources>
diff --git a/packages/SystemUI/res/values-mn-rMN/strings.xml b/packages/SystemUI/res/values-mn-rMN/strings.xml
index f6cca1a..5d61c88 100644
--- a/packages/SystemUI/res/values-mn-rMN/strings.xml
+++ b/packages/SystemUI/res/values-mn-rMN/strings.xml
@@ -343,8 +343,7 @@
<string name="guest_notification_text" msgid="335747957734796689">"Апп болон өгөгдлийг устгахын тулд зочин хэрэглэгчийг хасна уу"</string>
<string name="guest_notification_remove_action" msgid="8820670703892101990">"ЗОЧНЫГ ГАРГАХ"</string>
<string name="user_logout_notification_title" msgid="1453960926437240727">"Хэрэглэгчээс гарах"</string>
- <!-- no translation found for user_logout_notification_text (3350262809611876284) -->
- <skip />
+ <string name="user_logout_notification_text" msgid="3350262809611876284">"Одоогийн хэрэглэгчийг гаргах"</string>
<string name="user_logout_notification_action" msgid="1195428991423425062">"ХЭРЭГЛЭГЧЭЭС ГАРАХ"</string>
<string name="user_add_user_title" msgid="4553596395824132638">"Шинэ хэрэглэгч нэмэх үү?"</string>
<string name="user_add_user_message_short" msgid="2161624834066214559">"Та шинэ хэрэглэгч нэмбэл, тухайн хүн өөрийн профайлыг тохируулах шаардлагатай.\n\nАль ч хэрэглэгч бүх хэрэглэгчийн апп-уудыг шинэчлэх боломжтой."</string>
@@ -428,6 +427,5 @@
<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>
- <!-- no translation found for activity_not_found (348423244327799974) -->
- <skip />
+ <string name="activity_not_found" msgid="348423244327799974">"Апп-ыг таны төхөөрөмжид суулгаагүй байна"</string>
</resources>
diff --git a/packages/SystemUI/res/values-mr-rIN/strings.xml b/packages/SystemUI/res/values-mr-rIN/strings.xml
index c3b0bcd8..8f43871 100644
--- a/packages/SystemUI/res/values-mr-rIN/strings.xml
+++ b/packages/SystemUI/res/values-mr-rIN/strings.xml
@@ -345,8 +345,7 @@
<string name="guest_notification_text" msgid="335747957734796689">"अॅप्स आणि डेटा हटविण्यासाठी, अतिथी वापरकर्ता काढा"</string>
<string name="guest_notification_remove_action" msgid="8820670703892101990">"अतिथी काढा"</string>
<string name="user_logout_notification_title" msgid="1453960926437240727">"वापरकर्त्यास लॉगआउट करा"</string>
- <!-- no translation found for user_logout_notification_text (3350262809611876284) -->
- <skip />
+ <string name="user_logout_notification_text" msgid="3350262809611876284">"वर्तमान वापरकर्ता लॉगआउट करा"</string>
<string name="user_logout_notification_action" msgid="1195428991423425062">"वापरकर्त्यास लॉगआउट करा"</string>
<string name="user_add_user_title" msgid="4553596395824132638">"नवीन वापरकर्ता जोडायचा?"</string>
<string name="user_add_user_message_short" msgid="2161624834066214559">"आपण एक नवीन वापरकर्ता जोडता तेव्हा, त्या व्यक्तीने त्यांचे स्थान सेट करणे आवश्यक असते.\n\nकोणताही वापरकर्ता इतर सर्व वापरकर्त्यांसाठी अॅप्स अद्यतनित करू शकतो."</string>
@@ -430,6 +429,5 @@
<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>
- <!-- no translation found for activity_not_found (348423244327799974) -->
- <skip />
+ <string name="activity_not_found" msgid="348423244327799974">"अनुप्रयोग आपल्या डिव्हाइसवर स्थापित केलेला नाही"</string>
</resources>
diff --git a/packages/SystemUI/res/values-ms-rMY/strings.xml b/packages/SystemUI/res/values-ms-rMY/strings.xml
index 61e8525..08a4dec 100644
--- a/packages/SystemUI/res/values-ms-rMY/strings.xml
+++ b/packages/SystemUI/res/values-ms-rMY/strings.xml
@@ -345,8 +345,7 @@
<string name="guest_notification_text" msgid="335747957734796689">"Untuk memadamkan apl dan data, alih keluar pengguna tetamu"</string>
<string name="guest_notification_remove_action" msgid="8820670703892101990">"ALIH KELUAR TETAMU"</string>
<string name="user_logout_notification_title" msgid="1453960926437240727">"Log keluar pengguna"</string>
- <!-- no translation found for user_logout_notification_text (3350262809611876284) -->
- <skip />
+ <string name="user_logout_notification_text" msgid="3350262809611876284">"Log keluar pengguna semasa"</string>
<string name="user_logout_notification_action" msgid="1195428991423425062">"LOG KELUAR PENGGUNA"</string>
<string name="user_add_user_title" msgid="4553596395824132638">"Tambah pengguna baharu?"</string>
<string name="user_add_user_message_short" msgid="2161624834066214559">"Apabila anda menambah pengguna baharu, orang itu perlu menyediakan ruang mereka.\n\nMana-mana pengguna boleh mengemas kini apl untuk semua pengguna lain."</string>
@@ -430,6 +429,5 @@
<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>
- <!-- no translation found for activity_not_found (348423244327799974) -->
- <skip />
+ <string name="activity_not_found" msgid="348423244327799974">"Aplikasi tidak dipasang pada peranti anda"</string>
</resources>
diff --git a/packages/SystemUI/res/values-my-rMM/strings.xml b/packages/SystemUI/res/values-my-rMM/strings.xml
index 6763dac..4551f64 100644
--- a/packages/SystemUI/res/values-my-rMM/strings.xml
+++ b/packages/SystemUI/res/values-my-rMM/strings.xml
@@ -345,8 +345,7 @@
<string name="guest_notification_text" msgid="335747957734796689">"App များနှင့် ဒေတာအား ဖျက်ရန်၊ တခဏသုံးစွဲသူအား ဖယ်ရှားပါ"</string>
<string name="guest_notification_remove_action" msgid="8820670703892101990">"ဧည့်သည်ကို ဖယ်ထုတ်မည်"</string>
<string name="user_logout_notification_title" msgid="1453960926437240727">"အသုံးပြုသူ ထွက်လိုက်ပါ"</string>
- <!-- no translation found for user_logout_notification_text (3350262809611876284) -->
- <skip />
+ <string name="user_logout_notification_text" msgid="3350262809611876284">"လက်ရှိ အသုံးပြုသူကို ထုတ်ပစ်ရန်"</string>
<string name="user_logout_notification_action" msgid="1195428991423425062">"အသုံးပြုသူ ထွက်လိုက်ပါ"</string>
<string name="user_add_user_title" msgid="4553596395824132638">"အသုံးပြုသူ အသစ်ကို ထည့်ရမလား?"</string>
<string name="user_add_user_message_short" msgid="2161624834066214559">"သင်က အသုံးပြုသူ အသစ် တစ်ဦးကို ထည့်ပေးလိုက်လျှင်၊ ထိုသူသည် ၎င်း၏ နေရာကို သတ်မှတ်စီစဉ်ရန် လိုအပ်မည်။\n\n အသုံးပြုသူ မည်သူမဆို ကျန်အသုံးပြုသူ အားလုံးတို့အတွက် appများကို မွမ်းမံပေးနိုင်သည်။"</string>
@@ -430,6 +429,5 @@
<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>
- <!-- no translation found for activity_not_found (348423244327799974) -->
- <skip />
+ <string name="activity_not_found" msgid="348423244327799974">"အပလီကေးရှင်းကို သင်၏ ကိရိယာထဲသို့ တပ်ဆင်မပေးရသေးပါ။"</string>
</resources>
diff --git a/packages/SystemUI/res/values-nb/strings.xml b/packages/SystemUI/res/values-nb/strings.xml
index f45bd85..70308ce 100644
--- a/packages/SystemUI/res/values-nb/strings.xml
+++ b/packages/SystemUI/res/values-nb/strings.xml
@@ -345,8 +345,7 @@
<string name="guest_notification_text" msgid="335747957734796689">"Fjern gjesten for å slette appene og dataene"</string>
<string name="guest_notification_remove_action" msgid="8820670703892101990">"FJERN GJEST"</string>
<string name="user_logout_notification_title" msgid="1453960926437240727">"Logg ut bruker"</string>
- <!-- no translation found for user_logout_notification_text (3350262809611876284) -->
- <skip />
+ <string name="user_logout_notification_text" msgid="3350262809611876284">"Logg av nåværende bruker"</string>
<string name="user_logout_notification_action" msgid="1195428991423425062">"LOGG UT BRUKER"</string>
<string name="user_add_user_title" msgid="4553596395824132638">"Vil du legge til en ny bruker?"</string>
<string name="user_add_user_message_short" msgid="2161624834066214559">"Når du legger til en ny bruker, må vedkommende konfigurere sitt eget område.\n\nAlle brukere kan oppdatere apper for alle andre brukere."</string>
@@ -430,6 +429,5 @@
<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>
- <!-- no translation found for activity_not_found (348423244327799974) -->
- <skip />
+ <string name="activity_not_found" msgid="348423244327799974">"Appen er ikke installert på enheten din"</string>
</resources>
diff --git a/packages/SystemUI/res/values-ne-rNP/strings.xml b/packages/SystemUI/res/values-ne-rNP/strings.xml
index 059bfb2..027e2f1 100644
--- a/packages/SystemUI/res/values-ne-rNP/strings.xml
+++ b/packages/SystemUI/res/values-ne-rNP/strings.xml
@@ -345,8 +345,7 @@
<string name="guest_notification_text" msgid="335747957734796689">"अनुप्रयोगहरू र डेटा मेटाउन, अतिथि प्रयोगकर्ता हटाउनुहोस्"</string>
<string name="guest_notification_remove_action" msgid="8820670703892101990">"अतिथिलाई हटाउनुहोस्"</string>
<string name="user_logout_notification_title" msgid="1453960926437240727">"प्रयोगकर्ता लगआउट गर्नुहोस्"</string>
- <!-- no translation found for user_logout_notification_text (3350262809611876284) -->
- <skip />
+ <string name="user_logout_notification_text" msgid="3350262809611876284">"वर्तमान प्रयोगकर्ता लगआउट गर्नुहोस्"</string>
<string name="user_logout_notification_action" msgid="1195428991423425062">"प्रयोगकर्ता लगआउट गर्नुहोस्"</string>
<string name="user_add_user_title" msgid="4553596395824132638">"नयाँ प्रयोगकर्ता थप्नुहुन्छ?"</string>
<string name="user_add_user_message_short" msgid="2161624834066214559">"जब तपाईँले नयाँ प्रयोगकर्ता थप्नुहुन्छ, त्यस प्रयोगकर्ताले आफ्नो स्थान स्थापना गर्न पर्ने छ।\n\nकुनै पनि प्रयोगकर्ताले सबै अन्य प्रयोगकर्ताहरूका लागि अनुप्रयोगहरू अद्यावधिक गर्न सक्छन्।"</string>
@@ -430,6 +429,5 @@
<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>
- <!-- no translation found for activity_not_found (348423244327799974) -->
- <skip />
+ <string name="activity_not_found" msgid="348423244327799974">"तपाईँको यन्त्रमा अनुप्रयोग स्थापना भएको छैन"</string>
</resources>
diff --git a/packages/SystemUI/res/values-nl/strings.xml b/packages/SystemUI/res/values-nl/strings.xml
index a798618..a4aa1c4 100644
--- a/packages/SystemUI/res/values-nl/strings.xml
+++ b/packages/SystemUI/res/values-nl/strings.xml
@@ -345,8 +345,7 @@
<string name="guest_notification_text" msgid="335747957734796689">"Verwijder gastgebruiker om apps en gegevens te verwijderen"</string>
<string name="guest_notification_remove_action" msgid="8820670703892101990">"GAST VERWIJDEREN"</string>
<string name="user_logout_notification_title" msgid="1453960926437240727">"Gebruiker uitloggen"</string>
- <!-- no translation found for user_logout_notification_text (3350262809611876284) -->
- <skip />
+ <string name="user_logout_notification_text" msgid="3350262809611876284">"Huidige gebruiker uitloggen"</string>
<string name="user_logout_notification_action" msgid="1195428991423425062">"GEBRUIKER UITLOGGEN"</string>
<string name="user_add_user_title" msgid="4553596395824132638">"Nieuwe gebruiker toevoegen?"</string>
<string name="user_add_user_message_short" msgid="2161624834066214559">"Wanneer u een nieuwe gebruiker toevoegt, moet die persoon zijn eigen profiel instellen.\n\n1Elke gebruiker kan apps updaten voor alle andere gebruikers."</string>
@@ -430,6 +429,5 @@
<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>
- <!-- no translation found for activity_not_found (348423244327799974) -->
- <skip />
+ <string name="activity_not_found" msgid="348423244327799974">"Deze app is niet geïnstalleerd op uw apparaat"</string>
</resources>
diff --git a/packages/SystemUI/res/values-pa-rIN/strings.xml b/packages/SystemUI/res/values-pa-rIN/strings.xml
index 6b86a59..fc9d600 100644
--- a/packages/SystemUI/res/values-pa-rIN/strings.xml
+++ b/packages/SystemUI/res/values-pa-rIN/strings.xml
@@ -345,8 +345,7 @@
<string name="guest_notification_text" msgid="335747957734796689">"ਐਪਸ ਅਤੇ ਡਾਟਾ ਮਿਟਾਉਣ ਲਈ, ਮਹਿਮਾਨ ਉਪਭੋਗਤਾ ਹਟਾਓ"</string>
<string name="guest_notification_remove_action" msgid="8820670703892101990">"ਮਹਿਮਾਨ ਨੂੰ ਹਟਾਓ"</string>
<string name="user_logout_notification_title" msgid="1453960926437240727">"ਉਪਭੋਗਤਾ ਨੂੰ ਲੌਗ ਆਉਟ ਕਰੋ"</string>
- <!-- no translation found for user_logout_notification_text (3350262809611876284) -->
- <skip />
+ <string name="user_logout_notification_text" msgid="3350262809611876284">"ਵਰਤਮਾਨ ਉਪਭੋਗਤਾ ਨੂੰ ਲੌਗਆਉਟ ਕਰੋ"</string>
<string name="user_logout_notification_action" msgid="1195428991423425062">"ਉਪਭੋਗਤਾ ਨੂੰ ਲੌਗ ਆਉਟ ਕਰੋ"</string>
<string name="user_add_user_title" msgid="4553596395824132638">"ਕੀ ਨਵਾਂ ਉਪਭੋਗਤਾ ਜੋੜਨਾ ਹੈ?"</string>
<string name="user_add_user_message_short" msgid="2161624834066214559">"ਜਦੋਂ ਤੁਸੀਂ ਇੱਕ ਨਵਾਂ ਉਪਭੋਗਤਾ ਜੋੜਦੇ ਹੋ, ਉਸ ਵਿਅਕਤੀ ਨੂੰ ਆਪਣਾ ਸਪੇਸ ਸੈਟ ਅਪ ਕਰਨ ਦੀ ਲੋੜ ਹੁੰਦੀ ਹੈ।\n\nਕੋਈ ਵੀ ਉਪਭੋਗਤਾ ਹੋਰ ਸਾਰੇ ਉਪਭੋਗਤਾਵਾਂ ਦੇ ਐਪਸ ਨੂੰ ਅਪਡੇਟ ਕਰ ਸਕਦਾ ਹੈ।"</string>
@@ -430,6 +429,5 @@
<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>
- <!-- no translation found for activity_not_found (348423244327799974) -->
- <skip />
+ <string name="activity_not_found" msgid="348423244327799974">"ਐਪਲੀਕੇਸ਼ਨ ਤੁਹਾਡੀ ਡਿਵਾਈਸ ਤੇ ਇੰਸਟੌਲ ਨਹੀਂ ਕੀਤੀ ਗਈ ਹੈ"</string>
</resources>
diff --git a/packages/SystemUI/res/values-pl/strings.xml b/packages/SystemUI/res/values-pl/strings.xml
index 179c644..b6c9964 100644
--- a/packages/SystemUI/res/values-pl/strings.xml
+++ b/packages/SystemUI/res/values-pl/strings.xml
@@ -347,8 +347,7 @@
<string name="guest_notification_text" msgid="335747957734796689">"Usuń gościa, by usunąć aplikacje i dane"</string>
<string name="guest_notification_remove_action" msgid="8820670703892101990">"USUŃ GOŚCIA"</string>
<string name="user_logout_notification_title" msgid="1453960926437240727">"Wyloguj użytkownika"</string>
- <!-- no translation found for user_logout_notification_text (3350262809611876284) -->
- <skip />
+ <string name="user_logout_notification_text" msgid="3350262809611876284">"Wyloguj bieżącego użytkownika"</string>
<string name="user_logout_notification_action" msgid="1195428991423425062">"WYLOGUJ UŻYTKOWNIKA"</string>
<string name="user_add_user_title" msgid="4553596395824132638">"Dodać nowego użytkownika?"</string>
<string name="user_add_user_message_short" msgid="2161624834066214559">"Gdy dodasz nowego użytkownika, musi on skonfigurować swój profil.\n\nKażdy użytkownik może aktualizować aplikacje wszystkich innych użytkowników."</string>
@@ -432,6 +431,5 @@
<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>
- <!-- no translation found for activity_not_found (348423244327799974) -->
- <skip />
+ <string name="activity_not_found" msgid="348423244327799974">"Aplikacja nie jest zainstalowana na urządzeniu"</string>
</resources>
diff --git a/packages/SystemUI/res/values-pt-rBR/strings.xml b/packages/SystemUI/res/values-pt-rBR/strings.xml
index e62cc5f..9656de1 100644
--- a/packages/SystemUI/res/values-pt-rBR/strings.xml
+++ b/packages/SystemUI/res/values-pt-rBR/strings.xml
@@ -347,8 +347,7 @@
<string name="guest_notification_text" msgid="335747957734796689">"Para excluir apps e dados, remova o usuário convidado"</string>
<string name="guest_notification_remove_action" msgid="8820670703892101990">"REMOVER CONVIDADO"</string>
<string name="user_logout_notification_title" msgid="1453960926437240727">"Desconectar usuário"</string>
- <!-- no translation found for user_logout_notification_text (3350262809611876284) -->
- <skip />
+ <string name="user_logout_notification_text" msgid="3350262809611876284">"Desconectar usuário atual"</string>
<string name="user_logout_notification_action" msgid="1195428991423425062">"DESCONECTAR USUÁRIO"</string>
<string name="user_add_user_title" msgid="4553596395824132638">"Adicionar novo usuário?"</string>
<string name="user_add_user_message_short" msgid="2161624834066214559">"Quando você adiciona um novo usuário, essa pessoa precisa configurar o próprio espaço.\n\nQualquer usuário pode atualizar apps para os demais usuários."</string>
@@ -432,6 +431,5 @@
<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>
- <!-- no translation found for activity_not_found (348423244327799974) -->
- <skip />
+ <string name="activity_not_found" msgid="348423244327799974">"O app não está instalado no seu dispositivo"</string>
</resources>
diff --git a/packages/SystemUI/res/values-pt-rPT/strings.xml b/packages/SystemUI/res/values-pt-rPT/strings.xml
index 2af76b3..cde3da9 100644
--- a/packages/SystemUI/res/values-pt-rPT/strings.xml
+++ b/packages/SystemUI/res/values-pt-rPT/strings.xml
@@ -345,8 +345,7 @@
<string name="guest_notification_text" msgid="335747957734796689">"Para eliminar aplicações e dados, remover utiliz. convidado"</string>
<string name="guest_notification_remove_action" msgid="8820670703892101990">"REMOVER CONVIDADO"</string>
<string name="user_logout_notification_title" msgid="1453960926437240727">"Terminar sessão do utilizador"</string>
- <!-- no translation found for user_logout_notification_text (3350262809611876284) -->
- <skip />
+ <string name="user_logout_notification_text" msgid="3350262809611876284">"Terminar sessão do utilizador atual"</string>
<string name="user_logout_notification_action" msgid="1195428991423425062">"TERMINAR SESSÃO DO UTILIZADOR"</string>
<string name="user_add_user_title" msgid="4553596395824132638">"Adicionar um novo utilizador?"</string>
<string name="user_add_user_message_short" msgid="2161624834066214559">"Ao adicionar um novo utilizador, essa pessoa tem de configurar o respetivo espaço.\n\nQualquer utilizador pode atualizar aplicações para todos os outros utilizadores."</string>
@@ -430,6 +429,5 @@
<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>
- <!-- no translation found for activity_not_found (348423244327799974) -->
- <skip />
+ <string name="activity_not_found" msgid="348423244327799974">"A aplicação não está instalada no dispositivo"</string>
</resources>
diff --git a/packages/SystemUI/res/values-pt/strings.xml b/packages/SystemUI/res/values-pt/strings.xml
index e62cc5f..9656de1 100644
--- a/packages/SystemUI/res/values-pt/strings.xml
+++ b/packages/SystemUI/res/values-pt/strings.xml
@@ -347,8 +347,7 @@
<string name="guest_notification_text" msgid="335747957734796689">"Para excluir apps e dados, remova o usuário convidado"</string>
<string name="guest_notification_remove_action" msgid="8820670703892101990">"REMOVER CONVIDADO"</string>
<string name="user_logout_notification_title" msgid="1453960926437240727">"Desconectar usuário"</string>
- <!-- no translation found for user_logout_notification_text (3350262809611876284) -->
- <skip />
+ <string name="user_logout_notification_text" msgid="3350262809611876284">"Desconectar usuário atual"</string>
<string name="user_logout_notification_action" msgid="1195428991423425062">"DESCONECTAR USUÁRIO"</string>
<string name="user_add_user_title" msgid="4553596395824132638">"Adicionar novo usuário?"</string>
<string name="user_add_user_message_short" msgid="2161624834066214559">"Quando você adiciona um novo usuário, essa pessoa precisa configurar o próprio espaço.\n\nQualquer usuário pode atualizar apps para os demais usuários."</string>
@@ -432,6 +431,5 @@
<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>
- <!-- no translation found for activity_not_found (348423244327799974) -->
- <skip />
+ <string name="activity_not_found" msgid="348423244327799974">"O app não está instalado no seu dispositivo"</string>
</resources>
diff --git a/packages/SystemUI/res/values-ro/strings.xml b/packages/SystemUI/res/values-ro/strings.xml
index 26bd0c6..a62dd6c 100644
--- a/packages/SystemUI/res/values-ro/strings.xml
+++ b/packages/SystemUI/res/values-ro/strings.xml
@@ -346,8 +346,7 @@
<string name="guest_notification_text" msgid="335747957734796689">"Ștergeți aplicații și date eliminând utilizatorul invitat"</string>
<string name="guest_notification_remove_action" msgid="8820670703892101990">"ELIMINAȚI OASPETELE"</string>
<string name="user_logout_notification_title" msgid="1453960926437240727">"Deconectați utilizatorul"</string>
- <!-- no translation found for user_logout_notification_text (3350262809611876284) -->
- <skip />
+ <string name="user_logout_notification_text" msgid="3350262809611876284">"Deconectați utilizatorul actual"</string>
<string name="user_logout_notification_action" msgid="1195428991423425062">"DECONECTAȚI UTILIZATORUL"</string>
<string name="user_add_user_title" msgid="4553596395824132638">"Adăugați utilizator nou?"</string>
<string name="user_add_user_message_short" msgid="2161624834066214559">"Când adăugați un utilizator nou, acesta trebuie să-și configureze spațiul.\n\nOrice utilizator poate actualiza aplicațiile pentru toți ceilalți utilizatori."</string>
@@ -431,6 +430,5 @@
<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>
- <!-- no translation found for activity_not_found (348423244327799974) -->
- <skip />
+ <string name="activity_not_found" msgid="348423244327799974">"Aplicația nu este instalată pe dispozitiv"</string>
</resources>
diff --git a/packages/SystemUI/res/values-ru/strings.xml b/packages/SystemUI/res/values-ru/strings.xml
index a801376..6ad8a67 100644
--- a/packages/SystemUI/res/values-ru/strings.xml
+++ b/packages/SystemUI/res/values-ru/strings.xml
@@ -349,8 +349,7 @@
<string name="guest_notification_text" msgid="335747957734796689">"Чтобы стереть все приложения и данные, удалите аккаунт гостя."</string>
<string name="guest_notification_remove_action" msgid="8820670703892101990">"УДАЛИТЬ"</string>
<string name="user_logout_notification_title" msgid="1453960926437240727">"Выход от имени пользователя"</string>
- <!-- no translation found for user_logout_notification_text (3350262809611876284) -->
- <skip />
+ <string name="user_logout_notification_text" msgid="3350262809611876284">"Выход от имени пользователя"</string>
<string name="user_logout_notification_action" msgid="1195428991423425062">"ВЫЙТИ ОТ ИМЕНИ ПОЛЬЗОВАТЕЛЯ"</string>
<string name="user_add_user_title" msgid="4553596395824132638">"Добавить пользователя?"</string>
<string name="user_add_user_message_short" msgid="2161624834066214559">"После создания профиля его необходимо настроить.\n\nОбновлять приложения для всех аккаунтов может любой пользователь устройства."</string>
@@ -434,6 +433,5 @@
<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>
- <!-- no translation found for activity_not_found (348423244327799974) -->
- <skip />
+ <string name="activity_not_found" msgid="348423244327799974">"Приложение не установлено на вашем устройстве"</string>
</resources>
diff --git a/packages/SystemUI/res/values-si-rLK/strings.xml b/packages/SystemUI/res/values-si-rLK/strings.xml
index ce8228a..da41c3f 100644
--- a/packages/SystemUI/res/values-si-rLK/strings.xml
+++ b/packages/SystemUI/res/values-si-rLK/strings.xml
@@ -344,10 +344,9 @@
<string name="guest_notification_title" msgid="1585278533840603063">"ආගන්තුක පරිශිලකයා"</string>
<string name="guest_notification_text" msgid="335747957734796689">"යෙදුම් සහ දත්ත මැකීමට, ආගන්තුක පරිශීලකයා ඉවත් කරන්න"</string>
<string name="guest_notification_remove_action" msgid="8820670703892101990">"ආගන්තුකයා ඉවත් කරන්නද?"</string>
- <string name="user_logout_notification_title" msgid="1453960926437240727">"පරිශීලකයා වරනය කිරීම"</string>
- <!-- no translation found for user_logout_notification_text (3350262809611876284) -->
- <skip />
- <string name="user_logout_notification_action" msgid="1195428991423425062">"පරිශීලකයා වරනය කරන්න"</string>
+ <string name="user_logout_notification_title" msgid="1453960926437240727">"පරිශීලකයා වරන්න"</string>
+ <string name="user_logout_notification_text" msgid="3350262809611876284">"වත්මන් පරිශීලක වරන්න"</string>
+ <string name="user_logout_notification_action" msgid="1195428991423425062">"පරිශීලකයා වරන්න"</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>
@@ -430,6 +429,5 @@
<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>
- <!-- no translation found for activity_not_found (348423244327799974) -->
- <skip />
+ <string name="activity_not_found" msgid="348423244327799974">"යෙදුම ඔබේ උපාංගය මත ස්ථාපනය කර නැත"</string>
</resources>
diff --git a/packages/SystemUI/res/values-sk/strings.xml b/packages/SystemUI/res/values-sk/strings.xml
index 129ee99..af5d046 100644
--- a/packages/SystemUI/res/values-sk/strings.xml
+++ b/packages/SystemUI/res/values-sk/strings.xml
@@ -349,8 +349,7 @@
<string name="guest_notification_text" msgid="335747957734796689">"Ak chcete odstrániť aplikácie a údaje, odstráňte hosťa."</string>
<string name="guest_notification_remove_action" msgid="8820670703892101990">"ODSTRÁNIŤ HOSŤA"</string>
<string name="user_logout_notification_title" msgid="1453960926437240727">"Odhlásenie používateľa"</string>
- <!-- no translation found for user_logout_notification_text (3350262809611876284) -->
- <skip />
+ <string name="user_logout_notification_text" msgid="3350262809611876284">"Odhlásiť aktuálneho používateľa"</string>
<string name="user_logout_notification_action" msgid="1195428991423425062">"ODHLÁSIŤ POUŽÍVATEĽA"</string>
<string name="user_add_user_title" msgid="4553596395824132638">"Pridať nového používateľa?"</string>
<string name="user_add_user_message_short" msgid="2161624834066214559">"Keď pridáte nového používateľa, musí si nastaviť vlastný priestor.\n\nAkýkoľvek používateľ môže aktualizovať aplikácie všetkých ostatných používateľov."</string>
@@ -434,6 +433,5 @@
<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>
- <!-- no translation found for activity_not_found (348423244327799974) -->
- <skip />
+ <string name="activity_not_found" msgid="348423244327799974">"Aplikácia nie je nainštalovaná na zariadení"</string>
</resources>
diff --git a/packages/SystemUI/res/values-sl/strings.xml b/packages/SystemUI/res/values-sl/strings.xml
index 7d1c3c1..1205758 100644
--- a/packages/SystemUI/res/values-sl/strings.xml
+++ b/packages/SystemUI/res/values-sl/strings.xml
@@ -347,8 +347,7 @@
<string name="guest_notification_text" msgid="335747957734796689">"Če želite izbrisati aplikacije in podatke, odstranite gosta"</string>
<string name="guest_notification_remove_action" msgid="8820670703892101990">"ODSTRANI GOSTA"</string>
<string name="user_logout_notification_title" msgid="1453960926437240727">"Odjava uporabnika"</string>
- <!-- no translation found for user_logout_notification_text (3350262809611876284) -->
- <skip />
+ <string name="user_logout_notification_text" msgid="3350262809611876284">"Odjava trenutnega uporabnika"</string>
<string name="user_logout_notification_action" msgid="1195428991423425062">"ODJAVA UPORABNIKA"</string>
<string name="user_add_user_title" msgid="4553596395824132638">"Dodajanje novega uporabnika?"</string>
<string name="user_add_user_message_short" msgid="2161624834066214559">"Ko dodate novega uporabnika, mora ta nastaviti svoj prostor.\n\nVsak uporabnik lahko posodobi aplikacije za vse druge uporabnike."</string>
@@ -432,6 +431,5 @@
<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>
- <!-- no translation found for activity_not_found (348423244327799974) -->
- <skip />
+ <string name="activity_not_found" msgid="348423244327799974">"Aplikacija ni nameščena v napravi"</string>
</resources>
diff --git a/packages/SystemUI/res/values-sq-rAL/strings.xml b/packages/SystemUI/res/values-sq-rAL/strings.xml
index 8f284d4..baf17d1 100644
--- a/packages/SystemUI/res/values-sq-rAL/strings.xml
+++ b/packages/SystemUI/res/values-sq-rAL/strings.xml
@@ -345,8 +345,7 @@
<string name="guest_notification_text" msgid="335747957734796689">"Për të fshirë aplikacionet dhe të dhënat, hiqe përdoruesin vizitor"</string>
<string name="guest_notification_remove_action" msgid="8820670703892101990">"HIQ VIZITORIN"</string>
<string name="user_logout_notification_title" msgid="1453960926437240727">"Nxirr përdororuesin nga identifikimi"</string>
- <!-- no translation found for user_logout_notification_text (3350262809611876284) -->
- <skip />
+ <string name="user_logout_notification_text" msgid="3350262809611876284">"Nxirr përdoruesin aktual"</string>
<string name="user_logout_notification_action" msgid="1195428991423425062">"NXJERRJA E PËRDORUESIT NGA IDENTIFIKIMI"</string>
<string name="user_add_user_title" msgid="4553596395824132638">"Të shtohet përdorues i ri?"</string>
<string name="user_add_user_message_short" msgid="2161624834066214559">"Kur shton një përdorues të ri, ai person duhet të konfigurojë hapësirën e vet.\n\nÇdo përdorues mund t\'i përditësojë aplikacionet për të gjithë përdoruesit e tjerë."</string>
@@ -430,6 +429,5 @@
<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>
- <!-- no translation found for activity_not_found (348423244327799974) -->
- <skip />
+ <string name="activity_not_found" msgid="348423244327799974">"Aplikacioni nuk është instaluar në pajisjen tënde."</string>
</resources>
diff --git a/packages/SystemUI/res/values-sr/strings.xml b/packages/SystemUI/res/values-sr/strings.xml
index 82a1db1..282bdcc 100644
--- a/packages/SystemUI/res/values-sr/strings.xml
+++ b/packages/SystemUI/res/values-sr/strings.xml
@@ -346,8 +346,7 @@
<string name="guest_notification_text" msgid="335747957734796689">"Да бисте избрисали апликације и податке, уклоните госта"</string>
<string name="guest_notification_remove_action" msgid="8820670703892101990">"УКЛОНИ ГОСТА"</string>
<string name="user_logout_notification_title" msgid="1453960926437240727">"Одјављивање корисника"</string>
- <!-- no translation found for user_logout_notification_text (3350262809611876284) -->
- <skip />
+ <string name="user_logout_notification_text" msgid="3350262809611876284">"Одјавите актуелног корисника"</string>
<string name="user_logout_notification_action" msgid="1195428991423425062">"ОДЈАВИ КОРИСНИКА"</string>
<string name="user_add_user_title" msgid="4553596395824132638">"Додајете новог корисника?"</string>
<string name="user_add_user_message_short" msgid="2161624834066214559">"Када додате новог корисника, та особа треба да подеси сопствени простор.\n\nСваки корисник може да ажурира апликације за све остале кориснике."</string>
@@ -431,6 +430,5 @@
<string name="tuner_toast" msgid="603429811084428439">"Честитамо! Тјунер за кориснички интерфејс система је додат у Подешавања"</string>
<string name="remove_from_settings" msgid="8389591916603406378">"Уклони из Подешавања"</string>
<string name="remove_from_settings_prompt" msgid="6069085993355887748">"Желите ли да уклоните Тјунер за кориснички интерфејс система из Подешавања и да престанете да користите све његове функције?"</string>
- <!-- no translation found for activity_not_found (348423244327799974) -->
- <skip />
+ <string name="activity_not_found" msgid="348423244327799974">"Апликација није инсталирана на уређају"</string>
</resources>
diff --git a/packages/SystemUI/res/values-sv/strings.xml b/packages/SystemUI/res/values-sv/strings.xml
index 5171b3a..cb8cbcb 100644
--- a/packages/SystemUI/res/values-sv/strings.xml
+++ b/packages/SystemUI/res/values-sv/strings.xml
@@ -345,8 +345,7 @@
<string name="guest_notification_text" msgid="335747957734796689">"Ta bort gästanvändaren om du vill radera appar och data"</string>
<string name="guest_notification_remove_action" msgid="8820670703892101990">"TA BORT GÄSTEN"</string>
<string name="user_logout_notification_title" msgid="1453960926437240727">"Logga ut användaren"</string>
- <!-- no translation found for user_logout_notification_text (3350262809611876284) -->
- <skip />
+ <string name="user_logout_notification_text" msgid="3350262809611876284">"Logga ut den aktuella användaren"</string>
<string name="user_logout_notification_action" msgid="1195428991423425062">"LOGGA UT ANVÄNDAREN"</string>
<string name="user_add_user_title" msgid="4553596395824132638">"Lägga till ny användare?"</string>
<string name="user_add_user_message_short" msgid="2161624834066214559">"När du lägger till en ny användare måste den personen konfigurera sitt utrymme.\n\nAlla användare kan uppdatera appar för samtliga användares räkning."</string>
@@ -430,6 +429,5 @@
<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>
- <!-- no translation found for activity_not_found (348423244327799974) -->
- <skip />
+ <string name="activity_not_found" msgid="348423244327799974">"Appen är inte installerad på enheten"</string>
</resources>
diff --git a/packages/SystemUI/res/values-sw/strings.xml b/packages/SystemUI/res/values-sw/strings.xml
index 2c435ba..def1786 100644
--- a/packages/SystemUI/res/values-sw/strings.xml
+++ b/packages/SystemUI/res/values-sw/strings.xml
@@ -345,8 +345,7 @@
<string name="guest_notification_text" msgid="335747957734796689">"Ili uweze kufuta programu na data, mwondoe mtumiaji aliyealikwa"</string>
<string name="guest_notification_remove_action" msgid="8820670703892101990">"ONDOA MGENI"</string>
<string name="user_logout_notification_title" msgid="1453960926437240727">"Ondoa mtumiaji"</string>
- <!-- no translation found for user_logout_notification_text (3350262809611876284) -->
- <skip />
+ <string name="user_logout_notification_text" msgid="3350262809611876284">"Mwondoe mtumiaji wa sasa"</string>
<string name="user_logout_notification_action" msgid="1195428991423425062">"ONDOA MTUMIAJI"</string>
<string name="user_add_user_title" msgid="4553596395824132638">"Ungependa kuongeza mtumiaji?"</string>
<string name="user_add_user_message_short" msgid="2161624834066214559">"Unapomwongeza mtumiaji mpya, mtu huyo anahitaji kusanidi nafasi yake.\n\nMtumiaji yoyote anaweza kusasisha programu kwa ajili ya watumiaji wengine wote."</string>
@@ -430,6 +429,5 @@
<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>
- <!-- no translation found for activity_not_found (348423244327799974) -->
- <skip />
+ <string name="activity_not_found" msgid="348423244327799974">"Programu haijasakinishwa kwenye kifaa chako"</string>
</resources>
diff --git a/packages/SystemUI/res/values-ta-rIN/strings.xml b/packages/SystemUI/res/values-ta-rIN/strings.xml
index 1600017..c9d0853 100644
--- a/packages/SystemUI/res/values-ta-rIN/strings.xml
+++ b/packages/SystemUI/res/values-ta-rIN/strings.xml
@@ -345,8 +345,7 @@
<string name="guest_notification_text" msgid="335747957734796689">"பயன்பாடுகளையும் தரவையும் நீக்க, விருந்தினர் பயனரை அகற்றவும்"</string>
<string name="guest_notification_remove_action" msgid="8820670703892101990">"அழைக்கப்பட்டவரை அகற்றவா?"</string>
<string name="user_logout_notification_title" msgid="1453960926437240727">"பயனரை வெளியேற்று"</string>
- <!-- no translation found for user_logout_notification_text (3350262809611876284) -->
- <skip />
+ <string name="user_logout_notification_text" msgid="3350262809611876284">"தற்போதைய பயனரிலிருந்து வெளியேறு"</string>
<string name="user_logout_notification_action" msgid="1195428991423425062">"பயனரை வெளியேற்று"</string>
<string name="user_add_user_title" msgid="4553596395824132638">"புதியவரைச் சேர்க்கவா?"</string>
<string name="user_add_user_message_short" msgid="2161624834066214559">"புதிய பயனரைச் சேர்க்கும்போது, அவர் தனக்கான இடத்தை அமைக்க வேண்டும்.\n\nஎந்தவொரு பயனரும், மற்ற எல்லா பயனர்களுக்காகவும் பயன்பாடுகளைப் புதுப்பிக்கலாம்."</string>
@@ -430,6 +429,5 @@
<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>
- <!-- no translation found for activity_not_found (348423244327799974) -->
- <skip />
+ <string name="activity_not_found" msgid="348423244327799974">"சாதனத்தில் பயன்பாடு நிறுவப்படவில்லை"</string>
</resources>
diff --git a/packages/SystemUI/res/values-te-rIN/strings.xml b/packages/SystemUI/res/values-te-rIN/strings.xml
index c73c76a..548c021 100644
--- a/packages/SystemUI/res/values-te-rIN/strings.xml
+++ b/packages/SystemUI/res/values-te-rIN/strings.xml
@@ -345,8 +345,7 @@
<string name="guest_notification_text" msgid="335747957734796689">"అనువర్తనాలు, డేటా తొలగించేందుకు అతిథి వినియోగదారు తీసివేయండి"</string>
<string name="guest_notification_remove_action" msgid="8820670703892101990">"అతిథిని తీసివేయి"</string>
<string name="user_logout_notification_title" msgid="1453960926437240727">"వినియోగదారుని లాగ్ అవుట్ చేయండి"</string>
- <!-- no translation found for user_logout_notification_text (3350262809611876284) -->
- <skip />
+ <string name="user_logout_notification_text" msgid="3350262809611876284">"ప్రస్తుత వినియోగదారును లాగ్ అవుట్ చేయండి"</string>
<string name="user_logout_notification_action" msgid="1195428991423425062">"వినియోగదారుని లాగ్ అవుట్ చేయి"</string>
<string name="user_add_user_title" msgid="4553596395824132638">"కొత్త వినియోగదారుని జోడించాలా?"</string>
<string name="user_add_user_message_short" msgid="2161624834066214559">"మీరు కొత్త వినియోగదారుని జోడించినప్పుడు, ఆ వ్యక్తి తన స్థలాన్ని సెటప్ చేసుకోవాలి.\n\nఏ వినియోగదారు అయినా మిగతా అందరు వినియోగదారుల కోసం అనువర్తనాలను నవీకరించగలరు."</string>
@@ -430,6 +429,5 @@
<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>
- <!-- no translation found for activity_not_found (348423244327799974) -->
- <skip />
+ <string name="activity_not_found" msgid="348423244327799974">"అనువర్తనం మీ పరికరంలో ఇన్స్టాల్ చేయలేదు"</string>
</resources>
diff --git a/packages/SystemUI/res/values-th/strings.xml b/packages/SystemUI/res/values-th/strings.xml
index 2e51d78..ddae7f6 100644
--- a/packages/SystemUI/res/values-th/strings.xml
+++ b/packages/SystemUI/res/values-th/strings.xml
@@ -345,8 +345,7 @@
<string name="guest_notification_text" msgid="335747957734796689">"หากต้องการลบแอปและข้อมูล ให้นำผู้ใช้ที่เป็นผู้เข้าร่วมออก"</string>
<string name="guest_notification_remove_action" msgid="8820670703892101990">"นำผู้เข้าร่วมออก"</string>
<string name="user_logout_notification_title" msgid="1453960926437240727">"ออกจากระบบผู้ใช้"</string>
- <!-- no translation found for user_logout_notification_text (3350262809611876284) -->
- <skip />
+ <string name="user_logout_notification_text" msgid="3350262809611876284">"ทำการออกจากระบบให้ผู้ใช้รายปัจจุบัน"</string>
<string name="user_logout_notification_action" msgid="1195428991423425062">"ออกจากระบบผู้ใช้"</string>
<string name="user_add_user_title" msgid="4553596395824132638">"ต้องการเพิ่มผู้ใช้ใหม่ใช่ไหม"</string>
<string name="user_add_user_message_short" msgid="2161624834066214559">"เมื่อคุณเพิ่มผู้ใช้ใหม่ ผู้ใช้ดังกล่าวจะต้องตั้งค่าพื้นที่ของตนเอง\n\nผู้ใช้ทุกคนสามารถอัปเดตแอปสำหรับผู้ใช้รายอื่นทุกคนได้"</string>
@@ -430,6 +429,5 @@
<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>
- <!-- no translation found for activity_not_found (348423244327799974) -->
- <skip />
+ <string name="activity_not_found" msgid="348423244327799974">"ยังไม่ได้ติดตั้งแอปพลิเคชันบนอุปกรณ์ของคุณ"</string>
</resources>
diff --git a/packages/SystemUI/res/values-tl/strings.xml b/packages/SystemUI/res/values-tl/strings.xml
index 580ef4e..d001ba9 100644
--- a/packages/SystemUI/res/values-tl/strings.xml
+++ b/packages/SystemUI/res/values-tl/strings.xml
@@ -345,8 +345,7 @@
<string name="guest_notification_text" msgid="335747957734796689">"Upang mag-delete ng mga app at data, alisin ang bisitang user"</string>
<string name="guest_notification_remove_action" msgid="8820670703892101990">"ALISIN ANG BISITA"</string>
<string name="user_logout_notification_title" msgid="1453960926437240727">"I-logout ang user"</string>
- <!-- no translation found for user_logout_notification_text (3350262809611876284) -->
- <skip />
+ <string name="user_logout_notification_text" msgid="3350262809611876284">"I-logout ang kasalukuyang user"</string>
<string name="user_logout_notification_action" msgid="1195428991423425062">"I-LOGOUT ANG USER"</string>
<string name="user_add_user_title" msgid="4553596395824132638">"Magdagdag ng bagong user?"</string>
<string name="user_add_user_message_short" msgid="2161624834066214559">"Kapag nagdagdag ka ng bagong user, kailangang i-set up ng taong iyon ang kanyang espasyo.\n\nAng sinumang user ay maaaring mag-update ng mga app para sa lahat ng iba pang user."</string>
@@ -430,6 +429,5 @@
<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>
- <!-- no translation found for activity_not_found (348423244327799974) -->
- <skip />
+ <string name="activity_not_found" msgid="348423244327799974">"Hindi naka-install ang application sa iyong device"</string>
</resources>
diff --git a/packages/SystemUI/res/values-tr/strings.xml b/packages/SystemUI/res/values-tr/strings.xml
index 6ab64fb..5f804cf 100644
--- a/packages/SystemUI/res/values-tr/strings.xml
+++ b/packages/SystemUI/res/values-tr/strings.xml
@@ -345,8 +345,7 @@
<string name="guest_notification_text" msgid="335747957734796689">"Uyg. ve verileri silmek için misafir kullanıcıyı kaldırın"</string>
<string name="guest_notification_remove_action" msgid="8820670703892101990">"MİSAFİR KALDIRILSIN MI?"</string>
<string name="user_logout_notification_title" msgid="1453960926437240727">"Kullanıcı oturumunu kapatın"</string>
- <!-- no translation found for user_logout_notification_text (3350262809611876284) -->
- <skip />
+ <string name="user_logout_notification_text" msgid="3350262809611876284">"Geçerli kullanıcının oturumunu kapatın"</string>
<string name="user_logout_notification_action" msgid="1195428991423425062">"KULLANICI OTURUMUNU KAPAT"</string>
<string name="user_add_user_title" msgid="4553596395824132638">"Yeni kullanıcı eklensin mi?"</string>
<string name="user_add_user_message_short" msgid="2161624834066214559">"Yeni bir kullanıcı eklediğinizde, bu kişinin kendi alanını ayarlaması gerekir.\n\nHerhangi bir kullanıcı, diğer tüm kullanıcılar için uygulamaları güncelleyebilir."</string>
@@ -430,6 +429,5 @@
<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>
- <!-- no translation found for activity_not_found (348423244327799974) -->
- <skip />
+ <string name="activity_not_found" msgid="348423244327799974">"Uygulama, cihazınızda yüklü değil"</string>
</resources>
diff --git a/packages/SystemUI/res/values-uk/strings.xml b/packages/SystemUI/res/values-uk/strings.xml
index 5ff8945..0c1d328 100644
--- a/packages/SystemUI/res/values-uk/strings.xml
+++ b/packages/SystemUI/res/values-uk/strings.xml
@@ -347,8 +347,7 @@
<string name="guest_notification_text" msgid="335747957734796689">"Щоб видалити додатки й дані, вилучіть профіль гостя"</string>
<string name="guest_notification_remove_action" msgid="8820670703892101990">"ВИЙТИ З РЕЖИМУ ГОСТЯ"</string>
<string name="user_logout_notification_title" msgid="1453960926437240727">"Вийти з облікового запису"</string>
- <!-- no translation found for user_logout_notification_text (3350262809611876284) -->
- <skip />
+ <string name="user_logout_notification_text" msgid="3350262809611876284">"Вийти з поточного облікового запису"</string>
<string name="user_logout_notification_action" msgid="1195428991423425062">"ВИЙТИ З ОБЛІКОВОГО ЗАПИСУ"</string>
<string name="user_add_user_title" msgid="4553596395824132638">"Додати нового користувача?"</string>
<string name="user_add_user_message_short" msgid="2161624834066214559">"Користувач має налаштувати свій профіль після створення.\n\nБудь-який користувач пристрою може оновлювати додатки для решти користувачів."</string>
@@ -432,6 +431,5 @@
<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>
- <!-- no translation found for activity_not_found (348423244327799974) -->
- <skip />
+ <string name="activity_not_found" msgid="348423244327799974">"Додаток не встановлено на вашому пристрої"</string>
</resources>
diff --git a/packages/SystemUI/res/values-ur-rPK/strings.xml b/packages/SystemUI/res/values-ur-rPK/strings.xml
index 27dda92..d0e2fc6 100644
--- a/packages/SystemUI/res/values-ur-rPK/strings.xml
+++ b/packages/SystemUI/res/values-ur-rPK/strings.xml
@@ -345,8 +345,7 @@
<string name="guest_notification_text" msgid="335747957734796689">"ایپس اور ڈیٹا حذف کرنے کیلئے مہمان صارف کو ہٹائیں"</string>
<string name="guest_notification_remove_action" msgid="8820670703892101990">"مہمان کو ہٹائیں"</string>
<string name="user_logout_notification_title" msgid="1453960926437240727">"صارف لاگ آؤٹ کریں"</string>
- <!-- no translation found for user_logout_notification_text (3350262809611876284) -->
- <skip />
+ <string name="user_logout_notification_text" msgid="3350262809611876284">"موجودہ صارف کو لاگ آؤٹ کریں"</string>
<string name="user_logout_notification_action" msgid="1195428991423425062">"صارف لاگ آؤٹ کریں"</string>
<string name="user_add_user_title" msgid="4553596395824132638">"نیا صارف شامل کریں؟"</string>
<string name="user_add_user_message_short" msgid="2161624834066214559">"جب آپ ایک نیا صارف شامل کرتے ہیں تو اس شخص کو اپنی جگہ کو ترتیب دینے کی ضرورت ہوتی ہے۔\n\nکوئی بھی صارف دیگر سبھی صارفین کیلئے ایپس کو اپ ڈیٹ کر سکتا ہے۔"</string>
@@ -430,6 +429,5 @@
<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>
- <!-- no translation found for activity_not_found (348423244327799974) -->
- <skip />
+ <string name="activity_not_found" msgid="348423244327799974">"ایپلیکیشن آپ کے آلہ پر انسٹال نہیں ہے"</string>
</resources>
diff --git a/packages/SystemUI/res/values-uz-rUZ/strings.xml b/packages/SystemUI/res/values-uz-rUZ/strings.xml
index 852564f..8def6f42 100644
--- a/packages/SystemUI/res/values-uz-rUZ/strings.xml
+++ b/packages/SystemUI/res/values-uz-rUZ/strings.xml
@@ -344,10 +344,9 @@
<string name="guest_notification_title" msgid="1585278533840603063">"Mehmon foydalanuvchi"</string>
<string name="guest_notification_text" msgid="335747957734796689">"Ilova va ma’l-ni o‘chirish u-n mehmon hisobini o‘chiring"</string>
<string name="guest_notification_remove_action" msgid="8820670703892101990">"MEHMON HISOBINI O‘CHIRISH"</string>
- <string name="user_logout_notification_title" msgid="1453960926437240727">"Foydalanuvchini tizimdan chiqaring"</string>
- <!-- no translation found for user_logout_notification_text (3350262809611876284) -->
- <skip />
- <string name="user_logout_notification_action" msgid="1195428991423425062">"TIZIMDAN CHIQARISH"</string>
+ <string name="user_logout_notification_title" msgid="1453960926437240727">"Foydalanuvchi nomidan chiqish"</string>
+ <string name="user_logout_notification_text" msgid="3350262809611876284">"Joriy foydalanuvchini tizimdan chiqaring"</string>
+ <string name="user_logout_notification_action" msgid="1195428991423425062">"FOYDALANUVCHI NOMIDAN CHIQISH"</string>
<string name="user_add_user_title" msgid="4553596395824132638">"Yangi foyd-chi qo‘shilsinmi?"</string>
<string name="user_add_user_message_short" msgid="2161624834066214559">"Yangi foydalanuvchi qo‘shilgach, o‘sha shaxs o‘z hududini sozlashi lozim bo‘ladi.\n\nHar qanday foydalanuvchi ilovalarni barcha foydalanuvchilar uchun yangilashi mumkin."</string>
<string name="battery_saver_notification_title" msgid="237918726750955859">"Quvvat tejash rejimi yoqildi"</string>
@@ -430,6 +429,5 @@
<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>
- <!-- no translation found for activity_not_found (348423244327799974) -->
- <skip />
+ <string name="activity_not_found" msgid="348423244327799974">"Ilova qurilmangizga o‘rnatilmagan"</string>
</resources>
diff --git a/packages/SystemUI/res/values-vi/strings.xml b/packages/SystemUI/res/values-vi/strings.xml
index c60c832..0fc90d7 100644
--- a/packages/SystemUI/res/values-vi/strings.xml
+++ b/packages/SystemUI/res/values-vi/strings.xml
@@ -345,8 +345,7 @@
<string name="guest_notification_text" msgid="335747957734796689">"Để xóa ứng dụng và dữ liệu, hãy xóa người dùng khách"</string>
<string name="guest_notification_remove_action" msgid="8820670703892101990">"XÓA KHÁCH"</string>
<string name="user_logout_notification_title" msgid="1453960926437240727">"Đăng xuất người dùng"</string>
- <!-- no translation found for user_logout_notification_text (3350262809611876284) -->
- <skip />
+ <string name="user_logout_notification_text" msgid="3350262809611876284">"Đăng xuất người dùng hiện tại"</string>
<string name="user_logout_notification_action" msgid="1195428991423425062">"ĐĂNG XUẤT NGƯỜI DÙNG"</string>
<string name="user_add_user_title" msgid="4553596395824132638">"Thêm người dùng mới?"</string>
<string name="user_add_user_message_short" msgid="2161624834066214559">"Khi bạn thêm người dùng mới, người dùng đó cần thiết lập dung lượng lưu trữ của mình.\n\nMọi người dùng đều có thể cập nhật ứng dụng cho tất cả người dùng khác."</string>
@@ -430,6 +429,5 @@
<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>
- <!-- no translation found for activity_not_found (348423244327799974) -->
- <skip />
+ <string name="activity_not_found" msgid="348423244327799974">"Ứng dụng chưa được cài đặt trên thiết bị của bạn"</string>
</resources>
diff --git a/packages/SystemUI/res/values-zh-rCN/strings.xml b/packages/SystemUI/res/values-zh-rCN/strings.xml
index 9cac800..53980c1 100644
--- a/packages/SystemUI/res/values-zh-rCN/strings.xml
+++ b/packages/SystemUI/res/values-zh-rCN/strings.xml
@@ -347,8 +347,7 @@
<string name="guest_notification_text" msgid="335747957734796689">"要删除应用和数据,请退出访客用户身份"</string>
<string name="guest_notification_remove_action" msgid="8820670703892101990">"移除访客"</string>
<string name="user_logout_notification_title" msgid="1453960926437240727">"退出当前用户"</string>
- <!-- no translation found for user_logout_notification_text (3350262809611876284) -->
- <skip />
+ <string name="user_logout_notification_text" msgid="3350262809611876284">"退出当前用户"</string>
<string name="user_logout_notification_action" msgid="1195428991423425062">"退出当前用户"</string>
<string name="user_add_user_title" msgid="4553596395824132638">"要添加新用户吗?"</string>
<string name="user_add_user_message_short" msgid="2161624834066214559">"当您添加新用户时,该用户必须设置自己的空间。\n\n任何用户均可为其他所有用户更新应用。"</string>
@@ -432,6 +431,5 @@
<string name="tuner_toast" msgid="603429811084428439">"恭喜!系统界面调谐器已添加到“设置”中"</string>
<string name="remove_from_settings" msgid="8389591916603406378">"从“设置”中移除"</string>
<string name="remove_from_settings_prompt" msgid="6069085993355887748">"要将系统界面调谐器从“设置”中移除,并停止使用所有相关功能吗?"</string>
- <!-- no translation found for activity_not_found (348423244327799974) -->
- <skip />
+ <string name="activity_not_found" msgid="348423244327799974">"您的设备中未安装此应用"</string>
</resources>
diff --git a/packages/SystemUI/res/values-zh-rHK/strings.xml b/packages/SystemUI/res/values-zh-rHK/strings.xml
index 2d9ebf0..65e200b 100644
--- a/packages/SystemUI/res/values-zh-rHK/strings.xml
+++ b/packages/SystemUI/res/values-zh-rHK/strings.xml
@@ -347,8 +347,7 @@
<string name="guest_notification_text" msgid="335747957734796689">"如要刪除應用程式和資料,請移除訪客使用者"</string>
<string name="guest_notification_remove_action" msgid="8820670703892101990">"移除訪客"</string>
<string name="user_logout_notification_title" msgid="1453960926437240727">"登出使用者"</string>
- <!-- no translation found for user_logout_notification_text (3350262809611876284) -->
- <skip />
+ <string name="user_logout_notification_text" msgid="3350262809611876284">"登出目前使用者"</string>
<string name="user_logout_notification_action" msgid="1195428991423425062">"登出使用者"</string>
<string name="user_add_user_title" msgid="4553596395824132638">"新增使用者?"</string>
<string name="user_add_user_message_short" msgid="2161624834066214559">"新增的使用者需要自行設定個人空間。\n\n任何使用者均可為所有其他使用者更新應用程式。"</string>
@@ -432,6 +431,5 @@
<string name="tuner_toast" msgid="603429811084428439">"恭喜您!系統使用者介面調諧器已新增至「設定」中"</string>
<string name="remove_from_settings" msgid="8389591916603406378">"從「設定」移除"</string>
<string name="remove_from_settings_prompt" msgid="6069085993355887748">"要從「設定」移除系統使用者介面調諧器,並停止其所有功能嗎?"</string>
- <!-- no translation found for activity_not_found (348423244327799974) -->
- <skip />
+ <string name="activity_not_found" msgid="348423244327799974">"尚未在裝置安裝應用程式"</string>
</resources>
diff --git a/packages/SystemUI/res/values-zh-rTW/strings.xml b/packages/SystemUI/res/values-zh-rTW/strings.xml
index 1446db4..04d914b 100644
--- a/packages/SystemUI/res/values-zh-rTW/strings.xml
+++ b/packages/SystemUI/res/values-zh-rTW/strings.xml
@@ -347,8 +347,7 @@
<string name="guest_notification_text" msgid="335747957734796689">"如要刪除應用程式和資料,請移除訪客使用者"</string>
<string name="guest_notification_remove_action" msgid="8820670703892101990">"移除訪客"</string>
<string name="user_logout_notification_title" msgid="1453960926437240727">"登出使用者"</string>
- <!-- no translation found for user_logout_notification_text (3350262809611876284) -->
- <skip />
+ <string name="user_logout_notification_text" msgid="3350262809611876284">"登出目前使用者"</string>
<string name="user_logout_notification_action" msgid="1195428991423425062">"登出使用者"</string>
<string name="user_add_user_title" msgid="4553596395824132638">"新增使用者?"</string>
<string name="user_add_user_message_short" msgid="2161624834066214559">"新增的使用者需要自行設定個人空間。\n\n任何使用者皆可為其他所有使用者更新應用程式。"</string>
@@ -432,6 +431,5 @@
<string name="tuner_toast" msgid="603429811084428439">"恭喜!系統使用者介面調整精靈已新增到設定中"</string>
<string name="remove_from_settings" msgid="8389591916603406378">"從設定中移除"</string>
<string name="remove_from_settings_prompt" msgid="6069085993355887748">"要將系統使用者介面調整精靈從設定中移除,並停止使用所有相關功能嗎?"</string>
- <!-- no translation found for activity_not_found (348423244327799974) -->
- <skip />
+ <string name="activity_not_found" msgid="348423244327799974">"您的裝置未安裝這個應用程式"</string>
</resources>
diff --git a/packages/SystemUI/res/values-zu/strings.xml b/packages/SystemUI/res/values-zu/strings.xml
index 689852a..7a7e3fe 100644
--- a/packages/SystemUI/res/values-zu/strings.xml
+++ b/packages/SystemUI/res/values-zu/strings.xml
@@ -345,8 +345,7 @@
<string name="guest_notification_text" msgid="335747957734796689">"Ukuze ususe izinhlelo zokusebenza nedatha, susa umsebenzisi oyisihambeli"</string>
<string name="guest_notification_remove_action" msgid="8820670703892101990">"SUSA ISIHAMBELI"</string>
<string name="user_logout_notification_title" msgid="1453960926437240727">"Khipha umsebenzisi"</string>
- <!-- no translation found for user_logout_notification_text (3350262809611876284) -->
- <skip />
+ <string name="user_logout_notification_text" msgid="3350262809611876284">"Khipha ngemvume umsebenzisi wamanje"</string>
<string name="user_logout_notification_action" msgid="1195428991423425062">"KHIPHA UMSEBENZISI"</string>
<string name="user_add_user_title" msgid="4553596395824132638">"Engeza umsebenzisi omusha?"</string>
<string name="user_add_user_message_short" msgid="2161624834066214559">"Uma ungeza umsebenzisi omusha, loyo muntu udinga ukusetha isikhala sakhe.\n\nNoma yimuphi umsebenzisi angabuyekeza izinhlelo zokusebenza kubo bonke abasebenzisi."</string>
@@ -430,6 +429,5 @@
<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>
- <!-- no translation found for activity_not_found (348423244327799974) -->
- <skip />
+ <string name="activity_not_found" msgid="348423244327799974">"Uhlelo lokusebenza alufakiwe kudivayisi yakho"</string>
</resources>
diff --git a/packages/SystemUI/res/values/ids.xml b/packages/SystemUI/res/values/ids.xml
index 6d84727..8eef23e 100644
--- a/packages/SystemUI/res/values/ids.xml
+++ b/packages/SystemUI/res/values/ids.xml
@@ -49,5 +49,6 @@
<!-- For notification icons for which targetSdk < L, this caches whether the icon is grayscale -->
<item type="id" name="icon_is_grayscale" />
+ <item type="id" name="is_clicked_heads_up_tag" />
</resources>
diff --git a/packages/SystemUI/src/com/android/systemui/GuestResumeSessionReceiver.java b/packages/SystemUI/src/com/android/systemui/GuestResumeSessionReceiver.java
index 714b0a8..ec19e5a 100644
--- a/packages/SystemUI/src/com/android/systemui/GuestResumeSessionReceiver.java
+++ b/packages/SystemUI/src/com/android/systemui/GuestResumeSessionReceiver.java
@@ -47,7 +47,7 @@
public void register(Context context) {
IntentFilter f = new IntentFilter(Intent.ACTION_USER_SWITCHED);
- context.registerReceiverAsUser(this, UserHandle.OWNER,
+ context.registerReceiverAsUser(this, UserHandle.SYSTEM,
f, null /* permission */, null /* scheduler */);
}
@@ -121,8 +121,8 @@
try {
if (newGuest == null) {
- Log.e(TAG, "Could not create new guest, switching back to owner");
- ActivityManagerNative.getDefault().switchUser(UserHandle.USER_OWNER);
+ Log.e(TAG, "Could not create new guest, switching back to system user");
+ ActivityManagerNative.getDefault().switchUser(UserHandle.USER_SYSTEM);
userManager.removeUser(currentUser.id);
WindowManagerGlobal.getWindowManagerService().lockNow(null /* options */);
return;
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
index f0154a7..ae6ce53 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
@@ -340,7 +340,7 @@
@Override
public void onUserSwitchComplete(int userId) {
mSwitchingUser = false;
- if (userId != UserHandle.USER_OWNER) {
+ if (userId != UserHandle.USER_SYSTEM) {
UserInfo info = UserManager.get(mContext).getUserInfo(userId);
if (info != null && info.isGuest()) {
// If we just switched to a guest, try to dismiss keyguard.
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/FlashlightTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/FlashlightTile.java
index 5d74604..21cbef2 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/FlashlightTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/FlashlightTile.java
@@ -79,6 +79,8 @@
return;
}
state.value = value;
+ } else {
+ state.value = mFlashlightController.isEnabled();
}
final AnimationIcon icon = state.value ? mEnable : mDisable;
icon.setAllowAnimation(arg instanceof UserBoolean && ((UserBoolean) arg).userInitiated);
diff --git a/packages/SystemUI/src/com/android/systemui/recents/Recents.java b/packages/SystemUI/src/com/android/systemui/recents/Recents.java
index 8c2ac88..0cfa7a1 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;
@@ -62,15 +61,15 @@
import java.util.ArrayList;
/**
- * Annotation for a method that is only called from the primary user's SystemUI process and will be
+ * Annotation for a method that is only called from the system user's SystemUI process and will be
* proxied to the current user.
*/
-@interface ProxyFromPrimaryToCurrentUser {}
+@interface ProxyFromSystemToCurrentUser {}
/**
* Annotation for a method that may be called from any user's SystemUI process and will be proxied
- * to the primary user.
+ * to the system user.
*/
-@interface ProxyFromAnyToPrimaryUser {}
+@interface ProxyFromAnyToSystemUser {}
/** A proxy implementation for the recents component */
public class Recents extends SystemUI
@@ -225,7 +224,7 @@
}
/** Initializes the Recents. */
- @ProxyFromPrimaryToCurrentUser
+ @ProxyFromSystemToCurrentUser
@Override
public void start() {
if (sInstance == null) {
@@ -245,7 +244,7 @@
// Only the owner has the callback to update the SysUI visibility flags, so all non-owner
// instances of AlternateRecentsComponent needs to notify the owner when the visibility
// changes.
- if (mSystemServicesProxy.isForegroundUserOwner()) {
+ if (mSystemServicesProxy.isForegroundUserSystem()) {
mProxyBroadcastReceiver = new RecentsOwnerEventProxyReceiver();
IntentFilter filter = new IntentFilter();
filter.addAction(Recents.ACTION_PROXY_NOTIFY_RECENTS_VISIBLITY_TO_OWNER);
@@ -278,10 +277,10 @@
}
/** Shows the Recents. */
- @ProxyFromPrimaryToCurrentUser
+ @ProxyFromSystemToCurrentUser
@Override
public void showRecents(boolean triggeredFromAltTab, View statusBarView) {
- if (mSystemServicesProxy.isForegroundUserOwner()) {
+ if (mSystemServicesProxy.isForegroundUserSystem()) {
showRecentsInternal(triggeredFromAltTab);
} else {
Intent intent = createLocalBroadcastIntent(mContext,
@@ -302,10 +301,10 @@
}
/** Hides the Recents. */
- @ProxyFromPrimaryToCurrentUser
+ @ProxyFromSystemToCurrentUser
@Override
public void hideRecents(boolean triggeredFromAltTab, boolean triggeredFromHomeKey) {
- if (mSystemServicesProxy.isForegroundUserOwner()) {
+ if (mSystemServicesProxy.isForegroundUserSystem()) {
hideRecentsInternal(triggeredFromAltTab, triggeredFromHomeKey);
} else {
Intent intent = createLocalBroadcastIntent(mContext,
@@ -328,10 +327,10 @@
}
/** Toggles the Recents activity. */
- @ProxyFromPrimaryToCurrentUser
+ @ProxyFromSystemToCurrentUser
@Override
public void toggleRecents(Display display, int layoutDirection, View statusBarView) {
- if (mSystemServicesProxy.isForegroundUserOwner()) {
+ if (mSystemServicesProxy.isForegroundUserSystem()) {
toggleRecentsInternal();
} else {
Intent intent = createLocalBroadcastIntent(mContext,
@@ -351,10 +350,10 @@
}
/** Preloads info for the Recents activity. */
- @ProxyFromPrimaryToCurrentUser
+ @ProxyFromSystemToCurrentUser
@Override
public void preloadRecents() {
- if (mSystemServicesProxy.isForegroundUserOwner()) {
+ if (mSystemServicesProxy.isForegroundUserSystem()) {
preloadRecentsInternal();
} else {
Intent intent = createLocalBroadcastIntent(mContext,
@@ -483,9 +482,9 @@
}
/** Updates on configuration change. */
- @ProxyFromPrimaryToCurrentUser
+ @ProxyFromSystemToCurrentUser
public void onConfigurationChanged(Configuration newConfig) {
- if (mSystemServicesProxy.isForegroundUserOwner()) {
+ if (mSystemServicesProxy.isForegroundUserSystem()) {
configurationChanged();
} else {
Intent intent = createLocalBroadcastIntent(mContext,
@@ -849,16 +848,16 @@
}
/** Notifies the callbacks that the visibility of Recents has changed. */
- @ProxyFromAnyToPrimaryUser
+ @ProxyFromAnyToSystemUser
public static void notifyVisibilityChanged(Context context, SystemServicesProxy ssp,
boolean visible) {
- if (ssp.isForegroundUserOwner()) {
+ if (ssp.isForegroundUserSystem()) {
visibilityChanged(visible);
} else {
Intent intent = createLocalBroadcastIntent(context,
ACTION_PROXY_NOTIFY_RECENTS_VISIBLITY_TO_OWNER);
intent.putExtra(EXTRA_RECENTS_VISIBILITY, visible);
- context.sendBroadcastAsUser(intent, UserHandle.OWNER);
+ context.sendBroadcastAsUser(intent, UserHandle.SYSTEM);
}
}
static void visibilityChanged(boolean visible) {
@@ -868,14 +867,14 @@
}
/** Notifies the status bar to trigger screen pinning. */
- @ProxyFromAnyToPrimaryUser
+ @ProxyFromAnyToSystemUser
public static void startScreenPinning(Context context, SystemServicesProxy ssp) {
- if (ssp.isForegroundUserOwner()) {
+ if (ssp.isForegroundUserSystem()) {
onStartScreenPinning(context);
} else {
Intent intent = createLocalBroadcastIntent(context,
ACTION_PROXY_SCREEN_PINNING_REQUEST_TO_OWNER);
- context.sendBroadcastAsUser(intent, UserHandle.OWNER);
+ context.sendBroadcastAsUser(intent, UserHandle.SYSTEM);
}
}
static void onStartScreenPinning(Context context) {
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 17db471..afa32cbdf 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java
@@ -48,6 +48,8 @@
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
+import android.os.Handler;
+import android.os.HandlerThread;
import android.os.ParcelFileDescriptor;
import android.os.RemoteException;
import android.os.SystemProperties;
@@ -70,6 +72,7 @@
import com.android.systemui.recents.Constants;
import com.android.systemui.recents.Recents;
import com.android.systemui.recents.RecentsAppWidgetHost;
+import com.android.systemui.recents.RecentsConfiguration;
import java.io.IOException;
import java.util.ArrayList;
@@ -85,6 +88,15 @@
final static String TAG = "SystemServicesProxy";
final static BitmapFactory.Options sBitmapOptions;
+ final static HandlerThread sBgThread;
+
+ static {
+ sBgThread = new HandlerThread("Recents-SystemServicesProxy",
+ android.os.Process.THREAD_PRIORITY_BACKGROUND);
+ sBgThread.start();
+ sBitmapOptions = new BitmapFactory.Options();
+ sBitmapOptions.inMutable = true;
+ }
AccessibilityManager mAccm;
ActivityManager mAm;
@@ -98,17 +110,14 @@
String mRecentsPackage;
ComponentName mAssistComponent;
+ Handler mBgThreadHandler;
+
Bitmap mDummyIcon;
int mDummyThumbnailWidth;
int mDummyThumbnailHeight;
Paint mBgProtectionPaint;
Canvas mBgProtectionCanvas;
- static {
- sBitmapOptions = new BitmapFactory.Options();
- sBitmapOptions.inMutable = true;
- }
-
/** Private constructor */
public SystemServicesProxy(Context context) {
mAccm = AccessibilityManager.getInstance(context);
@@ -121,6 +130,7 @@
mWm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
mDisplay = mWm.getDefaultDisplay();
mRecentsPackage = context.getPackageName();
+ mBgThreadHandler = new Handler(sBgThread.getLooper());
// Get the dummy thumbnail width/heights
Resources res = context.getResources();
@@ -255,12 +265,16 @@
return false;
}
- /** Get the bounds of a stack / task. */
- public Rect getTaskBounds(int stackId) {
- ActivityManager.StackInfo info = getAllStackInfos().get(stackId);
- if (info != null)
- return info.bounds;
- return new Rect();
+ /** Get the bounds of a task. */
+ public Rect getTaskBounds(int taskId) {
+ if (mIam == null) return null;
+
+ try {
+ return mIam.getTaskBounds(taskId);
+ } catch (RemoteException e) {
+ e.printStackTrace();
+ }
+ return null;
}
/** Resize a given task. */
@@ -268,32 +282,17 @@
if (mIam == null) return;
try {
+ if (RecentsConfiguration.getInstance().multiStackEnabled) {
+ // In debug mode, we force all task to be resizeable regardless of the
+ // current app configuration.
+ mIam.setTaskResizeable(taskId, true);
+ }
mIam.resizeTask(taskId, bounds);
} catch (RemoteException e) {
e.printStackTrace();
}
}
- /** Returns the stack info for all stacks. */
- public SparseArray<ActivityManager.StackInfo> getAllStackInfos() {
- if (mIam == null) return new SparseArray<ActivityManager.StackInfo>();
-
- try {
- SparseArray<ActivityManager.StackInfo> stacks =
- new SparseArray<ActivityManager.StackInfo>();
- List<ActivityManager.StackInfo> infos = mIam.getAllStackInfos();
- int stackCount = infos.size();
- for (int i = 0; i < stackCount; i++) {
- ActivityManager.StackInfo info = infos.get(i);
- stacks.put(info.stackId, info);
- }
- return stacks;
- } catch (RemoteException e) {
- e.printStackTrace();
- return new SparseArray<ActivityManager.StackInfo>();
- }
- }
-
/** Returns the focused stack id. */
public int getFocusedStack() {
if (mIam == null) return -1;
@@ -383,12 +382,17 @@
}
/** Removes the task */
- public void removeTask(int taskId) {
+ public void removeTask(final int taskId) {
if (mAm == null) return;
if (Constants.DebugFlags.App.EnableSystemServicesProxy) return;
// Remove the task.
- mAm.removeTask(taskId);
+ mBgThreadHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ mAm.removeTask(taskId);
+ }
+ });
}
/**
@@ -522,10 +526,10 @@
/**
* Returns whether the foreground user is the owner.
*/
- public boolean isForegroundUserOwner() {
+ public boolean isForegroundUserSystem() {
if (mAm == null) return false;
- return mAm.getCurrentUser() == UserHandle.USER_OWNER;
+ return mAm.getCurrentUser() == UserHandle.USER_SYSTEM;
}
/**
@@ -656,22 +660,6 @@
return windowRect;
}
- /**
- * Takes a screenshot of the current surface.
- */
- public Bitmap takeScreenshot() {
- DisplayInfo di = new DisplayInfo();
- mDisplay.getDisplayInfo(di);
- return SurfaceControl.screenshot(di.getNaturalWidth(), di.getNaturalHeight());
- }
-
- /**
- * Takes a screenshot of the current app.
- */
- public Bitmap takeAppScreenshot() {
- return takeScreenshot();
- }
-
/** Starts an activity from recents. */
public boolean startActivityFromRecents(Context context, int taskId, String taskName,
ActivityOptions options) {
diff --git a/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoadPlan.java b/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoadPlan.java
index f40c58d..b8015c0 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoadPlan.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoadPlan.java
@@ -172,19 +172,13 @@
}
// Initialize the stacks
- SparseArray<ActivityManager.StackInfo> stackInfos = mSystemServicesProxy.getAllStackInfos();
mStacks.clear();
int stackCount = stacksTasks.size();
for (int i = 0; i < stackCount; i++) {
int stackId = stacksTasks.keyAt(i);
- ActivityManager.StackInfo info = stackInfos.get(stackId);
ArrayList<Task> stackTasks = stacksTasks.valueAt(i);
TaskStack stack = new TaskStack(stackId);
- if (Constants.DebugFlags.App.EnableMultiStackToSingleStack) {
- stack.setBounds(displayBounds, displayBounds);
- } else {
- stack.setBounds(info.bounds, displayBounds);
- }
+ stack.setBounds(displayBounds, displayBounds);
stack.setTasks(stackTasks);
stack.createAffiliatedGroupings(mConfig);
mStacks.put(stackId, stack);
diff --git a/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoader.java b/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoader.java
index b2aa2b6..ad25c85 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoader.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoader.java
@@ -343,11 +343,14 @@
if (infoHandle.info != null) {
label = ssp.getActivityLabel(infoHandle.info);
mActivityLabelCache.put(taskKey, label);
+ return label;
} else {
Log.w(TAG, "Missing ActivityInfo for " + taskKey.baseIntent.getComponent()
+ " u=" + taskKey.userId);
}
- return label;
+ // If the activity info does not exist or fails to load, return an empty label for now,
+ // but do not cache it
+ return "";
}
/** Returns the content description using as many cached values as we can. */
@@ -358,14 +361,22 @@
if (label != null) {
return label;
}
+ // If the given activity label is empty, don't compute or cache the content description
+ if (activityLabel.isEmpty()) {
+ return "";
+ }
+
label = ssp.getContentDescription(taskKey.baseIntent, taskKey.userId, activityLabel, res);
if (label != null) {
mContentDescriptionCache.put(taskKey, label);
+ return label;
} else {
Log.w(TAG, "Missing content description for " + taskKey.baseIntent.getComponent()
+ " u=" + taskKey.userId);
}
- return label;
+ // If the content description does not exist, return an empty label for now, but do not
+ // cache it
+ return "";
}
/** Returns the activity icon using as many cached values as we can. */
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 78b3512..2e0b80a 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewTouchHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewTouchHandler.java
@@ -316,7 +316,7 @@
overscrollRange);
// Invalidate to kick off computeScroll
mSv.invalidate();
- } else if (mScroller.isScrollOutOfBounds()) {
+ } else if (mIsScrolling && mScroller.isScrollOutOfBounds()) {
// Animate the scroll back into bounds
mScroller.animateBoundScroll();
} else if (mActiveTaskView == null) {
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewHeader.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewHeader.java
index 6db4020..353bcbe 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewHeader.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewHeader.java
@@ -224,7 +224,7 @@
/** Updates the resize task bar button. */
void updateResizeTaskBarIcon(Task t) {
Rect display = mSsp.getWindowRect();
- Rect taskRect = mSsp.getTaskBounds(t.key.stackId);
+ Rect taskRect = mSsp.getTaskBounds(t.key.id);
int resId = R.drawable.star;
if (display.equals(taskRect) || taskRect.isEmpty()) {
resId = R.drawable.vector_drawable_place_fullscreen;
diff --git a/packages/SystemUI/src/com/android/systemui/settings/CurrentUserTracker.java b/packages/SystemUI/src/com/android/systemui/settings/CurrentUserTracker.java
index f8ff616..d8a202c 100644
--- a/packages/SystemUI/src/com/android/systemui/settings/CurrentUserTracker.java
+++ b/packages/SystemUI/src/com/android/systemui/settings/CurrentUserTracker.java
@@ -58,8 +58,4 @@
}
public abstract void onUserSwitched(int newUserId);
-
- public boolean isCurrentUserOwner() {
- return mCurrentUserId == UserHandle.USER_OWNER;
- }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
index e3194d6..42c4e12 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
@@ -1628,6 +1628,7 @@
//
// In most cases, when FLAG_AUTO_CANCEL is set, the notification will
// become canceled shortly by NoMan, but we can't assume that.
+ HeadsUpManager.setIsClickedNotification(row, true);
mHeadsUpManager.releaseImmediately(notificationKey);
}
new Thread() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableView.java b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableView.java
index ccec759..71baf57 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableView.java
@@ -374,7 +374,11 @@
}
private void updateClipping() {
- mClipRect.set(0, mClipTopOptimization, getWidth(), getActualHeight());
+ int top = mClipTopOptimization;
+ if (top >= getActualHeight()) {
+ top = getActualHeight() - 1;
+ }
+ mClipRect.set(0, top, getWidth(), getActualHeight());
setClipBounds(mClipRect);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
index 31c94f7..46b00c7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
@@ -79,8 +79,8 @@
mBatteryInfo = IBatteryStats.Stub.asInterface(
ServiceManager.getService(BatteryStats.SERVICE_NAME));
KeyguardUpdateMonitor.getInstance(context).registerCallback(mUpdateMonitor);
- context.registerReceiverAsUser(
- mReceiver, UserHandle.OWNER, new IntentFilter(Intent.ACTION_TIME_TICK), null, null);
+ context.registerReceiverAsUser(mReceiver, UserHandle.SYSTEM,
+ new IntentFilter(Intent.ACTION_TIME_TICK), null, null);
}
public void setVisible(boolean visible) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java
index baac8ac..db2415a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java
@@ -194,7 +194,7 @@
public static Drawable getIcon(Context context, StatusBarIcon icon) {
int userId = icon.user.getIdentifier();
if (userId == UserHandle.USER_ALL) {
- userId = UserHandle.USER_OWNER;
+ userId = UserHandle.USER_SYSTEM;
}
return icon.icon.loadDrawableAsUser(context, userId);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DemoStatusIcons.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DemoStatusIcons.java
index fcdd4b7..4f57906 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DemoStatusIcons.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DemoStatusIcons.java
@@ -149,7 +149,7 @@
}
return;
}
- StatusBarIcon icon = new StatusBarIcon(iconPkg, UserHandle.OWNER, iconId, 0, 0, "Demo");
+ StatusBarIcon icon = new StatusBarIcon(iconPkg, UserHandle.SYSTEM, iconId, 0, 0, "Demo");
StatusBarIconView v = new StatusBarIconView(getContext(), null, null);
v.setTag(slot);
v.set(icon);
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 6627360..8e5d4d6 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
@@ -644,6 +644,16 @@
}
@Override
+ public void onScreenTurnedOn() {
+ mLockIcon.setScreenOn(true);
+ }
+
+ @Override
+ public void onScreenTurnedOff() {
+ mLockIcon.setScreenOn(false);
+ }
+
+ @Override
public void onKeyguardVisibilityChanged(boolean showing) {
mLockIcon.update();
}
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..463abfc 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,20 @@
} 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) {
+ 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;
}
if (iconRes == -1) {
- iconRes = getIconForState(state);
+ iconRes = getIconForState(state, mScreenOn, mDeviceInteractive);
+ isAnim = false;
}
Drawable icon = mContext.getDrawable(iconRes);
final AnimatedVectorDrawable animation = icon instanceof AnimatedVectorDrawable
@@ -135,23 +136,12 @@
: 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.
@@ -192,7 +182,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 +191,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,8 +203,9 @@
}
}
- 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_FINGERPRINT_ERROR && newState == STATE_FINGERPRINT) {
@@ -218,7 +213,8 @@
} 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;
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 af25562..367ff1a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
@@ -380,16 +380,18 @@
mLayoutTransitionsEnabled = enabled;
ViewGroup navButtons = (ViewGroup) mCurrentView.findViewById(R.id.nav_buttons);
LayoutTransition lt = navButtons.getLayoutTransition();
- if (enabled) {
- lt.enableTransitionType(LayoutTransition.APPEARING);
- lt.enableTransitionType(LayoutTransition.DISAPPEARING);
- lt.enableTransitionType(LayoutTransition.CHANGE_APPEARING);
- lt.enableTransitionType(LayoutTransition.CHANGE_DISAPPEARING);
- } else {
- lt.disableTransitionType(LayoutTransition.APPEARING);
- lt.disableTransitionType(LayoutTransition.DISAPPEARING);
- lt.disableTransitionType(LayoutTransition.CHANGE_APPEARING);
- lt.disableTransitionType(LayoutTransition.CHANGE_DISAPPEARING);
+ if (lt != null) {
+ if (enabled) {
+ lt.enableTransitionType(LayoutTransition.APPEARING);
+ lt.enableTransitionType(LayoutTransition.DISAPPEARING);
+ lt.enableTransitionType(LayoutTransition.CHANGE_APPEARING);
+ lt.enableTransitionType(LayoutTransition.CHANGE_DISAPPEARING);
+ } else {
+ lt.disableTransitionType(LayoutTransition.APPEARING);
+ lt.disableTransitionType(LayoutTransition.DISAPPEARING);
+ lt.disableTransitionType(LayoutTransition.CHANGE_APPEARING);
+ lt.disableTransitionType(LayoutTransition.CHANGE_DISAPPEARING);
+ }
}
}
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 cf945bc..c4c8e3d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
@@ -32,7 +32,6 @@
import android.view.MotionEvent;
import android.view.VelocityTracker;
import android.view.View;
-import android.view.ViewRootImpl;
import android.view.ViewTreeObserver;
import android.view.WindowInsets;
import android.view.accessibility.AccessibilityEvent;
@@ -203,10 +202,12 @@
private int mPositionMinSideMargin;
private int mLastOrientation = -1;
private boolean mClosingWithAlphaFadeOut;
+ private boolean mHeadsUpAnimatingAway;
private Runnable mHeadsUpExistenceChangedRunnable = new Runnable() {
@Override
public void run() {
+ mHeadsUpAnimatingAway = false;
notifyBarPanelExpansionChanged();
}
};
@@ -2292,6 +2293,7 @@
mHeadsUpExistenceChangedRunnable.run();
updateNotificationTranslucency();
} else {
+ mHeadsUpAnimatingAway = true;
mNotificationStackScroller.runAfterAnimationFinished(
mHeadsUpExistenceChangedRunnable);
}
@@ -2382,4 +2384,8 @@
public void clearNotificattonEffects() {
mStatusBar.clearNotificationEffects();
}
+
+ protected boolean isPanelVisibleBecauseOfHeadsUp() {
+ return mHeadsUpManager.hasPinnedHeadsUp() || mHeadsUpAnimatingAway;
+ }
}
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 89e1e5f..5995fe1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
@@ -1017,10 +1017,12 @@
protected void notifyBarPanelExpansionChanged() {
mBar.panelExpansionChanged(this, mExpandedFraction, mExpandedFraction > 0f || mPeekPending
- || mPeekAnimator != null || mInstantExpanding || mHeadsUpManager.hasPinnedHeadsUp()
+ || mPeekAnimator != null || mInstantExpanding || isPanelVisibleBecauseOfHeadsUp()
|| mTracking || mHeightAnimator != null);
}
+ protected abstract boolean isPanelVisibleBecauseOfHeadsUp();
+
/**
* Gets called when the user performs a click anywhere in the empty area of the panel.
*
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/FlashlightController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/FlashlightController.java
index cd1914c..29a8f67 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/FlashlightController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/FlashlightController.java
@@ -93,6 +93,10 @@
}
}
+ public synchronized boolean isEnabled() {
+ return mFlashlightEnabled;
+ }
+
public synchronized boolean isAvailable() {
return mTorchAvailable;
}
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 63f5711..ed9b123 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.java
@@ -51,6 +51,7 @@
private static final String TAG = "HeadsUpManager";
private static final boolean DEBUG = false;
private static final String SETTING_HEADS_UP_SNOOZE_LENGTH_MS = "heads_up_snooze_length_ms";
+ private static final int TAG_CLICKED_NOTIFICATION = R.id.is_clicked_heads_up_tag;
private final int mHeadsUpNotificationDecay;
private final int mMinimumDisplayTime;
@@ -452,8 +453,8 @@
for (NotificationData.Entry entry : mEntriesToRemoveAfterExpand) {
removeHeadsUpEntry(entry);
}
- mEntriesToRemoveAfterExpand.clear();
}
+ mEntriesToRemoveAfterExpand.clear();
}
public void setTrackingHeadsUp(boolean trackingHeadsUp) {
@@ -526,6 +527,15 @@
});
}
+ public static void setIsClickedNotification(View child, boolean clicked) {
+ child.setTag(TAG_CLICKED_NOTIFICATION, clicked ? true : null);
+ }
+
+ public static boolean isClickedHeadsUpNotification(View child) {
+ Boolean clicked = (Boolean) child.getTag(TAG_CLICKED_NOTIFICATION);
+ return clicked != null && clicked;
+ }
+
/**
* This represents a notification and how long it is in a heads up mode. It also manages its
* lifecycle automatically when created.
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java
index 13e9b16..ed1dca3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java
@@ -51,7 +51,7 @@
@VisibleForTesting
final PhoneStateListener mPhoneStateListener;
// Save entire info for logging, we only use the id.
- private final SubscriptionInfo mSubscriptionInfo;
+ final SubscriptionInfo mSubscriptionInfo;
// @VisibleForDemoMode
final SparseArray<MobileIconGroup> mNetworkToIconLookup;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
index 57dfff5..2996808 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
@@ -66,6 +66,11 @@
// additional diagnostics, but not logspew
static final boolean CHATTY = Log.isLoggable(TAG + "Chat", Log.DEBUG);
+ private static final int EMERGENCY_NO_CONTROLLERS = 0;
+ private static final int EMERGENCY_FIRST_CONTROLLER = 100;
+ private static final int EMERGENCY_VOICE_CONTROLLER = 200;
+ private static final int EMERGENCY_NO_SUB = 300;
+
private final Context mContext;
private final TelephonyManager mPhone;
private final WifiManager mWifiManager;
@@ -118,6 +123,9 @@
// Handler that all callbacks are made on.
private final CallbackHandler mCallbackHandler;
+ private int mEmergencySource;
+ private boolean mIsEmergency;
+
@VisibleForTesting
ServiceState mLastServiceState;
@@ -267,6 +275,7 @@
if (mMobileSignalControllers.size() == 0) {
// When there are no active subscriptions, determine emengency state from last
// broadcast.
+ mEmergencySource = EMERGENCY_NO_CONTROLLERS;
return mLastServiceState != null && mLastServiceState.isEmergencyOnly();
}
int voiceSubId = mSubDefaults.getDefaultVoiceSubId();
@@ -274,16 +283,20 @@
for (MobileSignalController mobileSignalController :
mMobileSignalControllers.values()) {
if (!mobileSignalController.getState().isEmergency) {
+ mEmergencySource = EMERGENCY_FIRST_CONTROLLER
+ + mobileSignalController.mSubscriptionInfo.getSubscriptionId();
if (DEBUG) Log.d(TAG, "Found emergency " + mobileSignalController.mTag);
return false;
}
}
}
if (mMobileSignalControllers.containsKey(voiceSubId)) {
+ mEmergencySource = EMERGENCY_VOICE_CONTROLLER + voiceSubId;
if (DEBUG) Log.d(TAG, "Getting emergency from " + voiceSubId);
return mMobileSignalControllers.get(voiceSubId).getState().isEmergency;
}
if (DEBUG) Log.e(TAG, "Cannot find controller for voice sub: " + voiceSubId);
+ mEmergencySource = EMERGENCY_NO_SUB + voiceSubId;
// Something is wrong, better assume we can't make calls...
return true;
}
@@ -293,7 +306,8 @@
* so we should recheck and send out the state to listeners.
*/
void recalculateEmergency() {
- mCallbackHandler.setEmergencyCallsOnly(isEmergencyOnly());
+ mIsEmergency = isEmergencyOnly();
+ mCallbackHandler.setEmergencyCallsOnly(mIsEmergency);
}
public void addSignalCallback(SignalCallback cb) {
@@ -606,6 +620,10 @@
pw.println(mLocale);
pw.print(" mLastServiceState=");
pw.println(mLastServiceState);
+ pw.print(" mIsEmergency=");
+ pw.println(mIsEmergency);
+ pw.print(" mEmergencySource=");
+ pw.println(emergencyToString(mEmergencySource));
for (MobileSignalController mobileSignalController : mMobileSignalControllers.values()) {
mobileSignalController.dump(pw);
@@ -617,6 +635,19 @@
mAccessPoints.dump(pw);
}
+ private static final String emergencyToString(int emergencySource) {
+ if (emergencySource > EMERGENCY_NO_SUB) {
+ return "NO_SUB(" + (emergencySource - EMERGENCY_NO_SUB) + ")";
+ } else if (emergencySource > EMERGENCY_VOICE_CONTROLLER) {
+ return "VOICE_CONTROLLER(" + (emergencySource - EMERGENCY_VOICE_CONTROLLER) + ")";
+ } else if (emergencySource > EMERGENCY_FIRST_CONTROLLER) {
+ return "FIRST_CONTROLLER(" + (emergencySource - EMERGENCY_FIRST_CONTROLLER) + ")";
+ } else if (emergencySource == EMERGENCY_NO_CONTROLLERS) {
+ return "NO_CONTROLLERS";
+ }
+ return "UNKNOWN_SOURCE";
+ }
+
private boolean mDemoMode;
private boolean mDemoInetCondition;
private WifiSignalController.WifiState mDemoWifiState;
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 ff18cd8..6b30183 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
@@ -222,6 +222,7 @@
private int[] mTempInt2 = new int[2];
private boolean mGenerateChildOrderChangedEvent;
private HashSet<Runnable> mAnimationFinishedRunnables = new HashSet<>();
+ private HashSet<View> mClearOverlayViewsWhenFinished = new HashSet<>();
private HashSet<Pair<ExpandableNotificationRow, Boolean>> mHeadsUpChangeAnimations
= new HashSet<>();
private HeadsUpManager mHeadsUpManager;
@@ -1656,6 +1657,11 @@
mAddedHeadsUpChildren.remove(child);
return false;
}
+ if (isClickedHeadsUp(child)) {
+ // An animation is already running, add it to the Overlay
+ mClearOverlayViewsWhenFinished.add(child);
+ return true;
+ }
if (mIsExpanded && mAnimationsEnabled && !isChildInInvisibleGroup(child)) {
if (!mChildrenToAddAnimated.contains(child)) {
// Generate Animations
@@ -1671,6 +1677,10 @@
return false;
}
+ private boolean isClickedHeadsUp(View child) {
+ return HeadsUpManager.isClickedHeadsUpNotification(child);
+ }
+
/**
* Remove a removed child view from the heads up animations if it was just added there
*
@@ -2327,6 +2337,13 @@
public void onChildAnimationFinished() {
requestChildrenUpdate();
runAnimationFinishedRunnables();
+ clearViewOverlays();
+ }
+
+ private void clearViewOverlays() {
+ for (View view : mClearOverlayViewsWhenFinished) {
+ getOverlay().remove(view);
+ }
}
private void runAnimationFinishedRunnables() {
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 5d2e5b7..82064a7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java
@@ -413,7 +413,9 @@
ExpandableNotificationRow topHeadsUpEntry = ambientState.getTopHeadsUpEntry();
int childCount = algorithmState.visibleChildren.size();
- int numberOfElementsCompletelyIn = (int) algorithmState.itemsInTopStack;
+ int numberOfElementsCompletelyIn = algorithmState.partialInTop == 1.0f
+ ? algorithmState.lastTopStackIndex
+ : (int) algorithmState.itemsInTopStack;
for (int i = 0; i < childCount; i++) {
ExpandableView child = algorithmState.visibleChildren.get(i);
StackViewState childViewState = resultState.getViewStateForView(child);
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 5b8fe89..97c7d30 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackStateAnimator.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackStateAnimator.java
@@ -29,6 +29,7 @@
import com.android.systemui.statusbar.ExpandableNotificationRow;
import com.android.systemui.statusbar.ExpandableView;
import com.android.systemui.statusbar.SpeedBumpView;
+import com.android.systemui.statusbar.policy.HeadsUpManager;
import java.util.ArrayList;
import java.util.HashSet;
@@ -670,6 +671,7 @@
animator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
+ HeadsUpManager.setIsClickedNotification(child, false);
child.setTag(TAG_ANIMATOR_TRANSLATION_Y, null);
child.setTag(TAG_START_TRANSLATION_Y, null);
child.setTag(TAG_END_TRANSLATION_Y, null);
diff --git a/services/core/java/com/android/server/AppOpsService.java b/services/core/java/com/android/server/AppOpsService.java
index 417f18d..45c020c 100644
--- a/services/core/java/com/android/server/AppOpsService.java
+++ b/services/core/java/com/android/server/AppOpsService.java
@@ -25,6 +25,7 @@
import java.io.PrintWriter;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
+import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
@@ -32,6 +33,7 @@
import android.app.ActivityManager;
import android.app.ActivityThread;
+import android.app.AppGlobals;
import android.app.AppOpsManager;
import android.content.Context;
import android.content.pm.ApplicationInfo;
@@ -56,15 +58,18 @@
import android.util.Pair;
import android.util.Slog;
import android.util.SparseArray;
+import android.util.SparseIntArray;
import android.util.TimeUtils;
import android.util.Xml;
import com.android.internal.app.IAppOpsService;
import com.android.internal.app.IAppOpsCallback;
import com.android.internal.os.Zygote;
+import com.android.internal.util.ArrayUtils;
import com.android.internal.util.FastXmlSerializer;
import com.android.internal.util.XmlUtils;
+import libcore.util.EmptyArray;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlSerializer;
@@ -98,19 +103,38 @@
}
};
- final SparseArray<HashMap<String, Ops>> mUidOps
- = new SparseArray<HashMap<String, Ops>>();
+ final SparseArray<UidState> mUidStates = new SparseArray<>();
private final SparseArray<boolean[]> mOpRestrictions = new SparseArray<boolean[]>();
+ private static final class UidState {
+ public final int uid;
+ public ArrayMap<String, Ops> pkgOps;
+ public SparseIntArray opModes;
+
+ public UidState(int uid) {
+ this.uid = uid;
+ }
+
+ public void clear() {
+ pkgOps = null;
+ opModes = null;
+ }
+
+ public boolean isDefault() {
+ return (pkgOps == null || pkgOps.isEmpty())
+ && (opModes == null || opModes.size() <= 0);
+ }
+ }
+
public final static class Ops extends SparseArray<Op> {
public final String packageName;
- public final int uid;
+ public final UidState uidState;
public final boolean isPrivileged;
- public Ops(String _packageName, int _uid, boolean _isPrivileged) {
+ public Ops(String _packageName, UidState _uidState, boolean _isPrivileged) {
packageName = _packageName;
- uid = _uid;
+ uidState = _uidState;
isPrivileged = _isPrivileged;
}
}
@@ -220,27 +244,42 @@
public void systemReady() {
synchronized (this) {
boolean changed = false;
- for (int i=0; i<mUidOps.size(); i++) {
- HashMap<String, Ops> pkgs = mUidOps.valueAt(i);
+ for (int i = mUidStates.size() - 1; i >= 0; i--) {
+ UidState uidState = mUidStates.valueAt(i);
+
+ String[] packageNames = getPackagesForUid(uidState.uid);
+ if (ArrayUtils.isEmpty(packageNames)) {
+ uidState.clear();
+ mUidStates.removeAt(i);
+ changed = true;
+ continue;
+ }
+
+ ArrayMap<String, Ops> pkgs = uidState.pkgOps;
+ if (pkgs == null) {
+ continue;
+ }
+
Iterator<Ops> it = pkgs.values().iterator();
while (it.hasNext()) {
Ops ops = it.next();
int curUid;
try {
curUid = mContext.getPackageManager().getPackageUid(ops.packageName,
- UserHandle.getUserId(ops.uid));
+ UserHandle.getUserId(ops.uidState.uid));
} catch (NameNotFoundException e) {
curUid = -1;
}
- if (curUid != ops.uid) {
+ if (curUid != ops.uidState.uid) {
Slog.i(TAG, "Pruning old package " + ops.packageName
- + "/" + ops.uid + ": new uid=" + curUid);
+ + "/" + ops.uidState + ": new uid=" + curUid);
it.remove();
changed = true;
}
}
- if (pkgs.size() <= 0) {
- mUidOps.removeAt(i);
+
+ if (uidState.isDefault()) {
+ mUidStates.removeAt(i);
}
}
if (changed) {
@@ -279,22 +318,34 @@
public void packageRemoved(int uid, String packageName) {
synchronized (this) {
- HashMap<String, Ops> pkgs = mUidOps.get(uid);
- if (pkgs != null) {
- if (pkgs.remove(packageName) != null) {
- if (pkgs.size() <= 0) {
- mUidOps.remove(uid);
- }
- scheduleFastWriteLocked();
- }
+ UidState uidState = mUidStates.get(uid);
+ if (uidState == null) {
+ return;
+ }
+
+ boolean changed = false;
+
+ // Remove any package state if such.
+ if (uidState.pkgOps != null && uidState.pkgOps.remove(packageName) != null) {
+ changed = true;
+ }
+
+ // If we just nuked the last package state check if the UID is valid.
+ if (changed && uidState.pkgOps.isEmpty()
+ && getPackagesForUid(uid).length <= 0) {
+ mUidStates.remove(uid);
+ }
+
+ if (changed) {
+ scheduleFastWriteLocked();
}
}
}
public void uidRemoved(int uid) {
synchronized (this) {
- if (mUidOps.indexOfKey(uid) >= 0) {
- mUidOps.remove(uid);
+ if (mUidStates.indexOfKey(uid) >= 0) {
+ mUidStates.remove(uid);
scheduleFastWriteLocked();
}
}
@@ -346,16 +397,23 @@
Binder.getCallingPid(), Binder.getCallingUid(), null);
ArrayList<AppOpsManager.PackageOps> res = null;
synchronized (this) {
- for (int i=0; i<mUidOps.size(); i++) {
- HashMap<String, Ops> packages = mUidOps.valueAt(i);
- for (Ops pkgOps : packages.values()) {
+ final int uidStateCount = mUidStates.size();
+ for (int i = 0; i < uidStateCount; i++) {
+ UidState uidState = mUidStates.valueAt(i);
+ if (uidState.pkgOps == null || uidState.pkgOps.isEmpty()) {
+ continue;
+ }
+ ArrayMap<String, Ops> packages = uidState.pkgOps;
+ final int packageCount = packages.size();
+ for (int j = 0; j < packageCount; j++) {
+ Ops pkgOps = packages.valueAt(j);
ArrayList<AppOpsManager.OpEntry> resOps = collectOps(pkgOps, ops);
if (resOps != null) {
if (res == null) {
res = new ArrayList<AppOpsManager.PackageOps>();
}
AppOpsManager.PackageOps resPackage = new AppOpsManager.PackageOps(
- pkgOps.packageName, pkgOps.uid, resOps);
+ pkgOps.packageName, pkgOps.uidState.uid, resOps);
res.add(resPackage);
}
}
@@ -380,7 +438,7 @@
}
ArrayList<AppOpsManager.PackageOps> res = new ArrayList<AppOpsManager.PackageOps>();
AppOpsManager.PackageOps resPackage = new AppOpsManager.PackageOps(
- pkgOps.packageName, pkgOps.uid, resOps);
+ pkgOps.packageName, pkgOps.uidState.uid, resOps);
res.add(resPackage);
return res;
}
@@ -392,11 +450,15 @@
if (ops != null) {
ops.remove(op.op);
if (ops.size() <= 0) {
- HashMap<String, Ops> pkgOps = mUidOps.get(uid);
+ UidState uidState = ops.uidState;
+ ArrayMap<String, Ops> pkgOps = uidState.pkgOps;
if (pkgOps != null) {
pkgOps.remove(ops.packageName);
- if (pkgOps.size() <= 0) {
- mUidOps.remove(uid);
+ if (pkgOps.isEmpty()) {
+ uidState.pkgOps = null;
+ }
+ if (uidState.isDefault()) {
+ mUidStates.remove(uid);
}
}
}
@@ -405,6 +467,115 @@
}
@Override
+ public void setUidMode(int code, int uid, int mode) {
+ if (Binder.getCallingPid() != Process.myPid()) {
+ mContext.enforcePermission(android.Manifest.permission.UPDATE_APP_OPS_STATS,
+ Binder.getCallingPid(), Binder.getCallingUid(), null);
+ }
+ verifyIncomingOp(code);
+ code = AppOpsManager.opToSwitch(code);
+
+ synchronized (this) {
+ final int defaultMode = AppOpsManager.opToDefaultMode(code);
+
+ UidState uidState = getUidStateLocked(uid, false);
+ if (uidState == null) {
+ if (mode == defaultMode) {
+ return;
+ }
+ uidState = new UidState(uid);
+ uidState.opModes = new SparseIntArray();
+ uidState.opModes.put(code, mode);
+ mUidStates.put(uid, uidState);
+ scheduleWriteLocked();
+ } else if (uidState.opModes == null) {
+ if (mode != defaultMode) {
+ uidState.opModes = new SparseIntArray();
+ uidState.opModes.put(code, mode);
+ scheduleWriteLocked();
+ }
+ } else {
+ if (uidState.opModes.get(code) == mode) {
+ return;
+ }
+ if (mode == defaultMode) {
+ uidState.opModes.delete(code);
+ if (uidState.opModes.size() <= 0) {
+ uidState.opModes = null;
+ }
+ } else {
+ uidState.opModes.put(code, mode);
+ }
+ scheduleWriteLocked();
+ }
+ }
+
+ String[] uidPackageNames = getPackagesForUid(uid);
+ ArrayMap<Callback, ArraySet<String>> callbackSpecs = null;
+
+ ArrayList<Callback> callbacks = mOpModeWatchers.get(code);
+ if (callbacks != null) {
+ final int callbackCount = callbacks.size();
+ for (int i = 0; i < callbackCount; i++) {
+ Callback callback = callbacks.get(i);
+ ArraySet<String> changedPackages = new ArraySet<>();
+ Collections.addAll(changedPackages, uidPackageNames);
+ callbackSpecs = new ArrayMap<>();
+ callbackSpecs.put(callback, changedPackages);
+ }
+ }
+
+ for (String uidPackageName : uidPackageNames) {
+ callbacks = mPackageModeWatchers.get(uidPackageName);
+ if (callbacks != null) {
+ if (callbackSpecs == null) {
+ callbackSpecs = new ArrayMap<>();
+ }
+ final int callbackCount = callbacks.size();
+ for (int i = 0; i < callbackCount; i++) {
+ Callback callback = callbacks.get(i);
+ ArraySet<String> changedPackages = callbackSpecs.get(callback);
+ if (changedPackages == null) {
+ changedPackages = new ArraySet<>();
+ callbackSpecs.put(callback, changedPackages);
+ }
+ changedPackages.add(uidPackageName);
+ }
+ }
+ }
+
+ if (callbackSpecs == null) {
+ return;
+ }
+
+ // There are components watching for mode changes such as window manager
+ // and location manager which are in our process. The callbacks in these
+ // components may require permissions our remote caller does not have.
+ final long identity = Binder.clearCallingIdentity();
+ try {
+ for (int i = 0; i < callbackSpecs.size(); i++) {
+ Callback callback = callbackSpecs.keyAt(i);
+ ArraySet<String> reportedPackageNames = callbackSpecs.valueAt(i);
+ try {
+ if (reportedPackageNames == null) {
+ callback.mCallback.opChanged(code, null);
+ } else {
+ final int reportedPackageCount = reportedPackageNames.size();
+ for (int j = 0; j < reportedPackageCount; j++) {
+ String reportedPackageName = reportedPackageNames.valueAt(j);
+ callback.mCallback.opChanged(code, reportedPackageName);
+ }
+ }
+ } catch (RemoteException e) {
+ Log.w(TAG, "Error dispatching op op change", e);
+ }
+ }
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
+ }
+
+ @Override
public void setMode(int code, int uid, String packageName, int mode) {
if (Binder.getCallingPid() != Process.myPid()) {
mContext.enforcePermission(android.Manifest.permission.UPDATE_APP_OPS_STATS,
@@ -414,6 +585,7 @@
ArrayList<Callback> repCbs = null;
code = AppOpsManager.opToSwitch(code);
synchronized (this) {
+ UidState uidState = getUidStateLocked(uid, false);
Op op = getOpLocked(code, uid, packageName, true);
if (op != null) {
if (op.mode != mode) {
@@ -468,14 +640,26 @@
if (callbacks == null) {
callbacks = new HashMap<Callback, ArrayList<Pair<String, Integer>>>();
}
+ boolean duplicate = false;
for (int i=0; i<cbs.size(); i++) {
Callback cb = cbs.get(i);
ArrayList<Pair<String, Integer>> reports = callbacks.get(cb);
if (reports == null) {
reports = new ArrayList<Pair<String, Integer>>();
callbacks.put(cb, reports);
+ } else {
+ final int reportCount = reports.size();
+ for (int j = 0; j < reportCount; j++) {
+ Pair<String, Integer> report = reports.get(j);
+ if (report.second == op && report.first.equals(packageName)) {
+ duplicate = true;
+ break;
+ }
+ }
}
- reports.add(new Pair<String, Integer>(packageName, op));
+ if (!duplicate) {
+ reports.add(new Pair<>(packageName, op));
+ }
}
return callbacks;
}
@@ -488,16 +672,54 @@
callingPid, callingUid, null);
reqUserId = ActivityManager.handleIncomingUser(callingPid, callingUid, reqUserId,
true, true, "resetAllModes", null);
+
+ int reqUid = -1;
+ if (reqPackageName != null) {
+ try {
+ reqUid = AppGlobals.getPackageManager().getPackageUid(
+ reqPackageName, reqUserId);
+ } catch (RemoteException e) {
+ /* ignore - local call */
+ }
+ }
+
HashMap<Callback, ArrayList<Pair<String, Integer>>> callbacks = null;
synchronized (this) {
boolean changed = false;
- for (int i=mUidOps.size()-1; i>=0; i--) {
- HashMap<String, Ops> packages = mUidOps.valueAt(i);
+ for (int i = mUidStates.size() - 1; i >= 0; i--) {
+ UidState uidState = mUidStates.valueAt(i);
+
+ SparseIntArray opModes = uidState.opModes;
+ if (opModes != null && (uidState.uid == reqUid || reqUid == -1)) {
+ final int uidOpCount = opModes.size();
+ for (int j = uidOpCount - 1; j >= 0; j--) {
+ final int code = opModes.keyAt(j);
+ if (AppOpsManager.opAllowsReset(code)) {
+ opModes.removeAt(j);
+ if (opModes.size() <= 0) {
+ uidState.opModes = null;
+ }
+ for (String packageName : getPackagesForUid(uidState.uid)) {
+ callbacks = addCallbacks(callbacks, packageName, code,
+ mOpModeWatchers.get(code));
+ callbacks = addCallbacks(callbacks, packageName, code,
+ mPackageModeWatchers.get(packageName));
+ }
+ }
+ }
+ }
+
+ if (uidState.pkgOps == null) {
+ continue;
+ }
+
if (reqUserId != UserHandle.USER_ALL
- && reqUserId != UserHandle.getUserId(mUidOps.keyAt(i))) {
+ && reqUserId != UserHandle.getUserId(uidState.uid)) {
// Skip any ops for a different user
continue;
}
+
+ Map<String, Ops> packages = uidState.pkgOps;
Iterator<Map.Entry<String, Ops>> it = packages.entrySet().iterator();
while (it.hasNext()) {
Map.Entry<String, Ops> ent = it.next();
@@ -526,10 +748,11 @@
it.remove();
}
}
- if (packages.size() == 0) {
- mUidOps.removeAt(i);
+ if (uidState.isDefault()) {
+ mUidStates.remove(uidState.uid);
}
}
+
if (changed) {
scheduleFastWriteLocked();
}
@@ -552,7 +775,7 @@
@Override
public void startWatchingMode(int op, String packageName, IAppOpsCallback callback) {
synchronized (this) {
- op = AppOpsManager.opToSwitch(op);
+ op = (op != AppOpsManager.OP_NONE) ? AppOpsManager.opToSwitch(op) : op;
Callback cb = mModeWatchers.get(callback.asBinder());
if (cb == null) {
cb = new Callback(callback);
@@ -621,7 +844,15 @@
if (isOpRestricted(uid, code, packageName)) {
return AppOpsManager.MODE_IGNORED;
}
- Op op = getOpLocked(AppOpsManager.opToSwitch(code), uid, packageName, false);
+ code = AppOpsManager.opToSwitch(code);
+ UidState uidState = getUidStateLocked(uid, false);
+ if (uidState != null && uidState.opModes != null) {
+ final int uidMode = uidState.opModes.get(code);
+ if (uidMode != AppOpsManager.MODE_ALLOWED) {
+ return uidMode;
+ }
+ }
+ Op op = getOpLocked(code, uid, packageName, false);
if (op == null) {
return AppOpsManager.opToDefaultMode(code);
}
@@ -703,7 +934,6 @@
}
return noteOperationUnchecked(code, proxiedUid, proxiedPackageName,
Binder.getCallingUid(), proxyPackageName);
-
}
@Override
@@ -732,6 +962,17 @@
}
op.duration = 0;
final int switchCode = AppOpsManager.opToSwitch(code);
+ UidState uidState = ops.uidState;
+ if (uidState.opModes != null) {
+ final int uidMode = uidState.opModes.get(switchCode);
+ if (uidMode != AppOpsManager.MODE_ALLOWED) {
+ if (DEBUG) Log.d(TAG, "noteOperation: reject #" + op.mode + " for code "
+ + switchCode + " (" + code + ") uid " + uid + " package "
+ + packageName);
+ op.rejectTime = System.currentTimeMillis();
+ return uidMode;
+ }
+ }
final Op switchOp = switchCode != code ? getOpLocked(ops, switchCode, true) : op;
if (switchOp.mode != AppOpsManager.MODE_ALLOWED) {
if (DEBUG) Log.d(TAG, "noteOperation: reject #" + op.mode + " for code "
@@ -766,6 +1007,17 @@
return AppOpsManager.MODE_IGNORED;
}
final int switchCode = AppOpsManager.opToSwitch(code);
+ UidState uidState = ops.uidState;
+ if (uidState.opModes != null) {
+ final int uidMode = uidState.opModes.get(switchCode);
+ if (uidMode != AppOpsManager.MODE_ALLOWED) {
+ if (DEBUG) Log.d(TAG, "noteOperation: reject #" + op.mode + " for code "
+ + switchCode + " (" + code + ") uid " + uid + " package "
+ + packageName);
+ op.rejectTime = System.currentTimeMillis();
+ return uidMode;
+ }
+ }
final Op switchOp = switchCode != code ? getOpLocked(ops, switchCode, true) : op;
if (switchOp.mode != AppOpsManager.MODE_ALLOWED) {
if (DEBUG) Log.d(TAG, "startOperation: reject #" + op.mode + " for code "
@@ -847,6 +1099,18 @@
throw new IllegalArgumentException("Bad operation #" + op);
}
+ private UidState getUidStateLocked(int uid, boolean edit) {
+ UidState uidState = mUidStates.get(uid);
+ if (uidState == null) {
+ if (!edit) {
+ return null;
+ }
+ uidState = new UidState(uid);
+ mUidStates.put(uid, uidState);
+ }
+ return uidState;
+ }
+
private Ops getOpsLocked(int uid, String packageName, boolean edit) {
if (uid == 0) {
packageName = "root";
@@ -857,15 +1121,19 @@
}
private Ops getOpsRawLocked(int uid, String packageName, boolean edit) {
- HashMap<String, Ops> pkgOps = mUidOps.get(uid);
- if (pkgOps == null) {
+ UidState uidState = getUidStateLocked(uid, edit);
+ if (uidState == null) {
+ return null;
+ }
+
+ if (uidState.pkgOps == null) {
if (!edit) {
return null;
}
- pkgOps = new HashMap<String, Ops>();
- mUidOps.put(uid, pkgOps);
+ uidState.pkgOps = new ArrayMap<>();
}
- Ops ops = pkgOps.get(packageName);
+
+ Ops ops = uidState.pkgOps.get(packageName);
if (ops == null) {
if (!edit) {
return null;
@@ -904,8 +1172,8 @@
Binder.restoreCallingIdentity(ident);
}
}
- ops = new Ops(packageName, uid, isPrivileged);
- pkgOps.put(packageName, ops);
+ ops = new Ops(packageName, uidState, isPrivileged);
+ uidState.pkgOps.put(packageName, ops);
}
return ops;
}
@@ -940,7 +1208,7 @@
if (!edit) {
return null;
}
- op = new Op(ops.uid, ops.packageName, code);
+ op = new Op(ops.uidState.uid, ops.packageName, code);
ops.put(code, op);
}
if (edit) {
@@ -1000,6 +1268,8 @@
String tagName = parser.getName();
if (tagName.equals("pkg")) {
readPackage(parser);
+ } else if (tagName.equals("uid")) {
+ readUidOps(parser);
} else {
Slog.w(TAG, "Unknown element under <app-ops>: "
+ parser.getName());
@@ -1021,7 +1291,7 @@
Slog.w(TAG, "Failed parsing " + e);
} finally {
if (!success) {
- mUidOps.clear();
+ mUidStates.clear();
}
try {
stream.close();
@@ -1032,6 +1302,34 @@
}
}
+ void readUidOps(XmlPullParser parser) throws NumberFormatException,
+ XmlPullParserException, IOException {
+ final int uid = Integer.parseInt(parser.getAttributeValue(null, "n"));
+ int outerDepth = parser.getDepth();
+ int type;
+ while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
+ && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
+ if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
+ continue;
+ }
+
+ String tagName = parser.getName();
+ if (tagName.equals("op")) {
+ final int code = Integer.parseInt(parser.getAttributeValue(null, "n"));
+ final int mode = Integer.parseInt(parser.getAttributeValue(null, "m"));
+ UidState uidState = getUidStateLocked(uid, true);
+ if (uidState.opModes == null) {
+ uidState.opModes = new SparseIntArray();
+ }
+ uidState.opModes.put(code, mode);
+ } else {
+ Slog.w(TAG, "Unknown element under <uid-ops>: "
+ + parser.getName());
+ XmlUtils.skipCurrentTag(parser);
+ }
+ }
+ }
+
void readPackage(XmlPullParser parser) throws NumberFormatException,
XmlPullParserException, IOException {
String pkgName = parser.getAttributeValue(null, "n");
@@ -1114,15 +1412,16 @@
if (proxyPackageName != null) {
op.proxyPackageName = proxyPackageName;
}
- HashMap<String, Ops> pkgOps = mUidOps.get(uid);
- if (pkgOps == null) {
- pkgOps = new HashMap<String, Ops>();
- mUidOps.put(uid, pkgOps);
+
+ UidState uidState = getUidStateLocked(uid, true);
+ if (uidState.pkgOps == null) {
+ uidState.pkgOps = new ArrayMap<>();
}
- Ops ops = pkgOps.get(pkgName);
+
+ Ops ops = uidState.pkgOps.get(pkgName);
if (ops == null) {
- ops = new Ops(pkgName, uid, isPrivileged);
- pkgOps.put(pkgName, ops);
+ ops = new Ops(pkgName, uidState, isPrivileged);
+ uidState.pkgOps.put(pkgName, ops);
}
ops.put(op.op, op);
} else {
@@ -1149,7 +1448,27 @@
XmlSerializer out = new FastXmlSerializer();
out.setOutput(stream, StandardCharsets.UTF_8.name());
out.startDocument(null, true);
- out.startTag(null, "app-ops");
+ out.startTag(null, "app");
+
+ final int uidStateCount = mUidStates.size();
+ for (int i = 0; i < uidStateCount; i++) {
+ UidState uidState = mUidStates.valueAt(i);
+ if (uidState.opModes != null && uidState.opModes.size() > 0) {
+ out.startTag(null, "uid");
+ out.attribute(null, "n", Integer.toString(uidState.uid));
+ SparseIntArray uidOpModes = uidState.opModes;
+ final int opCount = uidOpModes.size();
+ for (int j = 0; j < opCount; j++) {
+ final int op = uidOpModes.keyAt(j);
+ final int mode = uidOpModes.valueAt(j);
+ out.startTag(null, "op");
+ out.attribute(null, "n", Integer.toString(op));
+ out.attribute(null, "m", Integer.toString(mode));
+ out.endTag(null, "op");
+ }
+ out.endTag(null, "uid");
+ }
+ }
if (allOps != null) {
String lastPkg = null;
@@ -1316,9 +1635,27 @@
if (needSep) {
pw.println();
}
- for (int i=0; i<mUidOps.size(); i++) {
- pw.print(" Uid "); UserHandle.formatUid(pw, mUidOps.keyAt(i)); pw.println(":");
- HashMap<String, Ops> pkgOps = mUidOps.valueAt(i);
+ for (int i=0; i<mUidStates.size(); i++) {
+ UidState uidState = mUidStates.valueAt(i);
+
+ pw.print(" Uid "); UserHandle.formatUid(pw, uidState.uid); pw.println(":");
+
+ SparseIntArray opModes = uidState.opModes;
+ if (opModes != null) {
+ final int opModeCount = opModes.size();
+ for (int j = 0; j < opModeCount; j++) {
+ final int code = opModes.keyAt(j);
+ final int mode = opModes.valueAt(j);
+ pw.print(" "); pw.print(AppOpsManager.opToName(code));
+ pw.print(": mode="); pw.println(mode);
+ }
+ }
+
+ ArrayMap<String, Ops> pkgOps = uidState.pkgOps;
+ if (pkgOps == null) {
+ continue;
+ }
+
for (Ops ops : pkgOps.values()) {
pw.print(" Package "); pw.print(ops.packageName); pw.println(":");
for (int j=0; j<ops.size(); j++) {
@@ -1382,4 +1719,16 @@
}
}
+ private static String[] getPackagesForUid(int uid) {
+ String[] packageNames = null;
+ try {
+ packageNames= AppGlobals.getPackageManager().getPackagesForUid(uid);
+ } catch (RemoteException e) {
+ /* ignore - local call */
+ }
+ if (packageNames == null) {
+ return EmptyArray.STRING;
+ }
+ return packageNames;
+ }
}
diff --git a/services/core/java/com/android/server/BluetoothManagerService.java b/services/core/java/com/android/server/BluetoothManagerService.java
index b9f62e6..50bd544 100644
--- a/services/core/java/com/android/server/BluetoothManagerService.java
+++ b/services/core/java/com/android/server/BluetoothManagerService.java
@@ -805,6 +805,7 @@
IBinder mService;
ComponentName mClassName;
Intent mIntent;
+ boolean mInvokingProxyCallbacks = false;
ProfileServiceConnections(Intent intent) {
mService = null;
@@ -871,34 +872,54 @@
} catch (RemoteException e) {
Log.e(TAG, "Unable to linkToDeath", e);
}
- int n = mProxies.beginBroadcast();
- for (int i = 0; i < n; i++) {
- try {
- mProxies.getBroadcastItem(i).onServiceConnected(className, service);
- } catch (RemoteException e) {
- Log.e(TAG, "Unable to connect to proxy", e);
- }
+
+ if (mInvokingProxyCallbacks) {
+ Log.e(TAG, "Proxy callbacks already in progress.");
+ return;
}
- mProxies.finishBroadcast();
+ mInvokingProxyCallbacks = true;
+
+ final int n = mProxies.beginBroadcast();
+ try {
+ for (int i = 0; i < n; i++) {
+ try {
+ mProxies.getBroadcastItem(i).onServiceConnected(className, service);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Unable to connect to proxy", e);
+ }
+ }
+ } finally {
+ mProxies.finishBroadcast();
+ mInvokingProxyCallbacks = false;
+ }
}
@Override
public void onServiceDisconnected(ComponentName className) {
- if (mService == null) {
- return;
- }
+ if (mService == null) return;
mService.unlinkToDeath(this, 0);
mService = null;
mClassName = null;
- int n = mProxies.beginBroadcast();
- for (int i = 0; i < n; i++) {
- try {
- mProxies.getBroadcastItem(i).onServiceDisconnected(className);
- } catch (RemoteException e) {
- Log.e(TAG, "Unable to disconnect from proxy", e);
- }
+
+ if (mInvokingProxyCallbacks) {
+ Log.e(TAG, "Proxy callbacks already in progress.");
+ return;
}
- mProxies.finishBroadcast();
+ mInvokingProxyCallbacks = true;
+
+ final int n = mProxies.beginBroadcast();
+ try {
+ for (int i = 0; i < n; i++) {
+ try {
+ mProxies.getBroadcastItem(i).onServiceDisconnected(className);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Unable to disconnect from proxy", e);
+ }
+ }
+ } finally {
+ mProxies.finishBroadcast();
+ mInvokingProxyCallbacks = false;
+ }
}
@Override
@@ -916,16 +937,19 @@
}
private void sendBluetoothStateCallback(boolean isUp) {
- int n = mStateChangeCallbacks.beginBroadcast();
- if (DBG) Log.d(TAG,"Broadcasting onBluetoothStateChange("+isUp+") to " + n + " receivers.");
- for (int i=0; i <n;i++) {
- try {
- mStateChangeCallbacks.getBroadcastItem(i).onBluetoothStateChange(isUp);
- } catch (RemoteException e) {
- Log.e(TAG, "Unable to call onBluetoothStateChange() on callback #" + i , e);
+ try {
+ int n = mStateChangeCallbacks.beginBroadcast();
+ if (DBG) Log.d(TAG,"Broadcasting onBluetoothStateChange("+isUp+") to " + n + " receivers.");
+ for (int i=0; i <n;i++) {
+ try {
+ mStateChangeCallbacks.getBroadcastItem(i).onBluetoothStateChange(isUp);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Unable to call onBluetoothStateChange() on callback #" + i , e);
+ }
}
+ } finally {
+ mStateChangeCallbacks.finishBroadcast();
}
- mStateChangeCallbacks.finishBroadcast();
}
/**
@@ -934,16 +958,19 @@
private void sendBluetoothServiceUpCallback() {
if (!mConnection.isGetNameAddressOnly()) {
if (DBG) Log.d(TAG,"Calling onBluetoothServiceUp callbacks");
- int n = mCallbacks.beginBroadcast();
- Log.d(TAG,"Broadcasting onBluetoothServiceUp() to " + n + " receivers.");
- for (int i=0; i <n;i++) {
- try {
- mCallbacks.getBroadcastItem(i).onBluetoothServiceUp(mBluetooth);
- } catch (RemoteException e) {
- Log.e(TAG, "Unable to call onBluetoothServiceUp() on callback #" + i, e);
+ try {
+ int n = mCallbacks.beginBroadcast();
+ Log.d(TAG,"Broadcasting onBluetoothServiceUp() to " + n + " receivers.");
+ for (int i=0; i <n;i++) {
+ try {
+ mCallbacks.getBroadcastItem(i).onBluetoothServiceUp(mBluetooth);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Unable to call onBluetoothServiceUp() on callback #" + i, e);
+ }
}
+ } finally {
+ mCallbacks.finishBroadcast();
}
- mCallbacks.finishBroadcast();
}
}
/**
@@ -952,16 +979,19 @@
private void sendBluetoothServiceDownCallback() {
if (!mConnection.isGetNameAddressOnly()) {
if (DBG) Log.d(TAG,"Calling onBluetoothServiceDown callbacks");
- int n = mCallbacks.beginBroadcast();
- Log.d(TAG,"Broadcasting onBluetoothServiceDown() to " + n + " receivers.");
- for (int i=0; i <n;i++) {
- try {
- mCallbacks.getBroadcastItem(i).onBluetoothServiceDown();
- } catch (RemoteException e) {
- Log.e(TAG, "Unable to call onBluetoothServiceDown() on callback #" + i, e);
+ try {
+ int n = mCallbacks.beginBroadcast();
+ Log.d(TAG,"Broadcasting onBluetoothServiceDown() to " + n + " receivers.");
+ for (int i=0; i <n;i++) {
+ try {
+ mCallbacks.getBroadcastItem(i).onBluetoothServiceDown();
+ } catch (RemoteException e) {
+ Log.e(TAG, "Unable to call onBluetoothServiceDown() on callback #" + i, e);
+ }
}
+ } finally {
+ mCallbacks.finishBroadcast();
}
- mCallbacks.finishBroadcast();
}
}
@@ -1476,6 +1506,7 @@
//Unbind
mContext.unbindService(mConnection);
}
+ mBluetoothGatt = null;
}
SystemClock.sleep(100);
@@ -1781,6 +1812,7 @@
//Unbind
mContext.unbindService(mConnection);
}
+ mBluetoothGatt = null;
}
mHandler.removeMessages(MESSAGE_BLUETOOTH_STATE_CHANGE);
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index 445d8ad..028460c 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -3102,7 +3102,10 @@
@Override
public LegacyVpnInfo getLegacyVpnInfo(int userId) {
enforceCrossUserPermission(userId);
- throwIfLockdownEnabled();
+ if (mLockdownEnabled) {
+ return null;
+ }
+
synchronized(mVpns) {
return mVpns.get(userId).getLegacyVpnInfo();
}
@@ -4094,6 +4097,16 @@
}
if (!Objects.equals(nai.networkCapabilities, networkCapabilities)) {
final int oldScore = nai.getCurrentScore();
+ if (nai.networkCapabilities.hasCapability(NET_CAPABILITY_NOT_RESTRICTED) !=
+ networkCapabilities.hasCapability(NET_CAPABILITY_NOT_RESTRICTED)) {
+ try {
+ mNetd.setNetworkPermission(nai.network.netId,
+ networkCapabilities.hasCapability(NET_CAPABILITY_NOT_RESTRICTED) ?
+ null : NetworkManagementService.PERMISSION_SYSTEM);
+ } catch (RemoteException e) {
+ loge("Exception in setNetworkPermission: " + e);
+ }
+ }
synchronized (nai) {
nai.networkCapabilities = networkCapabilities;
}
@@ -4561,7 +4574,10 @@
(networkAgent.networkMisc == null ||
!networkAgent.networkMisc.allowBypass));
} else {
- mNetd.createPhysicalNetwork(networkAgent.network.netId);
+ mNetd.createPhysicalNetwork(networkAgent.network.netId,
+ networkAgent.networkCapabilities.hasCapability(
+ NET_CAPABILITY_NOT_RESTRICTED) ?
+ null : NetworkManagementService.PERMISSION_SYSTEM);
}
} catch (Exception e) {
loge("Error creating network " + networkAgent.network.netId + ": "
diff --git a/services/core/java/com/android/server/EventLogTags.logtags b/services/core/java/com/android/server/EventLogTags.logtags
index daf1751..13b3f8d 100644
--- a/services/core/java/com/android/server/EventLogTags.logtags
+++ b/services/core/java/com/android/server/EventLogTags.logtags
@@ -158,7 +158,7 @@
# Task removed with source explanation.
31003 wm_task_removed (TaskId|1|5),(Reason|3)
# Stack created.
-31004 wm_stack_created (StackId|1|5),(RelativeBoxId|1|5),(Position|1),(Weight|1|6)
+31004 wm_stack_created (StackId|1|5)
# Home stack moved to top (1) or bottom (0).
31005 wm_home_stack_moved (ToTop|1)
# Stack removed.
diff --git a/services/core/java/com/android/server/GestureLauncherService.java b/services/core/java/com/android/server/GestureLauncherService.java
index d7b0765..e17ff5c 100644
--- a/services/core/java/com/android/server/GestureLauncherService.java
+++ b/services/core/java/com/android/server/GestureLauncherService.java
@@ -32,6 +32,7 @@
import android.os.PowerManager.WakeLock;
import android.os.SystemProperties;
import android.provider.MediaStore;
+import android.provider.Settings;
import android.util.Slog;
/**
@@ -152,13 +153,25 @@
private void handleCameraLaunchGesture() {
if (DBG) Slog.d(TAG, "Received a camera launch event.");
+ 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;
+ }
+ if (DBG) Slog.d(TAG, String.format(
+ "userSetupComplete = %s, performing camera launch gesture.",
+ userSetupComplete));
boolean locked = mKeyGuard != null && mKeyGuard.inKeyguardRestrictedInputMode();
String action = locked
? MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA_SECURE
: MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA;
Intent intent = new Intent(action);
PackageManager pm = mContext.getPackageManager();
- ResolveInfo componentInfo = pm.resolveActivity(intent, PackageManager.MATCH_DEFAULT_ONLY);
+ ResolveInfo componentInfo = pm.resolveActivity(intent,
+ PackageManager.MATCH_DEFAULT_ONLY);
if (componentInfo == null) {
if (DBG) Slog.d(TAG, "Couldn't find an app to process the camera intent.");
return;
@@ -167,7 +180,6 @@
if (mVibrator != null && mVibrator.hasVibrator()) {
mVibrator.vibrate(1000L);
}
-
// Turn on the screen before the camera launches.
mWakeLock.acquire(500L);
intent.setComponent(new ComponentName(componentInfo.activityInfo.packageName,
diff --git a/services/core/java/com/android/server/InputMethodManagerService.java b/services/core/java/com/android/server/InputMethodManagerService.java
index 64ee5f1..4e11070 100644
--- a/services/core/java/com/android/server/InputMethodManagerService.java
+++ b/services/core/java/com/android/server/InputMethodManagerService.java
@@ -3555,7 +3555,7 @@
? new File(Environment.getDataDirectory(), SYSTEM_PATH)
: Environment.getUserSystemDirectory(userId);
final File inputMethodDir = new File(systemDir, INPUT_METHOD_PATH);
- if (!inputMethodDir.mkdirs()) {
+ if (!inputMethodDir.exists() && !inputMethodDir.mkdirs()) {
Slog.w(TAG, "Couldn't create dir.: " + inputMethodDir.getAbsolutePath());
}
final File subtypeFile = new File(inputMethodDir, ADDITIONAL_SUBTYPES_FILE_NAME);
diff --git a/services/core/java/com/android/server/MountService.java b/services/core/java/com/android/server/MountService.java
index 7d26a8f..7fa1d09 100644
--- a/services/core/java/com/android/server/MountService.java
+++ b/services/core/java/com/android/server/MountService.java
@@ -559,6 +559,7 @@
private static final int H_FSTRIM = 4;
private static final int H_VOLUME_MOUNT = 5;
private static final int H_VOLUME_BROADCAST = 6;
+ private static final int H_INTERNAL_BROADCAST = 7;
class MountServiceHandler extends Handler {
public MountServiceHandler(Looper looper) {
@@ -655,6 +656,13 @@
}
break;
}
+ case H_INTERNAL_BROADCAST: {
+ // Internal broadcasts aimed at system components, not for
+ // third-party apps.
+ final Intent intent = (Intent) msg.obj;
+ mContext.sendBroadcastAsUser(intent, UserHandle.ALL,
+ android.Manifest.permission.WRITE_MEDIA_STORAGE);
+ }
}
}
}
@@ -1126,8 +1134,7 @@
intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
intent.putExtra(DiskInfo.EXTRA_DISK_ID, disk.id);
intent.putExtra(DiskInfo.EXTRA_VOLUME_COUNT, volumeCount);
- mContext.sendBroadcastAsUser(intent, UserHandle.ALL,
- android.Manifest.permission.WRITE_MEDIA_STORAGE);
+ mHandler.obtainMessage(H_INTERNAL_BROADCAST, intent).sendToTarget();
final CountDownLatch latch = mDiskScanLatches.remove(disk.id);
if (latch != null) {
@@ -1239,8 +1246,7 @@
intent.putExtra(VolumeInfo.EXTRA_VOLUME_STATE, newState);
intent.putExtra(VolumeRecord.EXTRA_FS_UUID, vol.fsUuid);
intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
- mContext.sendBroadcastAsUser(intent, UserHandle.ALL,
- android.Manifest.permission.WRITE_MEDIA_STORAGE);
+ mHandler.obtainMessage(H_INTERNAL_BROADCAST, intent).sendToTarget();
}
final String oldStateEnv = VolumeInfo.getEnvironmentForState(oldState);
diff --git a/services/core/java/com/android/server/NetworkManagementService.java b/services/core/java/com/android/server/NetworkManagementService.java
index 0e3134d..dd19c6a 100644
--- a/services/core/java/com/android/server/NetworkManagementService.java
+++ b/services/core/java/com/android/server/NetworkManagementService.java
@@ -131,6 +131,19 @@
*/
public static final String LIMIT_GLOBAL_ALERT = "globalAlert";
+ /**
+ * String to pass to netd to indicate that a network is only accessible
+ * to apps that have the CHANGE_NETWORK_STATE permission.
+ */
+ public static final String PERMISSION_NETWORK = "NETWORK";
+
+ /**
+ * String to pass to netd to indicate that a network is only
+ * accessible to system apps and those with the CONNECTIVITY_INTERNAL
+ * permission.
+ */
+ public static final String PERMISSION_SYSTEM = "SYSTEM";
+
class NetdResponseCode {
/* Keep in sync with system/netd/server/ResponseCode.h */
public static final int InterfaceListResult = 110;
@@ -2010,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) == 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);
@@ -2329,11 +2342,15 @@
}
@Override
- public void createPhysicalNetwork(int netId) {
+ public void createPhysicalNetwork(int netId, String permission) {
mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
try {
- mConnector.execute("network", "create", netId);
+ if (permission != null) {
+ mConnector.execute("network", "create", netId, permission);
+ } else {
+ mConnector.execute("network", "create", netId);
+ }
} catch (NativeDaemonConnectorException e) {
throw e.rethrowAsParcelableException();
}
@@ -2425,6 +2442,22 @@
}
@Override
+ public void setNetworkPermission(int netId, String permission) {
+ mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
+
+ try {
+ if (permission != null) {
+ mConnector.execute("network", "permission", "network", "set", permission, netId);
+ } else {
+ mConnector.execute("network", "permission", "network", "clear", netId);
+ }
+ } catch (NativeDaemonConnectorException e) {
+ throw e.rethrowAsParcelableException();
+ }
+ }
+
+
+ @Override
public void setPermission(String permission, int[] uids) {
mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
diff --git a/services/core/java/com/android/server/TelephonyRegistry.java b/services/core/java/com/android/server/TelephonyRegistry.java
index a06bb30..19a4851 100644
--- a/services/core/java/com/android/server/TelephonyRegistry.java
+++ b/services/core/java/com/android/server/TelephonyRegistry.java
@@ -362,10 +362,10 @@
}
try {
- mContext.enforceCallingPermission(
+ mContext.enforceCallingOrSelfPermission(
android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE,
"addOnSubscriptionsChangedListener");
- // SKIP checking for run-time permission since obtained PRIVILEGED
+ // SKIP checking for run-time permission since caller or self has PRIVILEGED permission
} catch (SecurityException e) {
mContext.enforceCallingOrSelfPermission(
android.Manifest.permission.READ_PHONE_STATE,
@@ -481,9 +481,10 @@
if ((events & ENFORCE_PHONE_STATE_PERMISSION_MASK) != 0) {
try {
- mContext.enforceCallingPermission(
+ mContext.enforceCallingOrSelfPermission(
android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, null);
- // SKIP checking for run-time permission since obtained PRIVILEGED
+ // SKIP checking for run-time permission since caller or self has PRIVILEGED
+ // permission
} catch (SecurityException e) {
if (mAppOps.noteOp(AppOpsManager.OP_READ_PHONE_STATE, Binder.getCallingUid(),
callingPackage) != AppOpsManager.MODE_ALLOWED) {
@@ -661,10 +662,10 @@
}
private boolean canReadPhoneState(String callingPackage) {
- if (mContext.checkCallingPermission(
+ if (mContext.checkCallingOrSelfPermission(
android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) ==
PackageManager.PERMISSION_GRANTED) {
- // SKIP checking for run-time permission since obtained PRIVILEGED
+ // SKIP checking for run-time permission since caller or self has PRIVILEGED permission
return true;
}
boolean canReadPhoneState = mContext.checkCallingOrSelfPermission(
@@ -1589,9 +1590,10 @@
if ((events & ENFORCE_PHONE_STATE_PERMISSION_MASK) != 0) {
try {
- mContext.enforceCallingPermission(
+ mContext.enforceCallingOrSelfPermission(
android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, null);
- // SKIP checking for run-time permission since obtained PRIVILEGED
+ // SKIP checking for run-time permission since caller or self has PRIVILEGED
+ // permission
} catch (SecurityException e) {
mContext.enforceCallingOrSelfPermission(
android.Manifest.permission.READ_PHONE_STATE, null);
diff --git a/services/core/java/com/android/server/accounts/AccountManagerService.java b/services/core/java/com/android/server/accounts/AccountManagerService.java
index 32fd56a..83e8db0 100644
--- a/services/core/java/com/android/server/accounts/AccountManagerService.java
+++ b/services/core/java/com/android/server/accounts/AccountManagerService.java
@@ -527,14 +527,14 @@
+ ", pid " + Binder.getCallingPid());
}
if (account == null) throw new IllegalArgumentException("account is null");
- if (!isAccountManagedByCaller(account.type, callingUid)) {
+ int userId = UserHandle.getCallingUserId();
+ if (!isAccountManagedByCaller(account.type, callingUid, userId)) {
String msg = String.format(
"uid %s cannot get secrets for accounts of type: %s",
callingUid,
account.type);
throw new SecurityException(msg);
}
- int userId = UserHandle.getCallingUserId();
long identityToken = clearCallingIdentity();
try {
UserAccounts accounts = getUserAccounts(userId);
@@ -627,14 +627,14 @@
}
if (account == null) throw new IllegalArgumentException("account is null");
if (key == null) throw new IllegalArgumentException("key is null");
- if (!isAccountManagedByCaller(account.type, callingUid)) {
+ int userId = UserHandle.getCallingUserId();
+ if (!isAccountManagedByCaller(account.type, callingUid, userId)) {
String msg = String.format(
"uid %s cannot get user data for accounts of type: %s",
callingUid,
account.type);
throw new SecurityException(msg);
}
- int userId = UserHandle.getCallingUserId();
long identityToken = clearCallingIdentity();
try {
UserAccounts accounts = getUserAccounts(userId);
@@ -664,22 +664,32 @@
final long identityToken = clearCallingIdentity();
try {
- Collection<AccountAuthenticatorCache.ServiceInfo<AuthenticatorDescription>>
- authenticatorCollection = mAuthenticatorCache.getAllServices(userId);
- AuthenticatorDescription[] types =
- new AuthenticatorDescription[authenticatorCollection.size()];
- int i = 0;
- for (AccountAuthenticatorCache.ServiceInfo<AuthenticatorDescription> authenticator
- : authenticatorCollection) {
- types[i] = authenticator.type;
- i++;
- }
- return types;
+ return getAuthenticatorTypesInternal(userId);
+
} finally {
restoreCallingIdentity(identityToken);
}
}
+ /**
+ * Should only be called inside of a clearCallingIdentity block.
+ */
+ private AuthenticatorDescription[] getAuthenticatorTypesInternal(int userId) {
+ Collection<AccountAuthenticatorCache.ServiceInfo<AuthenticatorDescription>>
+ authenticatorCollection = mAuthenticatorCache.getAllServices(userId);
+ AuthenticatorDescription[] types =
+ new AuthenticatorDescription[authenticatorCollection.size()];
+ int i = 0;
+ for (AccountAuthenticatorCache.ServiceInfo<AuthenticatorDescription> authenticator
+ : authenticatorCollection) {
+ types[i] = authenticator.type;
+ i++;
+ }
+ return types;
+ }
+
+
+
private boolean isCrossUser(int callingUid, int userId) {
return (userId != UserHandle.getCallingUserId()
&& callingUid != Process.myUid()
@@ -697,7 +707,8 @@
+ ", pid " + Binder.getCallingPid());
}
if (account == null) throw new IllegalArgumentException("account is null");
- if (!isAccountManagedByCaller(account.type, callingUid)) {
+ int userId = UserHandle.getCallingUserId();
+ if (!isAccountManagedByCaller(account.type, callingUid, userId)) {
String msg = String.format(
"uid %s cannot explicitly add accounts of type: %s",
callingUid,
@@ -713,12 +724,10 @@
*/
// fails if the account already exists
- int uid = getCallingUid();
- int userId = UserHandle.getCallingUserId();
long identityToken = clearCallingIdentity();
try {
UserAccounts accounts = getUserAccounts(userId);
- return addAccountInternal(accounts, account, password, extras, false, uid);
+ return addAccountInternal(accounts, account, password, extras, false, callingUid);
} finally {
restoreCallingIdentity(identityToken);
}
@@ -794,25 +803,26 @@
if (account == null) {
throw new IllegalArgumentException("account is null");
}
- if (!isAccountManagedByCaller(account.type, callingUid)) {
+ int userId = UserHandle.getCallingUserId();
+ if (!isAccountManagedByCaller(account.type, callingUid, userId)) {
String msg = String.format(
"uid %s cannot notify authentication for accounts of type: %s",
callingUid,
account.type);
throw new SecurityException(msg);
}
- int userId = Binder.getCallingUserHandle().getIdentifier();
+
if (!canUserModifyAccounts(userId) || !canUserModifyAccountsForType(userId, account.type)) {
return false;
}
- int user = UserHandle.getCallingUserId();
+
long identityToken = clearCallingIdentity();
try {
- UserAccounts accounts = getUserAccounts(user);
+ UserAccounts accounts = getUserAccounts(userId);
+ return updateLastAuthenticatedTime(account);
} finally {
restoreCallingIdentity(identityToken);
}
- return updateLastAuthenticatedTime(account);
}
private boolean updateLastAuthenticatedTime(Account account) {
@@ -985,8 +995,9 @@
if (response == null) throw new IllegalArgumentException("response is null");
if (account == null) throw new IllegalArgumentException("account is null");
if (features == null) throw new IllegalArgumentException("features is null");
- checkReadAccountsPermitted(callingUid, account.type);
int userId = UserHandle.getCallingUserId();
+ checkReadAccountsPermitted(callingUid, account.type, userId);
+
long identityToken = clearCallingIdentity();
try {
UserAccounts accounts = getUserAccounts(userId);
@@ -1062,14 +1073,14 @@
+ ", pid " + Binder.getCallingPid());
}
if (accountToRename == null) throw new IllegalArgumentException("account is null");
- if (!isAccountManagedByCaller(accountToRename.type, callingUid)) {
+ int userId = UserHandle.getCallingUserId();
+ if (!isAccountManagedByCaller(accountToRename.type, callingUid, userId)) {
String msg = String.format(
"uid %s cannot rename accounts of type: %s",
callingUid,
accountToRename.type);
throw new SecurityException(msg);
}
- int userId = UserHandle.getCallingUserId();
long identityToken = clearCallingIdentity();
try {
UserAccounts accounts = getUserAccounts(userId);
@@ -1211,14 +1222,15 @@
* authenticator. This will let users remove accounts (via Settings in the system) but not
* arbitrary applications (like competing authenticators).
*/
- if (!isAccountManagedByCaller(account.type, callingUid) && !isSystemUid(callingUid)) {
+ UserHandle user = new UserHandle(userId);
+ if (!isAccountManagedByCaller(account.type, callingUid, user.getIdentifier())
+ && !isSystemUid(callingUid)) {
String msg = String.format(
"uid %s cannot remove accounts of type: %s",
callingUid,
account.type);
throw new SecurityException(msg);
}
-
if (!canUserModifyAccounts(userId)) {
try {
response.onError(AccountManager.ERROR_CODE_USER_RESTRICTED,
@@ -1235,10 +1247,7 @@
}
return;
}
-
- UserHandle user = new UserHandle(userId);
long identityToken = clearCallingIdentity();
-
UserAccounts accounts = getUserAccounts(userId);
cancelNotification(getSigninRequiredNotificationId(accounts, account), user);
synchronized(accounts.credentialsPermissionNotificationIds) {
@@ -1268,6 +1277,7 @@
+ ", caller's uid " + callingUid
+ ", pid " + Binder.getCallingPid());
}
+ int userId = Binder.getCallingUserHandle().getIdentifier();
if (account == null) {
/*
* Null accounts should result in returning false, as per
@@ -1275,22 +1285,18 @@
*/
Log.e(TAG, "account is null");
return false;
- } else if (!isAccountManagedByCaller(account.type, callingUid)) {
+ } else if (!isAccountManagedByCaller(account.type, callingUid, userId)) {
String msg = String.format(
"uid %s cannot explicitly add accounts of type: %s",
callingUid,
account.type);
throw new SecurityException(msg);
}
-
UserAccounts accounts = getUserAccountsForCaller();
- int userId = Binder.getCallingUserHandle().getIdentifier();
if (!canUserModifyAccounts(userId) || !canUserModifyAccountsForType(userId, account.type)) {
return false;
}
-
logRecord(accounts, DebugDbHelper.ACTION_CALLED_ACCOUNT_REMOVE, TABLE_ACCOUNTS);
-
long identityToken = clearCallingIdentity();
try {
return removeAccountInternal(accounts, account);
@@ -1524,14 +1530,14 @@
}
if (account == null) throw new IllegalArgumentException("account is null");
if (authTokenType == null) throw new IllegalArgumentException("authTokenType is null");
- if (!isAccountManagedByCaller(account.type, callingUid)) {
+ int userId = UserHandle.getCallingUserId();
+ if (!isAccountManagedByCaller(account.type, callingUid, userId)) {
String msg = String.format(
"uid %s cannot peek the authtokens associated with accounts of type: %s",
callingUid,
account.type);
throw new SecurityException(msg);
}
- int userId = UserHandle.getCallingUserId();
long identityToken = clearCallingIdentity();
try {
UserAccounts accounts = getUserAccounts(userId);
@@ -1552,14 +1558,14 @@
}
if (account == null) throw new IllegalArgumentException("account is null");
if (authTokenType == null) throw new IllegalArgumentException("authTokenType is null");
- if (!isAccountManagedByCaller(account.type, callingUid)) {
+ int userId = UserHandle.getCallingUserId();
+ if (!isAccountManagedByCaller(account.type, callingUid, userId)) {
String msg = String.format(
"uid %s cannot set auth tokens associated with accounts of type: %s",
callingUid,
account.type);
throw new SecurityException(msg);
}
- int userId = UserHandle.getCallingUserId();
long identityToken = clearCallingIdentity();
try {
UserAccounts accounts = getUserAccounts(userId);
@@ -1578,14 +1584,14 @@
+ ", pid " + Binder.getCallingPid());
}
if (account == null) throw new IllegalArgumentException("account is null");
- if (!isAccountManagedByCaller(account.type, callingUid)) {
+ int userId = UserHandle.getCallingUserId();
+ if (!isAccountManagedByCaller(account.type, callingUid, userId)) {
String msg = String.format(
"uid %s cannot set secrets for accounts of type: %s",
callingUid,
account.type);
throw new SecurityException(msg);
}
- int userId = UserHandle.getCallingUserId();
long identityToken = clearCallingIdentity();
try {
UserAccounts accounts = getUserAccounts(userId);
@@ -1642,14 +1648,14 @@
+ ", pid " + Binder.getCallingPid());
}
if (account == null) throw new IllegalArgumentException("account is null");
- if (!isAccountManagedByCaller(account.type, callingUid)) {
+ int userId = UserHandle.getCallingUserId();
+ if (!isAccountManagedByCaller(account.type, callingUid, userId)) {
String msg = String.format(
"uid %s cannot clear passwords for accounts of type: %s",
callingUid,
account.type);
throw new SecurityException(msg);
}
- int userId = UserHandle.getCallingUserId();
long identityToken = clearCallingIdentity();
try {
UserAccounts accounts = getUserAccounts(userId);
@@ -1670,14 +1676,14 @@
}
if (key == null) throw new IllegalArgumentException("key is null");
if (account == null) throw new IllegalArgumentException("account is null");
- if (!isAccountManagedByCaller(account.type, callingUid)) {
+ int userId = UserHandle.getCallingUserId();
+ if (!isAccountManagedByCaller(account.type, callingUid, userId)) {
String msg = String.format(
"uid %s cannot set user data for accounts of type: %s",
callingUid,
account.type);
throw new SecurityException(msg);
}
- int userId = UserHandle.getCallingUserId();
long identityToken = clearCallingIdentity();
try {
UserAccounts accounts = getUserAccounts(userId);
@@ -1840,8 +1846,8 @@
// skip the check if customTokens
final int callerUid = Binder.getCallingUid();
- final boolean permissionGranted = customTokens ||
- permissionIsGranted(account, authTokenType, callerUid);
+ final boolean permissionGranted =
+ customTokens || permissionIsGranted(account, authTokenType, callerUid, userId);
// Get the calling package. We will use it for the purpose of caching.
final String callerPkg = loginOptions.getString(AccountManager.KEY_ANDROID_PACKAGE_NAME);
@@ -2363,14 +2369,14 @@
}
if (response == null) throw new IllegalArgumentException("response is null");
if (accountType == null) throw new IllegalArgumentException("accountType is null");
- if (!isAccountManagedByCaller(accountType, callingUid) && !isSystemUid(callingUid)) {
+ int userId = UserHandle.getCallingUserId();
+ if (!isAccountManagedByCaller(accountType, callingUid, userId) && !isSystemUid(callingUid)) {
String msg = String.format(
"uid %s cannot edit authenticator properites for account type: %s",
callingUid,
accountType);
throw new SecurityException(msg);
}
- int userId = UserHandle.getCallingUserId();
long identityToken = clearCallingIdentity();
try {
UserAccounts accounts = getUserAccounts(userId);
@@ -2493,20 +2499,22 @@
}
/**
- * Returns the accounts for a specific user
+ * Returns the accounts visible to the client within the context of a specific user
* @hide
*/
public Account[] getAccounts(int userId) {
int callingUid = Binder.getCallingUid();
- if (!isReadAccountsPermitted(callingUid, null)) {
+ List<String> visibleAccountTypes = getTypesVisibleToCaller(callingUid, userId);
+ if (visibleAccountTypes.isEmpty()) {
return new Account[0];
}
long identityToken = clearCallingIdentity();
try {
- UserAccounts accounts = getUserAccounts(userId);
- synchronized (accounts.cacheLock) {
- return getAccountsFromCacheLocked(accounts, null, callingUid, null);
- }
+ return getAccountsInternal(
+ userId,
+ callingUid,
+ null, // packageName
+ visibleAccountTypes);
} finally {
restoreCallingIdentity(identityToken);
}
@@ -2588,22 +2596,52 @@
callingUid = packageUid;
}
- // Authenticators should be able to see their own accounts regardless of permissions.
- if (TextUtils.isEmpty(type) && !isReadAccountsPermitted(callingUid, type)) {
+ List<String> visibleAccountTypes = getTypesVisibleToCaller(callingUid, userId);
+ if (visibleAccountTypes.isEmpty()
+ || (type != null && !visibleAccountTypes.contains(type))) {
return new Account[0];
- }
+ } else if (visibleAccountTypes.contains(type)) {
+ // Prune the list down to just the requested type.
+ visibleAccountTypes = new ArrayList<>();
+ visibleAccountTypes.add(type);
+ } // else aggregate all the visible accounts (it won't matter if the list is empty).
long identityToken = clearCallingIdentity();
try {
- UserAccounts accounts = getUserAccounts(userId);
- synchronized (accounts.cacheLock) {
- return getAccountsFromCacheLocked(accounts, type, callingUid, callingPackage);
- }
+ return getAccountsInternal(
+ userId,
+ callingUid,
+ callingPackage,
+ visibleAccountTypes);
} finally {
restoreCallingIdentity(identityToken);
}
}
+ private Account[] getAccountsInternal(
+ int userId,
+ int callingUid,
+ String callingPackage,
+ List<String> visibleAccountTypes) {
+ UserAccounts accounts = getUserAccounts(userId);
+ synchronized (accounts.cacheLock) {
+ UserAccounts userAccounts = getUserAccounts(userId);
+ ArrayList<Account> visibleAccounts = new ArrayList<>();
+ for (String visibleType : visibleAccountTypes) {
+ Account[] accountsForType = getAccountsFromCacheLocked(
+ userAccounts, visibleType, callingUid, callingPackage);
+ if (accountsForType != null) {
+ visibleAccounts.addAll(Arrays.asList(accountsForType));
+ }
+ }
+ Account[] result = new Account[visibleAccounts.size()];
+ for (int i = 0; i < visibleAccounts.size(); i++) {
+ result[i] = visibleAccounts.get(i);
+ }
+ return result;
+ }
+ }
+
@Override
public boolean addSharedAccountAsUser(Account account, int userId) {
userId = handleIncomingUser(userId);
@@ -2739,8 +2777,12 @@
}
if (response == null) throw new IllegalArgumentException("response is null");
if (type == null) throw new IllegalArgumentException("accountType is null");
- if (!isReadAccountsPermitted(callingUid, type)) {
+ int userId = UserHandle.getCallingUserId();
+
+ List<String> visibleAccountTypes = getTypesVisibleToCaller(callingUid, userId);
+ if (!visibleAccountTypes.contains(type)) {
Bundle result = new Bundle();
+ // Need to return just the accounts that are from matching signatures.
result.putParcelableArray(AccountManager.KEY_ACCOUNTS, new Account[0]);
try {
response.onResult(result);
@@ -2749,7 +2791,6 @@
}
return;
}
- int userId = UserHandle.getCallingUserId();
long identityToken = clearCallingIdentity();
try {
UserAccounts userAccounts = getUserAccounts(userId);
@@ -2763,7 +2804,11 @@
onResult(response, result);
return;
}
- new GetAccountsByTypeAndFeatureSession(userAccounts, response, type, features,
+ new GetAccountsByTypeAndFeatureSession(
+ userAccounts,
+ response,
+ type,
+ features,
callingUid).bind();
} finally {
restoreCallingIdentity(identityToken);
@@ -3696,10 +3741,11 @@
return false;
}
- private boolean permissionIsGranted(Account account, String authTokenType, int callerUid) {
+ private boolean permissionIsGranted(
+ Account account, String authTokenType, int callerUid, int userId) {
final boolean isPrivileged = isPrivileged(callerUid);
final boolean fromAuthenticator = account != null
- && isAccountManagedByCaller(account.type, callerUid);
+ && isAccountManagedByCaller(account.type, callerUid, userId);
final boolean hasExplicitGrants = account != null
&& hasExplicitlyGrantedPermission(account, authTokenType, callerUid);
if (Log.isLoggable(TAG, Log.VERBOSE)) {
@@ -3711,23 +3757,45 @@
return fromAuthenticator || hasExplicitGrants || isPrivileged;
}
- private boolean isAccountManagedByCaller(String accountType, int callingUid) {
+ private boolean isAccountVisibleToCaller(String accountType, int callingUid, int userId) {
if (accountType == null) {
return false;
+ } else {
+ return getTypesVisibleToCaller(callingUid, userId).contains(accountType);
}
- final int callingUserId = UserHandle.getUserId(callingUid);
+ }
+
+ private boolean isAccountManagedByCaller(String accountType, int callingUid, int userId) {
+ if (accountType == null) {
+ return false;
+ } else {
+ return getTypesManagedByCaller(callingUid, userId).contains(accountType);
+ }
+ }
+
+ private List<String> getTypesVisibleToCaller(int callingUid, int userId) {
+ boolean isPermitted =
+ isPermitted(callingUid, Manifest.permission.GET_ACCOUNTS,
+ Manifest.permission.GET_ACCOUNTS_PRIVILEGED);
+ Log.i(TAG, String.format("getTypesVisibleToCaller: isPermitted? %s", isPermitted));
+ return getTypesForCaller(callingUid, userId, isPermitted);
+ }
+
+ private List<String> getTypesManagedByCaller(int callingUid, int userId) {
+ return getTypesForCaller(callingUid, userId, false);
+ }
+
+ private List<String> getTypesForCaller(
+ int callingUid, int userId, boolean isOtherwisePermitted) {
+ List<String> managedAccountTypes = new ArrayList<>();
for (RegisteredServicesCache.ServiceInfo<AuthenticatorDescription> serviceInfo :
- mAuthenticatorCache.getAllServices(callingUserId)) {
- if (serviceInfo.type.type.equals(accountType)) {
- /*
- * We can't simply compare uids because uids can be recycled before the
- * authenticator cache is updated.
- */
- final int sigChk = mPackageManager.checkSignatures(serviceInfo.uid, callingUid);
- return sigChk == PackageManager.SIGNATURE_MATCH;
+ mAuthenticatorCache.getAllServices(userId)) {
+ final int sigChk = mPackageManager.checkSignatures(serviceInfo.uid, callingUid);
+ if (isOtherwisePermitted || sigChk == PackageManager.SIGNATURE_MATCH) {
+ managedAccountTypes.add(serviceInfo.type.type);
}
}
- return false;
+ return managedAccountTypes;
}
private boolean isAccountPresentForCaller(String accountName, String accountType) {
@@ -3792,28 +3860,12 @@
return false;
}
- private boolean isReadAccountsPermitted(int callingUid, String accountType) {
- /*
- * Settings app (which is in the same uid as AcocuntManagerService), apps with the
- * GET_ACCOUNTS permission or authenticators that own the account type should be able to
- * access accounts of the specified account.
- */
- boolean isPermitted =
- isPermitted(callingUid, Manifest.permission.GET_ACCOUNTS,
- Manifest.permission.GET_ACCOUNTS_PRIVILEGED);
- boolean isAccountManagedByCaller = isAccountManagedByCaller(accountType, callingUid);
- Log.w(TAG, String.format(
- "isReadAccountPermitted: isPermitted: %s, isAM: %s",
- isPermitted,
- isAccountManagedByCaller));
- return isPermitted || isAccountManagedByCaller;
- }
-
/** Succeeds if any of the specified permissions are granted. */
private void checkReadAccountsPermitted(
int callingUid,
- String accountType) {
- if (!isReadAccountsPermitted(callingUid, accountType)) {
+ String accountType,
+ int userId) {
+ if (!isAccountVisibleToCaller(accountType, callingUid, userId)) {
String msg = String.format(
"caller uid %s cannot access %s accounts",
callingUid,
diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java
index 899139f..0119000 100755
--- a/services/core/java/com/android/server/am/ActiveServices.java
+++ b/services/core/java/com/android/server/am/ActiveServices.java
@@ -1587,7 +1587,7 @@
while (r.pendingStarts.size() > 0) {
Exception caughtException = null;
- ServiceRecord.StartItem si;
+ ServiceRecord.StartItem si = null;
try {
si = r.pendingStarts.remove(0);
if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "Sending arguments to: "
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 755d7a0..147a5fd 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -19,6 +19,7 @@
import static android.Manifest.permission.INTERACT_ACROSS_USERS;
import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
+import static android.app.ActivityManager.HOME_STACK_ID;
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
import static com.android.internal.util.XmlUtils.readBooleanAttribute;
import static com.android.internal.util.XmlUtils.readIntAttribute;
@@ -28,7 +29,6 @@
import static com.android.internal.util.XmlUtils.writeLongAttribute;
import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST;
import static com.android.server.am.ActivityManagerDebugConfig.*;
-import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID;
import static com.android.server.am.TaskRecord.INVALID_TASK_ID;
import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_DONT_LOCK;
import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_LAUNCHABLE_PRIV;
@@ -1278,7 +1278,7 @@
int mTargetUserId = UserHandle.USER_NULL;
// If there are multiple profiles for the current user, their ids are here
// Currently only the primary user can have managed profiles
- int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack
+ int[] mCurrentProfileIds = new int[] {}; // Accessed by ActivityStack
/**
* Mapping from each known user ID to the profile group ID it is associated with.
@@ -2695,6 +2695,21 @@
}
}
+ @Override
+ public void setFocusedTask(int taskId) {
+ if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedTask: taskId=" + taskId);
+ synchronized (ActivityManagerService.this) {
+ TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
+ if (task != null) {
+ ActivityRecord r = task.topRunningActivityLocked(null);
+ if (r != null) {
+ setFocusedActivityLocked(r, "setFocusedTask");
+ mStackSupervisor.resumeTopActivitiesLocked(task.stack, null, null);
+ }
+ }
+ }
+ }
+
/** Sets the task stack listener that gets callbacks when a task stack changes. */
@Override
public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
@@ -4237,14 +4252,13 @@
* @param token The Binder token referencing the Activity we want to finish.
* @param resultCode Result code, if any, from this Activity.
* @param resultData Result data (Intent), if any, from this Activity.
- * @param finishTask Whether to finish the task associated with this Activity. Only applies to
- * the root Activity in the task.
+ * @param finishTask Whether to finish the task associated with this Activity.
*
* @return Returns true if the activity successfully finished, or false if it is still running.
*/
@Override
public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
- boolean finishTask) {
+ int finishTask) {
// Refuse possible leaked file descriptors
if (resultData != null && resultData.hasFileDescriptors() == true) {
throw new IllegalArgumentException("File descriptors passed in Intent");
@@ -4291,7 +4305,8 @@
final long origId = Binder.clearCallingIdentity();
try {
boolean res;
- if (finishTask && r == rootR) {
+ if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY
+ || (finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY && r == rootR)) {
// If requested, remove the task that is associated to this activity only if it
// was the root activity in the task. The result code and data is ignored
// because we don't support returning them across task boundaries.
@@ -6549,6 +6564,17 @@
}
@Override
+ public boolean isRootVoiceInteraction(IBinder token) {
+ synchronized(this) {
+ ActivityRecord r = ActivityRecord.isInStackLocked(token);
+ if (r == null) {
+ return false;
+ }
+ return r.rootVoiceInteraction;
+ }
+ }
+
+ @Override
public IIntentSender getIntentSender(int type,
String packageName, IBinder token, String resultWho,
int requestCode, Intent[] intents, String[] resolvedTypes,
@@ -8575,6 +8601,27 @@
}
@Override
+ public Rect getTaskBounds(int taskId) {
+ enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
+ "getTaskBounds()");
+ long ident = Binder.clearCallingIdentity();
+ Rect rect = new Rect();
+ try {
+ synchronized (this) {
+ TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
+ if (task == null) {
+ Slog.w(TAG, "getTaskBounds: taskId=" + taskId + " not found");
+ return rect;
+ }
+ mWindowManager.getTaskBounds(task.taskId, rect);
+ }
+ } finally {
+ Binder.restoreCallingIdentity(ident);
+ }
+ return rect;
+ }
+
+ @Override
public Bitmap getTaskDescriptionIcon(String filename) {
if (!FileUtils.isValidExtFilename(filename)
|| !filename.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
@@ -8862,7 +8909,8 @@
"createStackOnDisplay()");
synchronized (this) {
final int stackId = mStackSupervisor.getNextStackId();
- final ActivityStack stack = mStackSupervisor.createStackOnDisplay(stackId, displayId);
+ final ActivityStack stack =
+ mStackSupervisor.createStackOnDisplay(stackId, displayId, true /*onTop*/);
if (stack == null) {
return null;
}
@@ -8882,6 +8930,35 @@
}
@Override
+ public int getActivityStackId(IBinder token) throws RemoteException {
+ synchronized (this) {
+ ActivityStack stack = ActivityRecord.getStackLocked(token);
+ if (stack == null) {
+ throw new IllegalArgumentException(
+ "getActivityStackId: No stack for token=" + token);
+ }
+ return stack.mStackId;
+ }
+ }
+
+ @Override
+ public void moveActivityToStack(IBinder token, int stackId) throws RemoteException {
+ synchronized(this) {
+ final long origId = Binder.clearCallingIdentity();
+ try {
+ final ActivityRecord r = ActivityRecord.forTokenLocked(token);
+ if (r == null) {
+ throw new IllegalArgumentException(
+ "moveActivityToStack: No activity record matching token=" + token);
+ }
+ moveTaskToStack(r.task.taskId, stackId, true /*toTop*/);
+ } finally {
+ Binder.restoreCallingIdentity(origId);
+ }
+ }
+ }
+
+ @Override
public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
"moveTaskToStack()");
@@ -8916,6 +8993,28 @@
}
@Override
+ public void positionTaskInStack(int taskId, int stackId, int position) {
+ enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
+ "positionTaskInStack()");
+ if (stackId == HOME_STACK_ID) {
+ Slog.e(TAG, "positionTaskInStack: Attempt to change the position of task "
+ + taskId + " in/to home stack",
+ new RuntimeException("here").fillInStackTrace());
+ }
+ synchronized (this) {
+ long ident = Binder.clearCallingIdentity();
+ try {
+ if (DEBUG_STACK) Slog.d(TAG_STACK,
+ "positionTaskInStack: positioning task=" + taskId
+ + " in stackId=" + stackId + " at position=" + position);
+ mStackSupervisor.positionTaskInStackLocked(taskId, stackId, position);
+ } finally {
+ Binder.restoreCallingIdentity(ident);
+ }
+ }
+ }
+
+ @Override
public List<StackInfo> getAllStackInfos() {
enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
"getAllStackInfos()");
@@ -9152,9 +9251,10 @@
private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
List<ProviderInfo> providers = null;
try {
- providers = AppGlobals.getPackageManager().
+ ParceledListSlice<ProviderInfo> slice = AppGlobals.getPackageManager().
queryContentProviders(app.processName, app.uid,
STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
+ providers = slice != null ? slice.getList() : null;
} catch (RemoteException ex) {
}
if (DEBUG_MU) Slog.v(TAG_MU,
diff --git a/services/core/java/com/android/server/am/ActivityRecord.java b/services/core/java/com/android/server/am/ActivityRecord.java
index 0957eb5..3f8a8a1 100755
--- a/services/core/java/com/android/server/am/ActivityRecord.java
+++ b/services/core/java/com/android/server/am/ActivityRecord.java
@@ -107,6 +107,7 @@
boolean fullscreen; // covers the full screen?
final boolean noDisplay; // activity is not displayed?
final boolean componentSpecified; // did caller specifiy an explicit component?
+ final boolean rootVoiceInteraction; // was this the root activity of a voice interaction?
static final int APPLICATION_ACTIVITY_TYPE = 0;
static final int HOME_ACTIVITY_TYPE = 1;
@@ -130,10 +131,10 @@
long pauseTime; // last time we started pausing the activity
long launchTickTime; // base time for launch tick messages
Configuration configuration; // configuration activity was last running in
- // Overridden configuration by the activity stack
- // WARNING: Reference points to {@link ActivityStack#mOverrideConfig}, so its internal state
+ // Overridden configuration by the activity task
+ // WARNING: Reference points to {@link TaskRecord#mOverrideConfig}, so its internal state
// should never be altered directly.
- Configuration stackConfigOverride;
+ Configuration taskConfigOverride;
CompatibilityInfo compat;// last used compatibility mode
ActivityRecord resultTo; // who started this entry, so will get our reply
final String resultWho; // additional identifier for use by resultTo.
@@ -207,12 +208,15 @@
pw.print(prefix); pw.print("stateNotNeeded="); pw.print(stateNotNeeded);
pw.print(" componentSpecified="); pw.print(componentSpecified);
pw.print(" mActivityType="); pw.println(mActivityType);
+ if (rootVoiceInteraction) {
+ pw.print(prefix); pw.print("rootVoiceInteraction="); pw.println(rootVoiceInteraction);
+ }
pw.print(prefix); pw.print("compat="); pw.print(compat);
pw.print(" labelRes=0x"); pw.print(Integer.toHexString(labelRes));
pw.print(" icon=0x"); pw.print(Integer.toHexString(icon));
pw.print(" theme=0x"); pw.println(Integer.toHexString(theme));
pw.print(prefix); pw.print("config="); pw.println(configuration);
- pw.print(prefix); pw.print("stackConfigOverride="); pw.println(stackConfigOverride);
+ pw.print(prefix); pw.print("taskConfigOverride="); pw.println(taskConfigOverride);
if (resultTo != null || resultWho != null) {
pw.print(prefix); pw.print("resultTo="); pw.print(resultTo);
pw.print(" resultWho="); pw.print(resultWho);
@@ -432,7 +436,8 @@
int _launchedFromUid, String _launchedFromPackage, Intent _intent, String _resolvedType,
ActivityInfo aInfo, Configuration _configuration,
ActivityRecord _resultTo, String _resultWho, int _reqCode,
- boolean _componentSpecified, ActivityStackSupervisor supervisor,
+ boolean _componentSpecified, boolean _rootVoiceInteraction,
+ ActivityStackSupervisor supervisor,
ActivityContainer container, Bundle options) {
service = _service;
appToken = new Token(this, service);
@@ -444,9 +449,9 @@
shortComponentName = _intent.getComponent().flattenToShortString();
resolvedType = _resolvedType;
componentSpecified = _componentSpecified;
+ rootVoiceInteraction = _rootVoiceInteraction;
configuration = _configuration;
- stackConfigOverride = (container != null)
- ? container.mStack.mOverrideConfig : Configuration.EMPTY;
+ taskConfigOverride = Configuration.EMPTY;
resultTo = _resultTo;
resultWho = _resultWho;
requestCode = _reqCode;
@@ -1257,7 +1262,7 @@
}
final ActivityRecord r = new ActivityRecord(service, /*caller*/null, launchedFromUid,
launchedFromPackage, intent, resolvedType, aInfo, service.getConfiguration(),
- null, null, 0, componentSpecified, stackSupervisor, null, null);
+ null, null, 0, componentSpecified, false, stackSupervisor, null, null);
r.persistentState = persistentState;
r.taskDescription = taskDescription;
diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java
index 2b763ed..494ae6c 100644
--- a/services/core/java/com/android/server/am/ActivityStack.java
+++ b/services/core/java/com/android/server/am/ActivityStack.java
@@ -16,6 +16,8 @@
package com.android.server.am;
+import static android.app.ActivityManager.FULLSCREEN_WORKSPACE_STACK_ID;
+import static android.app.ActivityManager.HOME_STACK_ID;
import static android.content.pm.ActivityInfo.FLAG_SHOW_FOR_ALL_USERS;
import static com.android.server.am.ActivityManagerDebugConfig.*;
@@ -23,9 +25,9 @@
import static com.android.server.am.ActivityRecord.HOME_ACTIVITY_TYPE;
import static com.android.server.am.ActivityRecord.APPLICATION_ACTIVITY_TYPE;
-import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID;
-
+import android.graphics.Rect;
import android.util.ArraySet;
+import android.view.IApplicationToken;
import com.android.internal.app.IVoiceInteractor;
import com.android.internal.content.ReferrerIntent;
import com.android.internal.os.BatteryStatsImpl;
@@ -113,11 +115,11 @@
// How long we wait for the activity to tell us it has stopped before
// giving up. This is a good amount of time because we really need this
// from the application in order to get its saved state.
- static final int STOP_TIMEOUT = 10*1000;
+ static final int STOP_TIMEOUT = 10 * 1000;
// How long we wait until giving up on an activity telling us it has
// finished destroying itself.
- static final int DESTROY_TIMEOUT = 10*1000;
+ static final int DESTROY_TIMEOUT = 10 * 1000;
// How long until we reset a task when the user returns to it. Currently
// disabled.
@@ -125,7 +127,7 @@
// How long between activity launches that we consider safe to not warn
// the user about an unexpected activity being launched on top.
- static final long START_WARN_TIME = 5*1000;
+ static final long START_WARN_TIME = 5 * 1000;
// Set to false to disable the preview that is shown while a new activity
// is being started.
@@ -214,8 +216,7 @@
// Activity.onTranslucentConversionComplete(false). If a timeout occurs prior to the last
// background activity being drawn then the same call will be made with a true value.
ActivityRecord mTranslucentActivityWaiting = null;
- private ArrayList<ActivityRecord> mUndrawnActivitiesBelowTopTranslucent =
- new ArrayList<ActivityRecord>();
+ private ArrayList<ActivityRecord> mUndrawnActivitiesBelowTopTranslucent = new ArrayList<>();
/**
* Set when we know we are going to be calling updateConfiguration()
@@ -223,7 +224,7 @@
*/
boolean mConfigWillChange;
- // Whether or not this stack covers the entire screen; by default stacks are full screen
+ // Whether or not this stack covers the entire screen; by default stacks are fullscreen
boolean mFullscreen = true;
long mLaunchStartTime = 0;
@@ -241,11 +242,6 @@
/** Run all ActivityStacks through this */
final ActivityStackSupervisor mStackSupervisor;
- Configuration mOverrideConfig;
- /** True if the stack was forced to full screen because {@link TaskRecord#mResizeable} is false
- * and the stack was previously resized. */
- private boolean mForcedFullscreen = false;
-
static final int PAUSE_TIMEOUT_MSG = ActivityManagerService.FIRST_ACTIVITY_STACK_MSG + 1;
static final int DESTROY_TIMEOUT_MSG = ActivityManagerService.FIRST_ACTIVITY_STACK_MSG + 2;
static final int LAUNCH_TICK_MSG = ActivityManagerService.FIRST_ACTIVITY_STACK_MSG + 3;
@@ -361,7 +357,6 @@
mStackId = activityContainer.mStackId;
mCurrentUser = mService.mCurrentUserId;
mRecentTasks = recentTasks;
- mOverrideConfig = Configuration.EMPTY;
}
boolean okToShowLocked(ActivityRecord r) {
@@ -485,7 +480,15 @@
mActivityContainer.mActivityDisplay.mDisplayId == Display.DEFAULT_DISPLAY;
}
- final void moveToFront(String reason) {
+ void moveToFront(String reason) {
+ moveToFront(reason, null);
+ }
+
+ /**
+ * @param reason The reason for moving the stack to the front.
+ * @param task If non-null, the task will be moved to the top of the stack.
+ * */
+ void moveToFront(String reason, TaskRecord task) {
if (isAttached()) {
final boolean homeStack = isHomeStack()
|| (mActivityContainer.mParentActivity != null
@@ -503,7 +506,11 @@
if (isOnHomeDisplay()) {
mStackSupervisor.moveHomeStack(homeStack, reason, lastFocusStack);
}
- final TaskRecord task = topTask();
+ if (task != null) {
+ insertTaskAtTop(task, null);
+ } else {
+ task = topTask();
+ }
if (task != null) {
mWindowManager.moveTaskToTop(task.taskId);
}
@@ -1165,16 +1172,18 @@
final int numStacks = mStacks.size();
while (stackNdx < numStacks) {
- ActivityStack historyStack = mStacks.get(stackNdx);
+ final ActivityStack historyStack = mStacks.get(stackNdx);
tasks = historyStack.mTaskHistory;
final int numTasks = tasks.size();
while (taskNdx < numTasks) {
- activities = tasks.get(taskNdx).mActivities;
+ final TaskRecord currentTask = tasks.get(taskNdx);
+ activities = currentTask.mActivities;
final int numActivities = activities.size();
while (activityNdx < numActivities) {
final ActivityRecord activity = activities.get(activityNdx);
if (!activity.finishing) {
- return historyStack.mFullscreen && activity.fullscreen ? null : activity;
+ return historyStack.mFullscreen
+ && currentTask.mFullscreen && activity.fullscreen ? null : activity;
}
++activityNdx;
}
@@ -1216,22 +1225,33 @@
return true;
}
+ // Any stack that isn't the front stack is not visible, except for the case of the home
+ // stack behind the main application stack since we can have dialog activities on the
+ // main application stack that need the home stack to display behind them.
+ // TODO(multi-window): Also need to add exception for side-by-side stacks.
+ final boolean homeStack = mStackId == HOME_STACK_ID;
+ if (!homeStack) {
+ return false;
+ }
+
/**
* Start at the task above this one and go up, looking for a visible
* fullscreen activity, or a translucent activity that requested the
* wallpaper to be shown behind it.
*/
for (int i = mStacks.indexOf(this) + 1; i < mStacks.size(); i++) {
- ActivityStack stack = mStacks.get(i);
- // stack above isn't full screen, so, we assume we're still visible. at some point
- // we should look at the stack bounds to see if we're occluded even if the stack
- // isn't fullscreen
- if (!stack.mFullscreen) {
- continue;
+ final ActivityStack stack = mStacks.get(i);
+ if (stack.mStackId != FULLSCREEN_WORKSPACE_STACK_ID) {
+ return false;
}
+
final ArrayList<TaskRecord> tasks = stack.getAllTasks();
for (int taskNdx = tasks.size() - 1; taskNdx >= 0; --taskNdx) {
final TaskRecord task = tasks.get(taskNdx);
+ // task above isn't fullscreen, so, we assume we're still visible.
+ if (!task.mFullscreen) {
+ continue;
+ }
final ArrayList<ActivityRecord> activities = task.mActivities;
for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
final ActivityRecord r = activities.get(activityNdx);
@@ -1285,6 +1305,10 @@
for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
final TaskRecord task = mTaskHistory.get(taskNdx);
final ArrayList<ActivityRecord> activities = task.mActivities;
+ // Set to true if an activity in this task is fullscreen thereby hiding other
+ // activities in the same task. Initialized to the same value as behindFullscreen
+ // which represent if the entire task/stack is behind another fullscreen task/stack.
+ boolean behindFullscreenActivity = behindFullscreen;
for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
final ActivityRecord r = activities.get(activityNdx);
if (r.finishing) {
@@ -1296,7 +1320,7 @@
aboveTop = false;
// mLaunchingBehind: Activities launching behind are at the back of the task stack
// but must be drawn initially for the animation as though they were visible.
- if (!behindFullscreen || r.mLaunchTaskBehind) {
+ if (!behindFullscreenActivity || r.mLaunchTaskBehind) {
if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY,
"Make visible? " + r + " finishing=" + r.finishing
+ " state=" + r.state);
@@ -1379,17 +1403,22 @@
configChanges |= r.configChangeFlags;
if (r.fullscreen) {
- // At this point, nothing else needs to be shown
- if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Fullscreen: at " + r);
- behindFullscreen = true;
+ // At this point, nothing else needs to be shown in this task.
+ behindFullscreenActivity = true;
+ if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Fullscreen: at " + r
+ + " behindFullscreen=" + behindFullscreen
+ + " behindFullscreenActivity=" + behindFullscreenActivity);
} else if (!isHomeStack() && r.frontOfTask && task.isOverHomeStack()) {
- if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Showing home: at " + r);
- behindFullscreen = true;
+ behindFullscreenActivity = true;
+ if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Showing home: at " + r
+ + " behindFullscreen=" + behindFullscreen
+ + " behindFullscreenActivity=" + behindFullscreenActivity);
}
} else {
if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY,
- "Make invisible? " + r + " finishing=" + r.finishing
- + " state=" + r.state + " behindFullscreen=" + behindFullscreen);
+ "Make invisible? " + r + " finishing=" + r.finishing
+ + " state=" + r.state + " behindFullscreen=" + behindFullscreen
+ + " behindFullscreenActivity=" + behindFullscreenActivity);
// Now for any activities that aren't visible to the user, make
// sure they no longer are keeping the screen frozen.
if (r.visible) {
@@ -1436,6 +1465,9 @@
}
}
}
+ // Factoring if the previous task is fullscreen there by affecting the visibility of
+ // task behind it.
+ behindFullscreen |= task.mFullscreen;
}
if (mTranslucentActivityWaiting != null &&
@@ -2025,6 +2057,31 @@
return null;
}
+ private void insertTaskAtPosition(TaskRecord task, int position) {
+ if (position >= mTaskHistory.size()) {
+ insertTaskAtTop(task, null);
+ return;
+ }
+ // Calculate maximum possible position for this task.
+ int maxPosition = mTaskHistory.size();
+ if (!mStackSupervisor.isCurrentProfileLocked(task.userId)
+ && task.topRunningActivityLocked(null) == null) {
+ // Put non-current user tasks below current user tasks.
+ while (maxPosition > 0) {
+ final TaskRecord tmpTask = mTaskHistory.get(maxPosition - 1);
+ if (!mStackSupervisor.isCurrentProfileLocked(tmpTask.userId)
+ || tmpTask.topRunningActivityLocked(null) == null) {
+ break;
+ }
+ maxPosition--;
+ }
+ }
+ position = Math.min(position, maxPosition);
+ mTaskHistory.remove(task);
+ mTaskHistory.add(position, task);
+ updateTaskMovement(task, true);
+ }
+
private void insertTaskAtTop(TaskRecord task, ActivityRecord newActivity) {
// If the moving task is over home stack, transfer its return type to next task
if (task.isOverHomeStack()) {
@@ -2102,11 +2159,7 @@
+ task, new RuntimeException("here").fillInStackTrace());
task.addActivityToTop(r);
r.putInHistory();
- mWindowManager.addAppToken(task.mActivities.indexOf(r), r.appToken,
- r.task.taskId, mStackId, r.info.screenOrientation, r.fullscreen,
- (r.info.flags & ActivityInfo.FLAG_SHOW_FOR_ALL_USERS) != 0,
- r.userId, r.info.configChanges, task.voiceSession != null,
- r.mLaunchTaskBehind);
+ addAppToken(r, task);
if (VALIDATE_TOKENS) {
validateAppTokensLocked();
}
@@ -2166,10 +2219,7 @@
: AppTransition.TRANSIT_ACTIVITY_OPEN, keepCurTransition);
mNoAnimActivities.remove(r);
}
- mWindowManager.addAppToken(task.mActivities.indexOf(r),
- r.appToken, r.task.taskId, mStackId, r.info.screenOrientation, r.fullscreen,
- (r.info.flags & ActivityInfo.FLAG_SHOW_FOR_ALL_USERS) != 0, r.userId,
- r.info.configChanges, task.voiceSession != null, r.mLaunchTaskBehind);
+ addAppToken(r, task);
boolean doShow = true;
if (newTask) {
// Even though this activity is starting fresh, we still need
@@ -2218,10 +2268,7 @@
} else {
// If this is the first activity, don't do any fancy animations,
// because there is nothing for it to animate on top of.
- mWindowManager.addAppToken(task.mActivities.indexOf(r), r.appToken,
- r.task.taskId, mStackId, r.info.screenOrientation, r.fullscreen,
- (r.info.flags & ActivityInfo.FLAG_SHOW_FOR_ALL_USERS) != 0, r.userId,
- r.info.configChanges, task.voiceSession != null, r.mLaunchTaskBehind);
+ addAppToken(r, task);
ActivityOptions.abort(options);
options = null;
}
@@ -2335,8 +2382,7 @@
+ " out to new task " + target.task);
}
- final int targetTaskId = targetTask.taskId;
- mWindowManager.setAppTask(target.appToken, targetTaskId);
+ setAppTask(target, targetTask);
boolean noOptions = canMoveOptions;
final int start = replyChainEnd < 0 ? i : replyChainEnd;
@@ -2361,10 +2407,10 @@
p.setTask(targetTask, null);
targetTask.addActivityAtBottom(p);
- mWindowManager.setAppTask(p.appToken, targetTaskId);
+ setAppTask(p, targetTask);
}
- mWindowManager.moveTaskToBottom(targetTaskId);
+ mWindowManager.moveTaskToBottom(targetTask.taskId);
if (VALIDATE_TOKENS) {
validateAppTokensLocked();
}
@@ -2503,7 +2549,7 @@
+ " callers=" + Debug.getCallers(3));
if (DEBUG_TASKS) Slog.v(TAG_TASKS, "Pulling activity " + p
+ " from " + srcPos + " in to resetting task " + task);
- mWindowManager.setAppTask(p.appToken, taskId);
+ setAppTask(p, task);
}
mWindowManager.moveTaskToTop(taskId);
if (VALIDATE_TOKENS) {
@@ -3818,29 +3864,12 @@
if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
"Ensuring correct configuration: " + r);
- // Make sure the current stack override configuration is supported by the top task
- // before continuing.
- final TaskRecord topTask = topTask();
- if (topTask != null && ((topTask.mResizeable && mForcedFullscreen)
- || (!topTask.mResizeable && !mFullscreen))) {
- final boolean prevFullscreen = mFullscreen;
- final Configuration newOverrideConfig =
- mWindowManager.forceStackToFullscreen(mStackId, !topTask.mResizeable);
- updateOverrideConfiguration(newOverrideConfig);
- mForcedFullscreen = !prevFullscreen && mFullscreen;
- if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
- "Updated stack config to support task=" + topTask
- + " resizeable=" + topTask.mResizeable
- + " mForcedFullscreen=" + mForcedFullscreen
- + " prevFullscreen=" + prevFullscreen
- + " mFullscreen=" + mFullscreen);
- }
-
// Short circuit: if the two configurations are the exact same
// object (the common case), then there is nothing to do.
- Configuration newConfig = mService.mConfiguration;
+ final Configuration newConfig = mService.mConfiguration;
+ final Configuration taskConfig = r.task.mOverrideConfig;
if (r.configuration == newConfig
- && r.stackConfigOverride == mOverrideConfig
+ && r.taskConfigOverride == taskConfig
&& !r.forceNewConfig) {
if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
"Configuration unchanged in " + r);
@@ -3858,30 +3887,30 @@
// Okay we now are going to make this activity have the new config.
// But then we need to figure out how it needs to deal with that.
final Configuration oldConfig = r.configuration;
- final Configuration oldStackOverride = r.stackConfigOverride;
+ final Configuration oldTaskOverride = r.taskConfigOverride;
r.configuration = newConfig;
- r.stackConfigOverride = mOverrideConfig;
+ r.taskConfigOverride = taskConfig;
// Determine what has changed. May be nothing, if this is a config
// that has come back from the app after going idle. In that case
// we just want to leave the official config object now in the
// activity and do nothing else.
- int stackChanges = oldStackOverride.diff(mOverrideConfig);
- if (stackChanges == 0) {
+ int taskChanges = oldTaskOverride.diff(taskConfig);
+ if (taskChanges == 0) {
// {@link Configuration#diff} doesn't catch changes from unset values.
// Check for changes we care about.
- if (oldStackOverride.orientation != mOverrideConfig.orientation) {
- stackChanges |= ActivityInfo.CONFIG_ORIENTATION;
+ if (oldTaskOverride.orientation != taskConfig.orientation) {
+ taskChanges |= ActivityInfo.CONFIG_ORIENTATION;
}
- if (oldStackOverride.screenHeightDp != mOverrideConfig.screenHeightDp
- || oldStackOverride.screenWidthDp != mOverrideConfig.screenWidthDp) {
- stackChanges |= ActivityInfo.CONFIG_SCREEN_SIZE;
+ if (oldTaskOverride.screenHeightDp != taskConfig.screenHeightDp
+ || oldTaskOverride.screenWidthDp != taskConfig.screenWidthDp) {
+ taskChanges |= ActivityInfo.CONFIG_SCREEN_SIZE;
}
- if (oldStackOverride.smallestScreenWidthDp != mOverrideConfig.smallestScreenWidthDp) {
- stackChanges |= ActivityInfo.CONFIG_SMALLEST_SCREEN_SIZE;
+ if (oldTaskOverride.smallestScreenWidthDp != taskConfig.smallestScreenWidthDp) {
+ taskChanges |= ActivityInfo.CONFIG_SMALLEST_SCREEN_SIZE;
}
}
- final int changes = oldConfig.diff(newConfig) | stackChanges;
+ final int changes = oldConfig.diff(newConfig) | taskChanges;
if (changes == 0 && !r.forceNewConfig) {
if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
"Configuration no differences in " + r);
@@ -3943,14 +3972,14 @@
}
// Default case: the activity can handle this new configuration, so hand it over.
- // NOTE: We only forward the stack override configuration as the system level configuration
+ // NOTE: We only forward the task override configuration as the system level configuration
// changes is always sent to all processes when they happen so it can just use whatever
// system level configuration it last got.
if (r.app != null && r.app.thread != null) {
try {
if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending new config to " + r);
r.app.thread.scheduleActivityConfigurationChanged(
- r.appToken, new Configuration(mOverrideConfig));
+ r.appToken, new Configuration(taskConfig));
} catch (RemoteException e) {
// If process died, whatever.
}
@@ -3984,7 +4013,7 @@
r.forceNewConfig = false;
r.app.thread.scheduleRelaunchActivity(r.appToken, results, newIntents, changes,
!andResume, new Configuration(mService.mConfiguration),
- new Configuration(mOverrideConfig));
+ new Configuration(r.task.mOverrideConfig));
// Note: don't need to call pauseIfSleepingLocked() here, because
// the caller will only pass in 'andResume' if this activity is
// currently resumed, which implies we aren't sleeping.
@@ -4371,6 +4400,41 @@
}
}
+ void positionTask(final TaskRecord task, int position, boolean moving) {
+ task.stack = this;
+ insertTaskAtPosition(task, position);
+ if (!moving && task.voiceSession != null) {
+ try {
+ task.voiceSession.taskStarted(task.intent, task.taskId);
+ } catch (RemoteException e) {
+ }
+ }
+ }
+
+ void addAppToken(ActivityRecord r, TaskRecord task) {
+ final Rect bounds = task.getLaunchBounds();
+ final Configuration config =
+ mWindowManager.addAppToken(task.mActivities.indexOf(r), r.appToken,
+ r.task.taskId, mStackId, r.info.screenOrientation, r.fullscreen,
+ (r.info.flags & ActivityInfo.FLAG_SHOW_FOR_ALL_USERS) != 0, r.userId,
+ r.info.configChanges, task.voiceSession != null, r.mLaunchTaskBehind,
+ bounds);
+ if (config != null) {
+ task.updateOverrideConfiguration(config, bounds);
+ }
+ r.taskConfigOverride = task.mOverrideConfig;
+ }
+
+ private void setAppTask(ActivityRecord r, TaskRecord task) {
+ final Rect bounds = task.getLaunchBounds();
+ final Configuration config =
+ mWindowManager.setAppTask(r.appToken, task.taskId, task.getLaunchBounds());
+ if (config != null) {
+ task.updateOverrideConfiguration(config, bounds);
+ }
+ r.taskConfigOverride = task.mOverrideConfig;
+ }
+
public int getStackId() {
return mStackId;
}
@@ -4381,16 +4445,6 @@
+ " stackId=" + mStackId + ", " + mTaskHistory.size() + " tasks}";
}
- boolean updateOverrideConfiguration(Configuration newConfig) {
- Configuration oldConfig = mOverrideConfig;
- mOverrideConfig = (newConfig == null) ? Configuration.EMPTY : newConfig;
- // We override the configuration only when the stack's dimensions are different from
- // the display. In this manner, we know that if the override configuration is empty,
- // the stack is necessarily full screen.
- mFullscreen = Configuration.EMPTY.equals(mOverrideConfig);
- return !mOverrideConfig.equals(oldConfig);
- }
-
void onLockTaskPackagesUpdatedLocked() {
for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
mTaskHistory.get(taskNdx).setLockTaskAuth();
diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
index b1ac7ee..4a0fd89 100644
--- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
@@ -17,9 +17,7 @@
package com.android.server.am;
import static android.Manifest.permission.START_ANY_ACTIVITY;
-import static android.app.ActivityManager.LOCK_TASK_MODE_LOCKED;
-import static android.app.ActivityManager.LOCK_TASK_MODE_NONE;
-import static android.app.ActivityManager.LOCK_TASK_MODE_PINNED;
+import static android.app.ActivityManager.*;
import static android.content.Intent.FLAG_ACTIVITY_CLEAR_TASK;
import static android.content.Intent.FLAG_ACTIVITY_CLEAR_TOP;
import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
@@ -99,6 +97,7 @@
import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.EventLog;
+import android.util.IntArray;
import android.util.Slog;
import android.util.SparseArray;
@@ -145,8 +144,6 @@
private static final String TAG_VISIBLE_BEHIND = TAG + POSTFIX_VISIBLE_BEHIND;
private static final String TAG_USER_LEAVING = TAG + POSTFIX_USER_LEAVING;
- public static final int HOME_STACK_ID = 0;
-
/** How long we wait until giving up on the last activity telling us it is idle. */
static final int IDLE_TIMEOUT = 10 * 1000;
@@ -213,8 +210,8 @@
WindowManagerService mWindowManager;
DisplayManager mDisplayManager;
- /** Identifier counter for all ActivityStacks */
- private int mLastStackId = HOME_STACK_ID;
+ /** Counter for next free stack ID to use for dynamic activity stacks. */
+ private int mNextFreeStackId = FIRST_DYNAMIC_STACK_ID;
/** Task identifier that activities are currently being started in. Incremented each time a
* new task is created. */
@@ -401,7 +398,7 @@
mActivityDisplays.put(displayId, activityDisplay);
}
- createStackOnDisplay(HOME_STACK_ID, Display.DEFAULT_DISPLAY);
+ createStackOnDisplay(HOME_STACK_ID, Display.DEFAULT_DISPLAY, true);
mHomeStack = mFocusedStack = mLastFocusedStack = getStack(HOME_STACK_ID);
mInputManagerInternal = LocalServices.getService(InputManagerInternal.class);
@@ -1283,7 +1280,7 @@
app.forceProcessStateUpTo(mService.mTopProcessState);
app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,
System.identityHashCode(r), r.info, new Configuration(mService.mConfiguration),
- new Configuration(stack.mOverrideConfig), r.compat, r.launchedFromPackage,
+ new Configuration(task.mOverrideConfig), r.compat, r.launchedFromPackage,
task.voiceInteractor, app.repProcState, r.icicle, r.persistentState, results,
newIntents, !andResume, mService.isNextTransitionForward(), profilerInfo);
@@ -1506,6 +1503,7 @@
if ((launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) == 0
&& sourceRecord.info.applicationInfo.uid != aInfo.applicationInfo.uid) {
try {
+ intent.addCategory(Intent.CATEGORY_VOICE);
if (!AppGlobals.getPackageManager().activitySupportsIntent(
intent.getComponent(), intent, resolvedType)) {
err = ActivityManager.START_NOT_VOICE_COMPATIBLE;
@@ -1626,7 +1624,7 @@
ActivityRecord r = new ActivityRecord(mService, callerApp, callingUid, callingPackage,
intent, resolvedType, aInfo, mService.mConfiguration, resultRecord, resultWho,
- requestCode, componentSpecified, this, container, options);
+ requestCode, componentSpecified, voiceSession != null, this, container, options);
if (outActivity != null) {
outActivity[0] = r;
}
@@ -1783,18 +1781,24 @@
return mFocusedStack;
}
+ // We first try to put the task in the first dynamic stack.
final ArrayList<ActivityStack> homeDisplayStacks = mHomeStack.mStacks;
for (int stackNdx = homeDisplayStacks.size() - 1; stackNdx >= 0; --stackNdx) {
stack = homeDisplayStacks.get(stackNdx);
- if (!stack.isHomeStack()) {
+ final boolean isDynamicStack = stack.mStackId >= FIRST_DYNAMIC_STACK_ID;
+ if (isDynamicStack) {
if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG_FOCUS,
"computeStackFocus: Setting focused stack=" + stack);
return stack;
}
}
- // Need to create an app stack for this user.
- stack = createStackOnDisplay(getNextStackId(), Display.DEFAULT_DISPLAY);
+ // If there is no suitable dynamic stack then we figure out which static stack to use.
+ stack = getStack(
+ task != null
+ ? task.getLaunchStackId(mFocusedStack) : FULLSCREEN_WORKSPACE_STACK_ID,
+ true /*createStaticStackIfNeeded*/,
+ true /*createOnTop*/);
if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG_FOCUS, "computeStackFocus: New stack r="
+ r + " stackId=" + stack.mStackId);
return stack;
@@ -1812,7 +1816,7 @@
Slog.w(TAG, "Can't set focus stack for r=" + r + " task=" + task);
return false;
}
- task.stack.moveToFront(reason);
+ task.stack.moveToFront(reason, task);
return true;
}
@@ -2781,11 +2785,19 @@
}
ActivityStack getStack(int stackId) {
+ return getStack(stackId, false /*createStaticStackIfNeeded*/, false /*createOnTop*/);
+ }
+
+ ActivityStack getStack(int stackId, boolean createStaticStackIfNeeded, boolean createOnTop) {
ActivityContainer activityContainer = mActivityContainers.get(stackId);
if (activityContainer != null) {
return activityContainer.mStack;
}
- return null;
+ if (!createStaticStackIfNeeded
+ || (stackId < FIRST_STATIC_STACK_ID || stackId > LAST_STATIC_STACK_ID)) {
+ return null;
+ }
+ return createStackOnDisplay(stackId, Display.DEFAULT_DISPLAY, createOnTop);
}
ArrayList<ActivityStack> getStacks() {
@@ -2871,9 +2883,58 @@
return;
}
- final Configuration overrideConfig = mWindowManager.resizeStack(stackId, bounds);
- if (stack.updateOverrideConfiguration(overrideConfig)) {
+ final IntArray changedTaskIds = new IntArray(stack.numTasks());
+ final List<Configuration> newTaskConfigs = new ArrayList<>(stack.numTasks());
+ stack.mFullscreen =
+ mWindowManager.resizeStack(stackId, bounds, changedTaskIds, newTaskConfigs);
+ for (int i = changedTaskIds.size() - 1; i >= 0; i--) {
+ final TaskRecord task = anyTaskForIdLocked(changedTaskIds.get(i), false);
+ if (task == null) {
+ Slog.wtf(TAG, "Task in WindowManager, but not in ActivityManager???");
+ continue;
+ }
+ task.updateOverrideConfiguration(newTaskConfigs.get(i), bounds);
+ }
+
+ if (r != null) {
+ final boolean updated = stack.ensureActivityConfigurationLocked(r, 0);
+ // And we need to make sure at this point that all other activities
+ // are made visible with the correct configuration.
+ ensureActivitiesVisibleLocked(r, 0);
+ if (!updated) {
+ resumeTopActivitiesLocked(stack, null, null);
+ }
+ }
+ }
+
+ void resizeTaskLocked(TaskRecord task, Rect bounds) {
+ if (!task.mResizeable) {
+ Slog.w(TAG, "resizeTask: task " + task + " not resizeable.");
+ return;
+ }
+
+ if (task.mBounds != null && task.mBounds.equals(bounds)) {
+ // Nothing to do here...
+ return;
+ }
+
+ if (!mWindowManager.isValidTaskId(task.taskId)) {
+ // Task doesn't exist in window manager yet (e.g. was restored from recents).
+ // All we can do for now is update the bounds so it can be used when the task is
+ // added to window manager.
+ task.mBounds = task.mLastNonFullscreenBounds = new Rect(bounds);
+ if (task.stack != null && task.stack.mStackId != FREEFORM_WORKSPACE_STACK_ID) {
+ // re-restore the task so it can have the proper stack association.
+ restoreRecentTaskLocked(task);
+ }
+ return;
+ }
+
+ final Configuration overrideConfig = mWindowManager.resizeTask(task.taskId, bounds);
+ if (task.updateOverrideConfiguration(overrideConfig, bounds)) {
+ ActivityRecord r = task.topRunningActivityLocked(null);
if (r != null) {
+ final ActivityStack stack = task.stack;
final boolean updated = stack.ensureActivityConfigurationLocked(r, 0);
// And we need to make sure at this point that all other activities
// are made visible with the correct configuration.
@@ -2885,49 +2946,7 @@
}
}
- /** Makes sure the input task is in a stack with the specified bounds by either resizing the
- * current task stack if it only has one entry, moving the task to a stack that matches the
- * bounds, or creating a new stack with the required bounds. Also, makes the task resizeable.*/
- void resizeTaskLocked(TaskRecord task, Rect bounds) {
- task.mResizeable = true;
- final ActivityStack currentStack = task.stack;
- if (currentStack.isHomeStack()) {
- // Can't move task off the home stack. Sorry!
- return;
- }
-
- final int matchingStackId = mWindowManager.getStackIdWithBounds(bounds);
- if (matchingStackId != -1) {
- // There is already a stack with the right bounds!
- if (currentStack != null && currentStack.mStackId == matchingStackId) {
- // Nothing to do here. Already in the right stack...
- return;
- }
- // Move task to stack with matching bounds.
- moveTaskToStackLocked(task.taskId, matchingStackId, true);
- return;
- }
-
- if (currentStack != null && currentStack.numTasks() == 1) {
- // Just resize the current stack since this is the task in it.
- resizeStackLocked(currentStack.mStackId, bounds);
- return;
- }
-
- // Create new stack and move the task to it.
- final int displayId = (currentStack != null && currentStack.mDisplayId != -1)
- ? currentStack.mDisplayId : Display.DEFAULT_DISPLAY;
- ActivityStack newStack = createStackOnDisplay(getNextStackId(), displayId);
-
- if (newStack == null) {
- Slog.e(TAG, "resizeTaskLocked: Can't create stack for task=" + task);
- return;
- }
- moveTaskToStackLocked(task.taskId, newStack.mStackId, true);
- resizeStackLocked(newStack.mStackId, bounds);
- }
-
- ActivityStack createStackOnDisplay(int stackId, int displayId) {
+ ActivityStack createStackOnDisplay(int stackId, int displayId, boolean onTop) {
ActivityDisplay activityDisplay = mActivityDisplays.get(displayId);
if (activityDisplay == null) {
return null;
@@ -2935,50 +2954,37 @@
ActivityContainer activityContainer = new ActivityContainer(stackId);
mActivityContainers.put(stackId, activityContainer);
- activityContainer.attachToDisplayLocked(activityDisplay);
+ activityContainer.attachToDisplayLocked(activityDisplay, onTop);
return activityContainer.mStack;
}
int getNextStackId() {
while (true) {
- if (++mLastStackId <= HOME_STACK_ID) {
- mLastStackId = HOME_STACK_ID + 1;
- }
- if (getStack(mLastStackId) == null) {
+ if (mNextFreeStackId >= FIRST_DYNAMIC_STACK_ID
+ && getStack(mNextFreeStackId) == null) {
break;
}
+ mNextFreeStackId++;
}
- return mLastStackId;
+ return mNextFreeStackId;
}
private boolean restoreRecentTaskLocked(TaskRecord task) {
- ActivityStack stack = null;
- // Determine stack to restore task to.
- if (mLeanbackOnlyDevice) {
- // There is only one stack for lean back devices.
- stack = mHomeStack;
- } else {
- // Look for the top stack on the home display that isn't the home stack.
- final ArrayList<ActivityStack> homeDisplayStacks = mHomeStack.mStacks;
- for (int stackNdx = homeDisplayStacks.size() - 1; stackNdx >= 0; --stackNdx) {
- final ActivityStack tmpStack = homeDisplayStacks.get(stackNdx);
- if (!tmpStack.isHomeStack() && tmpStack.mFullscreen) {
- stack = tmpStack;
- break;
- }
+ final int stackId =
+ mLeanbackOnlyDevice ? mHomeStack.mStackId : task.getLaunchStackId(mFocusedStack);
+ if (task.stack != null) {
+ // Task has already been restored once. See if we need to do anything more
+ if (task.stack.mStackId == stackId) {
+ // Nothing else to do since it is already restored in the right stack.
+ return true;
}
+ // Remove current stack association, so we can re-associate the task with the
+ // right stack below.
+ task.stack.removeTask(task, "restoreRecentTaskLocked", false /*notMoving*/);
}
- if (stack == null) {
- // We couldn't find a stack to restore the task to. Possible if are restoring recents
- // before an application stack is created...Go ahead and create one on the default
- // display.
- stack = createStackOnDisplay(getNextStackId(), Display.DEFAULT_DISPLAY);
- // Restore home stack to top.
- moveHomeStack(true, "restoreRecentTask");
- if (DEBUG_RECENTS) Slog.v(TAG_RECENTS,
- "Created stack=" + stack + " for recents restoration.");
- }
+ ActivityStack stack =
+ getStack(stackId, true /*createStaticStackIfNeeded*/, false /*createOnTop*/);
if (stack == null) {
// What does this mean??? Not sure how we would get here...
@@ -2992,12 +2998,7 @@
"Added restored task=" + task + " to stack=" + stack);
final ArrayList<ActivityRecord> activities = task.mActivities;
for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
- final ActivityRecord r = activities.get(activityNdx);
- mWindowManager.addAppToken(0, r.appToken, task.taskId, stack.mStackId,
- r.info.screenOrientation, r.fullscreen,
- (r.info.flags & ActivityInfo.FLAG_SHOW_FOR_ALL_USERS) != 0,
- r.userId, r.info.configChanges, task.voiceSession != null,
- r.mLaunchTaskBehind);
+ stack.addAppToken(activities.get(activityNdx), task);
}
return true;
}
@@ -3008,16 +3009,42 @@
Slog.w(TAG, "moveTaskToStack: no task for id=" + taskId);
return;
}
- final ActivityStack stack = getStack(stackId);
- if (stack == null) {
- Slog.w(TAG, "moveTaskToStack: no stack for id=" + stackId);
- return;
- }
+ ActivityStack stack =
+ getStack(stackId, true /*createStaticStackIfNeeded*/, toTop /*createOnTop*/);
mWindowManager.moveTaskToStack(taskId, stackId, toTop);
if (task.stack != null) {
task.stack.removeTask(task, "moveTaskToStack", false /* notMoving */);
}
stack.addTask(task, toTop, true);
+
+ // Make sure the task has the appropriate bounds/size for the stack it is in.
+ if (stackId == FULLSCREEN_WORKSPACE_STACK_ID && task.mBounds != null) {
+ resizeTaskLocked(task, null);
+ } else if (stackId == FREEFORM_WORKSPACE_STACK_ID
+ && task.mBounds == null && task.mLastNonFullscreenBounds != null) {
+ resizeTaskLocked(task, task.mLastNonFullscreenBounds);
+ }
+
+ // The task might have already been running and its visibility needs to be synchronized with
+ // the visibility of the stack / windows.
+ stack.ensureActivitiesVisibleLocked(null, 0);
+ resumeTopActivitiesLocked();
+ }
+
+ void positionTaskInStackLocked(int taskId, int stackId, int position) {
+ final TaskRecord task = anyTaskForIdLocked(taskId);
+ if (task == null) {
+ Slog.w(TAG, "positionTaskInStackLocked: no task for id=" + taskId);
+ return;
+ }
+ ActivityStack stack =
+ getStack(stackId, true /*createStaticStackIfNeeded*/, false /*createOnTop*/);
+ mWindowManager.positionTaskInStack(taskId, stackId, position);
+ final boolean stackChanged = task.stack != null && task.stack != stack;
+ if (stackChanged) {
+ task.stack.removeTask(task, "moveTaskToStack", false /* notMoving */);
+ }
+ stack.positionTask(task, position, stackChanged);
// The task might have already been running and its visibility needs to be synchronized with
// the visibility of the stack / windows.
stack.ensureActivitiesVisibleLocked(null, 0);
@@ -3721,19 +3748,19 @@
@Override
public void onDisplayAdded(int displayId) {
- Slog.v(TAG, "Display added displayId=" + displayId);
+ if (DEBUG_STACK) Slog.v(TAG, "Display added displayId=" + displayId);
mHandler.sendMessage(mHandler.obtainMessage(HANDLE_DISPLAY_ADDED, displayId, 0));
}
@Override
public void onDisplayRemoved(int displayId) {
- Slog.v(TAG, "Display removed displayId=" + displayId);
+ if (DEBUG_STACK) Slog.v(TAG, "Display removed displayId=" + displayId);
mHandler.sendMessage(mHandler.obtainMessage(HANDLE_DISPLAY_REMOVED, displayId, 0));
}
@Override
public void onDisplayChanged(int displayId) {
- Slog.v(TAG, "Display changed displayId=" + displayId);
+ if (DEBUG_STACK) Slog.v(TAG, "Display changed displayId=" + displayId);
mHandler.sendMessage(mHandler.obtainMessage(HANDLE_DISPLAY_CHANGED, displayId, 0));
}
@@ -3789,6 +3816,7 @@
final int numTasks = tasks.size();
int[] taskIds = new int[numTasks];
String[] taskNames = new String[numTasks];
+ Rect[] taskBounds = new Rect[numTasks];
for (int i = 0; i < numTasks; ++i) {
final TaskRecord task = tasks.get(i);
taskIds[i] = task.taskId;
@@ -3796,9 +3824,12 @@
: task.realActivity != null ? task.realActivity.flattenToString()
: task.getTopActivity() != null ? task.getTopActivity().packageName
: "unknown";
+ taskBounds[i] = new Rect();
+ mWindowManager.getTaskBounds(task.taskId, taskBounds[i]);
}
info.taskIds = taskIds;
info.taskNames = taskNames;
+ info.taskBounds = taskBounds;
return info;
}
@@ -3811,7 +3842,7 @@
}
ArrayList<StackInfo> getAllStackInfosLocked() {
- ArrayList<StackInfo> list = new ArrayList<StackInfo>();
+ ArrayList<StackInfo> list = new ArrayList<>();
for (int displayNdx = 0; displayNdx < mActivityDisplays.size(); ++displayNdx) {
ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
for (int ndx = stacks.size() - 1; ndx >= 0; --ndx) {
@@ -4197,15 +4228,15 @@
}
}
- void attachToDisplayLocked(ActivityDisplay activityDisplay) {
+ void attachToDisplayLocked(ActivityDisplay activityDisplay, boolean onTop) {
if (DEBUG_STACK) Slog.d(TAG_STACK, "attachToDisplayLocked: " + this
- + " to display=" + activityDisplay);
+ + " to display=" + activityDisplay + " onTop=" + onTop);
mActivityDisplay = activityDisplay;
mStack.mDisplayId = activityDisplay.mDisplayId;
mStack.mStacks = activityDisplay.mStacks;
- activityDisplay.attachActivities(mStack);
- mWindowManager.attachStack(mStackId, activityDisplay.mDisplayId);
+ activityDisplay.attachActivities(mStack, onTop);
+ mWindowManager.attachStack(mStackId, activityDisplay.mDisplayId, onTop);
}
@Override
@@ -4215,7 +4246,7 @@
if (activityDisplay == null) {
return;
}
- attachToDisplayLocked(activityDisplay);
+ attachToDisplayLocked(activityDisplay, true);
}
}
@@ -4428,7 +4459,7 @@
new VirtualActivityDisplay(width, height, density);
mActivityDisplay = virtualActivityDisplay;
mActivityDisplays.put(virtualActivityDisplay.mDisplayId, virtualActivityDisplay);
- attachToDisplayLocked(virtualActivityDisplay);
+ attachToDisplayLocked(virtualActivityDisplay, true);
}
if (mSurface != null) {
@@ -4514,10 +4545,15 @@
mDisplay.getDisplayInfo(mDisplayInfo);
}
- void attachActivities(ActivityStack stack) {
+ void attachActivities(ActivityStack stack, boolean onTop) {
if (DEBUG_STACK) Slog.v(TAG_STACK,
- "attachActivities: attaching " + stack + " to displayId=" + mDisplayId);
- mStacks.add(stack);
+ "attachActivities: attaching " + stack + " to displayId=" + mDisplayId
+ + " onTop=" + onTop);
+ if (onTop) {
+ mStacks.add(stack);
+ } else {
+ mStacks.add(0, stack);
+ }
}
void detachActivitiesLocked(ActivityStack stack) {
diff --git a/services/core/java/com/android/server/am/BroadcastRecord.java b/services/core/java/com/android/server/am/BroadcastRecord.java
index a7e6471..1fbfd9f 100644
--- a/services/core/java/com/android/server/am/BroadcastRecord.java
+++ b/services/core/java/com/android/server/am/BroadcastRecord.java
@@ -240,8 +240,12 @@
}
didSomething = true;
receivers.remove(i);
+ if (i < nextReceiver) {
+ nextReceiver--;
+ }
}
}
+ nextReceiver = Math.min(nextReceiver, receivers.size());
return didSomething;
}
diff --git a/services/core/java/com/android/server/am/RecentTasks.java b/services/core/java/com/android/server/am/RecentTasks.java
index 6ee1650..b216114 100644
--- a/services/core/java/com/android/server/am/RecentTasks.java
+++ b/services/core/java/com/android/server/am/RecentTasks.java
@@ -435,7 +435,8 @@
*/
int trimForTaskLocked(TaskRecord task, boolean doTrim) {
int recentsCount = size();
- final boolean document = task.intent != null && task.intent.isDocument();
+ final Intent intent = task.intent;
+ final boolean document = intent != null && intent.isDocument();
int maxRecents = task.maxRecents - 1;
for (int i = 0; i < recentsCount; i++) {
final TaskRecord tr = get(i);
@@ -446,12 +447,13 @@
if (i > MAX_RECENT_BITMAPS) {
tr.freeLastThumbnail();
}
+ final Intent trIntent = tr.intent;
final boolean sameAffinity =
task.affinity != null && task.affinity.equals(tr.affinity);
- final boolean trIsDocument = tr.intent != null && tr.intent.isDocument();
+ final boolean sameIntent = (intent != null && intent.filterEquals(trIntent));
+ final boolean trIsDocument = trIntent != null && trIntent.isDocument();
final boolean bothDocuments = document && trIsDocument;
- if (!sameAffinity && !bothDocuments) {
- // Not the same affinity and not documents. Move along...
+ if (!sameAffinity && !sameIntent && !bothDocuments) {
continue;
}
diff --git a/services/core/java/com/android/server/am/TaskRecord.java b/services/core/java/com/android/server/am/TaskRecord.java
index 7e2ad29..20117c3 100644
--- a/services/core/java/com/android/server/am/TaskRecord.java
+++ b/services/core/java/com/android/server/am/TaskRecord.java
@@ -16,6 +16,9 @@
package com.android.server.am;
+import static android.app.ActivityManager.FREEFORM_WORKSPACE_STACK_ID;
+import static android.app.ActivityManager.FULLSCREEN_WORKSPACE_STACK_ID;
+import static android.app.ActivityManager.HOME_STACK_ID;
import static android.content.Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
import static android.content.Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS;
import static android.content.pm.ActivityInfo.LOCK_TASK_LAUNCH_MODE_ALWAYS;
@@ -40,7 +43,9 @@
import android.content.pm.ApplicationInfo;
import android.content.pm.IPackageManager;
import android.content.pm.PackageManager;
+import android.content.res.Configuration;
import android.graphics.Bitmap;
+import android.graphics.Rect;
import android.os.Debug;
import android.os.ParcelFileDescriptor;
import android.os.RemoteException;
@@ -92,6 +97,7 @@
private static final String ATTR_CALLING_PACKAGE = "calling_package";
private static final String ATTR_RESIZEABLE = "resizeable";
private static final String ATTR_PRIVILEGED = "privileged";
+ private static final String ATTR_NON_FULLSCREEN_BOUNDS = "non_fullscreen_bounds";
private static final String TASK_THUMBNAIL_SUFFIX = "_task_thumbnail";
@@ -199,6 +205,18 @@
final ActivityManagerService mService;
+ // Whether or not this task covers the entire screen; by default tasks are fullscreen.
+ boolean mFullscreen = true;
+
+ // Bounds of the Task. null for fullscreen tasks.
+ Rect mBounds = null;
+ // Last non-fullscreen bounds the task was launched in or resized to.
+ // The information is persisted and used to determine the appropriate stack to launch the
+ // task into on restore.
+ Rect mLastNonFullscreenBounds = null;
+
+ Configuration mOverrideConfig = Configuration.EMPTY;
+
TaskRecord(ActivityManagerService service, int _taskId, ActivityInfo info, Intent _intent,
IVoiceInteractionSession _voiceSession, IVoiceInteractor _voiceInteractor) {
mService = service;
@@ -252,7 +270,8 @@
long _firstActiveTime, long _lastActiveTime, long lastTimeMoved,
boolean neverRelinquishIdentity, TaskDescription _lastTaskDescription,
int taskAffiliation, int prevTaskId, int nextTaskId, int taskAffiliationColor,
- int callingUid, String callingPackage, boolean resizeable, boolean privileged) {
+ int callingUid, String callingPackage, boolean resizeable, boolean privileged,
+ Rect bounds) {
mService = service;
mFilename = String.valueOf(_taskId) + TASK_THUMBNAIL_SUFFIX +
TaskPersister.IMAGE_EXTENSION;
@@ -289,6 +308,7 @@
mCallingPackage = callingPackage;
mResizeable = resizeable;
mPrivileged = privileged;
+ mBounds = mLastNonFullscreenBounds = bounds;
}
void touchActiveTime() {
@@ -950,6 +970,10 @@
out.attribute(null, ATTR_CALLING_PACKAGE, mCallingPackage == null ? "" : mCallingPackage);
out.attribute(null, ATTR_RESIZEABLE, String.valueOf(mResizeable));
out.attribute(null, ATTR_PRIVILEGED, String.valueOf(mPrivileged));
+ if (mLastNonFullscreenBounds != null) {
+ out.attribute(
+ null, ATTR_NON_FULLSCREEN_BOUNDS, mLastNonFullscreenBounds.flattenToString());
+ }
if (affinityIntent != null) {
out.startTag(null, TAG_AFFINITYINTENT);
@@ -1010,6 +1034,7 @@
String callingPackage = "";
boolean resizeable = false;
boolean privileged = false;
+ Rect bounds = null;
for (int attrNdx = in.getAttributeCount() - 1; attrNdx >= 0; --attrNdx) {
final String attrName = in.getAttributeName(attrNdx);
@@ -1067,6 +1092,8 @@
resizeable = Boolean.valueOf(attrValue);
} else if (ATTR_PRIVILEGED.equals(attrName)) {
privileged = Boolean.valueOf(attrValue);
+ } else if (ATTR_NON_FULLSCREEN_BOUNDS.equals(attrName)) {
+ bounds = Rect.unflattenFromString(attrValue);
} else {
Slog.w(TAG, "TaskRecord: Unknown attribute=" + attrName);
}
@@ -1126,7 +1153,7 @@
autoRemoveRecents, askedCompatMode, taskType, userId, effectiveUid, lastDescription,
activities, firstActiveTime, lastActiveTime, lastTimeOnTop, neverRelinquishIdentity,
taskDescription, taskAffiliation, prevTaskId, nextTaskId, taskAffiliationColor,
- callingUid, callingPackage, resizeable, privileged);
+ callingUid, callingPackage, resizeable, privileged, bounds);
for (int activityNdx = activities.size() - 1; activityNdx >=0; --activityNdx) {
activities.get(activityNdx).task = task;
@@ -1136,6 +1163,53 @@
return task;
}
+ boolean updateOverrideConfiguration(Configuration newConfig, Rect bounds) {
+ Configuration oldConfig = mOverrideConfig;
+ mOverrideConfig = (newConfig == null) ? Configuration.EMPTY : newConfig;
+ // We override the configuration only when the task's dimensions are different from the
+ // display. In this manner, we know that if the override configuration is empty, the task
+ // is necessarily fullscreen.
+ mFullscreen = Configuration.EMPTY.equals(mOverrideConfig);
+ if (mFullscreen) {
+ if (mBounds != null) {
+ mLastNonFullscreenBounds = mBounds;
+ }
+ mBounds = null;
+ } else {
+ mBounds = mLastNonFullscreenBounds = new Rect(bounds);
+ }
+ return !mOverrideConfig.equals(oldConfig);
+ }
+
+ /** Returns the stack that should be used to launch this task. */
+ int getLaunchStackId(ActivityStack focusStack) {
+ if (stack != null) {
+ // We are already in a stack silly...
+ return stack.mStackId;
+ }
+ if (isHomeTask()) {
+ return HOME_STACK_ID;
+ }
+ if (focusStack != null && focusStack.mStackId != HOME_STACK_ID) {
+ // Like it or not you are going in the focused stack!
+ return focusStack.mStackId;
+ }
+ if (mBounds != null || mLastNonFullscreenBounds != null) {
+ return FREEFORM_WORKSPACE_STACK_ID;
+ }
+ return FULLSCREEN_WORKSPACE_STACK_ID;
+ }
+
+ /** Returns the bounds that should be used to launch this task. */
+ Rect getLaunchBounds() {
+ if (stack == null
+ || stack.mStackId == HOME_STACK_ID
+ || stack.mStackId == FULLSCREEN_WORKSPACE_STACK_ID) {
+ return null;
+ }
+ return mLastNonFullscreenBounds;
+ }
+
void dump(PrintWriter pw, String prefix) {
pw.print(prefix); pw.print("userId="); pw.print(userId);
pw.print(" effectiveUid="); UserHandle.formatUid(pw, effectiveUid);
diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java
index 95cbf10..a8c8dce 100644
--- a/services/core/java/com/android/server/audio/AudioService.java
+++ b/services/core/java/com/android/server/audio/AudioService.java
@@ -1257,7 +1257,11 @@
}
for (int stream = 0; stream < mStreamStates.length; stream++) {
if (streamTypeAlias == mStreamVolumeAlias[stream]) {
- mStreamStates[stream].mute(state);
+ if (!(readCameraSoundForced()
+ && (mStreamStates[stream].getStreamType()
+ == AudioSystem.STREAM_SYSTEM_ENFORCED))) {
+ mStreamStates[stream].mute(state);
+ }
}
}
} else if ((direction == AudioManager.ADJUST_RAISE) &&
@@ -4723,13 +4727,19 @@
Slog.i(TAG, "deviceSpec:" + deviceSpec + " is(already)Connected:" + isConnected);
}
if (connect && !isConnected) {
- AudioSystem.setDeviceConnectionState(device, AudioSystem.DEVICE_STATE_AVAILABLE,
- address, deviceName);
+ final int res = AudioSystem.setDeviceConnectionState(device,
+ AudioSystem.DEVICE_STATE_AVAILABLE, address, deviceName);
+ if (res != AudioSystem.AUDIO_STATUS_OK) {
+ Slog.e(TAG, "not connecting device 0x" + Integer.toHexString(device) +
+ " due to command error " + res );
+ return false;
+ }
mConnectedDevices.put(deviceKey, new DeviceListSpec(device, deviceName, address));
return true;
} else if (!connect && isConnected) {
- AudioSystem.setDeviceConnectionState(device, AudioSystem.DEVICE_STATE_UNAVAILABLE,
- address, deviceName);
+ AudioSystem.setDeviceConnectionState(device,
+ AudioSystem.DEVICE_STATE_UNAVAILABLE, address, deviceName);
+ // always remove even if disconnection failed
mConnectedDevices.remove(deviceKey);
return true;
}
@@ -4862,7 +4872,10 @@
boolean isUsb = ((device & ~AudioSystem.DEVICE_OUT_ALL_USB) == 0) ||
(((device & AudioSystem.DEVICE_BIT_IN) != 0) &&
((device & ~AudioSystem.DEVICE_IN_ALL_USB) == 0));
- handleDeviceConnection(state == 1, device, address, deviceName);
+ if (!handleDeviceConnection(state == 1, device, address, deviceName)) {
+ // change of connection state failed, bailout
+ return;
+ }
if (state != 0) {
if ((device == AudioSystem.DEVICE_OUT_WIRED_HEADSET) ||
(device == AudioSystem.DEVICE_OUT_WIRED_HEADPHONE) ||
diff --git a/services/core/java/com/android/server/content/SyncManager.java b/services/core/java/com/android/server/content/SyncManager.java
index 658f6f8..c998c2c 100644
--- a/services/core/java/com/android/server/content/SyncManager.java
+++ b/services/core/java/com/android/server/content/SyncManager.java
@@ -297,7 +297,6 @@
private final UserManager mUserManager;
private static final long SYNC_ALARM_TIMEOUT_MIN = 30 * 1000; // 30 seconds
- private static final long SYNC_ALARM_TIMEOUT_MAX = 2 * 60 * 60 * 1000; // two hours
private List<UserInfo> getAllUsers() {
return mUserManager.getUsers();
@@ -1478,9 +1477,9 @@
final long now = SystemClock.elapsedRealtime();
pw.print("now: "); pw.print(now);
pw.println(" (" + formatTime(System.currentTimeMillis()) + ")");
- pw.print("offset: "); pw.print(DateUtils.formatElapsedTime(mSyncRandomOffsetMillis/1000));
+ pw.print("offset: "); pw.print(DateUtils.formatElapsedTime(mSyncRandomOffsetMillis / 1000));
pw.println(" (HH:MM:SS)");
- pw.print("uptime: "); pw.print(DateUtils.formatElapsedTime(now/1000));
+ pw.print("uptime: "); pw.print(DateUtils.formatElapsedTime(now / 1000));
pw.println(" (HH:MM:SS)");
pw.print("time spent syncing: ");
pw.print(DateUtils.formatElapsedTime(
@@ -1497,11 +1496,6 @@
pw.println("no alarm is scheduled (there had better not be any pending syncs)");
}
- pw.print("notification info: ");
- final StringBuilder sb = new StringBuilder();
- mSyncHandler.mSyncNotificationInfo.toString(sb);
- pw.println(sb.toString());
-
pw.println();
pw.println("Active Syncs: " + mActiveSyncContexts.size());
final PackageManager pm = mContext.getPackageManager();
@@ -1514,8 +1508,8 @@
pw.println();
}
+ final StringBuilder sb = new StringBuilder();
synchronized (mSyncQueue) {
- sb.setLength(0);
mSyncQueue.dump(sb);
// Dump Pending Operations.
getSyncStorageEngine().dumpPendingOperations(sb);
@@ -2349,7 +2343,6 @@
}
} finally {
- manageSyncNotificationLocked();
manageSyncAlarmLocked(earliestFuturePollTime, nextPendingSyncTime);
mSyncTimeTracker.update();
mSyncManagerWakeLock.release();
@@ -3169,67 +3162,6 @@
throw new IllegalStateException("we are not in an error state, " + syncResult);
}
- private void manageSyncNotificationLocked() {
- boolean shouldCancel;
- boolean shouldInstall;
-
- if (mActiveSyncContexts.isEmpty()) {
- mSyncNotificationInfo.startTime = null;
-
- // we aren't syncing. if the notification is active then remember that we need
- // to cancel it and then clear out the info
- shouldCancel = mSyncNotificationInfo.isActive;
- shouldInstall = false;
- } else {
- // we are syncing
- final long now = SystemClock.elapsedRealtime();
- if (mSyncNotificationInfo.startTime == null) {
- mSyncNotificationInfo.startTime = now;
- }
-
- // there are three cases:
- // - the notification is up: do nothing
- // - the notification is not up but it isn't time yet: don't install
- // - the notification is not up and it is time: need to install
-
- if (mSyncNotificationInfo.isActive) {
- shouldInstall = shouldCancel = false;
- } else {
- // it isn't currently up, so there is nothing to cancel
- shouldCancel = false;
-
- final boolean timeToShowNotification =
- now > mSyncNotificationInfo.startTime + SYNC_NOTIFICATION_DELAY;
- if (timeToShowNotification) {
- shouldInstall = true;
- } else {
- // show the notification immediately if this is a manual sync
- shouldInstall = false;
- for (ActiveSyncContext activeSyncContext : mActiveSyncContexts) {
- final boolean manualSync = activeSyncContext.mSyncOperation.extras
- .getBoolean(ContentResolver.SYNC_EXTRAS_MANUAL, false);
- if (manualSync) {
- shouldInstall = true;
- break;
- }
- }
- }
- }
- }
-
- if (shouldCancel && !shouldInstall) {
- mNeedSyncActiveNotification = false;
- sendSyncStateIntent();
- mSyncNotificationInfo.isActive = false;
- }
-
- if (shouldInstall) {
- mNeedSyncActiveNotification = true;
- sendSyncStateIntent();
- mSyncNotificationInfo.isActive = true;
- }
- }
-
private void manageSyncAlarmLocked(long nextPeriodicEventElapsedTime,
long nextPendingEventElapsedTime) {
// in each of these cases the sync loop will be kicked, which will cause this
@@ -3238,13 +3170,6 @@
if (mStorageIsLow) return;
if (mDeviceIsIdle) return;
- // When the status bar notification should be raised
- final long notificationTime =
- (!mSyncHandler.mSyncNotificationInfo.isActive
- && mSyncHandler.mSyncNotificationInfo.startTime != null)
- ? mSyncHandler.mSyncNotificationInfo.startTime + SYNC_NOTIFICATION_DELAY
- : Long.MAX_VALUE;
-
// When we should consider canceling an active sync
long earliestTimeoutTime = Long.MAX_VALUE;
for (ActiveSyncContext currentSyncContext : mActiveSyncContexts) {
@@ -3260,24 +3185,14 @@
}
if (Log.isLoggable(TAG, Log.VERBOSE)) {
- Log.v(TAG, "manageSyncAlarm: notificationTime is " + notificationTime);
- }
-
- if (Log.isLoggable(TAG, Log.VERBOSE)) {
Log.v(TAG, "manageSyncAlarm: earliestTimeoutTime is " + earliestTimeoutTime);
- }
-
- if (Log.isLoggable(TAG, Log.VERBOSE)) {
Log.v(TAG, "manageSyncAlarm: nextPeriodicEventElapsedTime is "
+ nextPeriodicEventElapsedTime);
- }
- if (Log.isLoggable(TAG, Log.VERBOSE)) {
Log.v(TAG, "manageSyncAlarm: nextPendingEventElapsedTime is "
+ nextPendingEventElapsedTime);
}
- long alarmTime = Math.min(notificationTime, earliestTimeoutTime);
- alarmTime = Math.min(alarmTime, nextPeriodicEventElapsedTime);
+ long alarmTime = Math.min(earliestTimeoutTime, nextPeriodicEventElapsedTime);
alarmTime = Math.min(alarmTime, nextPendingEventElapsedTime);
// Bound the alarm time.
@@ -3288,24 +3203,16 @@
+ alarmTime + ", setting to " + (now + SYNC_ALARM_TIMEOUT_MIN));
}
alarmTime = now + SYNC_ALARM_TIMEOUT_MIN;
- } else if (alarmTime > now + SYNC_ALARM_TIMEOUT_MAX) {
- if (Log.isLoggable(TAG, Log.VERBOSE)) {
- Log.v(TAG, "manageSyncAlarm: the alarmTime is too large, "
- + alarmTime + ", setting to " + (now + SYNC_ALARM_TIMEOUT_MIN));
- }
- alarmTime = now + SYNC_ALARM_TIMEOUT_MAX;
}
- // determine if we need to set or cancel the alarm
+ // Determine if we need to set or cancel the alarm
boolean shouldSet = false;
boolean shouldCancel = false;
final boolean alarmIsActive = (mAlarmScheduleTime != null) && (now < mAlarmScheduleTime);
- final boolean needAlarm = alarmTime != Long.MAX_VALUE;
- if (needAlarm) {
- // Need the alarm if
- // - it's currently not set
- // - if the alarm is set in the past.
- if (!alarmIsActive || alarmTime < mAlarmScheduleTime) {
+
+ if (alarmTime != Long.MAX_VALUE) {
+ // Need the alarm if it isn't set or has changed.
+ if (!alarmIsActive || alarmTime != mAlarmScheduleTime) {
shouldSet = true;
}
} else {
@@ -3329,14 +3236,6 @@
}
}
- private void sendSyncStateIntent() {
- Intent syncStateIntent = new Intent(Intent.ACTION_SYNC_STATE_CHANGED);
- syncStateIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
- syncStateIntent.putExtra("active", mNeedSyncActiveNotification);
- syncStateIntent.putExtra("failing", false);
- mContext.sendBroadcastAsUser(syncStateIntent, UserHandle.OWNER);
- }
-
private void installHandleTooManyDeletesNotification(Account account, String authority,
long numDeletes, int userId) {
if (mNotificationMgr == null) return;
diff --git a/services/core/java/com/android/server/job/JobStore.java b/services/core/java/com/android/server/job/JobStore.java
index 24d4f15..11e7605 100644
--- a/services/core/java/com/android/server/job/JobStore.java
+++ b/services/core/java/com/android/server/job/JobStore.java
@@ -457,7 +457,7 @@
while (eventType != XmlPullParser.START_TAG &&
eventType != XmlPullParser.END_DOCUMENT) {
eventType = parser.next();
- Slog.d(TAG, parser.getName());
+ Slog.d(TAG, "Start tag: " + parser.getName());
}
if (eventType == XmlPullParser.END_DOCUMENT) {
if (DEBUG) {
diff --git a/services/core/java/com/android/server/job/controllers/IdleController.java b/services/core/java/com/android/server/job/controllers/IdleController.java
index 8e2ca18..92df851 100644
--- a/services/core/java/com/android/server/job/controllers/IdleController.java
+++ b/services/core/java/com/android/server/job/controllers/IdleController.java
@@ -108,6 +108,7 @@
private AlarmManager mAlarm;
private PendingIntent mIdleTriggerIntent;
boolean mIdle;
+ boolean mScreenOn;
public IdlenessTracker() {
mAlarm = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE);
@@ -120,6 +121,7 @@
// At boot we presume that the user has just "interacted" with the
// device in some meaningful way.
mIdle = false;
+ mScreenOn = true;
}
public boolean isIdle() {
@@ -149,12 +151,14 @@
if (action.equals(Intent.ACTION_SCREEN_ON)
|| action.equals(Intent.ACTION_DREAMING_STOPPED)) {
- // possible transition to not-idle
+ if (DEBUG) {
+ Slog.v(TAG,"exiting idle : " + action);
+ }
+ mScreenOn = true;
+ //cancel the alarm
+ mAlarm.cancel(mIdleTriggerIntent);
if (mIdle) {
- if (DEBUG) {
- Slog.v(TAG, "exiting idle : " + action);
- }
- mAlarm.cancel(mIdleTriggerIntent);
+ // possible transition to not-idle
mIdle = false;
reportNewIdleState(mIdle);
}
@@ -169,11 +173,12 @@
Slog.v(TAG, "Scheduling idle : " + action + " now:" + nowElapsed + " when="
+ when);
}
+ mScreenOn = false;
mAlarm.setWindow(AlarmManager.ELAPSED_REALTIME_WAKEUP,
when, IDLE_WINDOW_SLOP, mIdleTriggerIntent);
} else if (action.equals(ACTION_TRIGGER_IDLE)) {
- // idle time starts now
- if (!mIdle) {
+ // idle time starts now. Do not set mIdle if screen is on.
+ if (!mIdle && !mScreenOn) {
if (DEBUG) {
Slog.v(TAG, "Idle trigger fired @ " + SystemClock.elapsedRealtime());
}
diff --git a/services/core/java/com/android/server/location/GpsLocationProvider.java b/services/core/java/com/android/server/location/GpsLocationProvider.java
index f7e435e..57ca552 100644
--- a/services/core/java/com/android/server/location/GpsLocationProvider.java
+++ b/services/core/java/com/android/server/location/GpsLocationProvider.java
@@ -490,6 +490,12 @@
private void checkSmsSuplInit(Intent intent) {
SmsMessage[] messages = Intents.getMessagesFromIntent(intent);
+
+ if (messages == null) {
+ Log.e(TAG, "Message does not exist in the intent.");
+ return;
+ }
+
for (int i=0; i <messages.length; i++) {
byte[] supl_init = messages[i].getUserData();
native_agps_ni_message(supl_init,supl_init.length);
diff --git a/services/core/java/com/android/server/location/GpsXtraDownloader.java b/services/core/java/com/android/server/location/GpsXtraDownloader.java
index 3585049..c464371 100644
--- a/services/core/java/com/android/server/location/GpsXtraDownloader.java
+++ b/services/core/java/com/android/server/location/GpsXtraDownloader.java
@@ -19,13 +19,14 @@
import android.text.TextUtils;
import android.util.Log;
+import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.URL;
-import libcore.io.Streams;
-
-import java.io.IOException;
import java.util.Properties;
import java.util.Random;
+import java.util.concurrent.TimeUnit;
+
+import libcore.io.Streams;
/**
* A class for downloading GPS XTRA data.
@@ -37,6 +38,7 @@
private static final String TAG = "GpsXtraDownloader";
private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
private static final String DEFAULT_USER_AGENT = "Android";
+ private static final int CONNECTION_TIMEOUT_MS = (int) TimeUnit.SECONDS.toMillis(30);
private final String[] mXtraServers;
// to load balance our server requests
@@ -113,6 +115,7 @@
connection.setRequestProperty(
"x-wap-profile",
"http://www.openmobilealliance.org/tech/profiles/UAPROF/ccppschema-20021212#");
+ connection.setConnectTimeout(CONNECTION_TIMEOUT_MS);
connection.connect();
int statusCode = connection.getResponseCode();
diff --git a/services/core/java/com/android/server/media/projection/MediaProjectionManagerService.java b/services/core/java/com/android/server/media/projection/MediaProjectionManagerService.java
index a029b0e..3ea4f2c 100644
--- a/services/core/java/com/android/server/media/projection/MediaProjectionManagerService.java
+++ b/services/core/java/com/android/server/media/projection/MediaProjectionManagerService.java
@@ -127,9 +127,7 @@
IBinder.DeathRecipient deathRecipient = new IBinder.DeathRecipient() {
@Override
public void binderDied() {
- synchronized (mLock) {
- removeCallback(callback);
- }
+ removeCallback(callback);
}
};
synchronized (mLock) {
@@ -344,6 +342,7 @@
public final String packageName;
public final UserHandle userHandle;
+ private IMediaProjectionCallback mCallback;
private IBinder mToken;
private IBinder.DeathRecipient mDeathEater;
private int mType;
@@ -406,7 +405,8 @@
throw new IllegalStateException(
"Cannot start already started MediaProjection");
}
- registerCallback(callback);
+ mCallback = callback;
+ registerCallback(mCallback);
try {
mToken = callback.asBinder();
mDeathEater = new IBinder.DeathRecipient() {
@@ -435,8 +435,11 @@
+ "pid=" + Binder.getCallingPid() + ")");
return;
}
- mToken.unlinkToDeath(mDeathEater, 0);
stopProjectionLocked(this);
+ mToken.unlinkToDeath(mDeathEater, 0);
+ mToken = null;
+ unregisterCallback(mCallback);
+ mCallback = null;
}
}
diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
index cd982d3..7334f5b 100644
--- a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
+++ b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
@@ -279,8 +279,6 @@
final SparseIntArray mUidPolicy = new SparseIntArray();
/** Currently derived rules for each UID. */
final SparseIntArray mUidRules = new SparseIntArray();
- /** Set of states for the child firewall chains. True if the chain is active. */
- final SparseBooleanArray mFirewallChainStates = new SparseBooleanArray();
/**
* UIDs that have been white-listed to always be able to have network access
@@ -1668,8 +1666,9 @@
public NetworkPolicy[] getNetworkPolicies(String callingPackage) {
mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG);
try {
- mContext.enforceCallingPermission(READ_PRIVILEGED_PHONE_STATE, TAG);
- // SKIP checking run-time OP_READ_PHONE_STATE since using PRIVILEGED
+ mContext.enforceCallingOrSelfPermission(READ_PRIVILEGED_PHONE_STATE, TAG);
+ // SKIP checking run-time OP_READ_PHONE_STATE since caller or self has PRIVILEGED
+ // permission
} catch (SecurityException e) {
mContext.enforceCallingOrSelfPermission(READ_PHONE_STATE, TAG);
@@ -2436,12 +2435,6 @@
* 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.
- return;
- }
- mFirewallChainStates.put(chain, enable);
try {
mNetworkManager.setFirewallChainEnabled(chain, enable);
} catch (IllegalStateException e) {
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index 7a6895f..9426b76 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -1842,7 +1842,7 @@
}
pw.println(':');
int N;
- final boolean zenOnly = filter != null && filter.zen;
+ final boolean zenOnly = filter.filtered && filter.zen;
if (!zenOnly) {
synchronized (mToastQueue) {
@@ -1864,13 +1864,13 @@
pw.println(" Notification List:");
for (int i=0; i<N; i++) {
final NotificationRecord nr = mNotificationList.get(i);
- if (filter != null && !filter.matches(nr.sbn)) continue;
+ if (filter.filtered && !filter.matches(nr.sbn)) continue;
nr.dump(pw, " ", getContext(), filter.redact);
}
pw.println(" ");
}
- if (filter == null) {
+ if (!filter.filtered) {
N = mLights.size();
if (N > 0) {
pw.println(" Lights List:");
@@ -1911,7 +1911,7 @@
mUsageStats.dump(pw, " ", filter);
}
- if (filter == null || zenOnly) {
+ if (!filter.filtered || zenOnly) {
pw.println("\n Zen Mode:");
pw.print(" mInterruptionFilter="); pw.println(mInterruptionFilter);
mZenModeHelper.dump(pw, " ");
diff --git a/services/core/java/com/android/server/notification/ZenModeHelper.java b/services/core/java/com/android/server/notification/ZenModeHelper.java
index 31fa5c4..57d7758 100644
--- a/services/core/java/com/android/server/notification/ZenModeHelper.java
+++ b/services/core/java/com/android/server/notification/ZenModeHelper.java
@@ -88,7 +88,6 @@
private int mUser = UserHandle.USER_OWNER;
private ZenModeConfig mConfig;
private AudioManagerInternal mAudioManager;
- private int mPreviousRingerMode = -1;
private boolean mEffectsSuppressed;
public ZenModeHelper(Context context, Looper looper, ConditionProviders conditionProviders) {
@@ -236,7 +235,6 @@
}
pw.print(prefix); pw.print("mUser="); pw.println(mUser);
dump(pw, prefix, "mConfig", mConfig);
- pw.print(prefix); pw.print("mPreviousRingerMode="); pw.println(mPreviousRingerMode);
pw.print(prefix); pw.print("mEffectsSuppressed="); pw.println(mEffectsSuppressed);
mFiltering.dump(pw, prefix);
mConditions.dump(pw, prefix);
@@ -357,6 +355,17 @@
Global.putInt(mContext.getContentResolver(), Global.ZEN_MODE, zen);
}
+ private int getPreviousRingerModeSetting() {
+ return Global.getInt(mContext.getContentResolver(),
+ Global.ZEN_MODE_RINGER_LEVEL, AudioManager.RINGER_MODE_NORMAL);
+ }
+
+ private void setPreviousRingerModeSetting(Integer previousRingerLevel) {
+ Global.putString(
+ mContext.getContentResolver(), Global.ZEN_MODE_RINGER_LEVEL,
+ previousRingerLevel == null ? null : Integer.toString(previousRingerLevel));
+ }
+
private boolean evaluateZenMode(String reason, boolean setRingerMode) {
if (DEBUG) Log.d(TAG, "evaluateZenMode");
final ArraySet<ZenRule> automaticRules = new ArraySet<ZenRule>();
@@ -430,16 +439,15 @@
case Global.ZEN_MODE_NO_INTERRUPTIONS:
case Global.ZEN_MODE_ALARMS:
if (ringerModeInternal != AudioManager.RINGER_MODE_SILENT) {
- mPreviousRingerMode = ringerModeInternal;
+ setPreviousRingerModeSetting(ringerModeInternal);
newRingerModeInternal = AudioManager.RINGER_MODE_SILENT;
}
break;
case Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS:
case Global.ZEN_MODE_OFF:
if (ringerModeInternal == AudioManager.RINGER_MODE_SILENT) {
- newRingerModeInternal = mPreviousRingerMode != -1 ? mPreviousRingerMode
- : AudioManager.RINGER_MODE_NORMAL;
- mPreviousRingerMode = -1;
+ newRingerModeInternal = getPreviousRingerModeSetting();
+ setPreviousRingerModeSetting(null);
}
break;
}
@@ -593,7 +601,7 @@
&& mZenMode != Global.ZEN_MODE_ALARMS) {
newZen = Global.ZEN_MODE_ALARMS;
}
- mPreviousRingerMode = ringerModeOld;
+ setPreviousRingerModeSetting(ringerModeOld);
}
break;
case AudioManager.RINGER_MODE_VIBRATE:
diff --git a/services/core/java/com/android/server/pm/DefaultPermissionGrantPolicy.java b/services/core/java/com/android/server/pm/DefaultPermissionGrantPolicy.java
index 6278371..3227ef8 100644
--- a/services/core/java/com/android/server/pm/DefaultPermissionGrantPolicy.java
+++ b/services/core/java/com/android/server/pm/DefaultPermissionGrantPolicy.java
@@ -634,6 +634,7 @@
&& doesPackageSupportRuntimePermissions(carrierPackage)) {
grantRuntimePermissionsLPw(carrierPackage, PHONE_PERMISSIONS, userId);
grantRuntimePermissionsLPw(carrierPackage, LOCATION_PERMISSIONS, userId);
+ grantRuntimePermissionsLPw(carrierPackage, SMS_PERMISSIONS, userId);
}
}
}
@@ -695,7 +696,7 @@
List<PackageParser.Package> syncAdapterPackages = new ArrayList<>();
Intent homeIntent = new Intent(Intent.ACTION_MAIN);
- homeIntent.addCategory(Intent.CATEGORY_HOME);
+ homeIntent.addCategory(Intent.CATEGORY_LAUNCHER);
for (String syncAdapterPackageName : syncAdapterPackageNames) {
homeIntent.setPackage(syncAdapterPackageName);
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 92f70ff..3b9f402 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -66,6 +66,7 @@
import static android.content.pm.PackageParser.isApkFile;
import static android.os.Process.PACKAGE_INFO_GID;
import static android.os.Process.SYSTEM_UID;
+import static android.os.Trace.TRACE_TAG_PACKAGE_MANAGER;
import static android.system.OsConstants.O_CREAT;
import static android.system.OsConstants.O_RDWR;
import static com.android.internal.app.IntentForwarderActivity.FORWARD_INTENT_TO_MANAGED_PROFILE;
@@ -163,6 +164,7 @@
import android.os.ServiceManager;
import android.os.SystemClock;
import android.os.SystemProperties;
+import android.os.Trace;
import android.os.UserHandle;
import android.os.UserManager;
import android.os.storage.IMountService;
@@ -1134,16 +1136,23 @@
// need to do anything. The pending install
// will be processed later on.
if (!mBound) {
- // If this is the only one pending we might
- // have to bind to the service again.
- if (!connectToService()) {
- Slog.e(TAG, "Failed to bind to media container service");
- params.serviceError();
- return;
- } else {
- // Once we bind to the service, the first
- // pending request will be processed.
- mPendingInstalls.add(idx, params);
+ try {
+ Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "bindMCS",
+ System.identityHashCode(params));
+ // If this is the only one pending we might
+ // have to bind to the service again.
+ if (!connectToService()) {
+ Slog.e(TAG, "Failed to bind to media container service");
+ params.serviceError();
+ return;
+ } else {
+ // Once we bind to the service, the first
+ // pending request will be processed.
+ mPendingInstalls.add(idx, params);
+ }
+ } finally {
+ Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "bindMCS",
+ System.identityHashCode(params));
}
} else {
mPendingInstalls.add(idx, params);
@@ -1168,6 +1177,8 @@
for (HandlerParams params : mPendingInstalls) {
// Indicate service bind error
params.serviceError();
+ Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
+ System.identityHashCode(params));
}
mPendingInstalls.clear();
} else {
@@ -1205,6 +1216,8 @@
}
}
}
+ Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
+ System.identityHashCode(params));
} else {
// Should never happen ideally.
Slog.w(TAG, "Empty queue");
@@ -1222,6 +1235,8 @@
for (HandlerParams params : mPendingInstalls) {
// Indicate service bind error
params.serviceError();
+ Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
+ System.identityHashCode(params));
}
mPendingInstalls.clear();
}
@@ -1249,7 +1264,9 @@
}
case MCS_GIVE_UP: {
if (DEBUG_INSTALL) Slog.i(TAG, "mcs_giveup too many retries");
- mPendingInstalls.remove(0);
+ HandlerParams params = mPendingInstalls.remove(0);
+ Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
+ System.identityHashCode(params));
break;
}
case SEND_PENDING_BROADCAST: {
@@ -1444,6 +1461,8 @@
} else {
Slog.e(TAG, "Bogus post-install token " + msg.arg1);
}
+
+ Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "postInstall", msg.arg1);
} break;
case UPDATED_MEDIA_STATUS: {
if (DEBUG_SD_INSTALL) Log.i(TAG, "Got message UPDATED_MEDIA_STATUS");
@@ -1525,6 +1544,8 @@
processPendingInstall(args, ret);
mHandler.sendEmptyMessage(MCS_UNBIND);
}
+ Trace.asyncTraceEnd(
+ TRACE_TAG_PACKAGE_MANAGER, "pendingVerification", verificationId);
break;
}
case PACKAGE_VERIFIED: {
@@ -2207,7 +2228,7 @@
mSettings.enableSystemPackageLPw(packageName);
try {
- scanPackageLI(scanFile, reparseFlags, scanFlags, 0, null);
+ scanPackageTracedLI(scanFile, reparseFlags, scanFlags, 0, null);
} catch (PackageManagerException e) {
Slog.e(TAG, "Failed to parse original system package: "
+ e.getMessage());
@@ -5433,7 +5454,7 @@
}
@Override
- public List<ProviderInfo> queryContentProviders(String processName,
+ public ParceledListSlice<ProviderInfo> queryContentProviders(String processName,
int uid, int flags) {
ArrayList<ProviderInfo> finalList = null;
// reader
@@ -5465,9 +5486,10 @@
if (finalList != null) {
Collections.sort(finalList, mProviderInitOrderSorter);
+ return new ParceledListSlice<ProviderInfo>(finalList);
}
- return finalList;
+ return null;
}
@Override
@@ -5577,7 +5599,7 @@
continue;
}
try {
- scanPackageLI(file, parseFlags | PackageParser.PARSE_MUST_BE_APK,
+ scanPackageTracedLI(file, parseFlags | PackageParser.PARSE_MUST_BE_APK,
scanFlags, currentTime, null);
} catch (PackageManagerException e) {
Slog.w(TAG, "Failed to parse " + file + ": " + e.getMessage());
@@ -5664,9 +5686,23 @@
}
}
- /*
- * Scan a package and return the newly parsed package.
- * Returns null in case of errors and the error code is stored in mLastScanError
+ /**
+ * Traces a package scan.
+ * @see #scanPackageLI(File, int, int, long, UserHandle)
+ */
+ private PackageParser.Package scanPackageTracedLI(File scanFile, int parseFlags, int scanFlags,
+ long currentTime, UserHandle user) throws PackageManagerException {
+ Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanPackage");
+ try {
+ return scanPackageLI(scanFile, parseFlags, scanFlags, currentTime, user);
+ } finally {
+ Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
+ }
+ }
+
+ /**
+ * Scans a package and returns the newly parsed package.
+ * Returns {@code null} in case of errors and the error code is stored in mLastScanError
*/
private PackageParser.Package scanPackageLI(File scanFile, int parseFlags, int scanFlags,
long currentTime, UserHandle user) throws PackageManagerException {
@@ -6437,6 +6473,16 @@
return cpuAbiOverride;
}
+ private PackageParser.Package scanPackageTracedLI(PackageParser.Package pkg, int parseFlags,
+ int scanFlags, long currentTime, UserHandle user) throws PackageManagerException {
+ Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanPackage");
+ try {
+ return scanPackageLI(pkg, parseFlags, scanFlags, currentTime, user);
+ } finally {
+ Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
+ }
+ }
+
private PackageParser.Package scanPackageLI(PackageParser.Package pkg, int parseFlags,
int scanFlags, long currentTime, UserHandle user) throws PackageManagerException {
boolean success = false;
@@ -6984,13 +7030,18 @@
// this symlink for 64 bit libraries.
if (pkg.applicationInfo.primaryCpuAbi != null &&
!VMRuntime.is64BitAbi(pkg.applicationInfo.primaryCpuAbi)) {
- final String nativeLibPath = pkg.applicationInfo.nativeLibraryDir;
- for (int userId : userIds) {
- if (mInstaller.linkNativeLibraryDirectory(pkg.volumeUuid, pkg.packageName,
- nativeLibPath, userId) < 0) {
- throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR,
- "Failed linking native library dir (user=" + userId + ")");
+ Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "linkNativeLib");
+ try {
+ final String nativeLibPath = pkg.applicationInfo.nativeLibraryDir;
+ for (int userId : userIds) {
+ if (mInstaller.linkNativeLibraryDirectory(pkg.volumeUuid, pkg.packageName,
+ nativeLibPath, userId) < 0) {
+ throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR,
+ "Failed linking native library dir (user=" + userId + ")");
+ }
}
+ } finally {
+ Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
}
}
}
@@ -7051,8 +7102,12 @@
}
if ((scanFlags & SCAN_NO_DEX) == 0) {
+ Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt");
+
int result = mPackageDexOptimizer.performDexOpt(pkg, null /* instruction sets */,
forceDex, (scanFlags & SCAN_DEFER_DEX) != 0, false /* inclDependencies */);
+
+ Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
if (result == PackageDexOptimizer.DEX_OPT_FAILED) {
throw new PackageManagerException(INSTALL_FAILED_DEXOPT, "scanPackageLI");
}
@@ -7141,8 +7196,12 @@
// so that we do not end up in a confused state while the user is still using the older
// version of the application while the new one gets installed.
if ((scanFlags & SCAN_REPLACING) != 0) {
+ Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "killApplication");
+
killApplication(pkg.applicationInfo.packageName,
pkg.applicationInfo.uid, "replace pkg");
+
+ Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
}
// Also need to kill any apps that are dependent on the library.
@@ -7159,6 +7218,9 @@
ksms.assertScannedPackageValid(pkg);
// writer
+ Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "updateSettings");
+
+ boolean createIdmapFailed = false;
synchronized (mPackages) {
// We don't expect installation to fail beyond this point
@@ -7501,8 +7563,7 @@
map.put(pkg.packageName, pkg);
PackageParser.Package orig = mPackages.get(pkg.mOverlayTarget);
if (orig != null && !createIdmapForPackagePairLI(orig, pkg)) {
- throw new PackageManagerException(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
- "scanPackageLI failed to createIdmap");
+ createIdmapFailed = true;
}
}
} else if (mOverlays.containsKey(pkg.packageName) &&
@@ -7512,6 +7573,12 @@
}
}
+ Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
+
+ if (createIdmapFailed) {
+ throw new PackageManagerException(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
+ "scanPackageLI failed to createIdmap");
+ }
return pkg;
}
@@ -8310,6 +8377,8 @@
return;
}
+ Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "grantPermissions");
+
PermissionsState permissionsState = ps.getPermissionsState();
PermissionsState origPermissions = permissionsState;
@@ -8536,6 +8605,8 @@
for (int userId : changedRuntimePermissionUserIds) {
mSettings.writeRuntimePermissionsForUserLPr(userId, false);
}
+
+ Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
}
private boolean isNewPlatformPermissionForPackage(String perm, PackageParser.Package pkg) {
@@ -8604,7 +8675,7 @@
if (!allowed) {
if (!allowed && (bp.protectionLevel
& PermissionInfo.PROTECTION_FLAG_PRE23) != 0
- && pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.MNC) {
+ && pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) {
// If this was a previously normal/dangerous permission that got moved
// to a system permission as part of the runtime permission redesign, then
// we still want to blindly grant it to old apps.
@@ -9528,6 +9599,10 @@
msg.obj = new InstallParams(origin, null, observer, params.installFlags,
installerPackageName, params.volumeUuid, verifParams, user, params.abiOverride,
params.grantedRuntimePermissions);
+
+ Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
+ System.identityHashCode(msg.obj));
+
mHandler.sendMessage(msg);
}
@@ -9599,6 +9674,7 @@
killApplication(packageName, UserHandle.getUid(userId, pkgSetting.appId),
"hiding pkg");
sendApplicationHiddenForUser(packageName, pkgSetting, userId);
+ return true;
}
} finally {
Binder.restoreCallingIdentity(callingId);
@@ -10102,7 +10178,7 @@
if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
args.doPreInstall(res.returnCode);
synchronized (mInstallLock) {
- installPackageLI(args, res);
+ installPackageTracedLI(args, res);
}
args.doPostInstall(res.returnCode, res.uid);
}
@@ -10136,6 +10212,7 @@
if (bm != null) {
if (DEBUG_INSTALL) Log.v(TAG, "token " + token
+ " to BM for possible restore");
+ Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "restore", token);
try {
if (bm.isBackupServiceActive(UserHandle.USER_OWNER)) {
bm.restoreAtInstall(res.pkg.applicationInfo.packageName, token);
@@ -10147,6 +10224,8 @@
} catch (Exception e) {
Slog.e(TAG, "Exception trying to enqueue restore", e);
doRestore = false;
+ } finally {
+ Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "restore", token);
}
} else {
Slog.e(TAG, "Backup Manager not found!");
@@ -10158,6 +10237,9 @@
// No restore possible, or the Backup Manager was mysteriously not
// available -- just fire the post-install work request directly.
if (DEBUG_INSTALL) Log.v(TAG, "No restore - queue post-install for " + token);
+
+ Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "postInstall", token);
+
Message msg = mHandler.obtainMessage(POST_INSTALL, token, 0);
mHandler.sendMessage(msg);
}
@@ -10521,7 +10603,6 @@
final boolean onSd = (installFlags & PackageManager.INSTALL_EXTERNAL) != 0;
final boolean onInt = (installFlags & PackageManager.INSTALL_INTERNAL) != 0;
-
PackageInfoLite pkgLite = null;
if (onInt && onSd) {
@@ -10717,6 +10798,8 @@
mRequiredVerifierPackage, receivers);
if (ret == PackageManager.INSTALL_SUCCEEDED
&& mRequiredVerifierPackage != null) {
+ Trace.asyncTraceBegin(
+ TRACE_TAG_PACKAGE_MANAGER, "pendingVerification", verificationId);
/*
* Send the intent to the required verification agent,
* but only start the verification timeout after the
@@ -10983,6 +11066,15 @@
}
int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException {
+ Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyApk");
+ try {
+ return doCopyApk(imcs, temp);
+ } finally {
+ Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
+ }
+ }
+
+ private int doCopyApk(IMediaContainerService imcs, boolean temp) throws RemoteException {
if (origin.staged) {
if (DEBUG_INSTALL) Slog.d(TAG, origin.file + " already staged; skipping copy");
codeFile = origin.file;
@@ -11692,12 +11784,15 @@
private void installNewPackageLI(PackageParser.Package pkg, int parseFlags, int scanFlags,
UserHandle user, String installerPackageName, String volumeUuid,
PackageInstalledInfo res) {
+ Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "installNewPackage");
+
// Remember this for later, in case we need to rollback this install
String pkgName = pkg.packageName;
if (DEBUG_INSTALL) Slog.d(TAG, "installNewPackageLI: " + pkg);
final boolean dataDirExists = Environment
.getDataUserPackageDirectory(volumeUuid, UserHandle.USER_OWNER, pkgName).exists();
+
synchronized(mPackages) {
if (mSettings.mRenamedPackages.containsKey(pkgName)) {
// A package with the same name is already installed, though
@@ -11718,7 +11813,7 @@
}
try {
- PackageParser.Package newPackage = scanPackageLI(pkg, parseFlags, scanFlags,
+ PackageParser.Package newPackage = scanPackageTracedLI(pkg, parseFlags, scanFlags,
System.currentTimeMillis(), user);
updateSettingsLI(newPackage, installerPackageName, volumeUuid, null, null, res, user);
@@ -11737,6 +11832,8 @@
} catch (PackageManagerException e) {
res.setError("Package couldn't be installed in " + pkg.codePath, e);
}
+
+ Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
}
private boolean shouldCheckUpgradeKeySetLP(PackageSetting oldPs, int scanFlags) {
@@ -11863,7 +11960,7 @@
deleteCodeCacheDirsLI(pkg.volumeUuid, pkgName);
try {
- final PackageParser.Package newPackage = scanPackageLI(pkg, parseFlags,
+ final PackageParser.Package newPackage = scanPackageTracedLI(pkg, parseFlags,
scanFlags | SCAN_UPDATE_TIME, System.currentTimeMillis(), user);
updateSettingsLI(newPackage, installerPackageName, volumeUuid, allUsers,
perUserInstalled, res, user);
@@ -11897,7 +11994,7 @@
(oldExternal ? PackageParser.PARSE_EXTERNAL_STORAGE : 0);
int oldScanFlags = SCAN_UPDATE_SIGNATURE | SCAN_UPDATE_TIME;
try {
- scanPackageLI(restoreFile, oldParseFlags, oldScanFlags, origUpdateTime, null);
+ scanPackageTracedLI(restoreFile, oldParseFlags, oldScanFlags, origUpdateTime, null);
} catch (PackageManagerException e) {
Slog.e(TAG, "Failed to restore package : " + pkgName + " after failed upgrade: "
+ e.getMessage());
@@ -11979,7 +12076,7 @@
PackageParser.Package newPackage = null;
try {
- newPackage = scanPackageLI(pkg, parseFlags, scanFlags, 0, user);
+ newPackage = scanPackageTracedLI(pkg, parseFlags, scanFlags, 0, user);
if (newPackage.mExtras != null) {
final PackageSetting newPkgSetting = (PackageSetting) newPackage.mExtras;
newPkgSetting.firstInstallTime = oldPkgSetting.firstInstallTime;
@@ -12012,7 +12109,7 @@
}
// Add back the old system package
try {
- scanPackageLI(oldPkg, parseFlags, SCAN_UPDATE_SIGNATURE, 0, user);
+ scanPackageTracedLI(oldPkg, parseFlags, SCAN_UPDATE_SIGNATURE, 0, user);
} catch (PackageManagerException e) {
Slog.e(TAG, "Failed to restore original package: " + e.getMessage());
}
@@ -12033,6 +12130,8 @@
private void updateSettingsLI(PackageParser.Package newPackage, String installerPackageName,
String volumeUuid, int[] allUsers, boolean[] perUserInstalled, PackageInstalledInfo res,
UserHandle user) {
+ Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "updateSettings");
+
String pkgName = newPackage.packageName;
synchronized (mPackages) {
//write settings. the installStatus will be incomplete at this stage.
@@ -12043,7 +12142,6 @@
}
if (DEBUG_INSTALL) Slog.d(TAG, "New package installed in " + newPackage.codePath);
-
synchronized (mPackages) {
updatePermissionsLPw(newPackage.packageName, newPackage,
UPDATE_PERMISSIONS_REPLACE_PKG | (newPackage.permissions.size() > 0
@@ -12094,6 +12192,17 @@
//to update install status
mSettings.writeLPr();
}
+
+ Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
+ }
+
+ private void installPackageTracedLI(InstallArgs args, PackageInstalledInfo res) {
+ try {
+ Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "installPackage");
+ installPackageLI(args, res);
+ } finally {
+ Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
+ }
}
private void installPackageLI(InstallArgs args, PackageInstalledInfo res) {
@@ -12114,6 +12223,7 @@
res.returnCode = PackageManager.INSTALL_SUCCEEDED;
if (DEBUG_INSTALL) Slog.d(TAG, "installPackageLI: path=" + tmpPackageFile);
+
// Retrieve PackageSettings and parse package
final int parseFlags = mDefParseFlags | PackageParser.PARSE_CHATTY
| (forwardLocked ? PackageParser.PARSE_FORWARD_LOCK : 0)
@@ -12122,12 +12232,15 @@
pp.setSeparateProcesses(mSeparateProcesses);
pp.setDisplayMetrics(mMetrics);
+ Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "parsePackage");
final PackageParser.Package pkg;
try {
pkg = pp.parsePackage(tmpPackageFile, parseFlags);
} catch (PackageParserException e) {
res.setError("Failed parse during installPackageLI", e);
return;
+ } finally {
+ Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
}
// Mark that we have an install time CPU ABI override.
@@ -12141,12 +12254,15 @@
}
}
+ Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "collectCertificates");
try {
pp.collectCertificates(pkg, parseFlags);
pp.collectManifestDigest(pkg);
} catch (PackageParserException e) {
res.setError("Failed collect during installPackageLI", e);
return;
+ } finally {
+ Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
}
/* If the installer passed in a manifest digest, compare it now. */
@@ -12928,7 +13044,7 @@
final PackageParser.Package newPkg;
try {
- newPkg = scanPackageLI(disabledPs.codePath, parseFlags, SCAN_NO_PATHS, 0, null);
+ newPkg = scanPackageTracedLI(disabledPs.codePath, parseFlags, SCAN_NO_PATHS, 0, null);
} catch (PackageManagerException e) {
Slog.w(TAG, "Failed to restore system package:" + newPs.name + ": " + e.getMessage());
return false;
@@ -15443,7 +15559,7 @@
synchronized (mInstallLock) {
PackageParser.Package pkg = null;
try {
- pkg = scanPackageLI(new File(codePath), parseFlags, 0, 0, null);
+ pkg = scanPackageTracedLI(new File(codePath), parseFlags, 0, 0, null);
} catch (PackageManagerException e) {
Slog.w(TAG, "Failed to scan " + codePath + ": " + e.getMessage());
}
@@ -15589,7 +15705,7 @@
for (PackageSetting ps : packages) {
final PackageParser.Package pkg;
try {
- pkg = scanPackageLI(ps.codePath, parseFlags, SCAN_INITIAL, 0L, null);
+ pkg = scanPackageTracedLI(ps.codePath, parseFlags, SCAN_INITIAL, 0L, null);
loaded.add(pkg.applicationInfo);
} catch (PackageManagerException e) {
Slog.w(TAG, "Failed to scan " + ps.codePath + ": " + e.getMessage());
@@ -15810,16 +15926,27 @@
"Cannot move system application");
}
- if (Objects.equals(ps.volumeUuid, volumeUuid)) {
- throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
- "Package already moved to " + volumeUuid);
+ if (pkg.applicationInfo.isExternalAsec()) {
+ currentAsec = true;
+ currentVolumeUuid = StorageManager.UUID_PRIMARY_PHYSICAL;
+ } else if (pkg.applicationInfo.isForwardLocked()) {
+ currentAsec = true;
+ currentVolumeUuid = "forward_locked";
+ } else {
+ currentAsec = false;
+ currentVolumeUuid = ps.volumeUuid;
+
+ final File probe = new File(pkg.codePath);
+ final File probeOat = new File(probe, "oat");
+ if (!probe.isDirectory() || !probeOat.isDirectory()) {
+ throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
+ "Move only supported for modern cluster style installs");
+ }
}
- final File probe = new File(pkg.codePath);
- final File probeOat = new File(probe, "oat");
- if (!probe.isDirectory() || !probeOat.isDirectory()) {
+ if (Objects.equals(currentVolumeUuid, volumeUuid)) {
throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
- "Move only supported for modern cluster style installs");
+ "Package already moved to " + volumeUuid);
}
if (ps.frozen) {
@@ -15828,9 +15955,6 @@
}
ps.frozen = true;
- currentAsec = pkg.applicationInfo.isForwardLocked()
- || pkg.applicationInfo.isExternalAsec();
- currentVolumeUuid = ps.volumeUuid;
codeFile = new File(pkg.codePath);
installerPackageName = ps.installerPackageName;
packageAbiOverride = ps.cpuAbiOverrideString;
diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java
index 3c92a52..5bdad50 100644
--- a/services/core/java/com/android/server/pm/Settings.java
+++ b/services/core/java/com/android/server/pm/Settings.java
@@ -616,6 +616,7 @@
p.sharedUser = origPackage.sharedUser;
p.appId = origPackage.appId;
p.origPackage = origPackage;
+ p.getPermissionsState().copyFrom(origPackage.getPermissionsState());
mRenamedPackages.put(name, origPackage.name);
name = origPackage.name;
// Update new package state.
@@ -815,6 +816,20 @@
p.sharedUser = sharedUser;
p.appId = sharedUser.userId;
}
+
+ // If the we know about this user id, we have to update it as it
+ // has to point to the same PackageSetting instance as the package.
+ Object userIdPs = getUserIdLPr(p.appId);
+ if (sharedUser == null) {
+ if (userIdPs != null && userIdPs != p) {
+ replaceUserIdLPw(p.appId, p);
+ }
+ } else {
+ if (userIdPs != null && userIdPs != sharedUser) {
+ replaceUserIdLPw(p.appId, sharedUser);
+ }
+ }
+
IntentFilterVerificationInfo ivi = mRestoredIntentFilterVerifications.get(name);
if (ivi != null) {
if (DEBUG_DOMAIN_VERIFICATION) {
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index 16571ea..454cdcf 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -5258,9 +5258,11 @@
}
private boolean shouldDispatchInputWhenNonInteractive() {
- // Send events to keyguard while the screen is on.
- if (isKeyguardShowingAndNotOccluded() && mDisplay != null
- && mDisplay.getState() != Display.STATE_OFF) {
+ if (mDisplay == null || mDisplay.getState() == Display.STATE_OFF) {
+ return false;
+ }
+ // Send events to keyguard while the screen is on and it's showing.
+ if (isKeyguardShowingAndNotOccluded()) {
return true;
}
diff --git a/services/core/java/com/android/server/power/PowerManagerService.java b/services/core/java/com/android/server/power/PowerManagerService.java
index b920f97..7ebb7f8 100644
--- a/services/core/java/com/android/server/power/PowerManagerService.java
+++ b/services/core/java/com/android/server/power/PowerManagerService.java
@@ -2269,7 +2269,7 @@
public void run() {
synchronized (this) {
if (shutdown) {
- ShutdownThread.shutdown(mContext, confirm);
+ ShutdownThread.shutdown(mContext, reason, confirm);
} else {
ShutdownThread.reboot(mContext, reason, confirm);
}
@@ -2546,9 +2546,14 @@
/**
* Low-level function turn the device off immediately, without trying
* to be clean. Most people should use {@link ShutdownThread} for a clean shutdown.
+ *
+ * @param reason code to pass to android_reboot() (e.g. "userrequested"), or null.
*/
- public static void lowLevelShutdown() {
- SystemProperties.set("sys.powerctl", "shutdown");
+ public static void lowLevelShutdown(String reason) {
+ if (reason == null) {
+ reason = "";
+ }
+ SystemProperties.set("sys.powerctl", "shutdown," + reason);
}
/**
@@ -3277,12 +3282,12 @@
* @param wait If true, this call waits for the shutdown to complete and does not return.
*/
@Override // Binder call
- public void shutdown(boolean confirm, boolean wait) {
+ public void shutdown(boolean confirm, String reason, boolean wait) {
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.REBOOT, null);
final long ident = Binder.clearCallingIdentity();
try {
- shutdownOrRebootInternal(true, confirm, null, wait);
+ shutdownOrRebootInternal(true, confirm, reason, wait);
} finally {
Binder.restoreCallingIdentity(ident);
}
diff --git a/services/core/java/com/android/server/power/ShutdownThread.java b/services/core/java/com/android/server/power/ShutdownThread.java
index dd8648d..ac6a28e 100644
--- a/services/core/java/com/android/server/power/ShutdownThread.java
+++ b/services/core/java/com/android/server/power/ShutdownThread.java
@@ -88,7 +88,7 @@
private static boolean mReboot;
private static boolean mRebootSafeMode;
private static boolean mRebootUpdate;
- private static String mRebootReason;
+ private static String mReason;
// Provides shutdown assurance in case the system_server is killed
public static final String SHUTDOWN_ACTION_PROPERTY = "sys.shutdown.requested";
@@ -124,11 +124,13 @@
* is shown.
*
* @param context Context used to display the shutdown progress dialog.
+ * @param reason code to pass to android_reboot() (e.g. "userrequested"), or null.
* @param confirm true if user confirmation is needed before shutting down.
*/
- public static void shutdown(final Context context, boolean confirm) {
+ public static void shutdown(final Context context, String reason, boolean confirm) {
mReboot = false;
mRebootSafeMode = false;
+ mReason = reason;
shutdownInner(context, confirm);
}
@@ -212,7 +214,7 @@
mReboot = true;
mRebootSafeMode = false;
mRebootUpdate = false;
- mRebootReason = reason;
+ mReason = reason;
shutdownInner(context, confirm);
}
@@ -232,7 +234,7 @@
mReboot = true;
mRebootSafeMode = true;
mRebootUpdate = false;
- mRebootReason = null;
+ mReason = null;
shutdownInner(context, confirm);
}
@@ -249,18 +251,18 @@
ProgressDialog pd = new ProgressDialog(context);
// Path 1: Reboot to recovery and install the update
- // Condition: mRebootReason == REBOOT_RECOVERY and mRebootUpdate == True
+ // Condition: mReason == REBOOT_RECOVERY and mRebootUpdate == True
// (mRebootUpdate is set by checking if /cache/recovery/uncrypt_file exists.)
// UI: progress bar
//
// Path 2: Reboot to recovery for factory reset
- // Condition: mRebootReason == REBOOT_RECOVERY
+ // Condition: mReason == REBOOT_RECOVERY
// UI: spinning circle only (no progress bar)
//
// Path 3: Regular reboot / shutdown
// Condition: Otherwise
// UI: spinning circle only (no progress bar)
- if (PowerManager.REBOOT_RECOVERY.equals(mRebootReason)) {
+ if (PowerManager.REBOOT_RECOVERY.equals(mReason)) {
mRebootUpdate = new File(UNCRYPT_PACKAGE_FILE).exists();
if (mRebootUpdate) {
pd.setTitle(context.getText(com.android.internal.R.string.reboot_to_update_title));
@@ -349,7 +351,7 @@
* the beginning of the SystemServer startup.
*/
{
- String reason = (mReboot ? "1" : "0") + (mRebootReason != null ? mRebootReason : "");
+ String reason = (mReboot ? "1" : "0") + (mReason != null ? mReason : "");
SystemProperties.set(SHUTDOWN_ACTION_PROPERTY, reason);
}
@@ -473,7 +475,7 @@
uncrypt();
}
- rebootOrShutdown(mContext, mReboot, mRebootReason);
+ rebootOrShutdown(mContext, mReboot, mReason);
}
private void setRebootProgress(final int progress, final CharSequence message) {
@@ -616,13 +618,14 @@
*
* @param context Context used to vibrate or null without vibration
* @param reboot true to reboot or false to shutdown
- * @param reason reason for reboot
+ * @param reason reason for reboot/shutdown
*/
public static void rebootOrShutdown(final Context context, boolean reboot, String reason) {
if (reboot) {
Log.i(TAG, "Rebooting, reason: " + reason);
PowerManagerService.lowLevelReboot(reason);
Log.e(TAG, "Reboot failed, will attempt shutdown instead");
+ reason = null;
} else if (SHUTDOWN_VIBRATE_MS > 0 && context != null) {
// vibrate before shutting down
Vibrator vibrator = new SystemVibrator(context);
@@ -642,7 +645,7 @@
// Shutdown power
Log.i(TAG, "Performing low-level shutdown...");
- PowerManagerService.lowLevelShutdown();
+ PowerManagerService.lowLevelShutdown(reason);
}
private void uncrypt() {
diff --git a/services/core/java/com/android/server/search/SearchManagerService.java b/services/core/java/com/android/server/search/SearchManagerService.java
index 04b2f60..4c7f888 100644
--- a/services/core/java/com/android/server/search/SearchManagerService.java
+++ b/services/core/java/com/android/server/search/SearchManagerService.java
@@ -106,7 +106,7 @@
}
private void onUserRemoved(int userId) {
- if (userId != UserHandle.USER_OWNER) {
+ if (userId != UserHandle.USER_NULL) {
synchronized (mSearchables) {
mSearchables.remove(userId);
}
@@ -133,7 +133,7 @@
private final class UserReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
- onUserRemoved(intent.getIntExtra(Intent.EXTRA_USER_HANDLE, UserHandle.USER_OWNER));
+ onUserRemoved(intent.getIntExtra(Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL));
}
}
diff --git a/services/core/java/com/android/server/trust/TrustManagerService.java b/services/core/java/com/android/server/trust/TrustManagerService.java
index 07fc23f..43f4047 100644
--- a/services/core/java/com/android/server/trust/TrustManagerService.java
+++ b/services/core/java/com/android/server/trust/TrustManagerService.java
@@ -579,8 +579,14 @@
private void clearUserHasAuthenticated(int userId) {
if (userId == UserHandle.USER_ALL) {
mUserHasAuthenticated.clear();
+ synchronized (mUserHasAuthenticatedSinceBoot) {
+ mUserHasAuthenticatedSinceBoot.clear();
+ }
} else {
mUserHasAuthenticated.put(userId, false);
+ synchronized (mUserHasAuthenticatedSinceBoot) {
+ mUserHasAuthenticatedSinceBoot.put(userId, false);
+ }
}
}
diff --git a/services/core/java/com/android/server/tv/TvInputManagerService.java b/services/core/java/com/android/server/tv/TvInputManagerService.java
index a5344b4..ee2353f 100644
--- a/services/core/java/com/android/server/tv/TvInputManagerService.java
+++ b/services/core/java/com/android/server/tv/TvInputManagerService.java
@@ -117,7 +117,7 @@
private final Object mLock = new Object();
// ID of the current user.
- private int mCurrentUserId = UserHandle.USER_OWNER;
+ private int mCurrentUserId = UserHandle.USER_SYSTEM;
// A map from user id to UserState.
private final SparseArray<UserState> mUserStates = new SparseArray<>();
diff --git a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
index 7784884..87d0700 100644
--- a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
+++ b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
@@ -484,8 +484,8 @@
mAppOpsManager = (AppOpsManager) mContext.getSystemService(Context.APP_OPS_SERVICE);
mMonitor = new MyPackageMonitor();
mMonitor.register(context, null, UserHandle.ALL, true);
- getWallpaperDir(UserHandle.USER_OWNER).mkdirs();
- loadSettingsLocked(UserHandle.USER_OWNER);
+ getWallpaperDir(UserHandle.USER_SYSTEM).mkdirs();
+ loadSettingsLocked(UserHandle.USER_SYSTEM);
}
private static File getWallpaperDir(int userId) {
@@ -503,7 +503,7 @@
public void systemRunning() {
if (DEBUG) Slog.v(TAG, "systemReady");
- WallpaperData wallpaper = mWallpaperMap.get(UserHandle.USER_OWNER);
+ WallpaperData wallpaper = mWallpaperMap.get(UserHandle.USER_SYSTEM);
switchWallpaper(wallpaper, null);
wallpaper.wallpaperObserver = new WallpaperObserver(wallpaper);
wallpaper.wallpaperObserver.startWatching();
diff --git a/services/core/java/com/android/server/wm/AppTransition.java b/services/core/java/com/android/server/wm/AppTransition.java
index a57463c..7bd0635 100644
--- a/services/core/java/com/android/server/wm/AppTransition.java
+++ b/services/core/java/com/android/server/wm/AppTransition.java
@@ -559,6 +559,7 @@
set.addAnimation(clipAnimTB);
set.addAnimation(translateY);
set.addAnimation(alpha);
+ set.setZAdjustment(Animation.ZORDER_TOP);
set.initialize(appWidth, appHeight, appWidth, appHeight);
anim = set;
} else {
diff --git a/services/core/java/com/android/server/wm/DimLayer.java b/services/core/java/com/android/server/wm/DimLayer.java
index e385be3..538d6b84 100644
--- a/services/core/java/com/android/server/wm/DimLayer.java
+++ b/services/core/java/com/android/server/wm/DimLayer.java
@@ -29,9 +29,6 @@
private static final String TAG = "DimLayer";
private static final boolean DEBUG = false;
- /** Reference to the owner of this object. */
- final DisplayContent mDisplayContent;
-
/** Actual surface that dims */
SurfaceControl mDimSurface;
@@ -62,13 +59,18 @@
/** Time in milliseconds to take to transition from mStartAlpha to mTargetAlpha */
long mDuration;
- /** Owning stack */
- final TaskStack mStack;
+ /** Interface implemented by users of the dim layer */
+ interface DimLayerUser {
+ /** Returns true if the user of the dim layer is fullscreen. */
+ boolean isFullscreen();
+ /** Returns the display info. of the dim layer user. */
+ DisplayInfo getDisplayInfo();
+ }
+ /** The user of this dim layer. */
+ final DimLayerUser mUser;
- DimLayer(WindowManagerService service, TaskStack stack, DisplayContent displayContent) {
- mStack = stack;
- mDisplayContent = displayContent;
- final int displayId = mDisplayContent.getDisplayId();
+ DimLayer(WindowManagerService service, DimLayerUser user, int displayId) {
+ mUser = user;
if (DEBUG) Slog.v(TAG, "Ctor: displayId=" + displayId);
SurfaceControl.openTransaction();
try {
@@ -145,14 +147,14 @@
private void adjustBounds() {
final int dw, dh;
final float xPos, yPos;
- if (!mStack.isFullscreen()) {
+ if (!mUser.isFullscreen()) {
dw = mBounds.width();
dh = mBounds.height();
xPos = mBounds.left;
yPos = mBounds.top;
} else {
// Set surface size to screen size.
- final DisplayInfo info = mDisplayContent.getDisplayInfo();
+ final DisplayInfo info = mUser.getDisplayInfo();
// Multiply by 1.5 so that rotating a frozen surface that includes this does not expose
// a corner.
dw = (int) (info.logicalWidth * 1.5);
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index 5d6df26..fcf743e 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -16,7 +16,8 @@
package com.android.server.wm;
-import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID;
+import static android.app.ActivityManager.HOME_STACK_ID;
+
import static com.android.server.wm.WindowManagerService.DEBUG_VISIBILITY;
import static com.android.server.wm.WindowManagerService.TAG;
@@ -89,8 +90,8 @@
* (except a future lockscreen TaskStack) moves to the top. */
private TaskStack mHomeStack = null;
- /** Detect user tapping outside of current focused stack bounds .*/
- StackTapPointerEventListener mTapDetector;
+ /** Detect user tapping outside of current focused task bounds .*/
+ TaskTapPointerEventListener mTapDetector;
/** Detect user tapping outside of current focused stack bounds .*/
Region mTouchExcludeRegion = new Region();
@@ -190,15 +191,19 @@
out.set(left, top, left + width, top + height);
}
- /** Refer to {@link WindowManagerService#attachStack(int, int)} */
- void attachStack(TaskStack stack) {
+ /** Refer to {@link WindowManagerService#attachStack(int, int, boolean)} */
+ void attachStack(TaskStack stack, boolean onTop) {
if (stack.mStackId == HOME_STACK_ID) {
if (mHomeStack != null) {
throw new IllegalArgumentException("attachStack: HOME_STACK_ID (0) not first.");
}
mHomeStack = stack;
}
- mStacks.add(stack);
+ if (onTop) {
+ mStacks.add(stack);
+ } else {
+ mStacks.add(0, stack);
+ }
layoutNeeded = true;
}
@@ -219,24 +224,27 @@
mContentRect.set(contentRect);
}
- int stackIdFromPoint(int x, int y) {
+ int taskIdFromPoint(int x, int y) {
for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
- final TaskStack stack = mStacks.get(stackNdx);
- stack.getBounds(mTmpRect);
- if (mTmpRect.contains(x, y)) {
- return stack.mStackId;
+ final ArrayList<Task> tasks = mStacks.get(stackNdx).getTasks();
+ for (int taskNdx = tasks.size() - 1; taskNdx >= 0; --taskNdx) {
+ final Task task = tasks.get(taskNdx);
+ task.getBounds(mTmpRect);
+ if (mTmpRect.contains(x, y)) {
+ return task.mTaskId;
+ }
}
}
return -1;
}
- void setTouchExcludeRegion(TaskStack focusedStack) {
+ void setTouchExcludeRegion(Task focusedTask) {
mTouchExcludeRegion.set(mBaseDisplayRect);
WindowList windows = getWindowList();
for (int i = windows.size() - 1; i >= 0; --i) {
final WindowState win = windows.get(i);
- final TaskStack stack = win.getStack();
- if (win.isVisibleLw() && stack != null && stack != focusedStack) {
+ final Task task = win.getTask();
+ if (win.isVisibleLw() && task != null && task != focusedTask) {
mTmpRect.set(win.mVisibleFrame);
// If no intersection, we need mTmpRect to be unmodified.
mTmpRect.intersect(win.mVisibleInsets);
@@ -273,21 +281,37 @@
boolean animateDimLayers() {
boolean result = false;
for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
- result |= mStacks.get(stackNdx).animateDimLayers();
+ final ArrayList<Task> tasks = mStacks.get(stackNdx).getTasks();
+ for (int taskNdx = tasks.size() - 1; taskNdx >= 0; --taskNdx) {
+ final Task task = tasks.get(taskNdx);
+ result |= task.animateDimLayers();
+ if (task.isFullscreen()) {
+ // No point in continuing as this task covers the entire screen.
+ // Also, fullscreen tasks all share the same dim layer, so we don't want
+ // processing of fullscreen task below this one affecting the dim layer state.
+ return result;
+ }
+ }
}
return result;
}
void resetDimming() {
for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
- mStacks.get(stackNdx).resetDimmingTag();
+ final ArrayList<Task> tasks = mStacks.get(stackNdx).getTasks();
+ for (int taskNdx = tasks.size() - 1; taskNdx >= 0; --taskNdx) {
+ tasks.get(taskNdx).clearContinueDimming();
+ }
}
}
boolean isDimming() {
for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
- if (mStacks.get(stackNdx).isDimming()) {
- return true;
+ final ArrayList<Task> tasks = mStacks.get(stackNdx).getTasks();
+ for (int taskNdx = tasks.size() - 1; taskNdx >= 0; --taskNdx) {
+ if (tasks.get(taskNdx).isDimming()) {
+ return true;
+ }
}
}
return false;
@@ -295,7 +319,10 @@
void stopDimmingIfNeeded() {
for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
- mStacks.get(stackNdx).stopDimmingIfNeeded();
+ final ArrayList<Task> tasks = mStacks.get(stackNdx).getTasks();
+ for (int taskNdx = tasks.size() - 1; taskNdx >= 0; --taskNdx) {
+ tasks.get(taskNdx).stopDimmingIfNeeded();
+ }
}
}
diff --git a/services/core/java/com/android/server/wm/DragState.java b/services/core/java/com/android/server/wm/DragState.java
index 1a125d4..222945c 100644
--- a/services/core/java/com/android/server/wm/DragState.java
+++ b/services/core/java/com/android/server/wm/DragState.java
@@ -413,7 +413,7 @@
continue;
}
- child.getStackBounds(mTmpRect);
+ child.getTaskBounds(mTmpRect);
if (!mTmpRect.contains(x, y)) {
// outside of this window's activity stack == don't tell about drags
continue;
diff --git a/services/core/java/com/android/server/wm/FocusedStackFrame.java b/services/core/java/com/android/server/wm/FocusedStackFrame.java
deleted file mode 100644
index 826fe97..0000000
--- a/services/core/java/com/android/server/wm/FocusedStackFrame.java
+++ /dev/null
@@ -1,146 +0,0 @@
-/*
- * 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.
- */
-
-package com.android.server.wm;
-
-import static com.android.server.wm.WindowManagerService.DEBUG_SURFACE_TRACE;
-import static com.android.server.wm.WindowManagerService.SHOW_LIGHT_TRANSACTIONS;
-
-import android.graphics.Canvas;
-import android.graphics.Color;
-import android.graphics.Paint;
-import android.graphics.PixelFormat;
-import android.graphics.Rect;
-import android.util.Slog;
-import android.view.Display;
-import android.view.Surface.OutOfResourcesException;
-import android.view.Surface;
-import android.view.SurfaceControl;
-import android.view.SurfaceSession;
-
-import com.android.server.wm.WindowStateAnimator.SurfaceTrace;
-
-class FocusedStackFrame {
- private static final String TAG = "FocusedStackFrame";
- private static final boolean DEBUG = false;
- private static final int THICKNESS = 2;
- private static final float ALPHA = 0.3f;
-
- private final SurfaceControl mSurfaceControl;
- private final Surface mSurface = new Surface();
- private final Paint mInnerPaint = new Paint();
- private final Paint mOuterPaint = new Paint();
- private final Rect mBounds = new Rect();
- private final Rect mLastBounds = new Rect();
- private int mLayer = -1;
-
- public FocusedStackFrame(Display display, SurfaceSession session) {
- SurfaceControl ctrl = null;
- try {
- if (DEBUG_SURFACE_TRACE) {
- ctrl = new SurfaceTrace(session, "FocusedStackFrame",
- 1, 1, PixelFormat.TRANSLUCENT, SurfaceControl.HIDDEN);
- } else {
- ctrl = new SurfaceControl(session, "FocusedStackFrame",
- 1, 1, PixelFormat.TRANSLUCENT, SurfaceControl.HIDDEN);
- }
- ctrl.setLayerStack(display.getLayerStack());
- ctrl.setAlpha(ALPHA);
- mSurface.copyFrom(ctrl);
- } catch (OutOfResourcesException e) {
- }
- mSurfaceControl = ctrl;
-
- mInnerPaint.setStyle(Paint.Style.STROKE);
- mInnerPaint.setStrokeWidth(THICKNESS);
- mInnerPaint.setColor(Color.WHITE);
- mOuterPaint.setStyle(Paint.Style.STROKE);
- mOuterPaint.setStrokeWidth(THICKNESS);
- mOuterPaint.setColor(Color.BLACK);
- }
-
- private void draw() {
- if (mLastBounds.isEmpty()) {
- // Currently unset. Set it.
- mLastBounds.set(mBounds);
- }
-
- if (DEBUG) Slog.i(TAG, "draw: mBounds=" + mBounds + " mLastBounds=" + mLastBounds);
-
- Canvas c = null;
- try {
- c = mSurface.lockCanvas(mLastBounds);
- } catch (IllegalArgumentException e) {
- Slog.e(TAG, "Unable to lock canvas", e);
- } catch (Surface.OutOfResourcesException e) {
- Slog.e(TAG, "Unable to lock canvas", e);
- }
- if (c == null) {
- if (DEBUG) Slog.w(TAG, "Canvas is null...");
- return;
- }
-
- c.drawRect(0, 0, mBounds.width(), mBounds.height(), mOuterPaint);
- c.drawRect(THICKNESS, THICKNESS, mBounds.width() - THICKNESS, mBounds.height() - THICKNESS,
- mInnerPaint);
- if (DEBUG) Slog.w(TAG, "c.width=" + c.getWidth() + " c.height=" + c.getHeight()
- + " c.clip=" + c .getClipBounds());
- mSurface.unlockCanvasAndPost(c);
- mLastBounds.set(mBounds);
- }
-
- private void setupSurface(boolean visible) {
- if (mSurfaceControl == null) {
- return;
- }
- if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG, ">>> OPEN TRANSACTION setupSurface");
- SurfaceControl.openTransaction();
- try {
- if (visible) {
- mSurfaceControl.setPosition(mBounds.left, mBounds.top);
- mSurfaceControl.setSize(mBounds.width(), mBounds.height());
- mSurfaceControl.show();
- } else {
- mSurfaceControl.hide();
- }
- } finally {
- SurfaceControl.closeTransaction();
- if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG, ">>> CLOSE TRANSACTION setupSurface");
- }
- }
-
- void setVisibility(TaskStack stack) {
- if (stack == null || stack.isFullscreen()) {
- setupSurface(false);
- } else {
- stack.getBounds(mBounds);
- setupSurface(true);
- if (!mBounds.equals(mLastBounds)) {
- draw();
- }
- }
- }
-
- // Note: caller responsible for being inside
- // Surface.openTransaction() / closeTransaction()
- void setLayer(int layer) {
- if (mLayer == layer) {
- return;
- }
- mLayer = layer;
- mSurfaceControl.setLayer(mLayer);
- }
-}
diff --git a/services/core/java/com/android/server/wm/InputMonitor.java b/services/core/java/com/android/server/wm/InputMonitor.java
index ae442e5..21e92c9 100644
--- a/services/core/java/com/android/server/wm/InputMonitor.java
+++ b/services/core/java/com/android/server/wm/InputMonitor.java
@@ -177,7 +177,7 @@
if (modal && child.mAppToken != null) {
// Limit the outer touch to the activity stack region.
flags |= WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;
- child.getStackBounds(mTmpRect);
+ child.getTaskBounds(mTmpRect);
inputWindowHandle.touchableRegion.set(mTmpRect);
} else {
// Not modal or full screen modal
diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java
index 0c3cf65..3ff5be1 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -17,13 +17,29 @@
package com.android.server.wm;
import static com.android.server.wm.WindowManagerService.TAG;
+import static com.android.server.wm.WindowManagerService.DEBUG_RESIZE;
import static com.android.server.wm.WindowManagerService.DEBUG_STACK;
+import android.content.res.Configuration;
+import android.graphics.Rect;
+import android.util.DisplayMetrics;
import android.util.EventLog;
import android.util.Slog;
+import android.util.SparseArray;
+import android.util.TypedValue;
+import android.view.DisplayInfo;
+import android.view.Surface;
+
import com.android.server.EventLogTags;
-class Task {
+import java.io.PrintWriter;
+import java.util.ArrayList;
+
+class Task implements DimLayer.DimLayerUser {
+ /** Amount of time in milliseconds to animate the dim surface from one value to another,
+ * when no window animation is driving it. */
+ private static final int DEFAULT_DIM_DURATION = 200;
+
TaskStack mStack;
final AppTokenList mAppTokens = new AppTokenList();
final int mTaskId;
@@ -31,11 +47,42 @@
boolean mDeferRemoval = false;
final WindowManagerService mService;
- Task(int taskId, TaskStack stack, int userId, WindowManagerService service) {
+ // Content limits relative to the DisplayContent this sits in.
+ private Rect mBounds = new Rect();
+
+ // Device rotation as of the last time {@link #mBounds} was set.
+ int mRotation;
+
+ // Whether mBounds is fullscreen
+ private boolean mFullscreen = true;
+
+ // Contains configurations settings that are different from the global configuration due to
+ // stack specific operations. E.g. {@link #setBounds}.
+ Configuration mOverrideConfig;
+
+ // For comparison with DisplayContent bounds.
+ private Rect mTmpRect = new Rect();
+ // For handling display rotations.
+ private Rect mTmpRect2 = new Rect();
+
+ // The particular window with FLAG_DIM_BEHIND set. If null, hide mDimLayer.
+ WindowStateAnimator mDimWinAnimator;
+ // Used to support {@link android.view.WindowManager.LayoutParams#FLAG_DIM_BEHIND}
+ private DimLayer mDimLayer;
+ // Set to false at the start of performLayoutAndPlaceSurfaces. If it is still false by the end
+ // then stop any dimming.
+ private boolean mContinueDimming;
+ // Shared dim layer for fullscreen tasks. {@link #mDimLayer} will point to this instead
+ // of creating a new object per fullscreen task on a display.
+ private static final SparseArray<DimLayer> sSharedFullscreenDimLayers = new SparseArray<>();
+
+ Task(int taskId, TaskStack stack, int userId, WindowManagerService service, Rect bounds) {
mTaskId = taskId;
mStack = stack;
mUserId = userId;
mService = service;
+ mOverrideConfig = Configuration.EMPTY;
+ setBounds(bounds);
}
DisplayContent getDisplayContent() {
@@ -85,6 +132,16 @@
stack.addTask(this, toTop);
}
+ void positionTaskInStack(TaskStack stack, int position) {
+ if (mStack != null && stack != mStack) {
+ if (DEBUG_STACK) Slog.i(TAG, "positionTaskInStack: removing taskId=" + mTaskId
+ + " from stack=" + mStack);
+ EventLog.writeEvent(EventLogTags.WM_TASK_REMOVED, mTaskId, "moveTask");
+ mStack.removeTask(this);
+ }
+ stack.positionTask(this, position, showForAllUsers());
+ }
+
boolean removeAppToken(AppWindowToken wtoken) {
boolean removed = mAppTokens.remove(wtoken);
if (mAppTokens.size() == 0) {
@@ -107,13 +164,290 @@
}
}
+ /** Set the task bounds. Passing in null sets the bounds to fullscreen. */
+ boolean setBounds(Rect bounds) {
+ boolean oldFullscreen = mFullscreen;
+ int rotation = Surface.ROTATION_0;
+ final DisplayContent displayContent = mStack.getDisplayContent();
+ if (displayContent != null) {
+ displayContent.getLogicalDisplayRect(mTmpRect);
+ rotation = displayContent.getDisplayInfo().rotation;
+ if (bounds == null) {
+ bounds = mTmpRect;
+ mFullscreen = true;
+ } else {
+ // ensure bounds are entirely within the display rect
+ if (!bounds.intersect(mTmpRect)) {
+ // Can't set bounds outside the containing display...Sorry!
+ return false;
+ }
+ mFullscreen = mTmpRect.equals(bounds);
+ }
+ }
+
+ if (bounds == null) {
+ // Can't set to fullscreen if we don't have a display to get bounds from...
+ return false;
+ }
+ if (mBounds.equals(bounds) && oldFullscreen == mFullscreen && mRotation == rotation) {
+ return false;
+ }
+
+ mBounds.set(bounds);
+ mRotation = rotation;
+ updateDimLayer();
+ updateOverrideConfiguration();
+ return true;
+ }
+
+ void getBounds(Rect out) {
+ out.set(mBounds);
+ }
+
+ private void updateOverrideConfiguration() {
+ final Configuration serviceConfig = mService.mCurConfiguration;
+ if (mFullscreen) {
+ mOverrideConfig = Configuration.EMPTY;
+ return;
+ }
+
+ if (mOverrideConfig == Configuration.EMPTY) {
+ mOverrideConfig = new Configuration();
+ }
+
+ // TODO(multidisplay): Update Dp to that of display stack is on.
+ final float density = serviceConfig.densityDpi * DisplayMetrics.DENSITY_DEFAULT_SCALE;
+ mOverrideConfig.screenWidthDp =
+ Math.min((int)(mBounds.width() / density), serviceConfig.screenWidthDp);
+ mOverrideConfig.screenHeightDp =
+ Math.min((int)(mBounds.height() / density), serviceConfig.screenHeightDp);
+ mOverrideConfig.smallestScreenWidthDp =
+ Math.min(mOverrideConfig.screenWidthDp, mOverrideConfig.screenHeightDp);
+ mOverrideConfig.orientation =
+ (mOverrideConfig.screenWidthDp <= mOverrideConfig.screenHeightDp)
+ ? Configuration.ORIENTATION_PORTRAIT : Configuration.ORIENTATION_LANDSCAPE;
+ }
+
+ void updateDisplayInfo(final DisplayContent displayContent) {
+ if (displayContent == null) {
+ return;
+ }
+ if (mFullscreen) {
+ setBounds(null);
+ return;
+ }
+ final int newRotation = displayContent.getDisplayInfo().rotation;
+ if (mRotation == newRotation) {
+ return;
+ }
+
+ // Device rotation changed. We don't want the task to move around on the screen when
+ // this happens, so update the task bounds so it stays in the same place.
+ final int rotationDelta = DisplayContent.deltaRotation(mRotation, newRotation);
+ displayContent.getLogicalDisplayRect(mTmpRect);
+ switch (rotationDelta) {
+ case Surface.ROTATION_0:
+ mTmpRect2.set(mBounds);
+ break;
+ case Surface.ROTATION_90:
+ mTmpRect2.top = mTmpRect.bottom - mBounds.right;
+ mTmpRect2.left = mBounds.top;
+ mTmpRect2.right = mTmpRect2.left + mBounds.height();
+ mTmpRect2.bottom = mTmpRect2.top + mBounds.width();
+ break;
+ case Surface.ROTATION_180:
+ mTmpRect2.top = mTmpRect.bottom - mBounds.bottom;
+ mTmpRect2.left = mTmpRect.right - mBounds.right;
+ mTmpRect2.right = mTmpRect2.left + mBounds.width();
+ mTmpRect2.bottom = mTmpRect2.top + mBounds.height();
+ break;
+ case Surface.ROTATION_270:
+ mTmpRect2.top = mBounds.left;
+ mTmpRect2.left = mTmpRect.right - mBounds.bottom;
+ mTmpRect2.right = mTmpRect2.left + mBounds.height();
+ mTmpRect2.bottom = mTmpRect2.top + mBounds.width();
+ break;
+ }
+ setBounds(mTmpRect2);
+ }
+
+ /** Updates the dim layer bounds, recreating it if needed. */
+ private void updateDimLayer() {
+ DimLayer newDimLayer;
+ final boolean previousFullscreen =
+ mDimLayer != null && sSharedFullscreenDimLayers.indexOfValue(mDimLayer) > -1;
+ final int displayId = mStack.getDisplayContent().getDisplayId();
+ if (mFullscreen) {
+ if (previousFullscreen) {
+ // Nothing to do here...
+ return;
+ }
+ // Use shared fullscreen dim layer
+ newDimLayer = sSharedFullscreenDimLayers.get(displayId);
+ if (newDimLayer == null) {
+ if (mDimLayer != null) {
+ // Re-purpose the previous dim layer.
+ newDimLayer = mDimLayer;
+ } else {
+ // Create new full screen dim layer.
+ newDimLayer = new DimLayer(mService, this, displayId);
+ }
+ newDimLayer.setBounds(mBounds);
+ sSharedFullscreenDimLayers.put(displayId, newDimLayer);
+ } else if (mDimLayer != null) {
+ mDimLayer.destroySurface();
+ }
+ } else {
+ newDimLayer = (mDimLayer == null || previousFullscreen)
+ ? new DimLayer(mService, this, displayId) : mDimLayer;
+ newDimLayer.setBounds(mBounds);
+ }
+ mDimLayer = newDimLayer;
+ }
+
+ boolean animateDimLayers() {
+ final int dimLayer;
+ final float dimAmount;
+ if (mDimWinAnimator == null) {
+ dimLayer = mDimLayer.getLayer();
+ dimAmount = 0;
+ } else {
+ dimLayer = mDimWinAnimator.mAnimLayer - WindowManagerService.LAYER_OFFSET_DIM;
+ dimAmount = mDimWinAnimator.mWin.mAttrs.dimAmount;
+ }
+ final float targetAlpha = mDimLayer.getTargetAlpha();
+ if (targetAlpha != dimAmount) {
+ if (mDimWinAnimator == null) {
+ mDimLayer.hide(DEFAULT_DIM_DURATION);
+ } else {
+ long duration = (mDimWinAnimator.mAnimating && mDimWinAnimator.mAnimation != null)
+ ? mDimWinAnimator.mAnimation.computeDurationHint()
+ : DEFAULT_DIM_DURATION;
+ if (targetAlpha > dimAmount) {
+ duration = getDimBehindFadeDuration(duration);
+ }
+ mDimLayer.show(dimLayer, dimAmount, duration);
+ }
+ } else if (mDimLayer.getLayer() != dimLayer) {
+ mDimLayer.setLayer(dimLayer);
+ }
+ if (mDimLayer.isAnimating()) {
+ if (!mService.okToDisplay()) {
+ // Jump to the end of the animation.
+ mDimLayer.show();
+ } else {
+ return mDimLayer.stepAnimation();
+ }
+ }
+ return false;
+ }
+
+ private long getDimBehindFadeDuration(long duration) {
+ TypedValue tv = new TypedValue();
+ mService.mContext.getResources().getValue(
+ com.android.internal.R.fraction.config_dimBehindFadeDuration, tv, true);
+ if (tv.type == TypedValue.TYPE_FRACTION) {
+ duration = (long)tv.getFraction(duration, duration);
+ } else if (tv.type >= TypedValue.TYPE_FIRST_INT && tv.type <= TypedValue.TYPE_LAST_INT) {
+ duration = tv.data;
+ }
+ return duration;
+ }
+
+ void clearContinueDimming() {
+ mContinueDimming = false;
+ }
+
+ void setContinueDimming() {
+ mContinueDimming = true;
+ }
+
+ boolean getContinueDimming() {
+ return mContinueDimming;
+ }
+
+ boolean isDimming() {
+ return mDimLayer.isDimming();
+ }
+
+ boolean isDimming(WindowStateAnimator winAnimator) {
+ return mDimWinAnimator == winAnimator && isDimming();
+ }
+
+ void startDimmingIfNeeded(WindowStateAnimator newWinAnimator) {
+ // Only set dim params on the highest dimmed layer.
+ // Don't turn on for an unshown surface, or for any layer but the highest dimmed layer.
+ if (newWinAnimator.mSurfaceShown && (mDimWinAnimator == null
+ || !mDimWinAnimator.mSurfaceShown
+ || mDimWinAnimator.mAnimLayer < newWinAnimator.mAnimLayer)) {
+ mDimWinAnimator = newWinAnimator;
+ if (mDimWinAnimator.mWin.mAppToken == null
+ && !mFullscreen && mStack.getDisplayContent() != null) {
+ // Dim should cover the entire screen for system windows.
+ mStack.getDisplayContent().getLogicalDisplayRect(mTmpRect);
+ mDimLayer.setBounds(mTmpRect);
+ }
+ }
+ }
+
+ void stopDimmingIfNeeded() {
+ if (!mContinueDimming && isDimming()) {
+ mDimWinAnimator = null;
+ mDimLayer.setBounds(mBounds);
+ }
+ }
+
+ void close() {
+ if (mDimLayer != null) {
+ mDimLayer.destroySurface();
+ mDimLayer = null;
+ }
+ }
+
+ void resizeWindows() {
+ final ArrayList<WindowState> resizingWindows = mService.mResizingWindows;
+ for (int activityNdx = mAppTokens.size() - 1; activityNdx >= 0; --activityNdx) {
+ final ArrayList<WindowState> windows = mAppTokens.get(activityNdx).allAppWindows;
+ for (int winNdx = windows.size() - 1; winNdx >= 0; --winNdx) {
+ final WindowState win = windows.get(winNdx);
+ if (!resizingWindows.contains(win)) {
+ if (DEBUG_RESIZE) Slog.d(TAG, "setBounds: Resizing " + win);
+ resizingWindows.add(win);
+ }
+ }
+ }
+ }
+
boolean showForAllUsers() {
final int tokensCount = mAppTokens.size();
return (tokensCount != 0) && mAppTokens.get(tokensCount - 1).showForAllUsers;
}
@Override
+ public boolean isFullscreen() {
+ return mFullscreen;
+ }
+
+ @Override
+ public DisplayInfo getDisplayInfo() {
+ return mStack.getDisplayContent().getDisplayInfo();
+ }
+
+ @Override
public String toString() {
return "{taskId=" + mTaskId + " appTokens=" + mAppTokens + " mdr=" + mDeferRemoval + "}";
}
+
+ public void printTo(String prefix, PrintWriter pw) {
+ pw.print(prefix); pw.print("taskId="); pw.print(mTaskId);
+ pw.print(prefix); pw.print("appTokens="); pw.print(mAppTokens);
+ pw.print(prefix); pw.print("mdr="); pw.println(mDeferRemoval);
+ if (mDimLayer.isDimming()) {
+ pw.print(prefix); pw.println("mDimLayer:");
+ mDimLayer.printTo(prefix + " ", pw);
+ pw.print(prefix); pw.print("mDimWinAnimator="); pw.println(mDimWinAnimator);
+ } else {
+ pw.println();
+ }
+ }
}
diff --git a/services/core/java/com/android/server/wm/TaskStack.java b/services/core/java/com/android/server/wm/TaskStack.java
index 4545032..90d2593 100644
--- a/services/core/java/com/android/server/wm/TaskStack.java
+++ b/services/core/java/com/android/server/wm/TaskStack.java
@@ -22,22 +22,18 @@
import android.content.res.Configuration;
import android.graphics.Rect;
import android.os.Debug;
-import android.util.DisplayMetrics;
import android.util.EventLog;
+import android.util.IntArray;
import android.util.Slog;
-import android.util.TypedValue;
-import android.view.Surface;
+import android.view.DisplayInfo;
import com.android.server.EventLogTags;
import java.io.PrintWriter;
import java.util.ArrayList;
+import java.util.List;
-public class TaskStack {
- /** Amount of time in milliseconds to animate the dim surface from one value to another,
- * when no window animation is driving it. */
- private static final int DEFAULT_DIM_DURATION = 200;
-
+public class TaskStack implements DimLayer.DimLayerUser {
/** Unique identifier */
final int mStackId;
@@ -49,12 +45,10 @@
/** The Tasks that define this stack. Oldest Tasks are at the bottom. The ordering must match
* mTaskHistory in the ActivityStack with the same mStackId */
- private final ArrayList<Task> mTasks = new ArrayList<Task>();
+ private final ArrayList<Task> mTasks = new ArrayList<>();
/** For comparison with DisplayContent bounds. */
private Rect mTmpRect = new Rect();
- /** For handling display rotations. */
- private Rect mTmpRect2 = new Rect();
/** Content limits relative to the DisplayContent this sits in. */
private Rect mBounds = new Rect();
@@ -62,49 +56,22 @@
/** Whether mBounds is fullscreen */
private boolean mFullscreen = true;
- /** Used to support {@link android.view.WindowManager.LayoutParams#FLAG_DIM_BEHIND} */
- private DimLayer mDimLayer;
-
- /** The particular window with FLAG_DIM_BEHIND set. If null, hide mDimLayer. */
- WindowStateAnimator mDimWinAnimator;
-
/** Support for non-zero {@link android.view.animation.Animation#getBackgroundColor()} */
DimLayer mAnimationBackgroundSurface;
/** The particular window with an Animation with non-zero background color. */
WindowStateAnimator mAnimationBackgroundAnimator;
- /** Set to false at the start of performLayoutAndPlaceSurfaces. If it is still false by the end
- * then stop any dimming. */
- boolean mDimmingTag;
-
/** Application tokens that are exiting, but still on screen for animations. */
final AppTokenList mExitingAppTokens = new AppTokenList();
/** Detach this stack from its display when animation completes. */
boolean mDeferDetach;
- // Contains configurations settings that are different from the global configuration due to
- // stack specific operations. E.g. {@link #setBounds}.
- Configuration mOverrideConfig;
- // True if the stack was forced to fullscreen disregarding the override configuration.
- private boolean mForceFullscreen;
- // The {@link #mBounds} before the stack was forced to fullscreen. Will be restored as the
- // stack bounds once the stack is no longer forced to fullscreen.
- final private Rect mPreForceFullscreenBounds;
-
- // Device rotation as of the last time {@link #mBounds} was set.
- int mRotation;
-
TaskStack(WindowManagerService service, int stackId) {
mService = service;
mStackId = stackId;
- mOverrideConfig = Configuration.EMPTY;
- mForceFullscreen = false;
- mPreForceFullscreenBounds = new Rect();
- // TODO: remove bounds from log, they are always 0.
- EventLog.writeEvent(EventLogTags.WM_STACK_CREATED, stackId, mBounds.left, mBounds.top,
- mBounds.right, mBounds.bottom);
+ EventLog.writeEvent(EventLogTags.WM_STACK_CREATED, stackId);
}
DisplayContent getDisplayContent() {
@@ -116,30 +83,39 @@
}
void resizeWindows() {
- final ArrayList<WindowState> resizingWindows = mService.mResizingWindows;
for (int taskNdx = mTasks.size() - 1; taskNdx >= 0; --taskNdx) {
- final ArrayList<AppWindowToken> activities = mTasks.get(taskNdx).mAppTokens;
- for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
- final ArrayList<WindowState> windows = activities.get(activityNdx).allAppWindows;
- for (int winNdx = windows.size() - 1; winNdx >= 0; --winNdx) {
- final WindowState win = windows.get(winNdx);
- if (!resizingWindows.contains(win)) {
- if (WindowManagerService.DEBUG_RESIZE) Slog.d(TAG,
- "setBounds: Resizing " + win);
- resizingWindows.add(win);
- }
- }
- }
+ mTasks.get(taskNdx).resizeWindows();
}
}
- /** Set the stack bounds. Passing in null sets the bounds to fullscreen. */
- boolean setBounds(Rect bounds) {
+ /**
+ * Set the bounds of the stack and its containing tasks.
+ * @param bounds New stack bounds. Passing in null sets the bounds to fullscreen.
+ * @param changedTaskIds Output list of Ids of tasks that changed in bounds.
+ * @param newTaskConfigs Output list of new Configuation of the tasks that changed.
+ * @return True if the stack bounds was changed.
+ * */
+ boolean setBounds(Rect bounds, IntArray changedTaskIds, List<Configuration> newTaskConfigs) {
+ if (!setBounds(bounds)) {
+ return false;
+ }
+
+ // Update bounds of containing tasks.
+ final Rect newBounds = mFullscreen ? null : mBounds;
+ for (int taskNdx = mTasks.size() - 1; taskNdx >= 0; --taskNdx) {
+ final Task task = mTasks.get(taskNdx);
+ if (task.setBounds(newBounds)) {
+ changedTaskIds.add(task.mTaskId);
+ newTaskConfigs.add(task.mOverrideConfig);
+ }
+ }
+ return true;
+ }
+
+ private boolean setBounds(Rect bounds) {
boolean oldFullscreen = mFullscreen;
- int rotation = Surface.ROTATION_0;
if (mDisplayContent != null) {
mDisplayContent.getLogicalDisplayRect(mTmpRect);
- rotation = mDisplayContent.getDisplayInfo().rotation;
if (bounds == null) {
bounds = mTmpRect;
mFullscreen = true;
@@ -157,15 +133,12 @@
// Can't set to fullscreen if we don't have a display to get bounds from...
return false;
}
- if (mBounds.equals(bounds) && oldFullscreen == mFullscreen && mRotation == rotation) {
+ if (mBounds.equals(bounds) && oldFullscreen == mFullscreen) {
return false;
}
- mDimLayer.setBounds(bounds);
mAnimationBackgroundSurface.setBounds(bounds);
mBounds.set(bounds);
- mRotation = rotation;
- updateOverrideConfiguration();
return true;
}
@@ -173,93 +146,12 @@
out.set(mBounds);
}
- private void updateOverrideConfiguration() {
- final Configuration serviceConfig = mService.mCurConfiguration;
- if (mFullscreen) {
- mOverrideConfig = Configuration.EMPTY;
- return;
- }
-
- if (mOverrideConfig == Configuration.EMPTY) {
- mOverrideConfig = new Configuration();
- }
-
- // TODO(multidisplay): Update Dp to that of display stack is on.
- final float density = serviceConfig.densityDpi * DisplayMetrics.DENSITY_DEFAULT_SCALE;
- mOverrideConfig.screenWidthDp =
- Math.min((int)(mBounds.width() / density), serviceConfig.screenWidthDp);
- mOverrideConfig.screenHeightDp =
- Math.min((int)(mBounds.height() / density), serviceConfig.screenHeightDp);
- mOverrideConfig.smallestScreenWidthDp =
- Math.min(mOverrideConfig.screenWidthDp, mOverrideConfig.screenHeightDp);
- mOverrideConfig.orientation =
- (mOverrideConfig.screenWidthDp <= mOverrideConfig.screenHeightDp)
- ? Configuration.ORIENTATION_PORTRAIT : Configuration.ORIENTATION_LANDSCAPE;
- }
-
void updateDisplayInfo() {
- if (mFullscreen) {
- setBounds(null);
- } else if (mDisplayContent != null) {
- final int newRotation = mDisplayContent.getDisplayInfo().rotation;
- if (mRotation == newRotation) {
- return;
+ if (mDisplayContent != null) {
+ setBounds(mFullscreen ? null : mBounds);
+ for (int taskNdx = mTasks.size() - 1; taskNdx >= 0; --taskNdx) {
+ mTasks.get(taskNdx).updateDisplayInfo(mDisplayContent);
}
-
- // Device rotation changed. We don't want the stack to move around on the screen when
- // this happens, so update the stack bounds so it stays in the same place.
- final int rotationDelta = DisplayContent.deltaRotation(mRotation, newRotation);
- mDisplayContent.getLogicalDisplayRect(mTmpRect);
- switch (rotationDelta) {
- case Surface.ROTATION_0:
- mTmpRect2.set(mBounds);
- break;
- case Surface.ROTATION_90:
- mTmpRect2.top = mTmpRect.bottom - mBounds.right;
- mTmpRect2.left = mBounds.top;
- mTmpRect2.right = mTmpRect2.left + mBounds.height();
- mTmpRect2.bottom = mTmpRect2.top + mBounds.width();
- break;
- case Surface.ROTATION_180:
- mTmpRect2.top = mTmpRect.bottom - mBounds.bottom;
- mTmpRect2.left = mTmpRect.right - mBounds.right;
- mTmpRect2.right = mTmpRect2.left + mBounds.width();
- mTmpRect2.bottom = mTmpRect2.top + mBounds.height();
- break;
- case Surface.ROTATION_270:
- mTmpRect2.top = mBounds.left;
- mTmpRect2.left = mTmpRect.right - mBounds.bottom;
- mTmpRect2.right = mTmpRect2.left + mBounds.height();
- mTmpRect2.bottom = mTmpRect2.top + mBounds.width();
- break;
- }
- setBounds(mTmpRect2);
- }
- }
-
- boolean isFullscreen() {
- return mFullscreen;
- }
-
- /** Forces the stack to fullscreen if input is true, else un-forces the stack from fullscreen.
- * Returns true if something happened.
- */
- boolean forceFullscreen(boolean forceFullscreen) {
- if (mForceFullscreen == forceFullscreen) {
- return false;
- }
- mForceFullscreen = forceFullscreen;
- if (forceFullscreen) {
- if (mFullscreen) {
- return false;
- }
- mPreForceFullscreenBounds.set(mBounds);
- return setBounds(null);
- } else {
- if (!mFullscreen || mPreForceFullscreenBounds.isEmpty()) {
- return false;
- }
- return setBounds(mPreForceFullscreenBounds);
}
}
@@ -290,33 +182,75 @@
* @param showForAllUsers Whether to show the task regardless of the current user.
*/
void addTask(Task task, boolean toTop, boolean showForAllUsers) {
- int stackNdx;
- if (!toTop) {
- stackNdx = 0;
+ positionTask(task, toTop ? mTasks.size() : 0, showForAllUsers);
+ }
+
+ void positionTask(Task task, int position, boolean showForAllUsers) {
+ final boolean canShowTask =
+ showForAllUsers || mService.isCurrentProfileLocked(task.mUserId);
+ mTasks.remove(task);
+ int stackSize = mTasks.size();
+ int minPosition = 0;
+ int maxPosition = stackSize;
+
+ if (canShowTask) {
+ minPosition = computeMinPosition(minPosition, stackSize);
} else {
- stackNdx = mTasks.size();
- if (!showForAllUsers && !mService.isCurrentProfileLocked(task.mUserId)) {
- // Place the task below all current user tasks.
- while (--stackNdx >= 0) {
- final Task tmpTask = mTasks.get(stackNdx);
- if (!tmpTask.showForAllUsers()
- || !mService.isCurrentProfileLocked(tmpTask.mUserId)) {
- break;
- }
- }
- // Put it above first non-current user task.
- ++stackNdx;
- }
+ maxPosition = computeMaxPosition(maxPosition);
}
- if (DEBUG_TASK_MOVEMENT) Slog.d(TAG, "addTask: task=" + task + " toTop=" + toTop
- + " pos=" + stackNdx);
- mTasks.add(stackNdx, task);
+ // Reset position based on minimum/maximum possible positions.
+ position = Math.min(Math.max(position, minPosition), maxPosition);
+
+ if (DEBUG_TASK_MOVEMENT) Slog.d(TAG,
+ "positionTask: task=" + task + " position=" + position);
+ mTasks.add(position, task);
task.mStack = this;
+ task.updateDisplayInfo(mDisplayContent);
+ boolean toTop = position == mTasks.size() - 1;
if (toTop) {
mDisplayContent.moveStack(this, true);
}
- EventLog.writeEvent(EventLogTags.WM_TASK_MOVED, task.mTaskId, toTop ? 1 : 0, stackNdx);
+ EventLog.writeEvent(EventLogTags.WM_TASK_MOVED, task.mTaskId, toTop ? 1 : 0, position);
+ }
+
+ /** Calculate the minimum possible position for a task that can be shown to the user.
+ * The minimum position will be above all other tasks that can't be shown.
+ * @param minPosition The minimum position the caller is suggesting.
+ * We will start adjusting up from here.
+ * @param size The size of the current task list.
+ */
+ private int computeMinPosition(int minPosition, int size) {
+ while (minPosition < size) {
+ final Task tmpTask = mTasks.get(minPosition);
+ final boolean canShowTmpTask =
+ tmpTask.showForAllUsers()
+ || mService.isCurrentProfileLocked(tmpTask.mUserId);
+ if (canShowTmpTask) {
+ break;
+ }
+ minPosition++;
+ }
+ return minPosition;
+ }
+
+ /** Calculate the maximum possible position for a task that can't be shown to the user.
+ * The maximum position will be below all other tasks that can be shown.
+ * @param maxPosition The maximum position the caller is suggesting.
+ * We will start adjusting down from here.
+ */
+ private int computeMaxPosition(int maxPosition) {
+ while (maxPosition > 0) {
+ final Task tmpTask = mTasks.get(maxPosition - 1);
+ final boolean canShowTmpTask =
+ tmpTask.showForAllUsers()
+ || mService.isCurrentProfileLocked(tmpTask.mUserId);
+ if (!canShowTmpTask) {
+ break;
+ }
+ maxPosition--;
+ }
+ return maxPosition;
}
void moveTaskToTop(Task task) {
@@ -361,8 +295,7 @@
}
mDisplayContent = displayContent;
- mDimLayer = new DimLayer(mService, this, displayContent);
- mAnimationBackgroundSurface = new DimLayer(mService, this, displayContent);
+ mAnimationBackgroundSurface = new DimLayer(mService, this, mDisplayContent.getDisplayId());
updateDisplayInfo();
}
@@ -394,98 +327,6 @@
mAnimationBackgroundSurface.hide();
}
- private long getDimBehindFadeDuration(long duration) {
- TypedValue tv = new TypedValue();
- mService.mContext.getResources().getValue(
- com.android.internal.R.fraction.config_dimBehindFadeDuration, tv, true);
- if (tv.type == TypedValue.TYPE_FRACTION) {
- duration = (long)tv.getFraction(duration, duration);
- } else if (tv.type >= TypedValue.TYPE_FIRST_INT && tv.type <= TypedValue.TYPE_LAST_INT) {
- duration = tv.data;
- }
- return duration;
- }
-
- boolean animateDimLayers() {
- final int dimLayer;
- final float dimAmount;
- if (mDimWinAnimator == null) {
- dimLayer = mDimLayer.getLayer();
- dimAmount = 0;
- } else {
- dimLayer = mDimWinAnimator.mAnimLayer - WindowManagerService.LAYER_OFFSET_DIM;
- dimAmount = mDimWinAnimator.mWin.mAttrs.dimAmount;
- }
- final float targetAlpha = mDimLayer.getTargetAlpha();
- if (targetAlpha != dimAmount) {
- if (mDimWinAnimator == null) {
- mDimLayer.hide(DEFAULT_DIM_DURATION);
- } else {
- long duration = (mDimWinAnimator.mAnimating && mDimWinAnimator.mAnimation != null)
- ? mDimWinAnimator.mAnimation.computeDurationHint()
- : DEFAULT_DIM_DURATION;
- if (targetAlpha > dimAmount) {
- duration = getDimBehindFadeDuration(duration);
- }
- mDimLayer.show(dimLayer, dimAmount, duration);
- }
- } else if (mDimLayer.getLayer() != dimLayer) {
- mDimLayer.setLayer(dimLayer);
- }
- if (mDimLayer.isAnimating()) {
- if (!mService.okToDisplay()) {
- // Jump to the end of the animation.
- mDimLayer.show();
- } else {
- return mDimLayer.stepAnimation();
- }
- }
- return false;
- }
-
- void resetDimmingTag() {
- mDimmingTag = false;
- }
-
- void setDimmingTag() {
- mDimmingTag = true;
- }
-
- boolean testDimmingTag() {
- return mDimmingTag;
- }
-
- boolean isDimming() {
- return mDimLayer.isDimming();
- }
-
- boolean isDimming(WindowStateAnimator winAnimator) {
- return mDimWinAnimator == winAnimator && mDimLayer.isDimming();
- }
-
- void startDimmingIfNeeded(WindowStateAnimator newWinAnimator) {
- // Only set dim params on the highest dimmed layer.
- // Don't turn on for an unshown surface, or for any layer but the highest dimmed layer.
- if (newWinAnimator.mSurfaceShown && (mDimWinAnimator == null
- || !mDimWinAnimator.mSurfaceShown
- || mDimWinAnimator.mAnimLayer < newWinAnimator.mAnimLayer)) {
- mDimWinAnimator = newWinAnimator;
- if (mDimWinAnimator.mWin.mAppToken == null
- && !mFullscreen && mDisplayContent != null) {
- // Dim should cover the entire screen for system windows.
- mDisplayContent.getLogicalDisplayRect(mTmpRect);
- mDimLayer.setBounds(mTmpRect);
- }
- }
- }
-
- void stopDimmingIfNeeded() {
- if (!mDimmingTag && isDimming()) {
- mDimWinAnimator = null;
- mDimLayer.setBounds(mBounds);
- }
- }
-
void setAnimationBackground(WindowStateAnimator winAnimator, int color) {
int animLayer = winAnimator.mAnimLayer;
if (mAnimationBackgroundAnimator == null
@@ -514,9 +355,8 @@
mAnimationBackgroundSurface.destroySurface();
mAnimationBackgroundSurface = null;
}
- if (mDimLayer != null) {
- mDimLayer.destroySurface();
- mDimLayer = null;
+ for (int taskNdx = mTasks.size() - 1; taskNdx >= 0; --taskNdx) {
+ mTasks.get(taskNdx).close();
}
}
@@ -524,21 +364,17 @@
pw.print(prefix); pw.print("mStackId="); pw.println(mStackId);
pw.print(prefix); pw.print("mDeferDetach="); pw.println(mDeferDetach);
for (int taskNdx = 0; taskNdx < mTasks.size(); ++taskNdx) {
- pw.print(prefix); pw.println(mTasks.get(taskNdx));
+ pw.print(prefix);
+ mTasks.get(taskNdx).printTo(prefix + " ", pw);
}
if (mAnimationBackgroundSurface.isDimming()) {
pw.print(prefix); pw.println("mWindowAnimationBackgroundSurface:");
mAnimationBackgroundSurface.printTo(prefix + " ", pw);
}
- if (mDimLayer.isDimming()) {
- pw.print(prefix); pw.println("mDimLayer:");
- mDimLayer.printTo(prefix + " ", pw);
- pw.print(prefix); pw.print("mDimWinAnimator="); pw.println(mDimWinAnimator);
- }
if (!mExitingAppTokens.isEmpty()) {
pw.println();
pw.println(" Exiting application tokens:");
- for (int i=mExitingAppTokens.size()-1; i>=0; i--) {
+ for (int i = mExitingAppTokens.size() - 1; i >= 0; i--) {
WindowToken token = mExitingAppTokens.get(i);
pw.print(" Exiting App #"); pw.print(i);
pw.print(' '); pw.print(token);
@@ -549,6 +385,16 @@
}
@Override
+ public boolean isFullscreen() {
+ return mFullscreen;
+ }
+
+ @Override
+ public DisplayInfo getDisplayInfo() {
+ return mDisplayContent.getDisplayInfo();
+ }
+
+ @Override
public String toString() {
return "{stackId=" + mStackId + " tasks=" + mTasks + "}";
}
diff --git a/services/core/java/com/android/server/wm/StackTapPointerEventListener.java b/services/core/java/com/android/server/wm/TaskTapPointerEventListener.java
similarity index 95%
rename from services/core/java/com/android/server/wm/StackTapPointerEventListener.java
rename to services/core/java/com/android/server/wm/TaskTapPointerEventListener.java
index 1a85993..c97d12f 100644
--- a/services/core/java/com/android/server/wm/StackTapPointerEventListener.java
+++ b/services/core/java/com/android/server/wm/TaskTapPointerEventListener.java
@@ -23,7 +23,7 @@
import com.android.server.wm.WindowManagerService.H;
-public class StackTapPointerEventListener implements PointerEventListener {
+public class TaskTapPointerEventListener implements PointerEventListener {
private static final int TAP_TIMEOUT_MSEC = 300;
private static final float TAP_MOTION_SLOP_INCHES = 0.125f;
@@ -35,7 +35,7 @@
private final WindowManagerService mService;
private final DisplayContent mDisplayContent;
- public StackTapPointerEventListener(WindowManagerService service,
+ public TaskTapPointerEventListener(WindowManagerService service,
DisplayContent displayContent) {
mService = service;
mDisplayContent = displayContent;
@@ -77,7 +77,7 @@
&& Math.abs(x - mDownX) < mMotionSlop
&& Math.abs(y - mDownY) < mMotionSlop
&& !mTouchExcludeRegion.contains(x, y)) {
- mService.mH.obtainMessage(H.TAP_OUTSIDE_STACK, x, y,
+ mService.mH.obtainMessage(H.TAP_OUTSIDE_TASK, x, y,
mDisplayContent).sendToTarget();
}
}
diff --git a/services/core/java/com/android/server/wm/WindowAnimator.java b/services/core/java/com/android/server/wm/WindowAnimator.java
index 85a9624..7578256 100644
--- a/services/core/java/com/android/server/wm/WindowAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowAnimator.java
@@ -709,8 +709,6 @@
mService.scheduleAnimationLocked();
}
- mService.setFocusedStackLayer();
-
if (mService.mWatermark != null) {
mService.mWatermark.drawIfNeeded();
}
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 2647244..3d7b499 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -70,6 +70,7 @@
import android.util.ArraySet;
import android.util.DisplayMetrics;
import android.util.EventLog;
+import android.util.IntArray;
import android.util.Log;
import android.util.Pair;
import android.util.Slog;
@@ -155,7 +156,6 @@
import static android.view.WindowManager.LayoutParams.FIRST_SUB_WINDOW;
import static android.view.WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
import static android.view.WindowManager.LayoutParams.FLAG_DIM_BEHIND;
-import static android.view.WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS;
import static android.view.WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON;
import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
import static android.view.WindowManager.LayoutParams.FLAG_SECURE;
@@ -184,7 +184,6 @@
import static android.view.WindowManager.LayoutParams.TYPE_VOICE_INTERACTION;
import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
import static android.view.WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
-import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID;
/** {@hide} */
public class WindowManagerService extends IWindowManager.Stub
@@ -251,11 +250,6 @@
static final int LAYER_OFFSET_DIM = 1;
/**
- * FocusedStackFrame layer is immediately above focused window.
- */
- static final int LAYER_OFFSET_FOCUSED_STACK = 1;
-
- /**
* Animation thumbnail is as far as possible below the window above
* the thumbnail (or in other words as far as possible above the window
* below it).
@@ -328,7 +322,7 @@
* Users that are profiles of the current user. These are also allowed to show windows
* on the current user.
*/
- int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER};
+ int[] mCurrentProfileIds = new int[] {};
final Context mContext;
@@ -446,9 +440,6 @@
StrictModeFlash mStrictModeFlash;
CircularDisplayMask mCircularDisplayMask;
EmulatorDisplayOverlay mEmulatorDisplayOverlay;
- FocusedStackFrame mFocusedStackFrame;
-
- int mFocusedStackLayer;
final float[] mTmpFloats = new float[9];
final Rect mTmpContentRect = new Rect();
@@ -991,8 +982,6 @@
SurfaceControl.openTransaction();
try {
createWatermarkInTransaction();
- mFocusedStackFrame = new FocusedStackFrame(
- getDefaultDisplayContentLocked().getDisplay(), mFxSession);
} finally {
SurfaceControl.closeTransaction();
}
@@ -2658,6 +2647,16 @@
return disabled;
}
+ boolean isSecureLocked(WindowState w) {
+ if ((w.mAttrs.flags&WindowManager.LayoutParams.FLAG_SECURE) != 0) {
+ return true;
+ }
+ if (isScreenCaptureDisabledLocked(UserHandle.getUserId(w.mOwnerUid))) {
+ return true;
+ }
+ return false;
+ }
+
/**
* Set mScreenCaptureDisabled for specific user
*/
@@ -3169,6 +3168,9 @@
boolean wallpaperMayMove = win.mViewVisibility != viewVisibility
&& (win.mAttrs.flags & FLAG_SHOW_WALLPAPER) != 0;
wallpaperMayMove |= (flagChanges & FLAG_SHOW_WALLPAPER) != 0;
+ if ((flagChanges & FLAG_SECURE) != 0 && winAnimator.mSurfaceControl != null) {
+ winAnimator.mSurfaceControl.setSecure(isSecureLocked(win));
+ }
win.mRelayoutCalled = true;
final int oldVisibility = win.mViewVisibility;
@@ -3685,24 +3687,26 @@
Binder.restoreCallingIdentity(origId);
}
- private Task createTaskLocked(int taskId, int stackId, int userId, AppWindowToken atoken) {
+ private Task createTaskLocked(
+ int taskId, int stackId, int userId, AppWindowToken atoken, Rect bounds) {
if (DEBUG_STACK) Slog.i(TAG, "createTaskLocked: taskId=" + taskId + " stackId=" + stackId
- + " atoken=" + atoken);
+ + " atoken=" + atoken + " bounds=" + bounds);
final TaskStack stack = mStackIdToStack.get(stackId);
if (stack == null) {
throw new IllegalArgumentException("addAppToken: invalid stackId=" + stackId);
}
EventLog.writeEvent(EventLogTags.WM_TASK_CREATED, taskId, stackId);
- Task task = new Task(taskId, stack, userId, this);
+ Task task = new Task(taskId, stack, userId, this, bounds);
mTaskIdToTask.put(taskId, task);
stack.addTask(task, !atoken.mLaunchTaskBehind /* toTop */, atoken.showForAllUsers);
return task;
}
@Override
- public void addAppToken(int addPos, IApplicationToken token, int taskId, int stackId,
+ public Configuration addAppToken(int addPos, IApplicationToken token, int taskId, int stackId,
int requestedOrientation, boolean fullscreen, boolean showForAllUsers, int userId,
- int configChanges, boolean voiceInteraction, boolean launchTaskBehind) {
+ int configChanges, boolean voiceInteraction, boolean launchTaskBehind,
+ Rect taskBounds) {
if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
"addAppToken()")) {
throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
@@ -3726,7 +3730,7 @@
AppWindowToken atoken = findAppWindowToken(token.asBinder());
if (atoken != null) {
Slog.w(TAG, "Attempted to add existing app token: " + token);
- return;
+ return null;
}
atoken = new AppWindowToken(this, token, voiceInteraction);
atoken.inputDispatchingTimeoutNanos = inputDispatchingTimeoutNanos;
@@ -3740,8 +3744,10 @@
+ " to stack=" + stackId + " task=" + taskId + " at " + addPos);
Task task = mTaskIdToTask.get(taskId);
+ Configuration outConfig = null;
if (task == null) {
- task = createTaskLocked(taskId, stackId, userId, atoken);
+ task = createTaskLocked(taskId, stackId, userId, atoken, taskBounds);
+ outConfig = task.mOverrideConfig;
}
task.addAppToken(addPos, atoken);
@@ -3751,12 +3757,12 @@
atoken.hidden = true;
atoken.hiddenRequested = true;
- //dump();
+ return outConfig;
}
}
@Override
- public void setAppTask(IBinder token, int taskId) {
+ public Configuration setAppTask(IBinder token, int taskId, Rect taskBounds) {
if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
"setAppTask()")) {
throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
@@ -3766,17 +3772,20 @@
final AppWindowToken atoken = findAppWindowToken(token);
if (atoken == null) {
Slog.w(TAG, "Attempted to set task id of non-existing app token: " + token);
- return;
+ return null;
}
final Task oldTask = atoken.mTask;
oldTask.removeAppToken(atoken);
Task newTask = mTaskIdToTask.get(taskId);
+ Configuration outConfig = null;
if (newTask == null) {
- newTask =
- createTaskLocked(taskId, oldTask.mStack.mStackId, oldTask.mUserId, atoken);
+ newTask = createTaskLocked(
+ taskId, oldTask.mStack.mStackId, oldTask.mUserId, atoken, taskBounds);
+ outConfig = newTask.mOverrideConfig;
}
newTask.addAppToken(Integer.MAX_VALUE /* at top */, atoken);
+ return outConfig;
}
}
@@ -4062,38 +4071,14 @@
}
}
- /** Call while in a Surface transaction. */
- void setFocusedStackLayer() {
- mFocusedStackLayer = 0;
- if (mFocusedApp != null) {
- final WindowList windows = mFocusedApp.allAppWindows;
- for (int i = windows.size() - 1; i >= 0; --i) {
- final WindowState win = windows.get(i);
- final int animLayer = win.mWinAnimator.mAnimLayer;
- if (win.mAttachedWindow == null && win.isVisibleLw() &&
- animLayer > mFocusedStackLayer) {
- mFocusedStackLayer = animLayer + LAYER_OFFSET_FOCUSED_STACK;
- }
- }
- }
- if (DEBUG_LAYERS) Slog.v(TAG, "Setting FocusedStackFrame to layer=" +
- mFocusedStackLayer);
- mFocusedStackFrame.setLayer(mFocusedStackLayer);
- }
-
- void setFocusedStackFrame() {
- final TaskStack stack;
+ void setFocusTaskRegion() {
if (mFocusedApp != null) {
final Task task = mFocusedApp.mTask;
- stack = task.mStack;
final DisplayContent displayContent = task.getDisplayContent();
if (displayContent != null) {
- displayContent.setTouchExcludeRegion(stack);
+ displayContent.setTouchExcludeRegion(task);
}
- } else {
- stack = null;
}
- mFocusedStackFrame.setVisibility(stack);
}
@Override
@@ -4121,15 +4106,7 @@
if (changed) {
mFocusedApp = newFocus;
mInputMonitor.setFocusedAppLw(newFocus);
- setFocusedStackFrame();
- if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG, ">>> OPEN TRANSACTION setFocusedApp");
- SurfaceControl.openTransaction();
- try {
- setFocusedStackLayer();
- } finally {
- SurfaceControl.closeTransaction();
- if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG, ">>> CLOSE TRANSACTION setFocusedApp");
- }
+ setFocusTaskRegion();
}
if (moveFocusNow && changed) {
@@ -5132,8 +5109,10 @@
* Create a new TaskStack and place it on a DisplayContent.
* @param stackId The unique identifier of the new stack.
* @param displayId The unique identifier of the DisplayContent.
+ * @param onTop If true the stack will be place at the top of the display,
+ * else at the bottom
*/
- public void attachStack(int stackId, int displayId) {
+ public void attachStack(int stackId, int displayId, boolean onTop) {
final long origId = Binder.clearCallingIdentity();
try {
synchronized (mWindowMap) {
@@ -5146,7 +5125,7 @@
mStackIdToStack.put(stackId, stack);
}
stack.attachDisplayContent(displayContent);
- displayContent.attachStack(stack);
+ displayContent.attachStack(stack, onTop);
moveStackWindowsLocked(displayContent);
final WindowList windows = displayContent.getWindowList();
for (int winNdx = windows.size() - 1; winNdx >= 0; --winNdx) {
@@ -5233,71 +5212,101 @@
}
}
- /**
- * Re-sizes the specified stack and its containing windows.
- * Returns a {@link Configuration} object that contains configurations settings
- * that should be overridden due to the operation.
- */
- public Configuration resizeStack(int stackId, Rect bounds) {
- synchronized (mWindowMap) {
- final TaskStack stack = mStackIdToStack.get(stackId);
- if (stack == null) {
- throw new IllegalArgumentException("resizeStack: stackId " + stackId
- + " not found.");
- }
- if (stack.setBounds(bounds)) {
- stack.resizeWindows();
- stack.getDisplayContent().layoutNeeded = true;
- performLayoutAndPlaceSurfacesLocked();
- }
- return new Configuration(stack.mOverrideConfig);
- }
- }
-
public void getStackBounds(int stackId, Rect bounds) {
- final TaskStack stack = mStackIdToStack.get(stackId);
- if (stack != null) {
- stack.getBounds(bounds);
- return;
- }
- bounds.setEmpty();
- }
-
- /** Returns the id of an application (non-home stack) stack that match the input bounds.
- * -1 if no stack matches.*/
- public int getStackIdWithBounds(Rect bounds) {
- Rect stackBounds = new Rect();
synchronized (mWindowMap) {
- for (int i = mStackIdToStack.size() - 1; i >= 0; --i) {
- TaskStack stack = mStackIdToStack.valueAt(i);
- if (stack.mStackId != HOME_STACK_ID) {
- stack.getBounds(stackBounds);
- if (stackBounds.equals(bounds)) {
- return stack.mStackId;
- }
- }
+ final TaskStack stack = mStackIdToStack.get(stackId);
+ if (stack != null) {
+ stack.getBounds(bounds);
+ return;
}
+ bounds.setEmpty();
}
- return -1;
}
- /** Forces the stack to fullscreen if input is true, else un-forces the stack from fullscreen.
- * Returns a {@link Configuration} object that contains configurations settings
- * that should be overridden due to the operation.
- */
- public Configuration forceStackToFullscreen(int stackId, boolean forceFullscreen) {
+ /**
+ * Re-sizes a stack and its containing tasks.
+ * @param stackId Id of stack to resize.
+ * @param bounds New stack bounds. Passing in null sets the bounds to fullscreen.
+ * @param changedTaskIds Output list of Ids of tasks that changed in bounds due to resize.
+ * @param newTaskConfigs Output list of new Configuation of the tasks that changed.
+ * @return True if the stack is now fullscreen.
+ * */
+ public boolean resizeStack(
+ int stackId, Rect bounds, IntArray changedTaskIds, List<Configuration> newTaskConfigs) {
synchronized (mWindowMap) {
final TaskStack stack = mStackIdToStack.get(stackId);
if (stack == null) {
throw new IllegalArgumentException("resizeStack: stackId " + stackId
+ " not found.");
}
- if (stack.forceFullscreen(forceFullscreen)) {
+ if (stack.setBounds(bounds, changedTaskIds, newTaskConfigs)) {
stack.resizeWindows();
stack.getDisplayContent().layoutNeeded = true;
performLayoutAndPlaceSurfacesLocked();
}
- return new Configuration(stack.mOverrideConfig);
+ return stack.isFullscreen();
+ }
+ }
+
+ public void positionTaskInStack(int taskId, int stackId, int position) {
+ synchronized (mWindowMap) {
+ if (DEBUG_STACK) Slog.i(TAG, "positionTaskInStack: positioning taskId=" + taskId
+ + " in stackId=" + stackId + " at " + position);
+ Task task = mTaskIdToTask.get(taskId);
+ if (task == null) {
+ if (DEBUG_STACK) Slog.i(TAG,
+ "positionTaskInStack: could not find taskId=" + taskId);
+ return;
+ }
+ TaskStack stack = mStackIdToStack.get(stackId);
+ if (stack == null) {
+ if (DEBUG_STACK) Slog.i(TAG,
+ "positionTaskInStack: could not find stackId=" + stackId);
+ return;
+ }
+ task.positionTaskInStack(stack, position);
+ final DisplayContent displayContent = stack.getDisplayContent();
+ displayContent.layoutNeeded = true;
+ performLayoutAndPlaceSurfacesLocked();
+ }
+ }
+
+ /**
+ * Re-sizes the specified task and its containing windows.
+ * Returns a {@link Configuration} object that contains configurations settings
+ * that should be overridden due to the operation.
+ */
+ public Configuration resizeTask(int taskId, Rect bounds) {
+ synchronized (mWindowMap) {
+ Task task = mTaskIdToTask.get(taskId);
+ if (task == null) {
+ throw new IllegalArgumentException("resizeTask: taskId " + taskId
+ + " not found.");
+ }
+ if (task.setBounds(bounds)) {
+ task.resizeWindows();
+ task.getDisplayContent().layoutNeeded = true;
+ performLayoutAndPlaceSurfacesLocked();
+ }
+ return new Configuration(task.mOverrideConfig);
+ }
+ }
+
+ public void getTaskBounds(int taskId, Rect bounds) {
+ synchronized (mWindowMap) {
+ Task task = mTaskIdToTask.get(taskId);
+ if (task != null) {
+ task.getBounds(bounds);
+ return;
+ }
+ bounds.setEmpty();
+ }
+ }
+
+ /** Return true if the input task id represents a valid window manager task. */
+ public boolean isValidTaskId(int taskId) {
+ synchronized (mWindowMap) {
+ return mTaskIdToTask.get(taskId) != null;
}
}
@@ -5635,7 +5644,7 @@
// Called by window manager policy. Not exposed externally.
@Override
public void shutdown(boolean confirm) {
- ShutdownThread.shutdown(mContext, confirm);
+ ShutdownThread.shutdown(mContext, PowerManager.SHUTDOWN_USER_REQUESTED, confirm);
}
// Called by window manager policy. Not exposed externally.
@@ -6249,7 +6258,7 @@
int right = wf.right - cr.right;
int bottom = wf.bottom - cr.bottom;
frame.union(left, top, right, bottom);
- ws.getStackBounds(stackBounds);
+ ws.getTaskBounds(stackBounds);
if (!frame.intersect(stackBounds)) {
// Set frame empty if there's no intersection.
frame.setEmpty();
@@ -7708,7 +7717,7 @@
public static final int DO_DISPLAY_CHANGED = 29;
public static final int CLIENT_FREEZE_TIMEOUT = 30;
- public static final int TAP_OUTSIDE_STACK = 31;
+ public static final int TAP_OUTSIDE_TASK = 31;
public static final int NOTIFY_ACTIVITY_DRAWN = 32;
public static final int ALL_WINDOWS_DRAWN = 33;
@@ -8170,14 +8179,14 @@
}
break;
- case TAP_OUTSIDE_STACK: {
- int stackId;
+ case TAP_OUTSIDE_TASK: {
+ int taskId;
synchronized (mWindowMap) {
- stackId = ((DisplayContent)msg.obj).stackIdFromPoint(msg.arg1, msg.arg2);
+ taskId = ((DisplayContent)msg.obj).taskIdFromPoint(msg.arg1, msg.arg2);
}
- if (stackId >= 0) {
+ if (taskId >= 0) {
try {
- mActivityManager.setFocusedStack(stackId);
+ mActivityManager.setFocusedTask(taskId);
} catch (RemoteException e) {
}
}
@@ -8877,8 +8886,8 @@
layerChanged = true;
anyLayerChanged = true;
}
- final TaskStack stack = w.getStack();
- if (layerChanged && stack != null && stack.isDimming(winAnimator)) {
+ final Task task = w.getTask();
+ if (layerChanged && task != null && task.isDimming(winAnimator)) {
// Force an animation pass just to update the mDimLayer layer.
scheduleAnimationLocked();
}
@@ -9768,14 +9777,14 @@
&& w.isDisplayedLw()
&& !w.mExiting) {
final WindowStateAnimator winAnimator = w.mWinAnimator;
- final TaskStack stack = w.getStack();
- if (stack == null) {
+ final Task task = w.getTask();
+ if (task == null) {
return;
}
- stack.setDimmingTag();
- if (!stack.isDimming(winAnimator)) {
+ task.setContinueDimming();
+ if (!task.isDimming(winAnimator)) {
if (localLOGV) Slog.v(TAG, "Win " + w + " start dimming.");
- stack.startDimmingIfNeeded(winAnimator);
+ task.startDimmingIfNeeded(winAnimator);
}
}
}
@@ -9927,7 +9936,7 @@
}
// FIRST LOOP: Perform a layout, if needed.
- if (repeats < 4) {
+ if (repeats < LAYOUT_REPEAT_THRESHOLD) {
performLayoutLockedInner(displayContent, repeats == 1,
false /*updateInputWindows*/);
} else {
@@ -9962,8 +9971,8 @@
final int N = windows.size();
for (i=N-1; i>=0; i--) {
WindowState w = windows.get(i);
- final TaskStack stack = w.getStack();
- if (stack == null && w.getAttrs().type != TYPE_PRIVATE_PRESENTATION) {
+ final Task task = w.getTask();
+ if (task == null && w.getAttrs().type != TYPE_PRIVATE_PRESENTATION) {
continue;
}
@@ -9975,7 +9984,7 @@
handleNotObscuredLocked(w, innerDw, innerDh);
}
- if (stack != null && !stack.testDimmingTag()) {
+ if (task != null && !task.getContinueDimming()) {
handleFlagDimBehind(w);
}
@@ -10369,7 +10378,7 @@
if (updateInputWindowsNeeded) {
mInputMonitor.updateInputWindowsLw(false /*force*/);
}
- setFocusedStackFrame();
+ setFocusTaskRegion();
// Check to see if we are now in a state where the screen should
// be enabled, because the window obscured flags have changed.
@@ -11428,7 +11437,8 @@
boolean dumpWindows(PrintWriter pw, String name, String[] args,
int opti, boolean dumpAll) {
WindowList windows = new WindowList();
- if ("visible".equals(name)) {
+ if ("visible".equals(name) || "visible-apps".equals(name)) {
+ final boolean appsOnly = "visible-apps".equals(name);
synchronized(mWindowMap) {
final int numDisplays = mDisplayContents.size();
for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
@@ -11436,7 +11446,8 @@
mDisplayContents.valueAt(displayNdx).getWindowList();
for (int winNdx = windowList.size() - 1; winNdx >= 0; --winNdx) {
final WindowState w = windowList.get(winNdx);
- if (w.mWinAnimator.mSurfaceShown) {
+ if (w.mWinAnimator.mSurfaceShown
+ && (!appsOnly || (appsOnly && w.mAppToken != null))) {
windows.add(w);
}
}
@@ -11561,6 +11572,7 @@
pw.println(" Window hex object identifier, or");
pw.println(" \"all\" for all windows, or");
pw.println(" \"visible\" for the visible windows.");
+ pw.println(" \"visible-apps\" for the visible app windows.");
pw.println(" -a: include all available server state.");
return;
} else {
@@ -11711,7 +11723,7 @@
// TODO: Create an input channel for each display with touch capability.
if (displayId == Display.DEFAULT_DISPLAY) {
- displayContent.mTapDetector = new StackTapPointerEventListener(this, displayContent);
+ displayContent.mTapDetector = new TaskTapPointerEventListener(this, displayContent);
registerPointerEventListener(displayContent.mTapDetector);
}
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index c2548de..4061149 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -535,10 +535,10 @@
Rect osf) {
mHaveFrame = true;
- final TaskStack stack = mAppToken != null ? getStack() : null;
- final boolean nonFullscreenStack = stack != null && !stack.isFullscreen();
- if (nonFullscreenStack) {
- stack.getBounds(mContainingFrame);
+ final Task task = mAppToken != null ? getTask() : null;
+ final boolean nonFullscreenTask = task != null && !task.isFullscreen();
+ if (nonFullscreenTask) {
+ task.getBounds(mContainingFrame);
final WindowState imeWin = mService.mInputMethodWindow;
if (imeWin != null && imeWin.isVisibleNow() && mService.mInputMethodTarget == this
&& mContainingFrame.bottom > cf.bottom) {
@@ -626,7 +626,7 @@
y = mAttrs.y;
}
- if (nonFullscreenStack) {
+ if (nonFullscreenTask) {
// Make sure window fits in containing frame since it is in a non-fullscreen stack as
// required by {@link Gravity#apply} call.
w = Math.min(w, pw);
@@ -856,27 +856,29 @@
return displayContent.getDisplayId();
}
- TaskStack getStack() {
+ Task getTask() {
AppWindowToken wtoken = mAppToken == null ? mService.mFocusedApp : mAppToken;
- if (wtoken != null) {
- Task task = wtoken.mTask;
- if (task != null) {
- if (task.mStack != null) {
- return task.mStack;
- }
- Slog.e(TAG, "getStack: mStack null for task=" + task);
- } else {
- Slog.e(TAG, "getStack: " + this + " couldn't find task for " + wtoken
- + " Callers=" + Debug.getCallers(4));
+ if (wtoken == null) {
+ return null;
+ }
+ final Task task = wtoken.mTask;
+ return task;
+ }
+
+ TaskStack getStack() {
+ Task task = getTask();
+ if (task != null) {
+ if (task.mStack != null) {
+ return task.mStack;
}
}
return mDisplayContent.getHomeStack();
}
- void getStackBounds(Rect bounds) {
- final TaskStack stack = getStack();
- if (stack != null) {
- stack.getBounds(bounds);
+ void getTaskBounds(Rect bounds) {
+ final Task task = getTask();
+ if (task != null) {
+ task.getBounds(bounds);
return;
}
bounds.set(mFrame);
@@ -1139,9 +1141,9 @@
}
boolean isConfigChanged() {
- final TaskStack stack = getStack();
+ final Task task = getTask();
final Configuration overrideConfig =
- (stack != null) ? stack.mOverrideConfig : Configuration.EMPTY;
+ (task != null) ? task.mOverrideConfig : Configuration.EMPTY;
final Configuration serviceConfig = mService.mCurConfiguration;
boolean configChanged =
(mConfiguration != serviceConfig && mConfiguration.diff(serviceConfig) != 0)
@@ -1387,11 +1389,11 @@
@Override
public boolean isDimming() {
- TaskStack stack = getStack();
- if (stack == null) {
+ Task task = getTask();
+ if (task == null) {
return false;
}
- return stack.isDimming(mWinAnimator);
+ return task.isDimming(mWinAnimator);
}
public void setShowToOwnerOnlyLocked(boolean showToOwnerOnly) {
@@ -1489,9 +1491,9 @@
if (DEBUG_RESIZE || DEBUG_ORIENTATION) Slog.v(TAG, "Reporting new frame to " + this
+ ": " + mCompatFrame);
boolean configChanged = isConfigChanged();
- final TaskStack stack = getStack();
+ final Task task = getTask();
final Configuration overrideConfig =
- (stack != null) ? stack.mOverrideConfig : Configuration.EMPTY;
+ (task != null) ? task.mOverrideConfig : Configuration.EMPTY;
if ((DEBUG_RESIZE || DEBUG_ORIENTATION || DEBUG_CONFIGURATION) && configChanged) {
Slog.i(TAG, "Sending new config to window " + this + ": "
+ mWinAnimator.mSurfaceW + "x" + mWinAnimator.mSurfaceH + " / config="
diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java
index 3251a56..48f2a9d 100644
--- a/services/core/java/com/android/server/wm/WindowStateAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java
@@ -169,9 +169,6 @@
/** Set when the window has been shown in the screen the first time. */
static final int HAS_DRAWN = 4;
- private static final int SYSTEM_UI_FLAGS_LAYOUT_STABLE_FULLSCREEN =
- View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN;
-
String drawStateToString() {
switch (mDrawState) {
case NO_SURFACE: return "NO_SURFACE";
@@ -788,11 +785,7 @@
int flags = SurfaceControl.HIDDEN;
final WindowManager.LayoutParams attrs = w.mAttrs;
- if ((attrs.flags&WindowManager.LayoutParams.FLAG_SECURE) != 0) {
- flags |= SurfaceControl.SECURE;
- }
-
- if (mService.isScreenCaptureDisabledLocked(UserHandle.getUserId(mWin.mOwnerUid))) {
+ if (mService.isSecureLocked(w)) {
flags |= SurfaceControl.SECURE;
}
@@ -1277,6 +1270,7 @@
if (displayContent == null) {
return;
}
+ final DisplayInfo displayInfo = displayContent.getDisplayInfo();
// Need to recompute a new system decor rect each time.
if ((w.mAttrs.flags & LayoutParams.FLAG_SCALED) != 0) {
@@ -1286,7 +1280,6 @@
} else if (!w.isDefaultDisplay()) {
// On a different display there is no system decor. Crop the window
// by the screen boundaries.
- final DisplayInfo displayInfo = displayContent.getDisplayInfo();
w.mSystemDecorRect.set(0, 0, w.mCompatFrame.width(), w.mCompatFrame.height());
w.mSystemDecorRect.intersect(-w.mCompatFrame.left, -w.mCompatFrame.top,
displayInfo.logicalWidth - w.mCompatFrame.left,
@@ -1308,9 +1301,11 @@
applyDecorRect(w.mDecorFrame);
}
- // By default, the clip rect is the system decor if the transformation doesn't specify one.
+ final boolean fullscreen = w.isFullscreen(displayInfo.appWidth, displayInfo.appHeight);
final Rect clipRect = mTmpClipRect;
- clipRect.set((mHasClipRect) ? mClipRect : w.mSystemDecorRect);
+ // We use the clip rect as provided by the tranformation for non-fullscreen windows to
+ // avoid premature clipping with the system decor rect.
+ clipRect.set((mHasClipRect && !fullscreen) ? mClipRect : w.mSystemDecorRect);
// Expand the clip rect for surface insets.
final WindowManager.LayoutParams attrs = w.mAttrs;
@@ -1319,6 +1314,13 @@
clipRect.right += attrs.surfaceInsets.right;
clipRect.bottom += attrs.surfaceInsets.bottom;
+ if (mHasClipRect && fullscreen) {
+ // We intersect the clip rect specified by the transformation with the expanded system
+ // decor rect to prevent artifacts from drawing during animation if the transformation
+ // clip rect extends outside the system decor rect.
+ clipRect.intersect(mClipRect);
+ }
+
// The clip rect was generated assuming (0,0) as the window origin,
// so we need to translate to match the actual surface coordinates.
clipRect.offset(attrs.surfaceInsets.left, attrs.surfaceInsets.top);
@@ -1418,9 +1420,9 @@
mAnimator.setPendingLayoutChanges(w.getDisplayId(),
WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER);
if ((w.mAttrs.flags & LayoutParams.FLAG_DIM_BEHIND) != 0) {
- final TaskStack stack = w.getStack();
- if (stack != null) {
- stack.startDimmingIfNeeded(this);
+ final Task task = w.getTask();
+ if (task != null) {
+ task.startDimmingIfNeeded(this);
}
}
} catch (RuntimeException e) {
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index d9afa00..cd2885b 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -1277,11 +1277,13 @@
&& !hasUserSetupCompleted(userId);
if (reqPolicy == DeviceAdminInfo.USES_POLICY_DEVICE_OWNER) {
- if (ownsDevice || (userId == UserHandle.USER_OWNER && ownsInitialization)) {
+ if ((userId == UserHandle.USER_OWNER && (ownsDevice || ownsInitialization))
+ || (ownsDevice && ownsProfile)) {
return true;
}
} else if (reqPolicy == DeviceAdminInfo.USES_POLICY_PROFILE_OWNER) {
- if (ownsDevice || ownsProfile || ownsInitialization) {
+ if ((userId == UserHandle.USER_OWNER && ownsDevice) || ownsProfile
+ || ownsInitialization) {
return true;
}
} else {
@@ -4244,6 +4246,17 @@
throw new IllegalArgumentException("Invalid component name " + initializer
+ " for device initializer");
}
+ boolean isInitializerSystemApp;
+ try {
+ isInitializerSystemApp = isSystemApp(AppGlobals.getPackageManager(),
+ initializer.getPackageName(), Binder.getCallingUserHandle().getIdentifier());
+ } catch (RemoteException | IllegalArgumentException e) {
+ isInitializerSystemApp = false;
+ Slog.e(LOG_TAG, "Fail to check if device initialzer is system app.", e);
+ }
+ if (!isInitializerSystemApp) {
+ throw new IllegalArgumentException("Only system app can be set as device initializer.");
+ }
synchronized (this) {
enforceCanSetDeviceInitializer(who);
@@ -6423,7 +6436,7 @@
final ApplicationInfo ai = AppGlobals.getPackageManager()
.getApplicationInfo(packageName, 0, user.getIdentifier());
final int targetSdkVersion = ai == null ? 0 : ai.targetSdkVersion;
- if (targetSdkVersion < android.os.Build.VERSION_CODES.MNC) {
+ if (targetSdkVersion < android.os.Build.VERSION_CODES.M) {
return false;
}
final PackageManager packageManager = mContext.getPackageManager();
diff --git a/services/tests/servicestests/src/com/android/server/ConnectivityServiceTest.java b/services/tests/servicestests/src/com/android/server/ConnectivityServiceTest.java
index 3618e1a..696f106 100644
--- a/services/tests/servicestests/src/com/android/server/ConnectivityServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/ConnectivityServiceTest.java
@@ -463,7 +463,7 @@
mService = new WrappedConnectivityService(
mServiceContext, mNetManager, mStatsService, mPolicyService);
mService.systemReady();
- mCm = new ConnectivityManager(mService);
+ mCm = new ConnectivityManager(getContext(), mService);
}
private int transportToLegacyType(int transport) {
@@ -937,6 +937,19 @@
}
private void tryNetworkFactoryRequests(int capability) throws Exception {
+ // Verify NOT_RESTRICTED is set appropriately
+ final NetworkCapabilities nc = new NetworkRequest.Builder().addCapability(capability)
+ .build().networkCapabilities;
+ if (capability == NET_CAPABILITY_CBS || capability == NET_CAPABILITY_DUN ||
+ capability == NET_CAPABILITY_EIMS || capability == NET_CAPABILITY_FOTA ||
+ capability == NET_CAPABILITY_IA || capability == NET_CAPABILITY_IMS ||
+ capability == NET_CAPABILITY_RCS || capability == NET_CAPABILITY_XCAP ||
+ capability == NET_CAPABILITY_TRUSTED || capability == NET_CAPABILITY_NOT_VPN) {
+ assertFalse(nc.hasCapability(NET_CAPABILITY_NOT_RESTRICTED));
+ } else {
+ assertTrue(nc.hasCapability(NET_CAPABILITY_NOT_RESTRICTED));
+ }
+
NetworkCapabilities filter = new NetworkCapabilities();
filter.addCapability(capability);
final HandlerThread handlerThread = new HandlerThread("testNetworkFactoryRequests");
diff --git a/services/usage/java/com/android/server/usage/UsageStatsService.java b/services/usage/java/com/android/server/usage/UsageStatsService.java
index a433ec45..eba9e1e 100644
--- a/services/usage/java/com/android/server/usage/UsageStatsService.java
+++ b/services/usage/java/com/android/server/usage/UsageStatsService.java
@@ -451,7 +451,7 @@
}
private File getScreenOnTimeFile() {
- return new File(mUsageStatsDir, UserHandle.USER_OWNER + "/screen_on_time");
+ return new File(mUsageStatsDir, UserHandle.USER_SYSTEM + "/screen_on_time");
}
private long readScreenOnTimeLocked() {
diff --git a/services/usb/java/com/android/server/usb/UsbDeviceManager.java b/services/usb/java/com/android/server/usb/UsbDeviceManager.java
index 1787b91..09e15a8 100644
--- a/services/usb/java/com/android/server/usb/UsbDeviceManager.java
+++ b/services/usb/java/com/android/server/usb/UsbDeviceManager.java
@@ -49,10 +49,8 @@
import com.android.server.FgThread;
import java.io.File;
-import java.io.FileDescriptor;
import java.io.FileNotFoundException;
import java.io.IOException;
-import java.io.PrintWriter;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
@@ -316,6 +314,9 @@
// Restore default functions.
mCurrentFunctions = SystemProperties.get(USB_CONFIG_PROPERTY,
UsbManager.USB_FUNCTION_NONE);
+ if (UsbManager.USB_FUNCTION_NONE.equals(mCurrentFunctions)) {
+ mCurrentFunctions = UsbManager.USB_FUNCTION_MTP;
+ }
mCurrentFunctionsApplied = mCurrentFunctions.equals(
SystemProperties.get(USB_STATE_PROPERTY));
mAdbEnabled = UsbManager.containsFunction(getDefaultFunctions(),
@@ -400,6 +401,14 @@
return waitForState(config);
}
+ private void setUsbDataUnlocked(boolean enable) {
+ if (DEBUG) Slog.d(TAG, "setUsbDataUnlocked: " + enable);
+ mUsbDataUnlocked = enable;
+ updateUsbNotification();
+ updateUsbStateBroadcast();
+ setEnabledFunctions(mCurrentFunctions, true);
+ }
+
private void setAdbEnabled(boolean enable) {
if (DEBUG) Slog.d(TAG, "setAdbEnabled: " + enable);
if (enable != mAdbEnabled) {
@@ -471,7 +480,6 @@
}
functions = applyAdbFunction(functions);
functions = applyOemOverrideFunction(functions);
- functions = applyUserRestrictions(functions);
if (!mCurrentFunctions.equals(functions) || !mCurrentFunctionsApplied
|| forceRestart) {
@@ -502,13 +510,9 @@
return functions;
}
- private String applyUserRestrictions(String functions) {
+ private boolean isUsbTransferAllowed() {
UserManager userManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
- if (userManager.hasUserRestriction(UserManager.DISALLOW_USB_FILE_TRANSFER)) {
- functions = UsbManager.removeFunction(functions, UsbManager.USB_FUNCTION_MTP);
- functions = UsbManager.removeFunction(functions, UsbManager.USB_FUNCTION_PTP);
- }
- return functions;
+ return !userManager.hasUserRestriction(UserManager.DISALLOW_USB_FILE_TRANSFER);
}
private void updateCurrentAccessory() {
@@ -555,7 +559,7 @@
| Intent.FLAG_RECEIVER_FOREGROUND);
intent.putExtra(UsbManager.USB_CONNECTED, mConnected);
intent.putExtra(UsbManager.USB_CONFIGURED, mConfigured);
- intent.putExtra(UsbManager.USB_DATA_UNLOCKED, mUsbDataUnlocked);
+ intent.putExtra(UsbManager.USB_DATA_UNLOCKED, isUsbTransferAllowed() && mUsbDataUnlocked);
if (mCurrentFunctions != null) {
String[] functions = mCurrentFunctions.split(",");
@@ -659,10 +663,7 @@
setEnabledFunctions(mCurrentFunctions, false);
break;
case MSG_SET_USB_DATA_UNLOCKED:
- mUsbDataUnlocked = (msg.arg1 == 1);
- updateUsbNotification();
- updateUsbStateBroadcast();
- setEnabledFunctions(mCurrentFunctions, true);
+ setUsbDataUnlocked(msg.arg1 == 1);
break;
case MSG_SYSTEM_READY:
updateUsbNotification();
@@ -807,8 +808,12 @@
}
private String getDefaultFunctions() {
- return SystemProperties.get(USB_PERSISTENT_CONFIG_PROPERTY,
- UsbManager.USB_FUNCTION_ADB);
+ String func = SystemProperties.get(USB_PERSISTENT_CONFIG_PROPERTY,
+ UsbManager.USB_FUNCTION_NONE);
+ if (UsbManager.USB_FUNCTION_NONE.equals(func)) {
+ func = UsbManager.USB_FUNCTION_MTP;
+ }
+ return func;
}
public void dump(IndentingPrintWriter pw) {
@@ -817,6 +822,7 @@
pw.println(" mCurrentFunctionsApplied: " + mCurrentFunctionsApplied);
pw.println(" mConnected: " + mConnected);
pw.println(" mConfigured: " + mConfigured);
+ pw.println(" mUsbDataUnlocked: " + mUsbDataUnlocked);
pw.println(" mCurrentAccessory: " + mCurrentAccessory);
try {
pw.println(" Kernel state: "
@@ -864,11 +870,6 @@
mHandler.sendMessage(MSG_SET_USB_DATA_UNLOCKED, unlocked);
}
- public boolean isUsbDataUnlocked() {
- if (DEBUG) Slog.d(TAG, "isUsbDataUnlocked() -> " + mHandler.mUsbDataUnlocked);
- return mHandler.mUsbDataUnlocked;
- }
-
private void readOemUsbOverrideConfig() {
String[] configList = mContext.getResources().getStringArray(
com.android.internal.R.array.config_oemUsbModeOverride);
diff --git a/services/usb/java/com/android/server/usb/UsbMidiDevice.java b/services/usb/java/com/android/server/usb/UsbMidiDevice.java
index 97bf505..38ede87 100644
--- a/services/usb/java/com/android/server/usb/UsbMidiDevice.java
+++ b/services/usb/java/com/android/server/usb/UsbMidiDevice.java
@@ -128,7 +128,7 @@
mReceiver = receiver;
}
}
-
+
public static UsbMidiDevice create(Context context, Bundle properties, int card, int device) {
// FIXME - support devices with different number of input and output ports
int subDeviceCount = nativeGetSubdeviceCount(card, device);
@@ -203,6 +203,8 @@
byte[] buffer = new byte[BUFFER_SIZE];
try {
while (true) {
+ // Record time of event immediately after waking.
+ long timestamp = System.nanoTime();
synchronized (mLock) {
if (!mIsOpen) break;
@@ -215,14 +217,14 @@
} else if ((pfd.revents & OsConstants.POLLIN) != 0) {
// clear readable flag
pfd.revents = 0;
-
+
if (index == mInputStreams.length - 1) {
// last file descriptor is used only for unblocking Os.poll()
break;
}
int count = mInputStreams[index].read(buffer);
- outputReceivers[index].send(buffer, 0, count);
+ outputReceivers[index].send(buffer, 0, count, timestamp);
}
}
}
diff --git a/services/usb/java/com/android/server/usb/UsbService.java b/services/usb/java/com/android/server/usb/UsbService.java
index f93a2ef..d6dbe90 100644
--- a/services/usb/java/com/android/server/usb/UsbService.java
+++ b/services/usb/java/com/android/server/usb/UsbService.java
@@ -119,7 +119,7 @@
mPortManager = new UsbPortManager(context);
}
- setCurrentUser(UserHandle.USER_OWNER);
+ setCurrentUser(UserHandle.USER_SYSTEM);
final IntentFilter filter = new IntentFilter();
filter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY);
@@ -322,23 +322,10 @@
@Override
public void setUsbDataUnlocked(boolean unlocked) {
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USB, null);
- // If attempt to change USB function while file transfer is restricted, ensure that
- // usb data is always locked, and return.
- UserManager userManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
- if (userManager.hasUserRestriction(UserManager.DISALLOW_USB_FILE_TRANSFER)) {
- if (mDeviceManager != null) mDeviceManager.setUsbDataUnlocked(false);
- return;
- }
mDeviceManager.setUsbDataUnlocked(unlocked);
}
@Override
- public boolean isUsbDataUnlocked() {
- mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USB, null);
- return mDeviceManager.isUsbDataUnlocked();
- }
-
- @Override
public void allowUsbDebugging(boolean alwaysAllow, String publicKey) {
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USB, null);
mDeviceManager.allowUsbDebugging(alwaysAllow, publicKey);
diff --git a/telecomm/java/android/telecom/Call.java b/telecomm/java/android/telecom/Call.java
index 49f738b..d91fa90 100644
--- a/telecomm/java/android/telecom/Call.java
+++ b/telecomm/java/android/telecom/Call.java
@@ -1019,6 +1019,7 @@
&& !parcelableCall.getCannedSmsResponses().isEmpty()) {
mCannedTextResponses =
Collections.unmodifiableList(parcelableCall.getCannedSmsResponses());
+ cannedTextResponsesChanged = true;
}
boolean videoCallChanged = parcelableCall.isVideoCallProviderChanged() &&
diff --git a/telecomm/java/android/telecom/Connection.java b/telecomm/java/android/telecom/Connection.java
index 26477ce..7b277c5 100644
--- a/telecomm/java/android/telecom/Connection.java
+++ b/telecomm/java/android/telecom/Connection.java
@@ -253,20 +253,27 @@
//**********************************************************************************************
/**
- * Call extras key to pack/unpack call history info.
- * The value for this key should be an ArrayList of Strings.
- * @hide
+ * Connection extra key used to store the last forwarded number associated with the current
+ * connection. Used to communicate to the user interface that the connection was forwarded via
+ * the specified number.
*/
- public static final String EXTRA_CALL_HISTORY_INFO = "android.telecom.EXTRA_CALL_HISTORY_INFO";
+ public static final String EXTRA_LAST_FORWARDED_NUMBER =
+ "android.telecom.extra.LAST_FORWARDED_NUMBER";
/**
- * Connection {@link #mExtras} key used to store a child number associated with the current
- * connection. Used to communicate to the user interface that the connection was received via
- * a child address (in telephony phone number) associated with the {@link PhoneAccount}'s
- * primary address.
- * @hide
+ * Connection extra key used to store a child number associated with the current connection.
+ * Used to communicate to the user interface that the connection was received via
+ * a child address (i.e. phone number) associated with the {@link PhoneAccount}'s primary
+ * address.
*/
- public static final String EXTRA_CHILD_ADDRESS = "android.telecom.EXTRA_CHILD_ADDRESS";
+ public static final String EXTRA_CHILD_ADDRESS = "android.telecom.extra.CHILD_ADDRESS";
+
+ /**
+ * Connection extra key used to store the subject for an incoming call. The user interface can
+ * query this extra and display its contents for incoming calls. Will only be used if the
+ * {@link PhoneAccount} supports the capability {@link PhoneAccount#CAPABILITY_CALL_SUBJECT}.
+ */
+ public static final String EXTRA_CALL_SUBJECT = "android.telecom.extra.CALL_SUBJECT";
// Flag controlling whether PII is emitted into the logs
private static final boolean PII_DEBUG = Log.isLoggable(android.util.Log.DEBUG);
@@ -1581,7 +1588,7 @@
return mUnmodifiableConferenceables;
}
- /*
+ /**
* @hide
*/
public final void setConnectionService(ConnectionService connectionService) {
diff --git a/telecomm/java/android/telecom/TelecomManager.java b/telecomm/java/android/telecom/TelecomManager.java
index 3b59f27d..067e734 100644
--- a/telecomm/java/android/telecom/TelecomManager.java
+++ b/telecomm/java/android/telecom/TelecomManager.java
@@ -177,6 +177,13 @@
"android.telecom.extra.PHONE_ACCOUNT_HANDLE";
/**
+ * Optional extra for {@link android.content.Intent#ACTION_CALL} containing a string call
+ * subject which will be associated with an outgoing call. Should only be specified if the
+ * {@link PhoneAccount} supports the capability {@link PhoneAccount#CAPABILITY_CALL_SUBJECT}.
+ */
+ public static final String EXTRA_CALL_SUBJECT = "android.telecom.extra.CALL_SUBJECT";
+
+ /**
* The extra used by a {@link ConnectionService} to provide the handle of the caller that
* has initiated a new incoming call.
*/
diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java
index e9c41a1..b5e4342 100644
--- a/telephony/java/android/telephony/CarrierConfigManager.java
+++ b/telephony/java/android/telephony/CarrierConfigManager.java
@@ -259,6 +259,14 @@
= "carrier_allow_turnoff_ims_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";
+
+ /**
* 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
@@ -393,6 +401,7 @@
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_INSTANT_LETTERING_AVAILABLE_BOOL, false);
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);
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index a8066d8..88612e9 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -2060,6 +2060,8 @@
* <p>
* Requires Permission:
* {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
+ * OR
+ * {@link android.Manifest.permission#READ_SMS}
* <p>
* The default SMS app can also use this.
*/
@@ -2073,6 +2075,8 @@
* <p>
* Requires Permission:
* {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
+ * OR
+ * {@link android.Manifest.permission#READ_SMS}
* <p>
* The default SMS app can also use this.
*
diff --git a/tests/VoiceInteraction/res/layout/main.xml b/tests/VoiceInteraction/res/layout/main.xml
index 0f968eb..a83d02c 100644
--- a/tests/VoiceInteraction/res/layout/main.xml
+++ b/tests/VoiceInteraction/res/layout/main.xml
@@ -26,6 +26,12 @@
android:text="@string/start"
/>
+ <CheckBox android:id="@+id/secure"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/secure"
+ />
+
<com.android.test.voiceinteraction.AsyncStructure
android:layout_width="match_parent"
android:layout_height="wrap_content"
diff --git a/tests/VoiceInteraction/res/layout/test_interaction.xml b/tests/VoiceInteraction/res/layout/test_interaction.xml
index d1a7ad5..277117e 100644
--- a/tests/VoiceInteraction/res/layout/test_interaction.xml
+++ b/tests/VoiceInteraction/res/layout/test_interaction.xml
@@ -39,6 +39,19 @@
android:layout_marginTop="16dp"
android:orientation="horizontal">
+ <Button android:id="@+id/airplane"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/launchAirplane"
+ />
+
+ </LinearLayout>
+
+ <LinearLayout android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="16dp"
+ android:orientation="horizontal">
+
<Button android:id="@+id/complete"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
diff --git a/tests/VoiceInteraction/res/values/strings.xml b/tests/VoiceInteraction/res/values/strings.xml
index ab39f99..c665c23 100644
--- a/tests/VoiceInteraction/res/values/strings.xml
+++ b/tests/VoiceInteraction/res/values/strings.xml
@@ -17,9 +17,11 @@
<resources>
<string name="start">Start</string>
+ <string name="secure">Secure</string>
<string name="tree">Tree</string>
<string name="text">Text</string>
<string name="asyncStructure">(Async structure goes here)</string>
+ <string name="launchAirplane">Launch airplane mode</string>
<string name="confirm">Confirm</string>
<string name="abort">Abort</string>
<string name="complete">Complete</string>
diff --git a/tests/VoiceInteraction/src/com/android/test/voiceinteraction/TestInteractionActivity.java b/tests/VoiceInteraction/src/com/android/test/voiceinteraction/TestInteractionActivity.java
index e10d89f..ada0e21 100644
--- a/tests/VoiceInteraction/src/com/android/test/voiceinteraction/TestInteractionActivity.java
+++ b/tests/VoiceInteraction/src/com/android/test/voiceinteraction/TestInteractionActivity.java
@@ -21,6 +21,7 @@
import android.content.ComponentName;
import android.content.Intent;
import android.os.Bundle;
+import android.provider.Settings;
import android.service.voice.VoiceInteractionService;
import android.util.Log;
import android.view.View;
@@ -39,6 +40,7 @@
VoiceInteractor mInteractor;
VoiceInteractor.Request mCurrentRequest = null;
TextView mLog;
+ Button mAirplaneButton;
Button mAbortButton;
Button mCompleteButton;
Button mCommandButton;
@@ -65,6 +67,8 @@
setContentView(R.layout.test_interaction);
mLog = (TextView)findViewById(R.id.log);
+ mAirplaneButton = (Button)findViewById(R.id.airplane);
+ mAirplaneButton.setOnClickListener(this);
mAbortButton = (Button)findViewById(R.id.abort);
mAbortButton.setOnClickListener(this);
mCompleteButton = (Button)findViewById(R.id.complete);
@@ -122,7 +126,12 @@
@Override
public void onClick(View v) {
- if (v == mAbortButton) {
+ if (v == mAirplaneButton) {
+ Intent intent = new Intent(Settings.ACTION_VOICE_CONTROL_AIRPLANE_MODE);
+ intent.addCategory(Intent.CATEGORY_VOICE);
+ intent.putExtra(Settings.EXTRA_AIRPLANE_MODE_ENABLED, true);
+ startActivity(intent);
+ } else if (v == mAbortButton) {
VoiceInteractor.AbortVoiceRequest req = new TestAbortVoice();
mInteractor.submitRequest(req, REQUEST_ABORT);
} else if (v == mCompleteButton) {
diff --git a/tests/VoiceInteraction/src/com/android/test/voiceinteraction/VoiceInteractionMain.java b/tests/VoiceInteraction/src/com/android/test/voiceinteraction/VoiceInteractionMain.java
index ee75f28..87fa91a 100644
--- a/tests/VoiceInteraction/src/com/android/test/voiceinteraction/VoiceInteractionMain.java
+++ b/tests/VoiceInteraction/src/com/android/test/voiceinteraction/VoiceInteractionMain.java
@@ -21,6 +21,8 @@
import android.net.Uri;
import android.os.Bundle;
import android.view.View;
+import android.view.WindowManager;
+import android.widget.CheckBox;
public class VoiceInteractionMain extends Activity {
@@ -30,6 +32,7 @@
setContentView(R.layout.main);
findViewById(R.id.start).setOnClickListener(mStartListener);
+ findViewById(R.id.secure).setOnClickListener(mSecureListener);
}
@Override
@@ -52,4 +55,14 @@
showAssist(null);
}
};
+
+ View.OnClickListener mSecureListener = new View.OnClickListener() {
+ public void onClick(View v) {
+ if (((CheckBox)v).isChecked()) {
+ getWindow().addFlags(WindowManager.LayoutParams.FLAG_SECURE);
+ } else {
+ getWindow().clearFlags(WindowManager.LayoutParams.FLAG_SECURE);
+ }
+ }
+ };
}
diff --git a/tests/permission/src/com/android/framework/permission/tests/WindowManagerPermissionTests.java b/tests/permission/src/com/android/framework/permission/tests/WindowManagerPermissionTests.java
index e44969d..6177784 100644
--- a/tests/permission/src/com/android/framework/permission/tests/WindowManagerPermissionTests.java
+++ b/tests/permission/src/com/android/framework/permission/tests/WindowManagerPermissionTests.java
@@ -93,7 +93,7 @@
}
try {
- mWm.addAppToken(0, null, 0, 0, 0, false, false, 0, 0, false, false);
+ mWm.addAppToken(0, null, 0, 0, 0, false, false, 0, 0, false, false, null);
fail("IWindowManager.addAppToken did not throw SecurityException as"
+ " expected");
} catch (SecurityException e) {
@@ -103,7 +103,7 @@
}
try {
- mWm.setAppTask(null, 0);
+ mWm.setAppTask(null, 0, null);
fail("IWindowManager.setAppGroupId did not throw SecurityException as"
+ " expected");
} catch (SecurityException e) {
diff --git a/tools/aapt/ResourceTable.cpp b/tools/aapt/ResourceTable.cpp
index e64fdf7..81642fa 100644
--- a/tools/aapt/ResourceTable.cpp
+++ b/tools/aapt/ResourceTable.cpp
@@ -4466,6 +4466,37 @@
return 0;
}
+static bool shouldGenerateVersionedResource(const sp<ResourceTable::ConfigList>& configList,
+ const ConfigDescription& sourceConfig,
+ const int sdkVersionToGenerate) {
+ assert(sdkVersionToGenerate > sourceConfig.sdkVersion);
+ const DefaultKeyedVector<ConfigDescription, sp<ResourceTable::Entry>>& entries
+ = configList->getEntries();
+ ssize_t idx = entries.indexOfKey(sourceConfig);
+
+ // The source config came from this list, so it should be here.
+ assert(idx >= 0);
+
+ idx += 1;
+ if (static_cast<size_t>(idx) >= entries.size()) {
+ // This is the last configuration, so we should generate a versioned resource.
+ return true;
+ }
+
+ const ConfigDescription& nextConfig = entries.keyAt(idx);
+
+ // Build a configuration that is the same as the source config,
+ // but with the SDK level of the next config. If they are the same,
+ // then they only differ in SDK level. If the next configs SDK level is
+ // higher than the one we want to generate, we must generate it.
+ ConfigDescription tempConfig(sourceConfig);
+ tempConfig.sdkVersion = nextConfig.sdkVersion;
+ if (nextConfig == tempConfig) {
+ return sdkVersionToGenerate < nextConfig.sdkVersion;
+ }
+ return false;
+}
+
/**
* Modifies the entries in the resource table to account for compatibility
* issues with older versions of Android.
@@ -4574,6 +4605,11 @@
for (size_t i = 0; i < sdkCount; i++) {
const int sdkLevel = attributesToRemove.keyAt(i);
+ if (!shouldGenerateVersionedResource(c, config, sdkLevel)) {
+ // There is a style that will override this generated one.
+ continue;
+ }
+
// Duplicate the entry under the same configuration
// but with sdkVersion == sdkLevel.
ConfigDescription newConfig(config);
@@ -4610,13 +4646,7 @@
const size_t entriesToAddCount = entriesToAdd.size();
for (size_t i = 0; i < entriesToAddCount; i++) {
- if (entries.indexOfKey(entriesToAdd[i].key) >= 0) {
- // An entry already exists for this config.
- // That means that any attributes that were
- // defined in L in the original bag will be overriden
- // anyways on L devices, so we do nothing.
- continue;
- }
+ assert(entries.indexOfKey(entriesToAdd[i].key) < 0);
if (bundle->getVerbose()) {
entriesToAdd[i].value->getPos()
@@ -4662,8 +4692,7 @@
}
sp<XMLNode> newRoot = NULL;
- ConfigDescription newConfig(target->getGroupEntry().toParams());
- newConfig.sdkVersion = SDK_LOLLIPOP_MR1;
+ int sdkVersionToGenerate = SDK_LOLLIPOP_MR1;
Vector<sp<XMLNode> > nodesToVisit;
nodesToVisit.push(root);
@@ -4689,9 +4718,7 @@
// Find the smallest sdk version that we need to synthesize for
// and do that one. Subsequent versions will be processed on
// the next pass.
- if (sdkLevel < newConfig.sdkVersion) {
- newConfig.sdkVersion = sdkLevel;
- }
+ sdkVersionToGenerate = std::min(sdkLevel, sdkVersionToGenerate);
if (bundle->getVerbose()) {
SourcePos(node->getFilename(), node->getStartLineNumber()).printf(
@@ -4721,8 +4748,10 @@
// Look to see if we already have an overriding v21 configuration.
sp<ConfigList> cl = getConfigList(String16(mAssets->getPackage()),
String16(target->getResourceType()), resourceName);
- if (cl->getEntries().indexOfKey(newConfig) < 0) {
+ if (shouldGenerateVersionedResource(cl, config, sdkVersionToGenerate)) {
// We don't have an overriding entry for v21, so we must duplicate this one.
+ ConfigDescription newConfig(config);
+ newConfig.sdkVersion = sdkVersionToGenerate;
sp<AaptFile> newFile = new AaptFile(target->getSourceFile(),
AaptGroupEntry(newConfig), target->getResourceType());
String8 resPath = String8::format("res/%s/%s",
@@ -4760,7 +4789,8 @@
return NO_ERROR;
}
-void ResourceTable::getDensityVaryingResources(KeyedVector<Symbol, Vector<SymbolDefinition> >& resources) {
+void ResourceTable::getDensityVaryingResources(
+ KeyedVector<Symbol, Vector<SymbolDefinition> >& resources) {
const ConfigDescription nullConfig;
const size_t packageCount = mOrderedPackages.size();
@@ -4771,19 +4801,23 @@
const Vector<sp<ConfigList> >& configs = types[t]->getOrderedConfigs();
const size_t configCount = configs.size();
for (size_t c = 0; c < configCount; c++) {
- const DefaultKeyedVector<ConfigDescription, sp<Entry> >& configEntries = configs[c]->getEntries();
+ const DefaultKeyedVector<ConfigDescription, sp<Entry> >& configEntries
+ = configs[c]->getEntries();
const size_t configEntryCount = configEntries.size();
for (size_t ce = 0; ce < configEntryCount; ce++) {
const ConfigDescription& config = configEntries.keyAt(ce);
if (AaptConfig::isDensityOnly(config)) {
// This configuration only varies with regards to density.
- const Symbol symbol(mOrderedPackages[p]->getName(),
+ const Symbol symbol(
+ mOrderedPackages[p]->getName(),
types[t]->getName(),
configs[c]->getName(),
- getResId(mOrderedPackages[p], types[t], configs[c]->getEntryIndex()));
+ getResId(mOrderedPackages[p], types[t],
+ configs[c]->getEntryIndex()));
const sp<Entry>& entry = configEntries.valueAt(ce);
- AaptUtil::appendValue(resources, symbol, SymbolDefinition(symbol, config, entry->getPos()));
+ AaptUtil::appendValue(resources, symbol,
+ SymbolDefinition(symbol, config, entry->getPos()));
}
}
}
diff --git a/tools/layoutlib/bridge/src/android/content/res/BridgeTypedArray.java b/tools/layoutlib/bridge/src/android/content/res/BridgeTypedArray.java
index 2e515fb..6a61090 100644
--- a/tools/layoutlib/bridge/src/android/content/res/BridgeTypedArray.java
+++ b/tools/layoutlib/bridge/src/android/content/res/BridgeTypedArray.java
@@ -239,15 +239,12 @@
public int getInt(int index, int defValue) {
String s = getString(index);
try {
- if (s != null) {
- return convertValueToInt(s, defValue);
- }
+ return convertValueToInt(s, defValue);
} catch (NumberFormatException e) {
Bridge.getLog().warning(LayoutLog.TAG_RESOURCES_FORMAT,
String.format("\"%1$s\" in attribute \"%2$s\" is not a valid integer",
s, mNames[index]),
null);
- return defValue;
}
return defValue;
}
@@ -949,7 +946,7 @@
* "XXXXXXXX" > 80000000.
*/
private static int convertValueToInt(@Nullable String charSeq, int defValue) {
- if (null == charSeq)
+ if (null == charSeq || charSeq.isEmpty())
return defValue;
int sign = 1;
diff --git a/tools/layoutlib/bridge/src/android/graphics/Matrix_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Matrix_Delegate.java
index 1105c7b..a503e50 100644
--- a/tools/layoutlib/bridge/src/android/graphics/Matrix_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/Matrix_Delegate.java
@@ -673,7 +673,7 @@
return;
}
- System.arraycopy(d.mValues, 0, d.mValues, 0, MATRIX_SIZE);
+ System.arraycopy(d.mValues, 0, values, 0, MATRIX_SIZE);
}
@LayoutlibDelegate
diff --git a/tools/layoutlib/bridge/src/android/graphics/Path_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Path_Delegate.java
index 776398f..3c9a062 100644
--- a/tools/layoutlib/bridge/src/android/graphics/Path_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/Path_Delegate.java
@@ -21,6 +21,7 @@
import com.android.layoutlib.bridge.impl.DelegateManager;
import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
+import android.annotation.NonNull;
import android.graphics.Path.Direction;
import android.graphics.Path.FillType;
@@ -30,6 +31,7 @@
import java.awt.geom.Area;
import java.awt.geom.Ellipse2D;
import java.awt.geom.GeneralPath;
+import java.awt.geom.Path2D;
import java.awt.geom.PathIterator;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
@@ -56,7 +58,7 @@
// ---- delegate data ----
private FillType mFillType = FillType.WINDING;
- private GeneralPath mPath = new GeneralPath();
+ private Path2D mPath = new Path2D.Double();
private float mLastX = 0;
private float mLastY = 0;
@@ -486,8 +488,54 @@
@LayoutlibDelegate
/*package*/ static float[] native_approximate(long nPath, float error) {
- Bridge.getLog().error(LayoutLog.TAG_UNSUPPORTED, "Path.approximate() not supported", null);
- return new float[0];
+ Bridge.getLog().warning(LayoutLog.TAG_UNSUPPORTED, "Path.approximate() not fully supported",
+ null);
+ Path_Delegate pathDelegate = sManager.getDelegate(nPath);
+ if (pathDelegate == null) {
+ return null;
+ }
+ PathIterator pathIterator = pathDelegate.mPath.getPathIterator(null);
+ float[] tmp = new float[6];
+ float[] coords = new float[6];
+ boolean isFirstPoint = true;
+ while (!pathIterator.isDone()) {
+ int type = pathIterator.currentSegment(tmp);
+ switch (type) {
+ case PathIterator.SEG_MOVETO:
+ case PathIterator.SEG_LINETO:
+ store(tmp, coords, 1, isFirstPoint);
+ break;
+ case PathIterator.SEG_QUADTO:
+ store(tmp, coords, 2, isFirstPoint);
+ break;
+ case PathIterator.SEG_CUBICTO:
+ store(tmp, coords, 3, isFirstPoint);
+ break;
+ case PathIterator.SEG_CLOSE:
+ // No points returned.
+ }
+ isFirstPoint = false;
+ pathIterator.next();
+ }
+ if (isFirstPoint) {
+ // No points found
+ return new float[0];
+ } else {
+ return coords;
+ }
+ }
+
+ private static void store(float[] src, float[] dst, int count, boolean isFirst) {
+ if (isFirst) {
+ dst[0] = 0; // fraction
+ dst[1] = src[0]; // abscissa
+ dst[2] = src[1]; // ordinate
+ }
+ if (count > 1 || !isFirst) {
+ dst[3] = 1;
+ dst[4] = src[2 * count - 2];
+ dst[5] = src[2 * count - 1];
+ }
}
// ---- Private helper methods ----
@@ -522,6 +570,7 @@
throw new IllegalArgumentException();
}
+ @NonNull
private static Direction getDirection(int direction) {
for (Direction d : Direction.values()) {
if (direction == d.nativeInt) {
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/MockView.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/MockView.java
index 4a9f718..44a9aad 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/MockView.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/MockView.java
@@ -30,6 +30,10 @@
*/
public class MockView extends TextView {
+ public MockView(Context context, AttributeSet attrs) {
+ this(context, attrs, 0);
+ }
+
public MockView(Context context, AttributeSet attrs, int defStyle) {
this(context, attrs, defStyle, 0);
}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgePowerManager.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgePowerManager.java
index 895f9c9..a410c53 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgePowerManager.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgePowerManager.java
@@ -86,7 +86,7 @@
}
@Override
- public void shutdown(boolean confirm, boolean wait) {
+ public void shutdown(boolean confirm, String reason, boolean wait) {
// pass for now.
}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/support/DesignLibUtil.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/support/DesignLibUtil.java
index 0426907..aa873a6 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/support/DesignLibUtil.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/support/DesignLibUtil.java
@@ -18,14 +18,12 @@
import com.android.ide.common.rendering.api.LayoutLog;
import com.android.layoutlib.bridge.Bridge;
+import com.android.layoutlib.bridge.util.ReflectionUtils.ReflectionException;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.view.View;
-import java.lang.reflect.Method;
-
-import static com.android.layoutlib.bridge.util.ReflectionUtils.ReflectionException;
import static com.android.layoutlib.bridge.util.ReflectionUtils.getMethod;
import static com.android.layoutlib.bridge.util.ReflectionUtils.invoke;
@@ -53,10 +51,7 @@
return;
}
try {
- Method setTitle = getMethod(view.getClass(), "setTitle", CharSequence.class);
- if (setTitle != null) {
- invoke(setTitle, view, title);
- }
+ invoke(getMethod(view.getClass(), "setTitle", CharSequence.class), view, title);
} catch (ReflectionException e) {
Bridge.getLog().warning(LayoutLog.TAG_INFO,
"Error occurred while trying to set title.", e);
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/support/RecyclerViewUtil.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/support/RecyclerViewUtil.java
index d14c80b..d432120 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/support/RecyclerViewUtil.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/support/RecyclerViewUtil.java
@@ -21,16 +21,13 @@
import com.android.layoutlib.bridge.Bridge;
import com.android.layoutlib.bridge.android.BridgeContext;
import com.android.layoutlib.bridge.android.RenderParamsFlags;
-import com.android.layoutlib.bridge.util.ReflectionUtils;
+import com.android.layoutlib.bridge.util.ReflectionUtils.ReflectionException;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.Context;
import android.view.View;
-import java.lang.reflect.Method;
-
-import static com.android.layoutlib.bridge.util.ReflectionUtils.ReflectionException;
import static com.android.layoutlib.bridge.util.ReflectionUtils.getCause;
import static com.android.layoutlib.bridge.util.ReflectionUtils.getMethod;
import static com.android.layoutlib.bridge.util.ReflectionUtils.invoke;
@@ -98,8 +95,7 @@
@Nullable
private static Object getLayoutManager(View recyclerView) throws ReflectionException {
- Method getLayoutManager = getMethod(recyclerView.getClass(), "getLayoutManager");
- return getLayoutManager != null ? invoke(getLayoutManager, recyclerView) : null;
+ return invoke(getMethod(recyclerView.getClass(), "getLayoutManager"), recyclerView);
}
@Nullable
@@ -127,10 +123,7 @@
private static void setProperty(@NonNull Object object, @NonNull Class<?> propertyClass,
@Nullable Object propertyValue, @NonNull String propertySetter)
throws ReflectionException {
- Method setter = getMethod(object.getClass(), propertySetter, propertyClass);
- if (setter != null) {
- invoke(setter, object, propertyValue);
- }
+ invoke(getMethod(object.getClass(), propertySetter, propertyClass), object, propertyValue);
}
/**
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/Config.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/Config.java
index dc89d0c..09937bc 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/Config.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/Config.java
@@ -74,8 +74,8 @@
}
public static String getTime(int platformVersion) {
- if (isGreaterOrEqual(platformVersion, LOLLIPOP_MR1)) {
- return "5:10";
+ if (isGreaterOrEqual(platformVersion, M)) {
+ return "6:00";
}
if (platformVersion < GINGERBREAD) {
return "2:20";
@@ -95,6 +95,9 @@
if (platformVersion < LOLLIPOP_MR1) {
return "5:00";
}
+ if (platformVersion < M) {
+ return "5:10";
+ }
// Should never happen.
return "4:04";
}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/CustomBar.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/CustomBar.java
index 145a03a..b76ec17 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/CustomBar.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/CustomBar.java
@@ -16,6 +16,7 @@
package com.android.layoutlib.bridge.bars;
+import com.android.ide.common.rendering.api.LayoutLog;
import com.android.ide.common.rendering.api.RenderResources;
import com.android.ide.common.rendering.api.ResourceValue;
import com.android.ide.common.rendering.api.StyleResourceValue;
@@ -258,8 +259,21 @@
ResourceValue resource = renderResources.findItemInTheme(attr, true);
// Form @color/bar to the #AARRGGBB
resource = renderResources.resolveResValue(resource);
- if (resource != null && ResourceType.COLOR.equals(resource.getResourceType())) {
- return ResourceHelper.getColor(resource.getValue());
+ if (resource != null) {
+ ResourceType type = resource.getResourceType();
+ if (type == null || type == ResourceType.COLOR) {
+ // if no type is specified, the value may have been specified directly in the style
+ // file, rather than referencing a color resource value.
+ try {
+ return ResourceHelper.getColor(resource.getValue());
+ } catch (NumberFormatException e) {
+ // Conversion failed.
+ Bridge.getLog().warning(LayoutLog.TAG_RESOURCES_FORMAT,
+ "Theme attribute @android:" + attr +
+ " does not reference a color, instead is '" +
+ resource.getValue() + "'.", resource);
+ }
+ }
}
return 0;
}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/Layout.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/Layout.java
index 89d8319..cbd0415 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/Layout.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/Layout.java
@@ -45,6 +45,7 @@
import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
import static android.widget.LinearLayout.VERTICAL;
+import static com.android.layoutlib.bridge.impl.ResourceHelper.getBooleanThemeValue;
/**
* The Layout used to create the system decor.
@@ -82,7 +83,7 @@
// Theme attributes used for configuring appearance of the system decor.
private static final String ATTR_WINDOW_FLOATING = "windowIsFloating";
private static final String ATTR_WINDOW_BACKGROUND = "windowBackground";
- private static final String ATTR_WINDOW_FULL_SCREEN = "windowFullScreen";
+ private static final String ATTR_WINDOW_FULL_SCREEN = "windowFullscreen";
private static final String ATTR_NAV_BAR_HEIGHT = "navigation_bar_height";
private static final String ATTR_NAV_BAR_WIDTH = "navigation_bar_width";
private static final String ATTR_STATUS_BAR_HEIGHT = "status_bar_height";
@@ -130,6 +131,7 @@
HardwareConfig hwConfig = getParams().getHardwareConfig();
Density density = hwConfig.getDensity();
boolean isRtl = Bridge.isLocaleRtl(getParams().getLocale());
+ setLayoutDirection(isRtl? LAYOUT_DIRECTION_RTL : LAYOUT_DIRECTION_LTR);
NavigationBar navBar = null;
if (mBuilder.hasNavBar()) {
@@ -165,13 +167,13 @@
FrameLayout contentRoot = new FrameLayout(getContext());
LayoutParams params = createLayoutParams(MATCH_PARENT, MATCH_PARENT);
int rule = mBuilder.isNavBarVertical() ? START_OF : ABOVE;
- if (mBuilder.solidBars()) {
+ if (mBuilder.hasNavBar() && mBuilder.solidBars()) {
params.addRule(rule, getId(ID_NAV_BAR));
}
int below = -1;
if (mBuilder.mActionBarSize <= 0 && mBuilder.mTitleBarSize > 0) {
below = getId(ID_TITLE_BAR);
- } else if (mBuilder.solidBars()) {
+ } else if (mBuilder.hasStatusBar() && mBuilder.solidBars()) {
below = getId(ID_STATUS_BAR);
}
if (below != -1) {
@@ -238,10 +240,10 @@
}
LayoutParams layoutParams = createLayoutParams(MATCH_PARENT, MATCH_PARENT);
int rule = mBuilder.isNavBarVertical() ? START_OF : ABOVE;
- if (mBuilder.solidBars()) {
+ if (mBuilder.hasNavBar() && mBuilder.solidBars()) {
layoutParams.addRule(rule, getId(ID_NAV_BAR));
}
- if (mBuilder.solidBars()) {
+ if (mBuilder.hasStatusBar() && mBuilder.solidBars()) {
layoutParams.addRule(BELOW, getId(ID_STATUS_BAR));
}
actionBar.getRootView().setLayoutParams(layoutParams);
@@ -254,7 +256,7 @@
int simulatedPlatformVersion) {
TitleBar titleBar = new TitleBar(context, title, simulatedPlatformVersion);
LayoutParams params = createLayoutParams(MATCH_PARENT, mBuilder.mTitleBarSize);
- if (mBuilder.solidBars()) {
+ if (mBuilder.hasStatusBar() && mBuilder.solidBars()) {
params.addRule(BELOW, getId(ID_STATUS_BAR));
}
if (mBuilder.isNavBarVertical() && mBuilder.solidBars()) {
@@ -325,16 +327,15 @@
mParams = params;
mContext = context;
mResources = mParams.getResources();
- mWindowIsFloating = ResourceHelper.getBooleanThemeValue(mResources, ATTR_WINDOW_FLOATING, true, true);
+ mWindowIsFloating = getBooleanThemeValue(mResources, ATTR_WINDOW_FLOATING, true, true);
findBackground();
- findStatusBar();
- findActionBar();
- findNavBar();
- }
- public boolean isNavBarVertical() {
- return mNavBarOrientation == VERTICAL;
+ if (!mParams.isForceNoDecor()) {
+ findStatusBar();
+ findActionBar();
+ findNavBar();
+ }
}
private void findBackground() {
@@ -346,11 +347,11 @@
private void findStatusBar() {
boolean windowFullScreen =
- ResourceHelper.getBooleanThemeValue(mResources, ATTR_WINDOW_FULL_SCREEN, true, false);
+ getBooleanThemeValue(mResources, ATTR_WINDOW_FULL_SCREEN, true, false);
if (!windowFullScreen && !mWindowIsFloating) {
mStatusBarSize =
getDimension(ATTR_STATUS_BAR_HEIGHT, true, DEFAULT_STATUS_BAR_HEIGHT);
- mTranslucentStatus = ResourceHelper.getBooleanThemeValue(mResources,
+ mTranslucentStatus = getBooleanThemeValue(mResources,
ATTR_WINDOW_TRANSLUCENT_STATUS, true, false);
}
}
@@ -360,14 +361,14 @@
return;
}
// Check if an actionbar is needed
- boolean windowActionBar = ResourceHelper.getBooleanThemeValue(mResources, ATTR_WINDOW_ACTION_BAR,
+ boolean windowActionBar = getBooleanThemeValue(mResources, ATTR_WINDOW_ACTION_BAR,
!isThemeAppCompat(), true);
if (windowActionBar) {
mActionBarSize = getDimension(ATTR_ACTION_BAR_SIZE, true, DEFAULT_TITLE_BAR_HEIGHT);
} else {
// Maybe the gingerbread era title bar is needed
boolean windowNoTitle =
- ResourceHelper.getBooleanThemeValue(mResources, ATTR_WINDOW_NO_TITLE, true, false);
+ getBooleanThemeValue(mResources, ATTR_WINDOW_NO_TITLE, true, false);
if (!windowNoTitle) {
mTitleBarSize =
getDimension(ATTR_WINDOW_TITLE_SIZE, true, DEFAULT_TITLE_BAR_HEIGHT);
@@ -395,7 +396,7 @@
mNavBarOrientation = barOnBottom ? LinearLayout.HORIZONTAL : VERTICAL;
mNavBarSize = getDimension(barOnBottom ? ATTR_NAV_BAR_HEIGHT : ATTR_NAV_BAR_WIDTH,
true, DEFAULT_NAV_BAR_SIZE);
- mTranslucentNav = ResourceHelper.getBooleanThemeValue(mResources,
+ mTranslucentNav = getBooleanThemeValue(mResources,
ATTR_WINDOW_TRANSLUCENT_NAV, true, false);
}
}
@@ -444,16 +445,27 @@
}
/**
- * Return if both status bar and nav bar are solid (content doesn't overlap with these
- * bars).
+ * Return true if the status bar or nav bar are present, they are not translucent (i.e
+ * content doesn't overlap with them).
*/
private boolean solidBars() {
- return hasNavBar() && !mTranslucentNav && !mTranslucentStatus && mStatusBarSize > 0;
+ return !(hasNavBar() && mTranslucentNav) && !(hasStatusBar() && mTranslucentStatus);
}
private boolean hasNavBar() {
return Config.showOnScreenNavBar(mParams.getSimulatedPlatformVersion()) &&
hasSoftwareButtons() && mNavBarSize > 0;
}
+
+ private boolean hasStatusBar() {
+ return mStatusBarSize > 0;
+ }
+
+ /**
+ * Return true if the nav bar is present and is vertical.
+ */
+ private boolean isNavBarVertical() {
+ return hasNavBar() && mNavBarOrientation == VERTICAL;
+ }
}
}
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/array_check.png b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/array_check.png
index 9a13568..336f9d8 100644
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/array_check.png
+++ b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/array_check.png
Binary files differ
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/expand_horz_layout.png b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/expand_horz_layout.png
index 92eb3e1..0c16215 100644
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/expand_horz_layout.png
+++ b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/expand_horz_layout.png
Binary files differ
diff --git a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/Main.java b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/Main.java
index b2909c9..9ebeebd 100644
--- a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/Main.java
+++ b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/Main.java
@@ -285,7 +285,7 @@
ConfigGenerator.getEnumMap(attrs), getLayoutLog());
}
- /** Text activity.xml */
+ /** Test activity.xml */
@Test
public void testActivity() throws ClassNotFoundException {
renderAndVerify("activity.xml", "activity.png");
@@ -329,8 +329,8 @@
.setNavigation(Navigation.NONAV);
SessionParams params = getSessionParams(parser, customConfigGenerator,
- layoutLibCallback, "Theme.Material.NoActionBar.Fullscreen", RenderingMode.V_SCROLL,
- 22);
+ layoutLibCallback, "Theme.Material.NoActionBar.Fullscreen", false,
+ RenderingMode.V_SCROLL, 22);
renderAndVerify(params, "expand_vert_layout.png");
@@ -342,8 +342,8 @@
parser = new LayoutPullParser(APP_TEST_RES + "/layout/" +
"expand_horz_layout.xml");
params = getSessionParams(parser, customConfigGenerator,
- layoutLibCallback, "Theme.Material.NoActionBar.Fullscreen", RenderingMode
- .H_SCROLL, 22);
+ layoutLibCallback, "Theme.Material.NoActionBar.Fullscreen", false,
+ RenderingMode.H_SCROLL, 22);
renderAndVerify(params, "expand_horz_layout.png");
}
@@ -390,7 +390,7 @@
// TODO: Set up action bar handler properly to test menu rendering.
// Create session params.
SessionParams params = getSessionParams(parser, ConfigGenerator.NEXUS_5,
- layoutLibCallback, "Theme.Material.Light.DarkActionBar", RenderingMode.NORMAL, 22);
+ layoutLibCallback, "AppTheme", true, RenderingMode.NORMAL, 22);
renderAndVerify(params, goldenFileName);
}
@@ -399,12 +399,12 @@
*/
private SessionParams getSessionParams(LayoutPullParser layoutParser,
ConfigGenerator configGenerator, LayoutLibTestCallback layoutLibCallback,
- String themeName, RenderingMode renderingMode, int targetSdk) {
+ String themeName, boolean isProjectTheme, RenderingMode renderingMode, int targetSdk) {
FolderConfiguration config = configGenerator.getFolderConfig();
ResourceResolver resourceResolver =
ResourceResolver.create(sProjectResources.getConfiguredResources(config),
sFrameworkRepo.getConfiguredResources(config),
- themeName, true);
+ themeName, isProjectTheme);
return new SessionParams(
layoutParser,
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/Main.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/Main.java
index 2951edb..383168f 100644
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/Main.java
+++ b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/Main.java
@@ -119,6 +119,7 @@
"android.icu.**", // needed by LayoutLib
"android.annotation.NonNull", // annotations
"android.annotation.Nullable", // annotations
+ "com.android.internal.transition.EpicenterTranslateClipReveal",
},
excludeClasses,
new String[] {
diff --git a/wifi/java/android/net/wifi/ScanResult.java b/wifi/java/android/net/wifi/ScanResult.java
index cc1e976..8a20012 100644
--- a/wifi/java/android/net/wifi/ScanResult.java
+++ b/wifi/java/android/net/wifi/ScanResult.java
@@ -363,11 +363,10 @@
}
/** {@hide} */
- public ScanResult(WifiSsid wifiSsid, String BSSID, String caps, int level, int frequency,
+ public ScanResult(String Ssid, String BSSID, String caps, int level, int frequency,
long tsf, int distCm, int distSdCm, int channelWidth, int centerFreq0, int centerFreq1,
boolean is80211McRTTResponder) {
- this.wifiSsid = wifiSsid;
- this.SSID = (wifiSsid != null) ? wifiSsid.toString() : WifiSsid.NONE;
+ this.SSID = Ssid;
this.BSSID = BSSID;
this.capabilities = caps;
this.level = level;
@@ -385,6 +384,15 @@
}
}
+ /** {@hide} */
+ public ScanResult(WifiSsid wifiSsid, String Ssid, String BSSID, String caps, int level,
+ int frequency, long tsf, int distCm, int distSdCm, int channelWidth,
+ int centerFreq0, int centerFreq1, boolean is80211McRTTResponder) {
+ this(Ssid, BSSID, caps,level, frequency, tsf, distCm, distSdCm, channelWidth, centerFreq0,
+ centerFreq1, is80211McRTTResponder);
+ this.wifiSsid = wifiSsid;
+ }
+
/** copy constructor {@hide} */
public ScanResult(ScanResult source) {
if (source != null) {
@@ -469,6 +477,7 @@
} else {
dest.writeInt(0);
}
+ dest.writeString(SSID);
dest.writeString(BSSID);
dest.writeString(capabilities);
dest.writeInt(level);
@@ -512,6 +521,7 @@
}
ScanResult sr = new ScanResult(
wifiSsid,
+ in.readString(), /* SSID */
in.readString(), /* BSSID */
in.readString(), /* capabilities */
in.readInt(), /* level */
diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java
index d915e5d..cf88df4 100644
--- a/wifi/java/android/net/wifi/WifiManager.java
+++ b/wifi/java/android/net/wifi/WifiManager.java
@@ -669,6 +669,7 @@
try {
return mService.getConfiguredNetworks();
} catch (RemoteException e) {
+ Log.w(TAG, "Caught RemoteException trying to get configured networks: " + e);
return null;
}
}
@@ -1589,6 +1590,7 @@
try {
return mService.buildWifiConfig(uriString, mimeType, data);
} catch (RemoteException e) {
+ Log.w(TAG, "Caught RemoteException trying to build wifi config: " + e);
return null;
}
}
diff --git a/wifi/java/android/net/wifi/WifiScanner.java b/wifi/java/android/net/wifi/WifiScanner.java
index a3dc077..a65f250 100644
--- a/wifi/java/android/net/wifi/WifiScanner.java
+++ b/wifi/java/android/net/wifi/WifiScanner.java
@@ -255,9 +255,7 @@
mResults = new ScanResult[s.mResults.length];
for (int i = 0; i < s.mResults.length; i++) {
ScanResult result = s.mResults[i];
- WifiSsid wifiSsid = WifiSsid.createFromAsciiEncoded(result.SSID);
ScanResult newResult = new ScanResult(result);
- newResult.wifiSsid = wifiSsid;
mResults[i] = newResult;
}
}