Merge "Add a cross-profile intent filter only if it wasn't previously added." into lmp-mr1-dev
diff --git a/api/current.txt b/api/current.txt
index 9513d90..476d9f5 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -113,8 +113,9 @@
field public static final java.lang.String RECEIVE_SMS = "android.permission.RECEIVE_SMS";
field public static final java.lang.String RECEIVE_WAP_PUSH = "android.permission.RECEIVE_WAP_PUSH";
field public static final java.lang.String RECORD_AUDIO = "android.permission.RECORD_AUDIO";
+ field public static final java.lang.String REGISTER_CALL_PROVIDER = "android.permission.REGISTER_CALL_PROVIDER";
field public static final java.lang.String REGISTER_CONNECTION_MANAGER = "android.permission.REGISTER_CONNECTION_MANAGER";
- field public static final java.lang.String REGISTER_PROVIDER_OR_SUBSCRIPTION = "android.permission.REGISTER_PROVIDER_OR_SUBSCRIPTION";
+ field public static final java.lang.String REGISTER_SIM_SUBSCRIPTION = "android.permission.REGISTER_SIM_SUBSCRIPTION";
field public static final java.lang.String REORDER_TASKS = "android.permission.REORDER_TASKS";
field public static final deprecated java.lang.String RESTART_PACKAGES = "android.permission.RESTART_PACKAGES";
field public static final java.lang.String SEND_RESPOND_VIA_MESSAGE = "android.permission.SEND_RESPOND_VIA_MESSAGE";
@@ -239,6 +240,8 @@
field public static final int accessibilityFeedbackType = 16843650; // 0x1010382
field public static final int accessibilityFlags = 16843652; // 0x1010384
field public static final int accessibilityLiveRegion = 16843758; // 0x10103ee
+ field public static final int accessibilityTraversalAfter = 16844036; // 0x1010504
+ field public static final int accessibilityTraversalBefore = 16844035; // 0x1010503
field public static final int accountPreferences = 16843423; // 0x101029f
field public static final int accountType = 16843407; // 0x101028f
field public static final int action = 16842797; // 0x101002d
@@ -4795,7 +4798,9 @@
method public int getCustomSizePreset();
method public android.app.PendingIntent getDisplayIntent();
method public int getGravity();
+ method public boolean getHintAvoidBackgroundClipping();
method public boolean getHintHideIcon();
+ method public int getHintScreenTimeout();
method public boolean getHintShowBackgroundOnly();
method public java.util.List<android.app.Notification> getPages();
method public boolean getStartScrollBottom();
@@ -4808,9 +4813,13 @@
method public android.app.Notification.WearableExtender setCustomSizePreset(int);
method public android.app.Notification.WearableExtender setDisplayIntent(android.app.PendingIntent);
method public android.app.Notification.WearableExtender setGravity(int);
+ method public android.app.Notification.WearableExtender setHintAvoidBackgroundClipping(boolean);
method public android.app.Notification.WearableExtender setHintHideIcon(boolean);
+ method public android.app.Notification.WearableExtender setHintScreenTimeout(int);
method public android.app.Notification.WearableExtender setHintShowBackgroundOnly(boolean);
method public android.app.Notification.WearableExtender setStartScrollBottom(boolean);
+ field public static final int SCREEN_TIMEOUT_LONG = -1; // 0xffffffff
+ field public static final int SCREEN_TIMEOUT_SHORT = 0; // 0x0
field public static final int SIZE_DEFAULT = 0; // 0x0
field public static final int SIZE_FULL_SCREEN = 5; // 0x5
field public static final int SIZE_LARGE = 4; // 0x4
@@ -5314,6 +5323,7 @@
method public boolean getScreenCaptureDisabled(android.content.ComponentName);
method public boolean getStorageEncryption(android.content.ComponentName);
method public int getStorageEncryptionStatus();
+ method public java.util.List<android.os.PersistableBundle> getTrustAgentConfiguration(android.content.ComponentName, android.content.ComponentName);
method public boolean hasCaCertInstalled(android.content.ComponentName, byte[]);
method public boolean hasGrantedPolicy(android.content.ComponentName, int);
method public boolean installCaCert(android.content.ComponentName, byte[]);
@@ -5362,6 +5372,7 @@
method public void setScreenCaptureDisabled(android.content.ComponentName, boolean);
method public void setSecureSetting(android.content.ComponentName, java.lang.String, java.lang.String);
method public int setStorageEncryption(android.content.ComponentName, boolean);
+ method public void setTrustAgentConfiguration(android.content.ComponentName, android.content.ComponentName, android.os.PersistableBundle);
method public void setUninstallBlocked(android.content.ComponentName, java.lang.String, boolean);
method public boolean switchUser(android.content.ComponentName, android.os.UserHandle);
method public void uninstallAllUserCaCerts(android.content.ComponentName);
@@ -16301,6 +16312,7 @@
method public void setPlaybackToRemote(android.media.VolumeProvider);
method public void setQueue(java.util.List<android.media.session.MediaSession.QueueItem>);
method public void setQueueTitle(java.lang.CharSequence);
+ method public void setRatingType(int);
method public void setSessionActivity(android.app.PendingIntent);
field public static final int FLAG_HANDLES_MEDIA_BUTTONS = 1; // 0x1
field public static final int FLAG_HANDLES_TRANSPORT_CONTROLS = 2; // 0x2
@@ -16359,6 +16371,7 @@
method public long getBufferedPosition();
method public java.util.List<android.media.session.PlaybackState.CustomAction> getCustomActions();
method public java.lang.CharSequence getErrorMessage();
+ method public android.os.Bundle getExtras();
method public long getLastPositionUpdateTime();
method public float getPlaybackSpeed();
method public long getPosition();
@@ -16403,6 +16416,7 @@
method public android.media.session.PlaybackState.Builder setActiveQueueItemId(long);
method public android.media.session.PlaybackState.Builder setBufferedPosition(long);
method public android.media.session.PlaybackState.Builder setErrorMessage(java.lang.CharSequence);
+ method public android.media.session.PlaybackState.Builder setExtras(android.os.Bundle);
method public android.media.session.PlaybackState.Builder setState(int, long, float, long);
method public android.media.session.PlaybackState.Builder setState(int, long, float);
}
@@ -25146,6 +25160,7 @@
field public static final java.lang.String ACTION_APPLICATION_DETAILS_SETTINGS = "android.settings.APPLICATION_DETAILS_SETTINGS";
field public static final java.lang.String ACTION_APPLICATION_DEVELOPMENT_SETTINGS = "android.settings.APPLICATION_DEVELOPMENT_SETTINGS";
field public static final java.lang.String ACTION_APPLICATION_SETTINGS = "android.settings.APPLICATION_SETTINGS";
+ field public static final java.lang.String ACTION_BATTERY_SAVER_SETTINGS = "android.settings.BATTERY_SAVER_SETTINGS";
field public static final java.lang.String ACTION_BLUETOOTH_SETTINGS = "android.settings.BLUETOOTH_SETTINGS";
field public static final java.lang.String ACTION_CAPTIONING_SETTINGS = "android.settings.CAPTIONING_SETTINGS";
field public static final java.lang.String ACTION_CAST_SETTINGS = "android.settings.CAST_SETTINGS";
@@ -28091,7 +28106,9 @@
method public final int getCapabilities();
method public final java.util.List<android.telecom.Connection> getConferenceableConnections();
method public final java.util.List<android.telecom.Connection> getConnections();
+ method public final android.telecom.DisconnectCause getDisconnectCause();
method public final android.telecom.PhoneAccountHandle getPhoneAccountHandle();
+ method public android.telecom.Connection getPrimaryConnection();
method public final int getState();
method public void onAudioStateChanged(android.telecom.AudioState);
method public void onDisconnect();
@@ -28181,6 +28198,7 @@
public abstract class ConnectionService extends android.app.Service {
ctor public ConnectionService();
method public final void addConference(android.telecom.Conference);
+ method public final void addExistingConnection(android.telecom.PhoneAccountHandle, android.telecom.Connection);
method public final void conferenceRemoteConnections(android.telecom.RemoteConnection, android.telecom.RemoteConnection);
method public final android.telecom.RemoteConnection createRemoteIncomingConnection(android.telecom.PhoneAccountHandle, android.telecom.ConnectionRequest);
method public final android.telecom.RemoteConnection createRemoteOutgoingConnection(android.telecom.PhoneAccountHandle, android.telecom.ConnectionRequest);
@@ -28190,6 +28208,7 @@
method public android.telecom.Connection onCreateIncomingConnection(android.telecom.PhoneAccountHandle, android.telecom.ConnectionRequest);
method public android.telecom.Connection onCreateOutgoingConnection(android.telecom.PhoneAccountHandle, android.telecom.ConnectionRequest);
method public void onRemoteConferenceAdded(android.telecom.RemoteConference);
+ method public void onRemoteExistingConnectionAdded(android.telecom.RemoteConnection);
field public static final java.lang.String SERVICE_INTERFACE = "android.telecom.ConnectionService";
}
@@ -28207,6 +28226,7 @@
method public void writeToParcel(android.os.Parcel, int);
field public static final int BUSY = 7; // 0x7
field public static final int CANCELED = 4; // 0x4
+ field public static final int CONNECTION_MANAGER_NOT_SUPPORTED = 10; // 0xa
field public static final android.os.Parcelable.Creator<android.telecom.DisconnectCause> CREATOR;
field public static final int ERROR = 1; // 0x1
field public static final int LOCAL = 2; // 0x2
@@ -28384,10 +28404,12 @@
method public void addNewIncomingCall(android.telecom.PhoneAccountHandle, android.os.Bundle);
method public void cancelMissedCallsNotification();
method public void clearAccounts();
+ method public android.net.Uri getAdnUriForPhoneAccount(android.telecom.PhoneAccountHandle);
method public android.telecom.PhoneAccountHandle getConnectionManager();
method public android.telecom.PhoneAccount getPhoneAccount(android.telecom.PhoneAccountHandle);
method public java.util.List<android.telecom.PhoneAccountHandle> getPhoneAccountsForPackage();
method public boolean handleMmi(java.lang.String);
+ method public boolean handleMmi(android.telecom.PhoneAccountHandle, java.lang.String);
method public boolean hasMultipleCallCapableAccounts();
method public boolean isInCall();
method public void registerPhoneAccount(android.telecom.PhoneAccount);
@@ -28841,26 +28863,20 @@
}
public class SubInfoRecord implements android.os.Parcelable {
- ctor public SubInfoRecord();
- ctor public SubInfoRecord(int, java.lang.String, int, java.lang.String, int, int, java.lang.String, int, int, int[], int, int);
method public int describeContents();
method public int getColor();
- method public android.graphics.drawable.BitmapDrawable getIconDrawable();
- method public java.lang.String getLabel();
+ method public int getDataRoaming();
+ method public java.lang.CharSequence getDisplayName();
+ method public java.lang.String getIccId();
+ method public android.graphics.drawable.BitmapDrawable getIcon();
+ method public int getMcc();
+ method public int getMnc();
+ method public int getNameSource();
+ method public java.lang.String getNumber();
+ method public int getSimSlotIndex();
+ method public int getSubscriptionId();
method public void writeToParcel(android.os.Parcel, int);
field public static final android.os.Parcelable.Creator<android.telephony.SubInfoRecord> CREATOR;
- field public int color;
- field public int dataRoaming;
- field public java.lang.String displayName;
- field public int displayNumberFormat;
- field public java.lang.String iccId;
- field public int mcc;
- field public int mnc;
- field public int nameSource;
- field public java.lang.String number;
- field public int[] simIconRes;
- field public int slotId;
- field public int subId;
}
public class SubscriptionManager implements android.provider.BaseColumns {
@@ -30270,19 +30286,6 @@
method public static java.text.DateFormat getMediumDateFormat(android.content.Context);
method public static java.text.DateFormat getTimeFormat(android.content.Context);
method public static boolean is24HourFormat(android.content.Context);
- field public static final deprecated char AM_PM = 97; // 0x0061 'a'
- field public static final deprecated char CAPITAL_AM_PM = 65; // 0x0041 'A'
- field public static final deprecated char DATE = 100; // 0x0064 'd'
- field public static final deprecated char DAY = 69; // 0x0045 'E'
- field public static final deprecated char HOUR = 104; // 0x0068 'h'
- field public static final deprecated char HOUR_OF_DAY = 107; // 0x006b 'k'
- field public static final deprecated char MINUTE = 109; // 0x006d 'm'
- field public static final deprecated char MONTH = 77; // 0x004d 'M'
- field public static final deprecated char QUOTE = 39; // 0x0027 '\''
- field public static final deprecated char SECONDS = 115; // 0x0073 's'
- field public static final deprecated char STANDALONE_MONTH = 76; // 0x004c 'L'
- field public static final deprecated char TIME_ZONE = 122; // 0x007a 'z'
- field public static final deprecated char YEAR = 121; // 0x0079 'y'
}
public class DateUtils {
@@ -32151,6 +32154,7 @@
method public static int complexToDimensionPixelSize(int, android.util.DisplayMetrics);
method public static float complexToFloat(int);
method public static float complexToFraction(int, float, float);
+ method public int getComplexUnit();
method public float getDimension(android.util.DisplayMetrics);
method public final float getFloat();
method public float getFraction(float, float);
@@ -33606,6 +33610,8 @@
method public static int generateViewId();
method public int getAccessibilityLiveRegion();
method public android.view.accessibility.AccessibilityNodeProvider getAccessibilityNodeProvider();
+ method public int getAccessibilityTraversalAfter();
+ method public int getAccessibilityTraversalBefore();
method public float getAlpha();
method public android.view.animation.Animation getAnimation();
method public android.os.IBinder getApplicationWindowToken();
@@ -33882,6 +33888,8 @@
method public void sendAccessibilityEventUnchecked(android.view.accessibility.AccessibilityEvent);
method public void setAccessibilityDelegate(android.view.View.AccessibilityDelegate);
method public void setAccessibilityLiveRegion(int);
+ method public void setAccessibilityTraversalAfter(int);
+ method public void setAccessibilityTraversalBefore(int);
method public void setActivated(boolean);
method public void setAlpha(float);
method public void setAnimation(android.view.animation.Animation);
@@ -35161,6 +35169,8 @@
method public java.lang.CharSequence getText();
method public int getTextSelectionEnd();
method public int getTextSelectionStart();
+ method public android.view.accessibility.AccessibilityNodeInfo getTraversalAfter();
+ method public android.view.accessibility.AccessibilityNodeInfo getTraversalBefore();
method public java.lang.String getViewIdResourceName();
method public android.view.accessibility.AccessibilityWindowInfo getWindow();
method public int getWindowId();
@@ -35231,6 +35241,10 @@
method public void setSource(android.view.View, int);
method public void setText(java.lang.CharSequence);
method public void setTextSelection(int, int);
+ method public void setTraversalAfter(android.view.View);
+ method public void setTraversalAfter(android.view.View, int);
+ method public void setTraversalBefore(android.view.View);
+ method public void setTraversalBefore(android.view.View, int);
method public void setViewIdResourceName(java.lang.String);
method public void setVisibleToUser(boolean);
method public void writeToParcel(android.os.Parcel, int);
@@ -38428,6 +38442,8 @@
method public boolean onLoadClass(java.lang.Class);
method public void reapply(android.content.Context, android.view.View);
method public void removeAllViews(int);
+ method public void setAccessibilityTraversalAfter(int, int);
+ method public void setAccessibilityTraversalBefore(int, int);
method public void setBitmap(int, java.lang.String, android.graphics.Bitmap);
method public void setBoolean(int, java.lang.String, boolean);
method public void setBundle(int, java.lang.String, android.os.Bundle);
diff --git a/api/removed.txt b/api/removed.txt
index 8972679..1b69ee8 100644
--- a/api/removed.txt
+++ b/api/removed.txt
@@ -22,6 +22,26 @@
}
+package android.text.format {
+
+ public class DateFormat {
+ field public static final deprecated char AM_PM = 97; // 0x0061 'a'
+ field public static final deprecated char CAPITAL_AM_PM = 65; // 0x0041 'A'
+ field public static final deprecated char DATE = 100; // 0x0064 'd'
+ field public static final deprecated char DAY = 69; // 0x0045 'E'
+ field public static final deprecated char HOUR = 104; // 0x0068 'h'
+ field public static final deprecated char HOUR_OF_DAY = 107; // 0x006b 'k'
+ field public static final deprecated char MINUTE = 109; // 0x006d 'm'
+ field public static final deprecated char MONTH = 77; // 0x004d 'M'
+ field public static final deprecated char QUOTE = 39; // 0x0027 '\''
+ field public static final deprecated char SECONDS = 115; // 0x0073 's'
+ field public static final deprecated char STANDALONE_MONTH = 76; // 0x004c 'L'
+ field public static final deprecated char TIME_ZONE = 122; // 0x007a 'z'
+ field public static final deprecated char YEAR = 121; // 0x0079 'y'
+ }
+
+}
+
package android.view {
public class View implements android.view.accessibility.AccessibilityEventSource android.graphics.drawable.Drawable.Callback android.view.KeyEvent.Callback {
diff --git a/cmds/am/src/com/android/commands/am/Am.java b/cmds/am/src/com/android/commands/am/Am.java
index ba11a81..bc57030 100644
--- a/cmds/am/src/com/android/commands/am/Am.java
+++ b/cmds/am/src/com/android/commands/am/Am.java
@@ -417,7 +417,7 @@
} else if (opt.equals("--ei")) {
String key = nextArgRequired();
String value = nextArgRequired();
- intent.putExtra(key, Integer.valueOf(value));
+ intent.putExtra(key, Integer.decode(value));
} else if (opt.equals("--eu")) {
String key = nextArgRequired();
String value = nextArgRequired();
@@ -434,7 +434,7 @@
String[] strings = value.split(",");
int[] list = new int[strings.length];
for (int i = 0; i < strings.length; i++) {
- list[i] = Integer.valueOf(strings[i]);
+ list[i] = Integer.decode(strings[i]);
}
intent.putExtra(key, list);
} else if (opt.equals("--el")) {
@@ -477,8 +477,23 @@
hasIntentInfo = true;
} else if (opt.equals("--ez")) {
String key = nextArgRequired();
- String value = nextArgRequired();
- intent.putExtra(key, Boolean.valueOf(value));
+ String value = nextArgRequired().toLowerCase();
+ // Boolean.valueOf() results in false for anything that is not "true", which is
+ // error-prone in shell commands
+ boolean arg;
+ if ("true".equals(value) || "t".equals(value)) {
+ arg = true;
+ } else if ("false".equals(value) || "f".equals(value)) {
+ arg = false;
+ } else {
+ try {
+ arg = Integer.decode(value) != 0;
+ } catch (NumberFormatException ex) {
+ throw new IllegalArgumentException("Invalid boolean value: " + value);
+ }
+ }
+
+ intent.putExtra(key, arg);
} else if (opt.equals("-n")) {
String str = nextArgRequired();
ComponentName cn = ComponentName.unflattenFromString(str);
diff --git a/cmds/pm/src/com/android/commands/pm/Pm.java b/cmds/pm/src/com/android/commands/pm/Pm.java
index 5e9d8f7..7fd586f 100644
--- a/cmds/pm/src/com/android/commands/pm/Pm.java
+++ b/cmds/pm/src/com/android/commands/pm/Pm.java
@@ -96,8 +96,9 @@
"Error: Could not access the Package Manager. Is the system running?";
public static void main(String[] args) {
+ int exitCode = 1;
try {
- new Pm().run(args);
+ exitCode = new Pm().run(args);
} catch (Exception e) {
Log.e(TAG, "Error", e);
System.err.println("Error: " + e);
@@ -105,20 +106,20 @@
System.err.println(PM_NOT_RUNNING_ERR);
}
}
+ System.exit(exitCode);
}
- public void run(String[] args) throws IOException, RemoteException {
+ public int run(String[] args) throws IOException, RemoteException {
boolean validCommand = false;
if (args.length < 1) {
- showUsage();
- return;
+ return showUsage();
}
mUm = IUserManager.Stub.asInterface(ServiceManager.getService("user"));
mPm = IPackageManager.Stub.asInterface(ServiceManager.getService("package"));
if (mPm == null) {
System.err.println(PM_NOT_RUNNING_ERR);
- return;
+ return 1;
}
mInstaller = mPm.getPackageInstaller();
@@ -127,155 +128,129 @@
mNextArg = 1;
if ("list".equals(op)) {
- runList();
- return;
+ return runList();
}
if ("path".equals(op)) {
- runPath();
- return;
+ return runPath();
}
if ("dump".equals(op)) {
- runDump();
- return;
+ return runDump();
}
if ("install".equals(op)) {
- runInstall();
- return;
+ return runInstall();
}
if ("install-create".equals(op)) {
- runInstallCreate();
- return;
+ return runInstallCreate();
}
if ("install-write".equals(op)) {
- runInstallWrite();
- return;
+ return runInstallWrite();
}
if ("install-commit".equals(op)) {
- runInstallCommit();
- return;
+ return runInstallCommit();
}
if ("install-abandon".equals(op) || "install-destroy".equals(op)) {
- runInstallAbandon();
- return;
+ return runInstallAbandon();
}
if ("set-installer".equals(op)) {
- runSetInstaller();
- return;
+ return runSetInstaller();
}
if ("uninstall".equals(op)) {
- runUninstall();
- return;
+ return runUninstall();
}
if ("clear".equals(op)) {
- runClear();
- return;
+ return runClear();
}
if ("enable".equals(op)) {
- runSetEnabledSetting(PackageManager.COMPONENT_ENABLED_STATE_ENABLED);
- return;
+ return runSetEnabledSetting(PackageManager.COMPONENT_ENABLED_STATE_ENABLED);
}
if ("disable".equals(op)) {
- runSetEnabledSetting(PackageManager.COMPONENT_ENABLED_STATE_DISABLED);
- return;
+ return runSetEnabledSetting(PackageManager.COMPONENT_ENABLED_STATE_DISABLED);
}
if ("disable-user".equals(op)) {
- runSetEnabledSetting(PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER);
- return;
+ return runSetEnabledSetting(PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER);
}
if ("disable-until-used".equals(op)) {
- runSetEnabledSetting(PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED);
- return;
+ return runSetEnabledSetting(PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED);
}
if ("hide".equals(op)) {
- runSetHiddenSetting(true);
- return;
+ return runSetHiddenSetting(true);
}
if ("unhide".equals(op)) {
- runSetHiddenSetting(false);
- return;
+ return runSetHiddenSetting(false);
}
if ("grant".equals(op)) {
- runGrantRevokePermission(true);
- return;
+ return runGrantRevokePermission(true);
}
if ("revoke".equals(op)) {
- runGrantRevokePermission(false);
- return;
+ return runGrantRevokePermission(false);
}
if ("set-permission-enforced".equals(op)) {
- runSetPermissionEnforced();
- return;
+ return runSetPermissionEnforced();
}
if ("set-install-location".equals(op)) {
- runSetInstallLocation();
- return;
+ return runSetInstallLocation();
}
if ("get-install-location".equals(op)) {
- runGetInstallLocation();
- return;
+ return runGetInstallLocation();
}
if ("trim-caches".equals(op)) {
- runTrimCaches();
- return;
+ return runTrimCaches();
}
if ("create-user".equals(op)) {
- runCreateUser();
- return;
+ return runCreateUser();
}
if ("remove-user".equals(op)) {
- runRemoveUser();
- return;
+ return runRemoveUser();
}
if ("get-max-users".equals(op)) {
- runGetMaxUsers();
- return;
+ return runGetMaxUsers();
}
if ("force-dex-opt".equals(op)) {
- runForceDexOpt();
- return;
+ return runForceDexOpt();
}
try {
if (args.length == 1) {
if (args[0].equalsIgnoreCase("-l")) {
validCommand = true;
- runListPackages(false);
+ return runListPackages(false);
} else if (args[0].equalsIgnoreCase("-lf")){
validCommand = true;
- runListPackages(true);
+ return runListPackages(true);
}
} else if (args.length == 2) {
if (args[0].equalsIgnoreCase("-p")) {
validCommand = true;
- displayPackageFilePath(args[1]);
+ return displayPackageFilePath(args[1]);
}
}
+ return 1;
} finally {
if (validCommand == false) {
if (op != null) {
@@ -296,35 +271,36 @@
* pm list libraries
* pm list instrumentation
*/
- private void runList() {
+ private int runList() {
String type = nextArg();
if (type == null) {
System.err.println("Error: didn't specify type of data to list");
- return;
+ return 1;
}
if ("package".equals(type) || "packages".equals(type)) {
- runListPackages(false);
+ return runListPackages(false);
} else if ("permission-groups".equals(type)) {
- runListPermissionGroups();
+ return runListPermissionGroups();
} else if ("permissions".equals(type)) {
- runListPermissions();
+ return runListPermissions();
} else if ("features".equals(type)) {
- runListFeatures();
+ return runListFeatures();
} else if ("libraries".equals(type)) {
- runListLibraries();
+ return runListLibraries();
} else if ("instrumentation".equals(type)) {
- runListInstrumentation();
+ return runListInstrumentation();
} else if ("users".equals(type)) {
- runListUsers();
+ return runListUsers();
} else {
System.err.println("Error: unknown list type '" + type + "'");
+ return 1;
}
}
/**
* Lists all the installed packages.
*/
- private void runListPackages(boolean showApplicationPackage) {
+ private int runListPackages(boolean showApplicationPackage) {
int getFlags = 0;
boolean listDisabled = false, listEnabled = false;
boolean listSystem = false, listThirdParty = false;
@@ -355,12 +331,12 @@
getFlags |= PackageManager.GET_UNINSTALLED_PACKAGES;
} else {
System.err.println("Error: Unknown option: " + opt);
- return;
+ return 1;
}
}
} catch (RuntimeException ex) {
System.err.println("Error: " + ex.toString());
- return;
+ return 1;
}
String filter = nextArg();
@@ -393,9 +369,11 @@
System.out.println();
}
}
+ return 0;
} catch (RemoteException e) {
System.err.println(e.toString());
System.err.println(PM_NOT_RUNNING_ERR);
+ return 1;
}
}
@@ -411,7 +389,7 @@
*
* pm list features
*/
- private void runListFeatures() {
+ private int runListFeatures() {
try {
List<FeatureInfo> list = new ArrayList<FeatureInfo>();
FeatureInfo[] rawList = mPm.getSystemAvailableFeatures();
@@ -438,9 +416,11 @@
else System.out.println("reqGlEsVersion=0x"
+ Integer.toHexString(fi.reqGlEsVersion));
}
+ return 0;
} catch (RemoteException e) {
System.err.println(e.toString());
System.err.println(PM_NOT_RUNNING_ERR);
+ return 1;
}
}
@@ -449,7 +429,7 @@
*
* pm list libraries
*/
- private void runListLibraries() {
+ private int runListLibraries() {
try {
List<String> list = new ArrayList<String>();
String[] rawList = mPm.getSystemSharedLibraryNames();
@@ -474,9 +454,11 @@
System.out.print("library:");
System.out.println(lib);
}
+ return 0;
} catch (RemoteException e) {
System.err.println(e.toString());
System.err.println(PM_NOT_RUNNING_ERR);
+ return 1;
}
}
@@ -485,7 +467,7 @@
*
* pm list instrumentation [package] [-f]
*/
- private void runListInstrumentation() {
+ private int runListInstrumentation() {
int flags = 0; // flags != 0 is only used to request meta-data
boolean showPackage = false;
String targetPackage = null;
@@ -499,12 +481,12 @@
targetPackage = opt;
} else {
System.err.println("Error: Unknown option: " + opt);
- return;
+ return 1;
}
}
} catch (RuntimeException ex) {
System.err.println("Error: " + ex.toString());
- return;
+ return 1;
}
try {
@@ -531,16 +513,18 @@
System.out.print(ii.targetPackage);
System.out.println(")");
}
+ return 0;
} catch (RemoteException e) {
System.err.println(e.toString());
System.err.println(PM_NOT_RUNNING_ERR);
+ return 1;
}
}
/**
* Lists all the known permission groups.
*/
- private void runListPermissionGroups() {
+ private int runListPermissionGroups() {
try {
List<PermissionGroupInfo> pgs = mPm.getAllPermissionGroups(0);
@@ -550,9 +534,11 @@
System.out.print("permission group:");
System.out.println(pgi.name);
}
+ return 0;
} catch (RemoteException e) {
System.err.println(e.toString());
System.err.println(PM_NOT_RUNNING_ERR);
+ return 1;
}
}
@@ -572,7 +558,7 @@
/**
* Lists all the permissions in a group.
*/
- private void runListPermissions() {
+ private int runListPermissions() {
try {
boolean labels = false;
boolean groups = false;
@@ -595,7 +581,7 @@
dangerousOnly = true;
} else {
System.err.println("Error: Unknown option: " + opt);
- return;
+ return 1;
}
}
@@ -637,9 +623,11 @@
doListPermissions(groupList, groups, labels, summary,
-10000, 10000);
}
+ return 0;
} catch (RemoteException e) {
System.err.println(e.toString());
System.err.println(PM_NOT_RUNNING_ERR);
+ return 1;
}
}
@@ -739,22 +727,23 @@
}
}
- private void runPath() {
+ private int runPath() {
String pkg = nextArg();
if (pkg == null) {
System.err.println("Error: no package specified");
- return;
+ return 1;
}
- displayPackageFilePath(pkg);
+ return displayPackageFilePath(pkg);
}
- private void runDump() {
+ private int runDump() {
String pkg = nextArg();
if (pkg == null) {
System.err.println("Error: no package specified");
- return;
+ return 1;
}
ActivityManager.dumpPackageStateStatic(FileDescriptor.out, pkg);
+ return 0;
}
class LocalPackageInstallObserver extends PackageInstallObserver {
@@ -822,31 +811,34 @@
return Integer.toString(result);
}
- private void runSetInstallLocation() {
+ private int runSetInstallLocation() {
int loc;
String arg = nextArg();
if (arg == null) {
System.err.println("Error: no install location specified.");
- return;
+ return 1;
}
try {
loc = Integer.parseInt(arg);
} catch (NumberFormatException e) {
System.err.println("Error: install location has to be a number.");
- return;
+ return 1;
}
try {
if (!mPm.setInstallLocation(loc)) {
System.err.println("Error: install location has to be a number.");
+ return 1;
}
+ return 0;
} catch (RemoteException e) {
System.err.println(e.toString());
System.err.println(PM_NOT_RUNNING_ERR);
+ return 1;
}
}
- private void runGetInstallLocation() {
+ private int runGetInstallLocation() {
try {
int loc = mPm.getInstallLocation();
String locStr = "invalid";
@@ -858,13 +850,15 @@
locStr = "external";
}
System.out.println(loc + "[" + locStr + "]");
+ return 0;
} catch (RemoteException e) {
System.err.println(e.toString());
System.err.println(PM_NOT_RUNNING_ERR);
+ return 1;
}
}
- private void runInstall() {
+ private int runInstall() {
int installFlags = 0;
int userId = UserHandle.USER_ALL;
String installerPackageName = null;
@@ -884,7 +878,7 @@
installerPackageName = nextOptionData();
if (installerPackageName == null) {
System.err.println("Error: no value specified for -i");
- return;
+ return 1;
}
} else if (opt.equals("-t")) {
installFlags |= PackageManager.INSTALL_ALLOW_TEST;
@@ -900,13 +894,13 @@
originatingUriString = nextOptionData();
if (originatingUriString == null) {
System.err.println("Error: must supply argument for --originating-uri");
- return;
+ return 1;
}
} else if (opt.equals("--referrer")) {
referrer = nextOptionData();
if (referrer == null) {
System.err.println("Error: must supply argument for --referrer");
- return;
+ return 1;
}
} else if (opt.equals("--abi")) {
abi = checkAbiArgument(nextOptionData());
@@ -914,7 +908,7 @@
userId = Integer.parseInt(nextOptionData());
} else {
System.err.println("Error: Unknown option: " + opt);
- return;
+ return 1;
}
}
@@ -944,7 +938,7 @@
System.err.println("\tpkg: " + apkFilePath);
if (apkFilePath == null) {
System.err.println("Error: no package specified");
- return;
+ return 1;
}
// Populate verificationURI, optionally present
@@ -973,19 +967,22 @@
}
if (obs.result == PackageManager.INSTALL_SUCCEEDED) {
System.out.println("Success");
+ return 0;
} else {
System.err.println("Failure ["
+ installFailureToString(obs)
+ "]");
+ return 1;
}
}
} catch (RemoteException e) {
System.err.println(e.toString());
System.err.println(PM_NOT_RUNNING_ERR);
+ return 1;
}
}
- private void runInstallCreate() throws RemoteException {
+ private int runInstallCreate() throws RemoteException {
int userId = UserHandle.USER_ALL;
String installerPackageName = null;
@@ -1040,9 +1037,10 @@
// NOTE: adb depends on parsing this string
System.out.println("Success: created install session [" + sessionId + "]");
+ return 0;
}
- private void runInstallWrite() throws IOException, RemoteException {
+ private int runInstallWrite() throws IOException, RemoteException {
long sizeBytes = -1;
String opt;
@@ -1097,6 +1095,7 @@
session.fsync(out);
System.out.println("Success: streamed " + total + " bytes");
+ return 0;
} finally {
IoUtils.closeQuietly(out);
IoUtils.closeQuietly(in);
@@ -1104,7 +1103,7 @@
}
}
- private void runInstallCommit() throws RemoteException {
+ private int runInstallCommit() throws RemoteException {
final int sessionId = Integer.parseInt(nextArg());
PackageInstaller.Session session = null;
@@ -1119,18 +1118,19 @@
PackageInstaller.STATUS_FAILURE);
if (status == PackageInstaller.STATUS_SUCCESS) {
System.out.println("Success");
+ return 0;
} else {
Log.e(TAG, "Failure details: " + result.getExtras());
- System.out.println("Failure ["
+ System.err.println("Failure ["
+ result.getStringExtra(PackageInstaller.EXTRA_STATUS_MESSAGE) + "]");
- return;
+ return 1;
}
} finally {
IoUtils.closeQuietly(session);
}
}
- private void runInstallAbandon() throws RemoteException {
+ private int runInstallAbandon() throws RemoteException {
final int sessionId = Integer.parseInt(nextArg());
PackageInstaller.Session session = null;
@@ -1138,12 +1138,13 @@
session = new PackageInstaller.Session(mInstaller.openSession(sessionId));
session.abandon();
System.out.println("Success");
+ return 0;
} finally {
IoUtils.closeQuietly(session);
}
}
- private void runSetInstaller() throws RemoteException {
+ private int runSetInstaller() throws RemoteException {
final String targetPackage = nextArg();
final String installerPackageName = nextArg();
@@ -1154,9 +1155,10 @@
mPm.setInstallerPackageName(targetPackage, installerPackageName);
System.out.println("Success");
+ return 0;
}
- public void runCreateUser() {
+ public int runCreateUser() {
String name;
int userId = -1;
int flags = 0;
@@ -1167,7 +1169,7 @@
if (optionData == null || !isNumber(optionData)) {
System.err.println("Error: no USER_ID specified");
showUsage();
- return;
+ return 1;
} else {
userId = Integer.parseInt(optionData);
}
@@ -1176,13 +1178,13 @@
} else {
System.err.println("Error: unknown option " + opt);
showUsage();
- return;
+ return 1;
}
}
String arg = nextArg();
if (arg == null) {
System.err.println("Error: no user name specified.");
- return;
+ return 1;
}
name = arg;
try {
@@ -1194,75 +1196,85 @@
}
if (info != null) {
System.out.println("Success: created user id " + info.id);
+ return 1;
} else {
System.err.println("Error: couldn't create User.");
+ return 1;
}
} catch (RemoteException e) {
System.err.println(e.toString());
System.err.println(PM_NOT_RUNNING_ERR);
+ return 1;
}
-
}
- public void runRemoveUser() {
+ public int runRemoveUser() {
int userId;
String arg = nextArg();
if (arg == null) {
System.err.println("Error: no user id specified.");
- return;
+ return 1;
}
try {
userId = Integer.parseInt(arg);
} catch (NumberFormatException e) {
System.err.println("Error: user id '" + arg + "' is not a number.");
- return;
+ return 1;
}
try {
if (mUm.removeUser(userId)) {
System.out.println("Success: removed user");
+ return 0;
} else {
System.err.println("Error: couldn't remove user id " + userId);
+ return 1;
}
} catch (RemoteException e) {
System.err.println(e.toString());
System.err.println(PM_NOT_RUNNING_ERR);
+ return 1;
}
}
- public void runListUsers() {
+ public int runListUsers() {
try {
IActivityManager am = ActivityManagerNative.getDefault();
List<UserInfo> users = mUm.getUsers(false);
if (users == null) {
System.err.println("Error: couldn't get users");
+ return 1;
} else {
System.out.println("Users:");
for (int i = 0; i < users.size(); i++) {
String running = am.isUserRunning(users.get(i).id, false) ? " running" : "";
System.out.println("\t" + users.get(i).toString() + running);
}
+ return 0;
}
} catch (RemoteException e) {
System.err.println(e.toString());
System.err.println(PM_NOT_RUNNING_ERR);
+ return 1;
}
}
- public void runGetMaxUsers() {
+ public int runGetMaxUsers() {
System.out.println("Maximum supported users: " + UserManager.getMaxSupportedUsers());
+ return 0;
}
- public void runForceDexOpt() {
+ public int runForceDexOpt() {
final String packageName = nextArg();
try {
mPm.forceDexOpt(packageName);
+ return 0;
} catch (RemoteException e) {
throw e.rethrowAsRuntimeException();
}
}
- private void runUninstall() throws RemoteException {
+ private int runUninstall() throws RemoteException {
int flags = 0;
int userId = UserHandle.USER_ALL;
@@ -1277,11 +1289,11 @@
} else {
showUsage();
System.err.println("Error: Invalid user: " + param);
- return;
+ return 1;
}
} else {
System.err.println("Error: Unknown option: " + opt);
- return;
+ return 1;
}
}
@@ -1289,7 +1301,7 @@
if (pkg == null) {
System.err.println("Error: no package specified");
showUsage();
- return;
+ return 1;
}
if (userId == UserHandle.USER_ALL) {
@@ -1302,11 +1314,11 @@
} catch (RemoteException e) {
System.err.println(e.toString());
System.err.println(PM_NOT_RUNNING_ERR);
- return;
+ return 1;
}
if (info == null) {
System.err.println("Failure - not installed for " + userId);
- return;
+ return 1;
}
final boolean isSystem =
(info.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
@@ -1326,10 +1338,12 @@
PackageInstaller.STATUS_FAILURE);
if (status == PackageInstaller.STATUS_SUCCESS) {
System.out.println("Success");
+ return 0;
} else {
Log.e(TAG, "Failure details: " + result.getExtras());
- System.out.println("Failure ["
+ System.err.println("Failure ["
+ result.getStringExtra(PackageInstaller.EXTRA_STATUS_MESSAGE) + "]");
+ return 1;
}
}
@@ -1347,7 +1361,7 @@
}
}
- private void runClear() {
+ private int runClear() {
int userId = 0;
String option = nextOption();
if (option != null && option.equals("--user")) {
@@ -1355,7 +1369,7 @@
if (optionData == null || !isNumber(optionData)) {
System.err.println("Error: no USER_ID specified");
showUsage();
- return;
+ return 1;
} else {
userId = Integer.parseInt(optionData);
}
@@ -1365,7 +1379,7 @@
if (pkg == null) {
System.err.println("Error: no package specified");
showUsage();
- return;
+ return 1;
}
ClearDataObserver obs = new ClearDataObserver();
@@ -1381,13 +1395,16 @@
}
if (obs.result) {
- System.err.println("Success");
+ System.out.println("Success");
+ return 0;
} else {
System.err.println("Failed");
+ return 1;
}
} catch (RemoteException e) {
System.err.println(e.toString());
System.err.println(PM_NOT_RUNNING_ERR);
+ return 1;
}
}
@@ -1416,7 +1433,7 @@
return true;
}
- private void runSetEnabledSetting(int state) {
+ private int runSetEnabledSetting(int state) {
int userId = 0;
String option = nextOption();
if (option != null && option.equals("--user")) {
@@ -1424,7 +1441,7 @@
if (optionData == null || !isNumber(optionData)) {
System.err.println("Error: no USER_ID specified");
showUsage();
- return;
+ return 1;
} else {
userId = Integer.parseInt(optionData);
}
@@ -1434,34 +1451,38 @@
if (pkg == null) {
System.err.println("Error: no package or component specified");
showUsage();
- return;
+ return 1;
}
ComponentName cn = ComponentName.unflattenFromString(pkg);
if (cn == null) {
try {
mPm.setApplicationEnabledSetting(pkg, state, 0, userId,
"shell:" + android.os.Process.myUid());
- System.err.println("Package " + pkg + " new state: "
+ System.out.println("Package " + pkg + " new state: "
+ enabledSettingToString(
mPm.getApplicationEnabledSetting(pkg, userId)));
+ return 0;
} catch (RemoteException e) {
System.err.println(e.toString());
System.err.println(PM_NOT_RUNNING_ERR);
+ return 1;
}
} else {
try {
mPm.setComponentEnabledSetting(cn, state, 0, userId);
- System.err.println("Component " + cn.toShortString() + " new state: "
+ System.out.println("Component " + cn.toShortString() + " new state: "
+ enabledSettingToString(
mPm.getComponentEnabledSetting(cn, userId)));
+ return 0;
} catch (RemoteException e) {
System.err.println(e.toString());
System.err.println(PM_NOT_RUNNING_ERR);
+ return 1;
}
}
}
- private void runSetHiddenSetting(boolean state) {
+ private int runSetHiddenSetting(boolean state) {
int userId = 0;
String option = nextOption();
if (option != null && option.equals("--user")) {
@@ -1469,7 +1490,7 @@
if (optionData == null || !isNumber(optionData)) {
System.err.println("Error: no USER_ID specified");
showUsage();
- return;
+ return 1;
} else {
userId = Integer.parseInt(optionData);
}
@@ -1479,30 +1500,32 @@
if (pkg == null) {
System.err.println("Error: no package or component specified");
showUsage();
- return;
+ return 1;
}
try {
mPm.setApplicationHiddenSettingAsUser(pkg, state, userId);
- System.err.println("Package " + pkg + " new hidden state: "
+ System.out.println("Package " + pkg + " new hidden state: "
+ mPm.getApplicationHiddenSettingAsUser(pkg, userId));
+ return 0;
} catch (RemoteException e) {
System.err.println(e.toString());
System.err.println(PM_NOT_RUNNING_ERR);
+ return 1;
}
}
- private void runGrantRevokePermission(boolean grant) {
+ private int runGrantRevokePermission(boolean grant) {
String pkg = nextArg();
if (pkg == null) {
System.err.println("Error: no package specified");
showUsage();
- return;
+ return 1;
}
String perm = nextArg();
if (perm == null) {
System.err.println("Error: no permission specified");
showUsage();
- return;
+ return 1;
}
try {
if (grant) {
@@ -1510,41 +1533,49 @@
} else {
mPm.revokePermission(pkg, perm);
}
+ return 0;
} catch (RemoteException e) {
System.err.println(e.toString());
System.err.println(PM_NOT_RUNNING_ERR);
+ return 1;
} catch (IllegalArgumentException e) {
System.err.println("Bad argument: " + e.toString());
showUsage();
+ return 1;
} catch (SecurityException e) {
System.err.println("Operation not allowed: " + e.toString());
+ return 1;
}
}
- private void runSetPermissionEnforced() {
+ private int runSetPermissionEnforced() {
final String permission = nextArg();
if (permission == null) {
System.err.println("Error: no permission specified");
showUsage();
- return;
+ return 1;
}
final String enforcedRaw = nextArg();
if (enforcedRaw == null) {
System.err.println("Error: no enforcement specified");
showUsage();
- return;
+ return 1;
}
final boolean enforced = Boolean.parseBoolean(enforcedRaw);
try {
mPm.setPermissionEnforced(permission, enforced);
+ return 0;
} catch (RemoteException e) {
System.err.println(e.toString());
System.err.println(PM_NOT_RUNNING_ERR);
+ return 1;
} catch (IllegalArgumentException e) {
System.err.println("Bad argument: " + e.toString());
showUsage();
+ return 1;
} catch (SecurityException e) {
System.err.println("Operation not allowed: " + e.toString());
+ return 1;
}
}
@@ -1563,12 +1594,12 @@
}
- private void runTrimCaches() {
+ private int runTrimCaches() {
String size = nextArg();
if (size == null) {
System.err.println("Error: no size specified");
showUsage();
- return;
+ return 1;
}
int len = size.length();
long multiplier = 1;
@@ -1583,7 +1614,7 @@
} else {
System.err.println("Invalid suffix: " + c);
showUsage();
- return;
+ return 1;
}
size = size.substring(0, len-1);
}
@@ -1593,7 +1624,7 @@
} catch (NumberFormatException e) {
System.err.println("Error: expected number at: " + size);
showUsage();
- return;
+ return 1;
}
ClearDataObserver obs = new ClearDataObserver();
try {
@@ -1606,14 +1637,18 @@
}
}
}
+ return 0;
} catch (RemoteException e) {
System.err.println(e.toString());
System.err.println(PM_NOT_RUNNING_ERR);
+ return 1;
} catch (IllegalArgumentException e) {
System.err.println("Bad argument: " + e.toString());
showUsage();
+ return 1;
} catch (SecurityException e) {
System.err.println("Operation not allowed: " + e.toString());
+ return 1;
}
}
@@ -1621,7 +1656,7 @@
* Displays the package file for a package.
* @param pckg
*/
- private void displayPackageFilePath(String pckg) {
+ private int displayPackageFilePath(String pckg) {
try {
PackageInfo info = mPm.getPackageInfo(pckg, 0, 0);
if (info != null && info.applicationInfo != null) {
@@ -1632,12 +1667,14 @@
System.out.print("package:");
System.out.println(splitSourceDir);
}
+ return 0;
}
}
} catch (RemoteException e) {
System.err.println(e.toString());
System.err.println(PM_NOT_RUNNING_ERR);
}
+ return 1;
}
private Resources getResources(PackageItemInfo pii) {
@@ -1752,7 +1789,7 @@
return arg;
}
- private static void showUsage() {
+ private static int showUsage() {
System.err.println("usage: pm list packages [-f] [-d] [-e] [-s] [-3] [-i] [-u] [--user USER_ID] [FILTER]");
System.err.println(" pm list permission-groups");
System.err.println(" pm list permissions [-g] [-f] [-d] [-u] [GROUP]");
@@ -1873,5 +1910,6 @@
System.err.println("pm remove-user: remove the user with the given USER_IDENTIFIER,");
System.err.println(" deleting all data associated with that user");
System.err.println("");
+ return 1;
}
}
diff --git a/core/java/android/accessibilityservice/AccessibilityService.java b/core/java/android/accessibilityservice/AccessibilityService.java
index 1e1b33f..a9eaf29 100644
--- a/core/java/android/accessibilityservice/AccessibilityService.java
+++ b/core/java/android/accessibilityservice/AccessibilityService.java
@@ -24,11 +24,9 @@
import android.os.Message;
import android.os.RemoteException;
import android.util.Log;
-import android.view.Display;
import android.view.KeyEvent;
-import android.view.View;
-import android.view.ViewGroup;
import android.view.WindowManager;
+import android.view.WindowManagerGlobal;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityInteractionClient;
import android.view.accessibility.AccessibilityNodeInfo;
@@ -620,18 +618,6 @@
}
}
- @Override
- public Object getSystemService(String name) {
- if (Context.WINDOW_SERVICE.equals(name)) {
- if (mWindowManager == null) {
- WindowManager wrapped = (WindowManager) super.getSystemService(name);
- mWindowManager = new LocalWindowManager(wrapped);
- }
- return mWindowManager;
- }
- return super.getSystemService(name);
- }
-
/**
* Implement to return the implementation of the internal accessibility
* service interface.
@@ -658,6 +644,9 @@
public void init(int connectionId, IBinder windowToken) {
mConnectionId = connectionId;
mWindowToken = windowToken;
+
+ // Let the window manager know about our shiny new token.
+ WindowManagerGlobal.getInstance().setDefaultToken(mWindowToken);
}
@Override
@@ -812,53 +801,4 @@
}
}
}
-
- private class LocalWindowManager implements WindowManager {
- private final WindowManager mImpl;
-
- private LocalWindowManager(WindowManager impl) {
- mImpl = impl;
- }
-
- @Override
- public Display getDefaultDisplay() {
- return mImpl.getDefaultDisplay();
- }
-
- @Override
- public void addView(View view, ViewGroup.LayoutParams params) {
- if (!(params instanceof WindowManager.LayoutParams)) {
- throw new IllegalArgumentException("Params must be WindowManager.LayoutParams");
- }
- WindowManager.LayoutParams windowParams = (WindowManager.LayoutParams) params;
- if (windowParams.type == LayoutParams.TYPE_ACCESSIBILITY_OVERLAY
- && windowParams.token == null) {
- windowParams.token = mWindowToken;
- }
- mImpl.addView(view, params);
- }
-
- @Override
- public void updateViewLayout(View view, ViewGroup.LayoutParams params) {
- if (!(params instanceof WindowManager.LayoutParams)) {
- throw new IllegalArgumentException("Params must be WindowManager.LayoutParams");
- }
- WindowManager.LayoutParams windowParams = (WindowManager.LayoutParams) params;
- if (windowParams.type == LayoutParams.TYPE_ACCESSIBILITY_OVERLAY
- && windowParams.token == null) {
- windowParams.token = mWindowToken;
- }
- mImpl.updateViewLayout(view, params);
- }
-
- @Override
- public void removeViewImmediate(View view) {
- mImpl.removeViewImmediate(view);
- }
-
- @Override
- public void removeView(View view) {
- mImpl.removeView(view);
- }
- }
}
diff --git a/core/java/android/animation/ObjectAnimator.java b/core/java/android/animation/ObjectAnimator.java
index 500634c..59daaab 100644
--- a/core/java/android/animation/ObjectAnimator.java
+++ b/core/java/android/animation/ObjectAnimator.java
@@ -885,7 +885,8 @@
}
/**
- * Sets the target object whose property will be animated by this animation
+ * Sets the target object whose property will be animated by this animation. If the
+ * animator has been started, it will be canceled.
*
* @param target The object being animated
*/
@@ -893,6 +894,9 @@
public void setTarget(@Nullable Object target) {
final Object oldTarget = getTarget();
if (oldTarget != target) {
+ if (isStarted()) {
+ cancel();
+ }
mTarget = target == null ? null : new WeakReference<Object>(target);
// New target should cause re-initialization prior to starting
mInitialized = false;
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java
index 37e8aa4..a285932 100644
--- a/core/java/android/app/ActivityManager.java
+++ b/core/java/android/app/ActivityManager.java
@@ -1243,26 +1243,16 @@
}
/**
- * If set, the process of the root activity of the task will be killed
- * as part of removing the task.
- * @hide
- */
- public static final int REMOVE_TASK_KILL_PROCESS = 0x0001;
-
- /**
* Completely remove the given task.
*
* @param taskId Identifier of the task to be removed.
- * @param flags Additional operational flags. May be 0 or
- * {@link #REMOVE_TASK_KILL_PROCESS}.
* @return Returns true if the given task was found and removed.
*
* @hide
*/
- public boolean removeTask(int taskId, int flags)
- throws SecurityException {
+ public boolean removeTask(int taskId) throws SecurityException {
try {
- return ActivityManagerNative.getDefault().removeTask(taskId, flags);
+ return ActivityManagerNative.getDefault().removeTask(taskId);
} catch (RemoteException e) {
// System dead, we will be dead too soon!
return false;
diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java
index 4e2ff0b..bc7114b 100644
--- a/core/java/android/app/ActivityManagerNative.java
+++ b/core/java/android/app/ActivityManagerNative.java
@@ -1884,8 +1884,7 @@
{
data.enforceInterface(IActivityManager.descriptor);
int taskId = data.readInt();
- int fl = data.readInt();
- boolean result = removeTask(taskId, fl);
+ boolean result = removeTask(taskId);
reply.writeNoException();
reply.writeInt(result ? 1 : 0);
return true;
@@ -4778,12 +4777,11 @@
return result;
}
- public boolean removeTask(int taskId, int flags) throws RemoteException {
+ public boolean removeTask(int taskId) throws RemoteException {
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
data.writeInterfaceToken(IActivityManager.descriptor);
data.writeInt(taskId);
- data.writeInt(flags);
mRemote.transact(REMOVE_TASK_TRANSACTION, data, reply, 0);
reply.readException();
boolean result = reply.readInt() != 0;
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index fa15ad7..cf6c049 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -1742,6 +1742,12 @@
new LoadedApk(this, aInfo, compatInfo, baseLoader,
securityViolation, includeCode &&
(aInfo.flags&ApplicationInfo.FLAG_HAS_CODE) != 0, registerPackage);
+
+ if (mSystemThread && "android".equals(aInfo.packageName)) {
+ packageInfo.installSystemApplicationInfo(aInfo,
+ getSystemContext().mPackageInfo.getClassLoader());
+ }
+
if (includeCode) {
mPackages.put(aInfo.packageName,
new WeakReference<LoadedApk>(packageInfo));
@@ -1802,10 +1808,6 @@
synchronized (this) {
getSystemContext().installSystemApplicationInfo(info, classLoader);
- // The code package for "android" in the system server needs
- // to be the system context's package.
- mPackages.put("android", new WeakReference<LoadedApk>(getSystemContext().mPackageInfo));
-
// give ourselves a default profiler
mProfiler = new Profiler();
}
diff --git a/core/java/android/app/ActivityTransitionCoordinator.java b/core/java/android/app/ActivityTransitionCoordinator.java
index 82b6e35..9062892 100644
--- a/core/java/android/app/ActivityTransitionCoordinator.java
+++ b/core/java/android/app/ActivityTransitionCoordinator.java
@@ -638,6 +638,7 @@
if (decorView != null) {
decorView.getLocationOnScreen(decorLoc);
}
+ Matrix tempMatrix = new Matrix();
for (String name: names) {
Bundle sharedElementBundle = state.getBundle(name);
if (sharedElementBundle != null) {
@@ -647,7 +648,7 @@
snapshot = mListener.onCreateSnapshotView(context, parcelable);
}
if (snapshot != null) {
- setSharedElementState(snapshot, name, state, null, null, decorLoc);
+ setSharedElementState(snapshot, name, state, tempMatrix, null, decorLoc);
}
snapshots.add(snapshot);
}
diff --git a/core/java/android/app/EnterTransitionCoordinator.java b/core/java/android/app/EnterTransitionCoordinator.java
index 7894887..ecf19c7 100644
--- a/core/java/android/app/EnterTransitionCoordinator.java
+++ b/core/java/android/app/EnterTransitionCoordinator.java
@@ -133,16 +133,17 @@
return;
}
mAreViewsReady = true;
+ final ViewGroup decor = getDecor();
// Ensure the views have been laid out before capturing the views -- we need the epicenter.
- if (sharedElements.isEmpty() || !sharedElements.valueAt(0).isLayoutRequested()) {
+ if (decor == null || (decor.isAttachedToWindow() &&
+ (sharedElements.isEmpty() || !sharedElements.valueAt(0).isLayoutRequested()))) {
viewsReady(sharedElements);
} else {
- final View sharedElement = sharedElements.valueAt(0);
- sharedElement.getViewTreeObserver()
+ decor.getViewTreeObserver()
.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
@Override
public boolean onPreDraw() {
- sharedElement.getViewTreeObserver().removeOnPreDrawListener(this);
+ decor.getViewTreeObserver().removeOnPreDrawListener(this);
viewsReady(sharedElements);
return true;
}
diff --git a/core/java/android/app/IActivityManager.java b/core/java/android/app/IActivityManager.java
index be26f30..efcb197 100644
--- a/core/java/android/app/IActivityManager.java
+++ b/core/java/android/app/IActivityManager.java
@@ -373,7 +373,7 @@
public boolean isUserRunning(int userid, boolean orStopping) throws RemoteException;
public int[] getRunningUserIds() throws RemoteException;
- public boolean removeTask(int taskId, int flags) throws RemoteException;
+ public boolean removeTask(int taskId) throws RemoteException;
public void registerProcessObserver(IProcessObserver observer) throws RemoteException;
public void unregisterProcessObserver(IProcessObserver observer) throws RemoteException;
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index 9849c51..c65f017 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -4340,6 +4340,19 @@
*/
public static final int SIZE_FULL_SCREEN = 5;
+ /**
+ * Sentinel value for use with {@link #setHintScreenTimeout} to keep the screen on for a
+ * short amount of time when this notification is displayed on the screen. This
+ * is the default value.
+ */
+ public static final int SCREEN_TIMEOUT_SHORT = 0;
+
+ /**
+ * Sentinel value for use with {@link #setHintScreenTimeout} to keep the screen on
+ * for a longer amount of time when this notification is displayed on the screen.
+ */
+ public static final int SCREEN_TIMEOUT_LONG = -1;
+
/** Notification extra which contains wearable extensions */
private static final String EXTRA_WEARABLE_EXTENSIONS = "android.wearable.EXTENSIONS";
@@ -4355,12 +4368,14 @@
private static final String KEY_CUSTOM_SIZE_PRESET = "customSizePreset";
private static final String KEY_CUSTOM_CONTENT_HEIGHT = "customContentHeight";
private static final String KEY_GRAVITY = "gravity";
+ private static final String KEY_HINT_SCREEN_TIMEOUT = "hintScreenTimeout";
// Flags bitwise-ored to mFlags
private static final int FLAG_CONTENT_INTENT_AVAILABLE_OFFLINE = 0x1;
private static final int FLAG_HINT_HIDE_ICON = 1 << 1;
private static final int FLAG_HINT_SHOW_BACKGROUND_ONLY = 1 << 2;
private static final int FLAG_START_SCROLL_BOTTOM = 1 << 3;
+ private static final int FLAG_HINT_AVOID_BACKGROUND_CLIPPING = 1 << 4;
// Default value for flags integer
private static final int DEFAULT_FLAGS = FLAG_CONTENT_INTENT_AVAILABLE_OFFLINE;
@@ -4379,6 +4394,7 @@
private int mCustomSizePreset = SIZE_DEFAULT;
private int mCustomContentHeight;
private int mGravity = DEFAULT_GRAVITY;
+ private int mHintScreenTimeout;
/**
* Create a {@link android.app.Notification.WearableExtender} with default
@@ -4414,6 +4430,7 @@
SIZE_DEFAULT);
mCustomContentHeight = wearableBundle.getInt(KEY_CUSTOM_CONTENT_HEIGHT);
mGravity = wearableBundle.getInt(KEY_GRAVITY, DEFAULT_GRAVITY);
+ mHintScreenTimeout = wearableBundle.getInt(KEY_HINT_SCREEN_TIMEOUT);
}
}
@@ -4461,6 +4478,9 @@
if (mGravity != DEFAULT_GRAVITY) {
wearableBundle.putInt(KEY_GRAVITY, mGravity);
}
+ if (mHintScreenTimeout != 0) {
+ wearableBundle.putInt(KEY_HINT_SCREEN_TIMEOUT, mHintScreenTimeout);
+ }
builder.getExtras().putBundle(EXTRA_WEARABLE_EXTENSIONS, wearableBundle);
return builder;
@@ -4480,6 +4500,7 @@
that.mCustomSizePreset = this.mCustomSizePreset;
that.mCustomContentHeight = this.mCustomContentHeight;
that.mGravity = this.mGravity;
+ that.mHintScreenTimeout = this.mHintScreenTimeout;
return that;
}
@@ -4875,6 +4896,48 @@
return (mFlags & FLAG_HINT_SHOW_BACKGROUND_ONLY) != 0;
}
+ /**
+ * Set a hint that this notification's background should not be clipped if possible.
+ * @param hintAvoidBackgroundClipping {@code true} to avoid clipping if possible.
+ * @return this object for method chaining
+ */
+ public WearableExtender setHintAvoidBackgroundClipping(
+ boolean hintAvoidBackgroundClipping) {
+ setFlag(FLAG_HINT_AVOID_BACKGROUND_CLIPPING, hintAvoidBackgroundClipping);
+ return this;
+ }
+
+ /**
+ * Get a hint that this notification's background should not be clipped if possible.
+ * @return {@code true} if it's ok if the background is clipped on the screen, false
+ * otherwise. The default value is {@code false} if this was never set.
+ */
+ public boolean getHintAvoidBackgroundClipping() {
+ return (mFlags & FLAG_HINT_AVOID_BACKGROUND_CLIPPING) != 0;
+ }
+
+ /**
+ * Set a hint that the screen should remain on for at least this duration when
+ * this notification is displayed on the screen.
+ * @param timeout The requested screen timeout in milliseconds. Can also be either
+ * {@link #SCREEN_TIMEOUT_SHORT} or {@link #SCREEN_TIMEOUT_LONG}.
+ * @return this object for method chaining
+ */
+ public WearableExtender setHintScreenTimeout(int timeout) {
+ mHintScreenTimeout = timeout;
+ return this;
+ }
+
+ /**
+ * Get the duration, in milliseconds, that the screen should remain on for
+ * when this notification is displayed.
+ * @return the duration in milliseconds if > 0, or either one of the sentinel values
+ * {@link #SCREEN_TIMEOUT_SHORT} or {@link #SCREEN_TIMEOUT_LONG}.
+ */
+ public int getHintScreenTimeout() {
+ return mHintScreenTimeout;
+ }
+
private void setFlag(int mask, boolean value) {
if (value) {
mFlags |= mask;
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index a30ae57..d3ff79d 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -31,6 +31,7 @@
import android.net.ProxyInfo;
import android.os.Bundle;
import android.os.Handler;
+import android.os.PersistableBundle;
import android.os.Process;
import android.os.RemoteCallback;
import android.os.RemoteException;
@@ -40,6 +41,7 @@
import android.provider.Settings;
import android.security.Credentials;
import android.service.restrictions.RestrictionsReceiver;
+import android.service.trust.TrustAgentService;
import android.util.Log;
import com.android.org.conscrypt.TrustedCertificateStore;
@@ -2604,25 +2606,29 @@
}
/**
- * Sets a list of features to enable for a TrustAgent component. This is meant to be
- * used in conjunction with {@link #KEYGUARD_DISABLE_TRUST_AGENTS}, which will disable all
- * trust agents but those with features enabled by this function call.
+ * Sets a list of configuration features to enable for a TrustAgent component. This is meant
+ * to be used in conjunction with {@link #KEYGUARD_DISABLE_TRUST_AGENTS}, which disables all
+ * trust agents but those enabled by this function call. If flag
+ * {@link #KEYGUARD_DISABLE_TRUST_AGENTS} is not set, then this call has no effect.
*
* <p>The calling device admin must have requested
* {@link DeviceAdminInfo#USES_POLICY_DISABLE_KEYGUARD_FEATURES} to be able to call
- * this method; if it has not, a security exception will be thrown.
+ * this method; if not, a security exception will be thrown.
*
* @param admin Which {@link DeviceAdminReceiver} this request is associated with.
- * @param agent Which component to enable features for.
- * @param features List of features to enable. Consult specific TrustAgent documentation for
- * the feature list.
- * @hide
+ * @param target Component name of the agent to be enabled.
+ * @param options TrustAgent-specific feature bundle. If null for any admin, agent
+ * will be strictly disabled according to the state of the
+ * {@link #KEYGUARD_DISABLE_TRUST_AGENTS} flag.
+ * <p>If {@link #KEYGUARD_DISABLE_TRUST_AGENTS} is set and options is not null for all admins,
+ * then it's up to the TrustAgent itself to aggregate the values from all device admins.
+ * <p>Consult documentation for the specific TrustAgent to determine legal options parameters.
*/
- public void setTrustAgentFeaturesEnabled(ComponentName admin, ComponentName agent,
- List<String> features) {
+ public void setTrustAgentConfiguration(ComponentName admin, ComponentName target,
+ PersistableBundle options) {
if (mService != null) {
try {
- mService.setTrustAgentFeaturesEnabled(admin, agent, features, UserHandle.myUserId());
+ mService.setTrustAgentConfiguration(admin, target, options, UserHandle.myUserId());
} catch (RemoteException e) {
Log.w(TAG, "Failed talking with device policy service", e);
}
@@ -2630,24 +2636,30 @@
}
/**
- * Gets list of enabled features for the given TrustAgent component. If admin is
- * null, this will return the intersection of all features enabled for the given agent by all
- * admins.
+ * Gets configuration for the given trust agent based on aggregating all calls to
+ * {@link #setTrustAgentConfiguration(ComponentName, ComponentName, PersistableBundle)} for
+ * all device admins.
*
* @param admin Which {@link DeviceAdminReceiver} this request is associated with.
* @param agent Which component to get enabled features for.
- * @return List of enabled features.
- * @hide
+ * @return configuration for the given trust agent.
*/
- public List<String> getTrustAgentFeaturesEnabled(ComponentName admin, ComponentName agent) {
+ public List<PersistableBundle> getTrustAgentConfiguration(ComponentName admin,
+ ComponentName agent) {
+ return getTrustAgentConfiguration(admin, agent, UserHandle.myUserId());
+ }
+
+ /** @hide per-user version */
+ public List<PersistableBundle> getTrustAgentConfiguration(ComponentName admin,
+ ComponentName agent, int userHandle) {
if (mService != null) {
try {
- return mService.getTrustAgentFeaturesEnabled(admin, agent, UserHandle.myUserId());
+ return mService.getTrustAgentConfiguration(admin, agent, userHandle);
} catch (RemoteException e) {
Log.w(TAG, "Failed talking with device policy service", e);
}
}
- return new ArrayList<String>(); // empty list
+ return new ArrayList<PersistableBundle>(); // empty list
}
/**
@@ -3133,9 +3145,10 @@
}
/**
- * Called by a profile owner to disable account management for a specific type of account.
+ * Called by a device owner or profile owner to disable account management for a specific type
+ * of account.
*
- * <p>The calling device admin must be a profile owner. If it is not, a
+ * <p>The calling device admin must be a device owner or profile owner. If it is not, a
* security exception will be thrown.
*
* <p>When account management is disabled for an account type, adding or removing an account
diff --git a/core/java/android/app/admin/IDevicePolicyManager.aidl b/core/java/android/app/admin/IDevicePolicyManager.aidl
index c8e1780..07aa800 100644
--- a/core/java/android/app/admin/IDevicePolicyManager.aidl
+++ b/core/java/android/app/admin/IDevicePolicyManager.aidl
@@ -22,6 +22,7 @@
import android.content.IntentFilter;
import android.net.ProxyInfo;
import android.os.Bundle;
+import android.os.PersistableBundle;
import android.os.RemoteCallback;
import android.os.UserHandle;
import java.util.List;
@@ -183,8 +184,10 @@
boolean getCrossProfileCallerIdDisabled(in ComponentName who);
boolean getCrossProfileCallerIdDisabledForUser(int userId);
- void setTrustAgentFeaturesEnabled(in ComponentName admin, in ComponentName agent, in List<String> features, int userId);
- List<String> getTrustAgentFeaturesEnabled(in ComponentName admin, in ComponentName agent, int userId);
+ void setTrustAgentConfiguration(in ComponentName admin, in ComponentName agent,
+ in PersistableBundle args, int userId);
+ List<PersistableBundle> getTrustAgentConfiguration(in ComponentName admin,
+ in ComponentName agent, int userId);
boolean addCrossProfileWidgetProvider(in ComponentName admin, String packageName);
boolean removeCrossProfileWidgetProvider(in ComponentName admin, String packageName);
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index 7676e4b..e06f034 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -41,6 +41,7 @@
import android.os.IBinder;
import android.os.Parcel;
import android.os.Parcelable;
+import android.os.Process;
import android.os.StrictMode;
import android.os.UserHandle;
import android.provider.DocumentsContract;
@@ -7498,8 +7499,10 @@
*/
public void prepareToEnterProcess() {
if (mContentUserHint != UserHandle.USER_CURRENT) {
- fixUris(mContentUserHint);
- mContentUserHint = UserHandle.USER_CURRENT;
+ if (UserHandle.getAppId(Process.myUid()) != Process.SYSTEM_UID) {
+ fixUris(mContentUserHint);
+ mContentUserHint = UserHandle.USER_CURRENT;
+ }
}
}
diff --git a/core/java/android/content/pm/LauncherApps.java b/core/java/android/content/pm/LauncherApps.java
index 5ee0b67..c164340 100644
--- a/core/java/android/content/pm/LauncherApps.java
+++ b/core/java/android/content/pm/LauncherApps.java
@@ -499,20 +499,4 @@
obtainMessage(MSG_UNAVAILABLE, info).sendToTarget();
}
}
-
- /**
- * TODO Remove after 2014-09-22
- * @hide
- */
- public void addCallback(Callback callback) {
- registerCallback(callback);
- }
-
- /**
- * TODO Remove after 2014-09-22
- * @hide
- */
- public void removeCallback(Callback callback) {
- unregisterCallback(callback);
- }
}
diff --git a/core/java/android/content/res/Resources.java b/core/java/android/content/res/Resources.java
index 6e9efe1..0145e05 100644
--- a/core/java/android/content/res/Resources.java
+++ b/core/java/android/content/res/Resources.java
@@ -18,6 +18,7 @@
import android.animation.Animator;
import android.animation.StateListAnimator;
+import android.annotation.NonNull;
import android.util.Pools.SynchronizedPool;
import android.view.ViewDebug;
import com.android.internal.util.XmlUtils;
@@ -1548,20 +1549,21 @@
* contents of the typed array are ultimately filled in by
* {@link Resources#getValue}.
*
- * @param values The base set of attribute values, must be equal
- * in length to {@code attrs} or {@code null}. All values
- * must be of type {@link TypedValue#TYPE_ATTRIBUTE}.
+ * @param values The base set of attribute values, must be equal in
+ * length to {@code attrs}. All values must be of type
+ * {@link TypedValue#TYPE_ATTRIBUTE}.
* @param attrs The desired attributes to be retrieved.
* @return Returns a TypedArray holding an array of the attribute
* values. Be sure to call {@link TypedArray#recycle()}
* when done with it.
* @hide
*/
- public TypedArray resolveAttributes(int[] values, int[] attrs) {
+ @NonNull
+ public TypedArray resolveAttributes(@NonNull int[] values, @NonNull int[] attrs) {
final int len = attrs.length;
- if (values != null && len != values.length) {
+ if (values == null || len != values.length) {
throw new IllegalArgumentException(
- "Base attribute values must be null or the same length as attrs");
+ "Base attribute values must the same length as attrs");
}
final TypedArray array = TypedArray.obtain(Resources.this, len);
diff --git a/core/java/android/hardware/display/DisplayManagerInternal.java b/core/java/android/hardware/display/DisplayManagerInternal.java
index 8447dde..bb162153 100644
--- a/core/java/android/hardware/display/DisplayManagerInternal.java
+++ b/core/java/android/hardware/display/DisplayManagerInternal.java
@@ -172,9 +172,12 @@
// If true, enables automatic brightness control.
public boolean useAutoBrightness;
- //If true, scales the brightness to half of desired.
+ // If true, scales the brightness to half of desired.
public boolean lowPowerMode;
+ // If true, applies a brightness boost.
+ public boolean boostScreenBrightness;
+
// If true, prevents the screen from completely turning on if it is currently off.
// The display does not enter a "ready" state if this flag is true and screen on is
// blocked. The window manager policy blocks screen on while it prepares the keyguard to
@@ -216,6 +219,7 @@
useAutoBrightness = other.useAutoBrightness;
blockScreenOn = other.blockScreenOn;
lowPowerMode = other.lowPowerMode;
+ boostScreenBrightness = other.boostScreenBrightness;
dozeScreenBrightness = other.dozeScreenBrightness;
dozeScreenState = other.dozeScreenState;
}
@@ -235,6 +239,7 @@
&& useAutoBrightness == other.useAutoBrightness
&& blockScreenOn == other.blockScreenOn
&& lowPowerMode == other.lowPowerMode
+ && boostScreenBrightness == other.boostScreenBrightness
&& dozeScreenBrightness == other.dozeScreenBrightness
&& dozeScreenState == other.dozeScreenState;
}
@@ -253,6 +258,7 @@
+ ", useAutoBrightness=" + useAutoBrightness
+ ", blockScreenOn=" + blockScreenOn
+ ", lowPowerMode=" + lowPowerMode
+ + ", boostScreenBrightness=" + boostScreenBrightness
+ ", dozeScreenBrightness=" + dozeScreenBrightness
+ ", dozeScreenState=" + Display.stateToString(dozeScreenState);
}
diff --git a/core/java/android/hardware/hdmi/HdmiRecordListener.java b/core/java/android/hardware/hdmi/HdmiRecordListener.java
index 29f6cfc..90b7768 100644
--- a/core/java/android/hardware/hdmi/HdmiRecordListener.java
+++ b/core/java/android/hardware/hdmi/HdmiRecordListener.java
@@ -39,6 +39,8 @@
/**
* Called when one touch record is started or failed during initialization.
*
+ * @param recorderAddress An address of recorder that reports result of one touch record
+ * request
* @param result result code. For more details, please look at all constants starting with
* "ONE_TOUCH_RECORD_". Only
* {@link HdmiControlManager#ONE_TOUCH_RECORD_RECORDING_CURRENTLY_SELECTED_SOURCE},
@@ -47,15 +49,17 @@
* {@link HdmiControlManager#ONE_TOUCH_RECORD_RECORDING_EXTERNAL_INPUT} mean normal
* start of recording; otherwise, describes failure.
*/
- public void onOneTouchRecordResult(int result) {
+ public void onOneTouchRecordResult(int recorderAddress, int result) {
}
/**
* Called when timer recording is started or failed during initialization.
*
+ * @param recorderAddress An address of recorder that reports result of timer recording
+ * request
* @param data timer status data. For more details, look at {@link TimerStatusData}.
*/
- public void onTimerRecordingResult(TimerStatusData data) {
+ public void onTimerRecordingResult(int recorderAddress, TimerStatusData data) {
}
/**
@@ -230,6 +234,8 @@
/**
* Called when receiving result for clear timer recording request.
*
+ * @param recorderAddress An address of recorder that reports result of clear timer recording
+ * request
* @param result result of clear timer. It should be one of
* {@link HdmiControlManager#CLEAR_TIMER_STATUS_TIMER_NOT_CLEARED_RECORDING}
* {@link HdmiControlManager#CLEAR_TIMER_STATUS_TIMER_NOT_CLEARED_NO_MATCHING},
@@ -239,6 +245,6 @@
* {@link HdmiControlManager#CLEAR_TIMER_STATUS_FAIL_TO_CLEAR_SELECTED_SOURCE},
* {@link HdmiControlManager#CLEAR_TIMER_STATUS_CEC_DISABLE}.
*/
- public void onClearTimerRecordingResult(int result) {
+ public void onClearTimerRecordingResult(int recorderAddress, int result) {
}
}
diff --git a/core/java/android/hardware/hdmi/HdmiTvClient.java b/core/java/android/hardware/hdmi/HdmiTvClient.java
index dbfb4ef..cef17dd 100644
--- a/core/java/android/hardware/hdmi/HdmiTvClient.java
+++ b/core/java/android/hardware/hdmi/HdmiTvClient.java
@@ -226,19 +226,19 @@
}
@Override
- public void onOneTouchRecordResult(int result) {
- callback.onOneTouchRecordResult(result);
+ public void onOneTouchRecordResult(int recorderAddress, int result) {
+ callback.onOneTouchRecordResult(recorderAddress, result);
}
@Override
- public void onTimerRecordingResult(int result) {
- callback.onTimerRecordingResult(
+ public void onTimerRecordingResult(int recorderAddress, int result) {
+ callback.onTimerRecordingResult(recorderAddress,
HdmiRecordListener.TimerStatusData.parseFrom(result));
}
@Override
- public void onClearTimerRecordingResult(int result) {
- callback.onClearTimerRecordingResult(result);
+ public void onClearTimerRecordingResult(int recorderAddress, int result) {
+ callback.onClearTimerRecordingResult(recorderAddress, result);
}
};
}
diff --git a/core/java/android/hardware/hdmi/IHdmiRecordListener.aidl b/core/java/android/hardware/hdmi/IHdmiRecordListener.aidl
index 44d9065..d2deb38 100644
--- a/core/java/android/hardware/hdmi/IHdmiRecordListener.aidl
+++ b/core/java/android/hardware/hdmi/IHdmiRecordListener.aidl
@@ -31,19 +31,25 @@
/**
* Called when one touch record is started or failed during initialization.
*
+ * @param recorderAddress An address of recorder that reports result of one touch record
+ * request
* @param result result code for one touch record
*/
- void onOneTouchRecordResult(int result);
+ void onOneTouchRecordResult(int recorderAddress, int result);
/**
* Called when timer recording is started or failed during initialization.
-
+ *
+ * @param recorderAddress An address of recorder that reports result of timer recording
+ * request
* @param result result code for timer recording
*/
- void onTimerRecordingResult(int result);
+ void onTimerRecordingResult(int recorderAddress, int result);
/**
* Called when receiving result for clear timer recording request.
*
- * @param result result of clear timer.
+ * @param recorderAddress An address of recorder that reports result of clear timer recording
+ * request
+ * @param result result of clear timer
*/
- void onClearTimerRecordingResult(int result);
+ void onClearTimerRecordingResult(int recorderAddress, int result);
}
\ No newline at end of file
diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java
index 9194ca8..a09c6c7 100644
--- a/core/java/android/net/ConnectivityManager.java
+++ b/core/java/android/net/ConnectivityManager.java
@@ -1012,60 +1012,57 @@
return null;
}
+ /**
+ * Guess what the network request was trying to say so that the resulting
+ * network is accessible via the legacy (deprecated) API such as
+ * requestRouteToHost.
+ * This means we should try to be fairly preceise about transport and
+ * capability but ignore things such as networkSpecifier.
+ * If the request has more than one transport or capability it doesn't
+ * match the old legacy requests (they selected only single transport/capability)
+ * so this function cannot map the request to a single legacy type and
+ * the resulting network will not be available to the legacy APIs.
+ *
+ * TODO - This should be removed when the legacy APIs are removed.
+ */
private int inferLegacyTypeForNetworkCapabilities(NetworkCapabilities netCap) {
if (netCap == null) {
return TYPE_NONE;
}
+
if (!netCap.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)) {
return TYPE_NONE;
}
+
+ String type = null;
+ int result = TYPE_NONE;
+
if (netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_CBS)) {
- if (netCap.equals(networkCapabilitiesForFeature(TYPE_MOBILE, "enableCBS"))) {
- return TYPE_MOBILE_CBS;
- } else {
- return TYPE_NONE;
- }
+ type = "enableCBS";
+ result = TYPE_MOBILE_CBS;
+ } else if (netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_IMS)) {
+ type = "enableIMS";
+ result = TYPE_MOBILE_IMS;
+ } else if (netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_FOTA)) {
+ type = "enableFOTA";
+ result = TYPE_MOBILE_FOTA;
+ } else if (netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_DUN)) {
+ type = "enableDUN";
+ result = TYPE_MOBILE_DUN;
+ } else if (netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_SUPL)) {
+ type = "enableSUPL";
+ result = TYPE_MOBILE_SUPL;
+ } else if (netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_MMS)) {
+ type = "enableMMS";
+ result = TYPE_MOBILE_MMS;
+ } else if (netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)) {
+ type = "enableHIPRI";
+ result = TYPE_MOBILE_HIPRI;
}
- if (netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_IMS)) {
- if (netCap.equals(networkCapabilitiesForFeature(TYPE_MOBILE, "enableIMS"))) {
- return TYPE_MOBILE_IMS;
- } else {
- return TYPE_NONE;
- }
- }
- if (netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_FOTA)) {
- if (netCap.equals(networkCapabilitiesForFeature(TYPE_MOBILE, "enableFOTA"))) {
- return TYPE_MOBILE_FOTA;
- } else {
- return TYPE_NONE;
- }
- }
- if (netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_DUN)) {
- if (netCap.equals(networkCapabilitiesForFeature(TYPE_MOBILE, "enableDUN"))) {
- return TYPE_MOBILE_DUN;
- } else {
- return TYPE_NONE;
- }
- }
- if (netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_SUPL)) {
- if (netCap.equals(networkCapabilitiesForFeature(TYPE_MOBILE, "enableSUPL"))) {
- return TYPE_MOBILE_SUPL;
- } else {
- return TYPE_NONE;
- }
- }
- if (netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_MMS)) {
- if (netCap.equals(networkCapabilitiesForFeature(TYPE_MOBILE, "enableMMS"))) {
- return TYPE_MOBILE_MMS;
- } else {
- return TYPE_NONE;
- }
- }
- if (netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)) {
- if (netCap.equals(networkCapabilitiesForFeature(TYPE_MOBILE, "enableHIPRI"))) {
- return TYPE_MOBILE_HIPRI;
- } else {
- return TYPE_NONE;
+ if (type != null) {
+ NetworkCapabilities testCap = networkCapabilitiesForFeature(TYPE_MOBILE, type);
+ if (testCap.equalsNetCapabilities(netCap) && testCap.equalsTransportTypes(netCap)) {
+ return result;
}
}
return TYPE_NONE;
diff --git a/core/java/android/net/DhcpResults.java b/core/java/android/net/DhcpResults.java
index 71df60a..6159e1e 100644
--- a/core/java/android/net/DhcpResults.java
+++ b/core/java/android/net/DhcpResults.java
@@ -200,7 +200,7 @@
vendorInfo = info;
}
- public void setDomains(String domains) {
- domains = domains;
+ public void setDomains(String newDomains) {
+ domains = newDomains;
}
}
diff --git a/core/java/android/net/NetworkCapabilities.java b/core/java/android/net/NetworkCapabilities.java
index 1efe478..ce7ad65 100644
--- a/core/java/android/net/NetworkCapabilities.java
+++ b/core/java/android/net/NetworkCapabilities.java
@@ -235,7 +235,8 @@
return ((nc.mNetworkCapabilities & this.mNetworkCapabilities) == this.mNetworkCapabilities);
}
- private boolean equalsNetCapabilities(NetworkCapabilities nc) {
+ /** @hide */
+ public boolean equalsNetCapabilities(NetworkCapabilities nc) {
return (nc.mNetworkCapabilities == this.mNetworkCapabilities);
}
@@ -344,7 +345,8 @@
return ((this.mTransportTypes == 0) ||
((this.mTransportTypes & nc.mTransportTypes) != 0));
}
- private boolean equalsTransportTypes(NetworkCapabilities nc) {
+ /** @hide */
+ public boolean equalsTransportTypes(NetworkCapabilities nc) {
return (nc.mTransportTypes == this.mTransportTypes);
}
diff --git a/core/java/android/net/NetworkScoreManager.java b/core/java/android/net/NetworkScoreManager.java
index 3f68a44..a939cce 100644
--- a/core/java/android/net/NetworkScoreManager.java
+++ b/core/java/android/net/NetworkScoreManager.java
@@ -41,10 +41,10 @@
* <ul>
* <li>Declares the {@link android.Manifest.permission#SCORE_NETWORKS} permission.
* <li>Includes a receiver for {@link #ACTION_SCORE_NETWORKS} guarded by the
- * {@link android.Manifest.permission#BROADCAST_SCORE_NETWORKS} permission which scores networks
- * and (eventually) calls {@link #updateScores} with the results. If this receiver specifies an
- * android:label attribute, this label will be used when referring to the application throughout
- * system settings; otherwise, the application label will be used.
+ * {@link android.Manifest.permission#BROADCAST_NETWORK_PRIVILEGED} permission which scores
+ * networks and (eventually) calls {@link #updateScores} with the results. If this receiver
+ * specifies an android:label attribute, this label will be used when referring to the
+ * application throughout system settings; otherwise, the application label will be used.
* </ul>
*
* <p>The system keeps track of an active scorer application; at any time, only this application
@@ -192,12 +192,15 @@
/**
* Set the active scorer to a new package and clear existing scores.
*
+ * <p>Should never be called directly without obtaining user consent. This can be done by using
+ * the {@link #ACTION_CHANGE_ACTIVE} broadcast, or using a custom configuration activity.
+ *
* @return true if the operation succeeded, or false if the new package is not a valid scorer.
* @throws SecurityException if the caller does not hold the
- * {@link android.Manifest.permission#BROADCAST_SCORE_NETWORKS} permission indicating
- * that it can manage scorer applications.
+ * {@link android.Manifest.permission#SCORE_NETWORKS} permission.
* @hide
*/
+ @SystemApi
public boolean setActiveScorer(String packageName) throws SecurityException {
try {
return mService.setActiveScorer(packageName);
@@ -228,7 +231,7 @@
*
* @return true if the broadcast was sent, or false if there is no active scorer.
* @throws SecurityException if the caller does not hold the
- * {@link android.Manifest.permission#BROADCAST_SCORE_NETWORKS} permission.
+ * {@link android.Manifest.permission#BROADCAST_NETWORK_PRIVILEGED} permission.
* @hide
*/
public boolean requestScores(NetworkKey[] networks) throws SecurityException {
@@ -252,7 +255,7 @@
* @param networkType the type of network this cache can handle. See {@link NetworkKey#type}.
* @param scoreCache implementation of {@link INetworkScoreCache} to store the scores.
* @throws SecurityException if the caller does not hold the
- * {@link android.Manifest.permission#BROADCAST_SCORE_NETWORKS} permission.
+ * {@link android.Manifest.permission#BROADCAST_NETWORK_PRIVILEGED} permission.
* @throws IllegalArgumentException if a score cache is already registered for this type.
* @hide
*/
diff --git a/core/java/android/net/NetworkScorerAppManager.java b/core/java/android/net/NetworkScorerAppManager.java
index c33f5ec..46f7194 100644
--- a/core/java/android/net/NetworkScorerAppManager.java
+++ b/core/java/android/net/NetworkScorerAppManager.java
@@ -79,7 +79,7 @@
* <ul>
* <li>Declares the {@link android.Manifest.permission#SCORE_NETWORKS} permission.
* <li>Includes a receiver for {@link NetworkScoreManager#ACTION_SCORE_NETWORKS} guarded by the
- * {@link android.Manifest.permission#BROADCAST_SCORE_NETWORKS} permission.
+ * {@link android.Manifest.permission#BROADCAST_NETWORK_PRIVILEGED} permission.
* </ul>
*
* @return the list of scorers, or the empty list if there are no valid scorers.
@@ -98,8 +98,8 @@
// Should never happen with queryBroadcastReceivers, but invalid nonetheless.
continue;
}
- if (!permission.BROADCAST_SCORE_NETWORKS.equals(receiverInfo.permission)) {
- // Receiver doesn't require the BROADCAST_SCORE_NETWORKS permission, which means
+ if (!permission.BROADCAST_NETWORK_PRIVILEGED.equals(receiverInfo.permission)) {
+ // Receiver doesn't require the BROADCAST_NETWORK_PRIVILEGED permission, which means
// anyone could trigger network scoring and flood the framework with score requests.
continue;
}
diff --git a/core/java/android/net/PskKeyManager.java b/core/java/android/net/PskKeyManager.java
index d162282..f82e635 100644
--- a/core/java/android/net/PskKeyManager.java
+++ b/core/java/android/net/PskKeyManager.java
@@ -81,6 +81,13 @@
* Subclasses should normally provide their own implementation of {@code getKey} because the default
* implementation returns no key, which aborts the handshake.
*
+ * <h3>Known issues</h3>
+ * The implementation of {@code ECDHE_PSK} cipher suites in API Level 21 contains a bug which breaks
+ * compatibility with other implementations. {@code ECDHE_PSK} cipher suites are enabled by default
+ * on platforms with API Level 21 when an {@code SSLContext} is initialized with a
+ * {@code PskKeyManager}. A workaround is to disable {@code ECDHE_PSK} cipher suites on platforms
+ * with API Level 21.
+ *
* <h3>Example</h3>
* The following example illustrates how to create an {@code SSLContext} which enables the use of
* TLS-PSK in {@code SSLSocket}, {@code SSLServerSocket} and {@code SSLEngine} instances obtained
diff --git a/core/java/android/net/StaticIpConfiguration.java b/core/java/android/net/StaticIpConfiguration.java
index 5a273cf..598a503 100644
--- a/core/java/android/net/StaticIpConfiguration.java
+++ b/core/java/android/net/StaticIpConfiguration.java
@@ -107,6 +107,7 @@
for (InetAddress dns : dnsServers) {
lp.addDnsServer(dns);
}
+ lp.setDomains(domains);
return lp;
}
diff --git a/core/java/android/os/Debug.java b/core/java/android/os/Debug.java
index 084ca30..3f42d25 100644
--- a/core/java/android/os/Debug.java
+++ b/core/java/android/os/Debug.java
@@ -165,7 +165,7 @@
public int otherSwappedOut;
/** @hide */
- public static final int NUM_OTHER_STATS = 16;
+ public static final int NUM_OTHER_STATS = 17;
/** @hide */
public static final int NUM_DVK_STATS = 5;
@@ -296,23 +296,24 @@
case 1: return "Stack";
case 2: return "Cursor";
case 3: return "Ashmem";
- case 4: return "Other dev";
- case 5: return ".so mmap";
- case 6: return ".jar mmap";
- case 7: return ".apk mmap";
- case 8: return ".ttf mmap";
- case 9: return ".dex mmap";
- case 10: return "code mmap";
- case 11: return "image mmap";
- case 12: return "Other mmap";
- case 13: return "Graphics";
- case 14: return "GL";
- case 15: return "Memtrack";
- case 16: return ".Heap";
- case 17: return ".LOS";
- case 18: return ".LinearAlloc";
- case 19: return ".GC";
- case 20: return ".JITCache";
+ case 4: return "Gfx driver";
+ case 5: return "Other dev";
+ case 6: return ".so mmap";
+ case 7: return ".jar mmap";
+ case 8: return ".apk mmap";
+ case 9: return ".ttf mmap";
+ case 10: return ".dex mmap";
+ case 11: return ".oat mmap";
+ case 12: return ".art mmap";
+ case 13: return "Other mmap";
+ case 14: return "Graphics";
+ case 15: return "GL";
+ case 16: return "Memtrack";
+ case 17: return ".Heap";
+ case 18: return ".LOS";
+ case 19: return ".LinearAlloc";
+ case 20: return ".GC";
+ case 21: return ".JITCache";
default: return "????";
}
}
diff --git a/core/java/android/os/INetworkManagementService.aidl b/core/java/android/os/INetworkManagementService.aidl
index d0ba4b8..5d5d2b3 100644
--- a/core/java/android/os/INetworkManagementService.aidl
+++ b/core/java/android/os/INetworkManagementService.aidl
@@ -92,6 +92,11 @@
void enableIpv6(String iface);
/**
+ * Enables or enables IPv6 ND offload.
+ */
+ void setInterfaceIpv6NdOffload(String iface, boolean enable);
+
+ /**
* Retrieves the network routes currently configured on the specified
* interface
*/
diff --git a/core/java/android/os/IPowerManager.aidl b/core/java/android/os/IPowerManager.aidl
index 182dbee..ec30684 100644
--- a/core/java/android/os/IPowerManager.aidl
+++ b/core/java/android/os/IPowerManager.aidl
@@ -50,6 +50,7 @@
void setStayOnSetting(int val);
void setMaximumScreenOffTimeoutFromDeviceAdmin(int timeMs);
+ void boostScreenBrightness(long time);
// temporarily overrides the screen brightness settings to allow the user to
// see the effect of a settings change without applying it immediately
diff --git a/core/java/android/os/PowerManager.java b/core/java/android/os/PowerManager.java
index 3b6ce53..8307d9b 100644
--- a/core/java/android/os/PowerManager.java
+++ b/core/java/android/os/PowerManager.java
@@ -669,6 +669,28 @@
}
/**
+ * Boosts the brightness of the screen to maximum for a predetermined
+ * period of time. This is used to make the screen more readable in bright
+ * daylight for a short duration.
+ * <p>
+ * Requires the {@link android.Manifest.permission#DEVICE_POWER} permission.
+ * </p>
+ *
+ * @param time The time when the request to boost was issued, in the
+ * {@link SystemClock#uptimeMillis()} time base. This timestamp is used to correctly
+ * order the boost request with other power management functions. It should be set
+ * to the timestamp of the input event that caused the request to boost.
+ *
+ * @hide Requires signature permission.
+ */
+ public void boostScreenBrightness(long time) {
+ try {
+ mService.boostScreenBrightness(time);
+ } catch (RemoteException e) {
+ }
+ }
+
+ /**
* Sets the brightness of the backlights (screen, keyboard, button).
* <p>
* Requires the {@link android.Manifest.permission#DEVICE_POWER} permission.
diff --git a/core/java/android/print/IPrintDocumentAdapter.aidl b/core/java/android/print/IPrintDocumentAdapter.aidl
index 9d384fb..8f33e0b 100644
--- a/core/java/android/print/IPrintDocumentAdapter.aidl
+++ b/core/java/android/print/IPrintDocumentAdapter.aidl
@@ -37,4 +37,5 @@
void write(in PageRange[] pages, in ParcelFileDescriptor fd,
IWriteResultCallback callback, int sequence);
void finish();
+ void kill(String reason);
}
diff --git a/core/java/android/print/PrintManager.java b/core/java/android/print/PrintManager.java
index bf8ac65..3fb812e 100644
--- a/core/java/android/print/PrintManager.java
+++ b/core/java/android/print/PrintManager.java
@@ -634,6 +634,17 @@
}
@Override
+ public void kill(String reason) {
+ synchronized (mLock) {
+ // If destroyed the handler is null.
+ if (!isDestroyedLocked()) {
+ mHandler.obtainMessage(MyHandler.MSG_ON_KILL,
+ reason).sendToTarget();
+ }
+ }
+ }
+
+ @Override
public void onActivityPaused(Activity activity) {
/* do nothing */
}
@@ -719,6 +730,7 @@
public static final int MSG_ON_LAYOUT = 2;
public static final int MSG_ON_WRITE = 3;
public static final int MSG_ON_FINISH = 4;
+ public static final int MSG_ON_KILL = 5;
public MyHandler(Looper looper) {
super(looper, null, true);
@@ -794,6 +806,15 @@
}
} break;
+ case MSG_ON_KILL: {
+ if (DEBUG) {
+ Log.i(LOG_TAG, "onKill()");
+ }
+
+ String reason = (String) message.obj;
+ throw new RuntimeException(reason);
+ }
+
default: {
throw new IllegalArgumentException("Unknown message: "
+ message.what);
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index c091d25..1ea520d 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -872,8 +872,9 @@
/**
* Activity Action: Show battery saver settings.
- *
- * @hide
+ * <p>
+ * In some cases, a matching Activity may not exist, so ensure you safeguard
+ * against this.
*/
@SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
public static final String ACTION_BATTERY_SAVER_SETTINGS
@@ -2624,12 +2625,6 @@
public static final String LOCK_TO_APP_ENABLED = "lock_to_app_enabled";
/**
- * Whether lock-to-app will lock the keyguard when exiting.
- * @hide
- */
- public static final String LOCK_TO_APP_EXIT_LOCKED = "lock_to_app_exit_locked";
-
- /**
* I am the lolrus.
* <p>
* Nonzero values indicate that the user has a bukkit.
@@ -2703,6 +2698,7 @@
POINTER_SPEED,
VIBRATE_WHEN_RINGING,
RINGTONE,
+ LOCK_TO_APP_ENABLED,
NOTIFICATION_SOUND
};
@@ -3665,6 +3661,12 @@
"lock_biometric_weak_flags";
/**
+ * Whether lock-to-app will lock the keyguard when exiting.
+ * @hide
+ */
+ public static final String LOCK_TO_APP_EXIT_LOCKED = "lock_to_app_exit_locked";
+
+ /**
* Whether autolock is enabled (0 = false, 1 = true)
*/
public static final String LOCK_PATTERN_ENABLED = "lock_pattern_autolock";
@@ -6628,7 +6630,8 @@
WIFI_NUM_OPEN_NETWORKS_KEPT,
EMERGENCY_TONE,
CALL_AUTO_RETRY,
- DOCK_AUDIO_MEDIA_ENABLED
+ DOCK_AUDIO_MEDIA_ENABLED,
+ LOW_POWER_MODE_TRIGGER_LEVEL
};
// Populated lazily, guarded by class object:
diff --git a/core/java/android/service/notification/ZenModeConfig.java b/core/java/android/service/notification/ZenModeConfig.java
index 9a84a1e..36401eb 100644
--- a/core/java/android/service/notification/ZenModeConfig.java
+++ b/core/java/android/service/notification/ZenModeConfig.java
@@ -78,6 +78,7 @@
private static final String ALLOW_ATT_EVENTS = "events";
private static final String SLEEP_TAG = "sleep";
private static final String SLEEP_ATT_MODE = "mode";
+ private static final String SLEEP_ATT_NONE = "none";
private static final String SLEEP_ATT_START_HR = "startHour";
private static final String SLEEP_ATT_START_MIN = "startMin";
@@ -107,6 +108,7 @@
public int sleepStartMinute; // 0-59
public int sleepEndHour;
public int sleepEndMinute;
+ public boolean sleepNone; // false = priority, true = none
public ComponentName[] conditionComponents;
public Uri[] conditionIds;
public Condition exitCondition;
@@ -125,6 +127,7 @@
sleepStartMinute = source.readInt();
sleepEndHour = source.readInt();
sleepEndMinute = source.readInt();
+ sleepNone = source.readInt() == 1;
int len = source.readInt();
if (len > 0) {
conditionComponents = new ComponentName[len];
@@ -155,6 +158,7 @@
dest.writeInt(sleepStartMinute);
dest.writeInt(sleepEndHour);
dest.writeInt(sleepEndMinute);
+ dest.writeInt(sleepNone ? 1 : 0);
if (conditionComponents != null && conditionComponents.length > 0) {
dest.writeInt(conditionComponents.length);
dest.writeTypedArray(conditionComponents, 0);
@@ -182,6 +186,7 @@
.append(",sleepMode=").append(sleepMode)
.append(",sleepStart=").append(sleepStartHour).append('.').append(sleepStartMinute)
.append(",sleepEnd=").append(sleepEndHour).append('.').append(sleepEndMinute)
+ .append(",sleepNone=").append(sleepNone)
.append(",conditionComponents=")
.append(conditionComponents == null ? null : TextUtils.join(",", conditionComponents))
.append(",conditionIds=")
@@ -214,6 +219,7 @@
&& other.allowFrom == allowFrom
&& other.allowEvents == allowEvents
&& Objects.equals(other.sleepMode, sleepMode)
+ && other.sleepNone == sleepNone
&& other.sleepStartHour == sleepStartHour
&& other.sleepStartMinute == sleepStartMinute
&& other.sleepEndHour == sleepEndHour
@@ -226,7 +232,7 @@
@Override
public int hashCode() {
- return Objects.hash(allowCalls, allowMessages, allowFrom, allowEvents, sleepMode,
+ return Objects.hash(allowCalls, allowMessages, allowFrom, allowEvents, sleepMode, sleepNone,
sleepStartHour, sleepStartMinute, sleepEndHour, sleepEndMinute,
Arrays.hashCode(conditionComponents), Arrays.hashCode(conditionIds),
exitCondition, exitConditionComponent);
@@ -302,6 +308,7 @@
} else if (SLEEP_TAG.equals(tag)) {
final String mode = parser.getAttributeValue(null, SLEEP_ATT_MODE);
rt.sleepMode = isValidSleepMode(mode)? mode : null;
+ rt.sleepNone = safeBoolean(parser, SLEEP_ATT_NONE, false);
final int startHour = safeInt(parser, SLEEP_ATT_START_HR, 0);
final int startMinute = safeInt(parser, SLEEP_ATT_START_MIN, 0);
final int endHour = safeInt(parser, SLEEP_ATT_END_HR, 0);
@@ -345,6 +352,7 @@
if (sleepMode != null) {
out.attribute(null, SLEEP_ATT_MODE, sleepMode);
}
+ out.attribute(null, SLEEP_ATT_NONE, Boolean.toString(sleepNone));
out.attribute(null, SLEEP_ATT_START_HR, Integer.toString(sleepStartHour));
out.attribute(null, SLEEP_ATT_START_MIN, Integer.toString(sleepStartMinute));
out.attribute(null, SLEEP_ATT_END_HR, Integer.toString(sleepEndHour));
@@ -498,7 +506,7 @@
}
// For built-in conditions
- private static final String SYSTEM_AUTHORITY = "android";
+ public static final String SYSTEM_AUTHORITY = "android";
// Built-in countdown conditions, e.g. condition://android/countdown/1399917958951
private static final String COUNTDOWN_PATH = "countdown";
diff --git a/core/java/android/service/trust/ITrustAgentService.aidl b/core/java/android/service/trust/ITrustAgentService.aidl
index bd80a3f..bb0c2b2 100644
--- a/core/java/android/service/trust/ITrustAgentService.aidl
+++ b/core/java/android/service/trust/ITrustAgentService.aidl
@@ -15,7 +15,7 @@
*/
package android.service.trust;
-import android.os.Bundle;
+import android.os.PersistableBundle;
import android.service.trust.ITrustAgentServiceCallback;
/**
@@ -25,6 +25,6 @@
interface ITrustAgentService {
oneway void onUnlockAttempt(boolean successful);
oneway void onTrustTimeout();
+ oneway void onConfigure(in List<PersistableBundle> options, IBinder token);
oneway void setCallback(ITrustAgentServiceCallback callback);
- oneway void setTrustAgentFeaturesEnabled(in Bundle options, IBinder token);
}
diff --git a/core/java/android/service/trust/ITrustAgentServiceCallback.aidl b/core/java/android/service/trust/ITrustAgentServiceCallback.aidl
index b107bcc..76b2be0 100644
--- a/core/java/android/service/trust/ITrustAgentServiceCallback.aidl
+++ b/core/java/android/service/trust/ITrustAgentServiceCallback.aidl
@@ -27,5 +27,5 @@
void grantTrust(CharSequence message, long durationMs, boolean initiatedByUser);
void revokeTrust();
void setManagingTrust(boolean managingTrust);
- void onSetTrustAgentFeaturesEnabledCompleted(boolean result, IBinder token);
+ void onConfigureCompleted(boolean result, IBinder token);
}
diff --git a/core/java/android/service/trust/TrustAgentService.java b/core/java/android/service/trust/TrustAgentService.java
index 3ef5b37..00d60c0 100644
--- a/core/java/android/service/trust/TrustAgentService.java
+++ b/core/java/android/service/trust/TrustAgentService.java
@@ -29,11 +29,14 @@
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
+import android.os.PersistableBundle;
import android.os.RemoteException;
import android.os.SystemClock;
import android.util.Log;
import android.util.Slog;
+import java.util.List;
+
/**
* A service that notifies the system about whether it believes the environment of the device
* to be trusted.
@@ -86,17 +89,47 @@
*/
public static final String TRUST_AGENT_META_DATA = "android.service.trust.trustagent";
- /**
- * A white list of features that the given trust agent should support when otherwise disabled
- * by device policy.
- * @hide
- */
- public static final String KEY_FEATURES = "trust_agent_features";
-
private static final int MSG_UNLOCK_ATTEMPT = 1;
- private static final int MSG_SET_TRUST_AGENT_FEATURES_ENABLED = 2;
+ private static final int MSG_CONFIGURE = 2;
private static final int MSG_TRUST_TIMEOUT = 3;
+ /**
+ * Container class for a list of configuration options and helper methods
+ */
+ public static final class Configuration {
+ public final List<PersistableBundle> options;
+ public Configuration(List<PersistableBundle> opts) {
+ options = opts;
+ }
+
+ /**
+ * Very basic method to determine if all bundles have the given feature, regardless
+ * of type.
+ * @param option String to search for.
+ * @return true if found in all bundles.
+ */
+ public boolean hasOption(String option) {
+ if (options == null || options.size() == 0) return false;
+ final int N = options.size();
+ for (int i = 0; i < N; i++) {
+ if (!options.get(i).containsKey(option)) return false;
+ }
+ return true;
+ }
+ }
+
+ /**
+ * Class containing raw data for a given configuration request.
+ */
+ private static final class ConfigurationData {
+ final IBinder token;
+ final List<PersistableBundle> options;
+ ConfigurationData(List<PersistableBundle> opts, IBinder t) {
+ options = opts;
+ token = t;
+ }
+ }
+
private ITrustAgentServiceCallback mCallback;
private Runnable mPendingGrantTrustTask;
@@ -112,13 +145,12 @@
case MSG_UNLOCK_ATTEMPT:
onUnlockAttempt(msg.arg1 != 0);
break;
- case MSG_SET_TRUST_AGENT_FEATURES_ENABLED:
- Bundle features = msg.peekData();
- IBinder token = (IBinder) msg.obj;
- boolean result = onSetTrustAgentFeaturesEnabled(features);
+ case MSG_CONFIGURE:
+ ConfigurationData data = (ConfigurationData) msg.obj;
+ boolean result = onConfigure(new Configuration(data.options));
try {
synchronized (mLock) {
- mCallback.onSetTrustAgentFeaturesEnabledCompleted(result, token);
+ mCallback.onConfigureCompleted(result, data.token);
}
} catch (RemoteException e) {
onError("calling onSetTrustAgentFeaturesEnabledCompleted()");
@@ -171,23 +203,16 @@
}
/**
- * Called when device policy wants to restrict features in the agent in response to
- * {@link DevicePolicyManager#setTrustAgentFeaturesEnabled(ComponentName, ComponentName, java.util.List) }.
- * Agents that support this feature should overload this method and return 'true'.
+ * Called when device policy admin wants to enable specific options for agent in response to
+ * {@link DevicePolicyManager#setKeyguardDisabledFeatures(ComponentName, int)} and
+ * {@link DevicePolicyManager#setTrustAgentConfiguration(ComponentName, ComponentName,
+ * PersistableBundle)}.
+ * <p>Agents that support configuration options should overload this method and return 'true'.
*
- * The list of options can be obtained by calling
- * options.getStringArrayList({@link #KEY_FEATURES}). Presence of a feature string in the list
- * means it should be enabled ("white-listed"). Absence of the feature means it should be
- * disabled. An empty list means all features should be disabled.
- *
- * This function is only called if {@link DevicePolicyManager#KEYGUARD_DISABLE_TRUST_AGENTS} is
- * set.
- *
- * @param options Option feature bundle.
- * @return true if the {@link TrustAgentService} supports this feature.
- * @hide
+ * @param options bundle containing all options or null if none.
+ * @return true if the {@link TrustAgentService} supports configuration options.
*/
- public boolean onSetTrustAgentFeaturesEnabled(Bundle options) {
+ public boolean onConfigure(Configuration options) {
return false;
}
@@ -295,6 +320,12 @@
}
@Override /* Binder API */
+ public void onConfigure(List<PersistableBundle> args, IBinder token) {
+ mHandler.obtainMessage(MSG_CONFIGURE, new ConfigurationData(args, token))
+ .sendToTarget();
+ }
+
+ @Override /* Binder API */
public void setCallback(ITrustAgentServiceCallback callback) {
synchronized (mLock) {
mCallback = callback;
@@ -313,13 +344,6 @@
}
}
}
-
- @Override /* Binder API */
- public void setTrustAgentFeaturesEnabled(Bundle features, IBinder token) {
- Message msg = mHandler.obtainMessage(MSG_SET_TRUST_AGENT_FEATURES_ENABLED, token);
- msg.setData(features);
- msg.sendToTarget();
- }
}
}
diff --git a/core/java/android/text/format/DateFormat.java b/core/java/android/text/format/DateFormat.java
index 9fec9a1..933bcee 100755
--- a/core/java/android/text/format/DateFormat.java
+++ b/core/java/android/text/format/DateFormat.java
@@ -60,27 +60,45 @@
* {@code SimpleDateFormat}.
*/
public class DateFormat {
- /** @deprecated Use a literal {@code '} instead. */
+ /**
+ * @deprecated Use a literal {@code '} instead.
+ * @removed
+ */
@Deprecated
public static final char QUOTE = '\'';
- /** @deprecated Use a literal {@code 'a'} instead. */
+ /**
+ * @deprecated Use a literal {@code 'a'} instead.
+ * @removed
+ */
@Deprecated
public static final char AM_PM = 'a';
- /** @deprecated Use a literal {@code 'a'} instead; 'A' was always equivalent to 'a'. */
+ /**
+ * @deprecated Use a literal {@code 'a'} instead; 'A' was always equivalent to 'a'.
+ * @removed
+ */
@Deprecated
public static final char CAPITAL_AM_PM = 'A';
- /** @deprecated Use a literal {@code 'd'} instead. */
+ /**
+ * @deprecated Use a literal {@code 'd'} instead.
+ * @removed
+ */
@Deprecated
public static final char DATE = 'd';
- /** @deprecated Use a literal {@code 'E'} instead. */
+ /**
+ * @deprecated Use a literal {@code 'E'} instead.
+ * @removed
+ */
@Deprecated
public static final char DAY = 'E';
- /** @deprecated Use a literal {@code 'h'} instead. */
+ /**
+ * @deprecated Use a literal {@code 'h'} instead.
+ * @removed
+ */
@Deprecated
public static final char HOUR = 'h';
@@ -88,31 +106,51 @@
* @deprecated Use a literal {@code 'H'} (for compatibility with {@link SimpleDateFormat}
* and Unicode) or {@code 'k'} (for compatibility with Android releases up to and including
* Jelly Bean MR-1) instead. Note that the two are incompatible.
+ *
+ * @removed
*/
@Deprecated
public static final char HOUR_OF_DAY = 'k';
- /** @deprecated Use a literal {@code 'm'} instead. */
+ /**
+ * @deprecated Use a literal {@code 'm'} instead.
+ * @removed
+ */
@Deprecated
public static final char MINUTE = 'm';
- /** @deprecated Use a literal {@code 'M'} instead. */
+ /**
+ * @deprecated Use a literal {@code 'M'} instead.
+ * @removed
+ */
@Deprecated
public static final char MONTH = 'M';
- /** @deprecated Use a literal {@code 'L'} instead. */
+ /**
+ * @deprecated Use a literal {@code 'L'} instead.
+ * @removed
+ */
@Deprecated
public static final char STANDALONE_MONTH = 'L';
- /** @deprecated Use a literal {@code 's'} instead. */
+ /**
+ * @deprecated Use a literal {@code 's'} instead.
+ * @removed
+ */
@Deprecated
public static final char SECONDS = 's';
- /** @deprecated Use a literal {@code 'z'} instead. */
+ /**
+ * @deprecated Use a literal {@code 'z'} instead.
+ * @removed
+ */
@Deprecated
public static final char TIME_ZONE = 'z';
- /** @deprecated Use a literal {@code 'y'} instead. */
+ /**
+ * @deprecated Use a literal {@code 'y'} instead.
+ * @removed
+ */
@Deprecated
public static final char YEAR = 'y';
@@ -306,9 +344,9 @@
}
/**
- * Gets the current date format stored as a char array. The array will contain
- * 3 elements ({@link #DATE}, {@link #MONTH}, and {@link #YEAR}) in the order
- * specified by the user's format preference. Note that this order is
+ * Gets the current date format stored as a char array. Returns a 3 element
+ * array containing the day ({@code 'd'}), month ({@code 'M'}), and year ({@code 'y'}))
+ * in the order specified by the user's format preference. Note that this order is
* <i>only</i> appropriate for all-numeric dates; spelled-out (MEDIUM and LONG)
* dates will generally contain other punctuation, spaces, or words,
* not just the day, month, and year, and not necessarily in the same
diff --git a/core/java/android/transition/Transition.java b/core/java/android/transition/Transition.java
index e99c2cf..2705bcf 100644
--- a/core/java/android/transition/Transition.java
+++ b/core/java/android/transition/Transition.java
@@ -84,8 +84,8 @@
*
* <p>Custom transition classes may be instantiated with a <code>transition</code> tag:</p>
* <pre><transition class="my.app.transition.CustomTransition"/></pre>
- * <p>Custom transition classes loaded from XML must have a public nullary (no argument)
- * constructor.</p>
+ * <p>Custom transition classes loaded from XML should have a public constructor taking
+ * a {@link android.content.Context} and {@link android.util.AttributeSet}.</p>
*
* <p>Note that attributes for the transition are not required, just as they are
* optional when declared in code; Transitions created from XML resources will use
@@ -955,7 +955,7 @@
* Views with different IDs, or no IDs whatsoever, will be ignored.
*
* <p>Note that using ids to specify targets implies that ids should be unique
- * within the view hierarchy underneat the scene root.</p>
+ * within the view hierarchy underneath the scene root.</p>
*
* @see View#getId()
* @param targetId The id of a target view, must be a positive number.
diff --git a/core/java/android/util/TypedValue.java b/core/java/android/util/TypedValue.java
index d42ed03..74d4245 100644
--- a/core/java/android/util/TypedValue.java
+++ b/core/java/android/util/TypedValue.java
@@ -312,6 +312,18 @@
}
/**
+ * Return the complex unit type for this value. For example, a dimen type
+ * with value 12sp will return {@link #COMPLEX_UNIT_SP}. Only use for values
+ * whose type is {@link #TYPE_DIMENSION}.
+ *
+ * @return The complex unit type.
+ */
+ public int getComplexUnit()
+ {
+ return COMPLEX_UNIT_MASK & (data>>TypedValue.COMPLEX_UNIT_SHIFT);
+ }
+
+ /**
* Converts an unpacked complex data value holding a dimension to its final floating
* point value. The two parameters <var>unit</var> and <var>value</var>
* are as in {@link #TYPE_DIMENSION}.
diff --git a/core/java/android/view/AccessibilityInteractionController.java b/core/java/android/view/AccessibilityInteractionController.java
index 1cadf69..5e05683 100644
--- a/core/java/android/view/AccessibilityInteractionController.java
+++ b/core/java/android/view/AccessibilityInteractionController.java
@@ -1109,15 +1109,17 @@
|| accessibilityViewId == providerHost.getAccessibilityViewId()) {
final AccessibilityNodeInfo parent;
if (virtualDescendantId != AccessibilityNodeInfo.UNDEFINED_ITEM_ID) {
- parent = provider.createAccessibilityNodeInfo(
- virtualDescendantId);
+ parent = provider.createAccessibilityNodeInfo(virtualDescendantId);
} else {
- parent= provider.createAccessibilityNodeInfo(
+ parent = provider.createAccessibilityNodeInfo(
AccessibilityNodeProvider.HOST_VIEW_ID);
}
- if (parent != null) {
- outInfos.add(parent);
+ if (parent == null) {
+ // Couldn't obtain the parent, which means we have a
+ // disconnected sub-tree. Abort prefetch immediately.
+ return;
}
+ outInfos.add(parent);
parentNodeId = parent.getParentNodeId();
accessibilityViewId = AccessibilityNodeInfo.getAccessibilityViewId(
parentNodeId);
diff --git a/core/java/android/view/IWindow.aidl b/core/java/android/view/IWindow.aidl
index 3e7aae0..9fc80fc 100644
--- a/core/java/android/view/IWindow.aidl
+++ b/core/java/android/view/IWindow.aidl
@@ -85,4 +85,9 @@
* is done.
*/
void doneAnimating();
+
+ /**
+ * Called for non-application windows when the enter animation has completed.
+ */
+ void dispatchWindowShown();
}
diff --git a/core/java/android/view/RenderNodeAnimator.java b/core/java/android/view/RenderNodeAnimator.java
index debf45d..b95f9a4 100644
--- a/core/java/android/view/RenderNodeAnimator.java
+++ b/core/java/android/view/RenderNodeAnimator.java
@@ -219,7 +219,7 @@
@Override
public void cancel() {
- if (mState != STATE_FINISHED) {
+ if (mState != STATE_PREPARE && mState != STATE_FINISHED) {
if (mState == STATE_DELAYED) {
getHelper().removeDelayedAnimation(this);
notifyStartListeners();
diff --git a/core/java/android/view/ThreadedRenderer.java b/core/java/android/view/ThreadedRenderer.java
index 0711aed..00a8884 100644
--- a/core/java/android/view/ThreadedRenderer.java
+++ b/core/java/android/view/ThreadedRenderer.java
@@ -191,7 +191,8 @@
final float lightX = width / 2.0f;
mWidth = width;
mHeight = height;
- if (surfaceInsets != null && !surfaceInsets.isEmpty()) {
+ if (surfaceInsets != null && (surfaceInsets.left != 0 || surfaceInsets.right != 0
+ || surfaceInsets.top != 0 || surfaceInsets.bottom != 0)) {
mHasInsets = true;
mInsetLeft = surfaceInsets.left;
mInsetTop = surfaceInsets.top;
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index e4f95a4..1d09696 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -3109,6 +3109,16 @@
private MatchLabelForPredicate mMatchLabelForPredicate;
/**
+ * Specifies a view before which this one is visited in accessibility traversal.
+ */
+ private int mAccessibilityTraversalBeforeId = NO_ID;
+
+ /**
+ * Specifies a view after which this one is visited in accessibility traversal.
+ */
+ private int mAccessibilityTraversalAfterId = NO_ID;
+
+ /**
* Predicate for matching a view by its id.
*/
private MatchIdPredicate mMatchIdPredicate;
@@ -3888,6 +3898,12 @@
case com.android.internal.R.styleable.View_contentDescription:
setContentDescription(a.getString(attr));
break;
+ case com.android.internal.R.styleable.View_accessibilityTraversalBefore:
+ setAccessibilityTraversalBefore(a.getResourceId(attr, NO_ID));
+ break;
+ case com.android.internal.R.styleable.View_accessibilityTraversalAfter:
+ setAccessibilityTraversalAfter(a.getResourceId(attr, NO_ID));
+ break;
case com.android.internal.R.styleable.View_labelFor:
setLabelFor(a.getResourceId(attr, NO_ID));
break;
@@ -5611,6 +5627,7 @@
if (rootView == null) {
rootView = this;
}
+
View label = rootView.findLabelForView(this, mID);
if (label != null) {
info.setLabeledBy(label);
@@ -5639,6 +5656,30 @@
}
}
+ if (mAccessibilityTraversalBeforeId != View.NO_ID) {
+ View rootView = getRootView();
+ if (rootView == null) {
+ rootView = this;
+ }
+ View next = rootView.findViewInsideOutShouldExist(this,
+ mAccessibilityTraversalBeforeId);
+ if (next != null) {
+ info.setTraversalBefore(next);
+ }
+ }
+
+ if (mAccessibilityTraversalAfterId != View.NO_ID) {
+ View rootView = getRootView();
+ if (rootView == null) {
+ rootView = this;
+ }
+ View next = rootView.findViewInsideOutShouldExist(this,
+ mAccessibilityTraversalAfterId);
+ if (next != null) {
+ info.setTraversalAfter(next);
+ }
+ }
+
info.setVisibleToUser(isVisibleToUser());
info.setPackageName(mContext.getPackageName());
@@ -6043,6 +6084,94 @@
}
/**
+ * Sets the id of a view before which this one is visited in accessibility traversal.
+ * A screen-reader must visit the content of this view before the content of the one
+ * it precedes. For example, if view B is set to be before view A, then a screen-reader
+ * will traverse the entire content of B before traversing the entire content of A,
+ * regardles of what traversal strategy it is using.
+ * <p>
+ * Views that do not have specified before/after relationships are traversed in order
+ * determined by the screen-reader.
+ * </p>
+ * <p>
+ * Setting that this view is before a view that is not important for accessibility
+ * or if this view is not important for accessibility will have no effect as the
+ * screen-reader is not aware of unimportant views.
+ * </p>
+ *
+ * @param beforeId The id of a view this one precedes in accessibility traversal.
+ *
+ * @attr ref android.R.styleable#View_accessibilityTraversalBefore
+ *
+ * @see #setImportantForAccessibility(int)
+ */
+ @RemotableViewMethod
+ public void setAccessibilityTraversalBefore(int beforeId) {
+ if (mAccessibilityTraversalBeforeId == beforeId) {
+ return;
+ }
+ mAccessibilityTraversalBeforeId = beforeId;
+ notifyViewAccessibilityStateChangedIfNeeded(
+ AccessibilityEvent.CONTENT_CHANGE_TYPE_UNDEFINED);
+ }
+
+ /**
+ * Gets the id of a view before which this one is visited in accessibility traversal.
+ *
+ * @return The id of a view this one precedes in accessibility traversal if
+ * specified, otherwise {@link #NO_ID}.
+ *
+ * @see #setAccessibilityTraversalBefore(int)
+ */
+ public int getAccessibilityTraversalBefore() {
+ return mAccessibilityTraversalBeforeId;
+ }
+
+ /**
+ * Sets the id of a view after which this one is visited in accessibility traversal.
+ * A screen-reader must visit the content of the other view before the content of this
+ * one. For example, if view B is set to be after view A, then a screen-reader
+ * will traverse the entire content of A before traversing the entire content of B,
+ * regardles of what traversal strategy it is using.
+ * <p>
+ * Views that do not have specified before/after relationships are traversed in order
+ * determined by the screen-reader.
+ * </p>
+ * <p>
+ * Setting that this view is after a view that is not important for accessibility
+ * or if this view is not important for accessibility will have no effect as the
+ * screen-reader is not aware of unimportant views.
+ * </p>
+ *
+ * @param afterId The id of a view this one succedees in accessibility traversal.
+ *
+ * @attr ref android.R.styleable#View_accessibilityTraversalAfter
+ *
+ * @see #setImportantForAccessibility(int)
+ */
+ @RemotableViewMethod
+ public void setAccessibilityTraversalAfter(int afterId) {
+ if (mAccessibilityTraversalAfterId == afterId) {
+ return;
+ }
+ mAccessibilityTraversalAfterId = afterId;
+ notifyViewAccessibilityStateChangedIfNeeded(
+ AccessibilityEvent.CONTENT_CHANGE_TYPE_UNDEFINED);
+ }
+
+ /**
+ * Gets the id of a view after which this one is visited in accessibility traversal.
+ *
+ * @return The id of a view this one succeedes in accessibility traversal if
+ * specified, otherwise {@link #NO_ID}.
+ *
+ * @see #setAccessibilityTraversalAfter(int)
+ */
+ public int getAccessibilityTraversalAfter() {
+ return mAccessibilityTraversalAfterId;
+ }
+
+ /**
* Gets the id of a view for which this view serves as a label for
* accessibility purposes.
*
@@ -6061,11 +6190,16 @@
*/
@RemotableViewMethod
public void setLabelFor(int id) {
+ if (mLabelForId == id) {
+ return;
+ }
mLabelForId = id;
if (mLabelForId != View.NO_ID
&& mID == View.NO_ID) {
mID = generateViewId();
}
+ notifyViewAccessibilityStateChangedIfNeeded(
+ AccessibilityEvent.CONTENT_CHANGE_TYPE_UNDEFINED);
}
/**
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 27f78b6..ea0a077 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -728,8 +728,8 @@
}
final Rect insets = attrs.surfaceInsets;
- final boolean hasSurfaceInsets = insets.left == 0 || insets.right == 0
- || insets.top == 0 || insets.bottom == 0;
+ final boolean hasSurfaceInsets = insets.left != 0 || insets.right != 0
+ || insets.top != 0 || insets.bottom != 0;
final boolean translucent = attrs.format != PixelFormat.OPAQUE || hasSurfaceInsets;
mAttachInfo.mHardwareRenderer = HardwareRenderer.create(mContext, translucent);
if (mAttachInfo.mHardwareRenderer != null) {
@@ -1649,6 +1649,9 @@
mLastScrolledFocus.clear();
}
mScrollY = mCurScrollY = 0;
+ if (mView instanceof RootViewSurfaceTaker) {
+ ((RootViewSurfaceTaker) mView).onRootViewScrollYChanged(mCurScrollY);
+ }
if (mScroller != null) {
mScroller.abortAnimation();
}
@@ -1743,8 +1746,8 @@
if (hwInitialized ||
mWidth != mAttachInfo.mHardwareRenderer.getWidth() ||
mHeight != mAttachInfo.mHardwareRenderer.getHeight()) {
- final Rect surfaceInsets = params != null ? params.surfaceInsets : null;
- mAttachInfo.mHardwareRenderer.setup(mWidth, mHeight, surfaceInsets);
+ mAttachInfo.mHardwareRenderer.setup(
+ mWidth, mHeight, mWindowAttributes.surfaceInsets);
if (!hwInitialized) {
mAttachInfo.mHardwareRenderer.invalidate(mSurface);
mFullRedrawNeeded = true;
@@ -2419,6 +2422,9 @@
if (mCurScrollY != curScrollY) {
mCurScrollY = curScrollY;
fullRedrawNeeded = true;
+ if (mView instanceof RootViewSurfaceTaker) {
+ ((RootViewSurfaceTaker) mView).onRootViewScrollYChanged(mCurScrollY);
+ }
}
final float appScale = mAttachInfo.mApplicationScale;
@@ -3089,6 +3095,7 @@
private final static int MSG_INVALIDATE_WORLD = 23;
private final static int MSG_WINDOW_MOVED = 24;
private final static int MSG_SYNTHESIZE_INPUT_EVENT = 25;
+ private final static int MSG_DISPATCH_WINDOW_SHOWN = 26;
final class ViewRootHandler extends Handler {
@Override
@@ -3138,6 +3145,8 @@
return "MSG_WINDOW_MOVED";
case MSG_SYNTHESIZE_INPUT_EVENT:
return "MSG_SYNTHESIZE_INPUT_EVENT";
+ case MSG_DISPATCH_WINDOW_SHOWN:
+ return "MSG_DISPATCH_WINDOW_SHOWN";
}
return super.getMessageName(message);
}
@@ -3366,6 +3375,9 @@
invalidateWorld(mView);
}
} break;
+ case MSG_DISPATCH_WINDOW_SHOWN: {
+ handleDispatchWindowShown();
+ }
}
}
}
@@ -5212,6 +5224,10 @@
}
}
+ public void handleDispatchWindowShown() {
+ mAttachInfo.mTreeObserver.dispatchOnWindowShown();
+ }
+
public void getLastTouchPoint(Point outLocation) {
outLocation.x = (int) mLastTouchPoint.x;
outLocation.y = (int) mLastTouchPoint.y;
@@ -6072,6 +6088,10 @@
mHandler.sendMessage(msg);
}
+ public void dispatchWindowShown() {
+ mHandler.sendEmptyMessage(MSG_DISPATCH_WINDOW_SHOWN);
+ }
+
public void dispatchCloseSystemDialogs(String reason) {
Message msg = Message.obtain();
msg.what = MSG_CLOSE_SYSTEM_DIALOGS;
@@ -6582,6 +6602,14 @@
viewAncestor.dispatchDoneAnimating();
}
}
+
+ @Override
+ public void dispatchWindowShown() {
+ final ViewRootImpl viewAncestor = mViewAncestor.get();
+ if (viewAncestor != null) {
+ viewAncestor.dispatchWindowShown();
+ }
+ }
}
public static final class CalledFromWrongThreadException extends AndroidRuntimeException {
diff --git a/core/java/android/view/ViewTreeObserver.java b/core/java/android/view/ViewTreeObserver.java
index a9444b4..b85fec8 100644
--- a/core/java/android/view/ViewTreeObserver.java
+++ b/core/java/android/view/ViewTreeObserver.java
@@ -44,10 +44,15 @@
private CopyOnWriteArray<OnComputeInternalInsetsListener> mOnComputeInternalInsetsListeners;
private CopyOnWriteArray<OnScrollChangedListener> mOnScrollChangedListeners;
private CopyOnWriteArray<OnPreDrawListener> mOnPreDrawListeners;
+ private CopyOnWriteArray<OnWindowShownListener> mOnWindowShownListeners;
// These listeners cannot be mutated during dispatch
private ArrayList<OnDrawListener> mOnDrawListeners;
+ /** Remains false until #dispatchOnWindowShown() is called. If a listener registers after
+ * that the listener will be immediately called. */
+ private boolean mWindowShown;
+
private boolean mAlive = true;
/**
@@ -174,6 +179,19 @@
}
/**
+ * Interface definition for a callback noting when a system window has been displayed.
+ * This is only used for non-Activity windows. Activity windows can use
+ * Activity.onEnterAnimationComplete() to get the same signal.
+ * @hide
+ */
+ public interface OnWindowShownListener {
+ /**
+ * Callback method to be invoked when a non-activity window is fully shown.
+ */
+ void onWindowShown();
+ }
+
+ /**
* Parameters used with OnComputeInternalInsetsListener.
*
* We are not yet ready to commit to this API and support it, so
@@ -375,6 +393,14 @@
}
}
+ if (observer.mOnWindowShownListeners != null) {
+ if (mOnWindowShownListeners != null) {
+ mOnWindowShownListeners.addAll(observer.mOnWindowShownListeners);
+ } else {
+ mOnWindowShownListeners = observer.mOnWindowShownListeners;
+ }
+ }
+
observer.kill();
}
@@ -568,6 +594,45 @@
}
/**
+ * Register a callback to be invoked when the view tree window has been shown
+ *
+ * @param listener The callback to add
+ *
+ * @throws IllegalStateException If {@link #isAlive()} returns false
+ * @hide
+ */
+ public void addOnWindowShownListener(OnWindowShownListener listener) {
+ checkIsAlive();
+
+ if (mOnWindowShownListeners == null) {
+ mOnWindowShownListeners = new CopyOnWriteArray<OnWindowShownListener>();
+ }
+
+ mOnWindowShownListeners.add(listener);
+ if (mWindowShown) {
+ listener.onWindowShown();
+ }
+ }
+
+ /**
+ * Remove a previously installed window shown callback
+ *
+ * @param victim The callback to remove
+ *
+ * @throws IllegalStateException If {@link #isAlive()} returns false
+ *
+ * @see #addOnWindowShownListener(OnWindowShownListener)
+ * @hide
+ */
+ public void removeOnWindowShownListener(OnWindowShownListener victim) {
+ checkIsAlive();
+ if (mOnWindowShownListeners == null) {
+ return;
+ }
+ mOnWindowShownListeners.remove(victim);
+ }
+
+ /**
* <p>Register a callback to be invoked when the view tree is about to be drawn.</p>
* <p><strong>Note:</strong> this method <strong>cannot</strong> be invoked from
* {@link android.view.ViewTreeObserver.OnDrawListener#onDraw()}.</p>
@@ -854,6 +919,27 @@
}
/**
+ * Notifies registered listeners that the window is now shown
+ * @hide
+ */
+ @SuppressWarnings("unchecked")
+ public final void dispatchOnWindowShown() {
+ mWindowShown = true;
+ final CopyOnWriteArray<OnWindowShownListener> listeners = mOnWindowShownListeners;
+ if (listeners != null && listeners.size() > 0) {
+ CopyOnWriteArray.Access<OnWindowShownListener> access = listeners.start();
+ try {
+ int count = access.size();
+ for (int i = 0; i < count; i++) {
+ access.get(i).onWindowShown();
+ }
+ } finally {
+ listeners.end();
+ }
+ }
+ }
+
+ /**
* Notifies registered listeners that the drawing pass is about to start.
*/
public final void dispatchOnDraw() {
diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java
index 5b48c0d..f4f047e 100644
--- a/core/java/android/view/WindowManager.java
+++ b/core/java/android/view/WindowManager.java
@@ -1324,7 +1324,7 @@
*
* @hide
*/
- public Rect surfaceInsets = new Rect();
+ public final Rect surfaceInsets = new Rect();
/**
* The desired bitmap format. May be one of the constants in
diff --git a/core/java/android/view/WindowManagerGlobal.java b/core/java/android/view/WindowManagerGlobal.java
index 5926d5f..82b1073 100644
--- a/core/java/android/view/WindowManagerGlobal.java
+++ b/core/java/android/view/WindowManagerGlobal.java
@@ -118,6 +118,9 @@
private Runnable mSystemPropertyUpdater;
+ /** Default token to apply to added views. */
+ private IBinder mDefaultToken;
+
private WindowManagerGlobal() {
}
@@ -169,6 +172,17 @@
}
}
+ /**
+ * Sets the default token to use in {@link #addView} when no parent window
+ * token is available and no token has been explicitly set in the view's
+ * layout params.
+ *
+ * @param token Default window token to apply to added views.
+ */
+ public void setDefaultToken(IBinder token) {
+ mDefaultToken = token;
+ }
+
public String[] getViewRootNames() {
synchronized (mLock) {
final int numRoots = mRoots.size();
@@ -216,6 +230,10 @@
}
}
+ if (wparams.token == null && mDefaultToken != null) {
+ wparams.token = mDefaultToken;
+ }
+
ViewRootImpl root;
View panelParentView = null;
diff --git a/core/java/android/view/accessibility/AccessibilityNodeInfo.java b/core/java/android/view/accessibility/AccessibilityNodeInfo.java
index 3987fbc..b5afdf7 100644
--- a/core/java/android/view/accessibility/AccessibilityNodeInfo.java
+++ b/core/java/android/view/accessibility/AccessibilityNodeInfo.java
@@ -547,6 +547,8 @@
private long mParentNodeId = ROOT_NODE_ID;
private long mLabelForId = ROOT_NODE_ID;
private long mLabeledById = ROOT_NODE_ID;
+ private long mTraversalBefore = ROOT_NODE_ID;
+ private long mTraversalAfter = ROOT_NODE_ID;
private int mBooleanProperties;
private final Rect mBoundsInParent = new Rect();
@@ -1046,6 +1048,126 @@
}
/**
+ * Gets the node before which this one is visited during traversal. A screen-reader
+ * must visit the content of this node before the content of the one it precedes.
+ *
+ * @return The succeeding node if such or <code>null</code>.
+ *
+ * @see #setTraversalBefore(android.view.View)
+ * @see #setTraversalBefore(android.view.View, int)
+ */
+ public AccessibilityNodeInfo getTraversalBefore() {
+ enforceSealed();
+ return getNodeForAccessibilityId(mTraversalBefore);
+ }
+
+ /**
+ * Sets the view before whose node this one should be visited during traversal. A
+ * screen-reader must visit the content of this node before the content of the one
+ * it precedes.
+ * <p>
+ * <strong>Note:</strong> Cannot be called from an
+ * {@link android.accessibilityservice.AccessibilityService}.
+ * This class is made immutable before being delivered to an AccessibilityService.
+ * </p>
+ *
+ * @param view The view providing the preceding node.
+ *
+ * @see #getTraversalBefore()
+ */
+ public void setTraversalBefore(View view) {
+ setTraversalBefore(view, UNDEFINED_ITEM_ID);
+ }
+
+ /**
+ * Sets the node before which this one is visited during traversal. A screen-reader
+ * must visit the content of this node before the content of the one it precedes.
+ * The successor is a virtual descendant of the given <code>root</code>. If
+ * <code>virtualDescendantId</code> equals to {@link View#NO_ID} the root is set
+ * as the successor.
+ * <p>
+ * A virtual descendant is an imaginary View that is reported as a part of the view
+ * hierarchy for accessibility purposes. This enables custom views that draw complex
+ * content to report them selves as a tree of virtual views, thus conveying their
+ * logical structure.
+ * </p>
+ * <p>
+ * <strong>Note:</strong> Cannot be called from an
+ * {@link android.accessibilityservice.AccessibilityService}.
+ * This class is made immutable before being delivered to an AccessibilityService.
+ * </p>
+ *
+ * @param root The root of the virtual subtree.
+ * @param virtualDescendantId The id of the virtual descendant.
+ */
+ public void setTraversalBefore(View root, int virtualDescendantId) {
+ enforceNotSealed();
+ final int rootAccessibilityViewId = (root != null)
+ ? root.getAccessibilityViewId() : UNDEFINED_ITEM_ID;
+ mTraversalBefore = makeNodeId(rootAccessibilityViewId, virtualDescendantId);
+ }
+
+ /**
+ * Gets the node after which this one is visited in accessibility traversal.
+ * A screen-reader must visit the content of the other node before the content
+ * of this one.
+ *
+ * @return The succeeding node if such or <code>null</code>.
+ *
+ * @see #setTraversalAfter(android.view.View)
+ * @see #setTraversalAfter(android.view.View, int)
+ */
+ public AccessibilityNodeInfo getTraversalAfter() {
+ enforceSealed();
+ return getNodeForAccessibilityId(mTraversalAfter);
+ }
+
+ /**
+ * Sets the view whose node is visited after this one in accessibility traversal.
+ * A screen-reader must visit the content of the other node before the content
+ * of this one.
+ * <p>
+ * <strong>Note:</strong> Cannot be called from an
+ * {@link android.accessibilityservice.AccessibilityService}.
+ * This class is made immutable before being delivered to an AccessibilityService.
+ * </p>
+ *
+ * @param view The previous view.
+ *
+ * @see #getTraversalAfter()
+ */
+ public void setTraversalAfter(View view) {
+ setTraversalAfter(view, UNDEFINED_ITEM_ID);
+ }
+
+ /**
+ * Sets the node after which this one is visited in accessibility traversal.
+ * A screen-reader must visit the content of the other node before the content
+ * of this one. If <code>virtualDescendantId</code> equals to {@link View#NO_ID}
+ * the root is set as the predecessor.
+ * <p>
+ * A virtual descendant is an imaginary View that is reported as a part of the view
+ * hierarchy for accessibility purposes. This enables custom views that draw complex
+ * content to report them selves as a tree of virtual views, thus conveying their
+ * logical structure.
+ * </p>
+ * <p>
+ * <strong>Note:</strong> Cannot be called from an
+ * {@link android.accessibilityservice.AccessibilityService}.
+ * This class is made immutable before being delivered to an AccessibilityService.
+ * </p>
+ *
+ * @param root The root of the virtual subtree.
+ * @param virtualDescendantId The id of the virtual descendant.
+ */
+ public void setTraversalAfter(View root, int virtualDescendantId) {
+ enforceNotSealed();
+ final int rootAccessibilityViewId = (root != null)
+ ? root.getAccessibilityViewId() : UNDEFINED_ITEM_ID;
+ mTraversalAfter = makeNodeId(rootAccessibilityViewId, virtualDescendantId);
+ }
+
+ /**
* Sets the maximum text length, or -1 for no limit.
* <p>
* Typically used to indicate that an editable text field has a limit on
@@ -1229,13 +1351,7 @@
*/
public AccessibilityNodeInfo getParent() {
enforceSealed();
- if (!canPerformRequestOverConnection(mParentNodeId)) {
- return null;
- }
- AccessibilityInteractionClient client = AccessibilityInteractionClient.getInstance();
- return client.findAccessibilityNodeInfoByAccessibilityId(mConnectionId,
- mWindowId, mParentNodeId, false, FLAG_PREFETCH_PREDECESSORS
- | FLAG_PREFETCH_DESCENDANTS | FLAG_PREFETCH_SIBLINGS);
+ return getNodeForAccessibilityId(mParentNodeId);
}
/**
@@ -2055,13 +2171,7 @@
*/
public AccessibilityNodeInfo getLabelFor() {
enforceSealed();
- if (!canPerformRequestOverConnection(mLabelForId)) {
- return null;
- }
- AccessibilityInteractionClient client = AccessibilityInteractionClient.getInstance();
- return client.findAccessibilityNodeInfoByAccessibilityId(mConnectionId,
- mWindowId, mLabelForId, false, FLAG_PREFETCH_PREDECESSORS
- | FLAG_PREFETCH_DESCENDANTS | FLAG_PREFETCH_SIBLINGS);
+ return getNodeForAccessibilityId(mLabelForId);
}
/**
@@ -2113,13 +2223,7 @@
*/
public AccessibilityNodeInfo getLabeledBy() {
enforceSealed();
- if (!canPerformRequestOverConnection(mLabeledById)) {
- return null;
- }
- AccessibilityInteractionClient client = AccessibilityInteractionClient.getInstance();
- return client.findAccessibilityNodeInfoByAccessibilityId(mConnectionId,
- mWindowId, mLabeledById, false, FLAG_PREFETCH_PREDECESSORS
- | FLAG_PREFETCH_DESCENDANTS | FLAG_PREFETCH_SIBLINGS);
+ return getNodeForAccessibilityId(mLabeledById);
}
/**
@@ -2453,6 +2557,9 @@
parcel.writeLong(mParentNodeId);
parcel.writeLong(mLabelForId);
parcel.writeLong(mLabeledById);
+ parcel.writeLong(mTraversalBefore);
+ parcel.writeLong(mTraversalAfter);
+
parcel.writeInt(mConnectionId);
final LongArray childIds = mChildNodeIds;
@@ -2571,6 +2678,8 @@
mParentNodeId = other.mParentNodeId;
mLabelForId = other.mLabelForId;
mLabeledById = other.mLabeledById;
+ mTraversalBefore = other.mTraversalBefore;
+ mTraversalAfter = other.mTraversalAfter;
mWindowId = other.mWindowId;
mConnectionId = other.mConnectionId;
mBoundsInParent.set(other.mBoundsInParent);
@@ -2633,6 +2742,9 @@
mParentNodeId = parcel.readLong();
mLabelForId = parcel.readLong();
mLabeledById = parcel.readLong();
+ mTraversalBefore = parcel.readLong();
+ mTraversalAfter = parcel.readLong();
+
mConnectionId = parcel.readInt();
final int childrenSize = parcel.readInt();
@@ -2725,6 +2837,8 @@
mParentNodeId = ROOT_NODE_ID;
mLabelForId = ROOT_NODE_ID;
mLabeledById = ROOT_NODE_ID;
+ mTraversalBefore = ROOT_NODE_ID;
+ mTraversalAfter = ROOT_NODE_ID;
mWindowId = UNDEFINED_ITEM_ID;
mConnectionId = UNDEFINED_CONNECTION_ID;
mMaxTextLength = -1;
@@ -2911,6 +3025,8 @@
builder.append("; accessibilityViewId: " + getAccessibilityViewId(mSourceNodeId));
builder.append("; virtualDescendantId: " + getVirtualDescendantId(mSourceNodeId));
builder.append("; mParentNodeId: " + mParentNodeId);
+ builder.append("; traversalBefore: ").append(mTraversalBefore);
+ builder.append("; traversalAfter: ").append(mTraversalAfter);
int granularities = mMovementGranularities;
builder.append("; MovementGranularities: [");
@@ -2963,6 +3079,16 @@
return builder.toString();
}
+ private AccessibilityNodeInfo getNodeForAccessibilityId(long accessibilityId) {
+ if (!canPerformRequestOverConnection(accessibilityId)) {
+ return null;
+ }
+ AccessibilityInteractionClient client = AccessibilityInteractionClient.getInstance();
+ return client.findAccessibilityNodeInfoByAccessibilityId(mConnectionId,
+ mWindowId, accessibilityId, false, FLAG_PREFETCH_PREDECESSORS
+ | FLAG_PREFETCH_DESCENDANTS | FLAG_PREFETCH_SIBLINGS);
+ }
+
/**
* A class defining an action that can be performed on an {@link AccessibilityNodeInfo}.
* Each action has a unique id that is mandatory and optional data.
diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java
index 6c107a2..6927660 100644
--- a/core/java/android/widget/AbsListView.java
+++ b/core/java/android/widget/AbsListView.java
@@ -2663,7 +2663,7 @@
* @return True if the selector should be shown
*/
boolean shouldShowSelector() {
- return (!isInTouchMode()) || (touchModeDrawsInPressedState() && isPressed());
+ return (isFocused() && !isInTouchMode()) || (touchModeDrawsInPressedState() && isPressed());
}
private void drawSelector(Canvas canvas) {
diff --git a/core/java/android/widget/DayPickerView.java b/core/java/android/widget/DayPickerView.java
index fcf66f6..f9544d0 100644
--- a/core/java/android/widget/DayPickerView.java
+++ b/core/java/android/widget/DayPickerView.java
@@ -107,9 +107,9 @@
mAdapter.setRange(mMinDate, mMaxDate);
- if (constrainCalendar(mSelectedDay, mMinDate, mMaxDate)) {
- goTo(mSelectedDay, false, true, true);
- }
+ // Changing the min/max date changes the selection position since we
+ // don't really have stable IDs.
+ goTo(mSelectedDay, false, true, true);
}
/**
diff --git a/core/java/android/widget/OverScroller.java b/core/java/android/widget/OverScroller.java
index 7b3dd31..a40d4f8 100644
--- a/core/java/android/widget/OverScroller.java
+++ b/core/java/android/widget/OverScroller.java
@@ -904,6 +904,10 @@
final long time = AnimationUtils.currentAnimationTimeMillis();
final long currentTime = time - mStartTime;
+ if (currentTime == 0) {
+ // Skip work but report that we're still going if we have a nonzero duration.
+ return mDuration > 0;
+ }
if (currentTime > mDuration) {
return false;
}
diff --git a/core/java/android/widget/RemoteViews.java b/core/java/android/widget/RemoteViews.java
index 80f364b..dd7fa18 100644
--- a/core/java/android/widget/RemoteViews.java
+++ b/core/java/android/widget/RemoteViews.java
@@ -2528,6 +2528,26 @@
}
/**
+ * Equivalent to calling {@link android.view.View#setAccessibilityTraversalBefore(int)}.
+ *
+ * @param viewId The id of the view whose before view in accessibility traversal to set.
+ * @param nextId The id of the next in the accessibility traversal.
+ **/
+ public void setAccessibilityTraversalBefore(int viewId, int nextId) {
+ setInt(viewId, "setAccessibilityTraversalBefore", nextId);
+ }
+
+ /**
+ * Equivalent to calling {@link android.view.View#setAccessibilityTraversalAfter(int)}.
+ *
+ * @param viewId The id of the view whose after view in accessibility traversal to set.
+ * @param nextId The id of the next in the accessibility traversal.
+ **/
+ public void setAccessibilityTraversalAfter(int viewId, int nextId) {
+ setInt(viewId, "setAccessibilityTraversalAfter", nextId);
+ }
+
+ /**
* Equivalent to calling View.setLabelFor(int).
*
* @param viewId The id of the view whose property to set.
diff --git a/core/java/android/widget/Toolbar.java b/core/java/android/widget/Toolbar.java
index d4d186c..f90d64a 100644
--- a/core/java/android/widget/Toolbar.java
+++ b/core/java/android/widget/Toolbar.java
@@ -1752,6 +1752,17 @@
}
/**
+ * Accessor to enable LayoutLib to get ActionMenuPresenter directly.
+ */
+ ActionMenuPresenter getOuterActionMenuPresenter() {
+ return mOuterActionMenuPresenter;
+ }
+
+ Context getPopupContext() {
+ return mPopupContext;
+ }
+
+ /**
* Interface responsible for receiving menu item click events if the items themselves
* do not have individual item click listeners.
*/
diff --git a/core/java/com/android/internal/app/AlertController.java b/core/java/com/android/internal/app/AlertController.java
index 3630cc7..35e03c3 100644
--- a/core/java/com/android/internal/app/AlertController.java
+++ b/core/java/com/android/internal/app/AlertController.java
@@ -37,6 +37,7 @@
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewGroup.LayoutParams;
+import android.view.ViewParent;
import android.view.ViewTreeObserver;
import android.view.Window;
import android.view.WindowInsets;
@@ -589,9 +590,10 @@
mScrollView.removeView(mMessageView);
if (mListView != null) {
- final int childIndex = mScrollView.indexOfChild(mScrollView);
- contentPanel.removeViewAt(childIndex);
- contentPanel.addView(mListView, childIndex,
+ final ViewGroup scrollParent = (ViewGroup) mScrollView.getParent();
+ final int childIndex = scrollParent.indexOfChild(mScrollView);
+ scrollParent.removeViewAt(childIndex);
+ scrollParent.addView(mListView, childIndex,
new LayoutParams(MATCH_PARENT, MATCH_PARENT));
} else {
contentPanel.setVisibility(View.GONE);
diff --git a/core/java/com/android/internal/app/ChooserActivity.java b/core/java/com/android/internal/app/ChooserActivity.java
index 0bc1a8d..64bd6b6 100644
--- a/core/java/com/android/internal/app/ChooserActivity.java
+++ b/core/java/com/android/internal/app/ChooserActivity.java
@@ -20,6 +20,7 @@
import android.content.ComponentName;
import android.content.Intent;
import android.content.IntentSender;
+import android.content.pm.ActivityInfo;
import android.os.Bundle;
import android.os.Parcelable;
import android.util.Log;
@@ -75,16 +76,21 @@
}
@Override
- public Intent getReplacementIntent(String packageName, Intent defIntent) {
+ public Intent getReplacementIntent(ActivityInfo aInfo, Intent defIntent) {
+ Intent result = defIntent;
if (mReplacementExtras != null) {
- final Bundle replExtras = mReplacementExtras.getBundle(packageName);
+ final Bundle replExtras = mReplacementExtras.getBundle(aInfo.packageName);
if (replExtras != null) {
- final Intent result = new Intent(defIntent);
+ result = new Intent(defIntent);
result.putExtras(replExtras);
- return result;
}
}
- return defIntent;
+ if (aInfo.name.equals(IntentForwarderActivity.FORWARD_INTENT_TO_USER_OWNER)
+ || aInfo.name.equals(IntentForwarderActivity.FORWARD_INTENT_TO_MANAGED_PROFILE)) {
+ result = Intent.createChooser(result,
+ getIntent().getCharSequenceExtra(Intent.EXTRA_TITLE));
+ }
+ return result;
}
@Override
diff --git a/core/java/com/android/internal/app/IntentForwarderActivity.java b/core/java/com/android/internal/app/IntentForwarderActivity.java
index 6e2f84a..9656a21 100644
--- a/core/java/com/android/internal/app/IntentForwarderActivity.java
+++ b/core/java/com/android/internal/app/IntentForwarderActivity.java
@@ -58,21 +58,22 @@
Intent intentReceived = getIntent();
String className = intentReceived.getComponent().getClassName();
- final UserHandle userDest;
+ final int targetUserId;
final int userMessageId;
if (className.equals(FORWARD_INTENT_TO_USER_OWNER)) {
userMessageId = com.android.internal.R.string.forward_intent_to_owner;
- userDest = UserHandle.OWNER;
+ targetUserId = UserHandle.USER_OWNER;
} else if (className.equals(FORWARD_INTENT_TO_MANAGED_PROFILE)) {
userMessageId = com.android.internal.R.string.forward_intent_to_work;
- userDest = getManagedProfile();
+ targetUserId = getManagedProfile();
} else {
Slog.wtf(TAG, IntentForwarderActivity.class.getName() + " cannot be called directly");
userMessageId = -1;
- userDest = null;
+ targetUserId = UserHandle.USER_NULL;
}
- if (userDest == null) { // This covers the case where there is no managed profile.
+ if (targetUserId == UserHandle.USER_NULL) {
+ // This covers the case where there is no managed profile.
finish();
return;
}
@@ -83,31 +84,24 @@
newIntent.addFlags(Intent.FLAG_ACTIVITY_FORWARD_RESULT
|Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP);
int callingUserId = getUserId();
- IPackageManager ipm = AppGlobals.getPackageManager();
- String resolvedType = newIntent.resolveTypeIfNeeded(getContentResolver());
- boolean canForward = false;
- Intent selector = newIntent.getSelector();
- if (selector == null) {
- selector = newIntent;
- }
- try {
- canForward = ipm.canForwardTo(selector, resolvedType, callingUserId,
- userDest.getIdentifier());
- } catch (RemoteException e) {
- Slog.e(TAG, "PackageManagerService is dead?");
- }
- if (canForward) {
- newIntent.setContentUserHint(callingUserId);
+
+ if (canForward(newIntent, targetUserId)) {
+ if (newIntent.getAction().equals(Intent.ACTION_CHOOSER)) {
+ Intent innerIntent = (Intent) newIntent.getParcelableExtra(Intent.EXTRA_INTENT);
+ innerIntent.setContentUserHint(callingUserId);
+ } else {
+ newIntent.setContentUserHint(callingUserId);
+ }
final android.content.pm.ResolveInfo ri = getPackageManager().resolveActivityAsUser(
- newIntent, MATCH_DEFAULT_ONLY, userDest.getIdentifier());
+ newIntent, MATCH_DEFAULT_ONLY, targetUserId);
// Only show a disclosure if this is a normal (non-OS) app
final boolean shouldShowDisclosure =
!UserHandle.isSameApp(ri.activityInfo.applicationInfo.uid, Process.SYSTEM_UID);
try {
- startActivityAsCaller(newIntent, null, userDest.getIdentifier());
+ startActivityAsCaller(newIntent, null, targetUserId);
} catch (RuntimeException e) {
int launchedFromUid = -1;
String launchedFromPackage = "?";
@@ -129,26 +123,55 @@
}
} else {
Slog.wtf(TAG, "the intent: " + newIntent + "cannot be forwarded from user "
- + callingUserId + " to user " + userDest.getIdentifier());
+ + callingUserId + " to user " + targetUserId);
}
finish();
}
+ boolean canForward(Intent intent, int targetUserId) {
+ IPackageManager ipm = AppGlobals.getPackageManager();
+ if (intent.getAction().equals(Intent.ACTION_CHOOSER)) {
+ // The EXTRA_INITIAL_INTENTS may not be allowed to be forwarded.
+ if (intent.hasExtra(Intent.EXTRA_INITIAL_INTENTS)) {
+ Slog.wtf(TAG, "An chooser intent with extra initial intents cannot be forwarded to"
+ + " a different user");
+ return false;
+ }
+ if (intent.hasExtra(Intent.EXTRA_REPLACEMENT_EXTRAS)) {
+ Slog.wtf(TAG, "A chooser intent with replacement extras cannot be forwarded to a"
+ + " different user");
+ return false;
+ }
+ intent = (Intent) intent.getParcelableExtra(Intent.EXTRA_INTENT);
+ }
+ String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
+ if (intent.getSelector() != null) {
+ intent = intent.getSelector();
+ }
+ try {
+ return ipm.canForwardTo(intent, resolvedType, getUserId(),
+ targetUserId);
+ } catch (RemoteException e) {
+ Slog.e(TAG, "PackageManagerService is dead?");
+ return false;
+ }
+ }
+
/**
- * Returns the managed profile for this device or null if there is no managed
- * profile.
+ * Returns the userId of the managed profile for this device or UserHandle.USER_NULL if there is
+ * no managed profile.
*
* TODO: Remove the assumption that there is only one managed profile
* on the device.
*/
- private UserHandle getManagedProfile() {
+ private int getManagedProfile() {
UserManager userManager = (UserManager) getSystemService(Context.USER_SERVICE);
List<UserInfo> relatedUsers = userManager.getProfiles(UserHandle.USER_OWNER);
for (UserInfo userInfo : relatedUsers) {
- if (userInfo.isManagedProfile()) return new UserHandle(userInfo.id);
+ if (userInfo.isManagedProfile()) return userInfo.id;
}
Slog.wtf(TAG, FORWARD_INTENT_TO_MANAGED_PROFILE
+ " has been called, but there is no managed profile");
- return null;
+ return UserHandle.USER_NULL;
}
}
diff --git a/core/java/com/android/internal/app/ResolverActivity.java b/core/java/com/android/internal/app/ResolverActivity.java
index ccffa19..376db6e 100644
--- a/core/java/com/android/internal/app/ResolverActivity.java
+++ b/core/java/com/android/internal/app/ResolverActivity.java
@@ -100,6 +100,7 @@
private int mMaxColumns;
private int mLastSelected = ListView.INVALID_POSITION;
private boolean mResolvingHome = false;
+ private int mProfileSwitchMessageId = -1;
private UsageStatsManager mUsm;
private Map<String, UsageStats> mStats;
@@ -200,6 +201,11 @@
List<ResolveInfo> rList, boolean alwaysUseOption) {
setTheme(R.style.Theme_DeviceDefault_Resolver);
super.onCreate(savedInstanceState);
+
+ // Determine whether we should show that intent is forwarded
+ // from managed profile to owner or other way around.
+ setProfileSwitchMessageId(intent.getContentUserHint());
+
try {
mLaunchedFromUid = ActivityManagerNative.getDefault().getLaunchedFromUid(
getActivityToken());
@@ -278,9 +284,9 @@
final ResolverDrawerLayout rdl = (ResolverDrawerLayout) findViewById(R.id.contentPanel);
if (rdl != null) {
- rdl.setOnClickOutsideListener(new View.OnClickListener() {
+ rdl.setOnDismissedListener(new ResolverDrawerLayout.OnDismissedListener() {
@Override
- public void onClick(View v) {
+ public void onDismissed() {
finish();
}
});
@@ -320,6 +326,22 @@
}
}
+ private void setProfileSwitchMessageId(int contentUserHint) {
+ if (contentUserHint != UserHandle.USER_CURRENT &&
+ contentUserHint != UserHandle.myUserId()) {
+ UserManager userManager = (UserManager) getSystemService(Context.USER_SERVICE);
+ UserInfo originUserInfo = userManager.getUserInfo(contentUserHint);
+ boolean originIsManaged = originUserInfo != null ? originUserInfo.isManagedProfile()
+ : false;
+ boolean targetIsManaged = userManager.isManagedProfile();
+ if (originIsManaged && !targetIsManaged) {
+ mProfileSwitchMessageId = com.android.internal.R.string.forward_intent_to_owner;
+ } else if (!originIsManaged && targetIsManaged) {
+ mProfileSwitchMessageId = com.android.internal.R.string.forward_intent_to_work;
+ }
+ }
+ }
+
/**
* Turn on launch mode that is safe to use when forwarding intents received from
* applications and running in system processes. This mode uses Activity.startActivityAsCaller
@@ -529,7 +551,7 @@
/**
* Replace me in subclasses!
*/
- public Intent getReplacementIntent(String packageName, Intent defIntent) {
+ public Intent getReplacementIntent(ActivityInfo aInfo, Intent defIntent) {
return defIntent;
}
@@ -642,6 +664,11 @@
}
public void safelyStartActivity(Intent intent) {
+ // If needed, show that intent is forwarded
+ // from managed profile to owner or other way around.
+ if (mProfileSwitchMessageId != -1) {
+ Toast.makeText(this, getString(mProfileSwitchMessageId), Toast.LENGTH_LONG).show();
+ }
if (!mSafeForwardingMode) {
startActivity(intent);
onActivityStarted(intent);
@@ -943,7 +970,7 @@
DisplayResolveInfo dri = filtered ? getItem(position) : mList.get(position);
Intent intent = new Intent(dri.origIntent != null ? dri.origIntent :
- getReplacementIntent(dri.ri.activityInfo.packageName, mIntent));
+ getReplacementIntent(dri.ri.activityInfo, mIntent));
intent.addFlags(Intent.FLAG_ACTIVITY_FORWARD_RESULT
|Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP);
ActivityInfo ai = dri.ri.activityInfo;
diff --git a/core/java/com/android/internal/statusbar/IStatusBarService.aidl b/core/java/com/android/internal/statusbar/IStatusBarService.aidl
index e6bcea1..5e610ed 100644
--- a/core/java/com/android/internal/statusbar/IStatusBarService.aidl
+++ b/core/java/com/android/internal/statusbar/IStatusBarService.aidl
@@ -51,7 +51,7 @@
void onNotificationVisibilityChanged(
in String[] newlyVisibleKeys, in String[] noLongerVisibleKeys);
void onNotificationExpansionChanged(in String key, in boolean userAction, in boolean expanded);
- void setSystemUiVisibility(int vis, int mask);
+ void setSystemUiVisibility(int vis, int mask, String cause);
void setWindowState(int window, int state);
void showRecentApps(boolean triggeredFromAltTab);
diff --git a/core/java/com/android/internal/util/MemInfoReader.java b/core/java/com/android/internal/util/MemInfoReader.java
index 1dd9464..b71fa06 100644
--- a/core/java/com/android/internal/util/MemInfoReader.java
+++ b/core/java/com/android/internal/util/MemInfoReader.java
@@ -106,4 +106,8 @@
public long getZramTotalSizeKb() {
return mInfos[Debug.MEMINFO_ZRAM_TOTAL];
}
+
+ public long[] getRawInfo() {
+ return mInfos;
+ }
}
diff --git a/core/java/com/android/internal/view/BaseIWindow.java b/core/java/com/android/internal/view/BaseIWindow.java
index 50a7a5e..993ab58 100644
--- a/core/java/com/android/internal/view/BaseIWindow.java
+++ b/core/java/com/android/internal/view/BaseIWindow.java
@@ -102,4 +102,8 @@
@Override
public void doneAnimating() {
}
+
+ @Override
+ public void dispatchWindowShown() {
+ }
}
diff --git a/core/java/com/android/internal/view/RootViewSurfaceTaker.java b/core/java/com/android/internal/view/RootViewSurfaceTaker.java
index 9c1b558..433ec73 100644
--- a/core/java/com/android/internal/view/RootViewSurfaceTaker.java
+++ b/core/java/com/android/internal/view/RootViewSurfaceTaker.java
@@ -1,3 +1,18 @@
+/*
+ * 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.
+ */
package com.android.internal.view;
import android.view.InputQueue;
@@ -10,4 +25,5 @@
void setSurfaceFormat(int format);
void setSurfaceKeepScreenOn(boolean keepOn);
InputQueue.Callback willYouTakeTheInputQueue();
+ void onRootViewScrollYChanged(int scrollY);
}
diff --git a/core/java/com/android/internal/widget/ResolverDrawerLayout.java b/core/java/com/android/internal/widget/ResolverDrawerLayout.java
index 375822f..25b4945 100644
--- a/core/java/com/android/internal/widget/ResolverDrawerLayout.java
+++ b/core/java/com/android/internal/widget/ResolverDrawerLayout.java
@@ -63,18 +63,22 @@
private float mCollapseOffset;
private int mCollapsibleHeight;
+ private int mUncollapsibleHeight;
private int mTopOffset;
private boolean mIsDragging;
private boolean mOpenOnClick;
private boolean mOpenOnLayout;
+ private boolean mDismissOnScrollerFinished;
private final int mTouchSlop;
private final float mMinFlingVelocity;
private final OverScroller mScroller;
private final VelocityTracker mVelocityTracker;
- private OnClickListener mClickOutsideListener;
+ private OnDismissedListener mOnDismissedListener;
+ private RunOnDismissedListener mRunOnDismissedListener;
+
private float mInitialTouchX;
private float mInitialTouchY;
private float mLastTouchY;
@@ -143,8 +147,8 @@
return isSmallCollapsed() ? mMaxCollapsedHeightSmall : mMaxCollapsedHeight;
}
- public void setOnClickOutsideListener(OnClickListener listener) {
- mClickOutsideListener = listener;
+ public void setOnDismissedListener(OnDismissedListener listener) {
+ mOnDismissedListener = listener;
}
@Override
@@ -194,7 +198,7 @@
}
if (mIsDragging) {
- mScroller.abortAnimation();
+ abortAnimation();
}
return mIsDragging || mOpenOnClick;
}
@@ -213,12 +217,9 @@
mInitialTouchX = x;
mInitialTouchY = mLastTouchY = y;
mActivePointerId = ev.getPointerId(0);
- if (findChildUnder(mInitialTouchX, mInitialTouchY) == null &&
- mClickOutsideListener != null) {
- mIsDragging = handled = true;
- }
- handled |= mCollapsibleHeight > 0;
- mScroller.abortAnimation();
+ mIsDragging = findChildUnder(mInitialTouchX, mInitialTouchY) != null;
+ handled = (!mIsDragging && mOnDismissedListener != null) || mCollapsibleHeight > 0;
+ abortAnimation();
}
break;
@@ -264,11 +265,12 @@
break;
case MotionEvent.ACTION_UP: {
+ final boolean wasDragging = mIsDragging;
mIsDragging = false;
- if (!mIsDragging && findChildUnder(mInitialTouchX, mInitialTouchY) == null &&
+ if (!wasDragging && findChildUnder(mInitialTouchX, mInitialTouchY) == null &&
findChildUnder(ev.getX(), ev.getY()) == null) {
- if (mClickOutsideListener != null) {
- mClickOutsideListener.onClick(this);
+ if (mOnDismissedListener != null) {
+ dispatchOnDismissed();
resetTouch();
return true;
}
@@ -281,7 +283,13 @@
mVelocityTracker.computeCurrentVelocity(1000);
final float yvel = mVelocityTracker.getYVelocity(mActivePointerId);
if (Math.abs(yvel) > mMinFlingVelocity) {
- smoothScrollTo(yvel < 0 ? 0 : mCollapsibleHeight, yvel);
+ if (mOnDismissedListener != null
+ && yvel > 0 && mCollapseOffset > mCollapsibleHeight) {
+ smoothScrollTo(mCollapsibleHeight + mUncollapsibleHeight, yvel);
+ mDismissOnScrollerFinished = true;
+ } else {
+ smoothScrollTo(yvel < 0 ? 0 : mCollapsibleHeight, yvel);
+ }
} else {
smoothScrollTo(
mCollapseOffset < mCollapsibleHeight / 2 ? 0 : mCollapsibleHeight, 0);
@@ -327,17 +335,27 @@
@Override
public void computeScroll() {
super.computeScroll();
- if (!mScroller.isFinished()) {
- final boolean keepGoing = mScroller.computeScrollOffset();
+ if (mScroller.computeScrollOffset()) {
+ final boolean keepGoing = !mScroller.isFinished();
performDrag(mScroller.getCurrY() - mCollapseOffset);
if (keepGoing) {
postInvalidateOnAnimation();
+ } else if (mDismissOnScrollerFinished && mOnDismissedListener != null) {
+ mRunOnDismissedListener = new RunOnDismissedListener();
+ post(mRunOnDismissedListener);
}
}
}
+ private void abortAnimation() {
+ mScroller.abortAnimation();
+ mRunOnDismissedListener = null;
+ mDismissOnScrollerFinished = false;
+ }
+
private float performDrag(float dy) {
- final float newPos = Math.max(0, Math.min(mCollapseOffset + dy, mCollapsibleHeight));
+ final float newPos = Math.max(0, Math.min(mCollapseOffset + dy,
+ mCollapsibleHeight + mUncollapsibleHeight));
if (newPos != mCollapseOffset) {
dy = newPos - mCollapseOffset;
final int childCount = getChildCount();
@@ -356,11 +374,18 @@
return 0;
}
- private void smoothScrollTo(int yOffset, float velocity) {
- if (getMaxCollapsedHeight() == 0) {
- return;
+ void dispatchOnDismissed() {
+ if (mOnDismissedListener != null) {
+ mOnDismissedListener.onDismissed();
}
- mScroller.abortAnimation();
+ if (mRunOnDismissedListener != null) {
+ removeCallbacks(mRunOnDismissedListener);
+ mRunOnDismissedListener = null;
+ }
+ }
+
+ private void smoothScrollTo(int yOffset, float velocity) {
+ abortAnimation();
final int sy = (int) mCollapseOffset;
int dy = yOffset - sy;
if (dy == 0) {
@@ -490,6 +515,7 @@
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
getViewTreeObserver().removeOnTouchModeChangeListener(mTouchModeChangeListener);
+ abortAnimation();
}
@Override
@@ -585,6 +611,7 @@
mCollapsibleHeight = Math.max(0,
heightUsed - alwaysShowHeight - getMaxCollapsedHeight());
+ mUncollapsibleHeight = heightUsed - mCollapsibleHeight;
if (isLaidOut()) {
mCollapseOffset = Math.min(mCollapseOffset, mCollapsibleHeight);
@@ -734,4 +761,15 @@
}
};
}
+
+ public interface OnDismissedListener {
+ public void onDismissed();
+ }
+
+ private class RunOnDismissedListener implements Runnable {
+ @Override
+ public void run() {
+ dispatchOnDismissed();
+ }
+ }
}
diff --git a/core/jni/android/graphics/pdf/PdfEditor.cpp b/core/jni/android/graphics/pdf/PdfEditor.cpp
index 5f60c9e..ed6f1d6 100644
--- a/core/jni/android/graphics/pdf/PdfEditor.cpp
+++ b/core/jni/android/graphics/pdf/PdfEditor.cpp
@@ -19,6 +19,9 @@
#include "fpdfview.h"
#include "fpdfedit.h"
#include "fpdfsave.h"
+#include "fsdk_rendercontext.h"
+#include "fpdf_transformpage.h"
+#include "SkMatrix.h"
#include <android_runtime/AndroidRuntime.h>
#include <vector>
@@ -29,6 +32,20 @@
namespace android {
+enum PageBox {PAGE_BOX_MEDIA, PAGE_BOX_CROP};
+
+static struct {
+ jfieldID x;
+ jfieldID y;
+} gPointClassInfo;
+
+static struct {
+ jfieldID left;
+ jfieldID top;
+ jfieldID right;
+ jfieldID bottom;
+} gRectClassInfo;
+
static Mutex sLock;
static int sUnmatchedInitRequestCount = 0;
@@ -72,8 +89,17 @@
if (!document) {
const long error = FPDF_GetLastError();
- jniThrowException(env, "java/io/IOException",
- "cannot create document. Error:" + error);
+ switch (error) {
+ case FPDF_ERR_PASSWORD:
+ case FPDF_ERR_SECURITY: {
+ jniThrowException(env, "java/lang/SecurityException",
+ "cannot create document. Error:" + error);
+ } break;
+ default: {
+ jniThrowException(env, "java/io/IOException",
+ "cannot create document. Error:" + error);
+ } break;
+ }
destroyLibraryIfNeeded();
return -1;
}
@@ -144,18 +170,201 @@
}
}
+static void nativeSetTransformAndClip(JNIEnv* env, jclass thiz, jlong documentPtr, jint pageIndex,
+ jlong transformPtr, jint clipLeft, jint clipTop, jint clipRight, jint clipBottom) {
+ FPDF_DOCUMENT document = reinterpret_cast<FPDF_DOCUMENT>(documentPtr);
+
+ CPDF_Page* page = (CPDF_Page*) FPDF_LoadPage(document, pageIndex);
+ if (!page) {
+ jniThrowException(env, "java/lang/IllegalStateException",
+ "cannot open page");
+ return;
+ }
+
+ double width = 0;
+ double height = 0;
+
+ const int result = FPDF_GetPageSizeByIndex(document, pageIndex, &width, &height);
+ if (!result) {
+ jniThrowException(env, "java/lang/IllegalStateException",
+ "cannot get page size");
+ return;
+ }
+
+ CFX_AffineMatrix matrix;
+
+ SkMatrix* skTransform = reinterpret_cast<SkMatrix*>(transformPtr);
+
+ SkScalar transformValues[6];
+ skTransform->asAffine(transformValues);
+
+ // PDF's coordinate system origin is left-bottom while in graphics it
+ // is the top-left. So, translate the PDF coordinates to ours.
+ matrix.Set(1, 0, 0, -1, 0, page->GetPageHeight());
+
+ // Apply the transformation what was created in our coordinates.
+ matrix.Concat(transformValues[SkMatrix::kAScaleX], transformValues[SkMatrix::kASkewY],
+ transformValues[SkMatrix::kASkewX], transformValues[SkMatrix::kAScaleY],
+ transformValues[SkMatrix::kATransX], transformValues[SkMatrix::kATransY]);
+
+ // Translate the result back to PDF coordinates.
+ matrix.Concat(1, 0, 0, -1, 0, page->GetPageHeight());
+
+ FS_MATRIX transform = {matrix.a, matrix.b, matrix.c, matrix.d, matrix.e, matrix.f};
+ FS_RECTF clip = {(float) clipLeft, (float) clipTop, (float) clipRight, (float) clipBottom};
+
+ FPDFPage_TransFormWithClip(page, &transform, &clip);
+
+ FPDF_ClosePage(page);
+}
+
+static void nativeGetPageSize(JNIEnv* env, jclass thiz, jlong documentPtr,
+ jint pageIndex, jobject outSize) {
+ FPDF_DOCUMENT document = reinterpret_cast<FPDF_DOCUMENT>(documentPtr);
+
+ FPDF_PAGE page = FPDF_LoadPage(document, pageIndex);
+ if (!page) {
+ jniThrowException(env, "java/lang/IllegalStateException",
+ "cannot open page");
+ return;
+ }
+
+ double width = 0;
+ double height = 0;
+
+ const int result = FPDF_GetPageSizeByIndex(document, pageIndex, &width, &height);
+ if (!result) {
+ jniThrowException(env, "java/lang/IllegalStateException",
+ "cannot get page size");
+ return;
+ }
+
+ env->SetIntField(outSize, gPointClassInfo.x, width);
+ env->SetIntField(outSize, gPointClassInfo.y, height);
+
+ FPDF_ClosePage(page);
+}
+
+static jboolean nativeScaleForPrinting(JNIEnv* env, jclass thiz, jlong documentPtr) {
+ FPDF_DOCUMENT document = reinterpret_cast<FPDF_DOCUMENT>(documentPtr);
+ FPDF_BOOL success = FPDF_VIEWERREF_GetPrintScaling(document);
+ return success ? JNI_TRUE : JNI_FALSE;
+}
+
+static bool nativeGetPageBox(JNIEnv* env, jclass thiz, jlong documentPtr, jint pageIndex,
+ PageBox pageBox, jobject outBox) {
+ FPDF_DOCUMENT document = reinterpret_cast<FPDF_DOCUMENT>(documentPtr);
+
+ FPDF_PAGE page = FPDF_LoadPage(document, pageIndex);
+ if (!page) {
+ jniThrowException(env, "java/lang/IllegalStateException",
+ "cannot open page");
+ return false;
+ }
+
+ float left;
+ float top;
+ float right;
+ float bottom;
+
+ const FPDF_BOOL success = (pageBox == PAGE_BOX_MEDIA)
+ ? FPDFPage_GetMediaBox(page, &left, &top, &right, &bottom)
+ : FPDFPage_GetCropBox(page, &left, &top, &right, &bottom);
+
+ FPDF_ClosePage(page);
+
+ if (!success) {
+ return false;
+ }
+
+ env->SetIntField(outBox, gRectClassInfo.left, (int) left);
+ env->SetIntField(outBox, gRectClassInfo.top, (int) top);
+ env->SetIntField(outBox, gRectClassInfo.right, (int) right);
+ env->SetIntField(outBox, gRectClassInfo.bottom, (int) bottom);
+
+ return true;
+}
+
+static jboolean nativeGetPageMediaBox(JNIEnv* env, jclass thiz, jlong documentPtr, jint pageIndex,
+ jobject outMediaBox) {
+ const bool success = nativeGetPageBox(env, thiz, documentPtr, pageIndex, PAGE_BOX_MEDIA,
+ outMediaBox);
+ return success ? JNI_TRUE : JNI_FALSE;
+}
+
+static jboolean nativeGetPageCropBox(JNIEnv* env, jclass thiz, jlong documentPtr, jint pageIndex,
+ jobject outMediaBox) {
+ const bool success = nativeGetPageBox(env, thiz, documentPtr, pageIndex, PAGE_BOX_CROP,
+ outMediaBox);
+ return success ? JNI_TRUE : JNI_FALSE;
+}
+
+static void nativeSetPageBox(JNIEnv* env, jclass thiz, jlong documentPtr, jint pageIndex,
+ PageBox pageBox, jobject box) {
+ FPDF_DOCUMENT document = reinterpret_cast<FPDF_DOCUMENT>(documentPtr);
+
+ FPDF_PAGE page = FPDF_LoadPage(document, pageIndex);
+ if (!page) {
+ jniThrowException(env, "java/lang/IllegalStateException",
+ "cannot open page");
+ return;
+ }
+
+ const int left = env->GetIntField(box, gRectClassInfo.left);
+ const int top = env->GetIntField(box, gRectClassInfo.top);
+ const int right = env->GetIntField(box, gRectClassInfo.right);
+ const int bottom = env->GetIntField(box, gRectClassInfo.bottom);
+
+ if (pageBox == PAGE_BOX_MEDIA) {
+ FPDFPage_SetMediaBox(page, left, top, right, bottom);
+ } else {
+ FPDFPage_SetCropBox(page, left, top, right, bottom);
+ }
+
+ FPDF_ClosePage(page);
+}
+
+static void nativeSetPageMediaBox(JNIEnv* env, jclass thiz, jlong documentPtr, jint pageIndex,
+ jobject mediaBox) {
+ nativeSetPageBox(env, thiz, documentPtr, pageIndex, PAGE_BOX_MEDIA, mediaBox);
+}
+
+static void nativeSetPageCropBox(JNIEnv* env, jclass thiz, jlong documentPtr, jint pageIndex,
+ jobject mediaBox) {
+ nativeSetPageBox(env, thiz, documentPtr, pageIndex, PAGE_BOX_CROP, mediaBox);
+}
+
static JNINativeMethod gPdfEditor_Methods[] = {
{"nativeOpen", "(IJ)J", (void*) nativeOpen},
{"nativeClose", "(J)V", (void*) nativeClose},
{"nativeGetPageCount", "(J)I", (void*) nativeGetPageCount},
{"nativeRemovePage", "(JI)I", (void*) nativeRemovePage},
- {"nativeWrite", "(JI)V", (void*) nativeWrite}
+ {"nativeWrite", "(JI)V", (void*) nativeWrite},
+ {"nativeSetTransformAndClip", "(JIJIIII)V", (void*) nativeSetTransformAndClip},
+ {"nativeGetPageSize", "(JILandroid/graphics/Point;)V", (void*) nativeGetPageSize},
+ {"nativeScaleForPrinting", "(J)Z", (void*) nativeScaleForPrinting},
+ {"nativeGetPageMediaBox", "(JILandroid/graphics/Rect;)Z", (void*) nativeGetPageMediaBox},
+ {"nativeSetPageMediaBox", "(JILandroid/graphics/Rect;)V", (void*) nativeSetPageMediaBox},
+ {"nativeGetPageCropBox", "(JILandroid/graphics/Rect;)Z", (void*) nativeGetPageCropBox},
+ {"nativeSetPageCropBox", "(JILandroid/graphics/Rect;)V", (void*) nativeSetPageCropBox}
};
int register_android_graphics_pdf_PdfEditor(JNIEnv* env) {
- return android::AndroidRuntime::registerNativeMethods(
+ const int result = android::AndroidRuntime::registerNativeMethods(
env, "android/graphics/pdf/PdfEditor", gPdfEditor_Methods,
NELEM(gPdfEditor_Methods));
+
+ jclass pointClass = env->FindClass("android/graphics/Point");
+ gPointClassInfo.x = env->GetFieldID(pointClass, "x", "I");
+ gPointClassInfo.y = env->GetFieldID(pointClass, "y", "I");
+
+ jclass rectClass = env->FindClass("android/graphics/Rect");
+ gRectClassInfo.left = env->GetFieldID(rectClass, "left", "I");
+ gRectClassInfo.top = env->GetFieldID(rectClass, "top", "I");
+ gRectClassInfo.right = env->GetFieldID(rectClass, "right", "I");
+ gRectClassInfo.bottom = env->GetFieldID(rectClass, "bottom", "I");
+
+ return result;
};
};
diff --git a/core/jni/android/graphics/pdf/PdfRenderer.cpp b/core/jni/android/graphics/pdf/PdfRenderer.cpp
index 303ddea..357d3c0 100644
--- a/core/jni/android/graphics/pdf/PdfRenderer.cpp
+++ b/core/jni/android/graphics/pdf/PdfRenderer.cpp
@@ -82,8 +82,17 @@
if (!document) {
const long error = FPDF_GetLastError();
- jniThrowException(env, "java/io/IOException",
- "cannot create document. Error:" + error);
+ switch (error) {
+ case FPDF_ERR_PASSWORD:
+ case FPDF_ERR_SECURITY: {
+ jniThrowException(env, "java/lang/SecurityException",
+ "cannot create document. Error:" + error);
+ } break;
+ default: {
+ jniThrowException(env, "java/io/IOException",
+ "cannot create document. Error:" + error);
+ } break;
+ }
destroyLibraryIfNeeded();
return -1;
}
diff --git a/core/jni/android_os_Debug.cpp b/core/jni/android_os_Debug.cpp
index 9ec9993..178bab6 100644
--- a/core/jni/android_os_Debug.cpp
+++ b/core/jni/android_os_Debug.cpp
@@ -46,10 +46,12 @@
HEAP_UNKNOWN,
HEAP_DALVIK,
HEAP_NATIVE,
+
HEAP_DALVIK_OTHER,
HEAP_STACK,
HEAP_CURSOR,
HEAP_ASHMEM,
+ HEAP_GL_DEV,
HEAP_UNKNOWN_DEV,
HEAP_SO,
HEAP_JAR,
@@ -297,7 +299,11 @@
} else if (strncmp(name, "[stack", 6) == 0) {
whichHeap = HEAP_STACK;
} else if (strncmp(name, "/dev/", 5) == 0) {
- whichHeap = HEAP_UNKNOWN_DEV;
+ if (strncmp(name, "/dev/kgsl-3d0", 13) == 0) {
+ whichHeap = HEAP_GL_DEV;
+ } else {
+ whichHeap = HEAP_UNKNOWN_DEV;
+ }
} else if (nameLen > 3 && strcmp(name+nameLen-3, ".so") == 0) {
whichHeap = HEAP_SO;
is_swappable = true;
diff --git a/core/jni/android_view_GLES20Canvas.cpp b/core/jni/android_view_GLES20Canvas.cpp
index 2e2b23f..9bdc6b5 100644
--- a/core/jni/android_view_GLES20Canvas.cpp
+++ b/core/jni/android_view_GLES20Canvas.cpp
@@ -43,6 +43,7 @@
#include <RenderNode.h>
#include <CanvasProperty.h>
#include <Paint.h>
+#include <renderthread/RenderProxy.h>
#include "MinikinUtils.h"
@@ -861,7 +862,7 @@
android_app_ActivityThread_dumpGraphics(JNIEnv* env, jobject clazz, jobject javaFileDescriptor) {
#ifdef USE_OPENGL_RENDERER
int fd = jniGetFDFromFileDescriptor(env, javaFileDescriptor);
- android::uirenderer::RenderNode::outputLogBuffer(fd);
+ android::uirenderer::renderthread::RenderProxy::outputLogBuffer(fd);
#endif // USE_OPENGL_RENDERER
}
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 8e0cd52..ffe2b60 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -1269,13 +1269,24 @@
android:description="@string/permdesc_use_sip"
android:label="@string/permlab_use_sip" />
- <!-- Protects the ability to register any PhoneAccount with a capability flags of either
- PhoneAccount#CAPABILITY_CALL_PROVIDER or PhoneAccount#CAPABILITY_SIM_SUBSCRIPTION. -->
- <permission android:name="android.permission.REGISTER_PROVIDER_OR_SUBSCRIPTION"
+ <!-- Protects the ability to register any PhoneAccount with
+ PhoneAccount#CAPABILITY_SIM_SUBSCRIPTION. This capability indicates that the PhoneAccount
+ corresponds to a device SIM. -->
+ <permission android:name="android.permission.REGISTER_SIM_SUBSCRIPTION"
android:permissionGroup="android.permission-group.PHONE_CALLS"
- android:description="@string/permdesc_register_provider"
- android:label="@string/permlab_register_provider" />
+ android:protectionLevel="system|signature"
+ android:description="@string/permdesc_register_sim_subscription"
+ android:label="@string/permlab_register_sim_subscription" />
+ <!-- Protects the ability to register any PhoneAccount with
+ PhoneAccount#CAPABILITY_CALL_PROVIDER. -->
+ <permission android:name="android.permission.REGISTER_CALL_PROVIDER"
+ android:permissionGroup="android.permission-group.PHONE_CALLS"
+ android:description="@string/permdesc_register_call_provider"
+ android:label="@string/permlab_register_call_provider" />
+
+ <!-- Protects the ability to register any PhoneAccount with
+ PhoneAccount#CAPABILITY_CONNECTION_MANAGER -->
<permission android:name="android.permission.REGISTER_CONNECTION_MANAGER"
android:permissionGroup="android.permission-group.PHONE_CALLS"
android:description="@string/permdesc_connection_manager"
@@ -2500,11 +2511,12 @@
android:description="@string/permdesc_broadcastWapPush"
android:protectionLevel="signature" />
- <!-- @SystemApi Allows an application to broadcast a SCORE_NETWORKS request.
+ <!-- @SystemApi Allows an application to broadcast privileged networking requests.
<p>Not for use by third-party applications. @hide -->
- <permission android:name="android.permission.BROADCAST_SCORE_NETWORKS"
- android:label="@string/permlab_broadcastScoreNetworks"
- android:description="@string/permdesc_broadcastScoreNetworks"
+ <permission android:name="android.permission.BROADCAST_NETWORK_PRIVILEGED"
+ android:permissionGroup="android.permission-group.NETWORK"
+ android:label="@string/permlab_broadcastNetworkPrivileged"
+ android:description="@string/permdesc_broadcastNetworkPrivileged"
android:protectionLevel="signature|system" />
<!-- @SystemApi Not for use by third-party applications. -->
diff --git a/core/res/res/drawable-hdpi/sym_def_app_icon.png b/core/res/res/drawable-hdpi/sym_def_app_icon.png
index 96a442e..cde69bc 100644
--- a/core/res/res/drawable-hdpi/sym_def_app_icon.png
+++ b/core/res/res/drawable-hdpi/sym_def_app_icon.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/sym_def_app_icon.png b/core/res/res/drawable-mdpi/sym_def_app_icon.png
index 359047d..c133a0c 100644
--- a/core/res/res/drawable-mdpi/sym_def_app_icon.png
+++ b/core/res/res/drawable-mdpi/sym_def_app_icon.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/sym_def_app_icon.png b/core/res/res/drawable-xhdpi/sym_def_app_icon.png
index 71c6d76..bfa42f0 100644
--- a/core/res/res/drawable-xhdpi/sym_def_app_icon.png
+++ b/core/res/res/drawable-xhdpi/sym_def_app_icon.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/sym_def_app_icon.png b/core/res/res/drawable-xxhdpi/sym_def_app_icon.png
index 20a47a0..324e72c 100644
--- a/core/res/res/drawable-xxhdpi/sym_def_app_icon.png
+++ b/core/res/res/drawable-xxhdpi/sym_def_app_icon.png
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/sym_def_app_icon.png b/core/res/res/drawable-xxxhdpi/sym_def_app_icon.png
new file mode 100644
index 0000000..aee44e1
--- /dev/null
+++ b/core/res/res/drawable-xxxhdpi/sym_def_app_icon.png
Binary files differ
diff --git a/core/res/res/layout/select_dialog_item_material.xml b/core/res/res/layout/select_dialog_item_material.xml
index fe326f3..b45edc6 100644
--- a/core/res/res/layout/select_dialog_item_material.xml
+++ b/core/res/res/layout/select_dialog_item_material.xml
@@ -28,6 +28,6 @@
android:textAppearance="?android:attr/textAppearanceListItemSmall"
android:textColor="?android:attr/textColorAlertDialogListItem"
android:gravity="center_vertical"
- android:paddingStart="@dimen/alert_dialog_padding_material"
- android:paddingEnd="@dimen/alert_dialog_padding_material"
+ android:paddingStart="?attr/listPreferredItemPaddingStart"
+ android:paddingEnd="?attr/listPreferredItemPaddingEnd"
android:ellipsize="marquee" />
diff --git a/core/res/res/mipmap-hdpi/sym_def_app_icon.png b/core/res/res/mipmap-hdpi/sym_def_app_icon.png
index c8a38ed..cde69bc 100644
--- a/core/res/res/mipmap-hdpi/sym_def_app_icon.png
+++ b/core/res/res/mipmap-hdpi/sym_def_app_icon.png
Binary files differ
diff --git a/core/res/res/mipmap-mdpi/sym_def_app_icon.png b/core/res/res/mipmap-mdpi/sym_def_app_icon.png
index b3e10f6..c133a0c 100644
--- a/core/res/res/mipmap-mdpi/sym_def_app_icon.png
+++ b/core/res/res/mipmap-mdpi/sym_def_app_icon.png
Binary files differ
diff --git a/core/res/res/mipmap-xhdpi/sym_def_app_icon.png b/core/res/res/mipmap-xhdpi/sym_def_app_icon.png
index f381f86..bfa42f0 100644
--- a/core/res/res/mipmap-xhdpi/sym_def_app_icon.png
+++ b/core/res/res/mipmap-xhdpi/sym_def_app_icon.png
Binary files differ
diff --git a/core/res/res/mipmap-xxhdpi/sym_def_app_icon.png b/core/res/res/mipmap-xxhdpi/sym_def_app_icon.png
index e3f3144..324e72c 100644
--- a/core/res/res/mipmap-xxhdpi/sym_def_app_icon.png
+++ b/core/res/res/mipmap-xxhdpi/sym_def_app_icon.png
Binary files differ
diff --git a/core/res/res/mipmap-xxxhdpi/sym_def_app_icon.png b/core/res/res/mipmap-xxxhdpi/sym_def_app_icon.png
new file mode 100644
index 0000000..aee44e1
--- /dev/null
+++ b/core/res/res/mipmap-xxxhdpi/sym_def_app_icon.png
Binary files differ
diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml
index ec4bd50..7598aa3 100644
--- a/core/res/res/values-af/strings.xml
+++ b/core/res/res/values-af/strings.xml
@@ -716,8 +716,14 @@
<string name="permdesc_cache_filesystem" msgid="5578967642265550955">"Laat die program toe om die kaslêerstelsel te lees en skryf."</string>
<string name="permlab_use_sip" msgid="2052499390128979920">"maak en/of ontvang SIP-oproepe"</string>
<string name="permdesc_use_sip" msgid="2297804849860225257">"Laat die program toe om SIP-oproepe te maak en te ontvang."</string>
- <string name="permlab_register_provider" msgid="2654513709546459553">"registreer nuwe telekom-verbinding"</string>
- <string name="permdesc_register_provider" msgid="7571533832018681544">"Laat die program toe om nuwe telekom-verbindings te registreer."</string>
+ <!-- no translation found for permlab_register_sim_subscription (3166535485877549177) -->
+ <skip />
+ <!-- no translation found for permdesc_register_sim_subscription (2138909035926222911) -->
+ <skip />
+ <!-- no translation found for permlab_register_call_provider (108102120289029841) -->
+ <skip />
+ <!-- no translation found for permdesc_register_call_provider (7034310263521081388) -->
+ <skip />
<string name="permlab_connection_manager" msgid="1116193254522105375">"bestuur telekom-verbindings"</string>
<string name="permdesc_connection_manager" msgid="5925480810356483565">"Laat die program toe om telekom-verbindings te bestuur."</string>
<string name="permlab_bind_incall_service" msgid="6773648341975287125">"beleef interaksie met inoproep-skerm"</string>
@@ -1233,6 +1239,7 @@
<string name="smv_application" msgid="3307209192155442829">"Die program <xliff:g id="APPLICATION">%1$s</xliff:g> (proses <xliff:g id="PROCESS">%2$s</xliff:g>) het sy selfopgelegde StrictMode-beleid oortree."</string>
<string name="smv_process" msgid="5120397012047462446">"Die proses <xliff:g id="PROCESS">%1$s</xliff:g> het die selfopgelegde StrictMode-beleid geskend."</string>
<string name="android_upgrading_title" msgid="1584192285441405746">"Android gradeer tans op..."</string>
+ <string name="android_start_title" msgid="8418054686415318207">"Android begin tans …"</string>
<string name="android_upgrading_apk" msgid="7904042682111526169">"Optimeer program <xliff:g id="NUMBER_0">%1$d</xliff:g> van <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
<string name="android_upgrading_starting_apps" msgid="451464516346926713">"Begin programme."</string>
<string name="android_upgrading_complete" msgid="1405954754112999229">"Voltooi herlaai."</string>
@@ -1776,10 +1783,14 @@
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Vra wagwoord voordat jy ontspeld"</string>
<string name="battery_saver_description" msgid="2510530476513605742">"Om batteryleeftyd te help verbeter, verminder batterybespaarder jou toestel se werkverrigting en beperk vibrasie en die meeste agtergronddata. E-pos, boodskappe en ander programme wat op sinkronisering staatmaak, sal dalk nie opdateer nie tensy jy hulle oopmaak.\n\nBatterybespaarder skakel outomaties af wanneer jou toestel laai."</string>
<string name="downtime_condition_summary" msgid="8761776337475705749">"Totdat jou ontspantyd om <xliff:g id="FORMATTEDTIME">%1$s</xliff:g> eindig"</string>
- <!-- no translation found for zen_mode_duration_minutes_summary:one (3177683545388923234) -->
- <!-- no translation found for zen_mode_duration_minutes_summary:other (2787867221129368935) -->
- <!-- no translation found for zen_mode_duration_hours_summary:one (597194865053253679) -->
- <!-- no translation found for zen_mode_duration_hours_summary:other (2827214920627669898) -->
+ <plurals name="zen_mode_duration_minutes_summary">
+ <item quantity="one" msgid="3177683545388923234">"Vir een minuut (tot <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ <item quantity="other" msgid="2787867221129368935">"Vir %1$d minute (tot <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ </plurals>
+ <plurals name="zen_mode_duration_hours_summary">
+ <item quantity="one" msgid="597194865053253679">"Vir een uur (tot <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ <item quantity="other" msgid="2827214920627669898">"Vir %1$d ure (tot <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ </plurals>
<plurals name="zen_mode_duration_minutes">
<item quantity="one" msgid="9040808414992812341">"Een minuut lank"</item>
<item quantity="other" msgid="6924190729213550991">"%d minute lank"</item>
@@ -1788,7 +1799,7 @@
<item quantity="one" msgid="3480040795582254384">"Een uur lank"</item>
<item quantity="other" msgid="5408537517529822157">"%d uur lank"</item>
</plurals>
- <!-- no translation found for zen_mode_until (7336308492289875088) -->
- <skip />
+ <string name="zen_mode_until" msgid="7336308492289875088">"Tot <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
<string name="zen_mode_forever" msgid="4316804956488785559">"Onbepaalde tyd"</string>
+ <string name="toolbar_collapse_description" msgid="2821479483960330739">"Vou in"</string>
</resources>
diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml
index 2ba358d..da4136d 100644
--- a/core/res/res/values-am/strings.xml
+++ b/core/res/res/values-am/strings.xml
@@ -716,8 +716,14 @@
<string name="permdesc_cache_filesystem" msgid="5578967642265550955">"መሸጎጫ ስርዓተ ፋይል ለማንበብ እና ለመፃፍ ለመተግበሪያው ይፈቅዳሉ።"</string>
<string name="permlab_use_sip" msgid="2052499390128979920">"የSIP ጥሪዎችን ያድርጉ/ይቀበሉ"</string>
<string name="permdesc_use_sip" msgid="2297804849860225257">"መተግበሪያው የSIP ጥሪዎችን እንዲያደር እና እንዲቀበል ያስችላል።"</string>
- <string name="permlab_register_provider" msgid="2654513709546459553">"አዲስ የቴሌኮም ግንኙነት ይመዘግባል"</string>
- <string name="permdesc_register_provider" msgid="7571533832018681544">"መተግበሪያው አዲስ የቴሌክኮም ግንኙነቶችን እንዲመዘግብ ያስችለዋል"</string>
+ <!-- no translation found for permlab_register_sim_subscription (3166535485877549177) -->
+ <skip />
+ <!-- no translation found for permdesc_register_sim_subscription (2138909035926222911) -->
+ <skip />
+ <!-- no translation found for permlab_register_call_provider (108102120289029841) -->
+ <skip />
+ <!-- no translation found for permdesc_register_call_provider (7034310263521081388) -->
+ <skip />
<string name="permlab_connection_manager" msgid="1116193254522105375">"የቴሌኮም ግንኙነቶችን ያቀናብራል"</string>
<string name="permdesc_connection_manager" msgid="5925480810356483565">"መተግበሪያው የቴሌኮም ግንኙነቶችን እንዲያቀናብር ያስችለዋል።"</string>
<string name="permlab_bind_incall_service" msgid="6773648341975287125">"ከውስጠ-ጥሪ ማያ ገጽ ጋር መስተጋብር ይፈጥራል"</string>
@@ -1233,6 +1239,7 @@
<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_apk" msgid="7904042682111526169">"መተግበሪያዎች በአግባቡ በመጠቀም ላይ <xliff:g id="NUMBER_0">%1$d</xliff:g> ከ <xliff:g id="NUMBER_1">%2$d</xliff:g> ፡፡"</string>
<string name="android_upgrading_starting_apps" msgid="451464516346926713">"መተግበሪያዎችን በማስጀመር ላይ፡፡"</string>
<string name="android_upgrading_complete" msgid="1405954754112999229">"አጨራረስ ማስነሻ፡፡"</string>
@@ -1776,10 +1783,14 @@
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"ከመንቀል በፊት የይለፍ ቃል ጠይቅ"</string>
<string name="battery_saver_description" msgid="2510530476513605742">"የባትሪ ህይወትን ለማሻሻል ሲባል ባትሪ ቆጣቢ የመሣሪያዎ የስራ አፈጻጸምን እና ንዝረትንና አብዛኛውን የጀርባ ውሂብ ይቀንሳል። ኢሜይል፣ መልዕክት መላላኪያ እና ሌሎች በማመሳሰል ላይ የሚወሰኑ መተግበሪያዎች እስኪከፍቷቸው ድረስ ላይዘምኑ ይችላሉ።\n\nመሣሪያዎ ባትሪ እየሞላ ሲሆን ባትሪ ቆጣቢ በራስ-ሰር ይጠፋል።"</string>
<string name="downtime_condition_summary" msgid="8761776337475705749">"የጥገና ጊዜዎ <xliff:g id="FORMATTEDTIME">%1$s</xliff:g> ላይ እስኪያበቃ ድረስ"</string>
- <!-- no translation found for zen_mode_duration_minutes_summary:one (3177683545388923234) -->
- <!-- no translation found for zen_mode_duration_minutes_summary:other (2787867221129368935) -->
- <!-- no translation found for zen_mode_duration_hours_summary:one (597194865053253679) -->
- <!-- no translation found for zen_mode_duration_hours_summary:other (2827214920627669898) -->
+ <plurals name="zen_mode_duration_minutes_summary">
+ <item quantity="one" msgid="3177683545388923234">"ለአንድ ደቂቃ (እስከ <xliff:g id="FORMATTEDTIME">%2$s</xliff:g> ድረስ)"</item>
+ <item quantity="other" msgid="2787867221129368935">"ለ%1$d ደቂቃዎች (እስከ <xliff:g id="FORMATTEDTIME">%2$s</xliff:g> ድረስ)"</item>
+ </plurals>
+ <plurals name="zen_mode_duration_hours_summary">
+ <item quantity="one" msgid="597194865053253679">"ለአንድ ሰዓት (እስከ <xliff:g id="FORMATTEDTIME">%2$s</xliff:g> ድረስ)"</item>
+ <item quantity="other" msgid="2827214920627669898">"ለ%1$d ሰዓቶች (እስከ <xliff:g id="FORMATTEDTIME">%2$s</xliff:g> ድረስ)"</item>
+ </plurals>
<plurals name="zen_mode_duration_minutes">
<item quantity="one" msgid="9040808414992812341">"ለአንድ ደቂቃ"</item>
<item quantity="other" msgid="6924190729213550991">"ለ%d ደቂቃዎች"</item>
@@ -1788,7 +1799,7 @@
<item quantity="one" msgid="3480040795582254384">"ለአንድ ሰዓት"</item>
<item quantity="other" msgid="5408537517529822157">"ለ%d ሰዓቶች"</item>
</plurals>
- <!-- no translation found for zen_mode_until (7336308492289875088) -->
- <skip />
+ <string name="zen_mode_until" msgid="7336308492289875088">"እስከ <xliff:g id="FORMATTEDTIME">%1$s</xliff:g> ድረስ"</string>
<string name="zen_mode_forever" msgid="4316804956488785559">"ያለገደብ"</string>
+ <string name="toolbar_collapse_description" msgid="2821479483960330739">"ሰብስብ"</string>
</resources>
diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml
index d1320d86..8439432 100644
--- a/core/res/res/values-ar/strings.xml
+++ b/core/res/res/values-ar/strings.xml
@@ -716,8 +716,14 @@
<string name="permdesc_cache_filesystem" msgid="5578967642265550955">"للسماح للتطبيق بقراءة نظام ملفات ذاكرة التخزين المؤقت والكتابة به."</string>
<string name="permlab_use_sip" msgid="2052499390128979920">"إجراء/تلقي مكالمات SIP"</string>
<string name="permdesc_use_sip" msgid="2297804849860225257">"للسماح للتطبيق بإجراء مكالمات SIP وتلقيها."</string>
- <string name="permlab_register_provider" msgid="2654513709546459553">"تسجيل الاتصال اللاسلكي الجديد"</string>
- <string name="permdesc_register_provider" msgid="7571533832018681544">"للسماح للتطبيق بتسجيل الاتصالات اللاسلكية الجديدة."</string>
+ <!-- no translation found for permlab_register_sim_subscription (3166535485877549177) -->
+ <skip />
+ <!-- no translation found for permdesc_register_sim_subscription (2138909035926222911) -->
+ <skip />
+ <!-- no translation found for permlab_register_call_provider (108102120289029841) -->
+ <skip />
+ <!-- no translation found for permdesc_register_call_provider (7034310263521081388) -->
+ <skip />
<string name="permlab_connection_manager" msgid="1116193254522105375">"إدارة الاتصالات اللاسلكية"</string>
<string name="permdesc_connection_manager" msgid="5925480810356483565">"للسماح للتطبيق بإدارة الاتصالات اللاسلكية."</string>
<string name="permlab_bind_incall_service" msgid="6773648341975287125">"التفاعل مع الشاشة أثناء الاتصال"</string>
@@ -1233,6 +1239,7 @@
<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_apk" msgid="7904042682111526169">"جارٍ تحسين التطبيق <xliff:g id="NUMBER_0">%1$d</xliff:g> من <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
<string name="android_upgrading_starting_apps" msgid="451464516346926713">"بدء التطبيقات."</string>
<string name="android_upgrading_complete" msgid="1405954754112999229">"جارٍ إعادة التشغيل."</string>
@@ -1776,10 +1783,14 @@
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"المطالبة بكلمة المرور قبل إزالة التثبيت"</string>
<string name="battery_saver_description" msgid="2510530476513605742">"للمساعدة في تحسين مدة تشغيل البطارية، يقلل وضع توفير طاقة البطارية أداء جهازك ويقلل من الاهتزاز ومعظم بيانات الخلفية. وقد لا يتم تحديث البريد الإلكتروني والمراسلة والتطبيقات الأخرى التي تعتمد على المزامنة ما لم تفتحها.\n\nيتم إيقاف وضع توفير طاقة البطارية تلقائيًا عندما يكون الجهاز قيد الشحن."</string>
<string name="downtime_condition_summary" msgid="8761776337475705749">"إلى أن ينتهي وقت التوقف عن العمل في <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
- <!-- no translation found for zen_mode_duration_minutes_summary:one (3177683545388923234) -->
- <!-- no translation found for zen_mode_duration_minutes_summary:other (2787867221129368935) -->
- <!-- no translation found for zen_mode_duration_hours_summary:one (597194865053253679) -->
- <!-- no translation found for zen_mode_duration_hours_summary:other (2827214920627669898) -->
+ <plurals name="zen_mode_duration_minutes_summary">
+ <item quantity="one" msgid="3177683545388923234">"لمدة دقيقة واحدة (حتى <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ <item quantity="other" msgid="2787867221129368935">"لمدة %1$d من الدقائق (حتى <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ </plurals>
+ <plurals name="zen_mode_duration_hours_summary">
+ <item quantity="one" msgid="597194865053253679">"لمدة ساعة واحدة (حتى <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ <item quantity="other" msgid="2827214920627669898">"لمدة %1$d من الساعات (حتى <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ </plurals>
<plurals name="zen_mode_duration_minutes">
<item quantity="one" msgid="9040808414992812341">"لمدة دقيقة واحدة"</item>
<item quantity="other" msgid="6924190729213550991">"لمدة %d من الدقائق"</item>
@@ -1788,7 +1799,7 @@
<item quantity="one" msgid="3480040795582254384">"لمدة ساعة واحدة"</item>
<item quantity="other" msgid="5408537517529822157">"لمدة %d من الساعات"</item>
</plurals>
- <!-- no translation found for zen_mode_until (7336308492289875088) -->
- <skip />
+ <string name="zen_mode_until" msgid="7336308492289875088">"حتى <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
<string name="zen_mode_forever" msgid="4316804956488785559">"إلى أجل غير مسمى"</string>
+ <string name="toolbar_collapse_description" msgid="2821479483960330739">"تصغير"</string>
</resources>
diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml
index e202127..c2f7a8f 100644
--- a/core/res/res/values-bg/strings.xml
+++ b/core/res/res/values-bg/strings.xml
@@ -716,8 +716,14 @@
<string name="permdesc_cache_filesystem" msgid="5578967642265550955">"Разрешава на приложението да чете и записва във файловата система на кеша."</string>
<string name="permlab_use_sip" msgid="2052499390128979920">"извършване/получаване на обаждания чрез SIP"</string>
<string name="permdesc_use_sip" msgid="2297804849860225257">"Разрешава на приложението да извършва и получава обаждания чрез SIP."</string>
- <string name="permlab_register_provider" msgid="2654513709546459553">"регистриране на новите телекомуникационни връзки"</string>
- <string name="permdesc_register_provider" msgid="7571533832018681544">"Разрешава на приложението да регистрира новите телекомуникационни връзки."</string>
+ <!-- no translation found for permlab_register_sim_subscription (3166535485877549177) -->
+ <skip />
+ <!-- no translation found for permdesc_register_sim_subscription (2138909035926222911) -->
+ <skip />
+ <!-- no translation found for permlab_register_call_provider (108102120289029841) -->
+ <skip />
+ <!-- no translation found for permdesc_register_call_provider (7034310263521081388) -->
+ <skip />
<string name="permlab_connection_manager" msgid="1116193254522105375">"управление на телекомуникационните връзки"</string>
<string name="permdesc_connection_manager" msgid="5925480810356483565">"Разрешава на приложението да управлява телекомуникационните връзки."</string>
<string name="permlab_bind_incall_service" msgid="6773648341975287125">"взаимодействие с екрана за обаждане"</string>
@@ -1233,6 +1239,7 @@
<string name="smv_application" msgid="3307209192155442829">"Приложението „<xliff:g id="APPLICATION">%1$s</xliff:g>“ (процес „<xliff:g id="PROCESS">%2$s</xliff:g>“) наруши правилото за стриктен режим, наложено от самото него."</string>
<string name="smv_process" msgid="5120397012047462446">"Процесът <xliff:g id="PROCESS">%1$s</xliff:g> наруши правилото за стриктен режим, наложено от самия него."</string>
<string name="android_upgrading_title" msgid="1584192285441405746">"Android се надстройва..."</string>
+ <string name="android_start_title" msgid="8418054686415318207">"Android се стартира…"</string>
<string name="android_upgrading_apk" msgid="7904042682111526169">"Оптимизира се приложение <xliff:g id="NUMBER_0">%1$d</xliff:g> от <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
<string name="android_upgrading_starting_apps" msgid="451464516346926713">"Приложенията се стартират."</string>
<string name="android_upgrading_complete" msgid="1405954754112999229">"Зареждането завършва."</string>
@@ -1776,10 +1783,14 @@
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Запитване за парола преди освобождаване"</string>
<string name="battery_saver_description" msgid="2510530476513605742">"С цел удължаване на живота на батерията режимът за запазването й намалява ефективността на устройството ви и ограничава вибрирането и повечето данни на заден план. Имейл, Съобщения и другите приложения, които разчитат на синхронизиране, може да не се актуализират, освен ако не ги отворите.\n\nТози режим автоматично се изключва, когато устройството ви се зарежда."</string>
<string name="downtime_condition_summary" msgid="8761776337475705749">"До приключване на неактивността в <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
- <!-- no translation found for zen_mode_duration_minutes_summary:one (3177683545388923234) -->
- <!-- no translation found for zen_mode_duration_minutes_summary:other (2787867221129368935) -->
- <!-- no translation found for zen_mode_duration_hours_summary:one (597194865053253679) -->
- <!-- no translation found for zen_mode_duration_hours_summary:other (2827214920627669898) -->
+ <plurals name="zen_mode_duration_minutes_summary">
+ <item quantity="one" msgid="3177683545388923234">"За една минута (до <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ <item quantity="other" msgid="2787867221129368935">"За %1$d минути (до <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ </plurals>
+ <plurals name="zen_mode_duration_hours_summary">
+ <item quantity="one" msgid="597194865053253679">"За един час (до <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ <item quantity="other" msgid="2827214920627669898">"За %1$d часа (до <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ </plurals>
<plurals name="zen_mode_duration_minutes">
<item quantity="one" msgid="9040808414992812341">"За една минута"</item>
<item quantity="other" msgid="6924190729213550991">"За %d минути"</item>
@@ -1788,7 +1799,7 @@
<item quantity="one" msgid="3480040795582254384">"За един час"</item>
<item quantity="other" msgid="5408537517529822157">"За %d часа"</item>
</plurals>
- <!-- no translation found for zen_mode_until (7336308492289875088) -->
- <skip />
+ <string name="zen_mode_until" msgid="7336308492289875088">"До <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
<string name="zen_mode_forever" msgid="4316804956488785559">"За неопределено време"</string>
+ <string name="toolbar_collapse_description" msgid="2821479483960330739">"Свиване"</string>
</resources>
diff --git a/core/res/res/values-bn-rBD/strings.xml b/core/res/res/values-bn-rBD/strings.xml
index 43a758d..9c6a344 100644
--- a/core/res/res/values-bn-rBD/strings.xml
+++ b/core/res/res/values-bn-rBD/strings.xml
@@ -716,8 +716,14 @@
<string name="permdesc_cache_filesystem" msgid="5578967642265550955">"ক্যাশে ফাইল সিস্টেম পড়তে ও লিখতে অ্যাপ্লিকেশানকে অনুমতি দেয়৷"</string>
<string name="permlab_use_sip" msgid="2052499390128979920">"SIP কল করুন/গ্রহণ করুন"</string>
<string name="permdesc_use_sip" msgid="2297804849860225257">"অ্যাপ্লিকেশানকে SIP কল করতে ও গ্রহণ করতে অনুমতি দেয়।"</string>
- <string name="permlab_register_provider" msgid="2654513709546459553">"নতুন টেলিকম সংযোগ নিবন্ধিত করুন"</string>
- <string name="permdesc_register_provider" msgid="7571533832018681544">"নতুন টেলিকম সংযোগ নিবন্ধিত করতে অ্যাপ্লিকেশানটিকে অনুমোদিত করে৷"</string>
+ <!-- no translation found for permlab_register_sim_subscription (3166535485877549177) -->
+ <skip />
+ <!-- no translation found for permdesc_register_sim_subscription (2138909035926222911) -->
+ <skip />
+ <!-- no translation found for permlab_register_call_provider (108102120289029841) -->
+ <skip />
+ <!-- no translation found for permdesc_register_call_provider (7034310263521081388) -->
+ <skip />
<string name="permlab_connection_manager" msgid="1116193254522105375">"টেলিকম সংযোগগুলি পরিচালনা করুন"</string>
<string name="permdesc_connection_manager" msgid="5925480810356483565">"টেলিকম সংযোগগুলি পরিচালনা করতে অ্যাপ্লিকেশানটিকে অনুমোদিত করে৷"</string>
<string name="permlab_bind_incall_service" msgid="6773648341975287125">"কলে-থাকা স্ক্রীণের সাথে ইন্টারঅ্যাক্ট করে"</string>
@@ -1233,6 +1239,7 @@
<string name="smv_application" msgid="3307209192155442829">"অ্যাপ্লিকেশানটি <xliff:g id="APPLICATION">%1$s</xliff:g> (প্রক্রিয়া <xliff:g id="PROCESS">%2$s</xliff:g>) তার স্ব-প্রয়োগ করা কঠোর মোড নীতি লঙ্ঘন করেছে৷"</string>
<string name="smv_process" msgid="5120397012047462446">"প্রক্রিয়াটি <xliff:g id="PROCESS">%1$s</xliff:g> তার স্ব-প্রয়োগ করা কঠোর মোড নীতি লঙ্ঘন করেছে৷"</string>
<string name="android_upgrading_title" msgid="1584192285441405746">"Android আপগ্রেড করা হচ্ছে..."</string>
+ <string name="android_start_title" msgid="8418054686415318207">"Android চালু হচ্ছে…"</string>
<string name="android_upgrading_apk" msgid="7904042682111526169">"<xliff:g id="NUMBER_1">%2$d</xliff:g>টির মধ্যে <xliff:g id="NUMBER_0">%1$d</xliff:g>টি অ্যাপ্লিকেশান অপ্টিমাইজ করা হচ্ছে৷"</string>
<string name="android_upgrading_starting_apps" msgid="451464516346926713">"অ্যাপ্লিকেশানগুলি শুরু করা হচ্ছে৷"</string>
<string name="android_upgrading_complete" msgid="1405954754112999229">"চালু করা সম্পূর্ণ হচ্ছে৷"</string>
@@ -1776,10 +1783,14 @@
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"আনপিন করার আগে পাসওয়ার্ড চান"</string>
<string name="battery_saver_description" msgid="2510530476513605742">"ব্যাটারির আয়ু বাড়াতে সহায়তার জন্য, ব্যাটারি সঞ্চয়কারী আপনার ডিভাইসের কার্য-সম্পাদনা কমিয়ে আনবে এবং কম্পন ও পশ্চাদভূমি ডেটাকে সীমিত করবে। ইমেল, বার্তাপ্রেরণ ও অন্যান্য অ্যাপ্লিকেশান, যেগুলি সিঙ্ক হওয়ার উপর নির্ভরশীল সেগুলিকে আপনি না খোলা পর্যন্ত সেগুলি আপডেট নাও হতে পারে।\n\nআপনার ডিভাইস চার্জ হওয়ার সময় ব্যাটারি সঞ্চয়কারী স্বয়ংক্রিয়ভাবে বন্ধ হয়ে যাবে।"</string>
<string name="downtime_condition_summary" msgid="8761776337475705749">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g>টার সময়ে আপনার ডাউনটাইম শেষ হওয়া পর্যন্ত"</string>
- <!-- no translation found for zen_mode_duration_minutes_summary:one (3177683545388923234) -->
- <!-- no translation found for zen_mode_duration_minutes_summary:other (2787867221129368935) -->
- <!-- no translation found for zen_mode_duration_hours_summary:one (597194865053253679) -->
- <!-- no translation found for zen_mode_duration_hours_summary:other (2827214920627669898) -->
+ <plurals name="zen_mode_duration_minutes_summary">
+ <item quantity="one" msgid="3177683545388923234">"এক মিনিটের জন্য (<xliff:g id="FORMATTEDTIME">%2$s</xliff:g> পর্যন্ত)"</item>
+ <item quantity="other" msgid="2787867221129368935">"%1$d মিনিটের জন্য (<xliff:g id="FORMATTEDTIME">%2$s</xliff:g> পর্যন্ত)"</item>
+ </plurals>
+ <plurals name="zen_mode_duration_hours_summary">
+ <item quantity="one" msgid="597194865053253679">"এক ঘন্টার জন্য (<xliff:g id="FORMATTEDTIME">%2$s</xliff:g> পর্যন্ত)"</item>
+ <item quantity="other" msgid="2827214920627669898">"%1$d ঘন্টার জন্য (<xliff:g id="FORMATTEDTIME">%2$s</xliff:g> পর্যন্ত)"</item>
+ </plurals>
<plurals name="zen_mode_duration_minutes">
<item quantity="one" msgid="9040808414992812341">"এক মিনিটের জন্য"</item>
<item quantity="other" msgid="6924190729213550991">"%d মিনিটের জন্য"</item>
@@ -1788,7 +1799,7 @@
<item quantity="one" msgid="3480040795582254384">"এক ঘন্টার জন্য"</item>
<item quantity="other" msgid="5408537517529822157">"%d ঘন্টার জন্য"</item>
</plurals>
- <!-- no translation found for zen_mode_until (7336308492289875088) -->
- <skip />
+ <string name="zen_mode_until" msgid="7336308492289875088">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g> পর্যন্ত"</string>
<string name="zen_mode_forever" msgid="4316804956488785559">"অনির্দিষ্টভাবে"</string>
+ <string name="toolbar_collapse_description" msgid="2821479483960330739">"সঙ্কুচিত করুন"</string>
</resources>
diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml
index 5aeb5d9..0ab84cd 100644
--- a/core/res/res/values-ca/strings.xml
+++ b/core/res/res/values-ca/strings.xml
@@ -716,8 +716,14 @@
<string name="permdesc_cache_filesystem" msgid="5578967642265550955">"Permet que l\'aplicació llegeixi el sistema de fitxers de la memòria cau i que hi escrigui."</string>
<string name="permlab_use_sip" msgid="2052499390128979920">"Fer i rebre trucades de SIP"</string>
<string name="permdesc_use_sip" msgid="2297804849860225257">"Permet que l\'aplicació pugui fer i rebre trucades de SIP."</string>
- <string name="permlab_register_provider" msgid="2654513709546459553">"registrar connexions de telecomunicacions noves"</string>
- <string name="permdesc_register_provider" msgid="7571533832018681544">"Permet que l\'aplicació registri connexions de telecomunicacions noves."</string>
+ <!-- no translation found for permlab_register_sim_subscription (3166535485877549177) -->
+ <skip />
+ <!-- no translation found for permdesc_register_sim_subscription (2138909035926222911) -->
+ <skip />
+ <!-- no translation found for permlab_register_call_provider (108102120289029841) -->
+ <skip />
+ <!-- no translation found for permdesc_register_call_provider (7034310263521081388) -->
+ <skip />
<string name="permlab_connection_manager" msgid="1116193254522105375">"gestionar les connexions de telecomunicacions"</string>
<string name="permdesc_connection_manager" msgid="5925480810356483565">"Permet que l\'aplicació gestioni les connexions de telecomunicacions."</string>
<string name="permlab_bind_incall_service" msgid="6773648341975287125">"interaccionar amb la pantalla de la trucada"</string>
@@ -1233,6 +1239,7 @@
<string name="smv_application" msgid="3307209192155442829">"L\'aplicació <xliff:g id="APPLICATION">%1$s</xliff:g>(procés <xliff:g id="PROCESS">%2$s</xliff:g>) ha incomplert la seva política autoimposada de mode estricte."</string>
<string name="smv_process" msgid="5120397012047462446">"El procés <xliff:g id="PROCESS">%1$s</xliff:g> ha incomplert la seva política de mode estricte."</string>
<string name="android_upgrading_title" msgid="1584192285441405746">"Android s\'està actualitzant..."</string>
+ <string name="android_start_title" msgid="8418054686415318207">"S\'està iniciant Android…"</string>
<string name="android_upgrading_apk" msgid="7904042682111526169">"S\'està optimitzant l\'aplicació <xliff:g id="NUMBER_0">%1$d</xliff:g> de <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
<string name="android_upgrading_starting_apps" msgid="451464516346926713">"S\'estan iniciant les aplicacions."</string>
<string name="android_upgrading_complete" msgid="1405954754112999229">"S\'està finalitzant l\'actualització."</string>
@@ -1776,10 +1783,14 @@
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Demana la contrasenya abans d\'anul·lar la fixació"</string>
<string name="battery_saver_description" msgid="2510530476513605742">"Per tal d\'augmentar la durada de la bateria, la funció d\'estalvi de bateria redueix el rendiment del dispositiu i en limita la vibració i la majoria de dades en segon pla. És possible que el correu electrònic, la missatgeria i la resta d\'aplicacions que se sincronitzen amb freqüència no s\'actualitzin llevat que les obris.\n\nL\'estalvi de bateria es desactiva automàticament mentre el dispositiu s\'està carregant."</string>
<string name="downtime_condition_summary" msgid="8761776337475705749">"Fins que no finalitzi la inactivitat a les <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>."</string>
- <!-- no translation found for zen_mode_duration_minutes_summary:one (3177683545388923234) -->
- <!-- no translation found for zen_mode_duration_minutes_summary:other (2787867221129368935) -->
- <!-- no translation found for zen_mode_duration_hours_summary:one (597194865053253679) -->
- <!-- no translation found for zen_mode_duration_hours_summary:other (2827214920627669898) -->
+ <plurals name="zen_mode_duration_minutes_summary">
+ <item quantity="one" msgid="3177683545388923234">"Durant 1 minut (fins a les <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ <item quantity="other" msgid="2787867221129368935">"Durant %1$d minuts (fins a les <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ </plurals>
+ <plurals name="zen_mode_duration_hours_summary">
+ <item quantity="one" msgid="597194865053253679">"Durant 1 hora (fins a les <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ <item quantity="other" msgid="2827214920627669898">"Durant %1$d hores (fins a les <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ </plurals>
<plurals name="zen_mode_duration_minutes">
<item quantity="one" msgid="9040808414992812341">"Durant un minut"</item>
<item quantity="other" msgid="6924190729213550991">"Durant %d minuts"</item>
@@ -1788,7 +1799,7 @@
<item quantity="one" msgid="3480040795582254384">"Durant una hora"</item>
<item quantity="other" msgid="5408537517529822157">"Durant %d hores"</item>
</plurals>
- <!-- no translation found for zen_mode_until (7336308492289875088) -->
- <skip />
+ <string name="zen_mode_until" msgid="7336308492289875088">"Fins a les <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
<string name="zen_mode_forever" msgid="4316804956488785559">"Indefinidament"</string>
+ <string name="toolbar_collapse_description" msgid="2821479483960330739">"Replega"</string>
</resources>
diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml
index ffb80da..10782fe 100644
--- a/core/res/res/values-cs/strings.xml
+++ b/core/res/res/values-cs/strings.xml
@@ -716,8 +716,14 @@
<string name="permdesc_cache_filesystem" msgid="5578967642265550955">"Umožňuje aplikaci číst a zapisovat do souborového systému mezipaměti."</string>
<string name="permlab_use_sip" msgid="2052499390128979920">"uskutečňování/příjem volání SIP"</string>
<string name="permdesc_use_sip" msgid="2297804849860225257">"Povolí aplikaci uskutečňovat a přijímat volání SIP."</string>
- <string name="permlab_register_provider" msgid="2654513709546459553">"registrace nového telekomunikačního připojení"</string>
- <string name="permdesc_register_provider" msgid="7571533832018681544">"Umožňuje aplikaci registrovat nová telekomunikační připojení."</string>
+ <!-- no translation found for permlab_register_sim_subscription (3166535485877549177) -->
+ <skip />
+ <!-- no translation found for permdesc_register_sim_subscription (2138909035926222911) -->
+ <skip />
+ <!-- no translation found for permlab_register_call_provider (108102120289029841) -->
+ <skip />
+ <!-- no translation found for permdesc_register_call_provider (7034310263521081388) -->
+ <skip />
<string name="permlab_connection_manager" msgid="1116193254522105375">"správa telekomunikačních připojení"</string>
<string name="permdesc_connection_manager" msgid="5925480810356483565">"Umožňuje aplikaci spravovat telekomunikační připojení."</string>
<string name="permlab_bind_incall_service" msgid="6773648341975287125">"interakce s obrazovkou příchozího hovoru"</string>
@@ -1233,6 +1239,7 @@
<string name="smv_application" msgid="3307209192155442829">"Aplikace <xliff:g id="APPLICATION">%1$s</xliff:g> (proces <xliff:g id="PROCESS">%2$s</xliff:g>) porušila své vlastní vynucené zásady StrictMode."</string>
<string name="smv_process" msgid="5120397012047462446">"Proces <xliff:g id="PROCESS">%1$s</xliff:g> porušil své vlastní vynucené zásady StrictMode."</string>
<string name="android_upgrading_title" msgid="1584192285441405746">"Android se upgraduje..."</string>
+ <string name="android_start_title" msgid="8418054686415318207">"Spouštění systému Android…"</string>
<string name="android_upgrading_apk" msgid="7904042682111526169">"Optimalizování aplikace <xliff:g id="NUMBER_0">%1$d</xliff:g> z <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
<string name="android_upgrading_starting_apps" msgid="451464516346926713">"Spouštění aplikací."</string>
<string name="android_upgrading_complete" msgid="1405954754112999229">"Dokončování inicializace."</string>
@@ -1776,10 +1783,14 @@
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Před uvolněním požádat o heslo"</string>
<string name="battery_saver_description" msgid="2510530476513605742">"Za účelem zvýšení životnosti baterie spořič baterie sníží výkon vašeho zařízení a omezí vibrace a většinu dat na pozadí. E-mail, zprávy a další aplikace, které používají synchronizaci, nemusejí být aktualizovány, dokud je nespustíte.\n\nPři nabíjení zařízení se spořič baterie automaticky vypne."</string>
<string name="downtime_condition_summary" msgid="8761776337475705749">"Dokud v <xliff:g id="FORMATTEDTIME">%1$s</xliff:g> neskončí pozastavení"</string>
- <!-- no translation found for zen_mode_duration_minutes_summary:one (3177683545388923234) -->
- <!-- no translation found for zen_mode_duration_minutes_summary:other (2787867221129368935) -->
- <!-- no translation found for zen_mode_duration_hours_summary:one (597194865053253679) -->
- <!-- no translation found for zen_mode_duration_hours_summary:other (2827214920627669898) -->
+ <plurals name="zen_mode_duration_minutes_summary">
+ <item quantity="one" msgid="3177683545388923234">"Jednu minutu (do <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ <item quantity="other" msgid="2787867221129368935">"%1$d min (do <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ </plurals>
+ <plurals name="zen_mode_duration_hours_summary">
+ <item quantity="one" msgid="597194865053253679">"Jednu hodinu (do <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ <item quantity="other" msgid="2827214920627669898">"%1$d h (do <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ </plurals>
<plurals name="zen_mode_duration_minutes">
<item quantity="one" msgid="9040808414992812341">"Na jednu minutu"</item>
<item quantity="other" msgid="6924190729213550991">"Na %d min"</item>
@@ -1788,7 +1799,7 @@
<item quantity="one" msgid="3480040795582254384">"Na 1 h"</item>
<item quantity="other" msgid="5408537517529822157">"Na %d h"</item>
</plurals>
- <!-- no translation found for zen_mode_until (7336308492289875088) -->
- <skip />
+ <string name="zen_mode_until" msgid="7336308492289875088">"Do <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
<string name="zen_mode_forever" msgid="4316804956488785559">"Na dobu neurčitou"</string>
+ <string name="toolbar_collapse_description" msgid="2821479483960330739">"Sbalit"</string>
</resources>
diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml
index 0a81979..980eff7 100644
--- a/core/res/res/values-da/strings.xml
+++ b/core/res/res/values-da/strings.xml
@@ -716,8 +716,14 @@
<string name="permdesc_cache_filesystem" msgid="5578967642265550955">"Tillader, at appen kan læse og skrive i cachefilsystemet."</string>
<string name="permlab_use_sip" msgid="2052499390128979920">"foretage/modtage SIP-opkald"</string>
<string name="permdesc_use_sip" msgid="2297804849860225257">"Tillader, at appen foretager og modtager SIP-opkald."</string>
- <string name="permlab_register_provider" msgid="2654513709546459553">"registrere nye telefonforbindelser"</string>
- <string name="permdesc_register_provider" msgid="7571533832018681544">"Tillader, at appen registrerer nye telefonforbindelser."</string>
+ <!-- no translation found for permlab_register_sim_subscription (3166535485877549177) -->
+ <skip />
+ <!-- no translation found for permdesc_register_sim_subscription (2138909035926222911) -->
+ <skip />
+ <!-- no translation found for permlab_register_call_provider (108102120289029841) -->
+ <skip />
+ <!-- no translation found for permdesc_register_call_provider (7034310263521081388) -->
+ <skip />
<string name="permlab_connection_manager" msgid="1116193254522105375">"administrere telefonforbindelser"</string>
<string name="permdesc_connection_manager" msgid="5925480810356483565">"Tillader, at appen administrerer telefonforbindelser."</string>
<string name="permlab_bind_incall_service" msgid="6773648341975287125">"interager med skærmen under opkald"</string>
@@ -1233,6 +1239,7 @@
<string name="smv_application" msgid="3307209192155442829">"Appen <xliff:g id="APPLICATION">%1$s</xliff:g> (proces <xliff:g id="PROCESS">%2$s</xliff:g>) har overtrådt sin egen StrictMode-politik."</string>
<string name="smv_process" msgid="5120397012047462446">"Processen <xliff:g id="PROCESS">%1$s</xliff:g> har overtrådt sin egen StrictMode-politik."</string>
<string name="android_upgrading_title" msgid="1584192285441405746">"Android opgraderes..."</string>
+ <string name="android_start_title" msgid="8418054686415318207">"Android starter..."</string>
<string name="android_upgrading_apk" msgid="7904042682111526169">"Optimerer app <xliff:g id="NUMBER_0">%1$d</xliff:g> ud af <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
<string name="android_upgrading_starting_apps" msgid="451464516346926713">"Åbner dine apps."</string>
<string name="android_upgrading_complete" msgid="1405954754112999229">"Gennemfører start."</string>
@@ -1776,10 +1783,14 @@
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Bed om adgangskode inden frigørelse"</string>
<string name="battery_saver_description" msgid="2510530476513605742">"For at forbedre batteriets levetid reducerer batterisparefunktionen enhedens ydeevne og begrænser vibrationer og de fleste baggrundsdata. E-mail, beskeder og andre apps, der benytter synkronisering, opdateres ikke, medmindre du åbner dem.\n\nBatterisparefunktionen deaktiveres automatisk, når enheden oplades."</string>
<string name="downtime_condition_summary" msgid="8761776337475705749">"Indtil din nedetid slutter kl. <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
- <!-- no translation found for zen_mode_duration_minutes_summary:one (3177683545388923234) -->
- <!-- no translation found for zen_mode_duration_minutes_summary:other (2787867221129368935) -->
- <!-- no translation found for zen_mode_duration_hours_summary:one (597194865053253679) -->
- <!-- no translation found for zen_mode_duration_hours_summary:other (2827214920627669898) -->
+ <plurals name="zen_mode_duration_minutes_summary">
+ <item quantity="one" msgid="3177683545388923234">"I ét minut (indtil <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ <item quantity="other" msgid="2787867221129368935">"I %1$d minutter (indtil <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ </plurals>
+ <plurals name="zen_mode_duration_hours_summary">
+ <item quantity="one" msgid="597194865053253679">"I én time (indtil <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ <item quantity="other" msgid="2827214920627669898">"I %1$d timer (indtil <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ </plurals>
<plurals name="zen_mode_duration_minutes">
<item quantity="one" msgid="9040808414992812341">"I ét minut"</item>
<item quantity="other" msgid="6924190729213550991">"I %d minutter"</item>
@@ -1788,7 +1799,7 @@
<item quantity="one" msgid="3480040795582254384">"I én time"</item>
<item quantity="other" msgid="5408537517529822157">"I %d timer"</item>
</plurals>
- <!-- no translation found for zen_mode_until (7336308492289875088) -->
- <skip />
+ <string name="zen_mode_until" msgid="7336308492289875088">"Indtil <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
<string name="zen_mode_forever" msgid="4316804956488785559">"Uendeligt"</string>
+ <string name="toolbar_collapse_description" msgid="2821479483960330739">"Skjul"</string>
</resources>
diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml
index 74bd5f9..3f242c3 100644
--- a/core/res/res/values-de/strings.xml
+++ b/core/res/res/values-de/strings.xml
@@ -716,8 +716,14 @@
<string name="permdesc_cache_filesystem" msgid="5578967642265550955">"Ermöglicht der App Lese- und Schreibzugriff auf das Cache-Dateisystem"</string>
<string name="permlab_use_sip" msgid="2052499390128979920">"SIP-Anrufe tätigen/empfangen"</string>
<string name="permdesc_use_sip" msgid="2297804849860225257">"Ermöglicht der App das Tätigen und Empfangen von SIP-Anrufen"</string>
- <string name="permlab_register_provider" msgid="2654513709546459553">"Neue Telekommunikationsverbindungen registrieren"</string>
- <string name="permdesc_register_provider" msgid="7571533832018681544">"Gestattet der App die Registrierung neuer Telekommunikationsverbindungen"</string>
+ <!-- no translation found for permlab_register_sim_subscription (3166535485877549177) -->
+ <skip />
+ <!-- no translation found for permdesc_register_sim_subscription (2138909035926222911) -->
+ <skip />
+ <!-- no translation found for permlab_register_call_provider (108102120289029841) -->
+ <skip />
+ <!-- no translation found for permdesc_register_call_provider (7034310263521081388) -->
+ <skip />
<string name="permlab_connection_manager" msgid="1116193254522105375">"Telekommunikationsverbindungen verwalten"</string>
<string name="permdesc_connection_manager" msgid="5925480810356483565">"Gestattet der App die Verwaltung der Telekommunikationsverbindungen"</string>
<string name="permlab_bind_incall_service" msgid="6773648341975287125">"Mit Anrufbildschirm interagieren"</string>
@@ -1233,6 +1239,7 @@
<string name="smv_application" msgid="3307209192155442829">"Die App <xliff:g id="APPLICATION">%1$s</xliff:g> (Prozess <xliff:g id="PROCESS">%2$s</xliff:g>) hat gegen ihre selbsterzwungene StrictMode-Richtlinie verstoßen."</string>
<string name="smv_process" msgid="5120397012047462446">"Der Prozess <xliff:g id="PROCESS">%1$s</xliff:g> hat gegen seine selbsterzwungene StrictMode-Richtlinie verstoßen."</string>
<string name="android_upgrading_title" msgid="1584192285441405746">"Android wird aktualisiert..."</string>
+ <string name="android_start_title" msgid="8418054686415318207">"Android wird gestartet…"</string>
<string name="android_upgrading_apk" msgid="7904042682111526169">"App <xliff:g id="NUMBER_0">%1$d</xliff:g> von <xliff:g id="NUMBER_1">%2$d</xliff:g> wird optimiert..."</string>
<string name="android_upgrading_starting_apps" msgid="451464516346926713">"Apps werden gestartet..."</string>
<string name="android_upgrading_complete" msgid="1405954754112999229">"Start wird abgeschlossen..."</string>
@@ -1776,10 +1783,14 @@
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Vor dem Beenden nach Passwort fragen"</string>
<string name="battery_saver_description" msgid="2510530476513605742">"Der Energiesparmodus hilft, den Akku zu schonen, indem er die Leistung des Geräts reduziert und die Vibrationsfunktion und die meisten Hintergrunddatenaktivitäten einschränkt. E-Mail-, SMS/MMS- und andere Apps, die die Synchronisierungsfunktion benötigen, werden möglicherweise nicht aktualisiert, bis Sie sie öffnen.\n\nDer Energiesparmodus endet automatisch, wenn Ihr Gerät aufgeladen wird."</string>
<string name="downtime_condition_summary" msgid="8761776337475705749">"Bis zum Ende der Downtime um <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
- <!-- no translation found for zen_mode_duration_minutes_summary:one (3177683545388923234) -->
- <!-- no translation found for zen_mode_duration_minutes_summary:other (2787867221129368935) -->
- <!-- no translation found for zen_mode_duration_hours_summary:one (597194865053253679) -->
- <!-- no translation found for zen_mode_duration_hours_summary:other (2827214920627669898) -->
+ <plurals name="zen_mode_duration_minutes_summary">
+ <item quantity="one" msgid="3177683545388923234">"1 Minute (bis <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ <item quantity="other" msgid="2787867221129368935">"%1$d Minuten (bis <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ </plurals>
+ <plurals name="zen_mode_duration_hours_summary">
+ <item quantity="one" msgid="597194865053253679">"1 Stunde (bis <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ <item quantity="other" msgid="2827214920627669898">"%1$d Stunden (bis <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ </plurals>
<plurals name="zen_mode_duration_minutes">
<item quantity="one" msgid="9040808414992812341">"Für eine Minute"</item>
<item quantity="other" msgid="6924190729213550991">"Für %d Minuten"</item>
@@ -1788,7 +1799,7 @@
<item quantity="one" msgid="3480040795582254384">"Für eine Stunde"</item>
<item quantity="other" msgid="5408537517529822157">"Für %d Stunden"</item>
</plurals>
- <!-- no translation found for zen_mode_until (7336308492289875088) -->
- <skip />
+ <string name="zen_mode_until" msgid="7336308492289875088">"Bis <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
<string name="zen_mode_forever" msgid="4316804956488785559">"Unbegrenzt"</string>
+ <string name="toolbar_collapse_description" msgid="2821479483960330739">"Minimieren"</string>
</resources>
diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml
index edffefc..c9465c0 100644
--- a/core/res/res/values-el/strings.xml
+++ b/core/res/res/values-el/strings.xml
@@ -716,8 +716,14 @@
<string name="permdesc_cache_filesystem" msgid="5578967642265550955">"Επιτρέπει στην εφαρμογή την ανάγνωση και την εγγραφή του συστήματος αρχείων προσωρινής μνήμης."</string>
<string name="permlab_use_sip" msgid="2052499390128979920">"πραγματοποίηση/λήψη κλήσεων SIP"</string>
<string name="permdesc_use_sip" msgid="2297804849860225257">"Επιτρέπει στην εφαρμογή να πραγματοποιεί και να λαμβάνει κλήσεις SIP."</string>
- <string name="permlab_register_provider" msgid="2654513709546459553">"εγγραφή νέας σύνδεσης τηλεπικοινωνιών"</string>
- <string name="permdesc_register_provider" msgid="7571533832018681544">"Επιτρέπει στην εφαρμογή να εγγράφει νέες συνδέσεις τηλεπικοινωνιών."</string>
+ <!-- no translation found for permlab_register_sim_subscription (3166535485877549177) -->
+ <skip />
+ <!-- no translation found for permdesc_register_sim_subscription (2138909035926222911) -->
+ <skip />
+ <!-- no translation found for permlab_register_call_provider (108102120289029841) -->
+ <skip />
+ <!-- no translation found for permdesc_register_call_provider (7034310263521081388) -->
+ <skip />
<string name="permlab_connection_manager" msgid="1116193254522105375">"διαχείριση των συνδέσεων τηλεπικοινωνιών"</string>
<string name="permdesc_connection_manager" msgid="5925480810356483565">"Επιτρέπει στην εφαρμογή να διαχειρίζεται τις συνδέσεις τηλεπικοινωνιών."</string>
<string name="permlab_bind_incall_service" msgid="6773648341975287125">"αλληλεπίδραση με την οθόνη κατά τη διάρκεια κλήσης"</string>
@@ -1233,6 +1239,7 @@
<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_apk" msgid="7904042682111526169">"Βελτιστοποίηση της εφαρμογής <xliff:g id="NUMBER_0">%1$d</xliff:g> από <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
<string name="android_upgrading_starting_apps" msgid="451464516346926713">"Έναρξη εφαρμογών."</string>
<string name="android_upgrading_complete" msgid="1405954754112999229">"Ολοκλήρωση εκκίνησης."</string>
@@ -1776,10 +1783,14 @@
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Να γίνεται ερώτηση για τον κωδικό πρόσβασης, πριν από το ξεκαρφίτσωμα"</string>
<string name="battery_saver_description" msgid="2510530476513605742">"Για τη βελτίωση της διάρκειας ζωής της μπαταρίας, η λειτουργία εξοικονόμησης μπαταρίας μειώνει την απόδοση της συσκευής σας και περιορίζει τη δόνηση και την πλειονότητα των δεδομένων παρασκηνίου. Το ηλεκτρονικό ταχυδρομείου, η ανταλλαγή μηνυμάτων και άλλες εφαρμογές που βασίζονται στο συγχρονισμό ενδέχεται να μην ενημερώνονται, παρά μόνο εάν τις ανοίξετε.\n\nΗ λειτουργία εξοικονόμησης μπαταρίας απενεργοποιείται αυτόματα κατά τη φόρτιση της συσκευής σας."</string>
<string name="downtime_condition_summary" msgid="8761776337475705749">"Έως τη λήξη του νεκρού χρόνου σας στις <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
- <!-- no translation found for zen_mode_duration_minutes_summary:one (3177683545388923234) -->
- <!-- no translation found for zen_mode_duration_minutes_summary:other (2787867221129368935) -->
- <!-- no translation found for zen_mode_duration_hours_summary:one (597194865053253679) -->
- <!-- no translation found for zen_mode_duration_hours_summary:other (2827214920627669898) -->
+ <plurals name="zen_mode_duration_minutes_summary">
+ <item quantity="one" msgid="3177683545388923234">"Για ένα λεπτό (έως τις <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ <item quantity="other" msgid="2787867221129368935">"Για %1$d λεπτά (έως τις <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ </plurals>
+ <plurals name="zen_mode_duration_hours_summary">
+ <item quantity="one" msgid="597194865053253679">"Για μία ώρα (έως τις <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ <item quantity="other" msgid="2827214920627669898">"Για %1$d ώρες (έως τις <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ </plurals>
<plurals name="zen_mode_duration_minutes">
<item quantity="one" msgid="9040808414992812341">"Για ένα λεπτό"</item>
<item quantity="other" msgid="6924190729213550991">"Για %d λεπτά"</item>
@@ -1788,7 +1799,7 @@
<item quantity="one" msgid="3480040795582254384">"Για μία ώρα"</item>
<item quantity="other" msgid="5408537517529822157">"Για %d ώρες"</item>
</plurals>
- <!-- no translation found for zen_mode_until (7336308492289875088) -->
- <skip />
+ <string name="zen_mode_until" msgid="7336308492289875088">"Έως τις <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
<string name="zen_mode_forever" msgid="4316804956488785559">"Επ\' αόριστον"</string>
+ <string name="toolbar_collapse_description" msgid="2821479483960330739">"Σύμπτυξη"</string>
</resources>
diff --git a/core/res/res/values-en-rGB/strings.xml b/core/res/res/values-en-rGB/strings.xml
index e356903..85b7be7 100644
--- a/core/res/res/values-en-rGB/strings.xml
+++ b/core/res/res/values-en-rGB/strings.xml
@@ -716,8 +716,14 @@
<string name="permdesc_cache_filesystem" msgid="5578967642265550955">"Allows the app to read and write the cache file system."</string>
<string name="permlab_use_sip" msgid="2052499390128979920">"make/receive SIP calls"</string>
<string name="permdesc_use_sip" msgid="2297804849860225257">"Allows the app to make and receive SIP calls."</string>
- <string name="permlab_register_provider" msgid="2654513709546459553">"register new telecom connection"</string>
- <string name="permdesc_register_provider" msgid="7571533832018681544">"Allows the app to register new telecom connections."</string>
+ <!-- no translation found for permlab_register_sim_subscription (3166535485877549177) -->
+ <skip />
+ <!-- no translation found for permdesc_register_sim_subscription (2138909035926222911) -->
+ <skip />
+ <!-- no translation found for permlab_register_call_provider (108102120289029841) -->
+ <skip />
+ <!-- no translation found for permdesc_register_call_provider (7034310263521081388) -->
+ <skip />
<string name="permlab_connection_manager" msgid="1116193254522105375">"manage telecom connections"</string>
<string name="permdesc_connection_manager" msgid="5925480810356483565">"Allows the app to manage telecom connections."</string>
<string name="permlab_bind_incall_service" msgid="6773648341975287125">"interact with in-call screen"</string>
@@ -1233,6 +1239,7 @@
<string name="smv_application" msgid="3307209192155442829">"The app <xliff:g id="APPLICATION">%1$s</xliff:g> (process <xliff:g id="PROCESS">%2$s</xliff:g>) has violated its self-enforced Strict Mode policy."</string>
<string name="smv_process" msgid="5120397012047462446">"The process <xliff:g id="PROCESS">%1$s</xliff:g> has violated its self-enforced StrictMode policy."</string>
<string name="android_upgrading_title" msgid="1584192285441405746">"Android is upgrading…"</string>
+ <string name="android_start_title" msgid="8418054686415318207">"Android is starting…"</string>
<string name="android_upgrading_apk" msgid="7904042682111526169">"Optimising app <xliff:g id="NUMBER_0">%1$d</xliff:g> of <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
<string name="android_upgrading_starting_apps" msgid="451464516346926713">"Starting apps."</string>
<string name="android_upgrading_complete" msgid="1405954754112999229">"Finishing boot."</string>
@@ -1776,10 +1783,14 @@
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Ask for password before unpinning"</string>
<string name="battery_saver_description" msgid="2510530476513605742">"To help improve battery life, battery saver reduces your device’s performance and limits vibration and most background data. Email, messaging and other apps that rely on syncing may not update unless you open them.\n\nBattery saver turns off automatically when your device is charging."</string>
<string name="downtime_condition_summary" msgid="8761776337475705749">"Until your downtime ends at <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
- <!-- no translation found for zen_mode_duration_minutes_summary:one (3177683545388923234) -->
- <!-- no translation found for zen_mode_duration_minutes_summary:other (2787867221129368935) -->
- <!-- no translation found for zen_mode_duration_hours_summary:one (597194865053253679) -->
- <!-- no translation found for zen_mode_duration_hours_summary:other (2827214920627669898) -->
+ <plurals name="zen_mode_duration_minutes_summary">
+ <item quantity="one" msgid="3177683545388923234">"For one minute (until <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ <item quantity="other" msgid="2787867221129368935">"For %1$d minutes (until <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ </plurals>
+ <plurals name="zen_mode_duration_hours_summary">
+ <item quantity="one" msgid="597194865053253679">"For one hour (until <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ <item quantity="other" msgid="2827214920627669898">"For %1$d hours (until <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ </plurals>
<plurals name="zen_mode_duration_minutes">
<item quantity="one" msgid="9040808414992812341">"For one minute"</item>
<item quantity="other" msgid="6924190729213550991">"For %d minutes"</item>
@@ -1788,7 +1799,7 @@
<item quantity="one" msgid="3480040795582254384">"For one hour"</item>
<item quantity="other" msgid="5408537517529822157">"For %d hours"</item>
</plurals>
- <!-- no translation found for zen_mode_until (7336308492289875088) -->
- <skip />
+ <string name="zen_mode_until" msgid="7336308492289875088">"Until <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
<string name="zen_mode_forever" msgid="4316804956488785559">"Indefinitely"</string>
+ <string name="toolbar_collapse_description" msgid="2821479483960330739">"Collapse"</string>
</resources>
diff --git a/core/res/res/values-en-rIN/strings.xml b/core/res/res/values-en-rIN/strings.xml
index e356903..85b7be7 100644
--- a/core/res/res/values-en-rIN/strings.xml
+++ b/core/res/res/values-en-rIN/strings.xml
@@ -716,8 +716,14 @@
<string name="permdesc_cache_filesystem" msgid="5578967642265550955">"Allows the app to read and write the cache file system."</string>
<string name="permlab_use_sip" msgid="2052499390128979920">"make/receive SIP calls"</string>
<string name="permdesc_use_sip" msgid="2297804849860225257">"Allows the app to make and receive SIP calls."</string>
- <string name="permlab_register_provider" msgid="2654513709546459553">"register new telecom connection"</string>
- <string name="permdesc_register_provider" msgid="7571533832018681544">"Allows the app to register new telecom connections."</string>
+ <!-- no translation found for permlab_register_sim_subscription (3166535485877549177) -->
+ <skip />
+ <!-- no translation found for permdesc_register_sim_subscription (2138909035926222911) -->
+ <skip />
+ <!-- no translation found for permlab_register_call_provider (108102120289029841) -->
+ <skip />
+ <!-- no translation found for permdesc_register_call_provider (7034310263521081388) -->
+ <skip />
<string name="permlab_connection_manager" msgid="1116193254522105375">"manage telecom connections"</string>
<string name="permdesc_connection_manager" msgid="5925480810356483565">"Allows the app to manage telecom connections."</string>
<string name="permlab_bind_incall_service" msgid="6773648341975287125">"interact with in-call screen"</string>
@@ -1233,6 +1239,7 @@
<string name="smv_application" msgid="3307209192155442829">"The app <xliff:g id="APPLICATION">%1$s</xliff:g> (process <xliff:g id="PROCESS">%2$s</xliff:g>) has violated its self-enforced Strict Mode policy."</string>
<string name="smv_process" msgid="5120397012047462446">"The process <xliff:g id="PROCESS">%1$s</xliff:g> has violated its self-enforced StrictMode policy."</string>
<string name="android_upgrading_title" msgid="1584192285441405746">"Android is upgrading…"</string>
+ <string name="android_start_title" msgid="8418054686415318207">"Android is starting…"</string>
<string name="android_upgrading_apk" msgid="7904042682111526169">"Optimising app <xliff:g id="NUMBER_0">%1$d</xliff:g> of <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
<string name="android_upgrading_starting_apps" msgid="451464516346926713">"Starting apps."</string>
<string name="android_upgrading_complete" msgid="1405954754112999229">"Finishing boot."</string>
@@ -1776,10 +1783,14 @@
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Ask for password before unpinning"</string>
<string name="battery_saver_description" msgid="2510530476513605742">"To help improve battery life, battery saver reduces your device’s performance and limits vibration and most background data. Email, messaging and other apps that rely on syncing may not update unless you open them.\n\nBattery saver turns off automatically when your device is charging."</string>
<string name="downtime_condition_summary" msgid="8761776337475705749">"Until your downtime ends at <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
- <!-- no translation found for zen_mode_duration_minutes_summary:one (3177683545388923234) -->
- <!-- no translation found for zen_mode_duration_minutes_summary:other (2787867221129368935) -->
- <!-- no translation found for zen_mode_duration_hours_summary:one (597194865053253679) -->
- <!-- no translation found for zen_mode_duration_hours_summary:other (2827214920627669898) -->
+ <plurals name="zen_mode_duration_minutes_summary">
+ <item quantity="one" msgid="3177683545388923234">"For one minute (until <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ <item quantity="other" msgid="2787867221129368935">"For %1$d minutes (until <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ </plurals>
+ <plurals name="zen_mode_duration_hours_summary">
+ <item quantity="one" msgid="597194865053253679">"For one hour (until <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ <item quantity="other" msgid="2827214920627669898">"For %1$d hours (until <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ </plurals>
<plurals name="zen_mode_duration_minutes">
<item quantity="one" msgid="9040808414992812341">"For one minute"</item>
<item quantity="other" msgid="6924190729213550991">"For %d minutes"</item>
@@ -1788,7 +1799,7 @@
<item quantity="one" msgid="3480040795582254384">"For one hour"</item>
<item quantity="other" msgid="5408537517529822157">"For %d hours"</item>
</plurals>
- <!-- no translation found for zen_mode_until (7336308492289875088) -->
- <skip />
+ <string name="zen_mode_until" msgid="7336308492289875088">"Until <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
<string name="zen_mode_forever" msgid="4316804956488785559">"Indefinitely"</string>
+ <string name="toolbar_collapse_description" msgid="2821479483960330739">"Collapse"</string>
</resources>
diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml
index 816436b..1467ad6 100644
--- a/core/res/res/values-es-rUS/strings.xml
+++ b/core/res/res/values-es-rUS/strings.xml
@@ -716,8 +716,14 @@
<string name="permdesc_cache_filesystem" msgid="5578967642265550955">"Permite que la aplicación lea y escriba el sistema de archivos almacenado en caché."</string>
<string name="permlab_use_sip" msgid="2052499390128979920">"realizar/recibir llamadas SIP"</string>
<string name="permdesc_use_sip" msgid="2297804849860225257">"Permite que la aplicación realice y reciba llamadas SIP."</string>
- <string name="permlab_register_provider" msgid="2654513709546459553">"registrar conexiones de telecomunicaciones nuevas"</string>
- <string name="permdesc_register_provider" msgid="7571533832018681544">"Permite que la aplicación registre las conexiones de telecomunicaciones nuevas."</string>
+ <!-- no translation found for permlab_register_sim_subscription (3166535485877549177) -->
+ <skip />
+ <!-- no translation found for permdesc_register_sim_subscription (2138909035926222911) -->
+ <skip />
+ <!-- no translation found for permlab_register_call_provider (108102120289029841) -->
+ <skip />
+ <!-- no translation found for permdesc_register_call_provider (7034310263521081388) -->
+ <skip />
<string name="permlab_connection_manager" msgid="1116193254522105375">"administrar conexiones de telecomunicaciones"</string>
<string name="permdesc_connection_manager" msgid="5925480810356483565">"Permite que la aplicación administre las conexiones de telecomunicaciones."</string>
<string name="permlab_bind_incall_service" msgid="6773648341975287125">"interactuar con la pantalla de llamada"</string>
@@ -1233,6 +1239,7 @@
<string name="smv_application" msgid="3307209192155442829">"La aplicación <xliff:g id="APPLICATION">%1$s</xliff:g> (proceso <xliff:g id="PROCESS">%2$s</xliff:g>) ha infringido su política StrictMode de aplicación automática."</string>
<string name="smv_process" msgid="5120397012047462446">"El proceso <xliff:g id="PROCESS">%1$s</xliff:g> ha violado su política StrictMode autoimpuesta."</string>
<string name="android_upgrading_title" msgid="1584192285441405746">"Android se está actualizando..."</string>
+ <string name="android_start_title" msgid="8418054686415318207">"Iniciando Android…"</string>
<string name="android_upgrading_apk" msgid="7904042682111526169">"Optimizando la aplicación <xliff:g id="NUMBER_0">%1$d</xliff:g> de <xliff:g id="NUMBER_1">%2$d</xliff:g>"</string>
<string name="android_upgrading_starting_apps" msgid="451464516346926713">"Iniciando aplicaciones"</string>
<string name="android_upgrading_complete" msgid="1405954754112999229">"Finalizando el inicio"</string>
@@ -1776,10 +1783,14 @@
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Solicitar contraseña para quitar fijación"</string>
<string name="battery_saver_description" msgid="2510530476513605742">"Para ayudar a mejorar la duración de la batería, la función de ahorro de batería reduce el rendimiento del dispositivo y limita la vibración y la mayor parte de la transmisión de datos en segundo plano. Es posible que las aplicaciones que se sincronizan, como las de correo electrónico y mensajería, no se actualicen a menos que las abras.\n\nEl ahorro de batería se desactiva automáticamente cuando el dispositivo se está cargando."</string>
<string name="downtime_condition_summary" msgid="8761776337475705749">"Hasta que termine el tiempo de inactividad a la(s) <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
- <!-- no translation found for zen_mode_duration_minutes_summary:one (3177683545388923234) -->
- <!-- no translation found for zen_mode_duration_minutes_summary:other (2787867221129368935) -->
- <!-- no translation found for zen_mode_duration_hours_summary:one (597194865053253679) -->
- <!-- no translation found for zen_mode_duration_hours_summary:other (2827214920627669898) -->
+ <plurals name="zen_mode_duration_minutes_summary">
+ <item quantity="one" msgid="3177683545388923234">"Durante 1 minuto; hasta la(s) <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>"</item>
+ <item quantity="other" msgid="2787867221129368935">"Durante %1$d minutos; hasta la(s) <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>"</item>
+ </plurals>
+ <plurals name="zen_mode_duration_hours_summary">
+ <item quantity="one" msgid="597194865053253679">"Durante 1 hora; hasta la(s) <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>"</item>
+ <item quantity="other" msgid="2827214920627669898">"Durante %1$d horas; hasta la(s) <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>"</item>
+ </plurals>
<plurals name="zen_mode_duration_minutes">
<item quantity="one" msgid="9040808414992812341">"Durante un minuto"</item>
<item quantity="other" msgid="6924190729213550991">"Durante %d minutos"</item>
@@ -1788,7 +1799,7 @@
<item quantity="one" msgid="3480040795582254384">"Durante una hora"</item>
<item quantity="other" msgid="5408537517529822157">"Durante %d horas"</item>
</plurals>
- <!-- no translation found for zen_mode_until (7336308492289875088) -->
- <skip />
+ <string name="zen_mode_until" msgid="7336308492289875088">"Hasta la(s) <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
<string name="zen_mode_forever" msgid="4316804956488785559">"Indefinidamente"</string>
+ <string name="toolbar_collapse_description" msgid="2821479483960330739">"Contraer"</string>
</resources>
diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml
index 10c8716..ca92f71 100644
--- a/core/res/res/values-es/strings.xml
+++ b/core/res/res/values-es/strings.xml
@@ -716,8 +716,14 @@
<string name="permdesc_cache_filesystem" msgid="5578967642265550955">"Permite que la aplicación lea y escriba el sistema de archivos almacenado en caché."</string>
<string name="permlab_use_sip" msgid="2052499390128979920">"hacer/recibir llamadas SIP"</string>
<string name="permdesc_use_sip" msgid="2297804849860225257">"Permite que la aplicación haga y reciba llamadas SIP."</string>
- <string name="permlab_register_provider" msgid="2654513709546459553">"registrar conexiones de telecomunicaciones nuevas"</string>
- <string name="permdesc_register_provider" msgid="7571533832018681544">"Permite que la aplicación registre conexiones de telecomunicaciones nuevas."</string>
+ <!-- no translation found for permlab_register_sim_subscription (3166535485877549177) -->
+ <skip />
+ <!-- no translation found for permdesc_register_sim_subscription (2138909035926222911) -->
+ <skip />
+ <!-- no translation found for permlab_register_call_provider (108102120289029841) -->
+ <skip />
+ <!-- no translation found for permdesc_register_call_provider (7034310263521081388) -->
+ <skip />
<string name="permlab_connection_manager" msgid="1116193254522105375">"administrar conexiones de telecomunicaciones"</string>
<string name="permdesc_connection_manager" msgid="5925480810356483565">"Permite que la aplicación administre las conexiones de telecomunicaciones."</string>
<string name="permlab_bind_incall_service" msgid="6773648341975287125">"interactuar con la pantalla de llamada"</string>
@@ -1233,6 +1239,7 @@
<string name="smv_application" msgid="3307209192155442829">"La aplicación <xliff:g id="APPLICATION">%1$s</xliff:g> (proceso <xliff:g id="PROCESS">%2$s</xliff:g>) ha infringido su política StrictMode autoaplicable."</string>
<string name="smv_process" msgid="5120397012047462446">"El proceso <xliff:g id="PROCESS">%1$s</xliff:g> ha infringido su política StrictMode autoaplicable."</string>
<string name="android_upgrading_title" msgid="1584192285441405746">"Actualizando Android"</string>
+ <string name="android_start_title" msgid="8418054686415318207">"Android se está iniciando…"</string>
<string name="android_upgrading_apk" msgid="7904042682111526169">"Optimizando aplicación <xliff:g id="NUMBER_0">%1$d</xliff:g> de <xliff:g id="NUMBER_1">%2$d</xliff:g>..."</string>
<string name="android_upgrading_starting_apps" msgid="451464516346926713">"Iniciando aplicaciones"</string>
<string name="android_upgrading_complete" msgid="1405954754112999229">"Finalizando inicio..."</string>
@@ -1776,10 +1783,14 @@
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Solicitar contraseña para desactivar"</string>
<string name="battery_saver_description" msgid="2510530476513605742">"Para ayudar a mejorar la duración de la batería, la función de ahorro de energía reduce el rendimiento del dispositivo y limita la vibración y la mayor parte de la transmisión de datos en segundo plano. Es posible que las aplicaciones que se sincronizan, como las de correo y mensajes, no se actualicen a menos que las abras.\n\nLa función de ahorro de energía se desactiva automáticamente cuando el dispositivo se carga."</string>
<string name="downtime_condition_summary" msgid="8761776337475705749">"Hasta que el tiempo de inactividad finalice el <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
- <!-- no translation found for zen_mode_duration_minutes_summary:one (3177683545388923234) -->
- <!-- no translation found for zen_mode_duration_minutes_summary:other (2787867221129368935) -->
- <!-- no translation found for zen_mode_duration_hours_summary:one (597194865053253679) -->
- <!-- no translation found for zen_mode_duration_hours_summary:other (2827214920627669898) -->
+ <plurals name="zen_mode_duration_minutes_summary">
+ <item quantity="one" msgid="3177683545388923234">"Durante un minuto (hasta las <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ <item quantity="other" msgid="2787867221129368935">"Durante %1$d minutos (hasta las <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ </plurals>
+ <plurals name="zen_mode_duration_hours_summary">
+ <item quantity="one" msgid="597194865053253679">"Durante una hora (hasta las <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ <item quantity="other" msgid="2827214920627669898">"Durante %1$d horas (hasta las <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ </plurals>
<plurals name="zen_mode_duration_minutes">
<item quantity="one" msgid="9040808414992812341">"Durante un minuto"</item>
<item quantity="other" msgid="6924190729213550991">"Durante %d minutos"</item>
@@ -1788,7 +1799,7 @@
<item quantity="one" msgid="3480040795582254384">"Durante 1 hora"</item>
<item quantity="other" msgid="5408537517529822157">"Durante %d horas"</item>
</plurals>
- <!-- no translation found for zen_mode_until (7336308492289875088) -->
- <skip />
+ <string name="zen_mode_until" msgid="7336308492289875088">"Hasta las <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
<string name="zen_mode_forever" msgid="4316804956488785559">"Indefinidamente"</string>
+ <string name="toolbar_collapse_description" msgid="2821479483960330739">"Contraer"</string>
</resources>
diff --git a/core/res/res/values-et-rEE/strings.xml b/core/res/res/values-et-rEE/strings.xml
index 379aef5..ccd08c6 100644
--- a/core/res/res/values-et-rEE/strings.xml
+++ b/core/res/res/values-et-rEE/strings.xml
@@ -716,8 +716,14 @@
<string name="permdesc_cache_filesystem" msgid="5578967642265550955">"Võimaldab rakendusel vahemälu failisüsteemi lugeda ja kirjutada."</string>
<string name="permlab_use_sip" msgid="2052499390128979920">"SIP-kõnede tegemine/vastuvõtmine"</string>
<string name="permdesc_use_sip" msgid="2297804849860225257">"Lubab rakendusel teha ja vastu võtta SIP-kõnesid."</string>
- <string name="permlab_register_provider" msgid="2654513709546459553">"uute telekommunikatsiooni ühenduste registreerimine"</string>
- <string name="permdesc_register_provider" msgid="7571533832018681544">"Lubab rakendusel registreerida uusi telekommunikatsiooni ühendusi."</string>
+ <!-- no translation found for permlab_register_sim_subscription (3166535485877549177) -->
+ <skip />
+ <!-- no translation found for permdesc_register_sim_subscription (2138909035926222911) -->
+ <skip />
+ <!-- no translation found for permlab_register_call_provider (108102120289029841) -->
+ <skip />
+ <!-- no translation found for permdesc_register_call_provider (7034310263521081388) -->
+ <skip />
<string name="permlab_connection_manager" msgid="1116193254522105375">"telekommunikatsiooni ühenduste haldamine"</string>
<string name="permdesc_connection_manager" msgid="5925480810356483565">"Lubab rakendusel hallata telekommunikatsiooni ühendusi."</string>
<string name="permlab_bind_incall_service" msgid="6773648341975287125">"ekraani Kõne pooleli kasutamine"</string>
@@ -1233,6 +1239,7 @@
<string name="smv_application" msgid="3307209192155442829">"Rakendus <xliff:g id="APPLICATION">%1$s</xliff:g> (protsess <xliff:g id="PROCESS">%2$s</xliff:g>) on rikkunud isekehtestatud StrictMode\'i eeskirju."</string>
<string name="smv_process" msgid="5120397012047462446">"Protsess <xliff:g id="PROCESS">%1$s</xliff:g> on rikkunud isejõustatud StrictMode\'i eeskirju."</string>
<string name="android_upgrading_title" msgid="1584192285441405746">"Android viiakse üle uuemale versioonile ..."</string>
+ <string name="android_start_title" msgid="8418054686415318207">"Android käivitub ..."</string>
<string name="android_upgrading_apk" msgid="7904042682111526169">"<xliff:g id="NUMBER_0">%1$d</xliff:g>. rakenduse <xliff:g id="NUMBER_1">%2$d</xliff:g>-st optimeerimine."</string>
<string name="android_upgrading_starting_apps" msgid="451464516346926713">"Rakenduste käivitamine."</string>
<string name="android_upgrading_complete" msgid="1405954754112999229">"Käivitamise lõpuleviimine."</string>
@@ -1776,10 +1783,14 @@
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Enne vabastamist küsi parooli"</string>
<string name="battery_saver_description" msgid="2510530476513605742">"Aku kestuse parandamiseks vähendab akusäästja teie seadme jõudlust ja piirab vibratsiooni ning suuremat osa taustaandmetest. E-posti, sõnumsidet ja muid sünkroonimisele tuginevaid rakendusi võidakse värskendada ainult siis, kui te need avate.\n\nAkusäästja lülitatakse seadme laadimise ajal automaatselt välja."</string>
<string name="downtime_condition_summary" msgid="8761776337475705749">"Kuni seisakuaja lõppemiseni kell <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
- <!-- no translation found for zen_mode_duration_minutes_summary:one (3177683545388923234) -->
- <!-- no translation found for zen_mode_duration_minutes_summary:other (2787867221129368935) -->
- <!-- no translation found for zen_mode_duration_hours_summary:one (597194865053253679) -->
- <!-- no translation found for zen_mode_duration_hours_summary:other (2827214920627669898) -->
+ <plurals name="zen_mode_duration_minutes_summary">
+ <item quantity="one" msgid="3177683545388923234">"Üheks minutiks (kuni <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ <item quantity="other" msgid="2787867221129368935">"%1$d minutiks (kuni <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ </plurals>
+ <plurals name="zen_mode_duration_hours_summary">
+ <item quantity="one" msgid="597194865053253679">"Üheks tunniks (kuni <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ <item quantity="other" msgid="2827214920627669898">"%1$d tunniks (kuni <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ </plurals>
<plurals name="zen_mode_duration_minutes">
<item quantity="one" msgid="9040808414992812341">"Üheks minutiks"</item>
<item quantity="other" msgid="6924190729213550991">"%d minutiks"</item>
@@ -1788,7 +1799,7 @@
<item quantity="one" msgid="3480040795582254384">"Üheks tunniks"</item>
<item quantity="other" msgid="5408537517529822157">"%d tunniks"</item>
</plurals>
- <!-- no translation found for zen_mode_until (7336308492289875088) -->
- <skip />
+ <string name="zen_mode_until" msgid="7336308492289875088">"Kuni <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
<string name="zen_mode_forever" msgid="4316804956488785559">"Määramata ajaks"</string>
+ <string name="toolbar_collapse_description" msgid="2821479483960330739">"Ahendamine"</string>
</resources>
diff --git a/core/res/res/values-eu-rES/strings.xml b/core/res/res/values-eu-rES/strings.xml
index c19b209..2b168b3 100644
--- a/core/res/res/values-eu-rES/strings.xml
+++ b/core/res/res/values-eu-rES/strings.xml
@@ -716,9 +716,15 @@
<string name="permdesc_cache_filesystem" msgid="5578967642265550955">"Cachearen fitxategi-sistema irakurtzea eta bertan idaztea baimentzen die aplikazioei."</string>
<string name="permlab_use_sip" msgid="2052499390128979920">"Egin/Jaso SIP deiak"</string>
<string name="permdesc_use_sip" msgid="2297804849860225257">"SIP deiak egitea eta jasotzea baimentzen die aplikazioei."</string>
- <string name="permlab_register_provider" msgid="2654513709546459553">"erregistratu telekomunikabideekiko konexioak"</string>
- <string name="permdesc_register_provider" msgid="7571533832018681544">"Telekomunikabideekiko konexioak erregistratzea baimentzen die aplikazioei."</string>
- <string name="permlab_connection_manager" msgid="1116193254522105375">"kudeatu telekomunikabideekiko konexioak"</string>
+ <!-- no translation found for permlab_register_sim_subscription (3166535485877549177) -->
+ <skip />
+ <!-- no translation found for permdesc_register_sim_subscription (2138909035926222911) -->
+ <skip />
+ <!-- no translation found for permlab_register_call_provider (108102120289029841) -->
+ <skip />
+ <!-- no translation found for permdesc_register_call_provider (7034310263521081388) -->
+ <skip />
+ <string name="permlab_connection_manager" msgid="1116193254522105375">"Kudeatu telekomunikabideekiko konexioak"</string>
<string name="permdesc_connection_manager" msgid="5925480810356483565">"Telekomunikabideekiko konexioak kudeatzea baimentzen die aplikazioei."</string>
<string name="permlab_bind_incall_service" msgid="6773648341975287125">"Deiak abian direnean pantaila erabiltzea"</string>
<string name="permdesc_bind_incall_service" msgid="8343471381323215005">"Erabiltzaileak deiaren pantaila noiz eta nola ikusten duen kontrolatzea baimentzen die aplikazioei."</string>
@@ -1233,6 +1239,7 @@
<string name="smv_application" msgid="3307209192155442829">"<xliff:g id="APPLICATION">%1$s</xliff:g> aplikazioak (<xliff:g id="PROCESS">%2$s</xliff:g> prozesua) berak aplikatutako StrictMode gidalerroa urratu du."</string>
<string name="smv_process" msgid="5120397012047462446">"<xliff:g id="PROCESS">%1$s</xliff:g> prozesuak bere kabuz ezarritako StrictMode gidalerroak urratu ditu."</string>
<string name="android_upgrading_title" msgid="1584192285441405746">"Android bertsio-berritzen ari da…"</string>
+ <string name="android_start_title" msgid="8418054686415318207">"Android abiarazten ari da…"</string>
<string name="android_upgrading_apk" msgid="7904042682111526169">"<xliff:g id="NUMBER_0">%1$d</xliff:g>/<xliff:g id="NUMBER_1">%2$d</xliff:g> aplikazio optimizatzen."</string>
<string name="android_upgrading_starting_apps" msgid="451464516346926713">"Aplikazioak abiarazten."</string>
<string name="android_upgrading_complete" msgid="1405954754112999229">"Bertsio-berritzea amaitzen."</string>
@@ -1776,10 +1783,14 @@
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Eskatu pasahitza aingura kendu aurretik"</string>
<string name="battery_saver_description" msgid="2510530476513605742">"Bateriak gehiago iraun dezan, bateria aurrezteko aukerak gailuaren errendimendua murrizten du, eta dardara eta atzeko planoko datu gehienak mugatzen ditu. Baliteke posta elektronikoa, mezuak eta sinkronizatzen diren beste aplikazio batzuk ez eguneratzea, ireki ezean.\n\nBateria aurrezteko aukera automatikoki desaktibatzen da gailua kargatzen ari denean."</string>
<string name="downtime_condition_summary" msgid="8761776337475705749">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g> arte iraungo du jarduerarik gabeko aldiak"</string>
- <!-- no translation found for zen_mode_duration_minutes_summary:one (3177683545388923234) -->
- <!-- no translation found for zen_mode_duration_minutes_summary:other (2787867221129368935) -->
- <!-- no translation found for zen_mode_duration_hours_summary:one (597194865053253679) -->
- <!-- no translation found for zen_mode_duration_hours_summary:other (2827214920627669898) -->
+ <plurals name="zen_mode_duration_minutes_summary">
+ <item quantity="one" msgid="3177683545388923234">"Minutu batez (<xliff:g id="FORMATTEDTIME">%2$s</xliff:g> arte)"</item>
+ <item quantity="other" msgid="2787867221129368935">"%1$d minutuz (<xliff:g id="FORMATTEDTIME">%2$s</xliff:g> arte)"</item>
+ </plurals>
+ <plurals name="zen_mode_duration_hours_summary">
+ <item quantity="one" msgid="597194865053253679">"Ordubetez (<xliff:g id="FORMATTEDTIME">%2$s</xliff:g> arte)"</item>
+ <item quantity="other" msgid="2827214920627669898">"%1$d orduz (<xliff:g id="FORMATTEDTIME">%2$s</xliff:g> arte)"</item>
+ </plurals>
<plurals name="zen_mode_duration_minutes">
<item quantity="one" msgid="9040808414992812341">"Minutu batez"</item>
<item quantity="other" msgid="6924190729213550991">"%d minutuz"</item>
@@ -1788,7 +1799,7 @@
<item quantity="one" msgid="3480040795582254384">"Ordubetez"</item>
<item quantity="other" msgid="5408537517529822157">"%d orduz"</item>
</plurals>
- <!-- no translation found for zen_mode_until (7336308492289875088) -->
- <skip />
+ <string name="zen_mode_until" msgid="7336308492289875088">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g> arte"</string>
<string name="zen_mode_forever" msgid="4316804956488785559">"Mugagabea"</string>
+ <string name="toolbar_collapse_description" msgid="2821479483960330739">"Tolestu"</string>
</resources>
diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml
index 5431716..584abe6 100644
--- a/core/res/res/values-fa/strings.xml
+++ b/core/res/res/values-fa/strings.xml
@@ -716,8 +716,14 @@
<string name="permdesc_cache_filesystem" msgid="5578967642265550955">"به برنامه اجازه میدهد تا سیستم فایل حافظهٔ پنهان را بخواند و بنویسد."</string>
<string name="permlab_use_sip" msgid="2052499390128979920">"تماس گرفتن/دریافت تماس از طریق SIP"</string>
<string name="permdesc_use_sip" msgid="2297804849860225257">"به برنامه اجازه میدهد تماسهای SIP بگیرد یا دریافت کند."</string>
- <string name="permlab_register_provider" msgid="2654513709546459553">"ثبت ارتباط مخابراتی جدید"</string>
- <string name="permdesc_register_provider" msgid="7571533832018681544">"به برنامه امکان میدهد ارتباط مخابراتی جدید ثبت کند."</string>
+ <!-- no translation found for permlab_register_sim_subscription (3166535485877549177) -->
+ <skip />
+ <!-- no translation found for permdesc_register_sim_subscription (2138909035926222911) -->
+ <skip />
+ <!-- no translation found for permlab_register_call_provider (108102120289029841) -->
+ <skip />
+ <!-- no translation found for permdesc_register_call_provider (7034310263521081388) -->
+ <skip />
<string name="permlab_connection_manager" msgid="1116193254522105375">"مدیریت ارتباطات مخابراتی"</string>
<string name="permdesc_connection_manager" msgid="5925480810356483565">"به برنامه امکان میدهد ارتباطات مخابراتی را مدیریت کند."</string>
<string name="permlab_bind_incall_service" msgid="6773648341975287125">"تعامل با صفحهنمایش هنگام تماس"</string>
@@ -1233,6 +1239,7 @@
<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_apk" msgid="7904042682111526169">"در حال بهینهسازی برنامهٔ <xliff:g id="NUMBER_0">%1$d</xliff:g> از <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
<string name="android_upgrading_starting_apps" msgid="451464516346926713">"در حال آغاز برنامهها."</string>
<string name="android_upgrading_complete" msgid="1405954754112999229">"در حال اتمام راهاندازی."</string>
@@ -1776,10 +1783,14 @@
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"درخواست گذرواژه قبل از برداشتن پین"</string>
<string name="battery_saver_description" msgid="2510530476513605742">"برای کمک به بهبود عمر باتری، ذخیرهکننده باتری عملکرد دستگاهتان را کاهش میدهد و اغلب اطلاعات پسزمینه و لرزش را محدود میکند. ایمیل، پیامرسانی و سایر برنامههایی که به همگامسازی وابسته هستند ممکن است بهروز نشوند مگر اینکه آنها را باز کنید.\n\nوقتی دستگاهتان شارژ میشود، ذخیرهکننده باتری به صورت خودکار خاموش میشود."</string>
<string name="downtime_condition_summary" msgid="8761776337475705749">"تا زمانی که زمان استراحت در <xliff:g id="FORMATTEDTIME">%1$s</xliff:g> به پایان برسد"</string>
- <!-- no translation found for zen_mode_duration_minutes_summary:one (3177683545388923234) -->
- <!-- no translation found for zen_mode_duration_minutes_summary:other (2787867221129368935) -->
- <!-- no translation found for zen_mode_duration_hours_summary:one (597194865053253679) -->
- <!-- no translation found for zen_mode_duration_hours_summary:other (2827214920627669898) -->
+ <plurals name="zen_mode_duration_minutes_summary">
+ <item quantity="one" msgid="3177683545388923234">"به مدت یک دقیقه (تا <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ <item quantity="other" msgid="2787867221129368935">"به مدت %1$d دقیقه (تا <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ </plurals>
+ <plurals name="zen_mode_duration_hours_summary">
+ <item quantity="one" msgid="597194865053253679">"به مدت یک ساعت (تا <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ <item quantity="other" msgid="2827214920627669898">"به مدت %1$d ساعت (تا <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ </plurals>
<plurals name="zen_mode_duration_minutes">
<item quantity="one" msgid="9040808414992812341">"برای یک دقیقه"</item>
<item quantity="other" msgid="6924190729213550991">"برای %d دقیقه"</item>
@@ -1788,7 +1799,7 @@
<item quantity="one" msgid="3480040795582254384">"برای یک ساعت"</item>
<item quantity="other" msgid="5408537517529822157">"برای %d ساعت"</item>
</plurals>
- <!-- no translation found for zen_mode_until (7336308492289875088) -->
- <skip />
+ <string name="zen_mode_until" msgid="7336308492289875088">"تا <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
<string name="zen_mode_forever" msgid="4316804956488785559">"نامحدود"</string>
+ <string name="toolbar_collapse_description" msgid="2821479483960330739">"کوچک کردن"</string>
</resources>
diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml
index fdec59a..1913af6 100644
--- a/core/res/res/values-fi/strings.xml
+++ b/core/res/res/values-fi/strings.xml
@@ -716,14 +716,16 @@
<string name="permdesc_cache_filesystem" msgid="5578967642265550955">"Antaa sovelluksen lukea välimuistin tiedostojärjestelmää ja kirjoittaa siihen."</string>
<string name="permlab_use_sip" msgid="2052499390128979920">"soita/vastaanota SIP-puheluja"</string>
<string name="permdesc_use_sip" msgid="2297804849860225257">"Sallii sovelluksen soittaa ja vastaanottaa SIP-puheluja."</string>
- <!-- no translation found for permlab_register_provider (2654513709546459553) -->
+ <!-- no translation found for permlab_register_sim_subscription (3166535485877549177) -->
<skip />
- <!-- no translation found for permdesc_register_provider (7571533832018681544) -->
+ <!-- no translation found for permdesc_register_sim_subscription (2138909035926222911) -->
<skip />
- <!-- no translation found for permlab_connection_manager (1116193254522105375) -->
+ <!-- no translation found for permlab_register_call_provider (108102120289029841) -->
<skip />
- <!-- no translation found for permdesc_connection_manager (5925480810356483565) -->
+ <!-- no translation found for permdesc_register_call_provider (7034310263521081388) -->
<skip />
+ <string name="permlab_connection_manager" msgid="1116193254522105375">"tietoliikenneyhteyksien hallinta"</string>
+ <string name="permdesc_connection_manager" msgid="5925480810356483565">"Antaa sovelluksen hallita tietoliikenneyhteyksiä."</string>
<string name="permlab_bind_incall_service" msgid="6773648341975287125">"Vuorovaikutteinen puhelunäyttö"</string>
<string name="permdesc_bind_incall_service" msgid="8343471381323215005">"Antaa sovelluksen määrätä, milloin ja millaisena käyttäjä näkee puhelunäytön."</string>
<string name="permlab_bind_connection_service" msgid="3557341439297014940">"Puhelinpalveluiden yhteyslupa"</string>
@@ -1237,6 +1239,7 @@
<string name="smv_application" msgid="3307209192155442829">"Sovellus <xliff:g id="APPLICATION">%1$s</xliff:g> (prosessi <xliff:g id="PROCESS">%2$s</xliff:g>) on rikkonut itse käyttöön ottamaansa StrictMode-käytäntöä."</string>
<string name="smv_process" msgid="5120397012047462446">"Prosessi <xliff:g id="PROCESS">%1$s</xliff:g> on rikkonut itse käyttöön ottamaansa StrictMode-käytäntöä."</string>
<string name="android_upgrading_title" msgid="1584192285441405746">"Androidia päivitetään…"</string>
+ <string name="android_start_title" msgid="8418054686415318207">"Android käynnistyy…"</string>
<string name="android_upgrading_apk" msgid="7904042682111526169">"Optimoidaan sovellusta <xliff:g id="NUMBER_0">%1$d</xliff:g>/<xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
<string name="android_upgrading_starting_apps" msgid="451464516346926713">"Käynnistetään sovelluksia."</string>
<string name="android_upgrading_complete" msgid="1405954754112999229">"Viimeistellään päivitystä."</string>
@@ -1780,10 +1783,14 @@
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Pyydä salasana ennen irrotusta"</string>
<string name="battery_saver_description" msgid="2510530476513605742">"Akunsäästötoiminto heikentää laitteen suorituskykyä ja rajoittaa värinää ja useimpia taustatietoja akun iän pidentämiseksi. Sähköposti, viestitys ja muut synkronointia edellyttävät sovellukset eivät ehkä päivity, ellet käynnistä niitä.\n\nAkunsäästö kytkeytyy automaattisesti pois laitteen akun latauksen ajaksi."</string>
<string name="downtime_condition_summary" msgid="8761776337475705749">"Käyttökatkos päättyy klo <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
- <!-- no translation found for zen_mode_duration_minutes_summary:one (3177683545388923234) -->
- <!-- no translation found for zen_mode_duration_minutes_summary:other (2787867221129368935) -->
- <!-- no translation found for zen_mode_duration_hours_summary:one (597194865053253679) -->
- <!-- no translation found for zen_mode_duration_hours_summary:other (2827214920627669898) -->
+ <plurals name="zen_mode_duration_minutes_summary">
+ <item quantity="one" msgid="3177683545388923234">"Yksi minuutti (kunnes kello on <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ <item quantity="other" msgid="2787867221129368935">"%1$d minuuttia (kunnes kello on <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ </plurals>
+ <plurals name="zen_mode_duration_hours_summary">
+ <item quantity="one" msgid="597194865053253679">"Yksi tunti (kunnes kello on <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ <item quantity="other" msgid="2827214920627669898">"%1$d tuntia (kunnes kello on <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ </plurals>
<plurals name="zen_mode_duration_minutes">
<item quantity="one" msgid="9040808414992812341">"Minuutiksi"</item>
<item quantity="other" msgid="6924190729213550991">"%d minuutiksi"</item>
@@ -1792,7 +1799,7 @@
<item quantity="one" msgid="3480040795582254384">"Tunniksi"</item>
<item quantity="other" msgid="5408537517529822157">"%d tunniksi"</item>
</plurals>
- <!-- no translation found for zen_mode_until (7336308492289875088) -->
- <skip />
+ <string name="zen_mode_until" msgid="7336308492289875088">"Kunnes kello on <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
<string name="zen_mode_forever" msgid="4316804956488785559">"Toistaiseksi"</string>
+ <string name="toolbar_collapse_description" msgid="2821479483960330739">"Kutista"</string>
</resources>
diff --git a/core/res/res/values-fr-rCA/strings.xml b/core/res/res/values-fr-rCA/strings.xml
index ed7386c..134e7d6 100644
--- a/core/res/res/values-fr-rCA/strings.xml
+++ b/core/res/res/values-fr-rCA/strings.xml
@@ -716,8 +716,14 @@
<string name="permdesc_cache_filesystem" msgid="5578967642265550955">"Permet à l\'application d\'obtenir des droits en lecture et en écriture pour le système de fichiers du cache."</string>
<string name="permlab_use_sip" msgid="2052499390128979920">"faire et recevoir des appels SIP"</string>
<string name="permdesc_use_sip" msgid="2297804849860225257">"Autorise l\'application à effectuer et à recevoir des appels SIP."</string>
- <string name="permlab_register_provider" msgid="2654513709546459553">"enregistrer des nouvelles connexions de télécommunication"</string>
- <string name="permdesc_register_provider" msgid="7571533832018681544">"Permettre à l\'application d\'enregistrer de nouvelles connexions de télécommunication"</string>
+ <!-- no translation found for permlab_register_sim_subscription (3166535485877549177) -->
+ <skip />
+ <!-- no translation found for permdesc_register_sim_subscription (2138909035926222911) -->
+ <skip />
+ <!-- no translation found for permlab_register_call_provider (108102120289029841) -->
+ <skip />
+ <!-- no translation found for permdesc_register_call_provider (7034310263521081388) -->
+ <skip />
<string name="permlab_connection_manager" msgid="1116193254522105375">"gérer les connexions de télécommunication"</string>
<string name="permdesc_connection_manager" msgid="5925480810356483565">"Permettre à l\'application de gérer les connexions de télécommunication"</string>
<string name="permlab_bind_incall_service" msgid="6773648341975287125">"interagir avec l\'écran d\'appel"</string>
@@ -1233,6 +1239,7 @@
<string name="smv_application" msgid="3307209192155442829">"L\'application <xliff:g id="APPLICATION">%1$s</xliff:g> (du processus <xliff:g id="PROCESS">%2$s</xliff:g>) a enfreint ses propres règles du mode strict."</string>
<string name="smv_process" msgid="5120397012047462446">"Le processus <xliff:g id="PROCESS">%1$s</xliff:g> a enfreint ses propres règles du mode strict."</string>
<string name="android_upgrading_title" msgid="1584192285441405746">"Mise à jour d\'Android…"</string>
+ <string name="android_start_title" msgid="8418054686415318207">"Android en cours de démarrage..."</string>
<string name="android_upgrading_apk" msgid="7904042682111526169">"Optimisation de l\'application <xliff:g id="NUMBER_0">%1$d</xliff:g> sur <xliff:g id="NUMBER_1">%2$d</xliff:g>…"</string>
<string name="android_upgrading_starting_apps" msgid="451464516346926713">"Lancement des applications…"</string>
<string name="android_upgrading_complete" msgid="1405954754112999229">"Finalisation de la mise à jour."</string>
@@ -1776,10 +1783,14 @@
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Demander le mot de passe avant d\'annuler l\'épinglage"</string>
<string name="battery_saver_description" msgid="2510530476513605742">"Pour optimiser l\'autonomie de la pile, l\'économiseur d\'énergie réduit les performances de votre appareil et limite les données en arrière-plan. Vous devrez peut-être ouvrir manuellement les applications de courriel, de messagerie et les autres applications synchronisées pour les mettre à jour.\n\nL\'économiseur d\'énergie se désactive automatiquement lorsque votre appareil est en charge."</string>
<string name="downtime_condition_summary" msgid="8761776337475705749">"Jusqu\'à ce que le temps d\'arrêt se termine à <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
- <!-- no translation found for zen_mode_duration_minutes_summary:one (3177683545388923234) -->
- <!-- no translation found for zen_mode_duration_minutes_summary:other (2787867221129368935) -->
- <!-- no translation found for zen_mode_duration_hours_summary:one (597194865053253679) -->
- <!-- no translation found for zen_mode_duration_hours_summary:other (2827214920627669898) -->
+ <plurals name="zen_mode_duration_minutes_summary">
+ <item quantity="one" msgid="3177683545388923234">"Pendant une minute (jusqu\'à <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ <item quantity="other" msgid="2787867221129368935">"Pendant %1$d minutes (jusqu\'à <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ </plurals>
+ <plurals name="zen_mode_duration_hours_summary">
+ <item quantity="one" msgid="597194865053253679">"Pendant une heure (jusqu\'à <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ <item quantity="other" msgid="2827214920627669898">"Pendant %1$d heures (jusqu\'à <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ </plurals>
<plurals name="zen_mode_duration_minutes">
<item quantity="one" msgid="9040808414992812341">"Pendant une minute"</item>
<item quantity="other" msgid="6924190729213550991">"Pendant %d minutes"</item>
@@ -1788,7 +1799,7 @@
<item quantity="one" msgid="3480040795582254384">"Pendant une heure"</item>
<item quantity="other" msgid="5408537517529822157">"Pendant %d heures"</item>
</plurals>
- <!-- no translation found for zen_mode_until (7336308492289875088) -->
- <skip />
+ <string name="zen_mode_until" msgid="7336308492289875088">"Jusqu\'à <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
<string name="zen_mode_forever" msgid="4316804956488785559">"Indéfiniment"</string>
+ <string name="toolbar_collapse_description" msgid="2821479483960330739">"Réduire"</string>
</resources>
diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml
index 4f67038..95b4e6f 100644
--- a/core/res/res/values-fr/strings.xml
+++ b/core/res/res/values-fr/strings.xml
@@ -716,8 +716,14 @@
<string name="permdesc_cache_filesystem" msgid="5578967642265550955">"Permet à l\'application d\'obtenir des droits en lecture/écriture concernant le système de fichiers du cache."</string>
<string name="permlab_use_sip" msgid="2052499390128979920">"effectuer/recevoir des appels SIP"</string>
<string name="permdesc_use_sip" msgid="2297804849860225257">"Autorise l\'application à effectuer et à recevoir des appels SIP."</string>
- <string name="permlab_register_provider" msgid="2654513709546459553">"enregistrer des nouvelles connexions de télécommunication"</string>
- <string name="permdesc_register_provider" msgid="7571533832018681544">"Permettre à l\'application d\'enregistrer de nouvelles connexions de télécommunication"</string>
+ <!-- no translation found for permlab_register_sim_subscription (3166535485877549177) -->
+ <skip />
+ <!-- no translation found for permdesc_register_sim_subscription (2138909035926222911) -->
+ <skip />
+ <!-- no translation found for permlab_register_call_provider (108102120289029841) -->
+ <skip />
+ <!-- no translation found for permdesc_register_call_provider (7034310263521081388) -->
+ <skip />
<string name="permlab_connection_manager" msgid="1116193254522105375">"gérer les connexions de télécommunication"</string>
<string name="permdesc_connection_manager" msgid="5925480810356483565">"Permettre à l\'application de gérer les connexions de télécommunication"</string>
<string name="permlab_bind_incall_service" msgid="6773648341975287125">"contrôler l\'écran d\'appel"</string>
@@ -1233,6 +1239,7 @@
<string name="smv_application" msgid="3307209192155442829">"L\'application <xliff:g id="APPLICATION">%1$s</xliff:g> (du processus <xliff:g id="PROCESS">%2$s</xliff:g>) a enfreint ses propres règles du mode strict."</string>
<string name="smv_process" msgid="5120397012047462446">"Le processus <xliff:g id="PROCESS">%1$s</xliff:g> a enfreint ses propres règles du mode strict."</string>
<string name="android_upgrading_title" msgid="1584192285441405746">"Mise à jour d\'Android…"</string>
+ <string name="android_start_title" msgid="8418054686415318207">"Démarrage d\'Android en cours"</string>
<string name="android_upgrading_apk" msgid="7904042682111526169">"Optimisation de l\'application <xliff:g id="NUMBER_0">%1$d</xliff:g> sur <xliff:g id="NUMBER_1">%2$d</xliff:g>…"</string>
<string name="android_upgrading_starting_apps" msgid="451464516346926713">"Lancement des applications…"</string>
<string name="android_upgrading_complete" msgid="1405954754112999229">"Finalisation de la mise à jour."</string>
@@ -1776,10 +1783,14 @@
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Demander le mot de passe avant d\'annuler l\'épinglage"</string>
<string name="battery_saver_description" msgid="2510530476513605742">"Pour optimiser l\'autonomie de la batterie, l\'économiseur de batterie réduit les performances de votre appareil et limite les données en arrière-plan. Vous devrez peut-être ouvrir manuellement vos applications d\'e-mail, de messagerie instantanée et autres applications synchronisées pour les mettre à jour.\n\nL\'économiseur de batterie s\'éteint automatiquement lorsque votre appareil est en charge."</string>
<string name="downtime_condition_summary" msgid="8761776337475705749">"Jusqu\'à ce que le temps d\'arrêt se termine à <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
- <!-- no translation found for zen_mode_duration_minutes_summary:one (3177683545388923234) -->
- <!-- no translation found for zen_mode_duration_minutes_summary:other (2787867221129368935) -->
- <!-- no translation found for zen_mode_duration_hours_summary:one (597194865053253679) -->
- <!-- no translation found for zen_mode_duration_hours_summary:other (2827214920627669898) -->
+ <plurals name="zen_mode_duration_minutes_summary">
+ <item quantity="one" msgid="3177683545388923234">"Pendant une minute (jusqu\'à <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ <item quantity="other" msgid="2787867221129368935">"Pendant %1$d minutes (jusqu\'à <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ </plurals>
+ <plurals name="zen_mode_duration_hours_summary">
+ <item quantity="one" msgid="597194865053253679">"Pendant une heure (jusqu\'à <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ <item quantity="other" msgid="2827214920627669898">"Pendant %1$d heures (jusqu\'à <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ </plurals>
<plurals name="zen_mode_duration_minutes">
<item quantity="one" msgid="9040808414992812341">"Pendant une minute"</item>
<item quantity="other" msgid="6924190729213550991">"Pendant %d minutes"</item>
@@ -1788,7 +1799,7 @@
<item quantity="one" msgid="3480040795582254384">"Pendant une heure"</item>
<item quantity="other" msgid="5408537517529822157">"Pendant %d heures"</item>
</plurals>
- <!-- no translation found for zen_mode_until (7336308492289875088) -->
- <skip />
+ <string name="zen_mode_until" msgid="7336308492289875088">"Jusqu\'à <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
<string name="zen_mode_forever" msgid="4316804956488785559">"Indéfiniment"</string>
+ <string name="toolbar_collapse_description" msgid="2821479483960330739">"Réduire"</string>
</resources>
diff --git a/core/res/res/values-gl-rES/strings.xml b/core/res/res/values-gl-rES/strings.xml
index 08de833..362867e 100644
--- a/core/res/res/values-gl-rES/strings.xml
+++ b/core/res/res/values-gl-rES/strings.xml
@@ -716,8 +716,14 @@
<string name="permdesc_cache_filesystem" msgid="5578967642265550955">"Permite á aplicación ler e escribir no sistema de ficheiros da caché."</string>
<string name="permlab_use_sip" msgid="2052499390128979920">"facer/recibir chamadas SIP"</string>
<string name="permdesc_use_sip" msgid="2297804849860225257">"Permite que a aplicación faga e reciba chamadas SIP."</string>
- <string name="permlab_register_provider" msgid="2654513709546459553">"rexistrar nova conexión de telecomunicacións"</string>
- <string name="permdesc_register_provider" msgid="7571533832018681544">"Permite que a aplicación rexistre novas conexións de telecomunicacións."</string>
+ <!-- no translation found for permlab_register_sim_subscription (3166535485877549177) -->
+ <skip />
+ <!-- no translation found for permdesc_register_sim_subscription (2138909035926222911) -->
+ <skip />
+ <!-- no translation found for permlab_register_call_provider (108102120289029841) -->
+ <skip />
+ <!-- no translation found for permdesc_register_call_provider (7034310263521081388) -->
+ <skip />
<string name="permlab_connection_manager" msgid="1116193254522105375">"xestionar conexións de telecomunicacións"</string>
<string name="permdesc_connection_manager" msgid="5925480810356483565">"Permite que a aplicación xestione conexións de telecomunicacións."</string>
<string name="permlab_bind_incall_service" msgid="6773648341975287125">"interactuar cunha pantalla de chamada"</string>
@@ -1233,6 +1239,7 @@
<string name="smv_application" msgid="3307209192155442829">"A aplicación <xliff:g id="APPLICATION">%1$s</xliff:g> (proceso <xliff:g id="PROCESS">%2$s</xliff:g>) infrinxiu a súa política StrictMode autoaplicada."</string>
<string name="smv_process" msgid="5120397012047462446">"O proceso <xliff:g id="PROCESS">%1$s</xliff:g> infrinxiu a política StrictMode de aplicación automática."</string>
<string name="android_upgrading_title" msgid="1584192285441405746">"Estase actualizando Android…"</string>
+ <string name="android_start_title" msgid="8418054686415318207">"Estase iniciando Android…"</string>
<string name="android_upgrading_apk" msgid="7904042682111526169">"Optimizando aplicación <xliff:g id="NUMBER_0">%1$d</xliff:g> de <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
<string name="android_upgrading_starting_apps" msgid="451464516346926713">"Iniciando aplicacións."</string>
<string name="android_upgrading_complete" msgid="1405954754112999229">"Está finalizando o arranque"</string>
@@ -1776,10 +1783,14 @@
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Solicitar un contrasinal antes de soltar a pantalla"</string>
<string name="battery_saver_description" msgid="2510530476513605742">"Para axudar a mellorar a duración da batería, o aforro de batería reduce o rendemento do dispositivo e restrinxe a vibración e a maioría dos datos en segundo plano. É posible que o correo, as mensaxes e outras aplicacións que se sincronizan con frecuencia, non se actualicen a menos que as abras.\n\nO aforro de batería desactívase automaticamente durante a carga do dispositivo."</string>
<string name="downtime_condition_summary" msgid="8761776337475705749">"Ata que remate o tempo de inactividade ás <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
- <!-- no translation found for zen_mode_duration_minutes_summary:one (3177683545388923234) -->
- <!-- no translation found for zen_mode_duration_minutes_summary:other (2787867221129368935) -->
- <!-- no translation found for zen_mode_duration_hours_summary:one (597194865053253679) -->
- <!-- no translation found for zen_mode_duration_hours_summary:other (2827214920627669898) -->
+ <plurals name="zen_mode_duration_minutes_summary">
+ <item quantity="one" msgid="3177683545388923234">"Durante un minuto (ata as <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ <item quantity="other" msgid="2787867221129368935">"Durante %1$d minutos (ata as <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ </plurals>
+ <plurals name="zen_mode_duration_hours_summary">
+ <item quantity="one" msgid="597194865053253679">"Durante unha hora (ata as <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ <item quantity="other" msgid="2827214920627669898">"Durante %1$d horas (ata as <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ </plurals>
<plurals name="zen_mode_duration_minutes">
<item quantity="one" msgid="9040808414992812341">"Durante un minuto"</item>
<item quantity="other" msgid="6924190729213550991">"Durante %d minutos"</item>
@@ -1788,7 +1799,7 @@
<item quantity="one" msgid="3480040795582254384">"Durante unha hora"</item>
<item quantity="other" msgid="5408537517529822157">"Durante %d horas"</item>
</plurals>
- <!-- no translation found for zen_mode_until (7336308492289875088) -->
- <skip />
+ <string name="zen_mode_until" msgid="7336308492289875088">"Ata as <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
<string name="zen_mode_forever" msgid="4316804956488785559">"Indefinidamente"</string>
+ <string name="toolbar_collapse_description" msgid="2821479483960330739">"Contraer"</string>
</resources>
diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml
index 51586ff..c9766e1 100644
--- a/core/res/res/values-hi/strings.xml
+++ b/core/res/res/values-hi/strings.xml
@@ -716,14 +716,16 @@
<string name="permdesc_cache_filesystem" msgid="5578967642265550955">"ऐप्स को संचय फ़ाइल सिस्टम पढ़ने और लिखने देता है."</string>
<string name="permlab_use_sip" msgid="2052499390128979920">"SIP कॉल करें/प्राप्त करें"</string>
<string name="permdesc_use_sip" msgid="2297804849860225257">"ऐप्स को SIP कॉल करने और प्राप्त करने देती है."</string>
- <!-- no translation found for permlab_register_provider (2654513709546459553) -->
+ <!-- no translation found for permlab_register_sim_subscription (3166535485877549177) -->
<skip />
- <!-- no translation found for permdesc_register_provider (7571533832018681544) -->
+ <!-- no translation found for permdesc_register_sim_subscription (2138909035926222911) -->
<skip />
- <!-- no translation found for permlab_connection_manager (1116193254522105375) -->
+ <!-- no translation found for permlab_register_call_provider (108102120289029841) -->
<skip />
- <!-- no translation found for permdesc_connection_manager (5925480810356483565) -->
+ <!-- no translation found for permdesc_register_call_provider (7034310263521081388) -->
<skip />
+ <string name="permlab_connection_manager" msgid="1116193254522105375">"टेलीकॉम कनेक्शन प्रबंधित करें"</string>
+ <string name="permdesc_connection_manager" msgid="5925480810356483565">"ऐप को टेलीकॉम कनेक्शन प्रबंधित करने देती है."</string>
<string name="permlab_bind_incall_service" msgid="6773648341975287125">"इन-कॉल स्क्रीन से सहभागिता करें"</string>
<string name="permdesc_bind_incall_service" msgid="8343471381323215005">"ऐप्स को यह नियंत्रित करने देती है कि उपयोगकर्ता को इन-कॉल स्क्रीन कब और कैसी दिखाई देती है."</string>
<string name="permlab_bind_connection_service" msgid="3557341439297014940">"टेलीफ़ोनी सेवाओं के साथ सहभागिता करें"</string>
@@ -1237,6 +1239,7 @@
<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_apk" msgid="7904042682111526169">"<xliff:g id="NUMBER_1">%2$d</xliff:g> में से <xliff:g id="NUMBER_0">%1$d</xliff:g> ऐप्स अनुकूलित हो रहा है."</string>
<string name="android_upgrading_starting_apps" msgid="451464516346926713">"ऐप्स प्रारंभ होने वाले हैं"</string>
<string name="android_upgrading_complete" msgid="1405954754112999229">"बूट समाप्त हो रहा है."</string>
@@ -1780,10 +1783,14 @@
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"अनपिन करने से पहले पासवर्ड के लिए पूछें"</string>
<string name="battery_saver_description" msgid="2510530476513605742">"बैटरी के जीवन काल को बेहतर बनाने में सहायता के लिए, बैटरी सेवर आपके डिवाइस के प्रदर्शन को घटा देता है तथा कंपन और अधिकांश पृष्ठभूमि डेटा को सीमित कर देता है. ईमेल, संदेश सेवा और अन्य ऐप्स जो समन्वयन पर निर्भर करते हैं वे तब तक अपडेट नहीं हो सकते जब तक कि आप उन्हें नहीं खोलते.\n\nजब आपका डिवाइस चार्ज हो रहा होता है तो बैटरी सेवर अपने आप बंद हो जाता है."</string>
<string name="downtime_condition_summary" msgid="8761776337475705749">"जब तक कि <xliff:g id="FORMATTEDTIME">%1$s</xliff:g> बजे आपका डाउनटाइम समाप्त न हो"</string>
- <!-- no translation found for zen_mode_duration_minutes_summary:one (3177683545388923234) -->
- <!-- no translation found for zen_mode_duration_minutes_summary:other (2787867221129368935) -->
- <!-- no translation found for zen_mode_duration_hours_summary:one (597194865053253679) -->
- <!-- no translation found for zen_mode_duration_hours_summary:other (2827214920627669898) -->
+ <plurals name="zen_mode_duration_minutes_summary">
+ <item quantity="one" msgid="3177683545388923234">"एक मिनट के लिए (<xliff:g id="FORMATTEDTIME">%2$s</xliff:g> तक)"</item>
+ <item quantity="other" msgid="2787867221129368935">"%1$d मिनट के लिए (<xliff:g id="FORMATTEDTIME">%2$s</xliff:g> तक)"</item>
+ </plurals>
+ <plurals name="zen_mode_duration_hours_summary">
+ <item quantity="one" msgid="597194865053253679">"एक घंटे के लिए (<xliff:g id="FORMATTEDTIME">%2$s</xliff:g> तक)"</item>
+ <item quantity="other" msgid="2827214920627669898">"%1$d घंटो के लिए (<xliff:g id="FORMATTEDTIME">%2$s</xliff:g> तक)"</item>
+ </plurals>
<plurals name="zen_mode_duration_minutes">
<item quantity="one" msgid="9040808414992812341">"एक मिनट के लिए"</item>
<item quantity="other" msgid="6924190729213550991">"%d मिनट के लिए"</item>
@@ -1792,7 +1799,7 @@
<item quantity="one" msgid="3480040795582254384">"एक घंटे के लिए"</item>
<item quantity="other" msgid="5408537517529822157">"%d घंटे के लिए"</item>
</plurals>
- <!-- no translation found for zen_mode_until (7336308492289875088) -->
- <skip />
+ <string name="zen_mode_until" msgid="7336308492289875088">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g> तक"</string>
<string name="zen_mode_forever" msgid="4316804956488785559">"अनिश्चित समय तक"</string>
+ <string name="toolbar_collapse_description" msgid="2821479483960330739">"संक्षिप्त करें"</string>
</resources>
diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml
index 1a4af08..530b735 100644
--- a/core/res/res/values-hr/strings.xml
+++ b/core/res/res/values-hr/strings.xml
@@ -716,8 +716,14 @@
<string name="permdesc_cache_filesystem" msgid="5578967642265550955">"Aplikaciji omogućuje čitanje i pisanje u datotečnom sustavu privremene memorije."</string>
<string name="permlab_use_sip" msgid="2052499390128979920">"upućivanje/primanje SIP poziva"</string>
<string name="permdesc_use_sip" msgid="2297804849860225257">"Aplikacija može upućivati i primati SIP pozive."</string>
- <string name="permlab_register_provider" msgid="2654513709546459553">"registriranje novih telekomunikacijskih veza"</string>
- <string name="permdesc_register_provider" msgid="7571533832018681544">"Aplikaciji omogućuje registriranje novih telekomunikacijskih veza."</string>
+ <!-- no translation found for permlab_register_sim_subscription (3166535485877549177) -->
+ <skip />
+ <!-- no translation found for permdesc_register_sim_subscription (2138909035926222911) -->
+ <skip />
+ <!-- no translation found for permlab_register_call_provider (108102120289029841) -->
+ <skip />
+ <!-- no translation found for permdesc_register_call_provider (7034310263521081388) -->
+ <skip />
<string name="permlab_connection_manager" msgid="1116193254522105375">"upravljanje telekomunikacijskim vezama"</string>
<string name="permdesc_connection_manager" msgid="5925480810356483565">"Aplikaciji omogućuje upravljanje telekomunikacijskim vezama."</string>
<string name="permlab_bind_incall_service" msgid="6773648341975287125">"interakcija sa zaslonom tijekom poziva"</string>
@@ -1233,6 +1239,7 @@
<string name="smv_application" msgid="3307209192155442829">"Aplikacija <xliff:g id="APPLICATION">%1$s</xliff:g> (proces <xliff:g id="PROCESS">%2$s</xliff:g>) prekršila je vlastito pravilo StrictMode."</string>
<string name="smv_process" msgid="5120397012047462446">"Proces <xliff:g id="PROCESS">%1$s</xliff:g> prekršio je svoje vlastito pravilo StrictMode."</string>
<string name="android_upgrading_title" msgid="1584192285441405746">"Android se nadograđuje…"</string>
+ <string name="android_start_title" msgid="8418054686415318207">"Pokretanje Androida..."</string>
<string name="android_upgrading_apk" msgid="7904042682111526169">"Optimiziranje aplikacije <xliff:g id="NUMBER_0">%1$d</xliff:g> od <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
<string name="android_upgrading_starting_apps" msgid="451464516346926713">"Pokretanje aplikacija."</string>
<string name="android_upgrading_complete" msgid="1405954754112999229">"Završetak inicijalizacije."</string>
@@ -1776,10 +1783,14 @@
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Traži zaporku radi otkvačivanja"</string>
<string name="battery_saver_description" msgid="2510530476513605742">"Da bi se produljilo trajanje baterije, ušteda baterije smanjuje rad uređaja i ograničava vibraciju i većinu pozadinskih podataka. Aplikacije za e-poštu, slanje poruka i ostalo koje se oslanjaju na sinkronizaciju možda se neće ažurirati ako ih ne otvorite.\n\nUšteda baterije isključuje se automatski dok se uređaj puni."</string>
<string name="downtime_condition_summary" msgid="8761776337475705749">"Dok razdoblje zastoja ne završi u <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
- <!-- no translation found for zen_mode_duration_minutes_summary:one (3177683545388923234) -->
- <!-- no translation found for zen_mode_duration_minutes_summary:other (2787867221129368935) -->
- <!-- no translation found for zen_mode_duration_hours_summary:one (597194865053253679) -->
- <!-- no translation found for zen_mode_duration_hours_summary:other (2827214920627669898) -->
+ <plurals name="zen_mode_duration_minutes_summary">
+ <item quantity="one" msgid="3177683545388923234">"Jednu minutu (do <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ <item quantity="other" msgid="2787867221129368935">"%1$d min (do <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ </plurals>
+ <plurals name="zen_mode_duration_hours_summary">
+ <item quantity="one" msgid="597194865053253679">"Jedan sat (do <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ <item quantity="other" msgid="2827214920627669898">"%1$d h (do <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ </plurals>
<plurals name="zen_mode_duration_minutes">
<item quantity="one" msgid="9040808414992812341">"Jednu minutu"</item>
<item quantity="other" msgid="6924190729213550991">"%d min"</item>
@@ -1788,7 +1799,7 @@
<item quantity="one" msgid="3480040795582254384">"Jedan sat"</item>
<item quantity="other" msgid="5408537517529822157">"%d h"</item>
</plurals>
- <!-- no translation found for zen_mode_until (7336308492289875088) -->
- <skip />
+ <string name="zen_mode_until" msgid="7336308492289875088">"Do <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
<string name="zen_mode_forever" msgid="4316804956488785559">"Neodređeno"</string>
+ <string name="toolbar_collapse_description" msgid="2821479483960330739">"Sažmi"</string>
</resources>
diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml
index 87be174..934b4db 100644
--- a/core/res/res/values-hu/strings.xml
+++ b/core/res/res/values-hu/strings.xml
@@ -716,8 +716,14 @@
<string name="permdesc_cache_filesystem" msgid="5578967642265550955">"Lehetővé teszi az alkalmazás számára a gyorsítótár-fájlrendszer olvasását és írását."</string>
<string name="permlab_use_sip" msgid="2052499390128979920">"SIP-hívások indítása/fogadása"</string>
<string name="permdesc_use_sip" msgid="2297804849860225257">"SIP-hívások indításának és fogadásának engedélyezése az alkalmazás számára."</string>
- <string name="permlab_register_provider" msgid="2654513709546459553">"új telekommunikációs kapcsolatok regisztrálása"</string>
- <string name="permdesc_register_provider" msgid="7571533832018681544">"Engedélyezi az alkalmazásnak új telekommunikációs kapcsolatok regisztrálását."</string>
+ <!-- no translation found for permlab_register_sim_subscription (3166535485877549177) -->
+ <skip />
+ <!-- no translation found for permdesc_register_sim_subscription (2138909035926222911) -->
+ <skip />
+ <!-- no translation found for permlab_register_call_provider (108102120289029841) -->
+ <skip />
+ <!-- no translation found for permdesc_register_call_provider (7034310263521081388) -->
+ <skip />
<string name="permlab_connection_manager" msgid="1116193254522105375">"telekommunikációs kapcsolatok kezelése"</string>
<string name="permdesc_connection_manager" msgid="5925480810356483565">"Engedélyezi az alkalmazásnak a telekommunikációs kapcsolatok kezelését."</string>
<string name="permlab_bind_incall_service" msgid="6773648341975287125">"interakció a hívás közbeni képernyővel"</string>
@@ -1233,6 +1239,7 @@
<string name="smv_application" msgid="3307209192155442829">"A(z) <xliff:g id="APPLICATION">%1$s</xliff:g> alkalmazás (<xliff:g id="PROCESS">%2$s</xliff:g> folyamat) megsértette az általa kényszerített Szigorú üzemmód irányelvet."</string>
<string name="smv_process" msgid="5120397012047462446">"<xliff:g id="PROCESS">%1$s</xliff:g> folyamat megsértette az általa kényszerített Szigorú üzemmód irányelvet."</string>
<string name="android_upgrading_title" msgid="1584192285441405746">"Android frissítése folyamatban..."</string>
+ <string name="android_start_title" msgid="8418054686415318207">"Az Android indítása…"</string>
<string name="android_upgrading_apk" msgid="7904042682111526169">"Alkalmazás optimalizálása: <xliff:g id="NUMBER_0">%1$d</xliff:g>/<xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
<string name="android_upgrading_starting_apps" msgid="451464516346926713">"Kezdő alkalmazások."</string>
<string name="android_upgrading_complete" msgid="1405954754112999229">"Rendszerindítás befejezése."</string>
@@ -1776,10 +1783,14 @@
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Jelszó kérése a rögzítés feloldásához"</string>
<string name="battery_saver_description" msgid="2510530476513605742">"Az akkumulátor üzemidejének növeléséhez az akkumulátorkímélő mód csökkenti az eszköz teljesítményét, valamint korlátozza a rezgést és a legtöbb háttéradatot. Előfordulhat, hogy az e-mailek, az üzenetküldő programok és más alkalmazások, amelyek a szinkronizálás funkciót használják, nem frissülnek addig, amíg meg nem nyitja őket.\n\nAz akkumulátorkímélő mód automatikusan kikapcsol, amikor az eszköz töltődik."</string>
<string name="downtime_condition_summary" msgid="8761776337475705749">"Amíg az állásidő véget nem ér ekkor: <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
- <!-- no translation found for zen_mode_duration_minutes_summary:one (3177683545388923234) -->
- <!-- no translation found for zen_mode_duration_minutes_summary:other (2787867221129368935) -->
- <!-- no translation found for zen_mode_duration_hours_summary:one (597194865053253679) -->
- <!-- no translation found for zen_mode_duration_hours_summary:other (2827214920627669898) -->
+ <plurals name="zen_mode_duration_minutes_summary">
+ <item quantity="one" msgid="3177683545388923234">"Egy percre (eddig: <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ <item quantity="other" msgid="2787867221129368935">"%1$d percre (eddig: <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ </plurals>
+ <plurals name="zen_mode_duration_hours_summary">
+ <item quantity="one" msgid="597194865053253679">"Egy órára (eddig: <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ <item quantity="other" msgid="2827214920627669898">"%1$d órára (eddig: <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ </plurals>
<plurals name="zen_mode_duration_minutes">
<item quantity="one" msgid="9040808414992812341">"Egy percen át"</item>
<item quantity="other" msgid="6924190729213550991">"%d percen át"</item>
@@ -1788,7 +1799,7 @@
<item quantity="one" msgid="3480040795582254384">"Egy órán át"</item>
<item quantity="other" msgid="5408537517529822157">"%d órán át"</item>
</plurals>
- <!-- no translation found for zen_mode_until (7336308492289875088) -->
- <skip />
+ <string name="zen_mode_until" msgid="7336308492289875088">"Eddig: <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
<string name="zen_mode_forever" msgid="4316804956488785559">"Határozatlan ideig"</string>
+ <string name="toolbar_collapse_description" msgid="2821479483960330739">"Összecsukás"</string>
</resources>
diff --git a/core/res/res/values-hy-rAM/strings.xml b/core/res/res/values-hy-rAM/strings.xml
index 1ab805e..86faca3 100644
--- a/core/res/res/values-hy-rAM/strings.xml
+++ b/core/res/res/values-hy-rAM/strings.xml
@@ -716,14 +716,16 @@
<string name="permdesc_cache_filesystem" msgid="5578967642265550955">"Թույլ է տալիս հավելվածին գրել և կարդալ քեշ ֆայլային համակարգը:"</string>
<string name="permlab_use_sip" msgid="2052499390128979920">"կատարել կամ ստանալ SIP զանգեր"</string>
<string name="permdesc_use_sip" msgid="2297804849860225257">"Ծրագրին թույլ է տալիս կատարել և ստանալ SIP զանգեր:"</string>
- <!-- no translation found for permlab_register_provider (2654513709546459553) -->
+ <!-- no translation found for permlab_register_sim_subscription (3166535485877549177) -->
<skip />
- <!-- no translation found for permdesc_register_provider (7571533832018681544) -->
+ <!-- no translation found for permdesc_register_sim_subscription (2138909035926222911) -->
<skip />
- <!-- no translation found for permlab_connection_manager (1116193254522105375) -->
+ <!-- no translation found for permlab_register_call_provider (108102120289029841) -->
<skip />
- <!-- no translation found for permdesc_connection_manager (5925480810356483565) -->
+ <!-- no translation found for permdesc_register_call_provider (7034310263521081388) -->
<skip />
+ <string name="permlab_connection_manager" msgid="1116193254522105375">"կառավարել հեռահաղորդակցության կապերը"</string>
+ <string name="permdesc_connection_manager" msgid="5925480810356483565">"Հավելվածին թույլ է տալիս կառավարել հեռահաղորդակցության կապերը:"</string>
<string name="permlab_bind_incall_service" msgid="6773648341975287125">"փոխազդել մուտքային զանգի էկրանին"</string>
<string name="permdesc_bind_incall_service" msgid="8343471381323215005">"Թույլ է տալիս ծրագրին վերահսկել՝ երբ և ինչպես է օգտվողը տեսնում մուտքային զանգը էկրանին:"</string>
<string name="permlab_bind_connection_service" msgid="3557341439297014940">"համագործակցել հեռախոսակապի ծառայությունների հետ"</string>
@@ -1237,6 +1239,8 @@
<string name="smv_application" msgid="3307209192155442829">"<xliff:g id="APPLICATION">%1$s</xliff:g> ծրագիրը (գործընթաց <xliff:g id="PROCESS">%2$s</xliff:g>) խախտել է իր ինքնահարկադրված Խիստ ռեժիմ քաղաքականությունը:"</string>
<string name="smv_process" msgid="5120397012047462446">"<xliff:g id="PROCESS">%1$s</xliff:g> գործընթացը խախտել է իր ինքնահարկադրված Խիստ ռեժիմ քաղաքականությունը:"</string>
<string name="android_upgrading_title" msgid="1584192285441405746">"Android-ը նորացվում է..."</string>
+ <!-- no translation found for android_start_title (8418054686415318207) -->
+ <skip />
<string name="android_upgrading_apk" msgid="7904042682111526169">"Օպտիմալացվում է հավելված <xliff:g id="NUMBER_0">%1$d</xliff:g>-ը <xliff:g id="NUMBER_1">%2$d</xliff:g>-ից:"</string>
<string name="android_upgrading_starting_apps" msgid="451464516346926713">"Հավելվածները մեկնարկում են:"</string>
<string name="android_upgrading_complete" msgid="1405954754112999229">"Բեռնումն ավարտվում է:"</string>
@@ -1780,10 +1784,14 @@
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Ապաամրացնելուց առաջ հարցնել գաղտնաբառը"</string>
<string name="battery_saver_description" msgid="2510530476513605742">"Մարտկոցի աշխատաժամանակը շատացնելու համար մարտկոցի տնտեսումը կնվազեցնի ձեր սարքի կատարողականը և կսահմանափակի թրթռոցն ու ֆոնային տվյալներից շատերը: Էլփոստը, հաղորդագրությունները և այլ ծրագրերը, որոնք օգտագործում են համաժամեցումը, կթարմանան միայն դրանք աշխատեցնելիս:\n\nՄարկտոցի տնտեսումը ավտոմատ կանջատվի, հենց սարքը միացվի լիցքավորման:"</string>
<string name="downtime_condition_summary" msgid="8761776337475705749">"Մինչև ձեր ժամանակն ավարտվի ժամը <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
- <!-- no translation found for zen_mode_duration_minutes_summary:one (3177683545388923234) -->
- <!-- no translation found for zen_mode_duration_minutes_summary:other (2787867221129368935) -->
- <!-- no translation found for zen_mode_duration_hours_summary:one (597194865053253679) -->
- <!-- no translation found for zen_mode_duration_hours_summary:other (2827214920627669898) -->
+ <plurals name="zen_mode_duration_minutes_summary">
+ <item quantity="one" msgid="3177683545388923234">"Մեկ րոպե (մինչև <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ <item quantity="other" msgid="2787867221129368935">"%1$d րոպե (մինչև <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ </plurals>
+ <plurals name="zen_mode_duration_hours_summary">
+ <item quantity="one" msgid="597194865053253679">"Մեկ ժամ (մինչև <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ <item quantity="other" msgid="2827214920627669898">"%1$d ժամ (մինչև <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ </plurals>
<plurals name="zen_mode_duration_minutes">
<item quantity="one" msgid="9040808414992812341">"Մեկ րոպե"</item>
<item quantity="other" msgid="6924190729213550991">"%d րոպե"</item>
@@ -1792,7 +1800,8 @@
<item quantity="one" msgid="3480040795582254384">"Մեկ ժամ"</item>
<item quantity="other" msgid="5408537517529822157">"%d ժամ"</item>
</plurals>
- <!-- no translation found for zen_mode_until (7336308492289875088) -->
- <skip />
+ <string name="zen_mode_until" msgid="7336308492289875088">"Մինչև <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
<string name="zen_mode_forever" msgid="4316804956488785559">"Անորոշ ժամանակով"</string>
+ <!-- no translation found for toolbar_collapse_description (2821479483960330739) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml
index d80c2bd..0ff8eae 100644
--- a/core/res/res/values-in/strings.xml
+++ b/core/res/res/values-in/strings.xml
@@ -716,8 +716,14 @@
<string name="permdesc_cache_filesystem" msgid="5578967642265550955">"Mengizinkan apl membaca dan menulis pada sistem file cache."</string>
<string name="permlab_use_sip" msgid="2052499390128979920">"lakukan/terima panggilan SIP"</string>
<string name="permdesc_use_sip" msgid="2297804849860225257">"Izinkan aplikasi melakukan dan menerima panggilan SIP."</string>
- <string name="permlab_register_provider" msgid="2654513709546459553">"daftarkan sambungan telekomunikasi baru"</string>
- <string name="permdesc_register_provider" msgid="7571533832018681544">"Mengizinkan aplikasi untuk mendaftarkan sambungan telekomunikasi baru."</string>
+ <!-- no translation found for permlab_register_sim_subscription (3166535485877549177) -->
+ <skip />
+ <!-- no translation found for permdesc_register_sim_subscription (2138909035926222911) -->
+ <skip />
+ <!-- no translation found for permlab_register_call_provider (108102120289029841) -->
+ <skip />
+ <!-- no translation found for permdesc_register_call_provider (7034310263521081388) -->
+ <skip />
<string name="permlab_connection_manager" msgid="1116193254522105375">"kelola sambungan telekomunikasi"</string>
<string name="permdesc_connection_manager" msgid="5925480810356483565">"Mengizinkan aplikasi untuk mengelola sambungan telekomunikasi."</string>
<string name="permlab_bind_incall_service" msgid="6773648341975287125">"berinteraksi dengan layar dalam panggilan"</string>
@@ -1233,6 +1239,7 @@
<string name="smv_application" msgid="3307209192155442829">"Apl <xliff:g id="APPLICATION">%1$s</xliff:g> (proses <xliff:g id="PROCESS">%2$s</xliff:g>) telah melanggar kebijakan StrictMode yang diberlakukannya sendiri."</string>
<string name="smv_process" msgid="5120397012047462446">"Proses <xliff:g id="PROCESS">%1$s</xliff:g> telah melanggar kebijakan StrictMode yang diberlakukan secara otomatis."</string>
<string name="android_upgrading_title" msgid="1584192285441405746">"Android sedang meningkatkan versi..."</string>
+ <string name="android_start_title" msgid="8418054686415318207">"Memulai Android…"</string>
<string name="android_upgrading_apk" msgid="7904042682111526169">"Mengoptimalkan aplikasi <xliff:g id="NUMBER_0">%1$d</xliff:g> dari <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
<string name="android_upgrading_starting_apps" msgid="451464516346926713">"Memulai aplikasi."</string>
<string name="android_upgrading_complete" msgid="1405954754112999229">"Menyelesaikan boot."</string>
@@ -1776,10 +1783,14 @@
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Meminta sandi sebelum melepas sematan"</string>
<string name="battery_saver_description" msgid="2510530476513605742">"Guna membantu meningkatkan masa pakai baterai, penghemat baterai mengurangi kinerja perangkat dan membatasi getaran serta sebagian besar data latar belakang. Email, perpesanan, dan aplikasi lain yang bergantung pada sinkronisasi mungkin tidak akan diperbarui kecuali Anda membukanya.\n\nPenghemat baterai dinonaktifkan secara otomatis saat perangkat diisi daya."</string>
<string name="downtime_condition_summary" msgid="8761776337475705749">"Hingga waktu perbaikan Anda berakhir pukul <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
- <!-- no translation found for zen_mode_duration_minutes_summary:one (3177683545388923234) -->
- <!-- no translation found for zen_mode_duration_minutes_summary:other (2787867221129368935) -->
- <!-- no translation found for zen_mode_duration_hours_summary:one (597194865053253679) -->
- <!-- no translation found for zen_mode_duration_hours_summary:other (2827214920627669898) -->
+ <plurals name="zen_mode_duration_minutes_summary">
+ <item quantity="one" msgid="3177683545388923234">"Selama semenit (hingga <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ <item quantity="other" msgid="2787867221129368935">"Selama %1$d menit (hingga <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ </plurals>
+ <plurals name="zen_mode_duration_hours_summary">
+ <item quantity="one" msgid="597194865053253679">"Selama sejam (hingga <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ <item quantity="other" msgid="2827214920627669898">"Selama %1$d jam (hingga <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ </plurals>
<plurals name="zen_mode_duration_minutes">
<item quantity="one" msgid="9040808414992812341">"Selama satu menit"</item>
<item quantity="other" msgid="6924190729213550991">"Selama %d menit"</item>
@@ -1788,7 +1799,7 @@
<item quantity="one" msgid="3480040795582254384">"Selama satu jam"</item>
<item quantity="other" msgid="5408537517529822157">"Selama %d jam"</item>
</plurals>
- <!-- no translation found for zen_mode_until (7336308492289875088) -->
- <skip />
+ <string name="zen_mode_until" msgid="7336308492289875088">"Hingga <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
<string name="zen_mode_forever" msgid="4316804956488785559">"Tidak ditentukan"</string>
+ <string name="toolbar_collapse_description" msgid="2821479483960330739">"Ciutkan"</string>
</resources>
diff --git a/core/res/res/values-is-rIS/strings.xml b/core/res/res/values-is-rIS/strings.xml
index 2b24154..5f15cb83 100644
--- a/core/res/res/values-is-rIS/strings.xml
+++ b/core/res/res/values-is-rIS/strings.xml
@@ -716,8 +716,14 @@
<string name="permdesc_cache_filesystem" msgid="5578967642265550955">"Leyfir forriti að lesa og skrifa í skráakerfi skyndiminnis."</string>
<string name="permlab_use_sip" msgid="2052499390128979920">"hringja/svara SIP-símtölum"</string>
<string name="permdesc_use_sip" msgid="2297804849860225257">"Leyfir forritinu að hringja og svara SIP-símtölum."</string>
- <string name="permlab_register_provider" msgid="2654513709546459553">"skrá nýjar símatengingar"</string>
- <string name="permdesc_register_provider" msgid="7571533832018681544">"Leyfir forritinu að skrá nýjar símatengingar."</string>
+ <!-- no translation found for permlab_register_sim_subscription (3166535485877549177) -->
+ <skip />
+ <!-- no translation found for permdesc_register_sim_subscription (2138909035926222911) -->
+ <skip />
+ <!-- no translation found for permlab_register_call_provider (108102120289029841) -->
+ <skip />
+ <!-- no translation found for permdesc_register_call_provider (7034310263521081388) -->
+ <skip />
<string name="permlab_connection_manager" msgid="1116193254522105375">"stjórna símatengingum"</string>
<string name="permdesc_connection_manager" msgid="5925480810356483565">"Leyfir forritinu að stjórna símatengingum."</string>
<string name="permlab_bind_incall_service" msgid="6773648341975287125">"eiga samskipti við símtalsskjá"</string>
@@ -1233,6 +1239,7 @@
<string name="smv_application" msgid="3307209192155442829">"Forritið <xliff:g id="APPLICATION">%1$s</xliff:g> (ferli <xliff:g id="PROCESS">%2$s</xliff:g>) hefur brotið gegn eigin StrictMode-stefnu."</string>
<string name="smv_process" msgid="5120397012047462446">"Forritið <xliff:g id="PROCESS">%1$s</xliff:g> braut gegn eigin StrictMode-stefnu."</string>
<string name="android_upgrading_title" msgid="1584192285441405746">"Android er að uppfæra…"</string>
+ <string name="android_start_title" msgid="8418054686415318207">"Android er að ræsast…"</string>
<string name="android_upgrading_apk" msgid="7904042682111526169">"Fínstillir forrit <xliff:g id="NUMBER_0">%1$d</xliff:g> af <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
<string name="android_upgrading_starting_apps" msgid="451464516346926713">"Ræsir forrit."</string>
<string name="android_upgrading_complete" msgid="1405954754112999229">"Lýkur ræsingu."</string>
@@ -1776,10 +1783,14 @@
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Biðja um aðgangsorð til að losa"</string>
<string name="battery_saver_description" msgid="2510530476513605742">"Til að auka endingu rafhlöðunnar dregur rafhlöðusparnaður úr afköstum tækisins og takmarkar titring og flest bakgrunnsgögn. Ekki er víst að tölvupóstur, skilaboð og önnur forrit sem reiða sig á samstillingu verði uppfærð fyrr en þú opnar þau.\n\nSjálfkrafa er slökkt á rafhlöðusparnaði þegar tækið er í hleðslu."</string>
<string name="downtime_condition_summary" msgid="8761776337475705749">"Þangað til niðritíma lýkur, <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
- <!-- no translation found for zen_mode_duration_minutes_summary:one (3177683545388923234) -->
- <!-- no translation found for zen_mode_duration_minutes_summary:other (2787867221129368935) -->
- <!-- no translation found for zen_mode_duration_hours_summary:one (597194865053253679) -->
- <!-- no translation found for zen_mode_duration_hours_summary:other (2827214920627669898) -->
+ <plurals name="zen_mode_duration_minutes_summary">
+ <item quantity="one" msgid="3177683545388923234">"Í eina mínútu (til <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ <item quantity="other" msgid="2787867221129368935">"Í %1$d mín. (til <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ </plurals>
+ <plurals name="zen_mode_duration_hours_summary">
+ <item quantity="one" msgid="597194865053253679">"Í eina klukkustund (til <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ <item quantity="other" msgid="2827214920627669898">"Í %1$d klst. (til <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ </plurals>
<plurals name="zen_mode_duration_minutes">
<item quantity="one" msgid="9040808414992812341">"Í eina mínútu"</item>
<item quantity="other" msgid="6924190729213550991">"Í %d mínútur"</item>
@@ -1788,7 +1799,7 @@
<item quantity="one" msgid="3480040795582254384">"Í eina klukkustund"</item>
<item quantity="other" msgid="5408537517529822157">"Í %d klukkustundir"</item>
</plurals>
- <!-- no translation found for zen_mode_until (7336308492289875088) -->
- <skip />
+ <string name="zen_mode_until" msgid="7336308492289875088">"Til <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
<string name="zen_mode_forever" msgid="4316804956488785559">"Án tímatakmarkana"</string>
+ <string name="toolbar_collapse_description" msgid="2821479483960330739">"Minnka"</string>
</resources>
diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml
index 69b76048..a102e4b 100644
--- a/core/res/res/values-it/strings.xml
+++ b/core/res/res/values-it/strings.xml
@@ -716,8 +716,14 @@
<string name="permdesc_cache_filesystem" msgid="5578967642265550955">"Consente all\'applicazione di leggere e scrivere il filesystem nella cache."</string>
<string name="permlab_use_sip" msgid="2052499390128979920">"fare/ricevere chiamate SIP"</string>
<string name="permdesc_use_sip" msgid="2297804849860225257">"Consente all\'app di effettuare e ricevere chiamate SIP."</string>
- <string name="permlab_register_provider" msgid="2654513709546459553">"registra nuova connessione di telecomunicazione"</string>
- <string name="permdesc_register_provider" msgid="7571533832018681544">"Consente all\'app di registrare nuove connessioni di telecomunicazione."</string>
+ <!-- no translation found for permlab_register_sim_subscription (3166535485877549177) -->
+ <skip />
+ <!-- no translation found for permdesc_register_sim_subscription (2138909035926222911) -->
+ <skip />
+ <!-- no translation found for permlab_register_call_provider (108102120289029841) -->
+ <skip />
+ <!-- no translation found for permdesc_register_call_provider (7034310263521081388) -->
+ <skip />
<string name="permlab_connection_manager" msgid="1116193254522105375">"gestisci connessioni di telecomunicazione"</string>
<string name="permdesc_connection_manager" msgid="5925480810356483565">"Consente all\'app di gestire connessioni di telecomunicazione."</string>
<string name="permlab_bind_incall_service" msgid="6773648341975287125">"interazione con lo schermo durante una chiamata"</string>
@@ -1233,6 +1239,7 @@
<string name="smv_application" msgid="3307209192155442829">"L\'applicazione <xliff:g id="APPLICATION">%1$s</xliff:g> (processo <xliff:g id="PROCESS">%2$s</xliff:g>) ha violato la norma StrictMode autoimposta."</string>
<string name="smv_process" msgid="5120397012047462446">"Il processo <xliff:g id="PROCESS">%1$s</xliff:g> ha violato la norma StrictMode autoimposta."</string>
<string name="android_upgrading_title" msgid="1584192285441405746">"Upgrade di Android..."</string>
+ <string name="android_start_title" msgid="8418054686415318207">"Avvio di Android…"</string>
<string name="android_upgrading_apk" msgid="7904042682111526169">"Ottimizzazione applicazione <xliff:g id="NUMBER_0">%1$d</xliff:g> di <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
<string name="android_upgrading_starting_apps" msgid="451464516346926713">"Avvio applicazioni."</string>
<string name="android_upgrading_complete" msgid="1405954754112999229">"Conclusione dell\'avvio."</string>
@@ -1776,10 +1783,14 @@
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Richiedi password prima di sbloccare"</string>
<string name="battery_saver_description" msgid="2510530476513605742">"Per aumentare la durata della batteria, la funzione Risparmio energetico riduce le prestazioni del dispositivo e limita vibrazione e gran parte dei dati in background. App di email, messaggi e altre app basate sulla sincronizzazione potrebbero non essere aggiornate se non le apri.\n\nIl risparmio energetico si disattiva automaticamente quando il dispositivo è in carica."</string>
<string name="downtime_condition_summary" msgid="8761776337475705749">"Fino al termine del periodo di inattività previsto per le <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
- <!-- no translation found for zen_mode_duration_minutes_summary:one (3177683545388923234) -->
- <!-- no translation found for zen_mode_duration_minutes_summary:other (2787867221129368935) -->
- <!-- no translation found for zen_mode_duration_hours_summary:one (597194865053253679) -->
- <!-- no translation found for zen_mode_duration_hours_summary:other (2827214920627669898) -->
+ <plurals name="zen_mode_duration_minutes_summary">
+ <item quantity="one" msgid="3177683545388923234">"Per un minuto (fino alle ore <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ <item quantity="other" msgid="2787867221129368935">"Per %1$d minuti (fino alle ore <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ </plurals>
+ <plurals name="zen_mode_duration_hours_summary">
+ <item quantity="one" msgid="597194865053253679">"Per un\'ora (fino alle ore <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ <item quantity="other" msgid="2827214920627669898">"Per %1$d ore (fino alle ore <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ </plurals>
<plurals name="zen_mode_duration_minutes">
<item quantity="one" msgid="9040808414992812341">"Per un minuto"</item>
<item quantity="other" msgid="6924190729213550991">"Per %d minuti"</item>
@@ -1788,7 +1799,7 @@
<item quantity="one" msgid="3480040795582254384">"Per un\'ora"</item>
<item quantity="other" msgid="5408537517529822157">"Per %d ore"</item>
</plurals>
- <!-- no translation found for zen_mode_until (7336308492289875088) -->
- <skip />
+ <string name="zen_mode_until" msgid="7336308492289875088">"Fino alle ore <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
<string name="zen_mode_forever" msgid="4316804956488785559">"Sempre"</string>
+ <string name="toolbar_collapse_description" msgid="2821479483960330739">"Comprimi"</string>
</resources>
diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml
index 6a41a47..71961b5 100644
--- a/core/res/res/values-iw/strings.xml
+++ b/core/res/res/values-iw/strings.xml
@@ -716,8 +716,14 @@
<string name="permdesc_cache_filesystem" msgid="5578967642265550955">"מאפשר לאפליקציה לקרוא ולכתוב במערכת הקבצים של הקבצים השמורים."</string>
<string name="permlab_use_sip" msgid="2052499390128979920">"ביצוע/קבלה של שיחות SIP"</string>
<string name="permdesc_use_sip" msgid="2297804849860225257">"אפשר לאפליקציה לבצע ולקבל שיחות SIP."</string>
- <string name="permlab_register_provider" msgid="2654513709546459553">"רישום של חיבור תקשורת חדש"</string>
- <string name="permdesc_register_provider" msgid="7571533832018681544">"מאפשר לאפליקציה לרשום חיבורי תקשורת חדשים."</string>
+ <!-- no translation found for permlab_register_sim_subscription (3166535485877549177) -->
+ <skip />
+ <!-- no translation found for permdesc_register_sim_subscription (2138909035926222911) -->
+ <skip />
+ <!-- no translation found for permlab_register_call_provider (108102120289029841) -->
+ <skip />
+ <!-- no translation found for permdesc_register_call_provider (7034310263521081388) -->
+ <skip />
<string name="permlab_connection_manager" msgid="1116193254522105375">"ניהול חיבורי תקשורת"</string>
<string name="permdesc_connection_manager" msgid="5925480810356483565">"מאפשר לאפליקציה לנהל חיבורי תקשורת."</string>
<string name="permlab_bind_incall_service" msgid="6773648341975287125">"צור אינטראקציה עם מסך שיחה נכנסת"</string>
@@ -1233,6 +1239,7 @@
<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_apk" msgid="7904042682111526169">"מבצע אופטימיזציה של אפליקציה <xliff:g id="NUMBER_0">%1$d</xliff:g> מתוך <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
<string name="android_upgrading_starting_apps" msgid="451464516346926713">"מפעיל אפליקציות."</string>
<string name="android_upgrading_complete" msgid="1405954754112999229">"מסיים אתחול."</string>
@@ -1776,10 +1783,14 @@
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"בקש סיסמה לפני ביטול הצמדה"</string>
<string name="battery_saver_description" msgid="2510530476513605742">"כדי לעזור בהארכת חיי הסוללה, תכונת \'חיסכון בסוללה\' מצמצמת את פעילות המכשיר ומגבילה את השימוש ברטט וברוב נתוני הרקע. ייתכן שאימייל, שליחת הודעות ואפליקציות אחרות המסתמכות על סנכרון לא יתעדכנו, אלא אם תפתח אותן.\n\nתכונת \'חיסכון בסוללה\' מופסקת אוטומטית כשהמכשיר מחובר לחשמל."</string>
<string name="downtime_condition_summary" msgid="8761776337475705749">"עד לסיום ההשבתה בשעה <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
- <!-- no translation found for zen_mode_duration_minutes_summary:one (3177683545388923234) -->
- <!-- no translation found for zen_mode_duration_minutes_summary:other (2787867221129368935) -->
- <!-- no translation found for zen_mode_duration_hours_summary:one (597194865053253679) -->
- <!-- no translation found for zen_mode_duration_hours_summary:other (2827214920627669898) -->
+ <plurals name="zen_mode_duration_minutes_summary">
+ <item quantity="one" msgid="3177683545388923234">"למשך דקה אחת (עד <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ <item quantity="other" msgid="2787867221129368935">"למשך %1$d דקות (עד <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ </plurals>
+ <plurals name="zen_mode_duration_hours_summary">
+ <item quantity="one" msgid="597194865053253679">"למשך שעה אחת (עד <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ <item quantity="other" msgid="2827214920627669898">"למשך %1$d שעות (עד <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ </plurals>
<plurals name="zen_mode_duration_minutes">
<item quantity="one" msgid="9040808414992812341">"למשך דקה אחת"</item>
<item quantity="other" msgid="6924190729213550991">"למשך %d דקות"</item>
@@ -1788,7 +1799,7 @@
<item quantity="one" msgid="3480040795582254384">"למשך שעה אחת"</item>
<item quantity="other" msgid="5408537517529822157">"למשך %d שעות"</item>
</plurals>
- <!-- no translation found for zen_mode_until (7336308492289875088) -->
- <skip />
+ <string name="zen_mode_until" msgid="7336308492289875088">"עד <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
<string name="zen_mode_forever" msgid="4316804956488785559">"ללא הגבלה"</string>
+ <string name="toolbar_collapse_description" msgid="2821479483960330739">"כווץ"</string>
</resources>
diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml
index 254c7f3..388e8f1 100644
--- a/core/res/res/values-ja/strings.xml
+++ b/core/res/res/values-ja/strings.xml
@@ -716,8 +716,14 @@
<string name="permdesc_cache_filesystem" msgid="5578967642265550955">"キャッシュファイルシステムの読み書きをアプリに許可します。"</string>
<string name="permlab_use_sip" msgid="2052499390128979920">"SIP通話の発着信"</string>
<string name="permdesc_use_sip" msgid="2297804849860225257">"SIP通話の発着信をアプリに許可します。"</string>
- <string name="permlab_register_provider" msgid="2654513709546459553">"新しい通信接続の登録"</string>
- <string name="permdesc_register_provider" msgid="7571533832018681544">"新しい通信接続の登録をアプリに許可します。"</string>
+ <!-- no translation found for permlab_register_sim_subscription (3166535485877549177) -->
+ <skip />
+ <!-- no translation found for permdesc_register_sim_subscription (2138909035926222911) -->
+ <skip />
+ <!-- no translation found for permlab_register_call_provider (108102120289029841) -->
+ <skip />
+ <!-- no translation found for permdesc_register_call_provider (7034310263521081388) -->
+ <skip />
<string name="permlab_connection_manager" msgid="1116193254522105375">"通信接続の管理"</string>
<string name="permdesc_connection_manager" msgid="5925480810356483565">"通信接続の管理をアプリに許可します。"</string>
<string name="permlab_bind_incall_service" msgid="6773648341975287125">"通話画面とのインタラクション"</string>
@@ -1233,6 +1239,7 @@
<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_apk" msgid="7904042682111526169">"<xliff:g id="NUMBER_1">%2$d</xliff:g>個中<xliff:g id="NUMBER_0">%1$d</xliff:g>個のアプリを最適化しています。"</string>
<string name="android_upgrading_starting_apps" msgid="451464516346926713">"アプリを起動しています。"</string>
<string name="android_upgrading_complete" msgid="1405954754112999229">"ブートを終了しています。"</string>
@@ -1776,10 +1783,14 @@
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"オフライン再生を解除する前にパスワードの入力を求める"</string>
<string name="battery_saver_description" msgid="2510530476513605742">"バッテリーを長持ちさせるため、バッテリーセーバーは端末のパフォーマンス、バイブレーション、ほとんどのバックグラウンドデータを制限します。同期を使用するメールやメッセージなどのアプリは起動しないと更新されない場合があります。\n\nバッテリーセーバーは、端末の充電中は自動的にOFFになります。"</string>
<string name="downtime_condition_summary" msgid="8761776337475705749">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g>にダウンロードが終わるまで"</string>
- <!-- no translation found for zen_mode_duration_minutes_summary:one (3177683545388923234) -->
- <!-- no translation found for zen_mode_duration_minutes_summary:other (2787867221129368935) -->
- <!-- no translation found for zen_mode_duration_hours_summary:one (597194865053253679) -->
- <!-- no translation found for zen_mode_duration_hours_summary:other (2827214920627669898) -->
+ <plurals name="zen_mode_duration_minutes_summary">
+ <item quantity="one" msgid="3177683545388923234">"1分間(<xliff:g id="FORMATTEDTIME">%2$s</xliff:g>まで)"</item>
+ <item quantity="other" msgid="2787867221129368935">"%1$d分間(<xliff:g id="FORMATTEDTIME">%2$s</xliff:g>まで)"</item>
+ </plurals>
+ <plurals name="zen_mode_duration_hours_summary">
+ <item quantity="one" msgid="597194865053253679">"1時間(<xliff:g id="FORMATTEDTIME">%2$s</xliff:g>まで)"</item>
+ <item quantity="other" msgid="2827214920627669898">"%1$d時間(<xliff:g id="FORMATTEDTIME">%2$s</xliff:g>まで)"</item>
+ </plurals>
<plurals name="zen_mode_duration_minutes">
<item quantity="one" msgid="9040808414992812341">"1分"</item>
<item quantity="other" msgid="6924190729213550991">"%d分"</item>
@@ -1788,7 +1799,7 @@
<item quantity="one" msgid="3480040795582254384">"1時間"</item>
<item quantity="other" msgid="5408537517529822157">"%d時間"</item>
</plurals>
- <!-- no translation found for zen_mode_until (7336308492289875088) -->
- <skip />
+ <string name="zen_mode_until" msgid="7336308492289875088">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g>まで"</string>
<string name="zen_mode_forever" msgid="4316804956488785559">"制限なし"</string>
+ <string name="toolbar_collapse_description" msgid="2821479483960330739">"折りたたむ"</string>
</resources>
diff --git a/core/res/res/values-ka-rGE/strings.xml b/core/res/res/values-ka-rGE/strings.xml
index d45fb04..fbf3671 100644
--- a/core/res/res/values-ka-rGE/strings.xml
+++ b/core/res/res/values-ka-rGE/strings.xml
@@ -716,14 +716,16 @@
<string name="permdesc_cache_filesystem" msgid="5578967642265550955">"აპებს აძლევს ქეშირებული სისტემური ფაილების წაკითხვისა და მათში ჩანაწერების გაკეთების საშუალებას."</string>
<string name="permlab_use_sip" msgid="2052499390128979920">"SIP ზარების წამოწყება/მიღება"</string>
<string name="permdesc_use_sip" msgid="2297804849860225257">"ნებას რთავს აპს განახორციელოს და მიიღოს SIP ზარები."</string>
- <!-- no translation found for permlab_register_provider (2654513709546459553) -->
+ <!-- no translation found for permlab_register_sim_subscription (3166535485877549177) -->
<skip />
- <!-- no translation found for permdesc_register_provider (7571533832018681544) -->
+ <!-- no translation found for permdesc_register_sim_subscription (2138909035926222911) -->
<skip />
- <!-- no translation found for permlab_connection_manager (1116193254522105375) -->
+ <!-- no translation found for permlab_register_call_provider (108102120289029841) -->
<skip />
- <!-- no translation found for permdesc_connection_manager (5925480810356483565) -->
+ <!-- no translation found for permdesc_register_call_provider (7034310263521081388) -->
<skip />
+ <string name="permlab_connection_manager" msgid="1116193254522105375">"ტელეკომის კავშირების მართვა"</string>
+ <string name="permdesc_connection_manager" msgid="5925480810356483565">"აპს ტელეკომის კავშირების მართვა შეეძლება."</string>
<string name="permlab_bind_incall_service" msgid="6773648341975287125">"ინტერაქცია საუბრის რეჟიმის ეკრანთან"</string>
<string name="permdesc_bind_incall_service" msgid="8343471381323215005">"აპს შეეძლება გაკონტროლება, როდის და როგორ დაინახავს მომხმარებელი საუბრის რეჟიმის ეკრანს."</string>
<string name="permlab_bind_connection_service" msgid="3557341439297014940">"ტელეფონიის სერვისებთან ინტერაქცია"</string>
@@ -1237,6 +1239,7 @@
<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_apk" msgid="7904042682111526169">"მიმდინარეობს აპლიკაციების ოპტიმიზაცია. დასრულებულია <xliff:g id="NUMBER_0">%1$d</xliff:g>, სულ <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
<string name="android_upgrading_starting_apps" msgid="451464516346926713">"აპების ჩართვა"</string>
<string name="android_upgrading_complete" msgid="1405954754112999229">"ჩატვირთვის დასასრული."</string>
@@ -1780,10 +1783,14 @@
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"ფიქსაციის მოხსნამდე პაროლის მოთხოვნა"</string>
<string name="battery_saver_description" msgid="2510530476513605742">"ბატარეის გამძლეობის გასახანგრძლივებლად, ბატარეის დამზოგი ამცირებს თქვენი მოწყობილობის წარმადობას და ზღუდავს ვიბრაციასა და უმეტეს ფონურ მონაცემს. თუ არ განაახლებთ, შეიძლება არ გაიხსნას ელფოსტა, შეტყობინებები და სხვა აპები, რომლებიც სინქრონიზაციაზეა დამოკიდებული.\n\nბატარეის დამზოგი ავტომატურად გამოირთვება, როდესაც თქვენი მოწყობილობა იტენება."</string>
<string name="downtime_condition_summary" msgid="8761776337475705749">"დანამ თქვენი კავშირგარეშე დრო დასრულდებოდეს <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>-ზე"</string>
- <!-- no translation found for zen_mode_duration_minutes_summary:one (3177683545388923234) -->
- <!-- no translation found for zen_mode_duration_minutes_summary:other (2787867221129368935) -->
- <!-- no translation found for zen_mode_duration_hours_summary:one (597194865053253679) -->
- <!-- no translation found for zen_mode_duration_hours_summary:other (2827214920627669898) -->
+ <plurals name="zen_mode_duration_minutes_summary">
+ <item quantity="one" msgid="3177683545388923234">"ერთი წუთის განმავლობაში (<xliff:g id="FORMATTEDTIME">%2$s</xliff:g>-მდე)"</item>
+ <item quantity="other" msgid="2787867221129368935">"%1$d წუთის განმავლობაში (<xliff:g id="FORMATTEDTIME">%2$s</xliff:g>-მდე)"</item>
+ </plurals>
+ <plurals name="zen_mode_duration_hours_summary">
+ <item quantity="one" msgid="597194865053253679">"ერთი საათის განმავლობაში (<xliff:g id="FORMATTEDTIME">%2$s</xliff:g>-მდე)"</item>
+ <item quantity="other" msgid="2827214920627669898">"%1$d საათის განმავლობაში (<xliff:g id="FORMATTEDTIME">%2$s</xliff:g>-მდე)"</item>
+ </plurals>
<plurals name="zen_mode_duration_minutes">
<item quantity="one" msgid="9040808414992812341">"ერთი წუთით"</item>
<item quantity="other" msgid="6924190729213550991">"%d წუთით"</item>
@@ -1792,7 +1799,7 @@
<item quantity="one" msgid="3480040795582254384">"ერთი საათით"</item>
<item quantity="other" msgid="5408537517529822157">"%d საათით"</item>
</plurals>
- <!-- no translation found for zen_mode_until (7336308492289875088) -->
- <skip />
+ <string name="zen_mode_until" msgid="7336308492289875088">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g>-მდე"</string>
<string name="zen_mode_forever" msgid="4316804956488785559">"სამუდამოდ"</string>
+ <string name="toolbar_collapse_description" msgid="2821479483960330739">"აკეცვა"</string>
</resources>
diff --git a/core/res/res/values-kk-rKZ/strings.xml b/core/res/res/values-kk-rKZ/strings.xml
index 7402cc1..b4a322c 100644
--- a/core/res/res/values-kk-rKZ/strings.xml
+++ b/core/res/res/values-kk-rKZ/strings.xml
@@ -716,14 +716,16 @@
<string name="permdesc_cache_filesystem" msgid="5578967642265550955">"Қолданбаға кэш файлдық жүйесін оқуға және оған жазуға рұқсат береді."</string>
<string name="permlab_use_sip" msgid="2052499390128979920">"SIP қоңырауларын шалу/қабылдау"</string>
<string name="permdesc_use_sip" msgid="2297804849860225257">"Қолданбаға SIP қоңырауларын шалуға және қабылдауға рұқсат етеді."</string>
- <!-- no translation found for permlab_register_provider (2654513709546459553) -->
+ <!-- no translation found for permlab_register_sim_subscription (3166535485877549177) -->
<skip />
- <!-- no translation found for permdesc_register_provider (7571533832018681544) -->
+ <!-- no translation found for permdesc_register_sim_subscription (2138909035926222911) -->
<skip />
- <!-- no translation found for permlab_connection_manager (1116193254522105375) -->
+ <!-- no translation found for permlab_register_call_provider (108102120289029841) -->
<skip />
- <!-- no translation found for permdesc_connection_manager (5925480810356483565) -->
+ <!-- no translation found for permdesc_register_call_provider (7034310263521081388) -->
<skip />
+ <string name="permlab_connection_manager" msgid="1116193254522105375">"телекоммуникациялық байланыстарды басқару"</string>
+ <string name="permdesc_connection_manager" msgid="5925480810356483565">"Қолданбаға телекоммуникациялық байланыстарды басқаруға рұқсат етеді."</string>
<string name="permlab_bind_incall_service" msgid="6773648341975287125">"қоңыраудағы экранмен өзара әрекеттесу"</string>
<string name="permdesc_bind_incall_service" msgid="8343471381323215005">"Қолданбаға пайдаланушының қоңырау кезінде экранды қашан және қалай көретінін басқару мүмкіндігін береді."</string>
<string name="permlab_bind_connection_service" msgid="3557341439297014940">"телефония қызметтерімен өзара әрекеттесу"</string>
@@ -1237,6 +1239,7 @@
<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> үрдісі өздігінен күшіне енген ҚатаңРежим ережесін бұзды."</string>
<string name="android_upgrading_title" msgid="1584192285441405746">"Android жаңартылуда…"</string>
+ <string name="android_start_title" msgid="8418054686415318207">"Android іске қосылуда…"</string>
<string name="android_upgrading_apk" msgid="7904042682111526169">"<xliff:g id="NUMBER_1">%2$d</xliff:g> ішінен <xliff:g id="NUMBER_0">%1$d</xliff:g> қолданба оңтайландырылуда."</string>
<string name="android_upgrading_starting_apps" msgid="451464516346926713">"Қолданбалар іске қосылуда."</string>
<string name="android_upgrading_complete" msgid="1405954754112999229">"Қосуды аяқтауда."</string>
@@ -1780,10 +1783,14 @@
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Босату алдында құпия сөзді сұрау"</string>
<string name="battery_saver_description" msgid="2510530476513605742">"Батареяның қызмет мерзімін жақсарту үшін батарея үнемдегіш құрылғының өнімділігін азайтады және діріл мен фондық деректердің көпшілігін шектейді. Синхрондауды қажет ететін электрондық пошта, хабар алмасу және басқа қолданбалар ашқанша жаңартылмауы мүмкін.\n\nБатарея үнемдегіш құрылғы зарядталып жатқанда автоматты түрде өшеді."</string>
<string name="downtime_condition_summary" msgid="8761776337475705749">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g> уақытында әрекетсіздік аяқталғанша"</string>
- <!-- no translation found for zen_mode_duration_minutes_summary:one (3177683545388923234) -->
- <!-- no translation found for zen_mode_duration_minutes_summary:other (2787867221129368935) -->
- <!-- no translation found for zen_mode_duration_hours_summary:one (597194865053253679) -->
- <!-- no translation found for zen_mode_duration_hours_summary:other (2827214920627669898) -->
+ <plurals name="zen_mode_duration_minutes_summary">
+ <item quantity="one" msgid="3177683545388923234">"Бір минут бойы (<xliff:g id="FORMATTEDTIME">%2$s</xliff:g> дейін)"</item>
+ <item quantity="other" msgid="2787867221129368935">"%1$d минут бойы (<xliff:g id="FORMATTEDTIME">%2$s</xliff:g> дейін)"</item>
+ </plurals>
+ <plurals name="zen_mode_duration_hours_summary">
+ <item quantity="one" msgid="597194865053253679">"Бір сағат бойы (<xliff:g id="FORMATTEDTIME">%2$s</xliff:g> дейін)"</item>
+ <item quantity="other" msgid="2827214920627669898">"%1$d сағат бойы (<xliff:g id="FORMATTEDTIME">%2$s</xliff:g> дейін)"</item>
+ </plurals>
<plurals name="zen_mode_duration_minutes">
<item quantity="one" msgid="9040808414992812341">"Бір минут бойы"</item>
<item quantity="other" msgid="6924190729213550991">"%d минут бойы"</item>
@@ -1792,7 +1799,7 @@
<item quantity="one" msgid="3480040795582254384">"Бір сағат бойы"</item>
<item quantity="other" msgid="5408537517529822157">"%d сағат бойы"</item>
</plurals>
- <!-- no translation found for zen_mode_until (7336308492289875088) -->
- <skip />
+ <string name="zen_mode_until" msgid="7336308492289875088">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g> дейін"</string>
<string name="zen_mode_forever" msgid="4316804956488785559">"Белгісіз уақыт бойы"</string>
+ <string name="toolbar_collapse_description" msgid="2821479483960330739">"Тасалау"</string>
</resources>
diff --git a/core/res/res/values-km-rKH/strings.xml b/core/res/res/values-km-rKH/strings.xml
index b6e5c28..94f7f01 100644
--- a/core/res/res/values-km-rKH/strings.xml
+++ b/core/res/res/values-km-rKH/strings.xml
@@ -716,8 +716,14 @@
<string name="permdesc_cache_filesystem" msgid="5578967642265550955">"ឲ្យកម្មវិធីអាន និងសរសេរប្រព័ន្ធឯកសារឃ្លាំងសម្ងាត់។"</string>
<string name="permlab_use_sip" msgid="2052499390128979920">"បង្កើត/ទទួល ការហៅ SIP"</string>
<string name="permdesc_use_sip" msgid="2297804849860225257">"ឲ្យកម្មវិធី បង្កើត និងទទួលការហៅ SIP ។"</string>
- <string name="permlab_register_provider" msgid="2654513709546459553">"ចុះឈ្មោះភ្ជាប់ទូរគមនាគមន៍ថ្មី"</string>
- <string name="permdesc_register_provider" msgid="7571533832018681544">"ឲ្យកម្មវិធីចុះឈ្មោះការភ្ជាប់ទូរគមនាគមន៍ថ្មី។"</string>
+ <!-- no translation found for permlab_register_sim_subscription (3166535485877549177) -->
+ <skip />
+ <!-- no translation found for permdesc_register_sim_subscription (2138909035926222911) -->
+ <skip />
+ <!-- no translation found for permlab_register_call_provider (108102120289029841) -->
+ <skip />
+ <!-- no translation found for permdesc_register_call_provider (7034310263521081388) -->
+ <skip />
<string name="permlab_connection_manager" msgid="1116193254522105375">"គ្រប់គ្រងការភ្ជាប់ទូរគមនាគមន៍"</string>
<string name="permdesc_connection_manager" msgid="5925480810356483565">"ឲ្យកម្មវិធីគ្រប់គ្រងការភ្ជាប់ទូរគមនាគមន៍។"</string>
<string name="permlab_bind_incall_service" msgid="6773648341975287125">"ទាក់ទងជាមួយអេក្រង់ហៅចូល"</string>
@@ -898,7 +904,7 @@
<string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"កូដ PIN មិនត្រឹមត្រូវ។"</string>
<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>
+ <string name="lockscreen_carrier_default" msgid="8963839242565653192">"គ្មានសេវា"</string>
<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>
@@ -1235,6 +1241,7 @@
<string name="smv_application" msgid="3307209192155442829">"កម្មវិធី <xliff:g id="APPLICATION">%1$s</xliff:g> (ដំណើរការ <xliff:g id="PROCESS">%2$s</xliff:g>) បានបំពានគោលនយោបាយរបៀបតឹងរ៉ឹងអនុវត្តដោយខ្លួនឯង។"</string>
<string name="smv_process" msgid="5120397012047462446">"ដំណើរការ <xliff:g id="PROCESS">%1$s</xliff:g> បានបំពានគោលនយោបាយរបៀបតឹងរឹងបង្ខំដោយខ្លួនឯង"</string>
<string name="android_upgrading_title" msgid="1584192285441405746">"Android កំពុងធ្វើបច្ចុប្បន្នភាព..."</string>
+ <string name="android_start_title" msgid="8418054686415318207">"Android កំពុងចាប់ផ្ដើម…"</string>
<string name="android_upgrading_apk" msgid="7904042682111526169">"ធ្វើឲ្យកម្មវិធីប្រសើរឡើង <xliff:g id="NUMBER_0">%1$d</xliff:g> នៃ <xliff:g id="NUMBER_1">%2$d</xliff:g> ។"</string>
<string name="android_upgrading_starting_apps" msgid="451464516346926713">"ចាប់ផ្ដើមកម្មវិធី។"</string>
<string name="android_upgrading_complete" msgid="1405954754112999229">"បញ្ចប់ការចាប់ផ្ដើម។"</string>
@@ -1778,10 +1785,14 @@
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"សួររកពាក្យសម្ងាត់មុនពេលផ្ដាច់"</string>
<string name="battery_saver_description" msgid="2510530476513605742">"ដើម្បីបង្កើនអាយុថ្ម កម្មវិធីសន្សំថ្មកាត់បន្ថយការអនុវត្តឧបករណ៍របស់អ្នក ហើយកម្រិតការញ័រ និងទិន្នន័យផ្ទៃខាងក្រោយ។ អ៊ីមែល, ការផ្ញើសារ និងកម្មវិធីផ្សេងៗទៀតដែលផ្អែកលើការធ្វើសមកាលកម្មមិនអាចធ្វើបច្ចុប្បន្នភាពលុះត្រាតែអ្នកបើកពួកវា។\n\nកម្មវិធីសន្សំថ្មបិទដោយស្វ័យប្រវត្តិពេលឧបករណ៍របស់អ្នកកំពុងបញ្ចូលថ្ម។"</string>
<string name="downtime_condition_summary" msgid="8761776337475705749">"រហូតដល់ម៉ោងសម្រាក ឬរវល់របស់អ្នកបញ្ចប់នៅ <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
- <!-- no translation found for zen_mode_duration_minutes_summary:one (3177683545388923234) -->
- <!-- no translation found for zen_mode_duration_minutes_summary:other (2787867221129368935) -->
- <!-- no translation found for zen_mode_duration_hours_summary:one (597194865053253679) -->
- <!-- no translation found for zen_mode_duration_hours_summary:other (2827214920627669898) -->
+ <plurals name="zen_mode_duration_minutes_summary">
+ <item quantity="one" msgid="3177683545388923234">"សម្រាប់មួយនាទី (រហូតដល់ <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ <item quantity="other" msgid="2787867221129368935">"សម្រាប់ %1$d នាទី (រហូតដល់ <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ </plurals>
+ <plurals name="zen_mode_duration_hours_summary">
+ <item quantity="one" msgid="597194865053253679">"សម្រាប់មួយម៉ោង (រហូតដល់ <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ <item quantity="other" msgid="2827214920627669898">"សម្រាប់ %1$d ម៉ោង (រហូតដល់ <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ </plurals>
<plurals name="zen_mode_duration_minutes">
<item quantity="one" msgid="9040808414992812341">"សម្រាប់មួយនាទី"</item>
<item quantity="other" msgid="6924190729213550991">"សម្រាប់ %d នាទី"</item>
@@ -1790,7 +1801,7 @@
<item quantity="one" msgid="3480040795582254384">"សម្រាប់មួយម៉ោង"</item>
<item quantity="other" msgid="5408537517529822157">"សម្រាប់ %d ម៉ោង"</item>
</plurals>
- <!-- no translation found for zen_mode_until (7336308492289875088) -->
- <skip />
+ <string name="zen_mode_until" msgid="7336308492289875088">"រហូតដល់ <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
<string name="zen_mode_forever" msgid="4316804956488785559">"គ្មានកំណត់"</string>
+ <string name="toolbar_collapse_description" msgid="2821479483960330739">"បង្រួម"</string>
</resources>
diff --git a/core/res/res/values-kn-rIN/strings.xml b/core/res/res/values-kn-rIN/strings.xml
index b23f82f..f8a668b 100644
--- a/core/res/res/values-kn-rIN/strings.xml
+++ b/core/res/res/values-kn-rIN/strings.xml
@@ -716,8 +716,14 @@
<string name="permdesc_cache_filesystem" msgid="5578967642265550955">"ಕ್ಯಾಷ್ ಫೈಲ್ ವ್ಯವಸ್ಥೆಯನ್ನು ಓದಲು ಮತ್ತು ಬರೆಯಲು ಅಪ್ಲಿಕೇಶನ್ ಅನುಮತಿಸುತ್ತದೆ."</string>
<string name="permlab_use_sip" msgid="2052499390128979920">"SIP ಕರೆಗಳನ್ನು ಮಾಡಿ/ಸ್ವೀಕರಿಸಿ"</string>
<string name="permdesc_use_sip" msgid="2297804849860225257">"SIP ಕರೆಗಳನ್ನು ಮಾಡಲು ಮತ್ತು ಸ್ವೀಕರಿಸಲು ಅಪ್ಲಿಕೇಶನ್ಗೆ ಅನುಮತಿಸುತ್ತದೆ."</string>
- <string name="permlab_register_provider" msgid="2654513709546459553">"ಹೊಸ ಟೆಲಿಕಾಂ ಸಂಪರ್ಕವನ್ನು ನೋಂದಣಿ ಮಾಡಿ"</string>
- <string name="permdesc_register_provider" msgid="7571533832018681544">"ಹೊಸ ಟೆಲಿಕಾಂ ಸಂಪರ್ಕಗಳನ್ನು ನೋಂದಣಿ ಮಾಡಲು ಅಪ್ಲಿಕೇಶನ್ ಅವಕಾಶ ಮಾಡಿಕೊಡುತ್ತದೆ."</string>
+ <!-- no translation found for permlab_register_sim_subscription (3166535485877549177) -->
+ <skip />
+ <!-- no translation found for permdesc_register_sim_subscription (2138909035926222911) -->
+ <skip />
+ <!-- no translation found for permlab_register_call_provider (108102120289029841) -->
+ <skip />
+ <!-- no translation found for permdesc_register_call_provider (7034310263521081388) -->
+ <skip />
<string name="permlab_connection_manager" msgid="1116193254522105375">"ಟೆಲಿಕಾಂ ಸಂಪರ್ಕಗಳನ್ನು ನಿರ್ವಹಿಸಿ"</string>
<string name="permdesc_connection_manager" msgid="5925480810356483565">"ಟೆಲಿಕಾಂ ಸಂಪರ್ಕಗಳನ್ನು ನಿರ್ವಹಿಸಲು ಅಪ್ಲಿಕೇಶನ್ ಅವಕಾಶ ಮಾಡಿಕೊಡುತ್ತದೆ."</string>
<string name="permlab_bind_incall_service" msgid="6773648341975287125">"ಒಳ-ಕರೆ ಪರದೆಯ ಮೂಲಕ ಸಂವಹನ ನಡೆಸಿ"</string>
@@ -1233,6 +1239,7 @@
<string name="smv_application" msgid="3307209192155442829">"ಅಪ್ಲಿಕೇಶನ್ <xliff:g id="APPLICATION">%1$s</xliff:g> (ಪ್ರಕ್ರಿಯೆಯು <xliff:g id="PROCESS">%2$s</xliff:g>) ತನ್ನ ಸ್ವಯಂ-ಜಾರಿ ಕಠಿಣ ಮೋಡ್ ನೀತಿಯನ್ನು ಉಲ್ಲಂಘನೆ ಮಾಡಿದೆ."</string>
<string name="smv_process" msgid="5120397012047462446">"<xliff:g id="PROCESS">%1$s</xliff:g> ಪ್ರಕ್ರಿಯೆಯು ತನ್ನ ಸ್ವಯಂ-ಜಾರಿ ಕಠಿಣ ಮೋಡ್ ನೀತಿಯನ್ನು ಉಲ್ಲಂಘನೆ ಮಾಡಿದೆ."</string>
<string name="android_upgrading_title" msgid="1584192285441405746">"Android ಅಪ್ಗ್ರೇಡ್ ಮಾಡಲಾಗುತ್ತಿದೆ…"</string>
+ <string name="android_start_title" msgid="8418054686415318207">"Android ಪ್ರಾರಂಭಿಸಲಾಗುತ್ತಿದೆ…"</string>
<string name="android_upgrading_apk" msgid="7904042682111526169">"<xliff:g id="NUMBER_1">%2$d</xliff:g> ರಲ್ಲಿ <xliff:g id="NUMBER_0">%1$d</xliff:g> ಅಪ್ಲಿಕೇಶನ್ ಆಪ್ಟಿಮೈಸ್ ಮಾಡಲಾಗುತ್ತಿದೆ."</string>
<string name="android_upgrading_starting_apps" msgid="451464516346926713">"ಅಪ್ಲಿಕೇಶನ್ಗಳನ್ನು ಪ್ರಾರಂಭಿಸಲಾಗುತ್ತಿದೆ."</string>
<string name="android_upgrading_complete" msgid="1405954754112999229">"ಬೂಟ್ ಪೂರ್ಣಗೊಳಿಸಲಾಗುತ್ತಿದೆ."</string>
@@ -1776,10 +1783,14 @@
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"ಅನ್ಪಿನ್ ಮಾಡುವುದಕ್ಕೂ ಮೊದಲು ಪಾಸ್ವರ್ಡ್ ಕೇಳಿ"</string>
<string name="battery_saver_description" msgid="2510530476513605742">"ಬ್ಯಾಟರಿ ಬಾಳಿಕೆಯನ್ನು ಹೆಚ್ಚಿಸುವ ನಿಟ್ಟಿನಲ್ಲಿ ಸಹಾಯ ಮಾಡಲು, ಬ್ಯಾಟರಿ ಉಳಿತಾಯವು ನಿಮ್ಮ ಸಾಧನದ ಕಾರ್ಯಕ್ಷಮತೆಯನ್ನು ಕುಂಠಿತಗೊಳಿಸುತ್ತದೆ ಮತ್ತು ವೈಬ್ರೇಷನ್ ಹಾಗೂ ಹೆಚ್ಚಿನ ಹಿನ್ನೆಲೆ ಡೇಟಾವನ್ನು ಸೀಮಿತಗೊಳಿಸುತ್ತದೆ. ಇಮೇಲ್, ಸಂದೇಶ ಕಳುಹಿಸುವಿಕೆ, ಮತ್ತು ಸಿಂಕ್ ಮಾಡುವುದನ್ನು ಅವಲಂಬಿಸಿರುವ ಇತರ ಅಪ್ಲಿಕೇಶನ್ಗಳನ್ನು ನೀವು ತೆರೆಯುವವರೆಗೆ ಅವುಗಳನ್ನು ನವೀಕರಿಸಲಾಗುವುದಿಲ್ಲ.\n\nನಿಮ್ಮ ಸಾಧನವು ಚಾರ್ಜ್ ಆಗುತ್ತಿರುವಾಗ ಬ್ಯಾಟರಿ ಉಳಿತಾಯವು ಸ್ವಯಂಚಾಲಿತವಾಗಿ ಆಫ್ ಆಗುತ್ತದೆ."</string>
<string name="downtime_condition_summary" msgid="8761776337475705749">"ನಿಮ್ಮ ಅಲಭ್ಯತೆ ಕೊನೆಗೊಳ್ಳುವವರೆಗೆ <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
- <!-- no translation found for zen_mode_duration_minutes_summary:one (3177683545388923234) -->
- <!-- no translation found for zen_mode_duration_minutes_summary:other (2787867221129368935) -->
- <!-- no translation found for zen_mode_duration_hours_summary:one (597194865053253679) -->
- <!-- no translation found for zen_mode_duration_hours_summary:other (2827214920627669898) -->
+ <plurals name="zen_mode_duration_minutes_summary">
+ <item quantity="one" msgid="3177683545388923234">"ಒಂದು ನಿಮಿಷದವರೆಗೆ (<xliff:g id="FORMATTEDTIME">%2$s</xliff:g> ವರೆಗೆ)"</item>
+ <item quantity="other" msgid="2787867221129368935">"%1$d ನಿಮಿಷಗಳವರೆಗೆ (<xliff:g id="FORMATTEDTIME">%2$s</xliff:g> ವರೆಗೆ)"</item>
+ </plurals>
+ <plurals name="zen_mode_duration_hours_summary">
+ <item quantity="one" msgid="597194865053253679">"ಒಂದು ಗಂಟೆಯವರೆಗೆ (<xliff:g id="FORMATTEDTIME">%2$s</xliff:g> ವರೆಗೆ)"</item>
+ <item quantity="other" msgid="2827214920627669898">"%1$d ಗಂಟೆಗಳವರೆಗೆ (<xliff:g id="FORMATTEDTIME">%2$s</xliff:g> ವರೆಗೆ)"</item>
+ </plurals>
<plurals name="zen_mode_duration_minutes">
<item quantity="one" msgid="9040808414992812341">"ಒಂದು ನಿಮಿಷದವರೆಗೆ"</item>
<item quantity="other" msgid="6924190729213550991">"%d ನಿಮಿಷಗಳವರೆಗೆ"</item>
@@ -1788,7 +1799,7 @@
<item quantity="one" msgid="3480040795582254384">"ಒಂದು ಗಂಟೆಯವರೆಗೆ"</item>
<item quantity="other" msgid="5408537517529822157">"%d ಗಂಟೆಗಳವರೆಗೆ"</item>
</plurals>
- <!-- no translation found for zen_mode_until (7336308492289875088) -->
- <skip />
+ <string name="zen_mode_until" msgid="7336308492289875088">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g> ವರೆಗೆ"</string>
<string name="zen_mode_forever" msgid="4316804956488785559">"ಅನಿರ್ದಿಷ್ಟವಾಗಿ"</string>
+ <string name="toolbar_collapse_description" msgid="2821479483960330739">"ಸಂಕುಚಿಸು"</string>
</resources>
diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml
index 2411593..89a74b6 100644
--- a/core/res/res/values-ko/strings.xml
+++ b/core/res/res/values-ko/strings.xml
@@ -716,14 +716,16 @@
<string name="permdesc_cache_filesystem" msgid="5578967642265550955">"앱이 캐시 파일 시스템을 읽고 쓸 수 있도록 허용합니다."</string>
<string name="permlab_use_sip" msgid="2052499390128979920">"SIP 통화 발신/수신"</string>
<string name="permdesc_use_sip" msgid="2297804849860225257">"앱에서 SIP 통화를 발신 및 수신하도록 허용"</string>
- <!-- no translation found for permlab_register_provider (2654513709546459553) -->
+ <!-- no translation found for permlab_register_sim_subscription (3166535485877549177) -->
<skip />
- <!-- no translation found for permdesc_register_provider (7571533832018681544) -->
+ <!-- no translation found for permdesc_register_sim_subscription (2138909035926222911) -->
<skip />
- <!-- no translation found for permlab_connection_manager (1116193254522105375) -->
+ <!-- no translation found for permlab_register_call_provider (108102120289029841) -->
<skip />
- <!-- no translation found for permdesc_connection_manager (5925480810356483565) -->
+ <!-- no translation found for permdesc_register_call_provider (7034310263521081388) -->
<skip />
+ <string name="permlab_connection_manager" msgid="1116193254522105375">"통신 연결 관리"</string>
+ <string name="permdesc_connection_manager" msgid="5925480810356483565">"앱이 통신 연결을 관리할 수 있게 허용합니다."</string>
<string name="permlab_bind_incall_service" msgid="6773648341975287125">"통화 화면과 상호작용"</string>
<string name="permdesc_bind_incall_service" msgid="8343471381323215005">"앱에서 사용자가 통화 화면을 보는 시기와 방법을 제어하도록 허용합니다."</string>
<string name="permlab_bind_connection_service" msgid="3557341439297014940">"전화 서비스와 상호 작용"</string>
@@ -1237,6 +1239,7 @@
<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_apk" msgid="7904042682111526169">"앱 <xliff:g id="NUMBER_1">%2$d</xliff:g>개 중 <xliff:g id="NUMBER_0">%1$d</xliff:g>개 최적화 중"</string>
<string name="android_upgrading_starting_apps" msgid="451464516346926713">"앱을 시작하는 중입니다."</string>
<string name="android_upgrading_complete" msgid="1405954754112999229">"부팅 완료"</string>
@@ -1643,7 +1646,7 @@
<string name="accessibility_enabled" msgid="1381972048564547685">"접근성을 사용 설정했습니다."</string>
<string name="enable_accessibility_canceled" msgid="3833923257966635673">"접근성이 취소되었습니다."</string>
<string name="user_switched" msgid="3768006783166984410">"현재 사용자는 <xliff:g id="NAME">%1$s</xliff:g>님입니다."</string>
- <string name="user_switching_message" msgid="2871009331809089783">"<xliff:g id="NAME">%1$s</xliff:g>님으로 전환하는 중…"</string>
+ <string name="user_switching_message" msgid="2871009331809089783">"<xliff:g id="NAME">%1$s</xliff:g>(으)로 전환하는 중…"</string>
<string name="owner_name" msgid="2716755460376028154">"소유자"</string>
<string name="error_message_title" msgid="4510373083082500195">"오류"</string>
<string name="error_message_change_not_allowed" msgid="1347282344200417578">"관리자가 이 변경을 허용하지 않습니다."</string>
@@ -1780,10 +1783,14 @@
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"고정 해제 이전에 비밀번호 요청"</string>
<string name="battery_saver_description" msgid="2510530476513605742">"배터리 수명을 개선하기 위해 배터리 세이버에서는 기기의 성능을 줄이고 진동과 대부분의 백그라운드 데이터를 제한합니다. 동기화가 필요한 이메일, 메시지, 기타 앱은 열어야 업데이트됩니다.\n\n기기를 충전하는 중에는 배터리 세이버가 자동으로 사용 중지됩니다."</string>
<string name="downtime_condition_summary" msgid="8761776337475705749">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g>에 정지가 종료될 때까지"</string>
- <!-- no translation found for zen_mode_duration_minutes_summary:one (3177683545388923234) -->
- <!-- no translation found for zen_mode_duration_minutes_summary:other (2787867221129368935) -->
- <!-- no translation found for zen_mode_duration_hours_summary:one (597194865053253679) -->
- <!-- no translation found for zen_mode_duration_hours_summary:other (2827214920627669898) -->
+ <plurals name="zen_mode_duration_minutes_summary">
+ <item quantity="one" msgid="3177683545388923234">"1분(<xliff:g id="FORMATTEDTIME">%2$s</xliff:g>까지)"</item>
+ <item quantity="other" msgid="2787867221129368935">"%1$d분(<xliff:g id="FORMATTEDTIME">%2$s</xliff:g>까지)"</item>
+ </plurals>
+ <plurals name="zen_mode_duration_hours_summary">
+ <item quantity="one" msgid="597194865053253679">"1시간(<xliff:g id="FORMATTEDTIME">%2$s</xliff:g>까지)"</item>
+ <item quantity="other" msgid="2827214920627669898">"%1$d시간(<xliff:g id="FORMATTEDTIME">%2$s</xliff:g>까지)"</item>
+ </plurals>
<plurals name="zen_mode_duration_minutes">
<item quantity="one" msgid="9040808414992812341">"1분 동안"</item>
<item quantity="other" msgid="6924190729213550991">"%d분 동안"</item>
@@ -1792,7 +1799,7 @@
<item quantity="one" msgid="3480040795582254384">"1시간 동안"</item>
<item quantity="other" msgid="5408537517529822157">"%d시간 동안"</item>
</plurals>
- <!-- no translation found for zen_mode_until (7336308492289875088) -->
- <skip />
+ <string name="zen_mode_until" msgid="7336308492289875088">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g>까지"</string>
<string name="zen_mode_forever" msgid="4316804956488785559">"무제한"</string>
+ <string name="toolbar_collapse_description" msgid="2821479483960330739">"접기"</string>
</resources>
diff --git a/core/res/res/values-ky-rKG/strings.xml b/core/res/res/values-ky-rKG/strings.xml
index 5f34b9d..df87e82 100644
--- a/core/res/res/values-ky-rKG/strings.xml
+++ b/core/res/res/values-ky-rKG/strings.xml
@@ -926,14 +926,16 @@
<string name="permdesc_cache_filesystem" msgid="5578967642265550955">"Колдонмого кэш файл тутумун окуу жана жазуу мүмкүнчүлүгүн берет."</string>
<string name="permlab_use_sip" msgid="2052499390128979920">"SIP чалууларын жасоо/кабыл алуу"</string>
<string name="permdesc_use_sip" msgid="2297804849860225257">"Колдонмонун SIP чалууларын жасап жана кабыл алуусуна жол ачат."</string>
- <!-- no translation found for permlab_register_provider (2654513709546459553) -->
+ <!-- no translation found for permlab_register_sim_subscription (3166535485877549177) -->
<skip />
- <!-- no translation found for permdesc_register_provider (7571533832018681544) -->
+ <!-- no translation found for permdesc_register_sim_subscription (2138909035926222911) -->
<skip />
- <!-- no translation found for permlab_connection_manager (1116193254522105375) -->
+ <!-- no translation found for permlab_register_call_provider (108102120289029841) -->
<skip />
- <!-- no translation found for permdesc_connection_manager (5925480810356483565) -->
+ <!-- no translation found for permdesc_register_call_provider (7034310263521081388) -->
<skip />
+ <string name="permlab_connection_manager" msgid="1116193254522105375">"телеком туташууларын башкаруу"</string>
+ <string name="permdesc_connection_manager" msgid="5925480810356483565">"Колдонмого телеком туташууларын башкаруу мүмкүнчүлүгүн берет."</string>
<string name="permlab_bind_incall_service" msgid="6773648341975287125">"чалуу экраны менен байланыштыруу"</string>
<string name="permdesc_bind_incall_service" msgid="8343471381323215005">"Колдонмого чалуу экраны качан жана кандай көрүнө тургандыгын башкаруу мүмкүнчүлүгүн берет."</string>
<string name="permlab_bind_connection_service" msgid="3557341439297014940">"телефония кызматтары"</string>
@@ -1597,6 +1599,7 @@
<!-- no translation found for smv_process (5120397012047462446) -->
<skip />
<string name="android_upgrading_title" msgid="1584192285441405746">"Android жаңыртылууда…"</string>
+ <string name="android_start_title" msgid="8418054686415318207">"Android жүргүзүлүүдө…"</string>
<string name="android_upgrading_apk" msgid="7904042682111526169">"<xliff:g id="NUMBER_1">%2$d</xliff:g> ичинен <xliff:g id="NUMBER_0">%1$d</xliff:g> колдонмо ыңгайлаштырылууда."</string>
<string name="android_upgrading_starting_apps" msgid="451464516346926713">"Колдонмолорду иштетип баштоо"</string>
<string name="android_upgrading_complete" msgid="1405954754112999229">"Жүктөө аякталууда."</string>
@@ -2260,10 +2263,14 @@
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Бошотуудан мурун сырсөз суралсын"</string>
<string name="battery_saver_description" msgid="2510530476513605742">"Батарея өмүрүн узартууга жардамдашуу үчүн, батарея үнөмдөгүч түзмөгүңүздүн өндүрүмдүүлүгүн азайтып, дирилдөөнү жана көпчүлүк фон дайындарын чектейт. Email, билдирүү жазуу жана башка шайкештирүүгө көз каранды колдонмолор, аларды ачмайыңызча жаңыртылбашы мүмкүн.\n\nТүзмөгүңүз кубатталып жатканда батарея үнөмдөгүч автоматтык түрдө өчөт."</string>
<string name="downtime_condition_summary" msgid="8761776337475705749">"Иштебей турган абал <xliff:g id="FORMATTEDTIME">%1$s</xliff:g> аяктамайынча"</string>
- <!-- no translation found for zen_mode_duration_minutes_summary:one (3177683545388923234) -->
- <!-- no translation found for zen_mode_duration_minutes_summary:other (2787867221129368935) -->
- <!-- no translation found for zen_mode_duration_hours_summary:one (597194865053253679) -->
- <!-- no translation found for zen_mode_duration_hours_summary:other (2827214920627669898) -->
+ <plurals name="zen_mode_duration_minutes_summary">
+ <item quantity="one" msgid="3177683545388923234">"Бир мүнөткө (<xliff:g id="FORMATTEDTIME">%2$s</xliff:g> чейин)"</item>
+ <item quantity="other" msgid="2787867221129368935">"%1$d мүнөткө (<xliff:g id="FORMATTEDTIME">%2$s</xliff:g> чейин)"</item>
+ </plurals>
+ <plurals name="zen_mode_duration_hours_summary">
+ <item quantity="one" msgid="597194865053253679">"Бир саатка (<xliff:g id="FORMATTEDTIME">%2$s</xliff:g> чейин)"</item>
+ <item quantity="other" msgid="2827214920627669898">"%1$d саатка (<xliff:g id="FORMATTEDTIME">%2$s</xliff:g> чейин)"</item>
+ </plurals>
<plurals name="zen_mode_duration_minutes">
<item quantity="one" msgid="9040808414992812341">"Бир мүнөткө"</item>
<item quantity="other" msgid="6924190729213550991">"%d мүнөткө"</item>
@@ -2272,7 +2279,7 @@
<item quantity="one" msgid="3480040795582254384">"Бир саатка"</item>
<item quantity="other" msgid="5408537517529822157">"%d саатка"</item>
</plurals>
- <!-- no translation found for zen_mode_until (7336308492289875088) -->
- <skip />
+ <string name="zen_mode_until" msgid="7336308492289875088">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g> чейин"</string>
<string name="zen_mode_forever" msgid="4316804956488785559">"Белгисиз"</string>
+ <string name="toolbar_collapse_description" msgid="2821479483960330739">"Жыйнап коюу"</string>
</resources>
diff --git a/core/res/res/values-lo-rLA/strings.xml b/core/res/res/values-lo-rLA/strings.xml
index 719717b..daed8b6 100644
--- a/core/res/res/values-lo-rLA/strings.xml
+++ b/core/res/res/values-lo-rLA/strings.xml
@@ -716,14 +716,16 @@
<string name="permdesc_cache_filesystem" msgid="5578967642265550955">"ອະນຸຍາດໃຫ້ແອັບຯ ອ່ານ ແລະຂຽນ ລະບົບໄຟລ໌ແຄດ."</string>
<string name="permlab_use_sip" msgid="2052499390128979920">"ຮັບສາຍ/ໂທອອກ ຜ່ານ SIP"</string>
<string name="permdesc_use_sip" msgid="2297804849860225257">"ອະນຸຍາດໃຫ້ແອັບຯສາມາດຮັບສາຍ ແລະໂທອອກຜ່ານ SIP ໄດ້"</string>
- <!-- no translation found for permlab_register_provider (2654513709546459553) -->
+ <!-- no translation found for permlab_register_sim_subscription (3166535485877549177) -->
<skip />
- <!-- no translation found for permdesc_register_provider (7571533832018681544) -->
+ <!-- no translation found for permdesc_register_sim_subscription (2138909035926222911) -->
<skip />
- <!-- no translation found for permlab_connection_manager (1116193254522105375) -->
+ <!-- no translation found for permlab_register_call_provider (108102120289029841) -->
<skip />
- <!-- no translation found for permdesc_connection_manager (5925480810356483565) -->
+ <!-- no translation found for permdesc_register_call_provider (7034310263521081388) -->
<skip />
+ <string name="permlab_connection_manager" msgid="1116193254522105375">"ຈັດການການເຊື່ອມຕໍ່ໂທລະຄົມມະນາຄົມ"</string>
+ <string name="permdesc_connection_manager" msgid="5925480810356483565">"ອະນຸຍາດໃຫ້ແອັບຯຈັດການການເຊື່ອມຕໍ່ໂທລະຄົມມະນາຄົມ."</string>
<string name="permlab_bind_incall_service" msgid="6773648341975287125">"ໂຕ້ຕອບກັບໜ້າຈໍການໂທ"</string>
<string name="permdesc_bind_incall_service" msgid="8343471381323215005">"ອະນຸຍາດໃຫ້ແອັບຯຄວບຄຸມເວລາ ແລະວິທີການທີ່ຜູ່ໃຊ້ເຫັນໜ້າຈໍການໂທໄດ້."</string>
<string name="permlab_bind_connection_service" msgid="3557341439297014940">"ສັ່ງບໍລິການໂທລະສັບ"</string>
@@ -1237,6 +1239,7 @@
<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_apk" msgid="7904042682111526169">"ກຳລັງປັບປຸງປະສິດທິພາບແອັບຯທີ <xliff:g id="NUMBER_0">%1$d</xliff:g> ຈາກທັງໝົດ <xliff:g id="NUMBER_1">%2$d</xliff:g> ແອັບຯ."</string>
<string name="android_upgrading_starting_apps" msgid="451464516346926713">"ກຳລັງເປີດແອັບຯ."</string>
<string name="android_upgrading_complete" msgid="1405954754112999229">"ກຳລັງສຳເລັດການເປີດລະບົບ."</string>
@@ -1780,10 +1783,14 @@
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"ຖາມຫາລະຫັດຜ່ານກ່ອນຍົກເລີກການປັກໝຸດ"</string>
<string name="battery_saver_description" msgid="2510530476513605742">"ເພື່ອຊ່ວຍປັບປຸງອາຍຸແບັດເຕີຣີ, ໂຕປະຢັດແບັດເຕີຣີຈະຫຼຸດປະສິດທິພາບຂອງອຸປະກອນທ່ານລົງ ແລະຈຳກັດການສັ່ນເຕືອນ ຮວມເຖິງຂໍ້ມູນພື້ນຫຼັງສ່ວນໃຫຍ່ນຳ. ອີເມວ, ການສົ່ງຂໍ້ຄວາມ ແລະແອັບຯອື່ນໆທີ່ອີງອາໃສການຊິ້ງຂໍ້ມູນອາດບໍ່ມີການອັບເດດຈົນກວ່າທ່ານຈະເປີດພວກມັນຂຶ້ນມາ.\n\nໂຕປະຢັດແບັດເຕີຣີຈະປິດໂດຍອັດຕະໂນມັດເມື່ອມີອຸປະກອນຖືກສາກໄຟ."</string>
<string name="downtime_condition_summary" msgid="8761776337475705749">"ຈົນກວ່າດາວທາມຂອງທ່ານຈະສິ້ນສຸດທີ່ <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
- <!-- no translation found for zen_mode_duration_minutes_summary:one (3177683545388923234) -->
- <!-- no translation found for zen_mode_duration_minutes_summary:other (2787867221129368935) -->
- <!-- no translation found for zen_mode_duration_hours_summary:one (597194865053253679) -->
- <!-- no translation found for zen_mode_duration_hours_summary:other (2827214920627669898) -->
+ <plurals name="zen_mode_duration_minutes_summary">
+ <item quantity="one" msgid="3177683545388923234">"ເປັນເວລາ 1 ນາທີ (ຈົນຮອດ <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ <item quantity="other" msgid="2787867221129368935">"ເປັນເວລາ %1$d ນາທີ (ຈົນຮອດ <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ </plurals>
+ <plurals name="zen_mode_duration_hours_summary">
+ <item quantity="one" msgid="597194865053253679">"ເປັນເວລາ 1 ຊົ່ວໂມງ (ຈົນຮອດ <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ <item quantity="other" msgid="2827214920627669898">"ເປັນເວລາ %1$d ຊົ່ວໂມງ (ຈົນຮອດ <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ </plurals>
<plurals name="zen_mode_duration_minutes">
<item quantity="one" msgid="9040808414992812341">"ເປັນເວລານຶ່ງນາທີ"</item>
<item quantity="other" msgid="6924190729213550991">"ເປັນເວລາ %d ນາທີ"</item>
@@ -1792,7 +1799,7 @@
<item quantity="one" msgid="3480040795582254384">"ເປັນເວລານຶ່ງຊົ່ວໂມງ"</item>
<item quantity="other" msgid="5408537517529822157">"ເປັນເວລາ %d ຊົ່ວໂມງ"</item>
</plurals>
- <!-- no translation found for zen_mode_until (7336308492289875088) -->
- <skip />
+ <string name="zen_mode_until" msgid="7336308492289875088">"ຈົນຮອດ <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
<string name="zen_mode_forever" msgid="4316804956488785559">"ຢ່າງບໍ່ມີກຳນົດ"</string>
+ <string name="toolbar_collapse_description" msgid="2821479483960330739">"ຫຍໍ້"</string>
</resources>
diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml
index f6e05dc..ad841ea 100644
--- a/core/res/res/values-lt/strings.xml
+++ b/core/res/res/values-lt/strings.xml
@@ -716,8 +716,14 @@
<string name="permdesc_cache_filesystem" msgid="5578967642265550955">"Leidžiama programai skaityti talpyklos failų sistemą ir į ją rašyti."</string>
<string name="permlab_use_sip" msgid="2052499390128979920">"skambinti / priimti SIP skambučius"</string>
<string name="permdesc_use_sip" msgid="2297804849860225257">"Leidžiama programai skambinti ir priimti SIP skambučius."</string>
- <string name="permlab_register_provider" msgid="2654513709546459553">"registruoti naujus telekomunikacijų ryšius"</string>
- <string name="permdesc_register_provider" msgid="7571533832018681544">"Programai leidžiama registruoti naujus telekomunikacijų ryšius."</string>
+ <!-- no translation found for permlab_register_sim_subscription (3166535485877549177) -->
+ <skip />
+ <!-- no translation found for permdesc_register_sim_subscription (2138909035926222911) -->
+ <skip />
+ <!-- no translation found for permlab_register_call_provider (108102120289029841) -->
+ <skip />
+ <!-- no translation found for permdesc_register_call_provider (7034310263521081388) -->
+ <skip />
<string name="permlab_connection_manager" msgid="1116193254522105375">"tvarkyti telekomunikacijų ryšius"</string>
<string name="permdesc_connection_manager" msgid="5925480810356483565">"Programai leidžiama tvarkyti telekomunikacijų ryšius."</string>
<string name="permlab_bind_incall_service" msgid="6773648341975287125">"sąveika su gaunamojo skambučio ekranu"</string>
@@ -1233,6 +1239,7 @@
<string name="smv_application" msgid="3307209192155442829">"Programa „<xliff:g id="APPLICATION">%1$s</xliff:g>“ (procesas „<xliff:g id="PROCESS">%2$s</xliff:g>“) pažeidė savo vykdomą „StrictMode“ politiką."</string>
<string name="smv_process" msgid="5120397012047462446">"„<xliff:g id="PROCESS">%1$s</xliff:g>“ procesas pažeidė savo vykdomą „StrictMode“ politiką."</string>
<string name="android_upgrading_title" msgid="1584192285441405746">"„Android“ naujovinama..."</string>
+ <string name="android_start_title" msgid="8418054686415318207">"Paleidžiama „Android“…"</string>
<string name="android_upgrading_apk" msgid="7904042682111526169">"Optimizuojama <xliff:g id="NUMBER_0">%1$d</xliff:g> progr. iš <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
<string name="android_upgrading_starting_apps" msgid="451464516346926713">"Paleidžiamos programos."</string>
<string name="android_upgrading_complete" msgid="1405954754112999229">"Užbaigiamas paleidimas."</string>
@@ -1776,10 +1783,14 @@
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Prašyti slaptažodžio prieš atsegant"</string>
<string name="battery_saver_description" msgid="2510530476513605742">"Siekiant pailginti akumuliatoriaus veikimo laiką, Akumuliatoriaus tausojimo priemonė sumažina įrenginio našumą ir apriboja vibravimą bei daugumą foninių duomenų. El. paštas, pranešimų siuntimas ir kitos programos, kurios veikia sinchronizavimo pagrindu, gali nebūti atnaujintos, nebent jas atidarysite.\n\nKraunant įrenginį Akumuliatoriaus tausojimo priemonė automatiškai išjungiama."</string>
<string name="downtime_condition_summary" msgid="8761776337475705749">"Kol jūsų prastova baigsis <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
- <!-- no translation found for zen_mode_duration_minutes_summary:one (3177683545388923234) -->
- <!-- no translation found for zen_mode_duration_minutes_summary:other (2787867221129368935) -->
- <!-- no translation found for zen_mode_duration_hours_summary:one (597194865053253679) -->
- <!-- no translation found for zen_mode_duration_hours_summary:other (2827214920627669898) -->
+ <plurals name="zen_mode_duration_minutes_summary">
+ <item quantity="one" msgid="3177683545388923234">"Vieną minutę (iki <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ <item quantity="other" msgid="2787867221129368935">"%1$d min. (iki <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ </plurals>
+ <plurals name="zen_mode_duration_hours_summary">
+ <item quantity="one" msgid="597194865053253679">"Vieną valandą (iki <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ <item quantity="other" msgid="2827214920627669898">"%1$d val. (iki <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ </plurals>
<plurals name="zen_mode_duration_minutes">
<item quantity="one" msgid="9040808414992812341">"1 min."</item>
<item quantity="other" msgid="6924190729213550991">"%d min."</item>
@@ -1788,7 +1799,7 @@
<item quantity="one" msgid="3480040795582254384">"1 val."</item>
<item quantity="other" msgid="5408537517529822157">"%d val."</item>
</plurals>
- <!-- no translation found for zen_mode_until (7336308492289875088) -->
- <skip />
+ <string name="zen_mode_until" msgid="7336308492289875088">"Iki <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
<string name="zen_mode_forever" msgid="4316804956488785559">"Neapibrėžta"</string>
+ <string name="toolbar_collapse_description" msgid="2821479483960330739">"Sutraukti"</string>
</resources>
diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml
index 72ecf59..f9587bd 100644
--- a/core/res/res/values-lv/strings.xml
+++ b/core/res/res/values-lv/strings.xml
@@ -716,8 +716,14 @@
<string name="permdesc_cache_filesystem" msgid="5578967642265550955">"Ļauj lietotnei lasīt un rakstīt kešatmiņas failu sistēmā."</string>
<string name="permlab_use_sip" msgid="2052499390128979920">"SIP zvanu veikšana/saņemšana"</string>
<string name="permdesc_use_sip" msgid="2297804849860225257">"Ļauj lietotnei veikt un saņemt SIP zvanus."</string>
- <string name="permlab_register_provider" msgid="2654513709546459553">"jauna telekomunikācijas savienojuma reģistrēšana"</string>
- <string name="permdesc_register_provider" msgid="7571533832018681544">"Ļauj lietotnei reģistrēt jaunus telekomunikācijas savienojumus."</string>
+ <!-- no translation found for permlab_register_sim_subscription (3166535485877549177) -->
+ <skip />
+ <!-- no translation found for permdesc_register_sim_subscription (2138909035926222911) -->
+ <skip />
+ <!-- no translation found for permlab_register_call_provider (108102120289029841) -->
+ <skip />
+ <!-- no translation found for permdesc_register_call_provider (7034310263521081388) -->
+ <skip />
<string name="permlab_connection_manager" msgid="1116193254522105375">"telekomunikācijas savienojumu pārvaldība"</string>
<string name="permdesc_connection_manager" msgid="5925480810356483565">"Ļauj lietotnei pārvaldīt telekomunikācijas savienojumus."</string>
<string name="permlab_bind_incall_service" msgid="6773648341975287125">"Mijiedarboties ar zvana laikā rādītu ekrānu"</string>
@@ -1233,6 +1239,7 @@
<string name="smv_application" msgid="3307209192155442829">"Lietotne <xliff:g id="APPLICATION">%1$s</xliff:g> (process <xliff:g id="PROCESS">%2$s</xliff:g>) ir pārkāpusi savu pašieviesto StrictMode politiku."</string>
<string name="smv_process" msgid="5120397012047462446">"Process <xliff:g id="PROCESS">%1$s</xliff:g> ir pārkāpis savu pašieviesto StrictMode politiku."</string>
<string name="android_upgrading_title" msgid="1584192285441405746">"Notiek Android jaunināšana..."</string>
+ <string name="android_start_title" msgid="8418054686415318207">"Notiek Android palaišana…"</string>
<string name="android_upgrading_apk" msgid="7904042682111526169">"Tiek optimizēta <xliff:g id="NUMBER_0">%1$d</xliff:g>. lietotne no <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
<string name="android_upgrading_starting_apps" msgid="451464516346926713">"Notiek lietotņu palaišana."</string>
<string name="android_upgrading_complete" msgid="1405954754112999229">"Tiek pabeigta sāknēšana."</string>
@@ -1776,10 +1783,14 @@
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Pirms atspraušanas pieprasīt paroli"</string>
<string name="battery_saver_description" msgid="2510530476513605742">"Lai paildzinātu akumulatora darbības laiku, akumulatora enerģijas taupīšanas režīmā tiks pazemināta ierīces veiktspēja, samazināta vibrācija un ierobežota liela daļa fona datu. E-pasta, ziņojumapmaiņas un citas lietotnes, kas regulāri tiek sinhronizētas, tiks atjauninātas tikai tad, ja tās atvērsiet.\n\nIerīces uzlādes laikā akumulatora jaudas taupīšana tiek izslēgta automātiski."</string>
<string name="downtime_condition_summary" msgid="8761776337475705749">"Līdz beigsies dīkstāve (<xliff:g id="FORMATTEDTIME">%1$s</xliff:g>)"</string>
- <!-- no translation found for zen_mode_duration_minutes_summary:one (3177683545388923234) -->
- <!-- no translation found for zen_mode_duration_minutes_summary:other (2787867221129368935) -->
- <!-- no translation found for zen_mode_duration_hours_summary:one (597194865053253679) -->
- <!-- no translation found for zen_mode_duration_hours_summary:other (2827214920627669898) -->
+ <plurals name="zen_mode_duration_minutes_summary">
+ <item quantity="one" msgid="3177683545388923234">"Vienu minūti (līdz <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ <item quantity="other" msgid="2787867221129368935">"%1$d minūtes (līdz <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ </plurals>
+ <plurals name="zen_mode_duration_hours_summary">
+ <item quantity="one" msgid="597194865053253679">"Vienu stundu (līdz <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ <item quantity="other" msgid="2827214920627669898">"%1$d stundas (līdz <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ </plurals>
<plurals name="zen_mode_duration_minutes">
<item quantity="one" msgid="9040808414992812341">"Vienu minūti"</item>
<item quantity="other" msgid="6924190729213550991">"%d min"</item>
@@ -1788,7 +1799,7 @@
<item quantity="one" msgid="3480040795582254384">"Vienu stundu"</item>
<item quantity="other" msgid="5408537517529822157">"%d h"</item>
</plurals>
- <!-- no translation found for zen_mode_until (7336308492289875088) -->
- <skip />
+ <string name="zen_mode_until" msgid="7336308492289875088">"Līdz <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
<string name="zen_mode_forever" msgid="4316804956488785559">"Uz nenoteiktu laiku"</string>
+ <string name="toolbar_collapse_description" msgid="2821479483960330739">"Sakļaut"</string>
</resources>
diff --git a/core/res/res/values-mcc204-mnc04/config.xml b/core/res/res/values-mcc204-mnc04/config.xml
index 3c03814..d7484e1 100644
--- a/core/res/res/values-mcc204-mnc04/config.xml
+++ b/core/res/res/values-mcc204-mnc04/config.xml
@@ -31,4 +31,11 @@
<item>"*611:+19085594899,BAE0000000000000"</item>
<item>"*86:+1MDN,BAE0000000000000"</item>
</string-array>
+
+ <!-- Flag indicating whether strict threshold is used, or lenient threshold is used,
+ when evaluating RSRP for LTE antenna bar display
+ 0. Strict threshold
+ 1. Lenient threshold
+ -->
+ <integer name="config_LTE_RSRP_threshold_type">0</integer>
</resources>
diff --git a/core/res/res/values-mcc311-mnc480/config.xml b/core/res/res/values-mcc311-mnc480/config.xml
index d0a57b3..8cb2928 100644
--- a/core/res/res/values-mcc311-mnc480/config.xml
+++ b/core/res/res/values-mcc311-mnc480/config.xml
@@ -49,4 +49,11 @@
<item>"*611:+19085594899,"</item>
<item>"*86:+1MDN,"</item>
</string-array>
+
+ <!-- Flag indicating whether strict threshold is used, or lenient threshold is used,
+ when evaluating RSRP for LTE antenna bar display
+ 0. Strict threshold
+ 1. Lenient threshold
+ -->
+ <integer name="config_LTE_RSRP_threshold_type">0</integer>
</resources>
diff --git a/core/res/res/values-mk-rMK/strings.xml b/core/res/res/values-mk-rMK/strings.xml
index 58ee5ec..d01a18b 100644
--- a/core/res/res/values-mk-rMK/strings.xml
+++ b/core/res/res/values-mk-rMK/strings.xml
@@ -716,8 +716,14 @@
<string name="permdesc_cache_filesystem" msgid="5578967642265550955">"Дозволува апликацијата да чита и да пишува кеш систем на датотеки."</string>
<string name="permlab_use_sip" msgid="2052499390128979920">"остварувај/примај повици преку СИП"</string>
<string name="permdesc_use_sip" msgid="2297804849860225257">"Дозволува апликацијата да остварува и прима повици преку СИП."</string>
- <string name="permlab_register_provider" msgid="2654513709546459553">"регистрира нови телекомуникациски врски"</string>
- <string name="permdesc_register_provider" msgid="7571533832018681544">"Дозволува апликацијата да регистрира нови телекомуникациски врски."</string>
+ <!-- no translation found for permlab_register_sim_subscription (3166535485877549177) -->
+ <skip />
+ <!-- no translation found for permdesc_register_sim_subscription (2138909035926222911) -->
+ <skip />
+ <!-- no translation found for permlab_register_call_provider (108102120289029841) -->
+ <skip />
+ <!-- no translation found for permdesc_register_call_provider (7034310263521081388) -->
+ <skip />
<string name="permlab_connection_manager" msgid="1116193254522105375">"управува со телекомуникациски врски"</string>
<string name="permdesc_connection_manager" msgid="5925480810356483565">"Дозволува апликацијата да управува со телекомуникациски врски."</string>
<string name="permlab_bind_incall_service" msgid="6773648341975287125">"комуницирај со екран на дојдовен повик"</string>
@@ -1233,6 +1239,7 @@
<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> ја прекрши својата самонаметната политика на строг режим."</string>
<string name="android_upgrading_title" msgid="1584192285441405746">"Android се ажурира…"</string>
+ <string name="android_start_title" msgid="8418054686415318207">"Android стартува…"</string>
<string name="android_upgrading_apk" msgid="7904042682111526169">"Се оптимизира апликација <xliff:g id="NUMBER_0">%1$d</xliff:g> од <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
<string name="android_upgrading_starting_apps" msgid="451464516346926713">"Се стартуваат апликациите."</string>
<string name="android_upgrading_complete" msgid="1405954754112999229">"Подигањето завршува."</string>
@@ -1778,10 +1785,14 @@
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Прашај за лозинка пред откачување"</string>
<string name="battery_saver_description" msgid="2510530476513605742">"За да помогне во подобрување на трајноста на батеријата, штедачот на батерија го намалува учинокот на уредот и ги ограничува вибрациите и повеќето податоци во заднина. Е-поштата, испраќањето пораки и другите апликации кои се потпираат на синхронизирање може да не се ажурираат освен ако не ги отворите.\n\nШтедачот на батерија автоматски се исклучува кога уредот се полни."</string>
<string name="downtime_condition_summary" msgid="8761776337475705749">"Додека не заврши паузата во <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
- <!-- no translation found for zen_mode_duration_minutes_summary:one (3177683545388923234) -->
- <!-- no translation found for zen_mode_duration_minutes_summary:other (2787867221129368935) -->
- <!-- no translation found for zen_mode_duration_hours_summary:one (597194865053253679) -->
- <!-- no translation found for zen_mode_duration_hours_summary:other (2827214920627669898) -->
+ <plurals name="zen_mode_duration_minutes_summary">
+ <item quantity="one" msgid="3177683545388923234">"Една минута (до <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ <item quantity="other" msgid="2787867221129368935">"%1$d минути (до <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ </plurals>
+ <plurals name="zen_mode_duration_hours_summary">
+ <item quantity="one" msgid="597194865053253679">"Еден час (до <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ <item quantity="other" msgid="2827214920627669898">"%1$d часа (до <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ </plurals>
<plurals name="zen_mode_duration_minutes">
<item quantity="one" msgid="9040808414992812341">"За една минута"</item>
<item quantity="other" msgid="6924190729213550991">"За %d минути"</item>
@@ -1790,7 +1801,7 @@
<item quantity="one" msgid="3480040795582254384">"За еден час"</item>
<item quantity="other" msgid="5408537517529822157">"За %d часа"</item>
</plurals>
- <!-- no translation found for zen_mode_until (7336308492289875088) -->
- <skip />
+ <string name="zen_mode_until" msgid="7336308492289875088">"До <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
<string name="zen_mode_forever" msgid="4316804956488785559">"Неодредено време"</string>
+ <string name="toolbar_collapse_description" msgid="2821479483960330739">"Собери"</string>
</resources>
diff --git a/core/res/res/values-ml-rIN/strings.xml b/core/res/res/values-ml-rIN/strings.xml
index c303fa2..d20da0a 100644
--- a/core/res/res/values-ml-rIN/strings.xml
+++ b/core/res/res/values-ml-rIN/strings.xml
@@ -716,8 +716,14 @@
<string name="permdesc_cache_filesystem" msgid="5578967642265550955">"കാഷെ ഫയൽ സിസ്റ്റം റീഡുചെയ്യുന്നതിനും റൈറ്റുചെയ്യുന്നതിനും അപ്ലിക്കേഷനെ അനുവദിക്കുന്നു."</string>
<string name="permlab_use_sip" msgid="2052499390128979920">"SIP കോളുകൾ വിളിക്കുക/സ്വീകരിക്കുക"</string>
<string name="permdesc_use_sip" msgid="2297804849860225257">"SIP കോളുകൾ വിളിക്കാനും സ്വീകരിക്കാനും അപ്ലിക്കേഷനെ അനുവദിക്കുന്നു."</string>
- <string name="permlab_register_provider" msgid="2654513709546459553">"പുതിയ ടെലികോം കണക്ഷൻ രജിസ്റ്റർ ചെയ്യുക"</string>
- <string name="permdesc_register_provider" msgid="7571533832018681544">"പുതിയ ടെലികോം കണക്ഷനുകൾ രജിസ്റ്റർ ചെയ്യാൻ അപ്ലിക്കേഷനെ അനുവദിക്കുന്നു."</string>
+ <!-- no translation found for permlab_register_sim_subscription (3166535485877549177) -->
+ <skip />
+ <!-- no translation found for permdesc_register_sim_subscription (2138909035926222911) -->
+ <skip />
+ <!-- no translation found for permlab_register_call_provider (108102120289029841) -->
+ <skip />
+ <!-- no translation found for permdesc_register_call_provider (7034310263521081388) -->
+ <skip />
<string name="permlab_connection_manager" msgid="1116193254522105375">"ടെലികോം കണക്ഷനുകൾ നിയന്ത്രിക്കുക"</string>
<string name="permdesc_connection_manager" msgid="5925480810356483565">"ടെലികോം കണക്ഷനുകൾ നിയന്ത്രിക്കാൻ അപ്ലിക്കേഷനെ അനുവദിക്കുന്നു."</string>
<string name="permlab_bind_incall_service" msgid="6773648341975287125">"ഇൻ-കോൾ സ്ക്രീനുമായി സംവദിക്കുക"</string>
@@ -1233,6 +1239,7 @@
<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_apk" msgid="7904042682111526169">"<xliff:g id="NUMBER_0">%1$d</xliff:g> / <xliff:g id="NUMBER_1">%2$d</xliff:g> അപ്ലിക്കേഷൻ ഓപ്റ്റിമൈസ് ചെയ്യുന്നു."</string>
<string name="android_upgrading_starting_apps" msgid="451464516346926713">"അപ്ലിക്കേഷനുകൾ ആരംഭിക്കുന്നു."</string>
<string name="android_upgrading_complete" msgid="1405954754112999229">"ബൂട്ട് ചെയ്യൽ പൂർത്തിയാകുന്നു."</string>
@@ -1776,10 +1783,12 @@
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"അൺപിൻ ചെയ്യുന്നതിനുമുമ്പ് പാസ്വേഡ് ആവശ്യപ്പെടുക"</string>
<string name="battery_saver_description" msgid="2510530476513605742">"ബാറ്ററി ആയുസ്സ് മെച്ചപ്പെടുത്താൻ സഹായിക്കുന്നതിന്, ബാറ്ററി സേവർ നിങ്ങളുടെ ഉപകരണത്തിന്റെ പ്രകടനത്തെ കുറയ്ക്കുകയും വൈബ്രേഷനെയും മിക്ക പശ്ചാത്തല ഡാറ്റയെയും പരിമിതപ്പെടുത്തുകയും ചെയ്യുന്നു. ഇമെയിൽ, സന്ദേശമയയ്ക്കൽ, സമന്വയിപ്പിക്കലിനെ ആശ്രയിച്ചുള്ള മറ്റ് അപ്ലിക്കേഷനുകൾ എന്നിവ നിങ്ങൾ തുറക്കുന്നതുവരെ അപ്ഡേറ്റുചെയ്യാനിടയില്ല.\n\nനിങ്ങളുടെ ഉപകരണം ചാർജ്ജുചെയ്യുമ്പോൾ ബാറ്ററി സേവർ യാന്ത്രികമായി ഓഫാകും."</string>
<string name="downtime_condition_summary" msgid="8761776337475705749">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g>-ന് നിങ്ങളുടെ കാലാവധി അവസാനിക്കുന്നതുവരെ"</string>
- <!-- no translation found for zen_mode_duration_minutes_summary:one (3177683545388923234) -->
+ <!-- String.format failed for translation -->
<!-- no translation found for zen_mode_duration_minutes_summary:other (2787867221129368935) -->
- <!-- no translation found for zen_mode_duration_hours_summary:one (597194865053253679) -->
- <!-- no translation found for zen_mode_duration_hours_summary:other (2827214920627669898) -->
+ <plurals name="zen_mode_duration_hours_summary">
+ <item quantity="one" msgid="597194865053253679">"ഒരു മണിക്കൂർ സമയത്തേക്ക് (<xliff:g id="FORMATTEDTIME">%2$s</xliff:g> വരെ)"</item>
+ <item quantity="other" msgid="2827214920627669898">"%1$d മണിക്കൂർ സമയത്തേക്ക് (<xliff:g id="FORMATTEDTIME">%2$s</xliff:g> വരെ)"</item>
+ </plurals>
<plurals name="zen_mode_duration_minutes">
<item quantity="one" msgid="9040808414992812341">"ഒരു മിനിറ്റ് ദൈർഘ്യം"</item>
<item quantity="other" msgid="6924190729213550991">"%d മിനിറ്റ് ദൈർഘ്യം"</item>
@@ -1788,7 +1797,7 @@
<item quantity="one" msgid="3480040795582254384">"ഒരു മണിക്കൂർ ദൈർഘ്യം"</item>
<item quantity="other" msgid="5408537517529822157">"%d മണിക്കൂർ ദൈർഘ്യം"</item>
</plurals>
- <!-- no translation found for zen_mode_until (7336308492289875088) -->
- <skip />
+ <string name="zen_mode_until" msgid="7336308492289875088">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g> വരെ"</string>
<string name="zen_mode_forever" msgid="4316804956488785559">"അവ്യക്തം"</string>
+ <string name="toolbar_collapse_description" msgid="2821479483960330739">"ചുരുക്കുക"</string>
</resources>
diff --git a/core/res/res/values-mn-rMN/strings.xml b/core/res/res/values-mn-rMN/strings.xml
index 38e395c..7132604 100644
--- a/core/res/res/values-mn-rMN/strings.xml
+++ b/core/res/res/values-mn-rMN/strings.xml
@@ -716,8 +716,14 @@
<string name="permdesc_cache_filesystem" msgid="5578967642265550955">"Апп нь кеш файлсистемийг унших бичих боломжтой."</string>
<string name="permlab_use_sip" msgid="2052499390128979920">"SIP дуудлага хийх/хүлээн авах"</string>
<string name="permdesc_use_sip" msgid="2297804849860225257">"Апп-д SIP дуудлага хийх болон хүлээн авахыг зөвшөөрөх."</string>
- <string name="permlab_register_provider" msgid="2654513709546459553">"шинэ телеком холболтуудыг бүртгэх"</string>
- <string name="permdesc_register_provider" msgid="7571533832018681544">"Апп-д шинэ телеком холболтуудыг бүртгэхийг зөвшөөрнө."</string>
+ <!-- no translation found for permlab_register_sim_subscription (3166535485877549177) -->
+ <skip />
+ <!-- no translation found for permdesc_register_sim_subscription (2138909035926222911) -->
+ <skip />
+ <!-- no translation found for permlab_register_call_provider (108102120289029841) -->
+ <skip />
+ <!-- no translation found for permdesc_register_call_provider (7034310263521081388) -->
+ <skip />
<string name="permlab_connection_manager" msgid="1116193254522105375">"телеком холболтуудыг удирдах."</string>
<string name="permdesc_connection_manager" msgid="5925480810356483565">"Апп-д телеком холболтуудыг удирдахыг зөвшөөрнө."</string>
<string name="permlab_bind_incall_service" msgid="6773648341975287125">"дуудлагын дэлгэцтэй харьцах"</string>
@@ -1233,6 +1239,7 @@
<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">"Андройдыг дэвшүүлж байна…"</string>
+ <string name="android_start_title" msgid="8418054686415318207">"Андройд эхэлж байна..."</string>
<string name="android_upgrading_apk" msgid="7904042682111526169">"<xliff:g id="NUMBER_1">%2$d</xliff:g>-н <xliff:g id="NUMBER_0">%1$d</xliff:g> апп-г тохируулж байна."</string>
<string name="android_upgrading_starting_apps" msgid="451464516346926713">"Апп-г эхлүүлж байна."</string>
<string name="android_upgrading_complete" msgid="1405954754112999229">"Эхлэлийг дуусгаж байна."</string>
@@ -1776,10 +1783,14 @@
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Тогтоосныг суллахаас өмнө нууц үг асуух"</string>
<string name="battery_saver_description" msgid="2510530476513605742">"Батерейны ашиглалтыг уртасгахын тулд батерей хэмнэгч нь таны төхөөрөмжийн ажиллагааг бууруулж, чичрэлт болон далд датаны ихэнх хувийг хязгаарлана. Имэйл, зурвас гэх мэт синк хийгддэг бусад апп-ууд таныг нээхээс нааш шинэчлэгдэхгүй байж болно.\n\nТаныг төхөөрөмжөө цэнэглэх үед батерей хэмнэгч автоматаар унтарна."</string>
<string name="downtime_condition_summary" msgid="8761776337475705749">"Таны уйтгартай байдал <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>-д дуусах хүртэл"</string>
- <!-- no translation found for zen_mode_duration_minutes_summary:one (3177683545388923234) -->
- <!-- no translation found for zen_mode_duration_minutes_summary:other (2787867221129368935) -->
- <!-- no translation found for zen_mode_duration_hours_summary:one (597194865053253679) -->
- <!-- no translation found for zen_mode_duration_hours_summary:other (2827214920627669898) -->
+ <plurals name="zen_mode_duration_minutes_summary">
+ <item quantity="one" msgid="3177683545388923234">"Нэг минутын турш (<xliff:g id="FORMATTEDTIME">%2$s</xliff:g> хүртэл)"</item>
+ <item quantity="other" msgid="2787867221129368935">"%1$d минутын турш (<xliff:g id="FORMATTEDTIME">%2$s</xliff:g> хүртэл)"</item>
+ </plurals>
+ <plurals name="zen_mode_duration_hours_summary">
+ <item quantity="one" msgid="597194865053253679">"Нэг цагийн турш (<xliff:g id="FORMATTEDTIME">%2$s</xliff:g> хүртэл)"</item>
+ <item quantity="other" msgid="2827214920627669898">"%1$d цагийн турш (<xliff:g id="FORMATTEDTIME">%2$s</xliff:g> хүртэл)"</item>
+ </plurals>
<plurals name="zen_mode_duration_minutes">
<item quantity="one" msgid="9040808414992812341">"Нэг минутын турш"</item>
<item quantity="other" msgid="6924190729213550991">"%d минутын турш"</item>
@@ -1788,7 +1799,7 @@
<item quantity="one" msgid="3480040795582254384">"Нэг цагийн турш"</item>
<item quantity="other" msgid="5408537517529822157">"%d цагийн турш"</item>
</plurals>
- <!-- no translation found for zen_mode_until (7336308492289875088) -->
- <skip />
+ <string name="zen_mode_until" msgid="7336308492289875088">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g> хүртэл"</string>
<string name="zen_mode_forever" msgid="4316804956488785559">"Тодорхойгүй"</string>
+ <string name="toolbar_collapse_description" msgid="2821479483960330739">"Хумих"</string>
</resources>
diff --git a/core/res/res/values-mr-rIN/strings.xml b/core/res/res/values-mr-rIN/strings.xml
index b7401c7..13347e7 100644
--- a/core/res/res/values-mr-rIN/strings.xml
+++ b/core/res/res/values-mr-rIN/strings.xml
@@ -716,8 +716,14 @@
<string name="permdesc_cache_filesystem" msgid="5578967642265550955">"कॅशे filesystem वाचण्यासाठी आणि लिहिण्यासाठी अॅप ला अनुमती देते."</string>
<string name="permlab_use_sip" msgid="2052499390128979920">"SIP कॉल करा/प्राप्त करा"</string>
<string name="permdesc_use_sip" msgid="2297804849860225257">"अॅपला SIP कॉल करण्याची आणि प्राप्त करण्याची अनुमती देते."</string>
- <string name="permlab_register_provider" msgid="2654513709546459553">"नवीन टेलिकॉम कनेक्शनची नोंदणी करा"</string>
- <string name="permdesc_register_provider" msgid="7571533832018681544">"नवीन टेलिकॉम कनेक्शनची नोंदणी करण्यासाठी अॅपला अनुमती देते."</string>
+ <!-- no translation found for permlab_register_sim_subscription (3166535485877549177) -->
+ <skip />
+ <!-- no translation found for permdesc_register_sim_subscription (2138909035926222911) -->
+ <skip />
+ <!-- no translation found for permlab_register_call_provider (108102120289029841) -->
+ <skip />
+ <!-- no translation found for permdesc_register_call_provider (7034310263521081388) -->
+ <skip />
<string name="permlab_connection_manager" msgid="1116193254522105375">"टेलिकॉम कनेक्शन व्यवस्थापित करा"</string>
<string name="permdesc_connection_manager" msgid="5925480810356483565">"टेलिकॉम कनेक्शन व्यवस्थापित करण्यासाठी अॅप ला अनुमती देते."</string>
<string name="permlab_bind_incall_service" msgid="6773648341975287125">"कॉल-मधील स्क्रीनशी परस्परसंवाद करा"</string>
@@ -1233,6 +1239,7 @@
<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_apk" msgid="7904042682111526169">"<xliff:g id="NUMBER_1">%2$d</xliff:g> पैकी <xliff:g id="NUMBER_0">%1$d</xliff:g> अॅप ऑप्टिमाइझ करत आहे."</string>
<string name="android_upgrading_starting_apps" msgid="451464516346926713">"अॅप्स प्रारंभ करत आहे."</string>
<string name="android_upgrading_complete" msgid="1405954754112999229">"बूट समाप्त होत आहे."</string>
@@ -1776,10 +1783,14 @@
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"अनपिन करण्यापूर्वी संकेतशब्दासाठी विचारा"</string>
<string name="battery_saver_description" msgid="2510530476513605742">"बॅटरीचे आयुष्य सुधारण्यात मदत होण्यासाठी, बॅटरी बचतकर्ता आपल्या डिव्हाइसचे कार्यप्रदर्शन कमी करतो आणि कंपन आणि बराच पार्श्वभूमी डेटा मर्यादित करतो. संकालनावर अवलंबून असणारे ईमेल, संदेशन आणि अन्य अॅप्स आपण ते उघडल्याशिवाय अद्यतनित होऊ शकत नाहीत.\n\nआपले डिव्हाइस चार्ज होत असते तेव्हा बॅटरी बचतकर्ता स्वयंचलितपणे बंद होतो."</string>
<string name="downtime_condition_summary" msgid="8761776337475705749">"आपला कार्य न करण्याचा कालावधी <xliff:g id="FORMATTEDTIME">%1$s</xliff:g> वाजता समाप्त होईपर्यंत"</string>
- <!-- no translation found for zen_mode_duration_minutes_summary:one (3177683545388923234) -->
- <!-- no translation found for zen_mode_duration_minutes_summary:other (2787867221129368935) -->
- <!-- no translation found for zen_mode_duration_hours_summary:one (597194865053253679) -->
- <!-- no translation found for zen_mode_duration_hours_summary:other (2827214920627669898) -->
+ <plurals name="zen_mode_duration_minutes_summary">
+ <item quantity="one" msgid="3177683545388923234">"एका मिनिटासाठी (<xliff:g id="FORMATTEDTIME">%2$s</xliff:g> पर्यंत)"</item>
+ <item quantity="other" msgid="2787867221129368935">"%1$d मिनिटांसाठी (<xliff:g id="FORMATTEDTIME">%2$s</xliff:g> पर्यंत)"</item>
+ </plurals>
+ <plurals name="zen_mode_duration_hours_summary">
+ <item quantity="one" msgid="597194865053253679">"एका तासासाठी (<xliff:g id="FORMATTEDTIME">%2$s</xliff:g> पर्यंत)"</item>
+ <item quantity="other" msgid="2827214920627669898">"%1$d तासांसाठी (<xliff:g id="FORMATTEDTIME">%2$s</xliff:g> पर्यंत)"</item>
+ </plurals>
<plurals name="zen_mode_duration_minutes">
<item quantity="one" msgid="9040808414992812341">"एक मिनिटासाठी"</item>
<item quantity="other" msgid="6924190729213550991">"%d मिनिटांसाठी"</item>
@@ -1788,7 +1799,7 @@
<item quantity="one" msgid="3480040795582254384">"एका तासासाठी"</item>
<item quantity="other" msgid="5408537517529822157">"%d तासांसाठी"</item>
</plurals>
- <!-- no translation found for zen_mode_until (7336308492289875088) -->
- <skip />
+ <string name="zen_mode_until" msgid="7336308492289875088">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g> पर्यंत"</string>
<string name="zen_mode_forever" msgid="4316804956488785559">"अनिश्चितपणे"</string>
+ <string name="toolbar_collapse_description" msgid="2821479483960330739">"संक्षिप्त करा"</string>
</resources>
diff --git a/core/res/res/values-ms-rMY/strings.xml b/core/res/res/values-ms-rMY/strings.xml
index 95d7cef..e65fe3f 100644
--- a/core/res/res/values-ms-rMY/strings.xml
+++ b/core/res/res/values-ms-rMY/strings.xml
@@ -716,14 +716,16 @@
<string name="permdesc_cache_filesystem" msgid="5578967642265550955">"Membenarkan apl membaca dan menulis cache sistem fail."</string>
<string name="permlab_use_sip" msgid="2052499390128979920">"buat/terima panggilan SIP"</string>
<string name="permdesc_use_sip" msgid="2297804849860225257">"Membenarkan apl membuat dan menerima panggilan SIP."</string>
- <!-- no translation found for permlab_register_provider (2654513709546459553) -->
+ <!-- no translation found for permlab_register_sim_subscription (3166535485877549177) -->
<skip />
- <!-- no translation found for permdesc_register_provider (7571533832018681544) -->
+ <!-- no translation found for permdesc_register_sim_subscription (2138909035926222911) -->
<skip />
- <!-- no translation found for permlab_connection_manager (1116193254522105375) -->
+ <!-- no translation found for permlab_register_call_provider (108102120289029841) -->
<skip />
- <!-- no translation found for permdesc_connection_manager (5925480810356483565) -->
+ <!-- no translation found for permdesc_register_call_provider (7034310263521081388) -->
<skip />
+ <string name="permlab_connection_manager" msgid="1116193254522105375">"urus sambungan telekomunikasi"</string>
+ <string name="permdesc_connection_manager" msgid="5925480810356483565">"Membenarkan apl mengurus sambungan telekomunikasi."</string>
<string name="permlab_bind_incall_service" msgid="6773648341975287125">"berinteraksi dengan skrin dalam panggilan"</string>
<string name="permdesc_bind_incall_service" msgid="8343471381323215005">"Membenarkan apl mengawal masa dan cara pengguna melihat skrin dalam panggilan."</string>
<string name="permlab_bind_connection_service" msgid="3557341439297014940">"berinteraksi dengan perkhidmatan telefoni"</string>
@@ -1237,6 +1239,7 @@
<string name="smv_application" msgid="3307209192155442829">"Apl <xliff:g id="APPLICATION">%1$s</xliff:g> (proses <xliff:g id="PROCESS">%2$s</xliff:g>) telah melanggar dasar Mod Tegasnya sendiri."</string>
<string name="smv_process" msgid="5120397012047462446">"Proses <xliff:g id="PROCESS">%1$s</xliff:g> telah melanggar dasar Mod Tegasnya sendiri."</string>
<string name="android_upgrading_title" msgid="1584192285441405746">"Android sedang menaik taraf..."</string>
+ <string name="android_start_title" msgid="8418054686415318207">"Android sedang dimulakan…"</string>
<string name="android_upgrading_apk" msgid="7904042682111526169">"Mengoptimumkan apl <xliff:g id="NUMBER_0">%1$d</xliff:g> daripada <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
<string name="android_upgrading_starting_apps" msgid="451464516346926713">"Memulakan apl."</string>
<string name="android_upgrading_complete" msgid="1405954754112999229">"But akhir."</string>
@@ -1780,10 +1783,14 @@
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Minta kata laluan sebelum menyahsemat"</string>
<string name="battery_saver_description" msgid="2510530476513605742">"Untuk membantu memperbaik hayat bateri, penjimat bateri mengurangkan prestasi peranti anda dan menghadkan getaran serta kebanyakan data latar belakang. E-mel, pemesejan dan apl lain yang bergantung pada penyegerakan mungkin tidak dikemas kini melainkan anda membuka apl tersebut.\n\nPenjimat bateri dimatikan secara automatik semasa peranti anda mengecas."</string>
<string name="downtime_condition_summary" msgid="8761776337475705749">"Sehingga waktu gendala anda berakhir pada <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
- <!-- no translation found for zen_mode_duration_minutes_summary:one (3177683545388923234) -->
- <!-- no translation found for zen_mode_duration_minutes_summary:other (2787867221129368935) -->
- <!-- no translation found for zen_mode_duration_hours_summary:one (597194865053253679) -->
- <!-- no translation found for zen_mode_duration_hours_summary:other (2827214920627669898) -->
+ <plurals name="zen_mode_duration_minutes_summary">
+ <item quantity="one" msgid="3177683545388923234">"Selama satu minit (sehingga <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ <item quantity="other" msgid="2787867221129368935">"Selaman %1$d minit (sehingga <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ </plurals>
+ <plurals name="zen_mode_duration_hours_summary">
+ <item quantity="one" msgid="597194865053253679">"Selama satu jam (sehingga <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ <item quantity="other" msgid="2827214920627669898">"Selama %1$d jam (sehingga <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ </plurals>
<plurals name="zen_mode_duration_minutes">
<item quantity="one" msgid="9040808414992812341">"Selama satu minit"</item>
<item quantity="other" msgid="6924190729213550991">"Selama %d minit"</item>
@@ -1792,7 +1799,7 @@
<item quantity="one" msgid="3480040795582254384">"Selama satu jam"</item>
<item quantity="other" msgid="5408537517529822157">"Selama %d jam"</item>
</plurals>
- <!-- no translation found for zen_mode_until (7336308492289875088) -->
- <skip />
+ <string name="zen_mode_until" msgid="7336308492289875088">"Sehingga <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
<string name="zen_mode_forever" msgid="4316804956488785559">"Selama-lamanya"</string>
+ <string name="toolbar_collapse_description" msgid="2821479483960330739">"Runtuhkan"</string>
</resources>
diff --git a/core/res/res/values-my-rMM/strings.xml b/core/res/res/values-my-rMM/strings.xml
index 999fb48..86b310d 100644
--- a/core/res/res/values-my-rMM/strings.xml
+++ b/core/res/res/values-my-rMM/strings.xml
@@ -716,8 +716,14 @@
<string name="permdesc_cache_filesystem" msgid="5578967642265550955">"appအား ဖိုင်စနစ်၏ကက်ရှကို ဖတ် နှင့် ရေး ခွင့်ပြုသည်။"</string>
<string name="permlab_use_sip" msgid="2052499390128979920">"SIP ခေါ်ဆိုမှုများ ခေါ်ရန်/လက်ခံရန်"</string>
<string name="permdesc_use_sip" msgid="2297804849860225257">"SIP ခေါ်ဆိုမှုများ ခေါ်ရန်နှင့် လက်ခံနိုင်ရန် app ကို ခွင့်ပြုပါ။"</string>
- <string name="permlab_register_provider" msgid="2654513709546459553">"တယ်လီကွမ် ဆက်သွယ်မှု အသစ်ကို မှတ်ပုံတင်ရန်"</string>
- <string name="permdesc_register_provider" msgid="7571533832018681544">"appအား တယ်လီကွမ် ဆက်သွယ်မှု အသစ်ကို မှတ်ပုံတင်ခွင့် ပြုပါ။"</string>
+ <!-- no translation found for permlab_register_sim_subscription (3166535485877549177) -->
+ <skip />
+ <!-- no translation found for permdesc_register_sim_subscription (2138909035926222911) -->
+ <skip />
+ <!-- no translation found for permlab_register_call_provider (108102120289029841) -->
+ <skip />
+ <!-- no translation found for permdesc_register_call_provider (7034310263521081388) -->
+ <skip />
<string name="permlab_connection_manager" msgid="1116193254522105375">"တယ်လီကွမ် ဆက်သွယ်မှုများကို စီမံရန်"</string>
<string name="permdesc_connection_manager" msgid="5925480810356483565">"appအား တယ်လီကွမ် ဆက်သွယ်မှုများကို စီမံခွင့် ပြုပါ။"</string>
<string name="permlab_bind_incall_service" msgid="6773648341975287125">"ခေါ်ဆိုမှု-အဝင် မျက်နှာပြင်နဲ့ တုံ့ပြန်လုပ်ကိုင်ရန်"</string>
@@ -1233,6 +1239,7 @@
<string name="smv_application" msgid="3307209192155442829">"app <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">"အန်ဒရွိုက်ကို မွမ်းမံနေ…"</string>
+ <string name="android_start_title" msgid="8418054686415318207">"Android စတင်နေ…"</string>
<string name="android_upgrading_apk" msgid="7904042682111526169">"<xliff:g id="NUMBER_0">%1$d</xliff:g> ထဲက app<xliff:g id="NUMBER_1">%2$d</xliff:g>ကို ဆီလျော်အောင် လုပ်နေ"</string>
<string name="android_upgrading_starting_apps" msgid="451464516346926713">"appများကို စတင်နေ"</string>
<string name="android_upgrading_complete" msgid="1405954754112999229">"လုပ်ငန်းစနစ်ထည့်သွင်း၍ ပြန်လည်စတင်ရန် ပြီးပါပြီ"</string>
@@ -1776,17 +1783,21 @@
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"ပင်မဖြုတ်မီမှာ စကားဝှက်ကို မေးကြည့်ရန်"</string>
<string name="battery_saver_description" msgid="2510530476513605742">"ဘက်ထရီသက်တမ်း ကြာရှည်ခံရန်အတွက်၊ ဘက်ထရီချွေတာရေးအပိုင်းမှ သင့် စက်ပစ္စည်း၏ဆောင်ရွက်ချက်များကို လျော့ချပေးပြီး တုန်ခါမှုနှင့် နောက်ခံအချက်အလက်အများစုကို ကန့်သတ်ပေးသည်။ အီးမေး၊ စာပို့ခြင်း နှင့် တခြားapp များကို သင်ဖွင့်မထားပါက အချိန်နှင့်တပြေးညီ ညှိမပေးပါ။ \n\n စက်ပစ္စည်း အားသွင်းနေစဉ် ဘက်ထရီချွေတာရေးအပိုင်းသည် အလိုအလျောက်ပင် အလုပ်မလုပ်ပါ။"</string>
<string name="downtime_condition_summary" msgid="8761776337475705749">"သင်၏ စက်ရပ်ချိန် <xliff:g id="FORMATTEDTIME">%1$s</xliff:g> မှာ ပြီးဆုံးသည့် အထိ။"</string>
- <!-- no translation found for zen_mode_duration_minutes_summary:one (3177683545388923234) -->
- <!-- no translation found for zen_mode_duration_minutes_summary:other (2787867221129368935) -->
- <!-- no translation found for zen_mode_duration_hours_summary:one (597194865053253679) -->
- <!-- no translation found for zen_mode_duration_hours_summary:other (2827214920627669898) -->
+ <plurals name="zen_mode_duration_minutes_summary">
+ <item quantity="one" msgid="3177683545388923234">"တစ်မိနစ်ကြာ (<xliff:g id="FORMATTEDTIME">%2$s</xliff:g>အထိ)"</item>
+ <item quantity="other" msgid="2787867221129368935">"%1$d မိနစ်ကြာ (<xliff:g id="FORMATTEDTIME">%2$s</xliff:g>အထိ)"</item>
+ </plurals>
+ <plurals name="zen_mode_duration_hours_summary">
+ <item quantity="one" msgid="597194865053253679">"တစ်နာရီကြာ (<xliff:g id="FORMATTEDTIME">%2$s</xliff:g>အထိ)"</item>
+ <item quantity="other" msgid="2827214920627669898">"%1$d နာရီကြာ (<xliff:g id="FORMATTEDTIME">%2$s</xliff:g>အထိ)"</item>
+ </plurals>
<plurals name="zen_mode_duration_minutes">
<item quantity="one" msgid="9040808414992812341">"တစ်မိနစ် အတွင်း"</item>
<item quantity="other" msgid="6924190729213550991">"%d မိနစ် အတွင်း"</item>
</plurals>
<!-- String.format failed for translation -->
<!-- no translation found for zen_mode_duration_hours:other (5408537517529822157) -->
- <!-- no translation found for zen_mode_until (7336308492289875088) -->
- <skip />
+ <string name="zen_mode_until" msgid="7336308492289875088">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g>အထိ"</string>
<string name="zen_mode_forever" msgid="4316804956488785559">"အကန့်အသတ်မရှိစွာ"</string>
+ <string name="toolbar_collapse_description" msgid="2821479483960330739">"ခေါက်ရန်"</string>
</resources>
diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml
index f9e44e7..a59a30a 100644
--- a/core/res/res/values-nb/strings.xml
+++ b/core/res/res/values-nb/strings.xml
@@ -716,8 +716,14 @@
<string name="permdesc_cache_filesystem" msgid="5578967642265550955">"Lar appen lese og skrive til det bufrede filsystemet."</string>
<string name="permlab_use_sip" msgid="2052499390128979920">"foreta/motta SIP-anrop"</string>
<string name="permdesc_use_sip" msgid="2297804849860225257">"Tillater at appen utfører og mottar SIP-anrop."</string>
- <string name="permlab_register_provider" msgid="2654513709546459553">"registrere nye telekom-tilkoblinger"</string>
- <string name="permdesc_register_provider" msgid="7571533832018681544">"Lar appen registrere nye telekom-tilkoblinger."</string>
+ <!-- no translation found for permlab_register_sim_subscription (3166535485877549177) -->
+ <skip />
+ <!-- no translation found for permdesc_register_sim_subscription (2138909035926222911) -->
+ <skip />
+ <!-- no translation found for permlab_register_call_provider (108102120289029841) -->
+ <skip />
+ <!-- no translation found for permdesc_register_call_provider (7034310263521081388) -->
+ <skip />
<string name="permlab_connection_manager" msgid="1116193254522105375">"administrere telekom-tilkoblinger"</string>
<string name="permdesc_connection_manager" msgid="5925480810356483565">"Lar appen administrere telekom-tilkoblinger."</string>
<string name="permlab_bind_incall_service" msgid="6773648341975287125">"samhandle med skjermen for innkommende anrop"</string>
@@ -1233,6 +1239,7 @@
<string name="smv_application" msgid="3307209192155442829">"Appen <xliff:g id="APPLICATION">%1$s</xliff:g> (prosessen <xliff:g id="PROCESS">%2$s</xliff:g>) har brutt de selvpålagte StrictMode-retningslinjene."</string>
<string name="smv_process" msgid="5120397012047462446">"Prosessen<xliff:g id="PROCESS">%1$s</xliff:g> har brutt de selvpålagte StrictMode-retningslinjene."</string>
<string name="android_upgrading_title" msgid="1584192285441405746">"Android oppgraderes …"</string>
+ <string name="android_start_title" msgid="8418054686415318207">"Android starter …"</string>
<string name="android_upgrading_apk" msgid="7904042682111526169">"Optimaliserer app <xliff:g id="NUMBER_0">%1$d</xliff:g> av <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
<string name="android_upgrading_starting_apps" msgid="451464516346926713">"Starter apper."</string>
<string name="android_upgrading_complete" msgid="1405954754112999229">"Ferdigstiller oppstart."</string>
@@ -1776,10 +1783,14 @@
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Krev passord for å løsne apper"</string>
<string name="battery_saver_description" msgid="2510530476513605742">"Batterisparing reduserer enhetens ytelse og begrenser vibrering og de fleste bakgrunnsdata for å forbedre batterilevetiden. Det kan hende E-post, Meldinger og andre apper som er avhengige av synkronisering, ikke oppdateres med mindre du åpner dem.\n\nBatterisparing slås automatisk av når enheten lades."</string>
<string name="downtime_condition_summary" msgid="8761776337475705749">"Til hviletiden din ender kl. <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
- <!-- no translation found for zen_mode_duration_minutes_summary:one (3177683545388923234) -->
- <!-- no translation found for zen_mode_duration_minutes_summary:other (2787867221129368935) -->
- <!-- no translation found for zen_mode_duration_hours_summary:one (597194865053253679) -->
- <!-- no translation found for zen_mode_duration_hours_summary:other (2827214920627669898) -->
+ <plurals name="zen_mode_duration_minutes_summary">
+ <item quantity="one" msgid="3177683545388923234">"I ett minutt (til <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ <item quantity="other" msgid="2787867221129368935">"I %1$d minutter (til <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ </plurals>
+ <plurals name="zen_mode_duration_hours_summary">
+ <item quantity="one" msgid="597194865053253679">"I én time (til <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ <item quantity="other" msgid="2827214920627669898">"I %1$d timer (til <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ </plurals>
<plurals name="zen_mode_duration_minutes">
<item quantity="one" msgid="9040808414992812341">"I ett minutt"</item>
<item quantity="other" msgid="6924190729213550991">"I %d minutter"</item>
@@ -1788,7 +1799,7 @@
<item quantity="one" msgid="3480040795582254384">"I én time"</item>
<item quantity="other" msgid="5408537517529822157">"I %d timer"</item>
</plurals>
- <!-- no translation found for zen_mode_until (7336308492289875088) -->
- <skip />
+ <string name="zen_mode_until" msgid="7336308492289875088">"Til <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
<string name="zen_mode_forever" msgid="4316804956488785559">"På ubestemt tid"</string>
+ <string name="toolbar_collapse_description" msgid="2821479483960330739">"Skjul"</string>
</resources>
diff --git a/core/res/res/values-ne-rNP/strings.xml b/core/res/res/values-ne-rNP/strings.xml
index e93bee1..f1502f8 100644
--- a/core/res/res/values-ne-rNP/strings.xml
+++ b/core/res/res/values-ne-rNP/strings.xml
@@ -716,10 +716,16 @@
<string name="permdesc_cache_filesystem" msgid="5578967642265550955">"केस फाइल प्रणालीलाई पढ्न र लेख्नको लागि अनुप्रयोगलाई अनुमति दिन्छ।"</string>
<string name="permlab_use_sip" msgid="2052499390128979920">"SIP कलहरू प्राप्त/बनाउन"</string>
<string name="permdesc_use_sip" msgid="2297804849860225257">"SIP कलहरू बनाउन र प्राप्त गर्न अनुप्रयोगलाई अनुमति दिन्छ।"</string>
- <string name="permlab_register_provider" msgid="2654513709546459553">"नयाँ दूरसंचार जडान दर्ता गर्नुहोस्"</string>
- <string name="permdesc_register_provider" msgid="7571533832018681544">"अनुप्रयोग लाई नयाँ दूरसंचार सम्पर्क दर्ता गर्न अनुमति दिन्छ।"</string>
+ <!-- no translation found for permlab_register_sim_subscription (3166535485877549177) -->
+ <skip />
+ <!-- no translation found for permdesc_register_sim_subscription (2138909035926222911) -->
+ <skip />
+ <!-- no translation found for permlab_register_call_provider (108102120289029841) -->
+ <skip />
+ <!-- no translation found for permdesc_register_call_provider (7034310263521081388) -->
+ <skip />
<string name="permlab_connection_manager" msgid="1116193254522105375">"दूरसंचार जडान व्यवस्थापन गर्नुहोस्"</string>
- <string name="permdesc_connection_manager" msgid="5925480810356483565">"अनुप्रयोग लाई टेलिकम जडान व्यवस्थापन गर्न अनुमति दिन्छ।"</string>
+ <string name="permdesc_connection_manager" msgid="5925480810356483565">"अनुप्रयोगलाई टेलिकम जडान व्यवस्थापन गर्न अनुमति दिन्छ।"</string>
<string name="permlab_bind_incall_service" msgid="6773648341975287125">"आगमन कल स्क्रिन संग अन्तर्क्रिया गर्नुहोस्"</string>
<string name="permdesc_bind_incall_service" msgid="8343471381323215005">"कहिले र कसरी प्रयोगकर्ताले आगमन कल स्क्रीन हेर्न सक्दछ भनेर नियन्त्रण गर्न अनुप्रयोगलाई अनुमति दिनुहोस्।"</string>
<string name="permlab_bind_connection_service" msgid="3557341439297014940">"टेलिफोनी सेवा अन्तरक्रिया"</string>
@@ -1241,6 +1247,7 @@
<string name="smv_application" msgid="3307209192155442829">"अनुप्रयोग <xliff:g id="APPLICATION">%1$s</xliff:g> (प्रक्रिया <xliff:g id="PROCESS">%2$s</xliff:g>) ले यसको स्वयं-लागु गरिएको स्ट्रिटमोड नीति उलङ्घन गरेको छ।"</string>
<string name="smv_process" msgid="5120397012047462446">"प्रक्रिया <xliff:g id="PROCESS">%1$s</xliff:g> यसको आफ्नै कडामोड नीतिका कारण उल्लङ्घन गरिएको छ।"</string>
<string name="android_upgrading_title" msgid="1584192285441405746">"एन्ड्रोइड अपग्रेड हुँदैछ…"</string>
+ <string name="android_start_title" msgid="8418054686415318207">"Android शुरू हुँदैछ..."</string>
<string name="android_upgrading_apk" msgid="7904042682111526169">"अनुप्रयोग अनुकुल हुँदै <xliff:g id="NUMBER_0">%1$d</xliff:g> को <xliff:g id="NUMBER_1">%2$d</xliff:g>।"</string>
<string name="android_upgrading_starting_apps" msgid="451464516346926713">"सुरुवात अनुप्रयोगहरू।"</string>
<string name="android_upgrading_complete" msgid="1405954754112999229">"बुट पुरा हुँदै।"</string>
@@ -1769,12 +1776,12 @@
<string name="item_is_selected" msgid="949687401682476608">"<xliff:g id="ITEM">%1$s</xliff:g> चयन गरियो"</string>
<string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> हटाइयो"</string>
<string name="managed_profile_label_badge" msgid="2355652472854327647">"कार्य <xliff:g id="LABEL">%1$s</xliff:g>"</string>
- <string name="lock_to_app_toast" msgid="7570091317001980053">"यो पर्दा अनपिन गर्न, छुनुहोस् र पछाडि पकड्नुहोस् र सोही समयमा अवलोकन गर्नुहोस्।"</string>
- <string name="lock_to_app_toast_accessible" msgid="8239120109365070664">"यो पर्दा अनपिन गर्न, छुनुहोस् र अवलोकन पकड्नुहोस्।"</string>
+ <string name="lock_to_app_toast" msgid="7570091317001980053">"यस पर्दालाई अनपिन गर्न एकै समय फिर्ता र सारांशलाई छोई पक्डिनुहोस्।"</string>
+ <string name="lock_to_app_toast_accessible" msgid="8239120109365070664">"यस पर्दालाई अनपिन गर्न सारांशलाई छुनुहोस् र पक्डनुहोस्।"</string>
<string name="lock_to_app_toast_locked" msgid="8739004135132606329">"स्क्रिन अनपिन हुँदैछ। अनपिन गर्ने तपाईँको संगठन द्वारा समर्थित छैन।"</string>
<string name="lock_to_app_title" msgid="1682643873107812874">"स्क्रिन पिन गर्ने प्रयोग गर्नुहुन्छ?"</string>
- <string name="lock_to_app_description" msgid="4120623404152035221">"पर्दा पिन गर्नाले एकल दृश्यमा प्रदर्शन बन्द हुन्छ।\n\nअनपिन गर्न, छुनुहोस् र पछाडि पकड्नुहोस् र सोही समयमा अवलोकन गर्नुहोस्।"</string>
- <string name="lock_to_app_description_accessible" msgid="199664191087836099">"पर्दा पिन गर्नाले एकल दृश्यमा प्रदर्शन बन्द हुन्छ।\n\nअनपिन गर्न, छुनुहोस् र अवलोकन पकड्नुहोस्।"</string>
+ <string name="lock_to_app_description" msgid="4120623404152035221">"पर्दा पिन गर्नाले एकल दृश्यमा प्रदर्शन बन्द हुन्छ।\n\nअनपिन गर्न, छुनुहोस् र पछाडि पकड्नुहोस् र सोही समयमा सारांशलाई हेर्नुहोस्।"</string>
+ <string name="lock_to_app_description_accessible" msgid="199664191087836099">"पर्दा पिन गर्नाले एकल दृश्यमा प्रदर्शन बन्द हुन्छ।\n\nअनपिन गर्न, छुनुहोस् र सारांश पकड्नुहोस्।"</string>
<string name="lock_to_app_negative" msgid="2259143719362732728">"होइन, धन्यवाद"</string>
<string name="lock_to_app_positive" msgid="7085139175671313864">"START"</string>
<string name="lock_to_app_start" msgid="6643342070839862795">"स्क्रिन पिन गरियो"</string>
@@ -1784,10 +1791,14 @@
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"पिन निकाल्नुअघि पासवर्ड सोध्नुहोस्"</string>
<string name="battery_saver_description" msgid="2510530476513605742">"ब्याट्री जीवन सुधार्न, ब्याट्री बचतले आफ्नो उपकरणको प्रदर्शन र कम्पनको सीमा र सबैभन्दा पृष्ठभूमि डेटा कम गर्छ। इमेल, सन्देश, र अन्य अनुप्रयोगहरू जसले तपाईं तिनीहरूलाई नखोले सम्म समिकरण अद्यावधिक नगर्न सक्छ भनि भर पर्छ।\n\nब्याट्री बचतले तपाईँको उपकरण चार्ज हुँदै बेला तपाईँको उपकरण स्वचालित बन्द गर्छ।"</string>
<string name="downtime_condition_summary" msgid="8761776337475705749">"तपाईँको <xliff:g id="FORMATTEDTIME">%1$s</xliff:g> डाउनटाइम समाप्त हुँदा सम्म"</string>
- <!-- no translation found for zen_mode_duration_minutes_summary:one (3177683545388923234) -->
- <!-- no translation found for zen_mode_duration_minutes_summary:other (2787867221129368935) -->
- <!-- no translation found for zen_mode_duration_hours_summary:one (597194865053253679) -->
- <!-- no translation found for zen_mode_duration_hours_summary:other (2827214920627669898) -->
+ <plurals name="zen_mode_duration_minutes_summary">
+ <item quantity="one" msgid="3177683545388923234">"एक मिनेटको लागि (<xliff:g id="FORMATTEDTIME">%2$s</xliff:g> सम्म)"</item>
+ <item quantity="other" msgid="2787867221129368935">"%1$d मिनेटको लागि (<xliff:g id="FORMATTEDTIME">%2$s</xliff:g> सम्म)"</item>
+ </plurals>
+ <plurals name="zen_mode_duration_hours_summary">
+ <item quantity="one" msgid="597194865053253679">"एक घण्टाको लागि (<xliff:g id="FORMATTEDTIME">%2$s</xliff:g> सम्म)"</item>
+ <item quantity="other" msgid="2827214920627669898">"%1$d घण्टाको लागि (<xliff:g id="FORMATTEDTIME">%2$s</xliff:g> सम्म)"</item>
+ </plurals>
<plurals name="zen_mode_duration_minutes">
<item quantity="one" msgid="9040808414992812341">"एक मिनेटको लागि"</item>
<item quantity="other" msgid="6924190729213550991">"%d मिनेटको लागि"</item>
@@ -1796,7 +1807,7 @@
<item quantity="one" msgid="3480040795582254384">"एक घण्टाको लागि"</item>
<item quantity="other" msgid="5408537517529822157">"%d घण्टाको लागि"</item>
</plurals>
- <!-- no translation found for zen_mode_until (7336308492289875088) -->
- <skip />
+ <string name="zen_mode_until" msgid="7336308492289875088">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g> सम्म"</string>
<string name="zen_mode_forever" msgid="4316804956488785559">"अनिश्चित"</string>
+ <string name="toolbar_collapse_description" msgid="2821479483960330739">"संक्षिप्त पार्नुहोस्"</string>
</resources>
diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml
index f2564d8..1454f6b 100644
--- a/core/res/res/values-nl/strings.xml
+++ b/core/res/res/values-nl/strings.xml
@@ -716,8 +716,14 @@
<string name="permdesc_cache_filesystem" msgid="5578967642265550955">"Hiermee kan de app het cachebestandssysteem lezen en schrijven."</string>
<string name="permlab_use_sip" msgid="2052499390128979920">"SIP-oproepen plaatsen/ontvangen"</string>
<string name="permdesc_use_sip" msgid="2297804849860225257">"Toestaan dat de app SIP-oproepen plaatst en ontvangt."</string>
- <string name="permlab_register_provider" msgid="2654513709546459553">"nieuwe telecomverbinding registreren"</string>
- <string name="permdesc_register_provider" msgid="7571533832018681544">"Hiermee kan de app nieuwe telecomverbindingen registreren."</string>
+ <!-- no translation found for permlab_register_sim_subscription (3166535485877549177) -->
+ <skip />
+ <!-- no translation found for permdesc_register_sim_subscription (2138909035926222911) -->
+ <skip />
+ <!-- no translation found for permlab_register_call_provider (108102120289029841) -->
+ <skip />
+ <!-- no translation found for permdesc_register_call_provider (7034310263521081388) -->
+ <skip />
<string name="permlab_connection_manager" msgid="1116193254522105375">"telecomverbindingen beheren"</string>
<string name="permdesc_connection_manager" msgid="5925480810356483565">"Hiermee kan de app telecomverbindingen beheren."</string>
<string name="permlab_bind_incall_service" msgid="6773648341975287125">"interactie met scherm in actieve oproep"</string>
@@ -1233,6 +1239,7 @@
<string name="smv_application" msgid="3307209192155442829">"De app <xliff:g id="APPLICATION">%1$s</xliff:g> (proces <xliff:g id="PROCESS">%2$s</xliff:g>) heeft het zelf afgedwongen StrictMode-beleid geschonden."</string>
<string name="smv_process" msgid="5120397012047462446">"Het proces <xliff:g id="PROCESS">%1$s</xliff:g> heeft het zelf afgedwongen StrictMode-beleid geschonden."</string>
<string name="android_upgrading_title" msgid="1584192285441405746">"Android wordt bijgewerkt..."</string>
+ <string name="android_start_title" msgid="8418054686415318207">"Android wordt gestart…"</string>
<string name="android_upgrading_apk" msgid="7904042682111526169">"App <xliff:g id="NUMBER_0">%1$d</xliff:g> van <xliff:g id="NUMBER_1">%2$d</xliff:g> optimaliseren."</string>
<string name="android_upgrading_starting_apps" msgid="451464516346926713">"Apps starten."</string>
<string name="android_upgrading_complete" msgid="1405954754112999229">"Opstarten afronden."</string>
@@ -1776,10 +1783,14 @@
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Vragen om wachtwoord voordat items worden losgemaakt"</string>
<string name="battery_saver_description" msgid="2510530476513605742">"Accubesparing beperkt de prestaties van uw apparaat, de trilfunctie en de meeste achtergrondgegevens om de accuduur te verlengen.\n\nAccubesparing wordt automatisch uitgeschakeld wanneer uw apparaat wordt opgeladen."</string>
<string name="downtime_condition_summary" msgid="8761776337475705749">"Totdat uw downtime eindigt om <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
- <!-- no translation found for zen_mode_duration_minutes_summary:one (3177683545388923234) -->
- <!-- no translation found for zen_mode_duration_minutes_summary:other (2787867221129368935) -->
- <!-- no translation found for zen_mode_duration_hours_summary:one (597194865053253679) -->
- <!-- no translation found for zen_mode_duration_hours_summary:other (2827214920627669898) -->
+ <plurals name="zen_mode_duration_minutes_summary">
+ <item quantity="one" msgid="3177683545388923234">"Eén minuut (tot <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ <item quantity="other" msgid="2787867221129368935">"%1$d minuten (tot <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ </plurals>
+ <plurals name="zen_mode_duration_hours_summary">
+ <item quantity="one" msgid="597194865053253679">"Eén uur (tot <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ <item quantity="other" msgid="2827214920627669898">"%1$d uur (tot <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ </plurals>
<plurals name="zen_mode_duration_minutes">
<item quantity="one" msgid="9040808414992812341">"Eén minuut"</item>
<item quantity="other" msgid="6924190729213550991">"%d minuten"</item>
@@ -1788,7 +1799,7 @@
<item quantity="one" msgid="3480040795582254384">"Eén uur"</item>
<item quantity="other" msgid="5408537517529822157">"%d uur"</item>
</plurals>
- <!-- no translation found for zen_mode_until (7336308492289875088) -->
- <skip />
+ <string name="zen_mode_until" msgid="7336308492289875088">"Tot <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
<string name="zen_mode_forever" msgid="4316804956488785559">"Voor onbepaalde tijd"</string>
+ <string name="toolbar_collapse_description" msgid="2821479483960330739">"Samenvouwen"</string>
</resources>
diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml
index 69ddf83..7e97987 100644
--- a/core/res/res/values-pl/strings.xml
+++ b/core/res/res/values-pl/strings.xml
@@ -716,8 +716,14 @@
<string name="permdesc_cache_filesystem" msgid="5578967642265550955">"Pozwala aplikacji na odczyt i zapis w systemie plików pamięci podręcznej."</string>
<string name="permlab_use_sip" msgid="2052499390128979920">"wykonywanie/odbieranie połączeń SIP"</string>
<string name="permdesc_use_sip" msgid="2297804849860225257">"Pozwala aplikacji na wykonywanie i odbieranie połączeń SIP."</string>
- <string name="permlab_register_provider" msgid="2654513709546459553">"rejestrowanie nowych połączeń telekomunikacyjnych"</string>
- <string name="permdesc_register_provider" msgid="7571533832018681544">"Zezwala aplikacji na rejestrowanie nowych połączeń telekomunikacyjnych."</string>
+ <!-- no translation found for permlab_register_sim_subscription (3166535485877549177) -->
+ <skip />
+ <!-- no translation found for permdesc_register_sim_subscription (2138909035926222911) -->
+ <skip />
+ <!-- no translation found for permlab_register_call_provider (108102120289029841) -->
+ <skip />
+ <!-- no translation found for permdesc_register_call_provider (7034310263521081388) -->
+ <skip />
<string name="permlab_connection_manager" msgid="1116193254522105375">"zarządzanie połączeniami telekomunikacyjnymi"</string>
<string name="permdesc_connection_manager" msgid="5925480810356483565">"Zezwala aplikacji na zarządzanie połączeniami telekomunikacyjnymi."</string>
<string name="permlab_bind_incall_service" msgid="6773648341975287125">"interakcje z ekranem połączenia"</string>
@@ -1233,6 +1239,7 @@
<string name="smv_application" msgid="3307209192155442829">"Aplikacja <xliff:g id="APPLICATION">%1$s</xliff:g> (proces <xliff:g id="PROCESS">%2$s</xliff:g>) naruszyła wymuszone przez siebie zasady StrictMode."</string>
<string name="smv_process" msgid="5120397012047462446">"Proces <xliff:g id="PROCESS">%1$s</xliff:g> naruszył wymuszone przez siebie zasady StrictMode."</string>
<string name="android_upgrading_title" msgid="1584192285441405746">"Android jest uaktualniany..."</string>
+ <string name="android_start_title" msgid="8418054686415318207">"Android się uruchamia…"</string>
<string name="android_upgrading_apk" msgid="7904042682111526169">"Optymalizowanie aplikacji <xliff:g id="NUMBER_0">%1$d</xliff:g> z <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
<string name="android_upgrading_starting_apps" msgid="451464516346926713">"Uruchamianie aplikacji."</string>
<string name="android_upgrading_complete" msgid="1405954754112999229">"Kończenie uruchamiania."</string>
@@ -1776,10 +1783,14 @@
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Aby odpiąć, poproś o hasło"</string>
<string name="battery_saver_description" msgid="2510530476513605742">"Aby wydłużyć czas pracy baterii, Oszczędzanie baterii ogranicza aktywność urządzenia, w tym wibracje i przetwarzanie większości danych w tle. Poczta, SMS i inne synchronizowane aplikacje mogą nie aktualizować swojej zawartości, dopóki ich nie otworzysz.\n\nOszczędzanie baterii wyłącza się automatycznie podczas ładowania urządzenia."</string>
<string name="downtime_condition_summary" msgid="8761776337475705749">"Do zakończenia przestoju o <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
- <!-- no translation found for zen_mode_duration_minutes_summary:one (3177683545388923234) -->
- <!-- no translation found for zen_mode_duration_minutes_summary:other (2787867221129368935) -->
- <!-- no translation found for zen_mode_duration_hours_summary:one (597194865053253679) -->
- <!-- no translation found for zen_mode_duration_hours_summary:other (2827214920627669898) -->
+ <plurals name="zen_mode_duration_minutes_summary">
+ <item quantity="one" msgid="3177683545388923234">"Przez minutę (do <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ <item quantity="other" msgid="2787867221129368935">"Przez %1$d min (do <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ </plurals>
+ <plurals name="zen_mode_duration_hours_summary">
+ <item quantity="one" msgid="597194865053253679">"Przez godzinę (do <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ <item quantity="other" msgid="2827214920627669898">"Przez %1$d godz. (do <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ </plurals>
<plurals name="zen_mode_duration_minutes">
<item quantity="one" msgid="9040808414992812341">"Przez minutę"</item>
<item quantity="other" msgid="6924190729213550991">"Przez %d min"</item>
@@ -1788,7 +1799,7 @@
<item quantity="one" msgid="3480040795582254384">"Przez 1 godz."</item>
<item quantity="other" msgid="5408537517529822157">"Przez %d godz."</item>
</plurals>
- <!-- no translation found for zen_mode_until (7336308492289875088) -->
- <skip />
+ <string name="zen_mode_until" msgid="7336308492289875088">"Do <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
<string name="zen_mode_forever" msgid="4316804956488785559">"Na czas nieokreślony"</string>
+ <string name="toolbar_collapse_description" msgid="2821479483960330739">"Zwiń"</string>
</resources>
diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml
index 84100f0..acdd6f8 100644
--- a/core/res/res/values-pt-rPT/strings.xml
+++ b/core/res/res/values-pt-rPT/strings.xml
@@ -716,8 +716,14 @@
<string name="permdesc_cache_filesystem" msgid="5578967642265550955">"Permite à aplicação ler e escrever no sistema de ficheiros da cache."</string>
<string name="permlab_use_sip" msgid="2052499390128979920">"efetuar/receber chamadas SIP"</string>
<string name="permdesc_use_sip" msgid="2297804849860225257">"Permite que a aplicação efetue e receba chamadas SIP."</string>
- <string name="permlab_register_provider" msgid="2654513709546459553">"registar novas ligações de telecomunicação"</string>
- <string name="permdesc_register_provider" msgid="7571533832018681544">"Permite que a aplicação registe novas ligações de telecomunicação."</string>
+ <!-- no translation found for permlab_register_sim_subscription (3166535485877549177) -->
+ <skip />
+ <!-- no translation found for permdesc_register_sim_subscription (2138909035926222911) -->
+ <skip />
+ <!-- no translation found for permlab_register_call_provider (108102120289029841) -->
+ <skip />
+ <!-- no translation found for permdesc_register_call_provider (7034310263521081388) -->
+ <skip />
<string name="permlab_connection_manager" msgid="1116193254522105375">"gerir ligações de telecomunicação"</string>
<string name="permdesc_connection_manager" msgid="5925480810356483565">"Permite que a aplicação faça a gestão das ligações de telecomunicação."</string>
<string name="permlab_bind_incall_service" msgid="6773648341975287125">"interagir com o ecrã durante uma chamada"</string>
@@ -1233,6 +1239,7 @@
<string name="smv_application" msgid="3307209192155442829">"A aplicação <xliff:g id="APPLICATION">%1$s</xliff:g> (processo <xliff:g id="PROCESS">%2$s</xliff:g>) violou a política StrictMode auto-imposta."</string>
<string name="smv_process" msgid="5120397012047462446">"O processo <xliff:g id="PROCESS">%1$s</xliff:g> violou a política StrictMode auto-imposta."</string>
<string name="android_upgrading_title" msgid="1584192285441405746">"O Android está a ser atualizado..."</string>
+ <string name="android_start_title" msgid="8418054686415318207">"O Android está a iniciar…"</string>
<string name="android_upgrading_apk" msgid="7904042682111526169">"A otimizar a aplicação <xliff:g id="NUMBER_0">%1$d</xliff:g> de <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
<string name="android_upgrading_starting_apps" msgid="451464516346926713">"A iniciar aplicações"</string>
<string name="android_upgrading_complete" msgid="1405954754112999229">"A concluir o arranque."</string>
@@ -1776,10 +1783,14 @@
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Pedir palavra-passe antes de soltar"</string>
<string name="battery_saver_description" msgid="2510530476513605742">"Para ajudar a melhorar a duração da bateria, a poupança de bateria reduz o desempenho do dispositivo e limita a vibração e a maior parte dos dados de segundo plano. O email, as mensagens e outras aplicações que dependem da sincronização não podem ser atualizados, exceto se os abrir.\n\nA poupança de bateria desliga-se automaticamente quando o dispositivo estiver a carregar."</string>
<string name="downtime_condition_summary" msgid="8761776337475705749">"Até o período de inatividade terminar às <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
- <!-- no translation found for zen_mode_duration_minutes_summary:one (3177683545388923234) -->
- <!-- no translation found for zen_mode_duration_minutes_summary:other (2787867221129368935) -->
- <!-- no translation found for zen_mode_duration_hours_summary:one (597194865053253679) -->
- <!-- no translation found for zen_mode_duration_hours_summary:other (2827214920627669898) -->
+ <plurals name="zen_mode_duration_minutes_summary">
+ <item quantity="one" msgid="3177683545388923234">"Durante um minuto (até às <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ <item quantity="other" msgid="2787867221129368935">"Durante %1$d minutos (até às <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ </plurals>
+ <plurals name="zen_mode_duration_hours_summary">
+ <item quantity="one" msgid="597194865053253679">"Durante uma hora (até às <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ <item quantity="other" msgid="2827214920627669898">"Durante %1$d horas (até às <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ </plurals>
<plurals name="zen_mode_duration_minutes">
<item quantity="one" msgid="9040808414992812341">"Durante um minuto"</item>
<item quantity="other" msgid="6924190729213550991">"Durante %d minutos"</item>
@@ -1788,7 +1799,7 @@
<item quantity="one" msgid="3480040795582254384">"Durante uma hora"</item>
<item quantity="other" msgid="5408537517529822157">"Durante %d horas"</item>
</plurals>
- <!-- no translation found for zen_mode_until (7336308492289875088) -->
- <skip />
+ <string name="zen_mode_until" msgid="7336308492289875088">"Até às <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
<string name="zen_mode_forever" msgid="4316804956488785559">"Indefinidamente"</string>
+ <string name="toolbar_collapse_description" msgid="2821479483960330739">"Reduzir"</string>
</resources>
diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml
index 3c0ab1e..6c77afb 100644
--- a/core/res/res/values-pt/strings.xml
+++ b/core/res/res/values-pt/strings.xml
@@ -716,8 +716,14 @@
<string name="permdesc_cache_filesystem" msgid="5578967642265550955">"Permite que o app leia e grave o sistema de arquivos cache."</string>
<string name="permlab_use_sip" msgid="2052499390128979920">"fazer/receber chamadas SIP"</string>
<string name="permdesc_use_sip" msgid="2297804849860225257">"Permite que o app faça e receba chamadas SIP."</string>
- <string name="permlab_register_provider" msgid="2654513709546459553">"registrar nova conexão de telecomunicações"</string>
- <string name="permdesc_register_provider" msgid="7571533832018681544">"Permite que o app registre novas conexões de telecomunicações."</string>
+ <!-- no translation found for permlab_register_sim_subscription (3166535485877549177) -->
+ <skip />
+ <!-- no translation found for permdesc_register_sim_subscription (2138909035926222911) -->
+ <skip />
+ <!-- no translation found for permlab_register_call_provider (108102120289029841) -->
+ <skip />
+ <!-- no translation found for permdesc_register_call_provider (7034310263521081388) -->
+ <skip />
<string name="permlab_connection_manager" msgid="1116193254522105375">"gerenciar conexões de telecomunicações"</string>
<string name="permdesc_connection_manager" msgid="5925480810356483565">"Permite que o app gerencie conexões de telecomunicações."</string>
<string name="permlab_bind_incall_service" msgid="6773648341975287125">"interagir com chamada na tela"</string>
@@ -1233,6 +1239,8 @@
<string name="smv_application" msgid="3307209192155442829">"O app <xliff:g id="APPLICATION">%1$s</xliff:g>, processo <xliff:g id="PROCESS">%2$s</xliff:g>, violou a política StrictMode imposta automaticamente."</string>
<string name="smv_process" msgid="5120397012047462446">"O processo <xliff:g id="PROCESS">%1$s</xliff:g> violou a política StrictMode imposta automaticamente."</string>
<string name="android_upgrading_title" msgid="1584192285441405746">"O Android está sendo atualizado..."</string>
+ <!-- no translation found for android_start_title (8418054686415318207) -->
+ <skip />
<string name="android_upgrading_apk" msgid="7904042682111526169">"Otimizando app <xliff:g id="NUMBER_0">%1$d</xliff:g> de <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
<string name="android_upgrading_starting_apps" msgid="451464516346926713">"Iniciando apps."</string>
<string name="android_upgrading_complete" msgid="1405954754112999229">"Concluindo a inicialização."</string>
@@ -1791,4 +1799,6 @@
<!-- no translation found for zen_mode_until (7336308492289875088) -->
<skip />
<string name="zen_mode_forever" msgid="4316804956488785559">"Indefinidamente"</string>
+ <!-- no translation found for toolbar_collapse_description (2821479483960330739) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml
index 6ae7f52..a602257 100644
--- a/core/res/res/values-ro/strings.xml
+++ b/core/res/res/values-ro/strings.xml
@@ -716,14 +716,16 @@
<string name="permdesc_cache_filesystem" msgid="5578967642265550955">"Permite aplicaţiei să scrie şi să citească sistemul de fişiere cache."</string>
<string name="permlab_use_sip" msgid="2052499390128979920">"efectuarea/primirea apelurilor SIP"</string>
<string name="permdesc_use_sip" msgid="2297804849860225257">"Permite aplicației să efectueze și să primească apeluri SIP."</string>
- <!-- no translation found for permlab_register_provider (2654513709546459553) -->
+ <!-- no translation found for permlab_register_sim_subscription (3166535485877549177) -->
<skip />
- <!-- no translation found for permdesc_register_provider (7571533832018681544) -->
+ <!-- no translation found for permdesc_register_sim_subscription (2138909035926222911) -->
<skip />
- <!-- no translation found for permlab_connection_manager (1116193254522105375) -->
+ <!-- no translation found for permlab_register_call_provider (108102120289029841) -->
<skip />
- <!-- no translation found for permdesc_connection_manager (5925480810356483565) -->
+ <!-- no translation found for permdesc_register_call_provider (7034310263521081388) -->
<skip />
+ <string name="permlab_connection_manager" msgid="1116193254522105375">"gestionarea conexiunilor de telecomunicații"</string>
+ <string name="permdesc_connection_manager" msgid="5925480810356483565">"Permite aplicației să gestioneze conexiuni de telecomunicații."</string>
<string name="permlab_bind_incall_service" msgid="6773648341975287125">"interacțiune cu ecranul în timpul unui apel"</string>
<string name="permdesc_bind_incall_service" msgid="8343471381323215005">"Permite aplicației să controleze când și cum vede utilizatorul ecranul în timpul unui apel."</string>
<string name="permlab_bind_connection_service" msgid="3557341439297014940">"să interacționeze cu servicii de telefonie"</string>
@@ -1237,6 +1239,7 @@
<string name="smv_application" msgid="3307209192155442829">"Aplicaţia <xliff:g id="APPLICATION">%1$s</xliff:g> (procesul <xliff:g id="PROCESS">%2$s</xliff:g>) a încălcat propria politică StrictMode."</string>
<string name="smv_process" msgid="5120397012047462446">"Procesul <xliff:g id="PROCESS">%1$s</xliff:g> a încălcat propria politică StrictMode."</string>
<string name="android_upgrading_title" msgid="1584192285441405746">"Android trece la o vers. superioară..."</string>
+ <string name="android_start_title" msgid="8418054686415318207">"Android pornește..."</string>
<string name="android_upgrading_apk" msgid="7904042682111526169">"Se optimizează aplicaţia <xliff:g id="NUMBER_0">%1$d</xliff:g> din <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
<string name="android_upgrading_starting_apps" msgid="451464516346926713">"Se pornesc aplicaţiile."</string>
<string name="android_upgrading_complete" msgid="1405954754112999229">"Se finalizează pornirea."</string>
@@ -1780,10 +1783,14 @@
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Solicită parola înainte de a anula fixarea"</string>
<string name="battery_saver_description" msgid="2510530476513605742">"Pentru a ajuta la îmbunătățirea duratei bateriei, modul Economisirea bateriei reduce performanțele dispozitivului și limitează vibrațiile și majoritatea datelor de fundal. Mesajele prin e-mail și alte aplicații care se bazează pe sincronizare nu se vor actualiza dacă nu le deschideți.\n\nEconomisirea baterie se dezactivează automat când dispozitivul se încarcă."</string>
<string name="downtime_condition_summary" msgid="8761776337475705749">"Până când inactivitatea dvs. se încheie la <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
- <!-- no translation found for zen_mode_duration_minutes_summary:one (3177683545388923234) -->
- <!-- no translation found for zen_mode_duration_minutes_summary:other (2787867221129368935) -->
- <!-- no translation found for zen_mode_duration_hours_summary:one (597194865053253679) -->
- <!-- no translation found for zen_mode_duration_hours_summary:other (2827214920627669898) -->
+ <plurals name="zen_mode_duration_minutes_summary">
+ <item quantity="one" msgid="3177683545388923234">"Timp de un minut (până la <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ <item quantity="other" msgid="2787867221129368935">"Timp de %1$d (de) minute (până la <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ </plurals>
+ <plurals name="zen_mode_duration_hours_summary">
+ <item quantity="one" msgid="597194865053253679">"Timp de o oră (până la <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ <item quantity="other" msgid="2827214920627669898">"Timp de %1$d (de) ore (până la <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ </plurals>
<plurals name="zen_mode_duration_minutes">
<item quantity="one" msgid="9040808414992812341">"Timp de un minut"</item>
<item quantity="other" msgid="6924190729213550991">"Timp de %d (de) minute"</item>
@@ -1792,7 +1799,7 @@
<item quantity="one" msgid="3480040795582254384">"Timp de o oră"</item>
<item quantity="other" msgid="5408537517529822157">"Timp de %d (de) ore"</item>
</plurals>
- <!-- no translation found for zen_mode_until (7336308492289875088) -->
- <skip />
+ <string name="zen_mode_until" msgid="7336308492289875088">"Până la <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
<string name="zen_mode_forever" msgid="4316804956488785559">"Nedefinit"</string>
+ <string name="toolbar_collapse_description" msgid="2821479483960330739">"Restrângeți"</string>
</resources>
diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml
index c12a0c8..3f67e8f 100644
--- a/core/res/res/values-ru/strings.xml
+++ b/core/res/res/values-ru/strings.xml
@@ -716,8 +716,14 @@
<string name="permdesc_cache_filesystem" msgid="5578967642265550955">"Приложение сможет выполнять чтение и запись в файловую систему кеша."</string>
<string name="permlab_use_sip" msgid="2052499390128979920">"Входящие и исходящие вызовы SIP"</string>
<string name="permdesc_use_sip" msgid="2297804849860225257">"Разрешить вызовы по протоколу SIP."</string>
- <string name="permlab_register_provider" msgid="2654513709546459553">"регистрация подключений"</string>
- <string name="permdesc_register_provider" msgid="7571533832018681544">"Регистрация новых сетевых подключений."</string>
+ <!-- no translation found for permlab_register_sim_subscription (3166535485877549177) -->
+ <skip />
+ <!-- no translation found for permdesc_register_sim_subscription (2138909035926222911) -->
+ <skip />
+ <!-- no translation found for permlab_register_call_provider (108102120289029841) -->
+ <skip />
+ <!-- no translation found for permdesc_register_call_provider (7034310263521081388) -->
+ <skip />
<string name="permlab_connection_manager" msgid="1116193254522105375">"управление подключениями"</string>
<string name="permdesc_connection_manager" msgid="5925480810356483565">"Управление сетевыми подключениями."</string>
<string name="permlab_bind_incall_service" msgid="6773648341975287125">"Управление экраном во время разговора"</string>
@@ -1233,6 +1239,7 @@
<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_apk" msgid="7904042682111526169">"Оптимизация приложения <xliff:g id="NUMBER_0">%1$d</xliff:g> из <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
<string name="android_upgrading_starting_apps" msgid="451464516346926713">"Запуск приложений."</string>
<string name="android_upgrading_complete" msgid="1405954754112999229">"Окончание загрузки..."</string>
@@ -1776,10 +1783,14 @@
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Запрашивать пароль для отключения блокировки"</string>
<string name="battery_saver_description" msgid="2510530476513605742">"Чтобы продлить время работы устройства от батареи, в режиме энергосбережения снижается производительность, а также ограничивается использование вибросигнала и фоновой передачи данных. Данные, требующие синхронизации, могут обновляться только когда вы откроете приложение.\n\nРежим энергосбережения автоматически отключается во время зарядки устройства."</string>
<string name="downtime_condition_summary" msgid="8761776337475705749">"До отключения режима (в <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>)"</string>
- <!-- no translation found for zen_mode_duration_minutes_summary:one (3177683545388923234) -->
- <!-- no translation found for zen_mode_duration_minutes_summary:other (2787867221129368935) -->
- <!-- no translation found for zen_mode_duration_hours_summary:one (597194865053253679) -->
- <!-- no translation found for zen_mode_duration_hours_summary:other (2827214920627669898) -->
+ <plurals name="zen_mode_duration_minutes_summary">
+ <item quantity="one" msgid="3177683545388923234">"На 1 мин. (до <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ <item quantity="other" msgid="2787867221129368935">"На %1$d мин. (до <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ </plurals>
+ <plurals name="zen_mode_duration_hours_summary">
+ <item quantity="one" msgid="597194865053253679">"На 1 ч. (до <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ <item quantity="other" msgid="2827214920627669898">"На %1$d ч. (до <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ </plurals>
<plurals name="zen_mode_duration_minutes">
<item quantity="one" msgid="9040808414992812341">"1 мин."</item>
<item quantity="other" msgid="6924190729213550991">"%d мин."</item>
@@ -1788,7 +1799,7 @@
<item quantity="one" msgid="3480040795582254384">"1 ч."</item>
<item quantity="other" msgid="5408537517529822157">"%d ч."</item>
</plurals>
- <!-- no translation found for zen_mode_until (7336308492289875088) -->
- <skip />
+ <string name="zen_mode_until" msgid="7336308492289875088">"До <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
<string name="zen_mode_forever" msgid="4316804956488785559">"Бессрочно"</string>
+ <string name="toolbar_collapse_description" msgid="2821479483960330739">"Свернуть"</string>
</resources>
diff --git a/core/res/res/values-si-rLK/strings.xml b/core/res/res/values-si-rLK/strings.xml
index b8042f7..75347d5 100644
--- a/core/res/res/values-si-rLK/strings.xml
+++ b/core/res/res/values-si-rLK/strings.xml
@@ -716,14 +716,16 @@
<string name="permdesc_cache_filesystem" msgid="5578967642265550955">"හැඹිලි ගොනු පද්ධති කියවීමට සහ ලිවීමට යෙදුමට අවසර දෙන්න."</string>
<string name="permlab_use_sip" msgid="2052499390128979920">"SIP ඇමතුම් සිදුකිරීමට/ලබාගැනීමට"</string>
<string name="permdesc_use_sip" msgid="2297804849860225257">"SIP ඇමතුම් සිදුකිරීමට සහ ලබාගැනීමට යෙදුමට ඉඩ දෙන්න."</string>
- <!-- no translation found for permlab_register_provider (2654513709546459553) -->
+ <!-- no translation found for permlab_register_sim_subscription (3166535485877549177) -->
<skip />
- <!-- no translation found for permdesc_register_provider (7571533832018681544) -->
+ <!-- no translation found for permdesc_register_sim_subscription (2138909035926222911) -->
<skip />
- <!-- no translation found for permlab_connection_manager (1116193254522105375) -->
+ <!-- no translation found for permlab_register_call_provider (108102120289029841) -->
<skip />
- <!-- no translation found for permdesc_connection_manager (5925480810356483565) -->
+ <!-- no translation found for permdesc_register_call_provider (7034310263521081388) -->
<skip />
+ <string name="permlab_connection_manager" msgid="1116193254522105375">"විදුලි සංදේශන සම්බන්ධතා කළමණාකරණය කරන්න"</string>
+ <string name="permdesc_connection_manager" msgid="5925480810356483565">"විදුලි සංදේශන සම්බන්ධතා කළමණාකරණය කිරීමට යෙදුමට ඉඩ දෙන්න."</string>
<string name="permlab_bind_incall_service" msgid="6773648341975287125">"ලැබෙන ඇමතුම් තිරය සමග අන්තර් ක්රියාකාරී වන්න"</string>
<string name="permdesc_bind_incall_service" msgid="8343471381323215005">"ලැබෙන ඇමතුම් තිරය පරිශීලකයාට පෙනෙන්නේ කෙදිනද සහ කෙසේද යැයි පාලනය කිරීමට යෙදුමට අවසර දෙන්න."</string>
<string name="permlab_bind_connection_service" msgid="3557341439297014940">"දුරකථන සේවාවන් සමඟ සම්බන්ධ වීම"</string>
@@ -1239,6 +1241,7 @@
<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_apk" msgid="7904042682111526169">"<xliff:g id="NUMBER_1">%2$d</xliff:g> කින් <xliff:g id="NUMBER_0">%1$d</xliff:g> වැනි යෙදුම ප්රශස්ත කරමින්."</string>
<string name="android_upgrading_starting_apps" msgid="451464516346926713">"යෙදුම් ආරම්භ කරමින්."</string>
<string name="android_upgrading_complete" msgid="1405954754112999229">"ඇරඹුම අවසාන කරමින්."</string>
@@ -1782,10 +1785,14 @@
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"ගැලවීමට පෙර මුරපදය විමසන්න"</string>
<string name="battery_saver_description" msgid="2510530476513605742">"බැටරියේ ජීව කාලය දියුණු කිරීමට උදව් කිරීමට, ඔබගේ උපාංගයේ ක්රියාකාරිත්වය සහ සීමා කළ කම්පනයන් සහ බොහොමයක් පසුබිම් දත්ත බැටරි සුරැකීමෙන් අඩු කරයි. සමමුහුර්ත කිරීම බලාපොරොත්තු වෙන ඊ-තැපෑල, පණිවිඩ යැවීම සහ වෙනත් යෙදුම් යාවත්කාලීන වන්නේ ඔබ ඒවා විවෘත කළ විට පමණි.\n\nඔබගේ උපාංගය ආරෝපණය වන විට බැටරි සුරැකීම ස්වයංක්රීයව අක්රිය වේ."</string>
<string name="downtime_condition_summary" msgid="8761776337475705749">"ඔබගේ බිඳවැටුම් වේලාව <xliff:g id="FORMATTEDTIME">%1$s</xliff:g> දී අවසන්වන තුරු"</string>
- <!-- no translation found for zen_mode_duration_minutes_summary:one (3177683545388923234) -->
- <!-- no translation found for zen_mode_duration_minutes_summary:other (2787867221129368935) -->
- <!-- no translation found for zen_mode_duration_hours_summary:one (597194865053253679) -->
- <!-- no translation found for zen_mode_duration_hours_summary:other (2827214920627669898) -->
+ <plurals name="zen_mode_duration_minutes_summary">
+ <item quantity="one" msgid="3177683545388923234">"මිනිත්තු එකක් සඳහා (<xliff:g id="FORMATTEDTIME">%2$s</xliff:g> තෙක්)"</item>
+ <item quantity="other" msgid="2787867221129368935">"මිනිත්තු %1$d සඳහා (<xliff:g id="FORMATTEDTIME">%2$s</xliff:g> තෙක්)"</item>
+ </plurals>
+ <plurals name="zen_mode_duration_hours_summary">
+ <item quantity="one" msgid="597194865053253679">"පැය එකක් සඳහා (<xliff:g id="FORMATTEDTIME">%2$s</xliff:g> තෙක්)"</item>
+ <item quantity="other" msgid="2827214920627669898">"පැය %1$d සඳහා (<xliff:g id="FORMATTEDTIME">%2$s</xliff:g> තෙක්)"</item>
+ </plurals>
<plurals name="zen_mode_duration_minutes">
<item quantity="one" msgid="9040808414992812341">"විනාඩි එකක් සඳහා"</item>
<item quantity="other" msgid="6924190729213550991">"විනාඩි %d සඳහා"</item>
@@ -1794,7 +1801,7 @@
<item quantity="one" msgid="3480040795582254384">"පැයක් සඳහා"</item>
<item quantity="other" msgid="5408537517529822157">"පැය %d ක් සඳහා"</item>
</plurals>
- <!-- no translation found for zen_mode_until (7336308492289875088) -->
- <skip />
+ <string name="zen_mode_until" msgid="7336308492289875088">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g> තෙක්"</string>
<string name="zen_mode_forever" msgid="4316804956488785559">"අනියත ආකාරයට"</string>
+ <string name="toolbar_collapse_description" msgid="2821479483960330739">"හකුළන්න"</string>
</resources>
diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml
index 2ac1c56..5567ccd 100644
--- a/core/res/res/values-sk/strings.xml
+++ b/core/res/res/values-sk/strings.xml
@@ -716,8 +716,14 @@
<string name="permdesc_cache_filesystem" msgid="5578967642265550955">"Umožňuje aplikácii čítať a zapisovať do súborového systému vyrovnávacej pamäte."</string>
<string name="permlab_use_sip" msgid="2052499390128979920">"uskutočňovanie/príjem hovorov SIP"</string>
<string name="permdesc_use_sip" msgid="2297804849860225257">"Umožňuje aplikácii uskutočňovať a prijímať hovory SIP."</string>
- <string name="permlab_register_provider" msgid="2654513709546459553">"registrácia nových pripojení telefonických sietí"</string>
- <string name="permdesc_register_provider" msgid="7571533832018681544">"Povoľuje aplikácii registrovať nové pripojenia telekomunikačnej siete."</string>
+ <!-- no translation found for permlab_register_sim_subscription (3166535485877549177) -->
+ <skip />
+ <!-- no translation found for permdesc_register_sim_subscription (2138909035926222911) -->
+ <skip />
+ <!-- no translation found for permlab_register_call_provider (108102120289029841) -->
+ <skip />
+ <!-- no translation found for permdesc_register_call_provider (7034310263521081388) -->
+ <skip />
<string name="permlab_connection_manager" msgid="1116193254522105375">"správa pripojení telefonických sietí"</string>
<string name="permdesc_connection_manager" msgid="5925480810356483565">"Povoľuje aplikácii spravovať pripojenia telekomunikačnej siete."</string>
<string name="permlab_bind_incall_service" msgid="6773648341975287125">"interakcia s obrazovkou hovoru"</string>
@@ -1233,6 +1239,7 @@
<string name="smv_application" msgid="3307209192155442829">"Aplikácia <xliff:g id="APPLICATION">%1$s</xliff:g> (proces <xliff:g id="PROCESS">%2$s</xliff:g>) porušila svoje vlastné vynútené pravidlá StrictMode."</string>
<string name="smv_process" msgid="5120397012047462446">"Proces <xliff:g id="PROCESS">%1$s</xliff:g> porušil svoje vlastné vynútené pravidlá StrictMode."</string>
<string name="android_upgrading_title" msgid="1584192285441405746">"Prebieha inovácia systému Android..."</string>
+ <string name="android_start_title" msgid="8418054686415318207">"Systém Android sa spúšťa…"</string>
<string name="android_upgrading_apk" msgid="7904042682111526169">"Prebieha optimalizácia aplikácie <xliff:g id="NUMBER_0">%1$d</xliff:g> z <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
<string name="android_upgrading_starting_apps" msgid="451464516346926713">"Prebieha spúšťanie aplikácií."</string>
<string name="android_upgrading_complete" msgid="1405954754112999229">"Prebieha dokončovanie spúšťania."</string>
@@ -1776,10 +1783,14 @@
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Pred uvoľnením požiadať o heslo"</string>
<string name="battery_saver_description" msgid="2510530476513605742">"Na predĺženie výdrže batérie šetrič batérie znižuje výkonnosť zariadenia a obmedzuje vibrácie a prenos údajov na pozadí. E-mail, správy a ďalšie aplikácie, ktoré používajú synchronizáciu, sa možno nebudú aktualizovať, dokiaľ ich neotvoríte.\n\nPri nabíjaní zariadenia sa šetrič batérie automaticky vypne."</string>
<string name="downtime_condition_summary" msgid="8761776337475705749">"Dokým o <xliff:g id="FORMATTEDTIME">%1$s</xliff:g> neskončí výpadok"</string>
- <!-- no translation found for zen_mode_duration_minutes_summary:one (3177683545388923234) -->
- <!-- no translation found for zen_mode_duration_minutes_summary:other (2787867221129368935) -->
- <!-- no translation found for zen_mode_duration_hours_summary:one (597194865053253679) -->
- <!-- no translation found for zen_mode_duration_hours_summary:other (2827214920627669898) -->
+ <plurals name="zen_mode_duration_minutes_summary">
+ <item quantity="one" msgid="3177683545388923234">"Na minútu (do <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ <item quantity="other" msgid="2787867221129368935">"Na %1$d min. (do <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ </plurals>
+ <plurals name="zen_mode_duration_hours_summary">
+ <item quantity="one" msgid="597194865053253679">"Na hodinu (do <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ <item quantity="other" msgid="2827214920627669898">"Na %1$d hod. (do <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ </plurals>
<plurals name="zen_mode_duration_minutes">
<item quantity="one" msgid="9040808414992812341">"Na jednu minútu"</item>
<item quantity="other" msgid="6924190729213550991">"Na %d min"</item>
@@ -1788,7 +1799,7 @@
<item quantity="one" msgid="3480040795582254384">"Na 1 h"</item>
<item quantity="other" msgid="5408537517529822157">"Na %d h"</item>
</plurals>
- <!-- no translation found for zen_mode_until (7336308492289875088) -->
- <skip />
+ <string name="zen_mode_until" msgid="7336308492289875088">"Do <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
<string name="zen_mode_forever" msgid="4316804956488785559">"Natrvalo"</string>
+ <string name="toolbar_collapse_description" msgid="2821479483960330739">"Zbaliť"</string>
</resources>
diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml
index fc7d93e..0af2557 100644
--- a/core/res/res/values-sl/strings.xml
+++ b/core/res/res/values-sl/strings.xml
@@ -716,8 +716,14 @@
<string name="permdesc_cache_filesystem" msgid="5578967642265550955">"Aplikaciji omogoča branje in pisanje v datotečni sistem predpomnilnika."</string>
<string name="permlab_use_sip" msgid="2052499390128979920">"opravljanje/sprejemanje klicev SIP"</string>
<string name="permdesc_use_sip" msgid="2297804849860225257">"Aplikaciji omogoča opravljanje in sprejemanje klicev SIP."</string>
- <string name="permlab_register_provider" msgid="2654513709546459553">"registriranje nove telekomunikacijske povezave"</string>
- <string name="permdesc_register_provider" msgid="7571533832018681544">"Aplikaciji omogoča registriranje novih telekomunikacijskih povezav."</string>
+ <!-- no translation found for permlab_register_sim_subscription (3166535485877549177) -->
+ <skip />
+ <!-- no translation found for permdesc_register_sim_subscription (2138909035926222911) -->
+ <skip />
+ <!-- no translation found for permlab_register_call_provider (108102120289029841) -->
+ <skip />
+ <!-- no translation found for permdesc_register_call_provider (7034310263521081388) -->
+ <skip />
<string name="permlab_connection_manager" msgid="1116193254522105375">"upravljanje telekomunikacijskih povezav"</string>
<string name="permdesc_connection_manager" msgid="5925480810356483565">"Aplikaciji omogoča upravljanje telekomunikacijskih povezav."</string>
<string name="permlab_bind_incall_service" msgid="6773648341975287125">"interakcija z zaslonom pri klicu"</string>
@@ -1233,6 +1239,7 @@
<string name="smv_application" msgid="3307209192155442829">"Aplikacija <xliff:g id="APPLICATION">%1$s</xliff:g> (proces <xliff:g id="PROCESS">%2$s</xliff:g>) krši svoj samouveljavljiv pravilnik o strogem načinu."</string>
<string name="smv_process" msgid="5120397012047462446">"Proces <xliff:g id="PROCESS">%1$s</xliff:g> krši svoj samoizvedljivi pravilnik o strogem načinu."</string>
<string name="android_upgrading_title" msgid="1584192285441405746">"Poteka nadgradnja Androida ..."</string>
+ <string name="android_start_title" msgid="8418054686415318207">"Android se zaganja …"</string>
<string name="android_upgrading_apk" msgid="7904042682111526169">"Optimiranje aplikacije <xliff:g id="NUMBER_0">%1$d</xliff:g> od <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
<string name="android_upgrading_starting_apps" msgid="451464516346926713">"Zagon aplikacij."</string>
<string name="android_upgrading_complete" msgid="1405954754112999229">"Dokončevanje zagona."</string>
@@ -1776,10 +1783,14 @@
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Pred odpenjanjem vprašaj za geslo"</string>
<string name="battery_saver_description" msgid="2510530476513605742">"Varčevanje z energijo akumulatorja poveča čas delovanja akumulatorja, tako da zmanjša zmogljivost delovanja naprave in omeji vibriranje ter prenos večine podatkov v ozadju. Aplikacije za e-pošto, sporočanje in drugo, ki uporabljajo sinhroniziranje, se morda ne posodabljajo, razen če jih odprete.\n\nVarčevanje z energijo se samodejno izklopi med polnjenjem akumulatorja naprave."</string>
<string name="downtime_condition_summary" msgid="8761776337475705749">"Do konca prekinitve delovanja ob <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
- <!-- no translation found for zen_mode_duration_minutes_summary:one (3177683545388923234) -->
- <!-- no translation found for zen_mode_duration_minutes_summary:other (2787867221129368935) -->
- <!-- no translation found for zen_mode_duration_hours_summary:one (597194865053253679) -->
- <!-- no translation found for zen_mode_duration_hours_summary:other (2827214920627669898) -->
+ <plurals name="zen_mode_duration_minutes_summary">
+ <item quantity="one" msgid="3177683545388923234">"Eno minuto (do <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ <item quantity="other" msgid="2787867221129368935">"Toliko minut: %1$d (do <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ </plurals>
+ <plurals name="zen_mode_duration_hours_summary">
+ <item quantity="one" msgid="597194865053253679">"Eno uro (do <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ <item quantity="other" msgid="2827214920627669898">"Toliko ur: %1$d (do <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ </plurals>
<plurals name="zen_mode_duration_minutes">
<item quantity="one" msgid="9040808414992812341">"Za eno minuto"</item>
<item quantity="other" msgid="6924190729213550991">"Za %d min"</item>
@@ -1788,7 +1799,7 @@
<item quantity="one" msgid="3480040795582254384">"Za eno uro"</item>
<item quantity="other" msgid="5408537517529822157">"Za %d h"</item>
</plurals>
- <!-- no translation found for zen_mode_until (7336308492289875088) -->
- <skip />
+ <string name="zen_mode_until" msgid="7336308492289875088">"Do <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
<string name="zen_mode_forever" msgid="4316804956488785559">"Za nedoločen čas"</string>
+ <string name="toolbar_collapse_description" msgid="2821479483960330739">"Strni"</string>
</resources>
diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml
index 4b44223..801d3cc 100644
--- a/core/res/res/values-sr/strings.xml
+++ b/core/res/res/values-sr/strings.xml
@@ -716,8 +716,14 @@
<string name="permdesc_cache_filesystem" msgid="5578967642265550955">"Дозвољава апликацији да чита систем датотека кеша и уписује податке у њега."</string>
<string name="permlab_use_sip" msgid="2052499390128979920">"упућивање/пријем SIP позива"</string>
<string name="permdesc_use_sip" msgid="2297804849860225257">"Омогућава апликацији да упућује и прима SIP позиве."</string>
- <string name="permlab_register_provider" msgid="2654513709546459553">"регистровање нових веза са телекомуникационим мрежама"</string>
- <string name="permdesc_register_provider" msgid="7571533832018681544">"Дозвољава апликацији да региструје нове везе са телекомуникационим мрежама."</string>
+ <!-- no translation found for permlab_register_sim_subscription (3166535485877549177) -->
+ <skip />
+ <!-- no translation found for permdesc_register_sim_subscription (2138909035926222911) -->
+ <skip />
+ <!-- no translation found for permlab_register_call_provider (108102120289029841) -->
+ <skip />
+ <!-- no translation found for permdesc_register_call_provider (7034310263521081388) -->
+ <skip />
<string name="permlab_connection_manager" msgid="1116193254522105375">"управљање везама са телекомуникационим мрежама"</string>
<string name="permdesc_connection_manager" msgid="5925480810356483565">"Дозвољава апликацији да управља везама са телекомуникационим мрежама."</string>
<string name="permlab_bind_incall_service" msgid="6773648341975287125">"комуницирај са екраном током позива"</string>
@@ -1233,6 +1239,7 @@
<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_apk" msgid="7904042682111526169">"Оптимизовање апликације <xliff:g id="NUMBER_0">%1$d</xliff:g> од <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
<string name="android_upgrading_starting_apps" msgid="451464516346926713">"Покретање апликација."</string>
<string name="android_upgrading_complete" msgid="1405954754112999229">"Завршавање покретања."</string>
@@ -1776,10 +1783,14 @@
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Тражи лозинку пре откачињања"</string>
<string name="battery_saver_description" msgid="2510530476513605742">"Да би смањила потрошњу батерије, Штедња батерије снижава перформансе уређаја, ограничава вибрацију и већину позадинских података. Имејл, размена порука и друге апликације које се ослањају на синхронизацију се можда неће ажурирати ако их не отворите.\n\nШтедња батерије се аутоматски искључује када се уређај пуни."</string>
<string name="downtime_condition_summary" msgid="8761776337475705749">"Док се прекид рада не заврши у <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
- <!-- no translation found for zen_mode_duration_minutes_summary:one (3177683545388923234) -->
- <!-- no translation found for zen_mode_duration_minutes_summary:other (2787867221129368935) -->
- <!-- no translation found for zen_mode_duration_hours_summary:one (597194865053253679) -->
- <!-- no translation found for zen_mode_duration_hours_summary:other (2827214920627669898) -->
+ <plurals name="zen_mode_duration_minutes_summary">
+ <item quantity="one" msgid="3177683545388923234">"Један минут (до <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ <item quantity="other" msgid="2787867221129368935">"%1$d минута (до <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ </plurals>
+ <plurals name="zen_mode_duration_hours_summary">
+ <item quantity="one" msgid="597194865053253679">"Један сат (до <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ <item quantity="other" msgid="2827214920627669898">"%1$d сата(и) (до <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ </plurals>
<plurals name="zen_mode_duration_minutes">
<item quantity="one" msgid="9040808414992812341">"Један минут"</item>
<item quantity="other" msgid="6924190729213550991">"%d мин"</item>
@@ -1788,7 +1799,7 @@
<item quantity="one" msgid="3480040795582254384">"Један сат"</item>
<item quantity="other" msgid="5408537517529822157">"%d с"</item>
</plurals>
- <!-- no translation found for zen_mode_until (7336308492289875088) -->
- <skip />
+ <string name="zen_mode_until" msgid="7336308492289875088">"До <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
<string name="zen_mode_forever" msgid="4316804956488785559">"Бесконачно"</string>
+ <string name="toolbar_collapse_description" msgid="2821479483960330739">"Скупи"</string>
</resources>
diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml
index 9008529..7c63a4f 100644
--- a/core/res/res/values-sv/strings.xml
+++ b/core/res/res/values-sv/strings.xml
@@ -716,8 +716,14 @@
<string name="permdesc_cache_filesystem" msgid="5578967642265550955">"Tillåter att appen läser och skriver till cachefilsystemet."</string>
<string name="permlab_use_sip" msgid="2052499390128979920">"gör/ta emot SIP-anrop"</string>
<string name="permdesc_use_sip" msgid="2297804849860225257">"Tillåter att appen gör och tar emot SIP-anrop."</string>
- <string name="permlab_register_provider" msgid="2654513709546459553">"registrera ny telekommunikationsanslutning"</string>
- <string name="permdesc_register_provider" msgid="7571533832018681544">"Tillåter att appen registrerar nya telekommunikationsanslutningar."</string>
+ <!-- no translation found for permlab_register_sim_subscription (3166535485877549177) -->
+ <skip />
+ <!-- no translation found for permdesc_register_sim_subscription (2138909035926222911) -->
+ <skip />
+ <!-- no translation found for permlab_register_call_provider (108102120289029841) -->
+ <skip />
+ <!-- no translation found for permdesc_register_call_provider (7034310263521081388) -->
+ <skip />
<string name="permlab_connection_manager" msgid="1116193254522105375">"hantera telekommunikationsanslutningar"</string>
<string name="permdesc_connection_manager" msgid="5925480810356483565">"Tillåter att appen hanterar telekommunikationsanslutningar."</string>
<string name="permlab_bind_incall_service" msgid="6773648341975287125">"interagera med skärmen för inkommande samtal"</string>
@@ -1233,6 +1239,7 @@
<string name="smv_application" msgid="3307209192155442829">"Appen <xliff:g id="APPLICATION">%1$s</xliff:g> (processen <xliff:g id="PROCESS">%2$s</xliff:g>) har brutit mot sin egen StrictMode-policy."</string>
<string name="smv_process" msgid="5120397012047462446">"Processen <xliff:g id="PROCESS">%1$s</xliff:g> har brutit mot sin egen StrictMode-policy."</string>
<string name="android_upgrading_title" msgid="1584192285441405746">"Android uppgraderas ..."</string>
+ <string name="android_start_title" msgid="8418054686415318207">"Android startar …"</string>
<string name="android_upgrading_apk" msgid="7904042682111526169">"Optimerar app <xliff:g id="NUMBER_0">%1$d</xliff:g> av <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
<string name="android_upgrading_starting_apps" msgid="451464516346926713">"Appar startas."</string>
<string name="android_upgrading_complete" msgid="1405954754112999229">"Uppgraderingen är klar."</string>
@@ -1776,10 +1783,14 @@
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Be om lösenord innan skärmen slutar fästas"</string>
<string name="battery_saver_description" msgid="2510530476513605742">"I batterisparläget reduceras enhetens prestanda så att batteriet ska räcka längre, och vibration samt den mesta användningen av bakgrundsdata begränsas. Det kan hända att appar för e-post, sms och annat som kräver synkronisering inte uppdateras förrän du öppnar dem.\n\nBatterisparläget inaktiveras automatiskt när enheten laddas."</string>
<string name="downtime_condition_summary" msgid="8761776337475705749">"Tills avbrottstiden är slut <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
- <!-- no translation found for zen_mode_duration_minutes_summary:one (3177683545388923234) -->
- <!-- no translation found for zen_mode_duration_minutes_summary:other (2787867221129368935) -->
- <!-- no translation found for zen_mode_duration_hours_summary:one (597194865053253679) -->
- <!-- no translation found for zen_mode_duration_hours_summary:other (2827214920627669898) -->
+ <plurals name="zen_mode_duration_minutes_summary">
+ <item quantity="one" msgid="3177683545388923234">"I en minut (till kl. <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ <item quantity="other" msgid="2787867221129368935">"I %1$d minuter (till kl. <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ </plurals>
+ <plurals name="zen_mode_duration_hours_summary">
+ <item quantity="one" msgid="597194865053253679">"I en timme (till kl. <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ <item quantity="other" msgid="2827214920627669898">"I %1$d timmar (till kl. <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ </plurals>
<plurals name="zen_mode_duration_minutes">
<item quantity="one" msgid="9040808414992812341">"I en minut"</item>
<item quantity="other" msgid="6924190729213550991">"I %d minuter"</item>
@@ -1788,7 +1799,7 @@
<item quantity="one" msgid="3480040795582254384">"I en timme"</item>
<item quantity="other" msgid="5408537517529822157">"I %d timmar"</item>
</plurals>
- <!-- no translation found for zen_mode_until (7336308492289875088) -->
- <skip />
+ <string name="zen_mode_until" msgid="7336308492289875088">"Till kl. <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
<string name="zen_mode_forever" msgid="4316804956488785559">"För alltid"</string>
+ <string name="toolbar_collapse_description" msgid="2821479483960330739">"Komprimera"</string>
</resources>
diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml
index 785f2ff..3bf0466 100644
--- a/core/res/res/values-sw/strings.xml
+++ b/core/res/res/values-sw/strings.xml
@@ -716,8 +716,14 @@
<string name="permdesc_cache_filesystem" msgid="5578967642265550955">"Huruhusu programu kusoma na kuandika mfumo wa faili wa akiba."</string>
<string name="permlab_use_sip" msgid="2052499390128979920">"piga/pokea simu za SIP"</string>
<string name="permdesc_use_sip" msgid="2297804849860225257">"Ruhusu programu ipige na kupokea simu za SIP."</string>
- <string name="permlab_register_provider" msgid="2654513709546459553">"sajili muunganisho mpya wa mawasiliano ya simu"</string>
- <string name="permdesc_register_provider" msgid="7571533832018681544">"Huruhusu programu kuandikisha miunganisho mipya ya mawasiliano ya simu."</string>
+ <!-- no translation found for permlab_register_sim_subscription (3166535485877549177) -->
+ <skip />
+ <!-- no translation found for permdesc_register_sim_subscription (2138909035926222911) -->
+ <skip />
+ <!-- no translation found for permlab_register_call_provider (108102120289029841) -->
+ <skip />
+ <!-- no translation found for permdesc_register_call_provider (7034310263521081388) -->
+ <skip />
<string name="permlab_connection_manager" msgid="1116193254522105375">"dhibiti miunganisho ya mawasiliano ya simu"</string>
<string name="permdesc_connection_manager" msgid="5925480810356483565">"Huruhusu programu kudhibiti miunganisho ya mawasiliano ya simu."</string>
<string name="permlab_bind_incall_service" msgid="6773648341975287125">"wezesha mwingiliano na skrini ya simu inayoingia"</string>
@@ -1233,6 +1239,7 @@
<string name="smv_application" msgid="3307209192155442829">"Programu <xliff:g id="APPLICATION">%1$s</xliff:g> (utaratibu <xliff:g id="PROCESS">%2$s</xliff:g>) imeenda kinyume na sera yake ya StrictMode."</string>
<string name="smv_process" msgid="5120397012047462446">"Shughuli ya <xliff:g id="PROCESS">%1$s</xliff:g> imeenda kinyume na kulazimisha sera yake ya StrictMode."</string>
<string name="android_upgrading_title" msgid="1584192285441405746">"Toleo jipya la Android linawekwa..."</string>
+ <string name="android_start_title" msgid="8418054686415318207">"Inaanzisha Android..."</string>
<string name="android_upgrading_apk" msgid="7904042682111526169">"Inaboresha programu <xliff:g id="NUMBER_0">%1$d</xliff:g> kutoka <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
<string name="android_upgrading_starting_apps" msgid="451464516346926713">"Programu zinaanza"</string>
<string name="android_upgrading_complete" msgid="1405954754112999229">"Inamaliza kuwasha."</string>
@@ -1776,10 +1783,14 @@
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Omba nenosiri kabla hujabandua"</string>
<string name="battery_saver_description" msgid="2510530476513605742">"Ili kusaidia kuokoa muda wa matumizi wa betri, kiokoa betri hupunguza utendaji wa kifaa chako na kuzuia kutetema na data nyingi ya chinichini. Barua pepe, kutuma ujumbe na programu zingine zinazotegemea usawazishaji huenda hazitasasisha usipozifungua.\n\nKiokoa betri hujizima kiotomatiki kifaa chako kikianza kuchajiwa."</string>
<string name="downtime_condition_summary" msgid="8761776337475705749">"Hadi <xliff:g id="FORMATTEDTIME">%1$s</xliff:g> wakati wa kutotenda kazi kwa kifaa chako unapoisha"</string>
- <!-- no translation found for zen_mode_duration_minutes_summary:one (3177683545388923234) -->
- <!-- no translation found for zen_mode_duration_minutes_summary:other (2787867221129368935) -->
- <!-- no translation found for zen_mode_duration_hours_summary:one (597194865053253679) -->
- <!-- no translation found for zen_mode_duration_hours_summary:other (2827214920627669898) -->
+ <plurals name="zen_mode_duration_minutes_summary">
+ <item quantity="one" msgid="3177683545388923234">"Kwa dakika moja (hadi <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ <item quantity="other" msgid="2787867221129368935">"Kwa dakika %1$d (hadi <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ </plurals>
+ <plurals name="zen_mode_duration_hours_summary">
+ <item quantity="one" msgid="597194865053253679">"Kwa saa moja (hadi <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ <item quantity="other" msgid="2827214920627669898">"Kwa saa %1$d (hadi <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ </plurals>
<plurals name="zen_mode_duration_minutes">
<item quantity="one" msgid="9040808414992812341">"Kwa dakika moja"</item>
<item quantity="other" msgid="6924190729213550991">"Kwa dakika %d"</item>
@@ -1788,7 +1799,7 @@
<item quantity="one" msgid="3480040795582254384">"Kwa saa moja"</item>
<item quantity="other" msgid="5408537517529822157">"Kwa saa %d"</item>
</plurals>
- <!-- no translation found for zen_mode_until (7336308492289875088) -->
- <skip />
+ <string name="zen_mode_until" msgid="7336308492289875088">"Hadi <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
<string name="zen_mode_forever" msgid="4316804956488785559">"Bila kikomo"</string>
+ <string name="toolbar_collapse_description" msgid="2821479483960330739">"Kunja"</string>
</resources>
diff --git a/core/res/res/values-ta-rIN/strings.xml b/core/res/res/values-ta-rIN/strings.xml
index 8bec63a..1306712 100644
--- a/core/res/res/values-ta-rIN/strings.xml
+++ b/core/res/res/values-ta-rIN/strings.xml
@@ -716,8 +716,14 @@
<string name="permdesc_cache_filesystem" msgid="5578967642265550955">"தற்காலிகச் சேமிப்பு கோப்பு அமைப்பைப் படிக்க மற்றும் எழுத, பயன்பாட்டை அனுமதிக்கிறது."</string>
<string name="permlab_use_sip" msgid="2052499390128979920">"SIP அழைப்புகளைச் செய்தல்/பெறுதல்"</string>
<string name="permdesc_use_sip" msgid="2297804849860225257">"SIP அழைப்புகளைச் செய்ய/பெற, பயன்பாட்டை அனுமதிக்கிறது."</string>
- <string name="permlab_register_provider" msgid="2654513709546459553">"புதிய தொலைத்தொடர்பு இணைப்பைப் பதிவுசெய்"</string>
- <string name="permdesc_register_provider" msgid="7571533832018681544">"புதிய தொலைத்தொடர்பு இணைப்புகளைப் பதிவுசெய்ய, பயன்பாட்டை அனுமதிக்கும்."</string>
+ <!-- no translation found for permlab_register_sim_subscription (3166535485877549177) -->
+ <skip />
+ <!-- no translation found for permdesc_register_sim_subscription (2138909035926222911) -->
+ <skip />
+ <!-- no translation found for permlab_register_call_provider (108102120289029841) -->
+ <skip />
+ <!-- no translation found for permdesc_register_call_provider (7034310263521081388) -->
+ <skip />
<string name="permlab_connection_manager" msgid="1116193254522105375">"தொலைத்தொடர்பு இணைப்புகளை நிர்வகி"</string>
<string name="permdesc_connection_manager" msgid="5925480810356483565">"தொலைத்தொடர்பு இணைப்புகளை நிர்வகிக்க, பயன்பாட்டை அனுமதிக்கும்."</string>
<string name="permlab_bind_incall_service" msgid="6773648341975287125">"உள்வரும் அழைப்பிற்கான திரையுடன் ஊடாடுதல்"</string>
@@ -1233,6 +1239,7 @@
<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_apk" msgid="7904042682111526169">"<xliff:g id="NUMBER_0">%1$d</xliff:g> / <xliff:g id="NUMBER_1">%2$d</xliff:g> பயன்பாட்டை ஒருங்கிணைக்கிறது."</string>
<string name="android_upgrading_starting_apps" msgid="451464516346926713">"பயன்பாடுகள் தொடங்கப்படுகின்றன."</string>
<string name="android_upgrading_complete" msgid="1405954754112999229">"துவக்குதலை முடிக்கிறது."</string>
@@ -1776,10 +1783,14 @@
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"அகற்றும் முன் கடவுச்சொல்லைக் கேள்"</string>
<string name="battery_saver_description" msgid="2510530476513605742">"பேட்டரியின் ஆயுட்காலத்தை அதிகரிக்க, பேட்டரி சேமிப்பான் சாதனத்தின் செயல்திறனைக் குறைத்து, அதிர்வுறுவதையும் பெரும்பாலான பின்புலத் தரவையும் வரம்பிடுகிறது. ஒத்திசைவைச் சார்ந்திருக்கும் மின்னஞ்சல், மெசேஜ், மேலும் பிற பயன்பாடுகளைத் திறக்கும் வரை, அவை புதுப்பிக்கப்படாமல் இருக்கலாம்.\n\nசாதனம் சார்ஜ் ஆகும் போது, பேட்டரி சேமிப்பான் தானாகவே முடக்கப்படும்."</string>
<string name="downtime_condition_summary" msgid="8761776337475705749">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g> முடியும் வரை"</string>
- <!-- no translation found for zen_mode_duration_minutes_summary:one (3177683545388923234) -->
- <!-- no translation found for zen_mode_duration_minutes_summary:other (2787867221129368935) -->
- <!-- no translation found for zen_mode_duration_hours_summary:one (597194865053253679) -->
- <!-- no translation found for zen_mode_duration_hours_summary:other (2827214920627669898) -->
+ <plurals name="zen_mode_duration_minutes_summary">
+ <item quantity="one" msgid="3177683545388923234">"ஒரு நிமிடத்திற்கு (<xliff:g id="FORMATTEDTIME">%2$s</xliff:g> வரை)"</item>
+ <item quantity="other" msgid="2787867221129368935">"%1$d நிமிடங்களுக்கு (<xliff:g id="FORMATTEDTIME">%2$s</xliff:g> வரை)"</item>
+ </plurals>
+ <plurals name="zen_mode_duration_hours_summary">
+ <item quantity="one" msgid="597194865053253679">"ஒரு மணிநேரத்திற்கு (<xliff:g id="FORMATTEDTIME">%2$s</xliff:g> வரை)"</item>
+ <item quantity="other" msgid="2827214920627669898">"%1$d மணிநேரத்திற்கு (<xliff:g id="FORMATTEDTIME">%2$s</xliff:g> வரை)"</item>
+ </plurals>
<plurals name="zen_mode_duration_minutes">
<item quantity="one" msgid="9040808414992812341">"ஒரு நிமிடம்"</item>
<item quantity="other" msgid="6924190729213550991">"%d நிமிடங்கள்"</item>
@@ -1788,7 +1799,7 @@
<item quantity="one" msgid="3480040795582254384">"ஒரு மணி நேரம்"</item>
<item quantity="other" msgid="5408537517529822157">"%d மணிநேரம்"</item>
</plurals>
- <!-- no translation found for zen_mode_until (7336308492289875088) -->
- <skip />
+ <string name="zen_mode_until" msgid="7336308492289875088">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g> வரை"</string>
<string name="zen_mode_forever" msgid="4316804956488785559">"வரையறையற்றது"</string>
+ <string name="toolbar_collapse_description" msgid="2821479483960330739">"சுருக்கு"</string>
</resources>
diff --git a/core/res/res/values-te-rIN/strings.xml b/core/res/res/values-te-rIN/strings.xml
index 0219a96..d33ee75 100644
--- a/core/res/res/values-te-rIN/strings.xml
+++ b/core/res/res/values-te-rIN/strings.xml
@@ -716,8 +716,14 @@
<string name="permdesc_cache_filesystem" msgid="5578967642265550955">"కాష్ ఫైల్సిస్టమ్ను చదవడానికి మరియు వ్రాయడానికి అనువర్తనాన్ని అనుమతిస్తుంది."</string>
<string name="permlab_use_sip" msgid="2052499390128979920">"SIP కాల్లను చేయడానికి/స్వీకరించడానికి"</string>
<string name="permdesc_use_sip" msgid="2297804849860225257">"SIP కాల్లను చేయడానికి మరియు స్వీకరించడానికి అనువర్తనాన్ని అనుమతిస్తుంది."</string>
- <string name="permlab_register_provider" msgid="2654513709546459553">"కొత్త టెలికామ్ కనెక్షన్లను నమోదు చేయడం"</string>
- <string name="permdesc_register_provider" msgid="7571533832018681544">"కొత్త టెలికామ్ కనెక్షన్లను నమోదు చేయడానికి అనువర్తనాన్ని అనుమతిస్తుంది."</string>
+ <!-- no translation found for permlab_register_sim_subscription (3166535485877549177) -->
+ <skip />
+ <!-- no translation found for permdesc_register_sim_subscription (2138909035926222911) -->
+ <skip />
+ <!-- no translation found for permlab_register_call_provider (108102120289029841) -->
+ <skip />
+ <!-- no translation found for permdesc_register_call_provider (7034310263521081388) -->
+ <skip />
<string name="permlab_connection_manager" msgid="1116193254522105375">"టెలికామ్ కనెక్షన్లను నిర్వహించడం"</string>
<string name="permdesc_connection_manager" msgid="5925480810356483565">"టెలికామ్ కనెక్షన్లను నిర్వహించడానికి అనువర్తనాన్ని అనుమతిస్తుంది."</string>
<string name="permlab_bind_incall_service" msgid="6773648341975287125">"ఇన్-కాల్ స్క్రీన్తో పరస్పర చర్య చేయడం"</string>
@@ -1233,6 +1239,7 @@
<string name="smv_application" msgid="3307209192155442829">"<xliff:g id="APPLICATION">%1$s</xliff:g> అనువర్తనం (<xliff:g id="PROCESS">%2$s</xliff:g> ప్రాసెస్) అది స్వయంగా అమలు చేసే ఖచ్చితమైన మోడ్ విధానాన్ని ఉల్లంఘించింది."</string>
<string name="smv_process" msgid="5120397012047462446">"ప్రక్రియ <xliff:g id="PROCESS">%1$s</xliff:g> అది స్వయంగా అమలు చేసే ఖచ్చితమైన మోడ్ విధానాన్ని ఉల్లంఘించింది."</string>
<string name="android_upgrading_title" msgid="1584192285441405746">"Android అప్గ్రేడ్ అవుతోంది…"</string>
+ <string name="android_start_title" msgid="8418054686415318207">"Android ప్రారంభమవుతోంది…"</string>
<string name="android_upgrading_apk" msgid="7904042682111526169">"<xliff:g id="NUMBER_1">%2$d</xliff:g>లో <xliff:g id="NUMBER_0">%1$d</xliff:g> అనువర్తనాన్ని అనుకూలీకరిస్తోంది."</string>
<string name="android_upgrading_starting_apps" msgid="451464516346926713">"అనువర్తనాలను ప్రారంభిస్తోంది."</string>
<string name="android_upgrading_complete" msgid="1405954754112999229">"బూట్ను ముగిస్తోంది."</string>
@@ -1776,10 +1783,14 @@
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"అన్పిన్ చేయడానికి ముందు పాస్వర్డ్ కోసం అడుగు"</string>
<string name="battery_saver_description" msgid="2510530476513605742">"బ్యాటరీ సామర్థ్యాన్ని మెరుగుపరచడంలో సహాయపడటానికి, బ్యాటరీ సేవర్ మీ పరికరం పనితీరుని తగ్గిస్తుంది మరియు వైబ్రేషన్ను మరియు అత్యధిక నేపథ్య డేటాను పరిమితపరుస్తుంది. అలాగే సమకాలీకరణపై ఆధారపడే ఇమెయిల్, సందేశ సేవ మరియు ఇతర అనువర్తనాలు మీరు వాటిని తెరిస్తే మినహా నవీకరించబడకపోవచ్చు.\n\nమీ పరికరం ఛార్జింగ్లో ఉన్నప్పుడు బ్యాటరీ సేవర్ స్వయంచాలకంగా ఆఫ్ చేయబడుతుంది."</string>
<string name="downtime_condition_summary" msgid="8761776337475705749">"మీ వృథా సమయం <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>కి ముగిసే వరకు"</string>
- <!-- no translation found for zen_mode_duration_minutes_summary:one (3177683545388923234) -->
- <!-- no translation found for zen_mode_duration_minutes_summary:other (2787867221129368935) -->
- <!-- no translation found for zen_mode_duration_hours_summary:one (597194865053253679) -->
- <!-- no translation found for zen_mode_duration_hours_summary:other (2827214920627669898) -->
+ <plurals name="zen_mode_duration_minutes_summary">
+ <item quantity="one" msgid="3177683545388923234">"ఒక నిమిషం పాటు (<xliff:g id="FORMATTEDTIME">%2$s</xliff:g> వరకు)"</item>
+ <item quantity="other" msgid="2787867221129368935">"%1$d నిమిషాల పాటు (<xliff:g id="FORMATTEDTIME">%2$s</xliff:g> వరకు)"</item>
+ </plurals>
+ <plurals name="zen_mode_duration_hours_summary">
+ <item quantity="one" msgid="597194865053253679">"ఒక గంట పాటు (<xliff:g id="FORMATTEDTIME">%2$s</xliff:g> వరకు)"</item>
+ <item quantity="other" msgid="2827214920627669898">"%1$d గంటల పాటు (<xliff:g id="FORMATTEDTIME">%2$s</xliff:g> వరకు)"</item>
+ </plurals>
<plurals name="zen_mode_duration_minutes">
<item quantity="one" msgid="9040808414992812341">"ఒక నిమిషానికి"</item>
<item quantity="other" msgid="6924190729213550991">"%d నిమిషాలకి"</item>
@@ -1788,7 +1799,7 @@
<item quantity="one" msgid="3480040795582254384">"ఒక గంటకు"</item>
<item quantity="other" msgid="5408537517529822157">"%d గంటలకు"</item>
</plurals>
- <!-- no translation found for zen_mode_until (7336308492289875088) -->
- <skip />
+ <string name="zen_mode_until" msgid="7336308492289875088">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g> వరకు"</string>
<string name="zen_mode_forever" msgid="4316804956488785559">"నిరవధికంగా"</string>
+ <string name="toolbar_collapse_description" msgid="2821479483960330739">"కుదించండి"</string>
</resources>
diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml
index fa6c0e8..a788389 100644
--- a/core/res/res/values-th/strings.xml
+++ b/core/res/res/values-th/strings.xml
@@ -716,8 +716,14 @@
<string name="permdesc_cache_filesystem" msgid="5578967642265550955">"อนุญาตให้แอปพลิเคชันอ่านและเขียนระบบไฟล์แคช"</string>
<string name="permlab_use_sip" msgid="2052499390128979920">"โทร/รับสาย SIP"</string>
<string name="permdesc_use_sip" msgid="2297804849860225257">"อนุญาตให้แอปโทรและรับสาย SIP"</string>
- <string name="permlab_register_provider" msgid="2654513709546459553">"ลงทะเบียนการเชื่อมต่อโทรคมนาคมใหม่"</string>
- <string name="permdesc_register_provider" msgid="7571533832018681544">"อนุญาตให้แอปลงทะเบียนการเชื่อมต่อโทรคมนาคมใหม่"</string>
+ <!-- no translation found for permlab_register_sim_subscription (3166535485877549177) -->
+ <skip />
+ <!-- no translation found for permdesc_register_sim_subscription (2138909035926222911) -->
+ <skip />
+ <!-- no translation found for permlab_register_call_provider (108102120289029841) -->
+ <skip />
+ <!-- no translation found for permdesc_register_call_provider (7034310263521081388) -->
+ <skip />
<string name="permlab_connection_manager" msgid="1116193254522105375">"จัดการการเชื่อมต่อโทรคมนาคม"</string>
<string name="permdesc_connection_manager" msgid="5925480810356483565">"อนุญาตให้แอปจัดการการเชื่อมต่อโทรคมนาคม"</string>
<string name="permlab_bind_incall_service" msgid="6773648341975287125">"โต้ตอบกับหน้าจอขณะกำลังใช้สาย"</string>
@@ -1233,6 +1239,7 @@
<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_apk" msgid="7904042682111526169">"กำลังเพิ่มประสิทธิภาพแอปพลิเคชัน <xliff:g id="NUMBER_0">%1$d</xliff:g> จาก <xliff:g id="NUMBER_1">%2$d</xliff:g> รายการ"</string>
<string name="android_upgrading_starting_apps" msgid="451464516346926713">"กำลังเริ่มต้นแอปพลิเคชัน"</string>
<string name="android_upgrading_complete" msgid="1405954754112999229">"เสร็จสิ้นการบูต"</string>
@@ -1776,10 +1783,14 @@
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"ขอรหัสผ่านก่อนเลิกตรึง"</string>
<string name="battery_saver_description" msgid="2510530476513605742">"เพื่อให้สามารถใช้แบตเตอรี่ได้ยาวนานขึ้น โหมดประหยัดแบตเตอรี่จะลดการทำงานของอุปกรณ์ และจำกัดการสั่นรวมถึงข้อมูลแบ็กกราวด์เกือบทั้งหมด อีเมล การรับส่งข้อความ และแอปอื่นๆ ที่ใช้การซิงค์อาจไม่อัปเดตจนกว่าคุณจะเปิดใช้\n\nโหมดประหยัดแบตเตอรี่จะปิดอัตโนมัติเมื่อชาร์จอุปกรณ์"</string>
<string name="downtime_condition_summary" msgid="8761776337475705749">"จนกว่าจะสิ้นสุดช่วงเวลาที่เครื่องไม่ทำงานในเวลา <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
- <!-- no translation found for zen_mode_duration_minutes_summary:one (3177683545388923234) -->
- <!-- no translation found for zen_mode_duration_minutes_summary:other (2787867221129368935) -->
- <!-- no translation found for zen_mode_duration_hours_summary:one (597194865053253679) -->
- <!-- no translation found for zen_mode_duration_hours_summary:other (2827214920627669898) -->
+ <plurals name="zen_mode_duration_minutes_summary">
+ <item quantity="one" msgid="3177683545388923234">"1 นาที (จนถึงเวลา <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ <item quantity="other" msgid="2787867221129368935">"%1$d นาที (จนถึงเวลา <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ </plurals>
+ <plurals name="zen_mode_duration_hours_summary">
+ <item quantity="one" msgid="597194865053253679">"1 ชั่วโมง (จนถึงเวลา <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ <item quantity="other" msgid="2827214920627669898">"%1$d ชั่วโมง (จนถึงเวลา <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ </plurals>
<plurals name="zen_mode_duration_minutes">
<item quantity="one" msgid="9040808414992812341">"1 นาที"</item>
<item quantity="other" msgid="6924190729213550991">"%d นาที"</item>
@@ -1788,7 +1799,7 @@
<item quantity="one" msgid="3480040795582254384">"1 ชั่วโมง"</item>
<item quantity="other" msgid="5408537517529822157">"%d ชั่วโมง"</item>
</plurals>
- <!-- no translation found for zen_mode_until (7336308492289875088) -->
- <skip />
+ <string name="zen_mode_until" msgid="7336308492289875088">"จนถึงเวลา <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
<string name="zen_mode_forever" msgid="4316804956488785559">"ไม่มีกำหนด"</string>
+ <string name="toolbar_collapse_description" msgid="2821479483960330739">"ยุบ"</string>
</resources>
diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml
index 41e2718..dd0db37 100644
--- a/core/res/res/values-tl/strings.xml
+++ b/core/res/res/values-tl/strings.xml
@@ -716,8 +716,14 @@
<string name="permdesc_cache_filesystem" msgid="5578967642265550955">"Pinapayagan ang app na basahin at isulat ang cache filesystem."</string>
<string name="permlab_use_sip" msgid="2052499390128979920">"magsagawa/tumanggap ng mga tawag sa SIP"</string>
<string name="permdesc_use_sip" msgid="2297804849860225257">"Pinapayagan ang app na magsagawa at makatanggap ng mga tawag sa SIP."</string>
- <string name="permlab_register_provider" msgid="2654513709546459553">"magrehistro ng bagong koneksyon sa telecom"</string>
- <string name="permdesc_register_provider" msgid="7571533832018681544">"Pinapayagan ang app na magrehistro ng mga bagong koneksyon sa telecom."</string>
+ <!-- no translation found for permlab_register_sim_subscription (3166535485877549177) -->
+ <skip />
+ <!-- no translation found for permdesc_register_sim_subscription (2138909035926222911) -->
+ <skip />
+ <!-- no translation found for permlab_register_call_provider (108102120289029841) -->
+ <skip />
+ <!-- no translation found for permdesc_register_call_provider (7034310263521081388) -->
+ <skip />
<string name="permlab_connection_manager" msgid="1116193254522105375">"papamahalaan ang mga koneksyon sa telecom"</string>
<string name="permdesc_connection_manager" msgid="5925480810356483565">"Pinapayagan ang app na mamahala ng mga koneksyon sa telecom."</string>
<string name="permlab_bind_incall_service" msgid="6773648341975287125">"makipag-ugnayan sa in-call na screen"</string>
@@ -1233,6 +1239,7 @@
<string name="smv_application" msgid="3307209192155442829">"Ang app na <xliff:g id="APPLICATION">%1$s</xliff:g> (prosesong <xliff:g id="PROCESS">%2$s</xliff:g>) ay lumabag sa sarili nitong ipinapatupad na patakarang StrictMode."</string>
<string name="smv_process" msgid="5120397012047462446">"Ang prosesong <xliff:g id="PROCESS">%1$s</xliff:g> ay lumabag sa sarili nitong ipinapatupad na patakarang StrictMode."</string>
<string name="android_upgrading_title" msgid="1584192285441405746">"Nag-a-upgrade ang Android…"</string>
+ <string name="android_start_title" msgid="8418054686415318207">"Nagsisimula ang Android…"</string>
<string name="android_upgrading_apk" msgid="7904042682111526169">"Ino-optimize ang app <xliff:g id="NUMBER_0">%1$d</xliff:g> ng <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
<string name="android_upgrading_starting_apps" msgid="451464516346926713">"Sinisimulan ang apps."</string>
<string name="android_upgrading_complete" msgid="1405954754112999229">"Pagtatapos ng pag-boot."</string>
@@ -1776,10 +1783,14 @@
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Humingi ng password bago mag-unpin"</string>
<string name="battery_saver_description" msgid="2510530476513605742">"Upang makatulong na mas mapatagal ang baterya, binabawasan ng battery saver ang pagganap ng iyong device at nililimitahan ang pag-vibrate at ang karamihan ng data ng background. Hindi maaaring ma-update ang email, pagmemensahe at iba pang mga app na umaasa sa pagsi-sync maliban kung bubuksan mo ang mga ito.\n\nAwtomatikong mao-off ang battery saver kapag nagcha-charge ang iyong device."</string>
<string name="downtime_condition_summary" msgid="8761776337475705749">"Hanggang sa matapos ang iyong downtime nang <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
- <!-- no translation found for zen_mode_duration_minutes_summary:one (3177683545388923234) -->
- <!-- no translation found for zen_mode_duration_minutes_summary:other (2787867221129368935) -->
- <!-- no translation found for zen_mode_duration_hours_summary:one (597194865053253679) -->
- <!-- no translation found for zen_mode_duration_hours_summary:other (2827214920627669898) -->
+ <plurals name="zen_mode_duration_minutes_summary">
+ <item quantity="one" msgid="3177683545388923234">"Sa loob ng isang minuto (hanggang <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ <item quantity="other" msgid="2787867221129368935">"Sa loob ng %1$d (na) minuto (hanggang <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ </plurals>
+ <plurals name="zen_mode_duration_hours_summary">
+ <item quantity="one" msgid="597194865053253679">"Sa loob ng isang oras (hanggang <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ <item quantity="other" msgid="2827214920627669898">"Sa loob ng %1$d (na) oras (hanggang <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ </plurals>
<plurals name="zen_mode_duration_minutes">
<item quantity="one" msgid="9040808414992812341">"Sa loob ng isang minuto"</item>
<item quantity="other" msgid="6924190729213550991">"Sa loob ng %d (na) minuto"</item>
@@ -1788,7 +1799,7 @@
<item quantity="one" msgid="3480040795582254384">"Sa loob ng isang oras"</item>
<item quantity="other" msgid="5408537517529822157">"Sa loob ng %d (na) oras"</item>
</plurals>
- <!-- no translation found for zen_mode_until (7336308492289875088) -->
- <skip />
+ <string name="zen_mode_until" msgid="7336308492289875088">"Hanggang <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
<string name="zen_mode_forever" msgid="4316804956488785559">"Walang tiyak na katapusan"</string>
+ <string name="toolbar_collapse_description" msgid="2821479483960330739">"I-collapse"</string>
</resources>
diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml
index 8ddc7f8..a828baa 100644
--- a/core/res/res/values-tr/strings.xml
+++ b/core/res/res/values-tr/strings.xml
@@ -716,14 +716,16 @@
<string name="permdesc_cache_filesystem" msgid="5578967642265550955">"Uygulamaya, önbellek dosya sisteminde okuma ve yazma yapma izni verir."</string>
<string name="permlab_use_sip" msgid="2052499390128979920">"SIP çağrıları yapma/alma"</string>
<string name="permdesc_use_sip" msgid="2297804849860225257">"Uygulamanın SIP çağrıları yapmasına ve almasına izin verir."</string>
- <!-- no translation found for permlab_register_provider (2654513709546459553) -->
+ <!-- no translation found for permlab_register_sim_subscription (3166535485877549177) -->
<skip />
- <!-- no translation found for permdesc_register_provider (7571533832018681544) -->
+ <!-- no translation found for permdesc_register_sim_subscription (2138909035926222911) -->
<skip />
- <!-- no translation found for permlab_connection_manager (1116193254522105375) -->
+ <!-- no translation found for permlab_register_call_provider (108102120289029841) -->
<skip />
- <!-- no translation found for permdesc_connection_manager (5925480810356483565) -->
+ <!-- no translation found for permdesc_register_call_provider (7034310263521081388) -->
<skip />
+ <string name="permlab_connection_manager" msgid="1116193254522105375">"telekomunikasyon bağlantılarını yönet"</string>
+ <string name="permdesc_connection_manager" msgid="5925480810356483565">"Uygulamanın telekomünikasyon bağlantılarını yönetmesine izin verir."</string>
<string name="permlab_bind_incall_service" msgid="6773648341975287125">"çağrı ekranıyla etkileşimde bulunma"</string>
<string name="permdesc_bind_incall_service" msgid="8343471381323215005">"Uygulamaya, kullanıcının çağrı ekranını ne zaman ve nasıl göreceğini denetleme izni verir."</string>
<string name="permlab_bind_connection_service" msgid="3557341439297014940">"telefon hizmetleriyle etkileşimde bulunma"</string>
@@ -1237,6 +1239,7 @@
<string name="smv_application" msgid="3307209192155442829">"<xliff:g id="APPLICATION">%1$s</xliff:g> uygulaması (<xliff:g id="PROCESS">%2$s</xliff:g> işlemi) kendiliğinden uyguladığı StrictMode politikasını ihlal etti."</string>
<string name="smv_process" msgid="5120397012047462446">"<xliff:g id="PROCESS">%1$s</xliff:g> işlemi kendiliğinden uyguladığı StrictMode politikasını ihlal etti."</string>
<string name="android_upgrading_title" msgid="1584192285441405746">"Android yeni sürüme geçiriliyor..."</string>
+ <string name="android_start_title" msgid="8418054686415318207">"Android başlatılıyor…"</string>
<string name="android_upgrading_apk" msgid="7904042682111526169">"<xliff:g id="NUMBER_0">%1$d</xliff:g>/<xliff:g id="NUMBER_1">%2$d</xliff:g> uygulama optimize ediliyor."</string>
<string name="android_upgrading_starting_apps" msgid="451464516346926713">"Uygulamalar başlatılıyor"</string>
<string name="android_upgrading_complete" msgid="1405954754112999229">"Açılış tamamlanıyor."</string>
@@ -1780,10 +1783,14 @@
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Sabitlemeyi kaldırmadan önce şifre sor"</string>
<string name="battery_saver_description" msgid="2510530476513605742">"Pil tasarrufu, pilin ömrünü uzatmaya yardımcı olmak amacıyla cihazınızın performansını düşürür ve arka plan verilerini sınırlar. E-posta, mesajlaşma ve senkronizasyona dayalı diğer uygulamalar siz açmadığınız müddetçe güncellenemez. \n\nPil tasarrufu, cihaz şarj olurken otomatik olarak kapanır."</string>
<string name="downtime_condition_summary" msgid="8761776337475705749">"Kesinti süreniz <xliff:g id="FORMATTEDTIME">%1$s</xliff:g> saatinde sona erene kadar"</string>
- <!-- no translation found for zen_mode_duration_minutes_summary:one (3177683545388923234) -->
- <!-- no translation found for zen_mode_duration_minutes_summary:other (2787867221129368935) -->
- <!-- no translation found for zen_mode_duration_hours_summary:one (597194865053253679) -->
- <!-- no translation found for zen_mode_duration_hours_summary:other (2827214920627669898) -->
+ <plurals name="zen_mode_duration_minutes_summary">
+ <item quantity="one" msgid="3177683545388923234">"Bir dakika için (şu saate kadar: <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ <item quantity="other" msgid="2787867221129368935">"%1$d dakika için (şu saate kadar: <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ </plurals>
+ <plurals name="zen_mode_duration_hours_summary">
+ <item quantity="one" msgid="597194865053253679">"Bir saat için (şu saate kadar: <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ <item quantity="other" msgid="2827214920627669898">"%1$d saat için (şu saate kadar: <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ </plurals>
<plurals name="zen_mode_duration_minutes">
<item quantity="one" msgid="9040808414992812341">"Bir dakika süreyle"</item>
<item quantity="other" msgid="6924190729213550991">"%d dakika süreyle"</item>
@@ -1792,7 +1799,7 @@
<item quantity="one" msgid="3480040795582254384">"Bir saat süreyle"</item>
<item quantity="other" msgid="5408537517529822157">"%d saat süreyle"</item>
</plurals>
- <!-- no translation found for zen_mode_until (7336308492289875088) -->
- <skip />
+ <string name="zen_mode_until" msgid="7336308492289875088">"Şu saate kadar: <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
<string name="zen_mode_forever" msgid="4316804956488785559">"Süresiz"</string>
+ <string name="toolbar_collapse_description" msgid="2821479483960330739">"Daralt"</string>
</resources>
diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml
index ca66cbb..2c038ed 100644
--- a/core/res/res/values-uk/strings.xml
+++ b/core/res/res/values-uk/strings.xml
@@ -716,8 +716,14 @@
<string name="permdesc_cache_filesystem" msgid="5578967642265550955">"Дозволяє програмі читати з файлової системи кеш-пам’яті та писати в неї."</string>
<string name="permlab_use_sip" msgid="2052499390128979920">"здійснювати й отримувати дзвінки через протокол SIP"</string>
<string name="permdesc_use_sip" msgid="2297804849860225257">"Додаток зможе здійснювати й отримувати дзвінки через протокол SIP."</string>
- <string name="permlab_register_provider" msgid="2654513709546459553">"реєстрація нових телекомунікаційних з’єднань"</string>
- <string name="permdesc_register_provider" msgid="7571533832018681544">"Додаток може реєструвати нові телекомунікаційні з’єднання."</string>
+ <!-- no translation found for permlab_register_sim_subscription (3166535485877549177) -->
+ <skip />
+ <!-- no translation found for permdesc_register_sim_subscription (2138909035926222911) -->
+ <skip />
+ <!-- no translation found for permlab_register_call_provider (108102120289029841) -->
+ <skip />
+ <!-- no translation found for permdesc_register_call_provider (7034310263521081388) -->
+ <skip />
<string name="permlab_connection_manager" msgid="1116193254522105375">"керування телекомунікаційними з’єднаннями"</string>
<string name="permdesc_connection_manager" msgid="5925480810356483565">"Додаток може керувати телекомунікаційними з’єднаннями."</string>
<string name="permlab_bind_incall_service" msgid="6773648341975287125">"взаємодіяти з екраном вхідного дзвінка"</string>
@@ -1233,6 +1239,7 @@
<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_apk" msgid="7904042682111526169">"Оптимізація програми <xliff:g id="NUMBER_0">%1$d</xliff:g> з <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
<string name="android_upgrading_starting_apps" msgid="451464516346926713">"Запуск програм."</string>
<string name="android_upgrading_complete" msgid="1405954754112999229">"Завершення завантаження."</string>
@@ -1776,10 +1783,14 @@
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Запитувати пароль перед відкріпленням"</string>
<string name="battery_saver_description" msgid="2510530476513605742">"Щоб подовжити час роботи акумулятора, функція заощадження заряду акумулятора знизить продуктивність пристрою й обмежить вібрацію та більшість фонових даних. Електронна пошта, повідомлення й інші додатки, які синхронізуються, можуть не оновлюватися, доки ви їх не відкриєте.\n\nФункція заощадження заряду акумулятора автоматично вимкнеться, коли пристрій заряджатиметься."</string>
<string name="downtime_condition_summary" msgid="8761776337475705749">"Термін простою закінчується о <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
- <!-- no translation found for zen_mode_duration_minutes_summary:one (3177683545388923234) -->
- <!-- no translation found for zen_mode_duration_minutes_summary:other (2787867221129368935) -->
- <!-- no translation found for zen_mode_duration_hours_summary:one (597194865053253679) -->
- <!-- no translation found for zen_mode_duration_hours_summary:other (2827214920627669898) -->
+ <plurals name="zen_mode_duration_minutes_summary">
+ <item quantity="one" msgid="3177683545388923234">"Одну хвилину (до <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ <item quantity="other" msgid="2787867221129368935">"%1$d хв (до <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ </plurals>
+ <plurals name="zen_mode_duration_hours_summary">
+ <item quantity="one" msgid="597194865053253679">"Одну годину (до <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ <item quantity="other" msgid="2827214920627669898">"%1$d год (до <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ </plurals>
<plurals name="zen_mode_duration_minutes">
<item quantity="one" msgid="9040808414992812341">"Протягом хвилини"</item>
<item quantity="other" msgid="6924190729213550991">"Протягом %d хв"</item>
@@ -1788,7 +1799,7 @@
<item quantity="one" msgid="3480040795582254384">"Протягом години"</item>
<item quantity="other" msgid="5408537517529822157">"Протягом %d год"</item>
</plurals>
- <!-- no translation found for zen_mode_until (7336308492289875088) -->
- <skip />
+ <string name="zen_mode_until" msgid="7336308492289875088">"До <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
<string name="zen_mode_forever" msgid="4316804956488785559">"Без обмежень"</string>
+ <string name="toolbar_collapse_description" msgid="2821479483960330739">"Згорнути"</string>
</resources>
diff --git a/core/res/res/values-ur-rPK/strings.xml b/core/res/res/values-ur-rPK/strings.xml
index faeab4d..20ab47e 100644
--- a/core/res/res/values-ur-rPK/strings.xml
+++ b/core/res/res/values-ur-rPK/strings.xml
@@ -716,14 +716,16 @@
<string name="permdesc_cache_filesystem" msgid="5578967642265550955">"ایپ کو کیش فائل سسٹم پڑھنے اور لکھنے کی اجازت دیتا ہے۔"</string>
<string name="permlab_use_sip" msgid="2052499390128979920">"SIP کالز کریں/موصول کریں"</string>
<string name="permdesc_use_sip" msgid="2297804849860225257">"ایپ کو SIP کالز کرنے اور موصول کرنے کی اجازت دیتا ہے۔"</string>
- <!-- no translation found for permlab_register_provider (2654513709546459553) -->
+ <!-- no translation found for permlab_register_sim_subscription (3166535485877549177) -->
<skip />
- <!-- no translation found for permdesc_register_provider (7571533832018681544) -->
+ <!-- no translation found for permdesc_register_sim_subscription (2138909035926222911) -->
<skip />
- <!-- no translation found for permlab_connection_manager (1116193254522105375) -->
+ <!-- no translation found for permlab_register_call_provider (108102120289029841) -->
<skip />
- <!-- no translation found for permdesc_connection_manager (5925480810356483565) -->
+ <!-- no translation found for permdesc_register_call_provider (7034310263521081388) -->
<skip />
+ <string name="permlab_connection_manager" msgid="1116193254522105375">"ٹیلی کام کنکشنز کا نظم کریں"</string>
+ <string name="permdesc_connection_manager" msgid="5925480810356483565">"ایپ کو ٹیلی کام کنکشنز کا نظم کرنے کی اجازت دیتی ہے۔"</string>
<string name="permlab_bind_incall_service" msgid="6773648341975287125">"درون کال اسکرین کے ساتھ تعامل کریں"</string>
<string name="permdesc_bind_incall_service" msgid="8343471381323215005">"ایپ کو صارف کے درون کال اسکرین دیکھنے کے وقت اور طریقے کو کنٹرول کرنے کی اجازت دیتا ہے۔"</string>
<string name="permlab_bind_connection_service" msgid="3557341439297014940">"ٹیلیفونی سروسز کے ساتھ تعامل کریں"</string>
@@ -1237,6 +1239,7 @@
<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_apk" msgid="7904042682111526169">"ایپ <xliff:g id="NUMBER_0">%1$d</xliff:g> از <xliff:g id="NUMBER_1">%2$d</xliff:g> کو بہتر بنایا جا رہا ہے۔"</string>
<string name="android_upgrading_starting_apps" msgid="451464516346926713">"ایپس شروع ہو رہی ہیں۔"</string>
<string name="android_upgrading_complete" msgid="1405954754112999229">"بوٹ مکمل ہو رہا ہے۔"</string>
@@ -1780,10 +1783,14 @@
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"پن ہٹانے سے پہلے پاس ورڈ طلب کریں"</string>
<string name="battery_saver_description" msgid="2510530476513605742">"بیٹری کی میعاد بہتر بنانے میں مدد کرنے کیلئے، بیٹری سیور آپ کے آلہ کی کارکردگی میں تخفیف کر دیتی ہے اور وائبریشن اور پس منظر کے زیادہ تر ڈیٹا کو محدود کر دیتی ہے۔ ای میل، پیغام رسانی اور مطابقت پذیری پر انحصار کرنے والی دیگر ایپس ممکن ہے اس وقت تک اپ ڈیٹ نہ ہوں جب تک آپ انہیں نہ کھولیں۔\n\nآپ کا آلہ چارج ہوتے وقت بیٹری سیور خود بخود آف ہو جاتی ہے۔"</string>
<string name="downtime_condition_summary" msgid="8761776337475705749">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g> پر آپ کا آخری وقت ختم ہونے تک"</string>
- <!-- no translation found for zen_mode_duration_minutes_summary:one (3177683545388923234) -->
- <!-- no translation found for zen_mode_duration_minutes_summary:other (2787867221129368935) -->
- <!-- no translation found for zen_mode_duration_hours_summary:one (597194865053253679) -->
- <!-- no translation found for zen_mode_duration_hours_summary:other (2827214920627669898) -->
+ <plurals name="zen_mode_duration_minutes_summary">
+ <item quantity="one" msgid="3177683545388923234">"ایک منٹ کیلئے (<xliff:g id="FORMATTEDTIME">%2$s</xliff:g> تک)"</item>
+ <item quantity="other" msgid="2787867221129368935">"%1$d منٹ کیلئے (<xliff:g id="FORMATTEDTIME">%2$s</xliff:g> تک)"</item>
+ </plurals>
+ <plurals name="zen_mode_duration_hours_summary">
+ <item quantity="one" msgid="597194865053253679">"ایک گھنٹے کیلئے (<xliff:g id="FORMATTEDTIME">%2$s</xliff:g> تک)"</item>
+ <item quantity="other" msgid="2827214920627669898">"%1$d گھنٹوں کیلئے (<xliff:g id="FORMATTEDTIME">%2$s</xliff:g> تک)"</item>
+ </plurals>
<plurals name="zen_mode_duration_minutes">
<item quantity="one" msgid="9040808414992812341">"ایک منٹ کیلئے"</item>
<item quantity="other" msgid="6924190729213550991">"%d منٹ کیلئے"</item>
@@ -1792,7 +1799,7 @@
<item quantity="one" msgid="3480040795582254384">"ایک گھنٹے کیلئے"</item>
<item quantity="other" msgid="5408537517529822157">"%d گھنٹوں کیلئے"</item>
</plurals>
- <!-- no translation found for zen_mode_until (7336308492289875088) -->
- <skip />
+ <string name="zen_mode_until" msgid="7336308492289875088">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g> تک"</string>
<string name="zen_mode_forever" msgid="4316804956488785559">"غیر متعینہ"</string>
+ <string name="toolbar_collapse_description" msgid="2821479483960330739">"سکیڑیں"</string>
</resources>
diff --git a/core/res/res/values-uz-rUZ/strings.xml b/core/res/res/values-uz-rUZ/strings.xml
index cf426e2..997b316 100644
--- a/core/res/res/values-uz-rUZ/strings.xml
+++ b/core/res/res/values-uz-rUZ/strings.xml
@@ -716,14 +716,16 @@
<string name="permdesc_cache_filesystem" msgid="5578967642265550955">"Ilova kesh fayl tizimini o‘qishi va unga yozishi mumkin."</string>
<string name="permlab_use_sip" msgid="2052499390128979920">"SIP qo‘ng‘iroqlarini amalga oshirish/qabul qilish"</string>
<string name="permdesc_use_sip" msgid="2297804849860225257">"Ilovaga SIP qo‘ng‘iroqlarini amalga oshirish va qabul qilish uchun ruxsat beradi."</string>
- <!-- no translation found for permlab_register_provider (2654513709546459553) -->
+ <!-- no translation found for permlab_register_sim_subscription (3166535485877549177) -->
<skip />
- <!-- no translation found for permdesc_register_provider (7571533832018681544) -->
+ <!-- no translation found for permdesc_register_sim_subscription (2138909035926222911) -->
<skip />
- <!-- no translation found for permlab_connection_manager (1116193254522105375) -->
+ <!-- no translation found for permlab_register_call_provider (108102120289029841) -->
<skip />
- <!-- no translation found for permdesc_connection_manager (5925480810356483565) -->
+ <!-- no translation found for permdesc_register_call_provider (7034310263521081388) -->
<skip />
+ <string name="permlab_connection_manager" msgid="1116193254522105375">"telekommunikatsiya aloqalarini boshqarish"</string>
+ <string name="permdesc_connection_manager" msgid="5925480810356483565">"Ilovaga telekommunikatsiya aloqalarini boshqarish uchun ruxsat beradi."</string>
<string name="permlab_bind_incall_service" msgid="6773648341975287125">"suhbat vaqtida ekranni boshqarish"</string>
<string name="permdesc_bind_incall_service" msgid="8343471381323215005">"Ilova suhbat vaqtida ekranni boshqarishi mumkin."</string>
<string name="permlab_bind_connection_service" msgid="3557341439297014940">"telefoniya xizmatlarini bilan aloqa qilish"</string>
@@ -1237,6 +1239,7 @@
<string name="smv_application" msgid="3307209192155442829">"“<xliff:g id="APPLICATION">%1$s</xliff:g>” ilovasi (jarayaon: <xliff:g id="PROCESS">%2$s</xliff:g>) o‘zining StrictMode qoidasini buzdi."</string>
<string name="smv_process" msgid="5120397012047462446">"<xliff:g id="PROCESS">%1$s</xliff:g> jarayoni o‘zining o‘zi-bajaruvchi StrictMode siyosatini buzdi."</string>
<string name="android_upgrading_title" msgid="1584192285441405746">"Android yangilanmoqda…"</string>
+ <string name="android_start_title" msgid="8418054686415318207">"Android ishga tushmoqda…"</string>
<string name="android_upgrading_apk" msgid="7904042682111526169">"Ilovalar optimallashtirilmoqda (<xliff:g id="NUMBER_0">%1$d</xliff:g> / <xliff:g id="NUMBER_1">%2$d</xliff:g>)."</string>
<string name="android_upgrading_starting_apps" msgid="451464516346926713">"Ilovalar ishga tushirilmoqda."</string>
<string name="android_upgrading_complete" msgid="1405954754112999229">"Tizimni yuklashni tugatish."</string>
@@ -1780,10 +1783,14 @@
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Bo‘shatishdan oldin parol so‘ralsin"</string>
<string name="battery_saver_description" msgid="2510530476513605742">"Batareya quvvatini uzoqroq vaqtga yetkazish uchun quvvat tejash funksiyasi qurilmangiz unumdorligini kamaytiradi hamda uning tebranishi va orqa fonda internetdan foydalanishni cheklaydi. Sinxronlanib turishi lozim bo‘lgan e-pochta, xabar almashinuv va boshqa ilovalar esa ishga tushirilmaguncha yangilanmaydi.\n\nQurilmani quvvat oldirish uchun energiya manbayiga ulashingiz bilanoq, quvvat tejash funksiyasi avtomatik tarzda o‘chadi."</string>
<string name="downtime_condition_summary" msgid="8761776337475705749">"Tanaffus vaqti tugaguncha – <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
- <!-- no translation found for zen_mode_duration_minutes_summary:one (3177683545388923234) -->
- <!-- no translation found for zen_mode_duration_minutes_summary:other (2787867221129368935) -->
- <!-- no translation found for zen_mode_duration_hours_summary:one (597194865053253679) -->
- <!-- no translation found for zen_mode_duration_hours_summary:other (2827214920627669898) -->
+ <plurals name="zen_mode_duration_minutes_summary">
+ <item quantity="one" msgid="3177683545388923234">"Bir daqiqa (ushbu vaqtgacha: <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ <item quantity="other" msgid="2787867221129368935">"%1$d daqiqa (ushbu vaqtgacha: <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ </plurals>
+ <plurals name="zen_mode_duration_hours_summary">
+ <item quantity="one" msgid="597194865053253679">"Bir soat (ushbu vaqtgacha: <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ <item quantity="other" msgid="2827214920627669898">"%1$d soat (ushbu vaqtgacha: <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ </plurals>
<plurals name="zen_mode_duration_minutes">
<item quantity="one" msgid="9040808414992812341">"1 daqiqa"</item>
<item quantity="other" msgid="6924190729213550991">"%d daqiqa"</item>
@@ -1792,7 +1799,7 @@
<item quantity="one" msgid="3480040795582254384">"1 soat"</item>
<item quantity="other" msgid="5408537517529822157">"%d soat"</item>
</plurals>
- <!-- no translation found for zen_mode_until (7336308492289875088) -->
- <skip />
+ <string name="zen_mode_until" msgid="7336308492289875088">"Ushbu vaqtgacha: <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
<string name="zen_mode_forever" msgid="4316804956488785559">"Uzluksiz ravishda"</string>
+ <string name="toolbar_collapse_description" msgid="2821479483960330739">"Yig‘ish"</string>
</resources>
diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml
index 5acd5bb..178272d 100644
--- a/core/res/res/values-vi/strings.xml
+++ b/core/res/res/values-vi/strings.xml
@@ -716,14 +716,16 @@
<string name="permdesc_cache_filesystem" msgid="5578967642265550955">"Cho phép ứng dụng đọc và ghi hệ thống tệp bộ nhớ cache."</string>
<string name="permlab_use_sip" msgid="2052499390128979920">"thực hiện/nhận các cuộc gọi qua SIP"</string>
<string name="permdesc_use_sip" msgid="2297804849860225257">"Cho phép ứng dụng thực hiện và nhận các cuộc gọi qua SIP."</string>
- <!-- no translation found for permlab_register_provider (2654513709546459553) -->
+ <!-- no translation found for permlab_register_sim_subscription (3166535485877549177) -->
<skip />
- <!-- no translation found for permdesc_register_provider (7571533832018681544) -->
+ <!-- no translation found for permdesc_register_sim_subscription (2138909035926222911) -->
<skip />
- <!-- no translation found for permlab_connection_manager (1116193254522105375) -->
+ <!-- no translation found for permlab_register_call_provider (108102120289029841) -->
<skip />
- <!-- no translation found for permdesc_connection_manager (5925480810356483565) -->
+ <!-- no translation found for permdesc_register_call_provider (7034310263521081388) -->
<skip />
+ <string name="permlab_connection_manager" msgid="1116193254522105375">"quản lý kết nối viễn thông"</string>
+ <string name="permdesc_connection_manager" msgid="5925480810356483565">"Cho phép ứng dụng quản lý kết nối viễn thông."</string>
<string name="permlab_bind_incall_service" msgid="6773648341975287125">"tương tác với màn hình trong cuộc gọi"</string>
<string name="permdesc_bind_incall_service" msgid="8343471381323215005">"Cho phép ứng dụng kiểm soát thời gian và cách người dùng nhìn thấy màn hình trong cuộc gọi."</string>
<string name="permlab_bind_connection_service" msgid="3557341439297014940">"tương tác với dịch vụ điện thoại"</string>
@@ -1237,6 +1239,7 @@
<string name="smv_application" msgid="3307209192155442829">"Ứng dụng <xliff:g id="APPLICATION">%1$s</xliff:g> (quá trình <xliff:g id="PROCESS">%2$s</xliff:g>) đã vi phạm chính sách StrictMode tự thi hành của mình."</string>
<string name="smv_process" msgid="5120397012047462446">"Quá trình <xliff:g id="PROCESS">%1$s</xliff:g> đã vi phạm chính sách StrictMode tự thi hành của mình."</string>
<string name="android_upgrading_title" msgid="1584192285441405746">"Android đang nâng cấp..."</string>
+ <string name="android_start_title" msgid="8418054686415318207">"Android đang khởi động..."</string>
<string name="android_upgrading_apk" msgid="7904042682111526169">"Đang tối ưu hóa ứng dụng <xliff:g id="NUMBER_0">%1$d</xliff:g> trong tổng số <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
<string name="android_upgrading_starting_apps" msgid="451464516346926713">"Khởi động ứng dụng."</string>
<string name="android_upgrading_complete" msgid="1405954754112999229">"Hoàn tất khởi động."</string>
@@ -1780,10 +1783,14 @@
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Hỏi mật khẩu trước khi bỏ ghim"</string>
<string name="battery_saver_description" msgid="2510530476513605742">"Để giúp tăng tuổi thọ pin, trình tiết kiệm pin sẽ giảm hiệu suất thiết bị của bạn và hạn chế chế rung và hầu hết dữ liệu nền. Email, nhắn tin và các ứng dụng khác dựa trên đồng bộ hóa không thể cập nhật trừ khi bạn mở chúng.\n\nTrình tiết kiệm pin tự động tắt khi thiết bị của bạn đang sạc."</string>
<string name="downtime_condition_summary" msgid="8761776337475705749">"Cho tới khi thời gian ngừng hoạt động của bạn kết thúc vào <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
- <!-- no translation found for zen_mode_duration_minutes_summary:one (3177683545388923234) -->
- <!-- no translation found for zen_mode_duration_minutes_summary:other (2787867221129368935) -->
- <!-- no translation found for zen_mode_duration_hours_summary:one (597194865053253679) -->
- <!-- no translation found for zen_mode_duration_hours_summary:other (2827214920627669898) -->
+ <plurals name="zen_mode_duration_minutes_summary">
+ <item quantity="one" msgid="3177683545388923234">"Trong một phút (cho đến <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ <item quantity="other" msgid="2787867221129368935">"Trong %1$d phút (cho đến <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ </plurals>
+ <plurals name="zen_mode_duration_hours_summary">
+ <item quantity="one" msgid="597194865053253679">"Trong một giờ (cho đến <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ <item quantity="other" msgid="2827214920627669898">"Trong %1$d giờ (cho đến <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ </plurals>
<plurals name="zen_mode_duration_minutes">
<item quantity="one" msgid="9040808414992812341">"Trong một phút"</item>
<item quantity="other" msgid="6924190729213550991">"Trong %d phút"</item>
@@ -1792,7 +1799,7 @@
<item quantity="one" msgid="3480040795582254384">"Trong một giờ"</item>
<item quantity="other" msgid="5408537517529822157">"Trong %d giờ"</item>
</plurals>
- <!-- no translation found for zen_mode_until (7336308492289875088) -->
- <skip />
+ <string name="zen_mode_until" msgid="7336308492289875088">"Cho đến <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
<string name="zen_mode_forever" msgid="4316804956488785559">"Không giới hạn"</string>
+ <string name="toolbar_collapse_description" msgid="2821479483960330739">"Thu gọn"</string>
</resources>
diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml
index f32c8c0..10ad4b8 100644
--- a/core/res/res/values-zh-rCN/strings.xml
+++ b/core/res/res/values-zh-rCN/strings.xml
@@ -716,14 +716,16 @@
<string name="permdesc_cache_filesystem" msgid="5578967642265550955">"允许应用读取和写入缓存文件系统。"</string>
<string name="permlab_use_sip" msgid="2052499390128979920">"拨打/接听SIP电话"</string>
<string name="permdesc_use_sip" msgid="2297804849860225257">"允许该应用拨打和接听SIP电话。"</string>
- <!-- no translation found for permlab_register_provider (2654513709546459553) -->
+ <!-- no translation found for permlab_register_sim_subscription (3166535485877549177) -->
<skip />
- <!-- no translation found for permdesc_register_provider (7571533832018681544) -->
+ <!-- no translation found for permdesc_register_sim_subscription (2138909035926222911) -->
<skip />
- <!-- no translation found for permlab_connection_manager (1116193254522105375) -->
+ <!-- no translation found for permlab_register_call_provider (108102120289029841) -->
<skip />
- <!-- no translation found for permdesc_connection_manager (5925480810356483565) -->
+ <!-- no translation found for permdesc_register_call_provider (7034310263521081388) -->
<skip />
+ <string name="permlab_connection_manager" msgid="1116193254522105375">"管理电信网络连接"</string>
+ <string name="permdesc_connection_manager" msgid="5925480810356483565">"允许该应用管理电信网络连接。"</string>
<string name="permlab_bind_incall_service" msgid="6773648341975287125">"与通话屏幕互动"</string>
<string name="permdesc_bind_incall_service" msgid="8343471381323215005">"允许应用控制用户看到通话屏幕的时机和方式。"</string>
<string name="permlab_bind_connection_service" msgid="3557341439297014940">"与电话服务交互"</string>
@@ -1237,6 +1239,7 @@
<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_apk" msgid="7904042682111526169">"正在优化第<xliff:g id="NUMBER_0">%1$d</xliff:g>个应用(共<xliff:g id="NUMBER_1">%2$d</xliff:g>个)。"</string>
<string name="android_upgrading_starting_apps" msgid="451464516346926713">"正在启动应用。"</string>
<string name="android_upgrading_complete" msgid="1405954754112999229">"即将完成启动。"</string>
@@ -1780,10 +1783,14 @@
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"取消时要求输入密码"</string>
<string name="battery_saver_description" msgid="2510530476513605742">"为了延长电池的续航时间,节电助手会降低设备的性能,并限制振动和大部分后台流量。对于电子邮件、聊天工具等依赖于同步功能的应用,可能要打开这类应用时才能收到新信息。\n\n节电助手会在设备充电时自动关闭。"</string>
<string name="downtime_condition_summary" msgid="8761776337475705749">"直到休息时间结束(<xliff:g id="FORMATTEDTIME">%1$s</xliff:g>)"</string>
- <!-- no translation found for zen_mode_duration_minutes_summary:one (3177683545388923234) -->
- <!-- no translation found for zen_mode_duration_minutes_summary:other (2787867221129368935) -->
- <!-- no translation found for zen_mode_duration_hours_summary:one (597194865053253679) -->
- <!-- no translation found for zen_mode_duration_hours_summary:other (2827214920627669898) -->
+ <plurals name="zen_mode_duration_minutes_summary">
+ <item quantity="one" msgid="3177683545388923234">"1 分钟(到<xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ <item quantity="other" msgid="2787867221129368935">"%1$d 分钟(到<xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ </plurals>
+ <plurals name="zen_mode_duration_hours_summary">
+ <item quantity="one" msgid="597194865053253679">"1 小时(到<xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ <item quantity="other" msgid="2827214920627669898">"%1$d 小时(到<xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ </plurals>
<plurals name="zen_mode_duration_minutes">
<item quantity="one" msgid="9040808414992812341">"1分钟"</item>
<item quantity="other" msgid="6924190729213550991">"%d分钟"</item>
@@ -1792,7 +1799,7 @@
<item quantity="one" msgid="3480040795582254384">"1小时"</item>
<item quantity="other" msgid="5408537517529822157">"%d小时"</item>
</plurals>
- <!-- no translation found for zen_mode_until (7336308492289875088) -->
- <skip />
+ <string name="zen_mode_until" msgid="7336308492289875088">"到<xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
<string name="zen_mode_forever" msgid="4316804956488785559">"无限期"</string>
+ <string name="toolbar_collapse_description" msgid="2821479483960330739">"收起"</string>
</resources>
diff --git a/core/res/res/values-zh-rHK/strings.xml b/core/res/res/values-zh-rHK/strings.xml
index 59ff983..ee458f2 100644
--- a/core/res/res/values-zh-rHK/strings.xml
+++ b/core/res/res/values-zh-rHK/strings.xml
@@ -716,14 +716,16 @@
<string name="permdesc_cache_filesystem" msgid="5578967642265550955">"允許應用程式讀取及寫入快取檔案系統。"</string>
<string name="permlab_use_sip" msgid="2052499390128979920">"撥打/接聽 SIP 電話"</string>
<string name="permdesc_use_sip" msgid="2297804849860225257">"允許應用程式撥打及接聽 SIP 電話。"</string>
- <!-- no translation found for permlab_register_provider (2654513709546459553) -->
+ <!-- no translation found for permlab_register_sim_subscription (3166535485877549177) -->
<skip />
- <!-- no translation found for permdesc_register_provider (7571533832018681544) -->
+ <!-- no translation found for permdesc_register_sim_subscription (2138909035926222911) -->
<skip />
- <!-- no translation found for permlab_connection_manager (1116193254522105375) -->
+ <!-- no translation found for permlab_register_call_provider (108102120289029841) -->
<skip />
- <!-- no translation found for permdesc_connection_manager (5925480810356483565) -->
+ <!-- no translation found for permdesc_register_call_provider (7034310263521081388) -->
<skip />
+ <string name="permlab_connection_manager" msgid="1116193254522105375">"管理電訊連接"</string>
+ <string name="permdesc_connection_manager" msgid="5925480810356483565">"允許應用程式管理電訊連接。"</string>
<string name="permlab_bind_incall_service" msgid="6773648341975287125">"與通話畫面互動"</string>
<string name="permdesc_bind_incall_service" msgid="8343471381323215005">"允許應用程式控制通話畫面的顯示時間和方式。"</string>
<string name="permlab_bind_connection_service" msgid="3557341439297014940">"與電話語音服務互動"</string>
@@ -1237,6 +1239,7 @@
<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_apk" msgid="7904042682111526169">"正在優化第 <xliff:g id="NUMBER_0">%1$d</xliff:g> 個應用程式 (共 <xliff:g id="NUMBER_1">%2$d</xliff:g> 個)。"</string>
<string name="android_upgrading_starting_apps" msgid="451464516346926713">"正在啟動應用程式。"</string>
<string name="android_upgrading_complete" msgid="1405954754112999229">"啟動完成。"</string>
@@ -1780,10 +1783,14 @@
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"取消固定時必須輸入密碼"</string>
<string name="battery_saver_description" msgid="2510530476513605742">"省電模式可延長電池使用時間,但會降低裝置的效能,並限制震動和大部分背景數據傳輸。電郵、短訊及其他需要同步處理的應用程式可能只會在開啟時才會更新。\n\n裝置充電時,省電模式會自動關閉。"</string>
<string name="downtime_condition_summary" msgid="8761776337475705749">"直到停機時間於 <xliff:g id="FORMATTEDTIME">%1$s</xliff:g> 結束"</string>
- <!-- no translation found for zen_mode_duration_minutes_summary:one (3177683545388923234) -->
- <!-- no translation found for zen_mode_duration_minutes_summary:other (2787867221129368935) -->
- <!-- no translation found for zen_mode_duration_hours_summary:one (597194865053253679) -->
- <!-- no translation found for zen_mode_duration_hours_summary:other (2827214920627669898) -->
+ <plurals name="zen_mode_duration_minutes_summary">
+ <item quantity="one" msgid="3177683545388923234">"需時 1 分鐘 (完成時間:<xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ <item quantity="other" msgid="2787867221129368935">"需時 %1$d 分鐘 (完成時間 <xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ </plurals>
+ <plurals name="zen_mode_duration_hours_summary">
+ <item quantity="one" msgid="597194865053253679">"需時 1 小時 (完成時間:<xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ <item quantity="other" msgid="2827214920627669898">"需時 %1$d 小時 (完成時間:<xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ </plurals>
<plurals name="zen_mode_duration_minutes">
<item quantity="one" msgid="9040808414992812341">"1 分鐘"</item>
<item quantity="other" msgid="6924190729213550991">"%d 分鐘"</item>
@@ -1792,7 +1799,7 @@
<item quantity="one" msgid="3480040795582254384">"1 小時"</item>
<item quantity="other" msgid="5408537517529822157">"%d 小時"</item>
</plurals>
- <!-- no translation found for zen_mode_until (7336308492289875088) -->
- <skip />
+ <string name="zen_mode_until" msgid="7336308492289875088">"完成時間:<xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
<string name="zen_mode_forever" msgid="4316804956488785559">"無限期"</string>
+ <string name="toolbar_collapse_description" msgid="2821479483960330739">"收合"</string>
</resources>
diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml
index 1848795..fdffb7c 100644
--- a/core/res/res/values-zh-rTW/strings.xml
+++ b/core/res/res/values-zh-rTW/strings.xml
@@ -716,14 +716,16 @@
<string name="permdesc_cache_filesystem" msgid="5578967642265550955">"允許應用程式讀取及寫入快取檔案系統。"</string>
<string name="permlab_use_sip" msgid="2052499390128979920">"撥打/接聽 SIP 通話"</string>
<string name="permdesc_use_sip" msgid="2297804849860225257">"允許應用程式撥打及接聽 SIP 通話。"</string>
- <!-- no translation found for permlab_register_provider (2654513709546459553) -->
+ <!-- no translation found for permlab_register_sim_subscription (3166535485877549177) -->
<skip />
- <!-- no translation found for permdesc_register_provider (7571533832018681544) -->
+ <!-- no translation found for permdesc_register_sim_subscription (2138909035926222911) -->
<skip />
- <!-- no translation found for permlab_connection_manager (1116193254522105375) -->
+ <!-- no translation found for permlab_register_call_provider (108102120289029841) -->
<skip />
- <!-- no translation found for permdesc_connection_manager (5925480810356483565) -->
+ <!-- no translation found for permdesc_register_call_provider (7034310263521081388) -->
<skip />
+ <string name="permlab_connection_manager" msgid="1116193254522105375">"管理電信連線"</string>
+ <string name="permdesc_connection_manager" msgid="5925480810356483565">"允許應用程式管理電信連線。"</string>
<string name="permlab_bind_incall_service" msgid="6773648341975287125">"與通話螢幕互動"</string>
<string name="permdesc_bind_incall_service" msgid="8343471381323215005">"允許應用程式控制使用者看到通話螢幕的時機和方式。"</string>
<string name="permlab_bind_connection_service" msgid="3557341439297014940">"與電話語音服務互動"</string>
@@ -1237,6 +1239,7 @@
<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_apk" msgid="7904042682111526169">"正在最佳化第 <xliff:g id="NUMBER_0">%1$d</xliff:g> 個應用程式 (共 <xliff:g id="NUMBER_1">%2$d</xliff:g> 個)。"</string>
<string name="android_upgrading_starting_apps" msgid="451464516346926713">"正在啟動應用程式。"</string>
<string name="android_upgrading_complete" msgid="1405954754112999229">"啟動完成。"</string>
@@ -1780,10 +1783,14 @@
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"取消固定時必須輸入密碼"</string>
<string name="battery_saver_description" msgid="2510530476513605742">"節約耗電量功能會降低裝置的效能,並限制震動和大多數背景資料,藉此延長電池續航力。此外,電子郵件、簡訊和其他需要使用同步功能的應用程式若未開啟,將不會自動更新。\n\n當您為裝置充電時,節約耗電量功能會自動關閉。"</string>
<string name="downtime_condition_summary" msgid="8761776337475705749">"直到 <xliff:g id="FORMATTEDTIME">%1$s</xliff:g> 停機時間結束"</string>
- <!-- no translation found for zen_mode_duration_minutes_summary:one (3177683545388923234) -->
- <!-- no translation found for zen_mode_duration_minutes_summary:other (2787867221129368935) -->
- <!-- no translation found for zen_mode_duration_hours_summary:one (597194865053253679) -->
- <!-- no translation found for zen_mode_duration_hours_summary:other (2827214920627669898) -->
+ <plurals name="zen_mode_duration_minutes_summary">
+ <item quantity="one" msgid="3177683545388923234">"1 分鐘 (結束時間:<xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ <item quantity="other" msgid="2787867221129368935">"%1$d 分鐘 (結束時間:<xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ </plurals>
+ <plurals name="zen_mode_duration_hours_summary">
+ <item quantity="one" msgid="597194865053253679">"1 小時 (結束時間:<xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ <item quantity="other" msgid="2827214920627669898">"%1$d 小時 (結束時間:<xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ </plurals>
<plurals name="zen_mode_duration_minutes">
<item quantity="one" msgid="9040808414992812341">"1 分鐘"</item>
<item quantity="other" msgid="6924190729213550991">"%d 分鐘"</item>
@@ -1792,7 +1799,7 @@
<item quantity="one" msgid="3480040795582254384">"1 小時"</item>
<item quantity="other" msgid="5408537517529822157">"%d 小時"</item>
</plurals>
- <!-- no translation found for zen_mode_until (7336308492289875088) -->
- <skip />
+ <string name="zen_mode_until" msgid="7336308492289875088">"結束時間:<xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
<string name="zen_mode_forever" msgid="4316804956488785559">"無限期"</string>
+ <string name="toolbar_collapse_description" msgid="2821479483960330739">"收合"</string>
</resources>
diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml
index 10d558f..2ac1433 100644
--- a/core/res/res/values-zu/strings.xml
+++ b/core/res/res/values-zu/strings.xml
@@ -716,8 +716,14 @@
<string name="permdesc_cache_filesystem" msgid="5578967642265550955">"Ivumela uhlelo lokusebenza ukuthi ifunde futhi ibhale isistimu yokufayila amafayela esikhashana."</string>
<string name="permlab_use_sip" msgid="2052499390128979920">"yenza/thola amakholi we-SIP"</string>
<string name="permdesc_use_sip" msgid="2297804849860225257">"Ivumela uhlelo lokusebenza ukwenza nokuthola amakholi we-SIP."</string>
- <string name="permlab_register_provider" msgid="2654513709546459553">"bhalisa ukuxhumana kwezokuxhumana kwefoni okusha"</string>
- <string name="permdesc_register_provider" msgid="7571533832018681544">"Ivumela uhlelo lokusebenza ukuthi lubhalise ukuxhumana kwezokuxhumana kwefoni okusha."</string>
+ <!-- no translation found for permlab_register_sim_subscription (3166535485877549177) -->
+ <skip />
+ <!-- no translation found for permdesc_register_sim_subscription (2138909035926222911) -->
+ <skip />
+ <!-- no translation found for permlab_register_call_provider (108102120289029841) -->
+ <skip />
+ <!-- no translation found for permdesc_register_call_provider (7034310263521081388) -->
+ <skip />
<string name="permlab_connection_manager" msgid="1116193254522105375">"phatha ukuxhumana kwezokuxhumana kwefoni"</string>
<string name="permdesc_connection_manager" msgid="5925480810356483565">"Ivumela uhlelo lokusebenza ukuthi luphathe ukuxhumana kwezokuxhumana kwefoni."</string>
<string name="permlab_bind_incall_service" msgid="6773648341975287125">"hlanganyela neskrini esingaphakathi kwekholi"</string>
@@ -1233,6 +1239,7 @@
<string name="smv_application" msgid="3307209192155442829">"Inqubo <xliff:g id="APPLICATION">%1$s</xliff:g> (yohlelo <xliff:g id="PROCESS">%2$s</xliff:g>) iphule inqubomgomo oziphoqelela yona Yemodi Ebukhali."</string>
<string name="smv_process" msgid="5120397012047462446">"Inqubo <xliff:g id="PROCESS">%1$s</xliff:g> yephule inqubomgomo yokuziphoqelela Yemodi Ebukhali."</string>
<string name="android_upgrading_title" msgid="1584192285441405746">"I-Android ifaka ezakamuva..."</string>
+ <string name="android_start_title" msgid="8418054686415318207">"I-Android iyaqala…"</string>
<string name="android_upgrading_apk" msgid="7904042682111526169">"Ukubeka ezingeni eliphezulu <xliff:g id="NUMBER_0">%1$d</xliff:g> uhlelo lokusebenza <xliff:g id="NUMBER_1">%2$d</xliff:g>"</string>
<string name="android_upgrading_starting_apps" msgid="451464516346926713">"Qalisa izinhlelo zokusebenza."</string>
<string name="android_upgrading_complete" msgid="1405954754112999229">"Qedela ukuqala kabusha."</string>
@@ -1776,10 +1783,14 @@
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Cela iphasiwedi ngaphambi kokususa ukuphina"</string>
<string name="battery_saver_description" msgid="2510530476513605742">"Ukuze usize ukwenza kangcono impilo yebhethri, isilondolozi sebhethri sehlisa ukusebenza kwedivayisi yakho futhi sikhawulela ukudlidliza nedatha eningi yangasemuva. I-imeyili, imilayezo, nezinye izinhlelo zokusebenza ezincike ekuvumelaniseni kungenzeka zingabuyekezi ngaphandle kokuthi uzivule.\n\nIsilondolozi sebhethri sivaleka ngokuzenzakalelayo uma idivayisi yakho ishaja."</string>
<string name="downtime_condition_summary" msgid="8761776337475705749">"Kuze kuphele isikhathi sakho ngo-<xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
- <!-- no translation found for zen_mode_duration_minutes_summary:one (3177683545388923234) -->
- <!-- no translation found for zen_mode_duration_minutes_summary:other (2787867221129368935) -->
- <!-- no translation found for zen_mode_duration_hours_summary:one (597194865053253679) -->
- <!-- no translation found for zen_mode_duration_hours_summary:other (2827214920627669898) -->
+ <plurals name="zen_mode_duration_minutes_summary">
+ <item quantity="one" msgid="3177683545388923234">"Okweminithi elilodwa (kuze kube ngu-<xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ <item quantity="other" msgid="2787867221129368935">"Okwamaminithi angu-%1$d (kuze kube ngu-<xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ </plurals>
+ <plurals name="zen_mode_duration_hours_summary">
+ <item quantity="one" msgid="597194865053253679">"Okwehora elilodwa (kuze kube ngu-<xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ <item quantity="other" msgid="2827214920627669898">"Ngamahora angu-%1$d (kuze kube ngu-<xliff:g id="FORMATTEDTIME">%2$s</xliff:g>)"</item>
+ </plurals>
<plurals name="zen_mode_duration_minutes">
<item quantity="one" msgid="9040808414992812341">"Iminithi elilodwa"</item>
<item quantity="other" msgid="6924190729213550991">"Amaminithi angu-%d"</item>
@@ -1788,7 +1799,7 @@
<item quantity="one" msgid="3480040795582254384">"Ihora elilodwa"</item>
<item quantity="other" msgid="5408537517529822157">"Amahora angu-%d"</item>
</plurals>
- <!-- no translation found for zen_mode_until (7336308492289875088) -->
- <skip />
+ <string name="zen_mode_until" msgid="7336308492289875088">"Kuze kube ngu-<xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
<string name="zen_mode_forever" msgid="4316804956488785559">"Unaphakade"</string>
+ <string name="toolbar_collapse_description" msgid="2821479483960330739">"Goqa"</string>
</resources>
diff --git a/core/res/res/values/arrays.xml b/core/res/res/values/arrays.xml
index bb9885c..f6a5787 100644
--- a/core/res/res/values/arrays.xml
+++ b/core/res/res/values/arrays.xml
@@ -441,4 +441,13 @@
<item>中文 (繁體)</item>
</string-array>
+ <array name="sim_colors">
+ <item>@color/Teal_700</item>
+ <item>@color/Blue_700</item>
+ <item>@color/Indigo_700</item>
+ <item>@color/Purple_700</item>
+ <item>@color/Pink_700</item>
+ <item>@color/Red_700</item>
+ </array>
+
</resources>
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index c4131b3..67ba27da 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -2363,6 +2363,18 @@
representation this attribute can be used for providing such. -->
<attr name="contentDescription" format="string" localization="suggested" />
+ <!-- Sets the id of a view before which this one is visited in accessibility traversal.
+ A screen-reader must visit the content of this view before the content of the one
+ it precedes.
+ @see android.view.View#setAccessibilityTraversalBefore(int)} -->
+ <attr name="accessibilityTraversalBefore" format="integer" />
+
+ <!-- Sets the id of a view after which this one is visited in accessibility traversal.
+ A screen-reader must visit the content of the other view before the content of
+ this one.
+ @see android.view.View#setAccessibilityTraversalAfter(int)} -->
+ <attr name="accessibilityTraversalAfter" format="integer" />
+
<!-- Name of the method in this View's context to invoke when the view is
clicked. This name must correspond to a public method that takes
exactly one parameter of type View. For instance, if you specify
@@ -6376,7 +6388,7 @@
<!-- The summary for the Preference in a PreferenceActivity screen. -->
<attr name="summary" />
<!-- The order for the Preference (lower values are to be ordered first). If this is not
- specified, the default orderin will be alphabetic. -->
+ specified, the default ordering will be alphabetic. -->
<attr name="order" format="integer" />
<!-- When used inside of a modern PreferenceActivity, this declares
a new PreferenceFragment to be shown when the user selects this item. -->
diff --git a/core/res/res/values/colors.xml b/core/res/res/values/colors.xml
index 9f83db4..b9825c5 100644
--- a/core/res/res/values/colors.xml
+++ b/core/res/res/values/colors.xml
@@ -160,5 +160,18 @@
<color name="user_icon_8">#ffff5722</color><!-- deep orange 500 -->
<color name="user_icon_default_gray">#ff9e9e9e</color><!-- gray 500 -->
<color name="user_icon_default_white">#ffffffff</color><!-- white -->
-</resources>
+ <!-- Multi-sim sim colors -->
+ <color name="Teal_700">#ff00796b</color>
+ <color name="Teal_800">#ff00695c</color>
+ <color name="Blue_700">#ff3367d6</color>
+ <color name="Blue_800">#ff2a56c6</color>
+ <color name="Indigo_700">#ff303f9f</color>
+ <color name="Indigo_800">#ff283593</color>
+ <color name="Purple_700">#ff7b1fa2</color>
+ <color name="Purple_800">#ff6a1b9a</color>
+ <color name="Pink_700">#ffc2185b</color>
+ <color name="Pink_800">#ffad1457</color>
+ <color name="Red_700">#ffc53929</color>
+ <color name="Red_800">#ffb93221</color>
+</resources>
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 9332105d..52ef4f9 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -473,6 +473,8 @@
<bool name="config_allowTheaterModeWakeFromDock">false</bool>
<!-- If this is true, allow wake from theater mode from window layout flag. -->
<bool name="config_allowTheaterModeWakeFromWindowLayout">false</bool>
+ <!-- If this is true, go to sleep when theater mode is enabled from button press -->
+ <bool name="config_goToSleepOnButtonPressTheaterMode">true</bool>
<!-- Auto-rotation behavior -->
@@ -586,6 +588,7 @@
0 - Nothing
1 - Global actions menu
2 - Power off (with confirmation)
+ 3 - Power off (without confirmation)
-->
<integer name="config_longPressOnPowerBehavior">1</integer>
@@ -597,6 +600,20 @@
-->
<integer name="config_shortPressOnPowerBehavior">1</integer>
+ <!-- Control the behavior when the user double presses the power button.
+ 0 - Nothing
+ 1 - Toggle theater mode setting
+ 2 - Brightness boost
+ -->
+ <integer name="config_doublePressOnPowerBehavior">0</integer>
+
+ <!-- Control the behavior when the user triple presses the power button.
+ 0 - Nothing
+ 1 - Toggle theater mode setting
+ 2 - Brightness boost
+ -->
+ <integer name="config_triplePressOnPowerBehavior">0</integer>
+
<!-- Package name for default keyguard appwidget [DO NOT TRANSLATE] -->
<string name="widget_default_package_name"></string>
@@ -786,6 +803,13 @@
that can be set by the user. -->
<integer name="config_screenBrightnessDoze">1</integer>
+ <!-- Allow automatic adjusting of the screen brightness while dozing in low power state. -->
+ <bool name="config_allowAutoBrightnessWhileDozing">false</bool>
+
+ <!-- If we allow automatic adjustment of screen brightness while dozing, how many times we want
+ to reduce it to preserve the battery. Value of 100% means no scaling. -->
+ <fraction name="config_screenAutoBrightnessDozeScaleFactor">100%</fraction>
+
<!-- Screen brightness used to dim the screen when the user activity
timeout expires. May be less than the minimum allowed brightness setting
that can be set by the user. -->
@@ -1885,4 +1909,14 @@
<bool name="config_switch_phone_on_voice_reg_state_change">true</bool>
<bool name="config_sms_force_7bit_encoding">false</bool>
+
+ <!-- Flag indicating whether strict threshold is used, or lenient threshold is used,
+ when evaluating RSRP for LTE antenna bar display
+ 0. Strict threshold
+ 1. Lenient threshold
+ -->
+ <integer name="config_LTE_RSRP_threshold_type">1</integer>
+
+ <!-- Show the next-alarm as a zen exit condition if it occurs in the next n hours. -->
+ <integer name="config_next_alarm_condition_lookahead_threshold_hrs">12</integer>
</resources>
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index c0b7fd0..c0a5ab2 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -2597,5 +2597,7 @@
<public type="attr" name="resizeClip"/>
<public type="attr" name="collapseContentDescription"/>
+ <public type="attr" name="accessibilityTraversalBefore" />
+ <public type="attr" name="accessibilityTraversalAfter" />
</resources>
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 27616c7..c5bd495 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -977,10 +977,10 @@
<!-- TODO: Mark these as translatable when API is finalized. -->
<!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
- <string name="permlab_broadcastScoreNetworks" translatable="false">send score networks broadcast</string>
+ <string name="permlab_broadcastNetworkPrivileged" translatable="false">send privileged network broadcasts</string>
<!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
- <string name="permdesc_broadcastScoreNetworks" translatable="false">Allows the app
- to broadcast a notification that networks need to be scored.
+ <string name="permdesc_broadcastNetworkPrivileged" translatable="false">Allows the app
+ to send privileged network broadcasts.
Never needed for normal apps.
</string>
@@ -2115,9 +2115,14 @@
<string name="permdesc_use_sip">Allows the app to make and receive SIP calls.</string>
<!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
- <string name="permlab_register_provider">register new telecom connection</string>
+ <string name="permlab_register_sim_subscription">register new telecom SIM connections</string>
<!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
- <string name="permdesc_register_provider">Allows the app to register new telecom connections.</string>
+ <string name="permdesc_register_sim_subscription">Allows the app to register new telecom SIM connections.</string>
+
+ <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+ <string name="permlab_register_call_provider">register new telecom connections</string>
+ <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+ <string name="permdesc_register_call_provider">Allows the app to register new telecom connections.</string>
<!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
<string name="permlab_connection_manager">manage telecom connections</string>
@@ -4874,7 +4879,10 @@
<string name="battery_saver_description">To help improve battery life, battery saver reduces your device’s performance and limits vibration and most background data. Email, messaging, and other apps that rely on syncing may not update unless you open them.\n\nBattery saver turns off automatically when your device is charging.</string>
<!-- [CHAR_LIMIT=NONE] Zen mode: Condition summary for built-in downtime condition, if active -->
- <string name="downtime_condition_summary">Until your downtime ends at <xliff:g id="formattedTime" example="10.00 PM">%1$s</xliff:g></string>
+ <string name="downtime_condition_summary">Until your downtime ends at <xliff:g id="formattedTime" example="10:00 PM">%1$s</xliff:g></string>
+
+ <!-- [CHAR_LIMIT=NONE] Zen mode: Condition line one for built-in downtime condition, if active -->
+ <string name="downtime_condition_line_one">Until your downtime ends</string>
<!-- Zen mode condition - summary: time duration in minutes. [CHAR LIMIT=NONE] -->
<plurals name="zen_mode_duration_minutes_summary">
@@ -4908,4 +4916,10 @@
<!-- Content description for the Toolbar icon used to collapse an expanded action mode. [CHAR LIMIT=NONE] -->
<string name="toolbar_collapse_description">Collapse</string>
+
+ <!-- Zen mode condition - summary: until next alarm. [CHAR LIMIT=NONE] -->
+ <string name="zen_mode_next_alarm_summary">Until next alarm at <xliff:g id="formattedTime" example="7:30 AM">%1$s</xliff:g></string>
+
+ <!-- Zen mode condition - line one: until next alarm. [CHAR LIMIT=NONE] -->
+ <string name="zen_mode_next_alarm_line_one">Until next alarm</string>
</resources>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 0432425..6e881a7 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -340,6 +340,7 @@
<java-symbol type="integer" name="config_bluetooth_max_advertisers" />
<java-symbol type="integer" name="config_bluetooth_max_scan_filters" />
<java-symbol type="integer" name="config_cursorWindowSize" />
+ <java-symbol type="integer" name="config_doublePressOnPowerBehavior" />
<java-symbol type="integer" name="config_extraFreeKbytesAdjust" />
<java-symbol type="integer" name="config_extraFreeKbytesAbsolute" />
<java-symbol type="integer" name="config_immersive_mode_confirmation_panic" />
@@ -354,6 +355,7 @@
<java-symbol type="integer" name="config_ntpTimeout" />
<java-symbol type="integer" name="config_shortPressOnPowerBehavior" />
<java-symbol type="integer" name="config_toastDefaultGravity" />
+ <java-symbol type="integer" name="config_triplePressOnPowerBehavior" />
<java-symbol type="integer" name="config_wifi_framework_scan_interval" />
<java-symbol type="integer" name="config_wifi_supplicant_scan_interval" />
<java-symbol type="integer" name="config_wifi_scan_interval_p2p_connected" />
@@ -1071,6 +1073,7 @@
<java-symbol type="array" name="networkAttributes" />
<java-symbol type="array" name="preloaded_color_state_lists" />
<java-symbol type="array" name="preloaded_drawables" />
+ <java-symbol type="array" name="sim_colors" />
<java-symbol type="array" name="special_locale_codes" />
<java-symbol type="array" name="special_locale_names" />
<java-symbol type="array" name="config_masterVolumeRamp" />
@@ -1572,6 +1575,7 @@
<java-symbol type="bool" name="config_enableNetworkLocationOverlay" />
<java-symbol type="bool" name="config_sf_limitedAlpha" />
<java-symbol type="bool" name="config_unplugTurnsOnScreen" />
+ <java-symbol type="bool" name="config_allowAutoBrightnessWhileDozing" />
<java-symbol type="bool" name="config_allowTheaterModeWakeFromUnplug" />
<java-symbol type="bool" name="config_allowTheaterModeWakeFromGesture" />
<java-symbol type="bool" name="config_allowTheaterModeWakeFromCameraLens" />
@@ -1581,6 +1585,7 @@
<java-symbol type="bool" name="config_allowTheaterModeWakeFromLidSwitch" />
<java-symbol type="bool" name="config_allowTheaterModeWakeFromDock" />
<java-symbol type="bool" name="config_allowTheaterModeWakeFromWindowLayout" />
+ <java-symbol type="bool" name="config_goToSleepOnButtonPressTheaterMode" />
<java-symbol type="bool" name="config_wifi_background_scan_support" />
<java-symbol type="bool" name="config_wifi_dual_band_support" />
<java-symbol type="bool" name="config_wimaxEnabled" />
@@ -1613,6 +1618,7 @@
<java-symbol type="id" name="replace_app_icon" />
<java-symbol type="id" name="replace_message" />
<java-symbol type="fraction" name="config_dimBehindFadeDuration" />
+ <java-symbol type="fraction" name="config_screenAutoBrightnessDozeScaleFactor" />
<java-symbol type="integer" name="config_carDockKeepsScreenOn" />
<java-symbol type="integer" name="config_criticalBatteryWarningLevel" />
<java-symbol type="integer" name="config_datause_notification_type" />
@@ -1982,12 +1988,16 @@
<java-symbol type="string" name="timepicker_transition_end_radius_multiplier" />
<java-symbol type="string" name="battery_saver_description" />
<java-symbol type="string" name="downtime_condition_summary" />
+ <java-symbol type="string" name="downtime_condition_line_one" />
<java-symbol type="string" name="zen_mode_forever" />
<java-symbol type="plurals" name="zen_mode_duration_minutes" />
<java-symbol type="plurals" name="zen_mode_duration_hours" />
<java-symbol type="plurals" name="zen_mode_duration_minutes_summary" />
<java-symbol type="plurals" name="zen_mode_duration_hours_summary" />
<java-symbol type="string" name="zen_mode_until" />
+ <java-symbol type="string" name="zen_mode_next_alarm_summary" />
+ <java-symbol type="string" name="zen_mode_next_alarm_line_one" />
+ <java-symbol type="integer" name="config_next_alarm_condition_lookahead_threshold_hrs" />
<java-symbol type="string" name="item_is_selected" />
<java-symbol type="string" name="day_of_week_label_typeface" />
@@ -2094,4 +2104,7 @@
<java-symbol type="layout" name="simple_account_item" />
<java-symbol type="id" name="scrollIndicatorUp" />
<java-symbol type="id" name="scrollIndicatorDown" />
+
+ <!-- From SignalStrength -->
+ <java-symbol type="integer" name="config_LTE_RSRP_threshold_type" />
</resources>
diff --git a/core/res/res/values/themes_material.xml b/core/res/res/values/themes_material.xml
index 1864f89..5640fc1 100644
--- a/core/res/res/values/themes_material.xml
+++ b/core/res/res/values/themes_material.xml
@@ -1019,10 +1019,10 @@
<item name="textAppearance">@style/TextAppearance.Material</item>
<item name="textAppearanceInverse">@style/TextAppearance.Material.Inverse</item>
- <item name="listPreferredItemPaddingLeft">16dip</item>
- <item name="listPreferredItemPaddingRight">16dip</item>
- <item name="listPreferredItemPaddingStart">16dip</item>
- <item name="listPreferredItemPaddingEnd">16dip</item>
+ <item name="listPreferredItemPaddingLeft">24dip</item>
+ <item name="listPreferredItemPaddingRight">24dip</item>
+ <item name="listPreferredItemPaddingStart">24dip</item>
+ <item name="listPreferredItemPaddingEnd">24dip</item>
<item name="listDivider">@null</item>
@@ -1135,10 +1135,10 @@
<item name="textAppearance">@style/TextAppearance.Material</item>
<item name="textAppearanceInverse">@style/TextAppearance.Material.Inverse</item>
- <item name="listPreferredItemPaddingLeft">16dip</item>
- <item name="listPreferredItemPaddingRight">16dip</item>
- <item name="listPreferredItemPaddingStart">16dip</item>
- <item name="listPreferredItemPaddingEnd">16dip</item>
+ <item name="listPreferredItemPaddingLeft">24dip</item>
+ <item name="listPreferredItemPaddingRight">24dip</item>
+ <item name="listPreferredItemPaddingStart">24dip</item>
+ <item name="listPreferredItemPaddingEnd">24dip</item>
<item name="listDivider">@null</item>
diff --git a/core/tests/coretests/src/android/net/NetworkScorerAppManagerTest.java b/core/tests/coretests/src/android/net/NetworkScorerAppManagerTest.java
index f916711..9bb44d0 100644
--- a/core/tests/coretests/src/android/net/NetworkScorerAppManagerTest.java
+++ b/core/tests/coretests/src/android/net/NetworkScorerAppManagerTest.java
@@ -59,7 +59,7 @@
// Package 1 - Valid scorer.
Pair<ResolveInfo, ResolveInfo> package1 = buildResolveInfo("package1", true, true, false);
- // Package 2 - Receiver does not have BROADCAST_SCORE_NETWORKS permission.
+ // Package 2 - Receiver does not have BROADCAST_NETWORK_PRIVILEGED permission.
Pair<ResolveInfo, ResolveInfo> package2 = buildResolveInfo("package2", false, true, false);
// Package 3 - App does not have SCORE_NETWORKS permission.
@@ -134,7 +134,7 @@
resolveInfo.activityInfo.packageName = packageName;
resolveInfo.activityInfo.applicationInfo = new ApplicationInfo();
if (hasReceiverPermission) {
- resolveInfo.activityInfo.permission = permission.BROADCAST_SCORE_NETWORKS;
+ resolveInfo.activityInfo.permission = permission.BROADCAST_NETWORK_PRIVILEGED;
}
ResolveInfo configActivityInfo = null;
diff --git a/docs/html/about/dashboards/index.jd b/docs/html/about/dashboards/index.jd
index 808f04a..448dcda 100644
--- a/docs/html/about/dashboards/index.jd
+++ b/docs/html/about/dashboards/index.jd
@@ -41,13 +41,6 @@
Google Play Store in the prior 7 days.</p>
-<div class="note">
-<p><strong>Note:</strong> Beginning in September, 2013, devices running versions older than Android
-2.2 do not appear in this data because those devices do not support the new Google Play Store
-app. Only the new app is able to measure the number of devices that actively visit Google Play Store
-and we believe this measurement best reflects your potential user-base.</p>
-</div>
-
<h2 id="Platform">Platform Versions</h2>
@@ -64,7 +57,7 @@
</div>
-<p style="clear:both"><em>Data collected during a 7-day period ending on September 9, 2014.
+<p style="clear:both"><em>Data collected during a 7-day period ending on November 3, 2014.
<br/>Any versions with less than 0.1% distribution are not shown.</em>
</p>
@@ -95,7 +88,7 @@
</div>
-<p style="clear:both"><em>Data collected during a 7-day period ending on September 9, 2014.
+<p style="clear:both"><em>Data collected during a 7-day period ending on November 3, 2014.
<br/>Any screen configurations with less than 0.1% distribution are not shown.</em></p>
@@ -115,7 +108,7 @@
<img alt="" style="float:right"
-src="//chart.googleapis.com/chart?chs=400x250&cht=p&chd=t%3A77.5%2C22.5&chf=bg%2Cs%2C00000000&chl=GL%202.0%7CGL%203.0&chco=c4df9b%2C6fad0c" />
+src="//chart.googleapis.com/chart?chl=GL%202.0%7CGL%203.0&chd=t%3A74.7%2C25.3&chf=bg%2Cs%2C00000000&chco=c4df9b%2C6fad0c&cht=p&chs=400x250" />
<p>To declare which version of OpenGL ES your application requires, you should use the {@code
android:glEsVersion} attribute of the <a
@@ -133,17 +126,17 @@
</tr>
<tr>
<td>2.0</td>
-<td>77.5%</td>
+<td>74.7%</td>
</tr>
<tr>
<td>3.0</td>
-<td>22.5%</td>
+<td>25.3%</td>
</tr>
</table>
-<p style="clear:both"><em>Data collected during a 7-day period ending on September 9, 2014</em></p>
+<p style="clear:both"><em>Data collected during a 7-day period ending on November 3, 2014</em></p>
@@ -161,42 +154,42 @@
var VERSION_DATA =
[
{
- "chart": "//chart.googleapis.com/chart?chco=c4df9b%2C6fad0c&cht=p&chs=500x250&chl=Froyo%7CGingerbread%7CIce%20Cream%20Sandwich%7CJelly%20Bean%7CKitKat&chd=t%3A0.7%2C11.4%2C9.6%2C53.8%2C24.5&chf=bg%2Cs%2C00000000",
+ "chart": "//chart.googleapis.com/chart?chl=Froyo%7CGingerbread%7CIce%20Cream%20Sandwich%7CJelly%20Bean%7CKitKat&chd=t%3A0.6%2C9.8%2C8.5%2C50.9%2C30.2&chf=bg%2Cs%2C00000000&chco=c4df9b%2C6fad0c&cht=p&chs=500x250",
"data": [
{
"api": 8,
"name": "Froyo",
- "perc": "0.7"
+ "perc": "0.6"
},
{
"api": 10,
"name": "Gingerbread",
- "perc": "11.4"
+ "perc": "9.8"
},
{
"api": 15,
"name": "Ice Cream Sandwich",
- "perc": "9.6"
+ "perc": "8.5"
},
{
"api": 16,
"name": "Jelly Bean",
- "perc": "25.1"
+ "perc": "22.8"
},
{
"api": 17,
"name": "Jelly Bean",
- "perc": "20.7"
+ "perc": "20.8"
},
{
"api": 18,
"name": "Jelly Bean",
- "perc": "8.0"
+ "perc": "7.3"
},
{
"api": 19,
"name": "KitKat",
- "perc": "24.5"
+ "perc": "30.2"
}
]
}
@@ -210,27 +203,27 @@
"Large": {
"hdpi": "0.6",
"ldpi": "0.5",
- "mdpi": "4.3",
- "tvdpi": "1.7",
+ "mdpi": "4.5",
+ "tvdpi": "1.9",
"xhdpi": "0.6"
},
"Normal": {
- "hdpi": "35.7",
- "mdpi": "10.6",
- "xhdpi": "19.2",
- "xxhdpi": "16.2"
+ "hdpi": "36.6",
+ "mdpi": "9.9",
+ "xhdpi": "18.9",
+ "xxhdpi": "16.0"
},
"Small": {
- "ldpi": "6.2"
+ "ldpi": "5.8"
},
"Xlarge": {
"hdpi": "0.3",
- "mdpi": "3.7",
- "xhdpi": "0.4"
+ "mdpi": "3.9",
+ "xhdpi": "0.5"
}
},
- "densitychart": "//chart.googleapis.com/chart?chco=c4df9b%2C6fad0c&cht=p&chs=400x250&chl=ldpi%7Cmdpi%7Ctvdpi%7Chdpi%7Cxhdpi%7Cxxhdpi&chd=t%3A6.7%2C18.6%2C1.7%2C36.6%2C20.2%2C16.2&chf=bg%2Cs%2C00000000",
- "layoutchart": "//chart.googleapis.com/chart?chco=c4df9b%2C6fad0c&cht=p&chs=400x250&chl=Xlarge%7CLarge%7CNormal%7CSmall&chd=t%3A4.4%2C7.7%2C81.7%2C6.2&chf=bg%2Cs%2C00000000"
+ "densitychart": "//chart.googleapis.com/chart?chl=ldpi%7Cmdpi%7Ctvdpi%7Chdpi%7Cxhdpi%7Cxxhdpi&chd=t%3A6.3%2C18.3%2C1.9%2C37.5%2C20.0%2C16.0&chf=bg%2Cs%2C00000000&chco=c4df9b%2C6fad0c&cht=p&chs=400x250",
+ "layoutchart": "//chart.googleapis.com/chart?chl=Xlarge%7CLarge%7CNormal%7CSmall&chd=t%3A4.7%2C8.1%2C81.4%2C5.8&chf=bg%2Cs%2C00000000&chco=c4df9b%2C6fad0c&cht=p&chs=400x250"
}
];
@@ -302,6 +295,16 @@
"api":19,
"link":"<a href='/about/versions/android-4.4.html'>4.4</a>",
"codename":"KitKat"
+ },
+ {
+ "api":20,
+ "link":"<a href='/about/versions/android-4.4.html'>4.4W</a>",
+ "codename":"KitKat for Wear"
+ },
+ {
+ "api":21,
+ "link":"<a href='/about/versions/android-5.0.html'>4.4</a>",
+ "codename":"Lollipop"
}
];
diff --git a/docs/html/design/tv/index.jd b/docs/html/design/tv/index.jd
index 483c24f..d79e279 100644
--- a/docs/html/design/tv/index.jd
+++ b/docs/html/design/tv/index.jd
@@ -1,4 +1,7 @@
-page.title=Android TV
+page.title=Designing for Android TV
+page.tags="tv", "leanback","designguidelines"
+page.metaDescription=Guidelines to help you create a great leanback experience on Android TV.
+page.image=design/tv/images/apps-games-rows.jpg
@jd:body
@@ -6,12 +9,15 @@
experience. It's important to understand how your app is presented in the main user interface and
how your app can help users get to the content they want quickly.</p>
-<p class="note">
+<p class="caution">
<strong>Important:</strong> There are specific design requirements your app must meet to qualify
as an Android TV app on Google Play. For more information, see the requirements listed in
<a href="{@docRoot}distribute/essentials/quality/tv.html">TV App Quality</a>.
</p>
+<p class="note"><strong>Note:</strong> For information about how to publish your TV apps in Google Play,
+see <a href="/distribute/googleplay/tv.html">Distributing to Android TV</a>.</p>
+
<h2>Home Screen</h2>
<p>The Home Screen is the start of the user experience, providing search, content
diff --git a/docs/html/design/tv/patterns.jd b/docs/html/design/tv/patterns.jd
index 768dcfc..be7ae31 100644
--- a/docs/html/design/tv/patterns.jd
+++ b/docs/html/design/tv/patterns.jd
@@ -41,6 +41,8 @@
language, you must provide versions of the banner image for each supported language.</li>
</ul>
+<p>See <a href="{@docRoot}training/tv/start/start.html#banner">Provide a home screen banner</a>
+in Get Started with TV Apps for more information.</p>
<h3>Recommendation Icons</h3>
diff --git a/docs/html/design/wear/patterns.jd b/docs/html/design/wear/patterns.jd
index 30fdc244..e56ac2d 100644
--- a/docs/html/design/wear/patterns.jd
+++ b/docs/html/design/wear/patterns.jd
@@ -76,6 +76,13 @@
<li>The cue card can be invoked to continue specifying the action. For example in a messaging application, tapping a “Reply” action button invokes the Cue Card and prompts for voice input. In this case the prompt label (such as “Speak your message…”) and a set of sample voice suggestions can be specified by developers.</li>
</ol>
+<a class="notice-developers left" href="{@docRoot}training/wearables/ui/confirm.html">
+ <div>
+ <h3>Developer Docs</h3>
+ <p>Showing Confirmations</p>
+ </div>
+</a>
+
<h2 id="Continuing" style="clear:both">Continuing activities on phone</h2>
@@ -100,6 +107,13 @@
<p>Good examples of using an action on card include: play and pause music, toggle light switch on and off, navigate to an address, and call a phone number.</p>
+<a class="notice-developers left" href="{@docRoot}training/wearables/ui/cards.html">
+ <div>
+ <h3>Developer Docs</h3>
+ <p>Creating Cards</p>
+ </div>
+</a>
+
<h2 id="Stacks" style="clear:both">Card stacks</h2>
<img src="{@docRoot}design/media/wear/expandable_stacks.png" width="147" height="147" style="float:right;margin:0 0 20px 40px">
@@ -124,6 +138,13 @@
<p>More information about how to use the 2D Picker pattern is provided in the <a href="{@docRoot}design/wear/structure.html#2DPicker">App Structure</a> guide.</p>
+<a class="notice-developers left" href="{@docRoot}training/wearables/ui/2d-picker.html">
+ <div>
+ <h3>Developer Docs</h3>
+ <p>Creating a 2D Picker</p>
+ </div>
+</a>
+
<h2 id="Voice" style="clear:both">Voice commands</h2>
@@ -148,3 +169,10 @@
<p>Of course, it is possible for Android Wear apps to extend themselves beyond the familiarities of these patterns. For a deeper look at the options available, see the <a href="{@docRoot}design/wear/structure.html">App Structure</a> guide.</p>
+
+<a class="notice-developers left" href="{@docRoot}training/wearables/ui/lists.html">
+ <div>
+ <h3>Developer Docs</h3>
+ <p>Creating Lists</p>
+ </div>
+</a>
diff --git a/docs/html/design/wear/structure.jd b/docs/html/design/wear/structure.jd
index b77ccc2..95d5c1a 100644
--- a/docs/html/design/wear/structure.jd
+++ b/docs/html/design/wear/structure.jd
@@ -84,12 +84,18 @@
<img src="{@docRoot}design/media/wear/1D_picker.png" alt="" width="499px" />
<p class="img-caption">This pattern can be used to present a single vertical list, or a “1D Picker”</p>
-<img src="{@docRoot}design/media/wear/2D_picker.png" alt="" width:760px" />
+<img src="{@docRoot}design/media/wear/2D_picker.png" alt="" width="760px" />
<p class="img-caption">It can also be used as a 2D matrix of options, as a way of presenting categorized options.</p>
<h3>Actions</h3>
+<a class="notice-developers" style="clear:none" href="{@docRoot}training/wearables/ui/2d-picker.html">
+ <div>
+ <h3>Developer Docs</h3>
+ <p>Creating a 2D Picker</p>
+ </div>
+</a>
<p>For actions on each card, use the <a href="{@docRoot}design/wear/patterns.html#Actions">Action cards pattern</a>.</p>
<h3>Making it fast</h3>
@@ -155,6 +161,6 @@
<h3>Manually exiting</h3>
<p>Even with logical exit points like these, some cases may exist where the user may want to immediately exit. This may be common in apps that are used for a longer while. In all cases, you should treat long-press as the user's intent to exit, using
-<a href="{@docRoot}training/wearables/apps/layouts.html#UiLibrary"><code>DismissOverlayView</code></a>.</p>
+<a href="{@docRoot}training/wearables/ui/exit.html"><code>DismissOverlayView</code></a>.</p>
diff --git a/docs/html/distribute/essentials/quality/tv.jd b/docs/html/distribute/essentials/quality/tv.jd
index b13307e..20018c3 100644
--- a/docs/html/distribute/essentials/quality/tv.jd
+++ b/docs/html/distribute/essentials/quality/tv.jd
@@ -47,11 +47,9 @@
qualify as an Android TV app on Google Play.
</p>
-<p class="note">
- <strong>Note:</strong> You will be able to submit TV apps to Google Play with the public release
- of Android 5.0 on November 3. Stay tuned for more information about how to submit your TV apps
- through the Google Play Developer Console.
-</p>
+<p class="note"><strong>Note:</strong> For information about how to publish your TV apps in Google Play,
+see <a href="{@docRoot}distribute/googleplay/tv.html">Distributing to Android TV</a>.</p>
+
<div class="headerLine">
diff --git a/docs/html/distribute/googleplay/edu/start.jd b/docs/html/distribute/googleplay/edu/start.jd
index 3c3a175..f4c9717 100644
--- a/docs/html/distribute/googleplay/edu/start.jd
+++ b/docs/html/distribute/googleplay/edu/start.jd
@@ -1,4 +1,4 @@
-page.title=Publish Apps
+page.title=Publish Education Apps
page.image=/distribute/images/play-education.jpg
meta.tags="education", "guidelines", "quality"
page.tags="education", "addendum"
diff --git a/docs/html/distribute/googleplay/googleplay_toc.cs b/docs/html/distribute/googleplay/googleplay_toc.cs
index 45464c7..fc7cd11 100644
--- a/docs/html/distribute/googleplay/googleplay_toc.cs
+++ b/docs/html/distribute/googleplay/googleplay_toc.cs
@@ -18,6 +18,12 @@
</div>
</li>
<li class="nav-section">
+ <div class="nav-section empty" style="font-weight:normal"><a href="<?cs var:toroot?>distribute/googleplay/tv.html">
+ <span class="en">Distributing to <span style="white-space:nowrap">Android TV</span></span>
+ </a>
+ </div>
+ </li>
+ <li class="nav-section">
<div class="nav-section-header" style="font-weight:normal"><a href="<?cs var:toroot?>distribute/googleplay/edu/about.html">
<span class="en">Google Play for Education</span>
</a>
diff --git a/docs/html/distribute/googleplay/index.jd b/docs/html/distribute/googleplay/index.jd
index a215930..20f07fa 100644
--- a/docs/html/distribute/googleplay/index.jd
+++ b/docs/html/distribute/googleplay/index.jd
@@ -21,7 +21,7 @@
data-maxResults="3">
</div>
- <h3>Google Play for Education</h3>
+ <h3>Distribute Your Apps</h3>
<div class="resource-widget resource-flow-layout landing col-16"
data-query="collection:distribute/gp/gpfelanding"
diff --git a/docs/html/distribute/googleplay/tv.jd b/docs/html/distribute/googleplay/tv.jd
new file mode 100644
index 0000000..37cbe26
--- /dev/null
+++ b/docs/html/distribute/googleplay/tv.jd
@@ -0,0 +1,320 @@
+page.title=Distributing to Android TV
+page.image=/design/tv/images/atv-home.jpg
+meta.tags="tv", "publish", "quality"
+page.tags="tv", "publish", "googleplay"
+page.metaDescription=Distribute your apps, games, and content to Android TV.
+
+@jd:body
+
+<div id="qv-wrapper"><div id="qv">
+<h2>How to Participate</h2>
+<ol>
+<li><a href="#understand_guidelines">Understand the guidelines</a></li>
+<li><a href="#develop_app">Develop a great app for TV</a></li>
+<li><a href="#test_app">Test for TV App Quality</a></li>
+<li><a href="#opt_in">Opt-in</a></li>
+<li><a href="#track_review">Track your review</a></li>
+</ol>
+
+<h2>You Should Also Read</h2>
+<ol>
+<li><a href="{@docRoot}distribute/essentials/quality/tv.html">TV App Quality</a></li>
+<li><a href="{@docRoot}distribute/essentials/quality/core.html">Core App Quality</a></li>
+</ol>
+
+</div></div>
+
+<p>
+ If you've got a great app or game, Android TV and Google Play can help you
+ bring it to users right in their living rooms. You'll be able to offer your
+ apps and games in a storefront experience that’s optimized for TV. You can
+ extend your new or existing apps for TV and then publish them using familiar
+ tools and processes in Google Play.
+</p>
+
+<p>
+ To get started, review the sections in this document to learn how to
+ distribute your TV apps to users through Google Play. Be sure to read
+ <a href="{@docRoot}distribute/essentials/quality/tv.html">TV App Quality</a>
+ for information on the usability and quality standards that your apps should
+ meet. When your app is ready, you can opt-in to publishing in the Android TV
+ storefront from the Developer Console.
+</p>
+
+<h2 id="how_to_participate">
+ How to Participate
+</h2>
+
+<p>
+ Google Play lets you put your TV apps in front of a new audience of users in
+ their living rooms. You can develop and publish using your existing Developer
+ Console account and your current distribution and pricing settings. It's easy
+ to participate — the sections below outline the process.
+</p>
+
+<div style="float:right;margin:1em 0 1.5em 2em;">
+ <img src="{@docRoot}images/gp-tv-process.png">
+</div>
+
+<h3 id="understand_guidelines">
+ 1. Understand guidelines and requirements
+</h3>
+
+<p>
+ To prepare for a successful launch on Android TV, start by reviewing the
+ guidelines for creating great app experiences on TV. See the <a href=
+ "{@docRoot}design/tv/index.html">Android TV design guidelines</a> for ideas
+ on extending your app for TV and details on design and usability.
+</p>
+
+<p>
+ As you get started designing your TV experience, make sure to read and
+ understand the quality criteria for TV apps. The Google Play experience for
+ Android TV <strong>showcases only apps that are usable on the TV</strong>
+ — your apps can participate if they meet a set of basic quality
+ criteria. See <a href="{@docRoot}distribute/essentials/quality/tv.html">TV
+ App Quality</a> for details.
+</p>
+
+<h3 id="develop_app">2. Develop a great app for TV</h3>
+
+<p>
+ A great app for TV is designed for living room use and takes advantage of the
+ capabilities of Android TV and related input accessories such as game
+ controllers, D-pads, and remotes. The app is refined to offer a polished,
+ high-quality experience on large screens and delivers a compelling feature
+ set for users.
+</p>
+
+<p>
+ As you consider your TV app, review the <a href=
+ "{@docRoot}training/tv/start/index.html">developer documentation</a> and
+ usability guidelines and plan on supporting them to the greatest extent
+ possible. Make sure to design a great leanback experience for users and build
+ it with the leanback library included in the SDK. You’ll want to optimize
+ other parts of your app for the TV use case and it's a good idea to identify
+ those early in your development process.
+</p>
+
+<p>
+ In most cases, we recommend delivering your TV experience as part of your
+ existing app for phones, tablets, and other devices, using the same package
+ name and store listing. This approach lets users upgrade to your TV experience
+ seamlessly and also lets you take advantage of the reviews and ratings you’ve
+ earned in your app for phones and tablets.
+</p>
+
+<p>
+ You can bundle your TV intents, leanback library, and TV-specific code and
+ resources as part of a single APK solution for all supported devices. If
+ necessary, you can use <a href=
+ "{@docRoot}google/play/publishing/multiple-apks.html">Multiple APK
+ Support</a> to deliver a custom binary to Android TV devices under the same
+ package name and store listing that you use for phones and tablets.
+</p>
+
+<p>
+ Throughout design and development, it's important to have a suitable device
+ on which to prototype and test your user experience. You should acquire one
+ or more Android TV devices or emulators and set up your testing environment
+ as early as possible. The recommended hardware device for testing in the
+ Android TV environment is Nexus Player, which is <a href=
+ "http://www.google.com/intl/all/nexus/player/">available from Google Play</a>
+ and other stores, and you should also acquire a game controller and other TV
+ input devices.
+</p>
+
+<h3 id="test_app">3. Test for TV App Quality</h3>
+
+<p>
+ Your TV apps should be designed to perform well, look great on Android TV,
+ and offer the best user experience possible. Google Play showcases
+ high-quality apps for easy discovery by users in Google Play. Here’s how you
+ can participate and deliver an Android TV app that users will enjoy.
+</p>
+
+<ul>
+ <li>Meet Core App Quality guidelines
+ <ul>
+ <li>Follow <a href="{@docRoot}design/index.html">Android Design
+ guidelines</a>. Pay special attention to using <a href=
+ "http://www.google.com/design/spec/material-design/introduction.html">material
+ design</a> in your app.
+ </li>
+
+ <li>Test your apps against the <a href=
+ "{@docRoot}distribute/essentials/quality/core.html">Core App Quality
+ guidelines</a>.
+ </li>
+ </ul>
+ </li>
+ <li>Meet <a href="{@docRoot}distribute/essentials/quality/tv.html">TV App
+ Quality</a> guidelines
+ <ul>
+ <li>Follow our best practices for <a href="{@docRoot}training/tv/index.html">
+ TV app development</a></li>
+ <li>Make sure your app meets all of the <a href=
+ "{@docRoot}distribute/essentials/quality/tv.html">TV App Quality</a> criteria</li>
+ </ul>
+ </li>
+ <li>Strive for simplicity and highest usability</li>
+</ul>
+
+<h3 id="opt_in">4. Opt-in to Android TV and publish</h3>
+
+<p>
+ When you've built your release-ready APK and tested to ensure that it meets
+ all of the <a href="{@docRoot}distribute/essentials/quality/tv.html">TV App
+ Quality</a> guidelines, upload it to the Developer Console. Update your store
+ listing with TV screenshots and TV banner, and set distribution options as
+ needed. If you aren't familiar with how to prepare for launch on Google Play,
+ see the <a href=
+ "{@docRoot}distribute/googleplay/publish/preparing.html">Launch
+ Checklist.</a>
+</p>
+
+<p>
+ Before you can publish to Android TV users, you need to opt-in to Android
+ TV from the <strong>Pricing and Distribution</strong> section of the
+ Developer Console. Opt-in means that you want your app to be made available
+ to Android TV users through Google Play, and that
+ your app meets <a href="{@docRoot}distribute/essentials/quality/tv.html">TV
+ App Quality</a> guidelines.
+</p>
+
+<p>
+ You can opt-in only if your app meets two preliminary quality
+ criteria that are automatically checked on APK upload:
+</p>
+
+<ul>
+ <li>Your app manifest must include an intent type of <a href=
+ "{@docRoot}reference/android/content/Intent.html#ACTION_MAIN"><code>ACTION_MAIN</code></a>
+ with category <a href=
+ "{@docRoot}reference/android/content/Intent.html#CATEGORY_LEANBACK_LAUNCHER">
+ <code>CATEGORY_LEANBACK_LAUNCHER</code></a>. Learn more <a href=
+ "{@docRoot}training/tv/start/start.html#tv-activity">here</a>.
+ </li>
+
+ <li>Your app must declare that it does not require a touchscreen. The
+ manifest must declare the <code>android.hardware.touchscreen</code> hardware
+ with <code>android:required="false”</code>. Learn more <a href=
+ "{@docRoot}training/tv/start/hardware.html#declare-hardware-requirements">here</a>.
+ </li>
+</ul>
+
+<p>
+ If your app meets the preliminary criteria, you’ll see an opt-in checkbox for
+ Android TV, as shown below. If the opt-in checkbox is not enabled, review
+ your APK to ensure it meets the preliminary criteria.
+</p>
+
+<p>
+ After you opt-in and save the changes, you can publish your app as usual.
+ Before making the app available to Android TV users, Google Play submits
+ your app for review against the <a href=
+ "{@docRoot}distribute/essentials/quality/tv.html">TV App Quality</a> criteria
+ and notifies you of the result. See the next section for details on how to
+ track the approval status of your app.
+</p>
+
+<p>
+ If your app meet <a href="{@docRoot}distribute/essentials/quality/tv.html">TV
+ App Quality</a> criteria, Google Play makes that app available to Android TV
+ users. Your app is alsoeligible for higher-visibility featuring in app
+ collections and promotions. To let users everywhere know that your app is
+ designed for Android TV, Google Play decorates the app’s store listing with a
+ TV badge.
+</p>
+
+<p>
+ Note that opt-in and review do not affect the availability of your app to
+ other devices in Google Play Store — on phones and tablets, for
+ example, your app is available as soon as you publish.
+</p>
+
+<p>
+ Here are the steps to opt-in to Android TV in the Developer Console:
+</p>
+
+<ol>
+ <li>Make sure your app meets all <a href=
+ "{@docRoot}distribute/essentials/quality/tv.html">TV App Quality</a> criteria
+ </li>
+
+ <li>Add TV screenshots and banner graphic to the app’s store listing
+ </li>
+
+ <li>In the <strong>All Applications</strong> page, click the app you want to opt-in.
+ </li>
+
+ <li>Under <strong>Pricing and Distribution</strong>, scroll down to find <em>Android TV</em> and the
+ opt-in checkbox.
+ </li>
+
+ <li>Click the checkbox next to <em>Distribute your app to Android TV</em>.
+ </li>
+
+ <li>Click <strong>Save</strong> to save your changes.
+ </li>
+</ol>
+
+<div style="padding-top:1em">
+ <img style="border:2px solid #ddd;" src="{@docRoot}images/gp-tv-opt-in.png">
+ <p class="caption">
+ <strong>Opt-in for TV:</strong> Include your app in Android TV by opting-in from the
+ Developer Console.
+ </p>
+</div>
+
+<h3 id="track_review">5. Track your review and approval</h3>
+
+<p>
+ If your app meets the technical and quality criteria for Android TV, as described above,
+ your app will be available for users to enjoy on Android TV. If your app doesn’t meet
+ the criteria, you’ll receive a <strong>notification email sent to your developer account
+ address</strong>, with a summary of the areas that you need to address. When you’ve made
+ the necessary adjustments, you can upload a new version of your app to the Developer
+ Console.
+</p>
+
+<p>
+ At any time, you can check the review and approval status of your app in the
+ Developer Console, under <em>Android TV</em> in the app's <strong>Pricing and Distribution</strong>
+ page.
+</p>
+
+<p>
+ There are three approval states:
+</p>
+
+<ul>
+ <li>
+ <em>Pending</em> — Your app was sent for review and the review is not yet
+ complete.
+ </li>
+
+ <li>
+ <em>Approved</em> — Your app was reviewed and approved. The app will be
+ made available directly to Android TV users.
+ </li>
+
+ <li>
+ <em>Not approved</em> — Your app was reviewed and not approved. Check the
+ notification email for information about why the app was not approved. You
+ can address any issues and opt-in and publish again to initiate another
+ review.
+ </li>
+</ul>
+
+<p>To understand how your apps are evaluated, please see the <a href=
+"{@docRoot}distribute/essentials/quality/tv.html">TV App Quality</a> document. </p>
+
+
+ <h3>Related resources</h3>
+
+ <div class="resource-widget resource-flow-layout col-16"
+ data-query="collection:tvlanding"
+ data-cardSizes="9x6, 6x3x2"
+ data-maxResults="6">
+ </div>
diff --git a/docs/html/distribute/tools/promote/badges.jd b/docs/html/distribute/tools/promote/badges.jd
index 4bea8be..eb09333 100644
--- a/docs/html/distribute/tools/promote/badges.jd
+++ b/docs/html/distribute/tools/promote/badges.jd
@@ -66,7 +66,7 @@
var APP_LANGS = ['it','pt-br','pt-pt','nl','ko','ja','fr','es','es-419','en','de'];
// variables for creating 'try it out' demo button
-var imagePath = "{@docRoot}images/brand/"
+var imagePath = "https://developer.android.com/images/brand/"
var linkStart = "<a href=\"https://play.google.com/store/";
var imageStart = "\">\n"
+ " <img alt=\"";
@@ -99,7 +99,7 @@
$("#button-preview").html(linkStart + "apps/details?id=" + packageName
+ imageStart + altText + imageSrc
+ selectedValue + imageEnd);
-
+
// Send the event to Analytics
ga('send', 'event', 'Distribute', 'Create Google Play Badge', 'Package ' + selectedValue);
} else if (form["publisher"].value != "Example, Inc.") {
@@ -111,7 +111,7 @@
$("#button-preview").html(linkStart + "search?q=pub:" + publisherName
+ imageStart + altText + imageSrc
+ selectedValue + imageEnd);
-
+
// Send the event to Analytics
ga('send', 'event', 'Distribute', 'Create Google Play Badge', 'Publisher ' + selectedValue);
} else {
@@ -159,7 +159,7 @@
/** Switch the badge urls for selected language */
function changeBadgeLang() {
var lang = $('#locale option:selected').val();
-
+
// check if we have the 'app' badge for this lang and show notice if not
$("div.button-row.error").remove(); // remove any existing instance of error message
if ($.inArray(lang,APP_LANGS) == -1) {
@@ -173,7 +173,7 @@
} else {
$("div.button-row.app").show(); // show the 'app' badge row
}
-
+
$('.button-row img').each(function() {
var id = $(this).parent().attr('for');
var imgName = lang + $('input#'+id).attr('value') + '.png';
@@ -356,7 +356,7 @@
style="font-family:monospace;background-color:#efefef;padding:5px;display:none;margin-bottom:1em">
</textarea >
-<p>Try it out:</p>
+<p>Test your badge:</p>
<div id="button-preview" style="margin-top:1em"></div>
</div>
diff --git a/docs/html/guide/topics/manifest/activity-element.jd b/docs/html/guide/topics/manifest/activity-element.jd
index ade05c9..7374a67 100644
--- a/docs/html/guide/topics/manifest/activity-element.jd
+++ b/docs/html/guide/topics/manifest/activity-element.jd
@@ -9,6 +9,7 @@
android:<a href="#reparent">allowTaskReparenting</a>=["true" | "false"]
android:<a href="#always">alwaysRetainTaskState</a>=["true" | "false"]
android:<a href="#autoremrecents">autoRemoveFromRecents</a>=["true" | "false"]
+ android:<a href="#banner">banner</a>="<i>drawable resource</i>"
android:<a href="#clear">clearTaskOnLaunch</a>=["true" | "false"]
android:<a href="#config">configChanges</a>=["mcc", "mnc", "locale",
"touchscreen", "keyboard", "keyboardHidden",
@@ -153,6 +154,29 @@
"{@code true}" or "{@code false}".</dd>
+<dt><a name="banner"></a>{@code android:banner}</dt>
+<dd>A <a href="{@docRoot}guide/topics/resources/drawable-resource.html">drawable resource</a>
+providing an extended graphical banner for its associated item. Use with the
+{@code <activity>} tag to supply a default banner for a specific activity, or with the
+<a href="{@docRoot}guide/topics/manifest/application-element.html"><code><application></code></a>
+tag to supply a banner for all application activities.
+
+<p>The system uses the banner to represent an app in
+the Android TV home screen. Since the banner is displayed only in the home screen, it
+should only be specified by applications with an activity that handles the
+{@link android.content.Intent#CATEGORY_LEANBACK_LAUNCHER} intent.</p>
+
+<p>This attribute must be set as a reference to a drawable resource containing
+the image (for example {@code "@drawable/banner"}). There is no default banner.
+</p>
+
+<p>
+See <a href="{@docRoot}design/tv/patterns.html#banner">
+Banners</a> in the UI Patterns for TV design guide, and <a href="{@docRoot}training/tv/start/start.html#banner">
+Provide a home screen banner</a> in Get Started with TV Apps for more information.
+</p></dd>
+
+
<dt><a name="clear"></a>{@code android:clearTaskOnLaunch}</dt>
<dd>Whether or not all activities will be removed from the task, except for
the root activity, whenever it is re-launched from the home screen —
diff --git a/docs/html/guide/topics/manifest/application-element.jd b/docs/html/guide/topics/manifest/application-element.jd
index 33f6bce..8a0e837 100644
--- a/docs/html/guide/topics/manifest/application-element.jd
+++ b/docs/html/guide/topics/manifest/application-element.jd
@@ -7,12 +7,14 @@
<dd><pre class="stx"><application android:<a href="#reparent">allowTaskReparenting</a>=["true" | "false"]
android:<a href="#allowbackup">allowBackup</a>=["true" | "false"]
android:<a href="#agent">backupAgent</a>="<i>string</i>"
+ android:<a href="#banner">banner</a>="<i>drawable resource</i>"
android:<a href="#debug">debuggable</a>=["true" | "false"]
android:<a href="#desc">description</a>="<i>string resource</i>"
android:<a href="#enabled">enabled</a>=["true" | "false"]
android:<a href="#code">hasCode</a>=["true" | "false"]
android:<a href="#hwaccel">hardwareAccelerated</a>=["true" | "false"]
android:<a href="#icon">icon</a>="<i>drawable resource</i>"
+ android:<a href="#isGame">isGame</a>=["true" | "false"]
android:<a href="#killrst">killAfterRestore</a>=["true" | "false"]
android:<a href="#largeHeap">largeHeap</a>=["true" | "false"]
android:<a href="#label">label</a>="<i>string resource</i>"
@@ -48,13 +50,13 @@
<dt>description:</dt>
<dd itemprop="description">The declaration of the application. This element contains subelements
-that declare each of the application's components and has attributes
-that can affect all the components. Many of these attributes (such as
-{@code icon}, {@code label}, {@code permission}, {@code process},
-{@code taskAffinity}, and {@code allowTaskReparenting}) set default values
+that declare each of the application's components and has attributes
+that can affect all the components. Many of these attributes (such as
+{@code icon}, {@code label}, {@code permission}, {@code process},
+{@code taskAffinity}, and {@code allowTaskReparenting}) set default values
for corresponding attributes of the component elements. Others (such as
-{@code debuggable}, {@code enabled}, {@code description}, and
-{@code allowClearUserData}) set values for the application as a whole and
+{@code debuggable}, {@code enabled}, {@code description}, and
+{@code allowClearUserData}) set values for the application as a whole and
cannot be overridden by the components.</dd>
@@ -65,18 +67,18 @@
<dd><dl class="attr">
<dt><a name="reparent"></a>{@code android:allowTaskReparenting}</dt>
-<dd>Whether or not activities that the application defines can move from
-the task that started them to the task they have an affinity for when that task
-is next brought to the front — {@code "true"} if they can move, and
-{@code "false"} if they must remain with the task where they started.
+<dd>Whether or not activities that the application defines can move from
+the task that started them to the task they have an affinity for when that task
+is next brought to the front — {@code "true"} if they can move, and
+{@code "false"} if they must remain with the task where they started.
The default value is {@code "false"}.
<p>
-The
-<code><a href="{@docRoot}guide/topics/manifest/activity-element.html"><activity></a></code>
-element has its own
+The
+<code><a href="{@docRoot}guide/topics/manifest/activity-element.html"><activity></a></code>
+element has its own
<code><a href="{@docRoot}guide/topics/manifest/activity-element.html#reparent">allowTaskReparenting</a></code>
-attribute that can override the value set here. See that attribute for more
+attribute that can override the value set here. See that attribute for more
information.
</p></dd>
@@ -92,46 +94,68 @@
<dt><a name="agent"></a>{@code android:backupAgent}</dt>
<dd>The name of the class that implement's the application's backup agent,
a subclass of {@link android.app.backup.BackupAgent}. The attribute value should be
-a fully qualified class name (such as, {@code "com.example.project.MyBackupAgent"}).
-However, as a shorthand, if the first character of the name is a period
-(for example, {@code ".MyBackupAgent"}), it is appended to the
-package name specified in the
-<code><a href="{@docRoot}guide/topics/manifest/manifest-element.html"><manifest></a></code>
+a fully qualified class name (such as, {@code "com.example.project.MyBackupAgent"}).
+However, as a shorthand, if the first character of the name is a period
+(for example, {@code ".MyBackupAgent"}), it is appended to the
+package name specified in the
+<code><a href="{@docRoot}guide/topics/manifest/manifest-element.html"><manifest></a></code>
element.
<p>
There is no default. The name must be specified.
</p></dd>
+<dt><a name="banner"></a>{@code android:banner}</dt>
+<dd>A <a href="{@docRoot}guide/topics/resources/drawable-resource.html">drawable resource</a>
+providing an extended graphical banner for its associated item. Use with the
+{@code <application>} tag to supply a default banner for all application activities, or with the
+<a href="{@docRoot}guide/topics/manifest/activity-element.html"><code><activity></code></a>
+tag to supply a banner for a specific activity.
+
+<p>The system uses the banner to represent an app in
+the Android TV home screen. Since the banner is displayed only in the home screen, it
+should only be specified by applications with an activity that handles the
+{@link android.content.Intent#CATEGORY_LEANBACK_LAUNCHER} intent.</p>
+
+<p>This attribute must be set as a reference to a drawable resource containing
+the image (for example {@code "@drawable/banner"}). There is no default banner.
+</p>
+
+<p>
+See <a href="{@docRoot}design/tv/patterns.html#banner">
+Banners</a> in the UI Patterns for TV design guide, and <a href="{@docRoot}training/tv/start/start.html#banner">
+Provide a home screen banner</a> in Get Started with TV Apps for more information.
+</p></dd>
+
<dt><a name="debug"></a>{@code android:debuggable}</dt>
-<dd>Whether or not the application can be debugged, even when running
+<dd>Whether or not the application can be debugged, even when running
on a device in user mode — {@code "true"} if it can be, and {@code "false"}
-if not. The default value is {@code "false"}.</dd>
+if not. The default value is {@code "false"}.</dd>
<dt><a name="desc"></a>{@code android:description}</dt>
<dd>User-readable text about the application, longer and more descriptive than the application label. The value must be set as a reference to a string resource. Unlike the label, it cannot be a raw string. There is no default value.</dd>
<dt><a name="enabled"></a>{@code android:enabled}</dt>
-<dd>Whether or not the Android system can instantiate components of
-the application — {@code "true"} if it can, and {@code "false"}
-if not. If the value is {@code "true"}, each component's
-{@code enabled} attribute determines whether that component is enabled
-or not. If the value is {@code "false"}, it overrides the
+<dd>Whether or not the Android system can instantiate components of
+the application — {@code "true"} if it can, and {@code "false"}
+if not. If the value is {@code "true"}, each component's
+{@code enabled} attribute determines whether that component is enabled
+or not. If the value is {@code "false"}, it overrides the
component-specific values; all components are disabled.
<p>
The default value is {@code "true"}.
-</p></dd>
+</p></dd>
<dt><a name="code"></a>{@code android:hasCode}</dt>
-<dd>Whether or not the application contains any code — {@code "true"}
-if it does, and {@code "false"} if not. When the value is {@code "false"},
-the system does not try to load any application code when launching components.
+<dd>Whether or not the application contains any code — {@code "true"}
+if it does, and {@code "false"} if not. When the value is {@code "false"},
+the system does not try to load any application code when launching components.
The default value is {@code "true"}.
<p>
An application would not have any code of its own only if it's using nothing
-but built-in component classes, such as an activity that uses the {@link
+but built-in component classes, such as an activity that uses the {@link
android.app.AliasActivity} class, a rare occurrence.</p>
</dd>
@@ -140,7 +164,7 @@
activities and views in this application — {@code "true"} if it
should be enabled, and {@code "false"} if not. The default value is {@code "true"} if you've set
either <a href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#min">{@code minSdkVersion}</a>
-or <a
+or <a
href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#target">{@code targetSdkVersion}</a>
to {@code "14"} or higher; otherwise, it's {@code "false"}.
@@ -161,20 +185,26 @@
</dd>
<dt><a name="icon"></a>{@code android:icon}</dt>
-<dd>An icon for the application as whole, and the default icon for
-each of the application's components. See the individual
-{@code icon} attributes for
-<code><a href="{@docRoot}guide/topics/manifest/activity-element.html"><activity></a></code>,
+<dd>An icon for the application as whole, and the default icon for
+each of the application's components. See the individual
+{@code icon} attributes for
+<code><a href="{@docRoot}guide/topics/manifest/activity-element.html"><activity></a></code>,
<code><a href="{@docRoot}guide/topics/manifest/activity-alias-element.html"><activity-alias></a></code>,
-<code><a href="{@docRoot}guide/topics/manifest/service-element.html"><service></a></code>,
+<code><a href="{@docRoot}guide/topics/manifest/service-element.html"><service></a></code>,
<code><a href="{@docRoot}guide/topics/manifest/receiver-element.html"><receiver></a></code>, and
<code><a href="{@docRoot}guide/topics/manifest/provider-element.html"><provider></a></code> elements.
<p>
This attribute must be set as a reference to a drawable resource containing
-the image (for example {@code "@drawable/icon"}). There is no default icon.
+the image (for example {@code "@drawable/icon"}). There is no default icon.
</p></dd>
+<dt><a name="isGame"></a>{@code android:isGame}</dt>
+<dd>Whether or not the application is a game. The system may group together applications classifed
+as games or display them separately from other applications.
+
+<p>The default is {@code false}.</p></dd>
+
<dt><a name="killrst"></a>{@code android:killAfterRestore}</dt>
<dd>Whether the application in question should be terminated after its
settings have been restored during a full-system restore operation.
@@ -202,65 +232,65 @@
</dd>
<dt><a name="label"></a>{@code android:label}</dt>
-<dd>A user-readable label for the application as a whole, and a default
-label for each of the application's components. See the individual
-{@code label} attributes for
-<code><a href="{@docRoot}guide/topics/manifest/activity-element.html"><activity></a></code>,
+<dd>A user-readable label for the application as a whole, and a default
+label for each of the application's components. See the individual
+{@code label} attributes for
+<code><a href="{@docRoot}guide/topics/manifest/activity-element.html"><activity></a></code>,
<code><a href="{@docRoot}guide/topics/manifest/activity-alias-element.html"><activity-alias></a></code>,
-<code><a href="{@docRoot}guide/topics/manifest/service-element.html"><service></a></code>,
+<code><a href="{@docRoot}guide/topics/manifest/service-element.html"><service></a></code>,
<code><a href="{@docRoot}guide/topics/manifest/receiver-element.html"><receiver></a></code>, and
<code><a href="{@docRoot}guide/topics/manifest/provider-element.html"><provider></a></code> elements.
<p>
The label should be set as a reference to a string resource, so that
-it can be localized like other strings in the user interface.
-However, as a convenience while you're developing the application,
+it can be localized like other strings in the user interface.
+However, as a convenience while you're developing the application,
it can also be set as a raw string.
</p></dd>
<dt><a name="logo"></a>{@code android:logo}</dt>
<dd>A logo for the application as whole, and the default logo for activities.
<p>This attribute must be set as a reference to a drawable resource containing
-the image (for example {@code "@drawable/logo"}). There is no default logo.</p></dd>
+the image (for example {@code "@drawable/logo"}). There is no default logo.</p></dd>
<dt><a name="space"></a>{@code android:manageSpaceActivity}</dt>
-<dd>The fully qualified name of an Activity subclass that the system
-can launch to let users manage the memory occupied by the application
-on the device. The activity should also be declared with an
+<dd>The fully qualified name of an Activity subclass that the system
+can launch to let users manage the memory occupied by the application
+on the device. The activity should also be declared with an
<code><a href="{@docRoot}guide/topics/manifest/activity-element.html"><activity></a></code> element.
</dd>
<dt><a name="nm"></a>{@code android:name}</dt>
-<dd>The fully qualified name of an {@link android.app.Application}
-subclass implemented for the application. When the application process
-is started, this class is instantiated before any of the application's
-components.
+<dd>The fully qualified name of an {@link android.app.Application}
+subclass implemented for the application. When the application process
+is started, this class is instantiated before any of the application's
+components.
<p>
The subclass is optional; most applications won't need one.
-In the absence of a subclass, Android uses an instance of the base
+In the absence of a subclass, Android uses an instance of the base
Application class.
</p></dd>
<dt><a name="prmsn"></a>{@code android:permission}</dt>
-<dd>The name of a permission that clients must have in order to interact
-with the application. This attribute is a convenient way to set a
-permission that applies to all of the application's components. It can
-be overwritten by setting the {@code permission} attributes of individual
+<dd>The name of a permission that clients must have in order to interact
+with the application. This attribute is a convenient way to set a
+permission that applies to all of the application's components. It can
+be overwritten by setting the {@code permission} attributes of individual
components.
<p>
-For more information on permissions, see the
-<a href="{@docRoot}guide/topics/manifest/manifest-intro.html#sectperm">Permissions</a>
-section in the introduction and another document,
+For more information on permissions, see the
+<a href="{@docRoot}guide/topics/manifest/manifest-intro.html#sectperm">Permissions</a>
+section in the introduction and another document,
<a href="{@docRoot}guide/topics/security/security.html">Security and
Permissions</a>.
</p></dd>
<dt><a name="persistent"></a>{@code android:persistent}</dt>
-<dd>Whether or not the application should remain running at all times —
-{@code "true"} if it should, and {@code "false"} if not. The default value
-is {@code "false"}. Applications should not normally set this flag;
+<dd>Whether or not the application should remain running at all times —
+{@code "true"} if it should, and {@code "false"} if not. The default value
+is {@code "false"}. Applications should not normally set this flag;
persistence mode is intended only for certain system applications.</dd>
<dt><a name="proc"></a>{@code android:process}</dt>
@@ -282,9 +312,9 @@
</p>
<p>
-If the name assigned to this attribute begins with a colon (':'), a new
+If the name assigned to this attribute begins with a colon (':'), a new
process, private to the application, is created when it's needed.
-If the process name begins with a lowercase character, a global process
+If the process name begins with a lowercase character, a global process
of that name is created. A global process can be shared with other
applications, reducing resource usage.
</p></dd>
@@ -307,7 +337,7 @@
If your app requires an {@link android.accounts.Account}, the value for this attribute must
correspond to the account authenticator
type used by your app (as defined by {@link android.accounts.AuthenticatorDescription}),
-such as "com.google".
+such as "com.google".
<p>The default value is null and indicates that the application
can work <em>without</em> any accounts.
@@ -369,13 +399,13 @@
<dt><a name="aff"></a>{@code android:taskAffinity}</dt>
<dd>An affinity name that applies to all activities within the application,
except for those that set a different affinity with their own
-<code><a href="{@docRoot}guide/topics/manifest/activity-element.html#aff">taskAffinity</a></code>
+<code><a href="{@docRoot}guide/topics/manifest/activity-element.html#aff">taskAffinity</a></code>
attributes. See that attribute for more information.
<p>
-By default, all activities within an application share the same
-affinity. The name of that affinity is the same as the package name
-set by the
+By default, all activities within an application share the same
+affinity. The name of that affinity is the same as the package name
+set by the
<code><a href="{@docRoot}guide/topics/manifest/manifest-element.html"><manifest></a></code> element.
</p></dd>
@@ -389,7 +419,7 @@
<dt><a name="theme"></a>{@code android:theme}</dt>
<dd>A reference to a style resource defining a default theme for all
activities in the application. Individual activities can override
-the default by setting their own <code><a href="{@docRoot}guide/topics/manifest/activity-element.html#theme">theme</a></code>
+the default by setting their own <code><a href="{@docRoot}guide/topics/manifest/activity-element.html#theme">theme</a></code>
attributes. For more information, see the <a
href="{@docRoot}guide/topics/ui/themes.html">Styles and Themes</a> developer guide.
</dd>
diff --git a/docs/html/images/emulator-wvga800l.png b/docs/html/images/emulator-wvga800l.png
deleted file mode 100644
index c92c1b9..0000000
--- a/docs/html/images/emulator-wvga800l.png
+++ /dev/null
Binary files differ
diff --git a/docs/html/images/emulator.png b/docs/html/images/emulator.png
new file mode 100644
index 0000000..96a2507
--- /dev/null
+++ b/docs/html/images/emulator.png
Binary files differ
diff --git a/docs/html/images/emulator@2x.png b/docs/html/images/emulator@2x.png
new file mode 100644
index 0000000..9b825a7
--- /dev/null
+++ b/docs/html/images/emulator@2x.png
Binary files differ
diff --git a/docs/html/images/games/game-controller-buttons_2x_crop.png b/docs/html/images/games/game-controller-buttons_2x_crop.png
new file mode 100644
index 0000000..54dc2fa
--- /dev/null
+++ b/docs/html/images/games/game-controller-buttons_2x_crop.png
Binary files differ
diff --git a/docs/html/images/gp-tv-opt-in.png b/docs/html/images/gp-tv-opt-in.png
new file mode 100644
index 0000000..a815818
--- /dev/null
+++ b/docs/html/images/gp-tv-opt-in.png
Binary files differ
diff --git a/docs/html/images/gp-tv-process.png b/docs/html/images/gp-tv-process.png
new file mode 100644
index 0000000..a530777
--- /dev/null
+++ b/docs/html/images/gp-tv-process.png
Binary files differ
diff --git a/docs/html/images/tools/as-attach.png b/docs/html/images/tools/as-attach.png
new file mode 100644
index 0000000..c572b1e
--- /dev/null
+++ b/docs/html/images/tools/as-attach.png
Binary files differ
diff --git a/docs/html/images/tools/studio-build-variant.png b/docs/html/images/tools/studio-build-variant.png
new file mode 100644
index 0000000..a400ad4
--- /dev/null
+++ b/docs/html/images/tools/studio-build-variant.png
Binary files differ
diff --git a/docs/html/images/ui/notifications/heads-up.png b/docs/html/images/ui/notifications/heads-up.png
index 42fbbcd..75cc95e 100644
--- a/docs/html/images/ui/notifications/heads-up.png
+++ b/docs/html/images/ui/notifications/heads-up.png
Binary files differ
diff --git a/docs/html/jd_collections.js b/docs/html/jd_collections.js
index 08c0090..d63580e 100644
--- a/docs/html/jd_collections.js
+++ b/docs/html/jd_collections.js
@@ -57,8 +57,8 @@
},
"distribute/gp/gpfelanding": {
"resources": [
+ "distribute/googleplay/tv.html",
"distribute/googleplay/edu/about.html",
- "distribute/googleplay/edu/start.html",
"distribute/googleplay/edu/videos.html"
]
},
@@ -773,6 +773,14 @@
"https://support.google.com/googleplay/answer/2651410"
]
},
+ "tvlanding": {
+ "title": "",
+ "resources": [
+ "tv/index.html",
+ "design/tv/index.html",
+ "training/tv/index.html"
+ ]
+ },
"distribute/stories/games": {
"title": "",
"resources": [
diff --git a/docs/html/sdk/installing/adding-packages.jd b/docs/html/sdk/installing/adding-packages.jd
index 22d055c..b8d8925 100644
--- a/docs/html/sdk/installing/adding-packages.jd
+++ b/docs/html/sdk/installing/adding-packages.jd
@@ -1,6 +1,6 @@
page.title=Adding SDK Packages
-page.tags=studio, sdk tools, eclipse adt, sdk manager, google play services, support library
+page.tags=sdk manager
helpoutsWidget=true
@jd:body
diff --git a/docs/html/sdk/installing/index.jd b/docs/html/sdk/installing/index.jd
index 6a99952..68f4eb7 100644
--- a/docs/html/sdk/installing/index.jd
+++ b/docs/html/sdk/installing/index.jd
@@ -1,6 +1,6 @@
page.title=Installing the Android SDK
-page.tags=studio, sdk tools, eclipse adt
+page.tags=sdk tools
helpoutsWidget=true
@jd:body
@@ -74,9 +74,9 @@
<!-- ################ STUDIO ##################### -->
<div id="studio" heading="Installing Android Studio" style="display:none">
-<p>Android Studio provides everything you need to start developing apps, including
-the Android SDK tools and the Android Studio IDE (powered by IntelliJ) to
-streamline your Android app development.</p>
+<p>Android Studio provides the tools you need to start developing apps, including
+the Android Studio IDE (powered by IntelliJ) and guides you to install
+the Android SDK tools to streamline your Android app development.</p>
<p>If you didn't download Android Studio, go <a href="{@docRoot}sdk/installing/studio.html"
><b>download Android Studio now</b></a>, or switch to the
@@ -103,8 +103,9 @@
<p><b>To set up Android Studio on Windows:</b></p>
<ol>
- <li>Launch the downloaded EXE file, {@code android-studio-bundle-<version>.exe}.</li>
- <li>Follow the setup wizard to install Android Studio.
+ <li>Unzip the file, {@code android-studio-ide-<version>-windows.zip} and launch the
+ <code>studio.exe</code> file.</li>
+ <li>Follow the setup wizard to install Android Studio and the SDK Tools.
<p>On some Windows systems, the launcher script does not find where Java is installed.
If you encounter this problem,
@@ -119,11 +120,10 @@
</ol>
-<p>The individual tools and
-other SDK packages are saved within the Android Studio application directory.
-If you need to access the tools directly, use a terminal to navigate into the application and locate
-the {@code sdk/} directory. For example:</p>
-<p><code>\Users\<user>\AppData\Local\Android\android-studio\sdk\</code></p>
+<p>The individual tools and other SDK packages are saved outside the Android Studio application
+directory. If you need to access the tools directly, use a terminal to navigate to the location
+where they are installed. For example:</p>
+<p><code>\Users\<user>\sdk\</code></p>
@@ -134,7 +134,7 @@
<p><b>To set up Android Studio on Mac OSX:</b></p>
<ol>
- <li>Open the downloaded DMG file, {@code android-studio-bundle-<version>.dmg}.</li>
+ <li>Unzip the downloaded zip file, {@code android-studio-ide-<version>-mac.zip}.</li>
<li>Drag and drop Android Studio into the Applications folder.
<p>
Depending on your security settings, when you attempt to open Android Studio, you might
@@ -143,13 +143,13 @@
<strong>Allow applications downloaded from</strong>, select <strong>Anywhere</strong>.
Then open Android Studio again.</p>
</li>
+ <li>Follow the links to install the SDK outside of the Android Studio directories.</li>
</ol>
-<p>The individual tools and
-other SDK packages are saved within the Android Studio application directory.
-If you need access the tools directly, use a terminal to navigate into the application and locate
-the {@code sdk/} directory. For example:</p>
-<p><code>/Applications/Android\ Studio.app/sdk/</code></p>
+<p>The individual tools and other SDK packages are saved outside the Android Studio application
+directory. If you need access the tools directly, use a terminal to navigate into the location
+where they are installed. For example:</p>
+<p><code>/Applications/sdk/</code></p>
</div><!-- end mac -->
@@ -160,13 +160,14 @@
<p><b>To set up Android Studio on Linux:</b></p>
<ol>
- <li>Unpack the downloaded Tar file, {@code android-studio-bundle-<version>.tgz}, into an appropriate
- location for your applications.
+ <li>Unpack the downloaded Tar file, {@code android-studio-ide-<version>-linux.zip}, into an
+ appropriate location for your applications.
<li>To launch Android Studio, navigate to the {@code android-studio/bin/} directory
in a terminal and execute {@code studio.sh}.
<p>You may want to add {@code android-studio/bin/} to your PATH environmental
variable so that you can start Android Studio from any directory.</p>
</li>
+ <li>Follow the links to install the SDK outside of the Android Studio directories.</li>
</ol>
</div><!-- end linux -->
@@ -217,11 +218,12 @@
<p>Your download package is an executable file that starts an installer. The installer checks your machine
for required tools, such as the proper Java SE Development Kit (JDK) and installs it if necessary.
- The installer then saves the Android SDK Tools into a default location (or you can specify the location).</p>
+ The installer then saves the Android SDK Tools to a specified the location outside of the Android
+ Studio directories.</p>
<ol>
<li>Double-click the executable ({@code .exe} file) to start the install.</li>
-<li>Make a note of the name and location in which it saves the SDK on your system—you will need to
+<li>Make a note of the name and location where you save the SDK on your system—you will need to
refer to the SDK directory later when using
the SDK tools from the command line.</li>
<li>Once the installation completes, the installer starts the Android SDK Manager.
@@ -237,8 +239,8 @@
<p><b>To get started on Mac OSX:</b></p>
<p>Unpack the ZIP file you've downloaded. By default, it's unpacked
-into a directory named <code>android-sdk-mac_x86</code>. Move it to an appropriate location on your machine,
-such as a "Development" directory in your home directory.</p>
+into a directory named <code>android-sdk-mac_x86</code>. Move it to an appropriate location on your
+machine, such as a "Development" directory in your home directory.</p>
<p>Make a note of the name and location of the SDK directory on your system—you will need to
refer to the SDK directory later when using
@@ -253,9 +255,8 @@
<p><b>To get started on Linux:</b></p>
-<p>Unpack the {@code .tgz} file you've downloaded. By default, the SDK files are unpacked
-into a directory named <code>android-sdk-linux_x86</code>. Move it to an appropriate location on your machine,
-such as a "Development" directory in your home directory.</p>
+<p>Unpack the {@code .zip} file you've downloaded. The SDK files are download separately to a
+user-specified directory. </p>
<p>Make a note of the name and location of the SDK directory on your system—you will need to
refer to the SDK directory later when using
diff --git a/docs/html/sdk/installing/studio-debug.jd b/docs/html/sdk/installing/studio-debug.jd
index 2e3e137..b048400 100644
--- a/docs/html/sdk/installing/studio-debug.jd
+++ b/docs/html/sdk/installing/studio-debug.jd
@@ -6,7 +6,11 @@
<div id="qv">
<h2>In this document</h2>
<ol>
- <li><a href="#runDebug">Run your App in Debug Mode</a></li>
+ <li><a href="#runDebug">Run your App in Debug Mode</a>
+ <ol>
+ <li><a href="#attachDebug">Attach the debugger to a running process</a></li>
+ </ol>
+ </li>
<li><a href="#systemLog">Use the System Log</a>
<ol>
<li><a href="#systemLogWrite">Write log messages in your code</a></li>
@@ -94,6 +98,22 @@
<p class="img-caption"><strong>Figure 2.</strong> The Debug tool window in Android Studio showing
the current thread and the object tree for a variable.</p>
+<h3 id="attachDebug">Attach the debugger to a running process</h3>
+
+<p>You don't always have to restart your app to debug it. To debug an app that you're already
+running:</p>
+
+<ol>
+<li>Click <strong>Attach debugger to Android proccess</strong>
+<img src="{@docRoot}images/tools/as-attach.png" alt=""
+style="vertical-align:bottom;margin:0;height:20px"/>.</li>
+<li>In the <em>Choose Process</em> window, select the device and app you want to attach the
+debugger to.</li>
+<li>To open the <em>Debug</em> tool window, click <strong>Debug</strong>
+<img src="{@docRoot}images/tools/as-debugwindowbutton.png"
+alt="" style="vertical-align:bottom;margin:0;height:20px"/>.</li>
+</ol>
+
<h2 id="systemLog">Use the System Log</h2>
diff --git a/docs/html/sdk/installing/studio.jd b/docs/html/sdk/installing/studio.jd
index b0567e7..f02cdbc 100644
--- a/docs/html/sdk/installing/studio.jd
+++ b/docs/html/sdk/installing/studio.jd
@@ -194,12 +194,12 @@
href="" style="display:none;width:368px;margin:0 auto;display:block;font-size:18px" ></a>
<div style="margin:20px 0 0 0">
-<p style="margin-bottom:8px">This download includes:</p>
+<p style="margin-bottom:8px">This installation includes:</p>
<ul style="margin-bottom:20px">
-<li>Android Studio Beta</li>
-<li>All the Android SDK Tools to design, test, and debug your app</li>
-<li>A version of the Android platform to compile your app</li>
-<li>A version of the Android system image to run your app in the emulator</li>
+ <li>Android Studio Beta</li>
+ <li>All the Android SDK Tools to design, test, and debug your app</li>
+ <li>A version of the Android platform to compile your app</li>
+ <li>A version of the Android system image to run your app in the emulator</li>
</ul>
</div>
@@ -244,43 +244,41 @@
<th>Platform</th>
<th>Package</th>
<th>Size</th>
- <th>MD5 Checksum</th>
+ <th>SHA Sum</th>
</tr>
<tr>
<td>Windows</td>
<td>
<a onclick="return onDownload(this)" id="win-studio"
- href="https://dl.google.com/android/studio/install/0.8.6/android-studio-bundle-135.1339820-windows.exe">
- android-studio-bundle-135.1339820-windows.exe
+ href="https://dl.google.com/dl/android/studio/ide-zips/0.8.14/android-studio-ide-135.1538390-windows.zip">android-studio-ide-135.1538390-windows.zip
</a>
</td>
- <td>379497130 bytes</td>
- <td>024e002b8c8fa7dcd2ff69fd69e06e56</td>
+ <td>177343814 bytes</td>
+ <td>b533480200ba893616c73b32477e66ebb357a1b3</td>
</tr>
<tr>
<td><nobr>Mac OS X</nobr></td>
<td>
<a onclick="return onDownload(this)" id="mac-studio"
- href="https://dl.google.com/android/studio/install/0.8.6/android-studio-bundle-135.1339820-mac.dmg">
- android-studio-bundle-135.1339820-mac.dmg
+ href="https://dl.google.com/dl/android/studio/ide-zips/0.8.14/android-studio-ide-135.1538390-mac.zip">
+ android-studio-ide-135.1538390-mac.zip
</a>
</td>
- <td>368507143 bytes</td>
- <td>4143f2aa556634eae91701965d88899b</td>
+ <td>176745627 bytes</td>
+ <td>4070e6f6a44d042266f46f1f2f9ca3448ac23f8cd</td>
</tr>
<tr>
<td>Linux</td>
<td>
<a onclick="return onDownload(this)" id="linux-studio"
- href="https://dl.google.com/android/studio/install/0.8.6/android-studio-bundle-135.1339820-linux.tgz">
- android-studio-bundle-135.1339820-linux.tgz
+ href="https://dl.google.com/dl/android/studio/ide-zips/0.8.14/android-studio-ide-135.1538390-linux.zip">android-studio-ide-135.1538390-linux.zip
</a>
</td>
- <td>417631443 bytes</td>
- <td>fa403762ecd0a5da87acbeff485f81cc</td>
+ <td>176358193 bytes</td>
+ <td>718356b49254f6c4e55c64b99164d311995205dd</td>
</tr>
</table>
@@ -301,44 +299,47 @@
<tr>
<td>
<ul>
- <li>Microsoft Windows 8, 7, Vista, 2003, or XP (32 or 64 bit)</li>
- <li>1 GB of RAM minimum, 2 GB recommended</li>
- <li>400 MB of disk space</li>
- <li>At least 1 GB of additional disk space for the Android SDK, emulator system images, and caches</li>
+ <li>Microsoft Windows 8/7/Vista/2003 (32 or 64 bit)</li>
+ <li>2 GB RAM minimum, 4 GB RAM recommended</li>
+ <li>400 MB disk space </li>
+ <li>At least 1 GB for Android SDK, emulator system images, and caches</li>
<li>1280x800 minimum screen resolution</li>
- <li>Java Development Kit (JDK) 6 or higher</li>
+ <li>Java Development Kit (JDK) 7 or higher</li>
+ <li>(Optional for accelerated emulator: Intel processor with support for Intel VT-x, Intel
+ EM64T (Intel 64), and Execute Disable (XD) Bit functionality)</li>
</ul>
</td>
<td>
<ul>
<li>Mac OS X 10.8.5 or higher, up to 10.9 (Mavericks)</li>
- <li>1 GB of RAM minimum, 2 GB recommended</li>
- <li>400 MB of disk space</li>
- <li>At least 1 GB of additional disk space for the Android SDK, emulator system images, and caches</li>
+ <li>2 GB RAM minimum, 4 GB RAM recommended</li>
+ <li>400 MB disk space</li>
+ <li>At least 1 GB for Android SDK, emulator system images, and caches</li>
<li>1280x800 minimum screen resolution</li>
- <li>Java Runtime Environment (JRE) 6 *</li>
- <li>Java Development Kit (JDK) 6 or JDK 7</li>
+ <li>Java Runtime Environment (JRE) 6</li>
+ <li>Java Development Kit (JDK) 7 or higher
+ <p>On Mac OS, run Android Studio with Java Runtime Environment (JRE) 6 for optimized font
+ rendering. You can then configure your project to use Java Development Kit (JDK) JDK 7.</p></li>
+ <li>(Optional for accelerated emulator: Intel processor with support for Intel VT-x, Intel
+ EM64T (Intel 64), and Execute Disable (XD) Bit functionality)</li>
</ul>
-<p>* On Mac OS, run Android Studio with Java Runtime Environment (JRE) 6 for optimized font
-rendering. You can then configure your project to use Java Development Kit (JDK) 6 or JDK 7.</p>
+
</td>
<td>
<ul>
- <li>64-bit distribution capable of running 32-bit applications</li>
+ <li>GNOME or KDE desktop.</li>
+ <li>Tested on Ubuntu 12.04, Precise Pangolin (64-bit distribution capable of running 32-bit
+ applications)</li>
<li>GNU C Library (glibc) 2.11 or later is required.</li>
- <li>Tested on Ubuntu 12.04, Precise Pangolin</li>
- <li>GNOME or KDE desktop</li>
- <li>1 GB of RAM minimum, 2 GB recommended</li>
- <li>400 MB of disk space</li>
- <li>At least 1 GB of additional disk space for the Android SDK, emulator system images, and caches</li>
+ <li>2 GB RAM minimum, 4 GB RAM recommended</li>
+ <li>400 MB disk space</li>
+ <li>At least 1 GB for Android SDK, emulator system images, and caches</li>
<li>1280x800 minimum screen resolution</li>
- <li>Oracle Java Development Kit (JDK) 6 or JDK 7</li>
+ <li>Java Development Kit (JDK) 7 or higher</li>
</ul>
</td>
</tr>
</table>
-<p class="note"><strong>Note:</strong> Java Development Kit (JDK) 7 is required if you're targeting
-the Android L Developer Preview.</p>
</div><!-- end pax -->
@@ -425,7 +426,7 @@
<p><strong>Caution:</strong> Replacing your existing installation of
Android Studio will remove any additional SDK packages you've installed, such as target
platforms, system images, and sample apps. To preserve these, copy them from your current
-SDK directory under Android Studio to a temporary location
+SDK directory to a temporary location
before installing the update. Then move them back once the update is complete.
If you fail to copy these packages, then you can instead download them again through
the Android SDK Manager.</p>
@@ -453,6 +454,17 @@
<div class="toggle-content opened">
<p><a href="#" onclick="return toggleContent(this)">
<img src="{@docRoot}assets/images/triangle-opened.png" class="toggle-content-img"
+ alt=""/>Android Studio v0.8.14</a> <em>(October 2014)</em>
+ </p>
+
+ <div class="toggle-content-toggleme">
+ <p>See <a href="http://tools.android.com/recent">tools.android.com</a> for a full list of changes.</p>
+ </div>
+</div>
+
+<div class="toggle-content closed">
+ <p><a href="#" onclick="return toggleContent(this)">
+ <img src="{@docRoot}assets/images/triangle-closed.png" class="toggle-content-img"
alt=""/>Android Studio v0.8.6</a> <em>(August 2014)</em>
</p>
@@ -650,7 +662,7 @@
if (os) {
/* set up primary ACE download button */
$('#download-ide-button').show();
- $('#download-ide-button').append("Download Android Studio Beta <span class='small'>v0.8.6</span>"
+ $('#download-ide-button').append("Download Android Studio Beta <span class='small'>v0.8.14</span>"
+ "<br/> <span class='small'>with the Android SDK for " + os + "</span>");
$('#download-ide-button').click(function() {return onDownload(this,true);}).attr('href', bundlename);
diff --git a/docs/html/tools/building/multidex.jd b/docs/html/tools/building/multidex.jd
new file mode 100644
index 0000000..49cde8c
--- /dev/null
+++ b/docs/html/tools/building/multidex.jd
@@ -0,0 +1,458 @@
+page.title=Building Apps with Over 65K Methods
+page.tags="65536","references","max","65k","dex","64k","multidex","multi-dex","methods"</p>
+
+@jd:body
+
+<div id="qv-wrapper">
+ <div id="qv">
+ <h2>In this document</h2>
+ <ol>
+ <li><a href="#about">
+ About the 65K Reference Limit</a>
+ <ol>
+ <li><a href="#mdex-pre-l">Multidex support prior to Android 5.0</a></li>
+ <li><a href="#mdex-on-l">Multidex support for Android 5.0 and higher</a></li>
+ </ol>
+ </li>
+ <li><a href="#avoid">
+ Avoiding the 65K Limit</a></li>
+ <li><a href="#mdex-gradle">
+ Configuring Your App for Multidex with Gradle</a>
+ <ol>
+ <li><a href="#limitations">
+ Limitations of the multidex support library</a></li>
+ </ol>
+ </li>
+ <li><a href="#dev-build">
+ Optimizing Multidex Development Builds</a>
+ <ol>
+ <li><a href="#variants-studio">
+ Using Build Variants in Android Studio</a></li>
+ </ol>
+ </li>
+ <li><a href="#testing">
+ Testing Multidex Apps</a></li>
+ </ol>
+
+ <h2>See Also</h2>
+ <ol>
+ <li><a href="{@docRoot}tools/help/proguard.html">ProGuard</a>
+ </li>
+ </ol>
+ </div>
+</div>
+
+
+<p>
+ As the Android platform has continued to grow, so has the size of Android apps. When your
+ application and the libraries it references reach a certain size, you encounter build errors that
+ indicate your app has reached a limit of the Android app build architecture. Earlier versions of
+ the build system report this error as follows:
+</p>
+
+<pre>
+Conversion to Dalvik format failed:
+Unable to execute dex: method ID not in [0, 0xffff]: 65536
+</pre>
+
+<p>
+ More recent versions of the Android build system display a different error, which is an
+ indication of the same problem:
+</p>
+
+<pre>
+trouble writing output:
+Too many field references: 131000; max is 65536.
+You may try using --multi-dex option.
+</pre>
+
+<p>
+ Both these error conditions display a common number: 65,536. This number is significant in that
+ it represents the total number of references that can be invoked by the code within a single
+ Dalvik Executable (dex) bytecode file. If you have built an Android app and received this error,
+ then congratulations, you have a lot of code! This document explains how to move past this
+ limitation and continue building your app.
+</p>
+
+<p class="note">
+ <strong>Note:</strong> The guidance provided in this document supersedes the guidance given in
+ the Android Developers blog post <a href=
+ "http://android-developers.blogspot.com/2011/07/custom-class-loading-in-dalvik.html">Custom Class
+ Loading in Dalvik</a>.
+</p>
+
+
+<h2 id="about">About the 65K Reference Limit</h2>
+
+<p>
+ Android application (APK) files contain executable bytecode files in the form of <a href=
+ "https://source.android.com/devices/tech/dalvik/">Dalvik</a> Executable (DEX) files, which
+ contain the compiled code used to run your app. The Dalvik Executable specification limits the
+ total number of methods that can be referenced within a single DEX file to 65,536, including
+ Android framework methods, library methods, and methods in your own code. Getting past this limit
+ requires that you configure your app build process to generate more than one DEX file, known as a
+ <em>multidex</em> configuration.
+</p>
+
+
+<h3 id="mdex-pre-l">Multidex support prior to Android 5.0</h3>
+
+<p>
+ Versions of the platform prior to Android 5.0 use the Dalvik runtime for executing app code. By
+ default, Dalvik limits apps to a single classes.dex bytecode file per APK. In order to get around
+ this limitation, you can use the <a href="{@docRoot}tools/support-library/features.html#multidex">
+ multidex support library</a>, which becomes part of the primary DEX file of your app and then
+ manages access to the additional DEX files and the code they contain.
+</p>
+
+
+<h3 id="mdex-on-l">Multidex support for Android 5.0 and higher</h3>
+
+<p>
+ Android 5.0 and higher uses a runtime called ART which natively supports loading multiple dex
+ files from application APK files. ART performs pre-compilation at application install time which
+ scans for classes(..N).dex files and compiles them into a single .oat file for execution by the
+ Android device. For more information on the Android 5.0 runtime, see <a href=
+ "https://source.android.com/devices/tech/dalvik/art.html">Introducing ART</a>.
+</p>
+
+
+<h2 id="avoid">Avoiding the 65K Limit</h2>
+
+<p>
+ Before configuring your app to enable use of 65K or more method references, you should take steps
+ to reduce the total number of references called by your app code, including methods defined by
+ your app code or included libraries. The following strategies can help you avoid hitting the dex
+ reference limit:
+</p>
+
+<ul>
+ <li>
+ <strong>Review your app's direct and transitive dependencies</strong> - Ensure any large library
+ dependency you include in your app is used in a manner that outweighs the amount of code
+ being added to the application. A common anti-pattern is to include a very large library
+ because a few utility methods were useful. Reducing your app code dependencies can often help
+ you avoid the dex reference limit.
+ </li>
+ <li>
+ <strong>Remove unused code with ProGuard</strong> - Configure the <a href=
+ "{@docRoot}tools/help/proguard.html">ProGuard</a> settings for your app to run ProGuard and
+ ensure you have shrinking enabled for release builds. Enabling shrinking ensures you
+ are not shipping unused code with your APKs.
+ </li>
+</ul>
+
+
+<p>
+ Using these techniques can help you avoid the build configuration changes required to enable more
+ method references in your app. These steps can also decrease the size of your APKs, which is
+ particularly important for markets where bandwidth costs are high.
+</p>
+
+
+<h2 id="mdex-gradle">Configuring Your App for Multidex with Gradle</h2>
+
+<p>
+ The Android plugin for Gradle available in Android SDK Build Tools 21.1 and higher supports
+ multidex as part of your build configuration. Make sure you update the Android SDK Build Tools
+ tools and the Android Support Repository to the latest version using the <a href=
+ "{@docRoot}tools/help/sdk-manager.html">SDK Manager</a> before attempting to configure your app
+ for multidex.
+</p>
+
+<p>
+ Setting up your app development project to use a multidex configuration requires that you make a
+ few modifications to your app development project. In particular you need to perform the
+ following steps:
+</p>
+
+<ul>
+ <li>Change your Gradle build configuration to enable multidex</li>
+ <li>Modify your manifest to reference the {@link android.support.multidex.MultiDexApplication}
+ class</li>
+</ul>
+
+<p>
+ Modify your app Gradle build file configuration to include the support library and enable
+ multidex output, as shown in the following Gradle build file snippet:
+</p>
+
+<pre>
+android {
+ compileSdkVersion 21
+ buildToolsVersion "21.1.0"
+
+ defaultConfig {
+ ...
+ minSdkVersion 14
+ targetSdkVersion 21
+ ...
+
+ // Enabling multidex support.
+ multiDexEnabled true
+ }
+ ...
+}
+
+dependencies {
+ compile 'com.android.support:multidex:1.0.0'
+}
+</pre>
+
+<p class="note">
+ <strong>Note:</strong> You can specify the <code>multiDexEnabled</code> setting in the
+ <code>defaultConfig,</code> <code>buildType</code>, or <code>productFlavor</code> sections of
+ your Gradle build file.
+</p>
+
+
+<p>
+ In your manifest add the {@link android.support.multidex.MultiDexApplication} class from the
+ multidex support library to the application element.
+</p>
+
+<pre>
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.android.multidex.myapplication">
+ <application
+ ...
+ android:name="android.support.multidex.MultiDexApplication">
+ ...
+ </application>
+</manifest>
+</pre>
+
+<p>
+ When these configuration settings are added to an app, the Android build tools construct a
+ primary dex (classes.dex) and supporting (classes2.dex, classes3.dex) as needed. The build system
+ will then package them into an APK file for distribution.
+</p>
+
+<p class="note">
+ <strong>Note:</strong> If your app uses extends the {@link android.app.Application} class, you
+ can override the attachBaseContext() method and call MultiDex.install(this) to enable multidex.
+ For more information, see the {@link android.support.multidex.MultiDexApplication} reference
+ documentation.
+</p>
+
+<h3 id="limitations">Limitations of the multidex support library</h3>
+
+<p>
+ The multidex support library has some known limitations that you should be aware of and test for
+ when you incorporate it into your app build configuration:
+</p>
+
+<ul>
+ <li>The installation of .dex files during startup onto a device's data partition is complex and
+ can result in Application Not Responding (ANR) errors if the secondary dex files are large. In
+ this case, you should apply code shrinking techniques with ProGuard to minimize the size of dex
+ files and remove unused portions of code.
+ </li>
+
+ <li>Applications that use multidex may not start on devices that run versions of the platform
+ earlier than Android 4.0 (API level 14) due to a Dalvik linearAlloc bug (Issue <a href=
+ "http://b.android.com/22586">22586</a>). If you are targeting API levels earlier than 14, make
+ sure to perform testing with these versions of the platform as your application can have issues
+ at startup or when particular groups of classes are loaded. Code shrinking can reduce or possibly
+ eliminate these potential issues.
+ </li>
+
+ <li>Applications using a multidex configuration that make very large memory allocation
+ requests may crash during run time due to a Dalvik linearAlloc limit (Issue <a href=
+ "http://b.android.com/78035">78035</a>). The allocation limit was increased in Android 4.0 (API
+ level 14), but apps may still run into this limit on Android versions prior to
+ Android 5.0 (API level 21).
+ </li>
+
+ <li>There are complex requirements regarding what classes are needed in the primary dex file when
+ executing in the Dalvik runtime. The Android build tooling updates handle the Android
+ requirements, but it is possible that other included libraries have additional dependency
+ requirements including the use of introspection or invocation of Java methods from native code.
+ Some libraries may not be able to be used until the multidex build tools are updated to allow you
+ to specify classes that must be included in the primary dex file.
+ </li>
+</ul>
+
+
+<h2 id="dev-build">Optimizing Multidex Development Builds</h2>
+
+<p>
+ A multidex configuration requires significantly increased build processing time because the build
+ system must make complex decisions about what classes must be included in the primary DEX file
+ and what classes can be included in secondary DEX files. This means that routine builds performed
+ as part of the development process with multidex typically take longer and can potentially slow
+ your development process.
+</p>
+
+<p>
+ In order to mitigate the typically longer build times for multidex output, you should create two
+ variations on your build output using the Android plugin for Gradle
+ <a href="http://tools.android.com/tech-docs/new-build-system/user-guide#TOC-Product-flavors">
+ {@code productFlavors}</a>: a development flavor and a production flavor.
+</p>
+
+<p>
+ For the development flavor, set a minimum SDK version of 21. This setting generates multidex
+ output much faster using the ART-supported format. For the release flavor, set a minimum SDK
+ version which matches your actual minimum support level. This setting generates a multidex APK
+ that is compatible with more devices, but takes longer to build.
+</p>
+
+<p>
+ The following build configuration sample demonstrates the how to set up these flavors in a Gradle
+ build file:
+</p>
+
+<pre>
+android {
+ productFlavors {
+ // Define separate dev and prod product flavors.
+ dev {
+ // dev utilizes minSDKVersion = 21 to allow the Android gradle plugin
+ // to pre-dex each module and produce an APK that can be tested on
+ // Android Lollipop without time consuming dex merging processes.
+ minSdkVersion 21
+ }
+ prod {
+ // The actual minSdkVersion for the application.
+ minSdkVersion 14
+ }
+ }
+ ...
+ buildTypes {
+ release {
+ runProguard true
+ proguardFiles getDefaultProguardFile('proguard-android.txt'),
+ 'proguard-rules.pro'
+ }
+ }
+}
+dependencies {
+ compile 'com.android.support:multidex:1.0.0'
+}
+</pre>
+
+<p>
+ After you have completed this configuration change, you can use the <code>devDebug</code> variant
+ of your app, which combines the attributes of the <code>dev</code> productFlavor and the
+ <code>debug</code> buildType. Using this target creates a debug app with proguard disabled,
+ multidex enabled, and minSdkVersion set to Android API level 21. These settings cause the Android
+ gradle plugin to do the following:
+</p>
+
+<ol>
+ <li>Build each module of the application (including dependencies) as separate dex files. This is
+ commonly referred to as pre-dexing.
+ </li>
+
+ <li>Include each dex file in the APK without modification.
+ </li>
+
+ <li>Most importantly, the module dex files will not be combined, and so the long-running
+ calculation to determine the contents of the primary dex file is avoided.
+ </li>
+</ol>
+
+<p>
+ These settings result in fast, incremental builds, because only the dex files of modified modules
+ are recomputed and repackaged into the APK file. The APK that results from these builds can be
+ used to test on Android 5.0 devices only. However, by implementing the configuration as a flavor,
+ you preserve the ability to perform normal builds with the release-appropriate minimum SDK level
+ and proguard settings.
+</p>
+
+<p>
+ You can also build the other variants, including a <code>prodDebug</code> variant
+ build, which takes longer to build, but can be used for testing outside of development.
+ Within the configuration shown, the <code>prodRelease</code> variant would be the final testing
+ and release version. If you are executing gradle tasks from the command line, you can use
+ standard commands with <code>DevDebug</code> appended to the end (such as <code>./gradlew
+ installDevDebug</code>). For more information about using flavors with Gradle tasks, see the
+ <a href="http://tools.android.com/tech-docs/new-build-system/user-guide">Gradle Plugin User
+ Guide</a>.
+</p>
+
+<p>
+ <strong>Tip:</strong> You can also provide a custom manifest, or a custom application class for each
+ flavor, allowing you to use the support library MultiDexApplication class, or calling
+ MultiDex.install() only for the variants that need it.
+</p>
+
+
+<h3 id="variants-studio">Using Build Variants in Android Studio</h3>
+
+<p>
+ Build variants can be very useful for managing the build process when using multidex. Android
+ Studio allows you to select these build variants in the user interface.
+</p>
+
+<p>
+ To have Android Studio build the "devDebug" variant of your app:
+</p>
+
+<ol>
+ <li>Open the <em>Build Variants</em> window from the left-sidebar. The option is located next to
+ <em>Favorites</em>.
+ </li>
+
+ <li>Click the name of the build variant to select a different variant, as shown in Figure 1.
+ </li>
+</ol>
+
+<img src="{@docRoot}images/tools/studio-build-variant.png" alt="" height="XXX" id="figure1">
+<p class="img-caption">
+ <strong>Figure 1.</strong> Screen shot of the Android Studio left panel showing a build variant.
+</p>
+
+<p class="note">
+ <strong>Note</strong>: The option to open this window is only available after you have
+ successfully synchronized Android Studio with your Gradle build file using the <strong>Tools >
+ Android > Sync Project with Gradle Files</strong> command.
+</p>
+
+
+<h2 id="testing">Testing Multidex Apps</h2>
+
+<p>
+ Testing apps that use multidex configuration require some additional steps and configuration.
+ Since the location of code for classes is not within a single DEX file, instrumentation tests do
+ not run properly unless configured for multidex.
+</p>
+
+<p>
+ When testing a multidex app with instrumentation tests, use
+ <a href="{@docRoot}reference/com/android/test/runner/MultiDexTestRunner.html">
+ MultiDexTestRunner</a> from the multidex testing support library. The following sample
+ {@code build.gradle} file, demonstrates how to configure your build to use this test runner:
+</p>
+
+<pre>
+android {
+ defaultConfig {
+ ...
+ testInstrumentationRunner "android.support.multidex.MultiDexTestRunner"
+ }
+}
+
+dependencies {
+ androidTestCompile 'com.android.support:multidex-instrumentation:1.0.0'
+}
+</pre>
+
+<p>
+ You may use the instrumentation test runner class directly or extend it to fit your testing
+ needs. Alternatively, you can override onCreate in existing instrumentations like this:
+</p>
+
+<pre>
+public void onCreate(Bundle arguments) {
+ MultiDex.install(getTargetContext());
+ super.onCreate(arguments);
+ ...
+}
+</pre>
+
+<p class="note">
+ <strong>Note:</strong> Use of multidex for creating a test APK is not currently supported.
+</p>
\ No newline at end of file
diff --git a/docs/html/tools/devices/emulator.jd b/docs/html/tools/devices/emulator.jd
index ea1549d..d7bb8c7 100644
--- a/docs/html/tools/devices/emulator.jd
+++ b/docs/html/tools/devices/emulator.jd
@@ -80,7 +80,9 @@
provides a screen in which your application is displayed, together with any other
active Android applications. </p>
-<img src="{@docRoot}images/emulator-wvga800l.png" width="367" height="349" />
+<img src="{@docRoot}images/emulator@2x.png"
+srcset="{@docRoot}images/emulator.png 1x, {@docRoot}images/emulator@2x.png 2x" alt=""
+ width="367" height="330"/>
<p>To let you model and test your application more easily, the emulator utilizes
Android Virtual Device (AVD) configurations. AVDs let you define certain hardware
diff --git a/docs/html/tools/revisions/build-tools.jd b/docs/html/tools/revisions/build-tools.jd
index 6f07755..ec88efc 100644
--- a/docs/html/tools/revisions/build-tools.jd
+++ b/docs/html/tools/revisions/build-tools.jd
@@ -77,6 +77,18 @@
<div class="toggle-content opened">
<p><a href="#" onclick="return toggleContent(this)">
<img src="{@docRoot}assets/images/triangle-opened.png" class="toggle-content-img"
+ alt=""/>Build Tools, Revision 21.1</a> <em>(October 2014)</em>
+ </p>
+ <div class="toggle-content-toggleme">
+ <p>Added multidex file support for APKs and Jack suppport to address the 64K method reference
+ limit.</p>
+ </div>
+</div>
+
+
+<div class="toggle-content closed">
+ <p><a href="#" onclick="return toggleContent(this)">
+ <img src="{@docRoot}assets/images/triangle-closed.png" class="toggle-content-img"
alt=""/>Build Tools, Revision 21.0.2</a> <em>(October 2014)</em>
</p>
<div class="toggle-content-toggleme">
diff --git a/docs/html/tools/revisions/platforms.jd b/docs/html/tools/revisions/platforms.jd
index 85b9c5e..ef8575a 100644
--- a/docs/html/tools/revisions/platforms.jd
+++ b/docs/html/tools/revisions/platforms.jd
@@ -88,7 +88,7 @@
<div class="toggle-content-toggleme">
- <p>Added location APIs support for Wear.</p>
+ <p>Updated the rendering library. </p>
<p>Dependencies:</p>
<ul>
diff --git a/docs/html/tools/support-library/features.jd b/docs/html/tools/support-library/features.jd
index 44c5045..3ebfc89 100644
--- a/docs/html/tools/support-library/features.jd
+++ b/docs/html/tools/support-library/features.jd
@@ -8,6 +8,7 @@
<h2>In this document</h2>
<ol>
<li><a href="#v4">v4 Support Library</a></li>
+ <li><a href="#multidex">Multidex Support Library</a></li>
<li><a href="#v7">v7 Support Libraries</a>
<ol>
<li><a href="#v7-appcompat">v7 appcompat library</a></li>
@@ -145,6 +146,34 @@
<p>This dependency notation specifies the release version 21.0.0 or higher.</p>
+<h2 id="multidex">Multidex Support Library</h2>
+
+<p>
+ This library provides support for building apps with multiple Dalvik Executable (DEX) files.
+ Apps that reference more than 65536 methods are required to use multidex configurations. For
+ more information about using multidex, see <a href="{@docRoot}tools/building/multidex.html">
+ Building Apps with Over 65K Methods</a>.
+</p>
+
+<p>
+ This library is located in the {@code <sdk>/extras/android/support/multidex/} directory
+ after you download the Android Support Libraries. The library does not contain user interface
+ resources. To include it in your application project, follow the instructions for <a href=
+ "{@docRoot}tools/support-library/setup.html#libs-without-res">Adding libraries without
+ resources</a>.
+</p>
+
+<p>
+ The Gradle build script dependency identifier for this library is as follows:
+</p>
+
+<pre>
+com.android.support:multidex:1.0.+
+</pre>
+
+<p>This dependency notation specifies the release version 1.0.0 or higher.</p>
+
+
<h2 id="v7">v7 Support Libraries</h2>
<p>There are several libraries designed to be used with Android 2.1 (API level 7) and higher.
diff --git a/docs/html/tools/testing/activity_testing.jd b/docs/html/tools/testing/activity_testing.jd
index 88ac9b2..8baa35d 100644
--- a/docs/html/tools/testing/activity_testing.jd
+++ b/docs/html/tools/testing/activity_testing.jd
@@ -242,7 +242,7 @@
This changes when you run tests against the application. With instrumentation-based classes,
you can invoke methods against the UI of the application under test. The other test classes
don't allow this. To run an entire test method on the UI thread, you can annotate the thread
- with <code>@UIThreadTest</code>. Notice that this will run <em>all</em> of the method statements
+ with <code>@UiThreadTest</code>. Notice that this will run <em>all</em> of the method statements
on the UI thread. Methods that do not interact with the UI are not allowed; for example, you
can't invoke <code>Instrumentation.waitForIdleSync()</code>.
</p>
diff --git a/docs/html/tools/tools_toc.cs b/docs/html/tools/tools_toc.cs
index 8eb9cbf..ac33185 100644
--- a/docs/html/tools/tools_toc.cs
+++ b/docs/html/tools/tools_toc.cs
@@ -66,10 +66,17 @@
<li class="nav-section">
- <div class="nav-section-header"><a href="<?cs var:toroot ?>tools/building/index.html"><span class="en">Building and Running</span></a></div>
+ <div class="nav-section-header">
+ <a href="<?cs var:toroot ?>tools/building/index.html">
+ <span class="en">Building and Running</span></a>
+ </div>
<ul>
- <li><a href="<?cs var:toroot ?>tools/building/building-eclipse.html"><span class="en">From Eclipse with ADT</span></a></li>
- <li><a href="<?cs var:toroot ?>tools/building/building-cmdline.html"><span class="en">From the Command Line</span></a></li>
+ <li><a href="<?cs var:toroot ?>tools/building/building-eclipse.html">
+ <span class="en">From Eclipse with ADT</span></a></li>
+ <li><a href="<?cs var:toroot ?>tools/building/building-cmdline.html">
+ <span class="en">From the Command Line</span></a></li>
+ <li><a href="<?cs var:toroot ?>tools/building/multidex.html">
+ <span class="en">Apps Over 65K Methods</span></a></li>
</ul>
</li>
diff --git a/docs/html/training/basics/firstapp/building-ui.jd b/docs/html/training/basics/firstapp/building-ui.jd
index c082642..0430cdd 100644
--- a/docs/html/training/basics/firstapp/building-ui.jd
+++ b/docs/html/training/basics/firstapp/building-ui.jd
@@ -1,7 +1,7 @@
page.title=Building a Simple User Interface
trainingnavtop=true
-page.tags=ui, views, layouts, widgets, string resources
+page.tags=ui
helpoutsWidget=true
@jd:body
diff --git a/docs/html/training/basics/firstapp/creating-project.jd b/docs/html/training/basics/firstapp/creating-project.jd
index 418eb68..2e06103 100644
--- a/docs/html/training/basics/firstapp/creating-project.jd
+++ b/docs/html/training/basics/firstapp/creating-project.jd
@@ -1,6 +1,6 @@
page.title=Creating an Android Project
-page.tags=eclipse adt, sdk tools, project setup
+page.tags=project setup
helpoutsWidget=true
trainingnavtop=true
diff --git a/docs/html/training/basics/firstapp/starting-activity.jd b/docs/html/training/basics/firstapp/starting-activity.jd
index f9dcba4..71f66dd 100644
--- a/docs/html/training/basics/firstapp/starting-activity.jd
+++ b/docs/html/training/basics/firstapp/starting-activity.jd
@@ -4,7 +4,7 @@
trainingnavtop=true
-page.tags=input events, intents, activity lifecycle
+page.tags=intents
helpoutsWidget=true
@jd:body
diff --git a/docs/html/training/material/animations.jd b/docs/html/training/material/animations.jd
index e8291b8..efc0ee3 100644
--- a/docs/html/training/material/animations.jd
+++ b/docs/html/training/material/animations.jd
@@ -84,12 +84,14 @@
int cy = (myView.getTop() + myView.getBottom()) / 2;
// get the final radius for the clipping circle
-int finalRadius = myView.getWidth();
+int finalRadius = Math.max(myView.getWidth(), myView.getHeight());
-// create and start the animator for this view
-// (the start radius is zero)
+// create the animator for this view (the start radius is zero)
Animator anim =
ViewAnimationUtils.createCircularReveal(myView, cx, cy, 0, finalRadius);
+
+// make the view visible and start the animation
+myView.setVisibility(View.VISIBLE);
anim.start();
</pre>
diff --git a/docs/html/training/tv/discovery/index.jd b/docs/html/training/tv/discovery/index.jd
index fbc8c9f..5849149 100644
--- a/docs/html/training/tv/discovery/index.jd
+++ b/docs/html/training/tv/discovery/index.jd
@@ -1,4 +1,5 @@
-page.title=Helping Users Find Content on TV
+page.title=Helping Users Find Your Content on TV
+page.tags="tv", "leanback"
startpage=true
diff --git a/docs/html/training/tv/games/index.jd b/docs/html/training/tv/games/index.jd
index 2f510a9..5276d7f 100644
--- a/docs/html/training/tv/games/index.jd
+++ b/docs/html/training/tv/games/index.jd
@@ -1,5 +1,7 @@
page.title=Building TV Games
-page.tags="controller"
+page.tags="tv", "games", "controller"
+page.image=images/games/game-controller-buttons_2x_crop.png
+page.metaDescription=How to bring your games to Android TV, including recommendations and examples.
page.article=true
@jd:body
@@ -180,7 +182,7 @@
It includes a white controller on black background and a black controller on white background
(shown in figure 1), as a PNG file and an Adobe® Illustrator® file.</p>
-<img src="{@docRoot}images/games/game-controller-buttons_2x.png" width="700"
+<img itemprop="image" src="{@docRoot}images/games/game-controller-buttons_2x.png" width="700"
srcset="{@docRoot}images/games/game-controller-buttons_2x.png 2x,
{@docRoot}images/games/game-controller-buttons.png 1x" />
<p class="img-caption"><b>Figure 1.</b> Example controller instructions using the
@@ -194,22 +196,22 @@
<p>There are a some special things games should include in the Android manifest.</p>
-<h3 id="Launcher">Show your game in the launcher</h3>
+<h3 id="Launcher">Show your game on the home screen</h3>
<p>
- The Android TV launcher home screen displays games in a separate row from regular apps.
- To make your game appear in the list of games, add the
- <a href="{@docRoot}guide/topics/manifest/meta-data-element.html"
- ><code><meta-data></code></a> tag in your app manifest with <code>android:name</code>
- set to <code>"isGame"</code> and <code>android:value</code>
- set to <code>"true"</code>. For example:
+ The Android TV home screen displays games in a separate row from regular apps.
+ To make your game appear in the list of games, set the
+ <a href="{@docRoot}guide/topics/manifest/application-element.html#isGame">
+ {@code android:isGame}</a> attribute to <code>"true"</code> in your app manifest's
+ <a href="{@docRoot}guide/topics/manifest/application-element.html"><code><application></code>
+ </a> tag. For example:
</p>
<pre class="fragment">
-<application>
- ...
- <meta-data android:name="isGame" android:value="true" >
- ...
-</application>
+<application
+ ...
+ android:isGame="true"
+ ...
+>
</pre>
diff --git a/docs/html/training/tv/index.jd b/docs/html/training/tv/index.jd
index 56667a9..d52e1e8 100644
--- a/docs/html/training/tv/index.jd
+++ b/docs/html/training/tv/index.jd
@@ -1,8 +1,11 @@
page.title=Building Apps for TV
page.trainingcourse=true
-
+page.metaDescription=Starting point for building apps and games for Android TV, with guidelines, information, and examples.
+page.image=design/tv/images/focus.png
@jd:body
-<p>These classes teach you how to build apps for TV devices.</p>
\ No newline at end of file
+<p>These classes teach you how to build apps for TV devices.</p>
+
+<p class="note"><strong>Note:</strong> For details on how to publish your TV apps in Google Play, see <a href="{docRoot}distribute/googleplay/tv.html">Distributing to Android TV</a>.</p>
\ No newline at end of file
diff --git a/docs/html/training/tv/playback/index.jd b/docs/html/training/tv/playback/index.jd
index 118fc6c..09c3f24 100644
--- a/docs/html/training/tv/playback/index.jd
+++ b/docs/html/training/tv/playback/index.jd
@@ -1,5 +1,5 @@
page.title=Building TV Playback Apps
-page.tags="leanback"
+page.tags="tv","leanback"
startpage=true
diff --git a/docs/html/training/tv/start/index.jd b/docs/html/training/tv/start/index.jd
index ceefea1..fb478a8 100644
--- a/docs/html/training/tv/start/index.jd
+++ b/docs/html/training/tv/start/index.jd
@@ -1,4 +1,5 @@
page.title=Building TV Apps
+page.tags="tv", "leanback"
startpage=true
@jd:body
diff --git a/docs/html/training/tv/start/start.jd b/docs/html/training/tv/start/start.jd
index bebeedd..3b26abf 100644
--- a/docs/html/training/tv/start/start.jd
+++ b/docs/html/training/tv/start/start.jd
@@ -100,7 +100,8 @@
<p>The following code snippet shows how to include this intent filter in your manifest:</p>
<pre>
-<application>
+<application
+ android:banner="@drawable/banner" >
...
<activity
android:name="com.example.android.MainActivity"
@@ -141,6 +142,34 @@
"{@docRoot}training/tv/start/layouts.html">Building TV Layouts</a>.
</p>
+<h3 id="banner">Provide a home screen banner</h3>
+
+<p>
+ An application must provide a home screen banner if it includes a Leanback launcher intent
+ filter. The banner is the app launch point that appears on the home screen in the apps and
+ games rows. Desribe the banner in the manifest as follows:
+</p>
+
+<pre>
+<application
+ . . .
+ android:banner="@drawable/banner" >
+ . . .
+</application>
+</pre>
+
+<p>
+ Use the <a href="{@docRoot}guide/topics/manifest/application-element.html#banner">{@code android:banner}</a>
+ attribute with the <a href="{@docRoot}guide/topics/manifest/application.html"><code><application></code></a>
+ tag to supply a default banner for all application activities, or with the
+ <a href="{@docRoot}guide/topics/manifest/activity-element.html"><code><activity></code></a>
+ tag to supply a banner for a specific activity.
+</p>
+
+<p>
+ See <a href="{@docRoot}design/tv/patterns.html#banner">Banners</a> in the UI Patterns for TV
+ design guide.
+</p>
<h3 id="tv-libraries">Add TV support libraries</h3>
diff --git a/docs/html/training/tv/tif/index.jd b/docs/html/training/tv/tif/index.jd
index 4746e42..cde8ba7 100644
--- a/docs/html/training/tv/tif/index.jd
+++ b/docs/html/training/tv/tif/index.jd
@@ -1,5 +1,5 @@
page.title=Building Live TV Apps
-page.tags=tif
+page.tags="tv", "tif"
page.article=true
@jd:body
diff --git a/docs/html/training/wearables/apps/bt-debugging.jd b/docs/html/training/wearables/apps/bt-debugging.jd
index 8d09c43..98cf804 100644
--- a/docs/html/training/wearables/apps/bt-debugging.jd
+++ b/docs/html/training/wearables/apps/bt-debugging.jd
@@ -58,7 +58,8 @@
</li>
<li>Connect the handheld to your machine over USB and run:
<pre>
-adb forward tcp:4444 localabstract:/adb-hub; adb connect localhost:4444
+adb forward tcp:4444 localabstract:/adb-hub
+adb connect localhost:4444
</pre>
<p class="note"><b>Note</b>: You can use any available port that you have access to.</p>
diff --git a/docs/html/training/wearables/apps/layouts.jd b/docs/html/training/wearables/apps/layouts.jd
index e62d3e5..a35acb0 100644
--- a/docs/html/training/wearables/apps/layouts.jd
+++ b/docs/html/training/wearables/apps/layouts.jd
@@ -90,9 +90,10 @@
</ol>
<h2 id="UiLibrary">Create Layouts with the Wearable UI Library</h2>
<p>
-There's an unofficial UI library that is automatically included when you create your wearable
-app with the Android Studio Project Wizard. You can also add the library to your <code>build.gradle</code>
+The Wearable UI Library is automatically included when you create your wearable
+app with the Android Studio Project Wizard. You can also add this library to your <code>build.gradle</code>
file with the following dependency declaration:
+</p>
<pre>
dependencies {
@@ -101,8 +102,11 @@
compile 'com.google.android.gms:play-services-wearable:+'
}
</pre>
-This library helps you build UIs that are designed for wearables. Here are some of the major classes:
-</p>
+
+<p>This library helps you build UIs that are designed for wearables. For more information, see
+<a href="{@docRoot}training/wearables/ui/index.html">Creating Custom UIs for Wear Devices</a>.</p>
+
+<p>Here are some of the major classes in the Wearable UI Library:</p>
<ul>
<li><code>BoxInsetLayout</code> - A FrameLayout that's aware of screen shape and can box its
diff --git a/docs/html/training/wearables/data-layer/accessing.jd b/docs/html/training/wearables/data-layer/accessing.jd
index 896a698..36e3daa 100644
--- a/docs/html/training/wearables/data-layer/accessing.jd
+++ b/docs/html/training/wearables/data-layer/accessing.jd
@@ -37,7 +37,7 @@
implementing its callbacks, and handling error cases.</p>
<pre style="clear:right">
-GoogleApiClient mGoogleAppiClient = new GoogleApiClient.Builder(this)
+GoogleApiClient mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(new ConnectionCallbacks() {
@Override
public void onConnected(Bundle connectionHint) {
@@ -64,4 +64,4 @@
method, as described in
<a href="{@docRoot}google/auth/api-client.html#Starting">Accessing Google Play services APIs</a>.
When the system invokes the <code>onConnected()</code> callback for your client, you're ready
-to use the data layer API.</p>
\ No newline at end of file
+to use the data layer API.</p>
diff --git a/docs/html/training/wearables/data-layer/index.jd b/docs/html/training/wearables/data-layer/index.jd
index 39d6561..6ef3fc7 100644
--- a/docs/html/training/wearables/data-layer/index.jd
+++ b/docs/html/training/wearables/data-layer/index.jd
@@ -8,7 +8,7 @@
<h2>Dependencies and prerequisites</h2>
<ul>
<li>Android 4.3 (API Level 18) or higher on the handset device</li>
- <li>The latest version of <a href="{@docRoot}google/play">Google Play services</a></li>
+ <li>The latest version of <a href="{@docRoot}google/play-services/index.html">Google Play services</a></li>
<li>An Android Wear device or Wear AVD</li>
</ul>
</div>
diff --git a/docs/html/training/wearables/notifications/pages.jd b/docs/html/training/wearables/notifications/pages.jd
index d74c8ea..6315037 100644
--- a/docs/html/training/wearables/notifications/pages.jd
+++ b/docs/html/training/wearables/notifications/pages.jd
@@ -57,15 +57,14 @@
.setStyle(secondPageStyle)
.build();
-// Add second page with wearable extender and extend the main notification
-Notification twoPageNotification =
- new WearableExtender()
- .addPage(secondPageNotification)
- .extend(notificationBuilder)
- .build();
+// Extend the notification builder with the second page
+Notification notification = notificationBuilder
+ .extend(new NotificationCompat.WearableExtender()
+ .addPage(secondPageNotification))
+ .build();
// Issue the notification
notificationManager =
NotificationManagerCompat.from(this);
-notificationManager.notify(notificationId, twoPageNotification);
+notificationManager.notify(notificationId, notification);
</pre>
\ No newline at end of file
diff --git a/docs/html/training/wearables/notifications/voice-input.jd b/docs/html/training/wearables/notifications/voice-input.jd
index 4a27826..3ce1c80 100644
--- a/docs/html/training/wearables/notifications/voice-input.jd
+++ b/docs/html/training/wearables/notifications/voice-input.jd
@@ -37,7 +37,7 @@
<h2 id="VoiceInput">Define the Voice Input</h2>
-<p>To create an action that supports voice input, create an instance of
+<p>To create an action that supports voice input, create an instance of
{@link android.support.v4.app.RemoteInput.Builder} that you can add to your notification action.
This class's constructor accepts a string that the system uses as
the key for the voice input, which you'll later use to retrieve the text of the
@@ -166,9 +166,8 @@
private CharSequence getMessageText(Intent intent) {
Bundle remoteInput = RemoteInput.getResultsFromIntent(intent);
- if (remoteInput != null) {
- return remoteInput.getCharSequence(EXTRA_VOICE_REPLY);
- }
+ if (remoteInput != null) {
+ return remoteInput.getCharSequence(EXTRA_VOICE_REPLY);
}
return null;
}
diff --git a/docs/html/tv/index.jd b/docs/html/tv/index.jd
index 71e177b..e4d7f7a 100644
--- a/docs/html/tv/index.jd
+++ b/docs/html/tv/index.jd
@@ -1,5 +1,9 @@
-page.title=Android TV
+page.title=About Android TV
+page.type=about
+page.image=tv/images/hero.jpg
page.viewport_width=970
+page.tags="tv", "leanback"
+page.metaDescription=Bring your apps, games, and content to the biggest screen in the house.
fullpage=true
no_footer_links=true
page.type=about
diff --git a/graphics/java/android/graphics/drawable/AnimatedStateListDrawable.java b/graphics/java/android/graphics/drawable/AnimatedStateListDrawable.java
index 3b125fd..5a3a617 100644
--- a/graphics/java/android/graphics/drawable/AnimatedStateListDrawable.java
+++ b/graphics/java/android/graphics/drawable/AnimatedStateListDrawable.java
@@ -361,7 +361,7 @@
super.applyTheme(theme);
final AnimatedStateListState state = mState;
- if (state == null || !state.canApplyTheme()) {
+ if (state == null || state.mAnimThemeAttrs == null) {
return;
}
diff --git a/graphics/java/android/graphics/drawable/ClipDrawable.java b/graphics/java/android/graphics/drawable/ClipDrawable.java
index f80a5f4..e5b2b76 100644
--- a/graphics/java/android/graphics/drawable/ClipDrawable.java
+++ b/graphics/java/android/graphics/drawable/ClipDrawable.java
@@ -148,7 +148,7 @@
super.applyTheme(t);
final ClipState state = mState;
- if (state == null) {
+ if (state == null || state.mThemeAttrs == null) {
return;
}
diff --git a/graphics/java/android/graphics/drawable/GradientDrawable.java b/graphics/java/android/graphics/drawable/GradientDrawable.java
index 1458238..94c7026 100644
--- a/graphics/java/android/graphics/drawable/GradientDrawable.java
+++ b/graphics/java/android/graphics/drawable/GradientDrawable.java
@@ -943,7 +943,11 @@
float radius = st.mGradientRadius;
if (st.mGradientRadiusType == RADIUS_TYPE_FRACTION) {
- radius *= Math.min(st.mWidth, st.mHeight);
+ // Fall back to parent width or height if intrinsic
+ // size is not specified.
+ final float width = st.mWidth >= 0 ? st.mWidth : r.width();
+ final float height = st.mHeight >= 0 ? st.mHeight : r.height();
+ radius *= Math.min(width, height);
} else if (st.mGradientRadiusType == RADIUS_TYPE_FRACTION_PARENT) {
radius *= Math.min(r.width(), r.height());
}
@@ -954,9 +958,9 @@
mGradientRadius = radius;
- if (radius == 0) {
- // We can't have a shader with zero radius, so let's
- // have a very, very small radius.
+ if (radius <= 0) {
+ // We can't have a shader with non-positive radius, so
+ // let's have a very, very small radius.
radius = 0.001f;
}
diff --git a/graphics/java/android/graphics/drawable/RotateDrawable.java b/graphics/java/android/graphics/drawable/RotateDrawable.java
index 9208a0a..3304b33 100644
--- a/graphics/java/android/graphics/drawable/RotateDrawable.java
+++ b/graphics/java/android/graphics/drawable/RotateDrawable.java
@@ -427,19 +427,22 @@
return;
}
- final TypedArray a = t.resolveAttributes(state.mThemeAttrs, R.styleable.RotateDrawable);
- try {
- updateStateFromTypedArray(a);
- verifyRequiredAttributes(a);
- } catch (XmlPullParserException e) {
- throw new RuntimeException(e);
- } finally {
- a.recycle();
+ if (state.mThemeAttrs != null) {
+ final TypedArray a = t.resolveAttributes(state.mThemeAttrs, R.styleable.RotateDrawable);
+ try {
+ updateStateFromTypedArray(a);
+ verifyRequiredAttributes(a);
+ } catch (XmlPullParserException e) {
+ throw new RuntimeException(e);
+ } finally {
+ a.recycle();
+ }
}
if (state.mDrawable != null && state.mDrawable.canApplyTheme()) {
state.mDrawable.applyTheme(t);
}
+
}
private void inflateChildElements(Resources r, XmlPullParser parser, AttributeSet attrs,
diff --git a/graphics/java/android/graphics/drawable/ScaleDrawable.java b/graphics/java/android/graphics/drawable/ScaleDrawable.java
index fbe38b4..35ef76f 100644
--- a/graphics/java/android/graphics/drawable/ScaleDrawable.java
+++ b/graphics/java/android/graphics/drawable/ScaleDrawable.java
@@ -114,7 +114,7 @@
return;
}
- if (state.mThemeAttrs == null) {
+ if (state.mThemeAttrs != null) {
final TypedArray a = t.resolveAttributes(state.mThemeAttrs, R.styleable.ScaleDrawable);
try {
updateStateFromTypedArray(a);
diff --git a/graphics/java/android/graphics/pdf/PdfEditor.java b/graphics/java/android/graphics/pdf/PdfEditor.java
index 9837139..2b70b6a 100644
--- a/graphics/java/android/graphics/pdf/PdfEditor.java
+++ b/graphics/java/android/graphics/pdf/PdfEditor.java
@@ -17,6 +17,10 @@
package android.graphics.pdf;
import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.graphics.Matrix;
+import android.graphics.Point;
+import android.graphics.Rect;
import android.os.ParcelFileDescriptor;
import android.system.ErrnoException;
import android.system.OsConstants;
@@ -55,6 +59,10 @@
*
* @param input Seekable file descriptor to read from.
*
+ * @throws java.io.IOException If an error occurs while reading the file.
+ * @throws java.lang.SecurityException If the file requires a password or
+ * the security scheme is not supported.
+ *
* @see #close()
*/
public PdfEditor(@NonNull ParcelFileDescriptor input) throws IOException {
@@ -98,6 +106,109 @@
}
/**
+ * Sets a transformation and clip for a given page. The transformation matrix if
+ * non-null must be affine as per {@link android.graphics.Matrix#isAffine()}. If
+ * the clip is null, then no clipping is performed.
+ *
+ * @param pageIndex The page whose transform to set.
+ * @param transform The transformation to apply.
+ * @param clip The clip to apply.
+ */
+ public void setTransformAndClip(int pageIndex, @Nullable Matrix transform,
+ @Nullable Rect clip) {
+ throwIfClosed();
+ throwIfPageNotInDocument(pageIndex);
+ throwIfNotNullAndNotAfine(transform);
+ if (transform == null) {
+ transform = Matrix.IDENTITY_MATRIX;
+ }
+ if (clip == null) {
+ Point size = new Point();
+ getPageSize(pageIndex, size);
+ nativeSetTransformAndClip(mNativeDocument, pageIndex, transform.native_instance,
+ 0, 0, size.x, size.y);
+ } else {
+ nativeSetTransformAndClip(mNativeDocument, pageIndex, transform.native_instance,
+ clip.left, clip.top, clip.right, clip.bottom);
+ }
+ }
+
+ /**
+ * Gets the size of a given page in mils (1/72").
+ *
+ * @param pageIndex The page index.
+ * @param outSize The size output.
+ */
+ public void getPageSize(int pageIndex, @NonNull Point outSize) {
+ throwIfClosed();
+ throwIfOutSizeNull(outSize);
+ throwIfPageNotInDocument(pageIndex);
+ nativeGetPageSize(mNativeDocument, pageIndex, outSize);
+ }
+
+ /**
+ * Gets the media box of a given page in mils (1/72").
+ *
+ * @param pageIndex The page index.
+ * @param outMediaBox The media box output.
+ */
+ public boolean getPageMediaBox(int pageIndex, @NonNull Rect outMediaBox) {
+ throwIfClosed();
+ throwIfOutMediaBoxNull(outMediaBox);
+ throwIfPageNotInDocument(pageIndex);
+ return nativeGetPageMediaBox(mNativeDocument, pageIndex, outMediaBox);
+ }
+
+ /**
+ * Sets the media box of a given page in mils (1/72").
+ *
+ * @param pageIndex The page index.
+ * @param mediaBox The media box.
+ */
+ public void setPageMediaBox(int pageIndex, @NonNull Rect mediaBox) {
+ throwIfClosed();
+ throwIfMediaBoxNull(mediaBox);
+ throwIfPageNotInDocument(pageIndex);
+ nativeSetPageMediaBox(mNativeDocument, pageIndex, mediaBox);
+ }
+
+ /**
+ * Gets the crop box of a given page in mils (1/72").
+ *
+ * @param pageIndex The page index.
+ * @param outCropBox The crop box output.
+ */
+ public boolean getPageCropBox(int pageIndex, @NonNull Rect outCropBox) {
+ throwIfClosed();
+ throwIfOutCropBoxNull(outCropBox);
+ throwIfPageNotInDocument(pageIndex);
+ return nativeGetPageCropBox(mNativeDocument, pageIndex, outCropBox);
+ }
+
+ /**
+ * Sets the crop box of a given page in mils (1/72").
+ *
+ * @param pageIndex The page index.
+ * @param cropBox The crop box.
+ */
+ public void setPageCropBox(int pageIndex, @NonNull Rect cropBox) {
+ throwIfClosed();
+ throwIfCropBoxNull(cropBox);
+ throwIfPageNotInDocument(pageIndex);
+ nativeSetPageCropBox(mNativeDocument, pageIndex, cropBox);
+ }
+
+ /**
+ * Gets whether the document prefers to be scaled for printing.
+ *
+ * @return Whether to scale the document.
+ */
+ public boolean shouldScaleForPrinting() {
+ throwIfClosed();
+ return nativeScaleForPrinting(mNativeDocument);
+ }
+
+ /**
* Writes the PDF file to the provided destination.
* <p>
* <strong>Note:</strong> This method takes ownership of the passed in file
@@ -154,9 +265,57 @@
}
}
+ private void throwIfNotNullAndNotAfine(Matrix matrix) {
+ if (matrix != null && !matrix.isAffine()) {
+ throw new IllegalStateException("Matrix must be afine");
+ }
+ }
+
+ private void throwIfOutSizeNull(Point outSize) {
+ if (outSize == null) {
+ throw new NullPointerException("outSize cannot be null");
+ }
+ }
+
+ private void throwIfOutMediaBoxNull(Rect outMediaBox) {
+ if (outMediaBox == null) {
+ throw new NullPointerException("outMediaBox cannot be null");
+ }
+ }
+
+ private void throwIfMediaBoxNull(Rect mediaBox) {
+ if (mediaBox == null) {
+ throw new NullPointerException("mediaBox cannot be null");
+ }
+ }
+
+ private void throwIfOutCropBoxNull(Rect outCropBox) {
+ if (outCropBox == null) {
+ throw new NullPointerException("outCropBox cannot be null");
+ }
+ }
+
+ private void throwIfCropBoxNull(Rect cropBox) {
+ if (cropBox == null) {
+ throw new NullPointerException("cropBox cannot be null");
+ }
+ }
+
private static native long nativeOpen(int fd, long size);
private static native void nativeClose(long documentPtr);
private static native int nativeGetPageCount(long documentPtr);
private static native int nativeRemovePage(long documentPtr, int pageIndex);
private static native void nativeWrite(long documentPtr, int fd);
+ private static native void nativeSetTransformAndClip(long documentPtr, int pageIndex,
+ long transformPtr, int clipLeft, int clipTop, int clipRight, int clipBottom);
+ private static native void nativeGetPageSize(long documentPtr, int pageIndex, Point outSize);
+ private static native boolean nativeGetPageMediaBox(long documentPtr, int pageIndex,
+ Rect outMediaBox);
+ private static native void nativeSetPageMediaBox(long documentPtr, int pageIndex,
+ Rect mediaBox);
+ private static native boolean nativeGetPageCropBox(long documentPtr, int pageIndex,
+ Rect outMediaBox);
+ private static native void nativeSetPageCropBox(long documentPtr, int pageIndex,
+ Rect mediaBox);
+ private static native boolean nativeScaleForPrinting(long documentPtr);
}
diff --git a/graphics/java/android/graphics/pdf/PdfRenderer.java b/graphics/java/android/graphics/pdf/PdfRenderer.java
index 359c294..79934da 100644
--- a/graphics/java/android/graphics/pdf/PdfRenderer.java
+++ b/graphics/java/android/graphics/pdf/PdfRenderer.java
@@ -131,6 +131,10 @@
* </p>
*
* @param input Seekable file descriptor to read from.
+ *
+ * @throws java.io.IOException If an error occurs while reading the file.
+ * @throws java.lang.SecurityException If the file requires a password or
+ * the security scheme is not supported.
*/
public PdfRenderer(@NonNull ParcelFileDescriptor input) throws IOException {
if (input == null) {
diff --git a/include/androidfw/ResourceTypes.h b/include/androidfw/ResourceTypes.h
index 85e442da..6b84494 100644
--- a/include/androidfw/ResourceTypes.h
+++ b/include/androidfw/ResourceTypes.h
@@ -36,6 +36,17 @@
namespace android {
+/**
+ * In C++11, char16_t is defined as *at least* 16 bits. We do a lot of
+ * casting on raw data and expect char16_t to be exactly 16 bits.
+ */
+#if __cplusplus >= 201103L
+struct __assertChar16Size {
+ static_assert(sizeof(char16_t) == sizeof(uint16_t), "char16_t is not 16 bits");
+ static_assert(alignof(char16_t) == alignof(uint16_t), "char16_t is not 16-bit aligned");
+};
+#endif
+
/** ********************************************************************
* PNG Extensions
*
@@ -702,25 +713,25 @@
// These are available for all nodes:
int32_t getCommentID() const;
- const uint16_t* getComment(size_t* outLen) const;
+ const char16_t* getComment(size_t* outLen) const;
uint32_t getLineNumber() const;
// This is available for TEXT:
int32_t getTextID() const;
- const uint16_t* getText(size_t* outLen) const;
+ const char16_t* getText(size_t* outLen) const;
ssize_t getTextValue(Res_value* outValue) const;
// These are available for START_NAMESPACE and END_NAMESPACE:
int32_t getNamespacePrefixID() const;
- const uint16_t* getNamespacePrefix(size_t* outLen) const;
+ const char16_t* getNamespacePrefix(size_t* outLen) const;
int32_t getNamespaceUriID() const;
- const uint16_t* getNamespaceUri(size_t* outLen) const;
+ const char16_t* getNamespaceUri(size_t* outLen) const;
// These are available for START_TAG and END_TAG:
int32_t getElementNamespaceID() const;
- const uint16_t* getElementNamespace(size_t* outLen) const;
+ const char16_t* getElementNamespace(size_t* outLen) const;
int32_t getElementNameID() const;
- const uint16_t* getElementName(size_t* outLen) const;
+ const char16_t* getElementName(size_t* outLen) const;
// Remaining methods are for retrieving information about attributes
// associated with a START_TAG:
@@ -729,10 +740,10 @@
// Returns -1 if no namespace, -2 if idx out of range.
int32_t getAttributeNamespaceID(size_t idx) const;
- const uint16_t* getAttributeNamespace(size_t idx, size_t* outLen) const;
+ const char16_t* getAttributeNamespace(size_t idx, size_t* outLen) const;
int32_t getAttributeNameID(size_t idx) const;
- const uint16_t* getAttributeName(size_t idx, size_t* outLen) const;
+ const char16_t* getAttributeName(size_t idx, size_t* outLen) const;
uint32_t getAttributeNameResID(size_t idx) const;
// These will work only if the underlying string pool is UTF-8.
@@ -740,7 +751,7 @@
const char* getAttributeName8(size_t idx, size_t* outLen) const;
int32_t getAttributeValueStringID(size_t idx) const;
- const uint16_t* getAttributeStringValue(size_t idx, size_t* outLen) const;
+ const char16_t* getAttributeStringValue(size_t idx, size_t* outLen) const;
int32_t getAttributeDataType(size_t idx) const;
int32_t getAttributeData(size_t idx) const;
@@ -845,7 +856,7 @@
uint32_t id;
// Actual name of this package, \0-terminated.
- char16_t name[128];
+ uint16_t name[128];
// Offset to a ResStringPool_header defining the resource
// type symbol table. If zero, this package is inheriting from
@@ -1450,7 +1461,7 @@
uint32_t packageId;
// The package name of the shared library. \0 terminated.
- char16_t packageName[128];
+ uint16_t packageName[128];
};
/**
@@ -1681,7 +1692,7 @@
size_t defPackageLen = 0,
uint32_t* outTypeSpecFlags = NULL) const;
- static bool expandResourceRef(const uint16_t* refStr, size_t refLen,
+ static bool expandResourceRef(const char16_t* refStr, size_t refLen,
String16* outPackage,
String16* outType,
String16* outName,
diff --git a/libs/androidfw/Android.mk b/libs/androidfw/Android.mk
index dbee7ed..20d5470 100644
--- a/libs/androidfw/Android.mk
+++ b/libs/androidfw/Android.mk
@@ -14,7 +14,7 @@
LOCAL_PATH:= $(call my-dir)
-# libandroidfw is partially built for the host (used by obbtool and others)
+# libandroidfw is partially built for the host (used by obbtool, aapt, and others)
# These files are common to host and target builds.
commonSources := \
@@ -35,26 +35,17 @@
BackupHelpers.cpp \
CursorWindow.cpp
-hostSources := \
- $(commonSources)
+hostSources := $(commonSources)
# For the host
# =====================================================
-
include $(CLEAR_VARS)
-LOCAL_SRC_FILES:= $(hostSources)
-
LOCAL_MODULE:= libandroidfw
-
LOCAL_MODULE_TAGS := optional
-
LOCAL_CFLAGS += -DSTATIC_ANDROIDFW_FOR_TOOLS
-
-LOCAL_C_INCLUDES := \
- external/zlib
-
-LOCAL_STATIC_LIBRARIES := liblog libziparchive-host libutils
+LOCAL_SRC_FILES:= $(hostSources)
+LOCAL_C_INCLUDES := external/zlib
include $(BUILD_HOST_STATIC_LIBRARY)
@@ -64,8 +55,13 @@
include $(CLEAR_VARS)
+LOCAL_MODULE:= libandroidfw
+LOCAL_MODULE_TAGS := optional
LOCAL_SRC_FILES:= $(deviceSources)
-
+LOCAL_C_INCLUDES := \
+ external/zlib \
+ system/core/include
+LOCAL_STATIC_LIBRARIES := libziparchive
LOCAL_SHARED_LIBRARIES := \
libbinder \
liblog \
@@ -73,16 +69,6 @@
libutils \
libz
-LOCAL_STATIC_LIBRARIES := libziparchive
-
-LOCAL_C_INCLUDES := \
- external/zlib \
- system/core/include
-
-LOCAL_MODULE:= libandroidfw
-
-LOCAL_MODULE_TAGS := optional
-
include $(BUILD_SHARED_LIBRARY)
diff --git a/libs/androidfw/ResourceTypes.cpp b/libs/androidfw/ResourceTypes.cpp
index 3bbca1a..3cf1021 100644
--- a/libs/androidfw/ResourceTypes.cpp
+++ b/libs/androidfw/ResourceTypes.cpp
@@ -87,11 +87,11 @@
// range checked; guaranteed to NUL-terminate within the stated number of available slots
// NOTE: if this truncates the dst string due to running out of space, no attempt is
// made to avoid splitting surrogate pairs.
-static void strcpy16_dtoh(uint16_t* dst, const uint16_t* src, size_t avail)
+static void strcpy16_dtoh(char16_t* dst, const uint16_t* src, size_t avail)
{
- uint16_t* last = dst + avail - 1;
+ char16_t* last = dst + avail - 1;
while (*src && (dst < last)) {
- char16_t s = dtohs(*src);
+ char16_t s = dtohs(static_cast<char16_t>(*src));
*dst++ = s;
src++;
}
@@ -501,7 +501,7 @@
if (mHeader->flags&ResStringPool_header::UTF8_FLAG) {
charSize = sizeof(uint8_t);
} else {
- charSize = sizeof(char16_t);
+ charSize = sizeof(uint16_t);
}
// There should be at least space for the smallest string
@@ -547,8 +547,8 @@
e[i] = dtohl(mEntries[i]);
}
if (!(mHeader->flags&ResStringPool_header::UTF8_FLAG)) {
- const char16_t* strings = (const char16_t*)mStrings;
- char16_t* s = const_cast<char16_t*>(strings);
+ const uint16_t* strings = (const uint16_t*)mStrings;
+ uint16_t* s = const_cast<uint16_t*>(strings);
for (i=0; i<mStringPoolSize; i++) {
s[i] = dtohs(strings[i]);
}
@@ -558,7 +558,7 @@
if ((mHeader->flags&ResStringPool_header::UTF8_FLAG &&
((uint8_t*)mStrings)[mStringPoolSize-1] != 0) ||
(!mHeader->flags&ResStringPool_header::UTF8_FLAG &&
- ((char16_t*)mStrings)[mStringPoolSize-1] != 0)) {
+ ((uint16_t*)mStrings)[mStringPoolSize-1] != 0)) {
ALOGW("Bad string block: last string is not 0-terminated\n");
return (mError=BAD_TYPE);
}
@@ -656,7 +656,7 @@
* add it together with the next character.
*/
static inline size_t
-decodeLength(const char16_t** str)
+decodeLength(const uint16_t** str)
{
size_t len = **str;
if ((len & 0x8000) != 0) {
@@ -689,19 +689,19 @@
return len;
}
-const uint16_t* ResStringPool::stringAt(size_t idx, size_t* u16len) const
+const char16_t* ResStringPool::stringAt(size_t idx, size_t* u16len) const
{
if (mError == NO_ERROR && idx < mHeader->stringCount) {
const bool isUTF8 = (mHeader->flags&ResStringPool_header::UTF8_FLAG) != 0;
- const uint32_t off = mEntries[idx]/(isUTF8?sizeof(char):sizeof(char16_t));
+ const uint32_t off = mEntries[idx]/(isUTF8?sizeof(uint8_t):sizeof(uint16_t));
if (off < (mStringPoolSize-1)) {
if (!isUTF8) {
- const char16_t* strings = (char16_t*)mStrings;
- const char16_t* str = strings+off;
+ const uint16_t* strings = (uint16_t*)mStrings;
+ const uint16_t* str = strings+off;
*u16len = decodeLength(&str);
if ((uint32_t)(str+*u16len-strings) < mStringPoolSize) {
- return str;
+ return reinterpret_cast<const char16_t*>(str);
} else {
ALOGW("Bad string block: string #%d extends to %d, past end at %d\n",
(int)idx, (int)(str+*u16len-strings), (int)mStringPoolSize);
@@ -1013,7 +1013,7 @@
return mCurNode != NULL ? dtohl(mCurNode->comment.index) : -1;
}
-const uint16_t* ResXMLParser::getComment(size_t* outLen) const
+const char16_t* ResXMLParser::getComment(size_t* outLen) const
{
int32_t id = getCommentID();
return id >= 0 ? mTree.mStrings.stringAt(id, outLen) : NULL;
@@ -1032,7 +1032,7 @@
return -1;
}
-const uint16_t* ResXMLParser::getText(size_t* outLen) const
+const char16_t* ResXMLParser::getText(size_t* outLen) const
{
int32_t id = getTextID();
return id >= 0 ? mTree.mStrings.stringAt(id, outLen) : NULL;
@@ -1055,7 +1055,7 @@
return -1;
}
-const uint16_t* ResXMLParser::getNamespacePrefix(size_t* outLen) const
+const char16_t* ResXMLParser::getNamespacePrefix(size_t* outLen) const
{
int32_t id = getNamespacePrefixID();
//printf("prefix=%d event=%p\n", id, mEventCode);
@@ -1070,7 +1070,7 @@
return -1;
}
-const uint16_t* ResXMLParser::getNamespaceUri(size_t* outLen) const
+const char16_t* ResXMLParser::getNamespaceUri(size_t* outLen) const
{
int32_t id = getNamespaceUriID();
//printf("uri=%d event=%p\n", id, mEventCode);
@@ -1088,7 +1088,7 @@
return -1;
}
-const uint16_t* ResXMLParser::getElementNamespace(size_t* outLen) const
+const char16_t* ResXMLParser::getElementNamespace(size_t* outLen) const
{
int32_t id = getElementNamespaceID();
return id >= 0 ? mTree.mStrings.stringAt(id, outLen) : NULL;
@@ -1105,7 +1105,7 @@
return -1;
}
-const uint16_t* ResXMLParser::getElementName(size_t* outLen) const
+const char16_t* ResXMLParser::getElementName(size_t* outLen) const
{
int32_t id = getElementNameID();
return id >= 0 ? mTree.mStrings.stringAt(id, outLen) : NULL;
@@ -1134,7 +1134,7 @@
return -2;
}
-const uint16_t* ResXMLParser::getAttributeNamespace(size_t idx, size_t* outLen) const
+const char16_t* ResXMLParser::getAttributeNamespace(size_t idx, size_t* outLen) const
{
int32_t id = getAttributeNamespaceID(idx);
//printf("attribute namespace=%d idx=%d event=%p\n", id, idx, mEventCode);
@@ -1165,7 +1165,7 @@
return -1;
}
-const uint16_t* ResXMLParser::getAttributeName(size_t idx, size_t* outLen) const
+const char16_t* ResXMLParser::getAttributeName(size_t idx, size_t* outLen) const
{
int32_t id = getAttributeNameID(idx);
//printf("attribute name=%d idx=%d event=%p\n", id, idx, mEventCode);
@@ -1205,7 +1205,7 @@
return -1;
}
-const uint16_t* ResXMLParser::getAttributeStringValue(size_t idx, size_t* outLen) const
+const char16_t* ResXMLParser::getAttributeStringValue(size_t idx, size_t* outLen) const
{
int32_t id = getAttributeValueStringID(idx);
//XML_NOISY(printf("getAttributeValue 0x%x=0x%x\n", idx, id));
@@ -3645,8 +3645,12 @@
Entry entry;
status_t err = getEntry(grp, t, e, &desiredConfig, &entry);
if (err != NO_ERROR) {
+ // Only log the failure when we're not running on the host as
+ // part of a tool. The caller will do its own logging.
+#ifndef STATIC_ANDROIDFW_FOR_TOOLS
ALOGW("Failure getting entry for 0x%08x (t=%d e=%d) (error %d)\n",
resID, t, e, err);
+#endif
return err;
}
@@ -4239,7 +4243,7 @@
return 0;
}
-bool ResTable::expandResourceRef(const uint16_t* refStr, size_t refLen,
+bool ResTable::expandResourceRef(const char16_t* refStr, size_t refLen,
String16* outPackage,
String16* outType,
String16* outName,
@@ -5665,8 +5669,8 @@
if (idx == 0) {
idx = mPackageGroups.size() + 1;
- char16_t tmpName[sizeof(pkg->name)/sizeof(char16_t)];
- strcpy16_dtoh(tmpName, pkg->name, sizeof(pkg->name)/sizeof(char16_t));
+ char16_t tmpName[sizeof(pkg->name)/sizeof(pkg->name[0])];
+ strcpy16_dtoh(tmpName, pkg->name, sizeof(pkg->name)/sizeof(pkg->name[0]));
group = new PackageGroup(this, String16(tmpName), id);
if (group == NULL) {
delete package;
@@ -6036,7 +6040,10 @@
*outSize += 2 * sizeof(uint16_t);
// overlay packages are assumed to contain only one package group
- const String16 overlayPackage(overlay.mPackageGroups[0]->packages[0]->package->name);
+ const ResTable_package* overlayPackageStruct = overlay.mPackageGroups[0]->packages[0]->package;
+ char16_t tmpName[sizeof(overlayPackageStruct->name)/sizeof(overlayPackageStruct->name[0])];
+ strcpy16_dtoh(tmpName, overlayPackageStruct->name, sizeof(overlayPackageStruct->name)/sizeof(overlayPackageStruct->name[0]));
+ const String16 overlayPackage(tmpName);
for (size_t typeIndex = 0; typeIndex < pg->types.size(); ++typeIndex) {
const TypeList& typeList = pg->types[typeIndex];
@@ -6345,8 +6352,10 @@
// Use a package's real ID, since the ID may have been assigned
// if this package is a shared library.
packageId = pkg->package->id;
+ char16_t tmpName[sizeof(pkg->package->name)/sizeof(pkg->package->name[0])];
+ strcpy16_dtoh(tmpName, pkg->package->name, sizeof(pkg->package->name)/sizeof(pkg->package->name[0]));
printf(" Package %d id=0x%02x name=%s\n", (int)pkgIndex,
- pkg->package->id, String8(String16(pkg->package->name)).string());
+ pkg->package->id, String8(tmpName).string());
}
for (size_t typeIndex=0; typeIndex < pg->types.size(); typeIndex++) {
diff --git a/libs/androidfw/misc.cpp b/libs/androidfw/misc.cpp
index 29686ef..ea54cc5 100644
--- a/libs/androidfw/misc.cpp
+++ b/libs/androidfw/misc.cpp
@@ -22,9 +22,9 @@
#include <androidfw/misc.h>
#include <sys/stat.h>
-#include <string.h>
+#include <cstring>
#include <errno.h>
-#include <stdio.h>
+#include <cstdio>
using namespace android;
diff --git a/libs/androidfw/tests/Android.mk b/libs/androidfw/tests/Android.mk
index b2e465c..2d7906f 100644
--- a/libs/androidfw/tests/Android.mk
+++ b/libs/androidfw/tests/Android.mk
@@ -37,7 +37,6 @@
include $(CLEAR_VARS)
LOCAL_MODULE := libandroidfw_tests
-
LOCAL_SRC_FILES := $(testFiles)
LOCAL_STATIC_LIBRARIES := \
libandroidfw \
@@ -55,11 +54,9 @@
include $(CLEAR_VARS)
LOCAL_MODULE := libandroidfw_tests
-
LOCAL_SRC_FILES := $(testFiles) \
BackupData_test.cpp \
ObbFile_test.cpp
-
LOCAL_SHARED_LIBRARIES := \
libandroidfw \
libcutils \
diff --git a/libs/hwui/Caches.cpp b/libs/hwui/Caches.cpp
index f0bf7b2..952f739 100644
--- a/libs/hwui/Caches.cpp
+++ b/libs/hwui/Caches.cpp
@@ -265,14 +265,27 @@
}
void Caches::dumpMemoryUsage(String8 &log) {
+ uint32_t total = 0;
log.appendFormat("Current memory usage / total memory usage (bytes):\n");
log.appendFormat(" TextureCache %8d / %8d\n",
textureCache.getSize(), textureCache.getMaxSize());
log.appendFormat(" LayerCache %8d / %8d (numLayers = %zu)\n",
layerCache.getSize(), layerCache.getMaxSize(), layerCache.getCount());
- log.appendFormat(" Garbage layers %8zu\n", mLayerGarbage.size());
- log.appendFormat(" Active layers %8zu\n",
- mRenderState ? mRenderState->mActiveLayers.size() : 0);
+ if (mRenderState) {
+ int memused = 0;
+ for (std::set<const Layer*>::iterator it = mRenderState->mActiveLayers.begin();
+ it != mRenderState->mActiveLayers.end(); it++) {
+ const Layer* layer = *it;
+ log.appendFormat(" Layer size %dx%d; isTextureLayer()=%d; texid=%u fbo=%u; refs=%d\n",
+ layer->getWidth(), layer->getHeight(),
+ layer->isTextureLayer(), layer->getTexture(),
+ layer->getFbo(), layer->getStrongCount());
+ memused += layer->getWidth() * layer->getHeight() * 4;
+ }
+ log.appendFormat(" Layers total %8d (numLayers = %zu)\n",
+ memused, mRenderState->mActiveLayers.size());
+ total += memused;
+ }
log.appendFormat(" RenderBufferCache %8d / %8d\n",
renderBufferCache.getSize(), renderBufferCache.getMaxSize());
log.appendFormat(" GradientCache %8d / %8d\n",
@@ -297,9 +310,7 @@
log.appendFormat(" FboCache %8d / %8d\n",
fboCache.getSize(), fboCache.getMaxSize());
- uint32_t total = 0;
total += textureCache.getSize();
- total += layerCache.getSize();
total += renderBufferCache.getSize();
total += gradientCache.getSize();
total += pathCache.getSize();
@@ -323,27 +334,6 @@
textureCache.clearGarbage();
pathCache.clearGarbage();
patchCache.clearGarbage();
-
- Vector<Layer*> layers;
-
- { // scope for the lock
- Mutex::Autolock _l(mGarbageLock);
- layers = mLayerGarbage;
- mLayerGarbage.clear();
- }
-
- size_t count = layers.size();
- for (size_t i = 0; i < count; i++) {
- Layer* layer = layers.itemAt(i);
- delete layer;
- }
- layers.clear();
-}
-
-void Caches::deleteLayerDeferred(Layer* layer) {
- Mutex::Autolock _l(mGarbageLock);
- layer->state = Layer::kState_InGarbageList;
- mLayerGarbage.push(layer);
}
void Caches::flush(FlushMode mode) {
diff --git a/libs/hwui/DeferredLayerUpdater.cpp b/libs/hwui/DeferredLayerUpdater.cpp
index a6d7e78..d02455c 100644
--- a/libs/hwui/DeferredLayerUpdater.cpp
+++ b/libs/hwui/DeferredLayerUpdater.cpp
@@ -24,25 +24,6 @@
namespace android {
namespace uirenderer {
-class DeleteLayerTask : public renderthread::RenderTask {
-public:
- DeleteLayerTask(renderthread::EglManager& eglManager, Layer* layer)
- : mEglManager(eglManager)
- , mLayer(layer)
- {}
-
- virtual void run() {
- mEglManager.requireGlContext();
- LayerRenderer::destroyLayer(mLayer);
- mLayer = 0;
- delete this;
- }
-
-private:
- renderthread::EglManager& mEglManager;
- Layer* mLayer;
-};
-
DeferredLayerUpdater::DeferredLayerUpdater(renderthread::RenderThread& thread, Layer* layer)
: mSurfaceTexture(0)
, mTransform(0)
@@ -62,7 +43,7 @@
DeferredLayerUpdater::~DeferredLayerUpdater() {
SkSafeUnref(mColorFilter);
setTransform(0);
- mRenderThread.queue(new DeleteLayerTask(mRenderThread.eglManager(), mLayer));
+ mLayer->postDecStrong();
mLayer = 0;
}
diff --git a/libs/hwui/DisplayList.cpp b/libs/hwui/DisplayList.cpp
index d8932ce..4a927cf 100644
--- a/libs/hwui/DisplayList.cpp
+++ b/libs/hwui/DisplayList.cpp
@@ -61,10 +61,6 @@
caches.resourceCache.decrementRefcountLocked(sourcePaths.itemAt(i));
}
- for (size_t i = 0; i < layers.size(); i++) {
- caches.resourceCache.decrementRefcountLocked(layers.itemAt(i));
- }
-
caches.resourceCache.unlock();
for (size_t i = 0; i < paints.size(); i++) {
@@ -86,7 +82,6 @@
paints.clear();
regions.clear();
paths.clear();
- layers.clear();
}
size_t DisplayListData::addChild(DrawRenderNodeOp* op) {
diff --git a/libs/hwui/DisplayList.h b/libs/hwui/DisplayList.h
index dea109c..cb8a8d1 100644
--- a/libs/hwui/DisplayList.h
+++ b/libs/hwui/DisplayList.h
@@ -147,7 +147,6 @@
Vector<const SkPath*> paths;
SortedVector<const SkPath*> sourcePaths;
Vector<const SkRegion*> regions;
- Vector<Layer*> layers;
Vector<Functor*> functors;
const Vector<Chunk>& getChunks() const {
@@ -157,11 +156,7 @@
size_t addChild(DrawRenderNodeOp* childOp);
const Vector<DrawRenderNodeOp*>& children() { return mChildren; }
- void refProperty(CanvasPropertyPrimitive* prop) {
- mReferenceHolders.push(prop);
- }
-
- void refProperty(CanvasPropertyPaint* prop) {
+ void ref(VirtualLightRefBase* prop) {
mReferenceHolders.push(prop);
}
diff --git a/libs/hwui/DisplayListRenderer.cpp b/libs/hwui/DisplayListRenderer.cpp
index 1f70921..c17dd09 100644
--- a/libs/hwui/DisplayListRenderer.cpp
+++ b/libs/hwui/DisplayListRenderer.cpp
@@ -189,7 +189,7 @@
}
status_t DisplayListRenderer::drawLayer(Layer* layer, float x, float y) {
- layer = refLayer(layer);
+ mDisplayListData->ref(layer);
addDrawOp(new (alloc()) DrawLayerOp(layer, x, y));
return DrawGlInfo::kStatusDone;
}
@@ -280,13 +280,13 @@
CanvasPropertyPrimitive* right, CanvasPropertyPrimitive* bottom,
CanvasPropertyPrimitive* rx, CanvasPropertyPrimitive* ry,
CanvasPropertyPaint* paint) {
- mDisplayListData->refProperty(left);
- mDisplayListData->refProperty(top);
- mDisplayListData->refProperty(right);
- mDisplayListData->refProperty(bottom);
- mDisplayListData->refProperty(rx);
- mDisplayListData->refProperty(ry);
- mDisplayListData->refProperty(paint);
+ mDisplayListData->ref(left);
+ mDisplayListData->ref(top);
+ mDisplayListData->ref(right);
+ mDisplayListData->ref(bottom);
+ mDisplayListData->ref(rx);
+ mDisplayListData->ref(ry);
+ mDisplayListData->ref(paint);
addDrawOp(new (alloc()) DrawRoundRectPropsOp(&left->value, &top->value,
&right->value, &bottom->value, &rx->value, &ry->value, &paint->value));
return DrawGlInfo::kStatusDone;
@@ -300,10 +300,10 @@
status_t DisplayListRenderer::drawCircle(CanvasPropertyPrimitive* x, CanvasPropertyPrimitive* y,
CanvasPropertyPrimitive* radius, CanvasPropertyPaint* paint) {
- mDisplayListData->refProperty(x);
- mDisplayListData->refProperty(y);
- mDisplayListData->refProperty(radius);
- mDisplayListData->refProperty(paint);
+ mDisplayListData->ref(x);
+ mDisplayListData->ref(y);
+ mDisplayListData->ref(radius);
+ mDisplayListData->ref(paint);
addDrawOp(new (alloc()) DrawCirclePropsOp(&x->value, &y->value,
&radius->value, &paint->value));
return DrawGlInfo::kStatusDone;
diff --git a/libs/hwui/DisplayListRenderer.h b/libs/hwui/DisplayListRenderer.h
index 3a3fc3a..901e8f0 100644
--- a/libs/hwui/DisplayListRenderer.h
+++ b/libs/hwui/DisplayListRenderer.h
@@ -267,12 +267,6 @@
return regionCopy;
}
- inline Layer* refLayer(Layer* layer) {
- mDisplayListData->layers.add(layer);
- mCaches.resourceCache.incrementRefcount(layer);
- return layer;
- }
-
inline const SkBitmap* refBitmap(const SkBitmap* bitmap) {
// Note that this assumes the bitmap is immutable. There are cases this won't handle
// correctly, such as creating the bitmap from scratch, drawing with it, changing its
diff --git a/libs/hwui/Layer.cpp b/libs/hwui/Layer.cpp
index b5089aa..b95636b 100644
--- a/libs/hwui/Layer.cpp
+++ b/libs/hwui/Layer.cpp
@@ -35,6 +35,9 @@
, renderState(renderState)
, texture(caches)
, type(layerType) {
+ // TODO: This is a violation of Android's typical ref counting, but it
+ // preserves the old inc/dec ref locations. This should be changed...
+ incStrong(0);
mesh = NULL;
meshElementCount = 0;
cacheable = true;
@@ -53,20 +56,14 @@
forceFilter = false;
deferredList = NULL;
convexMask = NULL;
- caches.resourceCache.incrementRefcount(this);
rendererLightPosDirty = true;
wasBuildLayered = false;
- if (!isTextureLayer()) {
- // track only non-texture layer lifecycles in renderstate,
- // because texture layers are destroyed via finalizer
- renderState.registerLayer(this);
- }
+ renderState.registerLayer(this);
}
Layer::~Layer() {
- if (!isTextureLayer()) {
- renderState.unregisterLayer(this);
- }
+ renderState.requireGLContext();
+ renderState.unregisterLayer(this);
SkSafeUnref(colorFilter);
removeFbo();
deleteTexture();
@@ -292,5 +289,9 @@
renderNode = NULL;
}
+void Layer::postDecStrong() {
+ renderState.postDecStrong(this);
+}
+
}; // namespace uirenderer
}; // namespace android
diff --git a/libs/hwui/Layer.h b/libs/hwui/Layer.h
index a8e1c26..64d1d12 100644
--- a/libs/hwui/Layer.h
+++ b/libs/hwui/Layer.h
@@ -52,7 +52,7 @@
/**
* A layer has dimensions and is backed by an OpenGL texture or FBO.
*/
-class Layer {
+class Layer : public VirtualLightRefBase {
public:
enum Type {
kType_Texture,
@@ -280,6 +280,12 @@
void render(const OpenGLRenderer& rootRenderer);
/**
+ * Posts a decStrong call to the appropriate thread.
+ * Thread-safe.
+ */
+ void postDecStrong();
+
+ /**
* Bounds of the layer.
*/
Rect layer;
diff --git a/libs/hwui/LayerCache.cpp b/libs/hwui/LayerCache.cpp
index 833f64b..3033dc6 100644
--- a/libs/hwui/LayerCache.cpp
+++ b/libs/hwui/LayerCache.cpp
@@ -84,7 +84,7 @@
layer->getFbo());
mSize -= layer->getWidth() * layer->getHeight() * 4;
layer->state = Layer::kState_DeletedFromCache;
- Caches::getInstance().resourceCache.decrementRefcount(layer);
+ layer->decStrong(0);
}
}
diff --git a/libs/hwui/LayerRenderer.cpp b/libs/hwui/LayerRenderer.cpp
index 103c843..394c647 100644
--- a/libs/hwui/LayerRenderer.cpp
+++ b/libs/hwui/LayerRenderer.cpp
@@ -212,7 +212,7 @@
// Creating a new layer always increment its refcount by 1, this allows
// us to destroy the layer object if one was created for us
- Caches::getInstance().resourceCache.decrementRefcount(layer);
+ layer->decStrong(0);
return NULL;
}
@@ -240,7 +240,7 @@
if (glGetError() != GL_NO_ERROR) {
ALOGE("Could not allocate texture for layer (fbo=%d %dx%d)", fbo, width, height);
renderState.bindFramebuffer(previousFbo);
- caches.resourceCache.decrementRefcount(layer);
+ layer->decStrong(0);
return NULL;
}
}
@@ -316,7 +316,7 @@
if (!Caches::getInstance().layerCache.put(layer)) {
LAYER_RENDERER_LOGD(" Destroyed!");
- Caches::getInstance().resourceCache.decrementRefcount(layer);
+ layer->decStrong(0);
} else {
LAYER_RENDERER_LOGD(" Cached!");
#if DEBUG_LAYER_RENDERER
@@ -328,14 +328,6 @@
}
}
-void LayerRenderer::destroyLayerDeferred(Layer* layer) {
- if (layer) {
- LAYER_RENDERER_LOGD("Deferring layer destruction, fbo = %d", layer->getFbo());
-
- Caches::getInstance().deleteLayerDeferred(layer);
- }
-}
-
void LayerRenderer::flushLayer(RenderState& renderState, Layer* layer) {
#ifdef GL_EXT_discard_framebuffer
if (!layer) return;
diff --git a/libs/hwui/LayerRenderer.h b/libs/hwui/LayerRenderer.h
index bf7828c..4d8620b 100644
--- a/libs/hwui/LayerRenderer.h
+++ b/libs/hwui/LayerRenderer.h
@@ -60,7 +60,6 @@
static void updateTextureLayer(Layer* layer, uint32_t width, uint32_t height,
bool isOpaque, bool forceFilter, GLenum renderTarget, float* textureTransform);
static void destroyLayer(Layer* layer);
- ANDROID_API static void destroyLayerDeferred(Layer* layer);
static bool copyLayer(RenderState& renderState, Layer* layer, SkBitmap* bitmap);
static void flushLayer(RenderState& renderState, Layer* layer);
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index 19fc9a3..d570b0d 100755
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -509,11 +509,8 @@
// Note: it is very important to update the layers in order
for (int i = 0; i < count; i++) {
- Layer* layer = mLayerUpdates.itemAt(i);
+ Layer* layer = mLayerUpdates.itemAt(i).get();
updateLayer(layer, false);
- if (CC_UNLIKELY(mCaches.drawDeferDisabled)) {
- mCaches.resourceCache.decrementRefcount(layer);
- }
}
if (CC_UNLIKELY(mCaches.drawDeferDisabled)) {
@@ -532,7 +529,7 @@
// Note: it is very important to update the layers in order
for (int i = 0; i < count; i++) {
- Layer* layer = mLayerUpdates.itemAt(i);
+ Layer* layer = mLayerUpdates.itemAt(i).get();
sprintf(layerName, "Layer #%d", i);
startMark(layerName);
@@ -542,8 +539,6 @@
ATRACE_END();
endMark();
-
- mCaches.resourceCache.decrementRefcount(layer);
}
mLayerUpdates.clear();
@@ -565,7 +560,6 @@
}
}
mLayerUpdates.push_back(layer);
- mCaches.resourceCache.incrementRefcount(layer);
}
}
@@ -574,25 +568,12 @@
for (int i = mLayerUpdates.size() - 1; i >= 0; i--) {
if (mLayerUpdates.itemAt(i) == layer) {
mLayerUpdates.removeAt(i);
- mCaches.resourceCache.decrementRefcount(layer);
break;
}
}
}
}
-void OpenGLRenderer::clearLayerUpdates() {
- size_t count = mLayerUpdates.size();
- if (count > 0) {
- mCaches.resourceCache.lock();
- for (size_t i = 0; i < count; i++) {
- mCaches.resourceCache.decrementRefcountLocked(mLayerUpdates.itemAt(i));
- }
- mCaches.resourceCache.unlock();
- mLayerUpdates.clear();
- }
-}
-
void OpenGLRenderer::flushLayerUpdates() {
ATRACE_CALL();
syncState();
@@ -956,7 +937,7 @@
layer->setConvexMask(NULL);
if (!mCaches.layerCache.put(layer)) {
LAYER_LOGD("Deleting layer");
- Caches::getInstance().resourceCache.decrementRefcount(layer);
+ layer->decStrong(0);
}
}
diff --git a/libs/hwui/OpenGLRenderer.h b/libs/hwui/OpenGLRenderer.h
index c2c0b0e..e1c3d10 100755
--- a/libs/hwui/OpenGLRenderer.h
+++ b/libs/hwui/OpenGLRenderer.h
@@ -140,7 +140,6 @@
void pushLayerUpdate(Layer* layer);
void cancelLayerUpdate(Layer* layer);
- void clearLayerUpdates();
void flushLayerUpdates();
void markLayersAsBuildLayers();
@@ -982,7 +981,7 @@
// List of rectangles to clear after saveLayer() is invoked
Vector<Rect*> mLayers;
// List of layers to update at the beginning of a frame
- Vector<Layer*> mLayerUpdates;
+ Vector< sp<Layer> > mLayerUpdates;
// The following fields are used to setup drawing
// Used to describe the shaders to generate
diff --git a/libs/hwui/PathTessellator.cpp b/libs/hwui/PathTessellator.cpp
index 281ca02..27ef06f 100644
--- a/libs/hwui/PathTessellator.cpp
+++ b/libs/hwui/PathTessellator.cpp
@@ -812,7 +812,7 @@
// determine point shape
SkPath path;
float radius = paintInfo.halfStrokeWidth;
- if (radius == 0.0f) radius = 0.25f;
+ if (radius == 0.0f) radius = 0.5f;
if (paintInfo.cap == SkPaint::kRound_Cap) {
path.addCircle(0, 0, radius);
diff --git a/libs/hwui/Program.cpp b/libs/hwui/Program.cpp
index cc72ae0..0dad0dc 100644
--- a/libs/hwui/Program.cpp
+++ b/libs/hwui/Program.cpp
@@ -141,11 +141,12 @@
GLint status;
glGetShaderiv(shader, GL_COMPILE_STATUS, &status);
if (status != GL_TRUE) {
+ ALOGE("Error while compiling this shader:\n===\n%s\n===", source);
// Some drivers return wrong values for GL_INFO_LOG_LENGTH
// use a fixed size instead
GLchar log[512];
glGetShaderInfoLog(shader, sizeof(log), 0, &log[0]);
- LOG_ALWAYS_FATAL("Error while compiling shader: %s", log);
+ LOG_ALWAYS_FATAL("Shader info log: %s", log);
return 0;
}
diff --git a/libs/hwui/RenderNode.cpp b/libs/hwui/RenderNode.cpp
index 40cd13e..c9ed9a7 100644
--- a/libs/hwui/RenderNode.cpp
+++ b/libs/hwui/RenderNode.cpp
@@ -87,7 +87,11 @@
RenderNode::~RenderNode() {
deleteDisplayListData();
delete mStagingDisplayListData;
- LayerRenderer::destroyLayerDeferred(mLayer);
+ if (mLayer) {
+ ALOGW("Memory Warning: Layer %p missed its detachment, held on to for far too long!", mLayer);
+ mLayer->postDecStrong();
+ mLayer = 0;
+ }
}
void RenderNode::setStagingDisplayList(DisplayListData* data) {
@@ -201,6 +205,7 @@
info.damageAccumulator->peekAtDirty(&dirty);
if (!mLayer) {
+ Caches::getInstance().dumpMemoryUsage();
if (info.errorHandler) {
std::string msg = "Unable to create layer for ";
msg += getName();
diff --git a/libs/hwui/RenderNode.h b/libs/hwui/RenderNode.h
index f329283..2ce7cb7 100644
--- a/libs/hwui/RenderNode.h
+++ b/libs/hwui/RenderNode.h
@@ -101,7 +101,7 @@
kReplayFlag_ClipChildren = 0x1
};
- ANDROID_API static void outputLogBuffer(int fd);
+ static void outputLogBuffer(int fd);
void debugDumpLayers(const char* prefix);
ANDROID_API void setStagingDisplayList(DisplayListData* newData);
diff --git a/libs/hwui/RenderState.cpp b/libs/hwui/RenderState.cpp
index 86bd7dd..a8cf26f 100644
--- a/libs/hwui/RenderState.cpp
+++ b/libs/hwui/RenderState.cpp
@@ -16,15 +16,18 @@
#include "RenderState.h"
#include "renderthread/CanvasContext.h"
+#include "renderthread/EglManager.h"
namespace android {
namespace uirenderer {
-RenderState::RenderState()
- : mCaches(NULL)
+RenderState::RenderState(renderthread::RenderThread& thread)
+ : mRenderThread(thread)
+ , mCaches(NULL)
, mViewportWidth(0)
, mViewportHeight(0)
, mFramebuffer(0) {
+ mThreadId = pthread_self();
}
RenderState::~RenderState() {
@@ -39,7 +42,6 @@
void RenderState::onGLContextDestroyed() {
/*
- AutoMutex _lock(mLayerLock);
size_t size = mActiveLayers.size();
if (CC_UNLIKELY(size != 0)) {
ALOGE("Crashing, have %d contexts and %d layers at context destruction. isempty %d",
@@ -146,5 +148,34 @@
}
}
+void RenderState::requireGLContext() {
+ assertOnGLThread();
+ mRenderThread.eglManager().requireGlContext();
+}
+
+void RenderState::assertOnGLThread() {
+ pthread_t curr = pthread_self();
+ LOG_ALWAYS_FATAL_IF(!pthread_equal(mThreadId, curr), "Wrong thread!");
+}
+
+
+class DecStrongTask : public renderthread::RenderTask {
+public:
+ DecStrongTask(VirtualLightRefBase* object) : mObject(object) {}
+
+ virtual void run() {
+ mObject->decStrong(0);
+ mObject = 0;
+ delete this;
+ }
+
+private:
+ VirtualLightRefBase* mObject;
+};
+
+void RenderState::postDecStrong(VirtualLightRefBase* object) {
+ mRenderThread.queue(new DecStrongTask(object));
+}
+
} /* namespace uirenderer */
} /* namespace android */
diff --git a/libs/hwui/RenderState.h b/libs/hwui/RenderState.h
index cbe7cfc..afeef95 100644
--- a/libs/hwui/RenderState.h
+++ b/libs/hwui/RenderState.h
@@ -53,16 +53,10 @@
void debugOverdraw(bool enable, bool clear);
void registerLayer(const Layer* layer) {
- /*
- AutoMutex _lock(mLayerLock);
mActiveLayers.insert(layer);
- */
}
void unregisterLayer(const Layer* layer) {
- /*
- AutoMutex _lock(mLayerLock);
mActiveLayers.erase(layer);
- */
}
void registerCanvasContext(renderthread::CanvasContext* context) {
@@ -73,16 +67,24 @@
mRegisteredContexts.erase(context);
}
+ void requireGLContext();
+
+ // TODO: This system is a little clunky feeling, this could use some
+ // more thinking...
+ void postDecStrong(VirtualLightRefBase* object);
+
private:
friend class renderthread::RenderThread;
friend class Caches;
void interruptForFunctorInvoke();
void resumeFromFunctorInvoke();
+ void assertOnGLThread();
- RenderState();
+ RenderState(renderthread::RenderThread& thread);
~RenderState();
+ renderthread::RenderThread& mRenderThread;
Caches* mCaches;
std::set<const Layer*> mActiveLayers;
std::set<renderthread::CanvasContext*> mRegisteredContexts;
@@ -90,7 +92,8 @@
GLsizei mViewportWidth;
GLsizei mViewportHeight;
GLuint mFramebuffer;
- Mutex mLayerLock;
+
+ pthread_t mThreadId;
};
} /* namespace uirenderer */
diff --git a/libs/hwui/ResourceCache.cpp b/libs/hwui/ResourceCache.cpp
index 8b553d1..329d92f 100644
--- a/libs/hwui/ResourceCache.cpp
+++ b/libs/hwui/ResourceCache.cpp
@@ -75,10 +75,6 @@
incrementRefcount((void*) patchResource, kNinePatch);
}
-void ResourceCache::incrementRefcount(Layer* layerResource) {
- incrementRefcount((void*) layerResource, kLayer);
-}
-
void ResourceCache::incrementRefcountLocked(void* resource, ResourceType resourceType) {
ssize_t index = mCache->indexOfKey(resource);
ResourceReference* ref = index >= 0 ? mCache->valueAt(index) : NULL;
@@ -103,10 +99,6 @@
incrementRefcountLocked((void*) patchResource, kNinePatch);
}
-void ResourceCache::incrementRefcountLocked(Layer* layerResource) {
- incrementRefcountLocked((void*) layerResource, kLayer);
-}
-
void ResourceCache::decrementRefcount(void* resource) {
Mutex::Autolock _l(mLock);
decrementRefcountLocked(resource);
@@ -126,10 +118,6 @@
decrementRefcount((void*) patchResource);
}
-void ResourceCache::decrementRefcount(Layer* layerResource) {
- decrementRefcount((void*) layerResource);
-}
-
void ResourceCache::decrementRefcountLocked(void* resource) {
ssize_t index = mCache->indexOfKey(resource);
ResourceReference* ref = index >= 0 ? mCache->valueAt(index) : NULL;
@@ -157,10 +145,6 @@
decrementRefcountLocked((void*) patchResource);
}
-void ResourceCache::decrementRefcountLocked(Layer* layerResource) {
- decrementRefcountLocked((void*) layerResource);
-}
-
void ResourceCache::destructor(SkPath* resource) {
Mutex::Autolock _l(mLock);
destructorLocked(resource);
@@ -274,7 +258,7 @@
if (ref->recycled && ref->resourceType == kBitmap) {
((SkBitmap*) resource)->setPixels(NULL, NULL);
}
- if (ref->destroyed || ref->resourceType == kLayer) {
+ if (ref->destroyed) {
switch (ref->resourceType) {
case kBitmap: {
SkBitmap* bitmap = (SkBitmap*) resource;
@@ -305,11 +289,6 @@
}
}
break;
- case kLayer: {
- Layer* layer = (Layer*) resource;
- Caches::getInstance().deleteLayerDeferred(layer);
- }
- break;
}
}
mCache->removeItem(resource);
diff --git a/libs/hwui/ResourceCache.h b/libs/hwui/ResourceCache.h
index 3864d4b..8539d12 100644
--- a/libs/hwui/ResourceCache.h
+++ b/libs/hwui/ResourceCache.h
@@ -36,8 +36,7 @@
enum ResourceType {
kBitmap,
kNinePatch,
- kPath,
- kLayer
+ kPath
};
class ResourceReference {
@@ -69,22 +68,18 @@
void incrementRefcount(const SkPath* resource);
void incrementRefcount(const SkBitmap* resource);
void incrementRefcount(const Res_png_9patch* resource);
- void incrementRefcount(Layer* resource);
void incrementRefcountLocked(const SkPath* resource);
void incrementRefcountLocked(const SkBitmap* resource);
void incrementRefcountLocked(const Res_png_9patch* resource);
- void incrementRefcountLocked(Layer* resource);
void decrementRefcount(const SkBitmap* resource);
void decrementRefcount(const SkPath* resource);
void decrementRefcount(const Res_png_9patch* resource);
- void decrementRefcount(Layer* resource);
void decrementRefcountLocked(const SkBitmap* resource);
void decrementRefcountLocked(const SkPath* resource);
void decrementRefcountLocked(const Res_png_9patch* resource);
- void decrementRefcountLocked(Layer* resource);
void destructor(SkPath* resource);
void destructor(const SkBitmap* resource);
diff --git a/libs/hwui/renderthread/CanvasContext.cpp b/libs/hwui/renderthread/CanvasContext.cpp
index 9d2ae8b..b499dd0 100644
--- a/libs/hwui/renderthread/CanvasContext.cpp
+++ b/libs/hwui/renderthread/CanvasContext.cpp
@@ -236,6 +236,8 @@
if (status & DrawGlInfo::kStatusDrew) {
swapBuffers();
+ } else {
+ mEglManager.cancelFrame();
}
profiler().finishFrame();
diff --git a/libs/hwui/renderthread/EglManager.cpp b/libs/hwui/renderthread/EglManager.cpp
index e37aafc..9bd6f41 100644
--- a/libs/hwui/renderthread/EglManager.cpp
+++ b/libs/hwui/renderthread/EglManager.cpp
@@ -73,7 +73,8 @@
, mAllowPreserveBuffer(load_dirty_regions_property())
, mCurrentSurface(EGL_NO_SURFACE)
, mAtlasMap(NULL)
- , mAtlasMapSize(0) {
+ , mAtlasMapSize(0)
+ , mInFrame(false) {
mCanSetPreserveBuffer = mAllowPreserveBuffer;
ALOGD("Use EGL_SWAP_BEHAVIOR_PRESERVED: %s", mAllowPreserveBuffer ? "true" : "false");
}
@@ -105,10 +106,12 @@
void EglManager::requireGlContext() {
LOG_ALWAYS_FATAL_IF(mEglDisplay == EGL_NO_DISPLAY, "No EGL context");
- // We can't be certain about the state of the current surface (whether
- // or not it is destroyed, for example), so err on the side of using
- // the pbuffer surface which we fully control
- usePBufferSurface();
+ if (!mInFrame) {
+ // We can't be certain about the state of the current surface (whether
+ // or not it is destroyed, for example), so err on the side of using
+ // the pbuffer surface which we fully control
+ usePBufferSurface();
+ }
}
void EglManager::loadConfig() {
@@ -251,9 +254,11 @@
eglQuerySurface(mEglDisplay, surface, EGL_HEIGHT, height);
}
eglBeginFrame(mEglDisplay, surface);
+ mInFrame = true;
}
bool EglManager::swapBuffers(EGLSurface surface) {
+ mInFrame = false;
eglSwapBuffers(mEglDisplay, surface);
EGLint err = eglGetError();
if (CC_LIKELY(err == EGL_SUCCESS)) {
@@ -272,6 +277,10 @@
return false;
}
+void EglManager::cancelFrame() {
+ mInFrame = false;
+}
+
bool EglManager::setPreserveBuffer(EGLSurface surface, bool preserve) {
if (CC_UNLIKELY(!mAllowPreserveBuffer)) return false;
diff --git a/libs/hwui/renderthread/EglManager.h b/libs/hwui/renderthread/EglManager.h
index ae03ea1..e12db3a 100644
--- a/libs/hwui/renderthread/EglManager.h
+++ b/libs/hwui/renderthread/EglManager.h
@@ -48,6 +48,7 @@
bool makeCurrent(EGLSurface surface);
void beginFrame(EGLSurface surface, EGLint* width, EGLint* height);
bool swapBuffers(EGLSurface surface);
+ void cancelFrame();
// Returns true iff the surface is now preserving buffers.
bool setPreserveBuffer(EGLSurface surface, bool preserve);
@@ -80,6 +81,12 @@
sp<GraphicBuffer> mAtlasBuffer;
int64_t* mAtlasMap;
size_t mAtlasMapSize;
+
+ // Whether or not we are in the middle of drawing a frame. This is used
+ // to avoid switching surfaces mid-frame if requireGlContext() is called
+ // TODO: Need to be better about surface/context management so that this isn't
+ // necessary
+ bool mInFrame;
};
} /* namespace renderthread */
diff --git a/libs/hwui/renderthread/RenderProxy.cpp b/libs/hwui/renderthread/RenderProxy.cpp
index 8f99b4e..5d55ea6 100644
--- a/libs/hwui/renderthread/RenderProxy.cpp
+++ b/libs/hwui/renderthread/RenderProxy.cpp
@@ -235,12 +235,7 @@
// waitForCompletion = true is expected to be fairly rare and only
// happen in destruction. Thus it should be fine to temporarily
// create a Mutex
- Mutex mutex;
- Condition condition;
- SignalingRenderTask syncTask(task, &mutex, &condition);
- AutoMutex _lock(mutex);
- thread.queue(&syncTask);
- condition.wait(mutex);
+ staticPostAndWait(task);
} else {
thread.queue(task);
}
@@ -258,17 +253,6 @@
postAndWait(task);
}
-CREATE_BRIDGE1(destroyLayer, Layer* layer) {
- LayerRenderer::destroyLayer(args->layer);
- return NULL;
-}
-
-void RenderProxy::enqueueDestroyLayer(Layer* layer) {
- SETUP_TASK(destroyLayer);
- args->layer = layer;
- RenderThread::getInstance().queue(task);
-}
-
CREATE_BRIDGE2(createTextureLayer, RenderThread* thread, CanvasContext* context) {
Layer* layer = args->context->createTextureLayer();
if (!layer) return 0;
@@ -400,6 +384,17 @@
postAndWait(task);
}
+CREATE_BRIDGE1(outputLogBuffer, int fd) {
+ RenderNode::outputLogBuffer(args->fd);
+ return NULL;
+}
+
+void RenderProxy::outputLogBuffer(int fd) {
+ SETUP_TASK(outputLogBuffer);
+ args->fd = fd;
+ staticPostAndWait(task);
+}
+
CREATE_BRIDGE4(setTextureAtlas, RenderThread* thread, GraphicBuffer* buffer, int64_t* map, size_t size) {
CanvasContext::setTextureAtlas(*args->thread, args->buffer, args->map, args->size);
args->buffer->decStrong(0);
@@ -430,6 +425,19 @@
return retval;
}
+void* RenderProxy::staticPostAndWait(MethodInvokeRenderTask* task) {
+ RenderThread& thread = RenderThread::getInstance();
+ void* retval;
+ task->setReturnPtr(&retval);
+ Mutex mutex;
+ Condition condition;
+ SignalingRenderTask syncTask(task, &mutex, &condition);
+ AutoMutex _lock(mutex);
+ thread.queue(&syncTask);
+ condition.wait(mutex);
+ return retval;
+}
+
} /* namespace renderthread */
} /* namespace uirenderer */
} /* namespace android */
diff --git a/libs/hwui/renderthread/RenderProxy.h b/libs/hwui/renderthread/RenderProxy.h
index dddf0c7..4989b14 100644
--- a/libs/hwui/renderthread/RenderProxy.h
+++ b/libs/hwui/renderthread/RenderProxy.h
@@ -81,7 +81,6 @@
ANDROID_API void runWithGlContext(RenderTask* task);
- static void enqueueDestroyLayer(Layer* layer);
ANDROID_API DeferredLayerUpdater* createTextureLayer();
ANDROID_API void buildLayer(RenderNode* node);
ANDROID_API bool copyLayerInto(DeferredLayerUpdater* layer, SkBitmap* bitmap);
@@ -97,6 +96,7 @@
ANDROID_API void notifyFramePending();
ANDROID_API void dumpProfileInfo(int fd);
+ ANDROID_API static void outputLogBuffer(int fd);
ANDROID_API void setTextureAtlas(const sp<GraphicBuffer>& buffer, int64_t* map, size_t size);
@@ -114,6 +114,8 @@
void post(RenderTask* task);
void* postAndWait(MethodInvokeRenderTask* task);
+ static void* staticPostAndWait(MethodInvokeRenderTask* task);
+
// Friend class to help with bridging
friend class RenderProxyBridge;
};
diff --git a/libs/hwui/renderthread/RenderThread.cpp b/libs/hwui/renderthread/RenderThread.cpp
index 403e164..f887103 100644
--- a/libs/hwui/renderthread/RenderThread.cpp
+++ b/libs/hwui/renderthread/RenderThread.cpp
@@ -168,7 +168,7 @@
void RenderThread::initThreadLocals() {
initializeDisplayEventReceiver();
mEglManager = new EglManager(*this);
- mRenderState = new RenderState();
+ mRenderState = new RenderState(*this);
}
int RenderThread::displayEventReceiverCallback(int fd, int events, void* data) {
diff --git a/media/java/android/media/AudioAttributes.java b/media/java/android/media/AudioAttributes.java
index 17d3251..20c4978 100644
--- a/media/java/android/media/AudioAttributes.java
+++ b/media/java/android/media/AudioAttributes.java
@@ -161,6 +161,12 @@
* Usage value to use when the usage is for game audio.
*/
public final static int USAGE_GAME = 14;
+ /**
+ * @hide
+ * Usage value to use when feeding audio to the platform and replacing "traditional" audio
+ * source, such as audio capture devices.
+ */
+ public final static int USAGE_VIRTUAL_SOURCE = 15;
/**
* Flag defining a behavior where the audibility of the sound will be ensured by the system.
@@ -374,6 +380,7 @@
case USAGE_ASSISTANCE_NAVIGATION_GUIDANCE:
case USAGE_ASSISTANCE_SONIFICATION:
case USAGE_GAME:
+ case USAGE_VIRTUAL_SOURCE:
mUsage = usage;
break;
default:
diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java
index 716ff99..8fc0b8e 100644
--- a/media/java/android/media/AudioManager.java
+++ b/media/java/android/media/AudioManager.java
@@ -2663,9 +2663,13 @@
}
IAudioService service = getService();
try {
- if (!service.registerAudioPolicy(policy.getConfig(), policy.token())) {
+ String regId = service.registerAudioPolicy(policy.getConfig(), policy.token());
+ if (regId == null) {
return ERROR;
+ } else {
+ policy.setRegistration(regId);
}
+ // successful registration
} catch (RemoteException e) {
Log.e(TAG, "Dead object in registerAudioPolicyAsync()", e);
return ERROR;
diff --git a/media/java/android/media/AudioService.java b/media/java/android/media/AudioService.java
index 6a69517..29d4930 100644
--- a/media/java/android/media/AudioService.java
+++ b/media/java/android/media/AudioService.java
@@ -48,6 +48,7 @@
import android.hardware.usb.UsbManager;
import android.media.MediaPlayer.OnCompletionListener;
import android.media.MediaPlayer.OnErrorListener;
+import android.media.audiopolicy.AudioMix;
import android.media.audiopolicy.AudioPolicyConfig;
import android.media.session.MediaSessionLegacyHelper;
import android.os.Binder;
@@ -118,6 +119,10 @@
/** Debug audio mode */
protected static final boolean DEBUG_MODE = Log.isLoggable(TAG + ".MOD", Log.DEBUG);
+
+ /** Debug audio policy feature */
+ protected static final boolean DEBUG_AP = Log.isLoggable(TAG + ".AP", Log.DEBUG);
+
/** Debug volumes */
protected static final boolean DEBUG_VOL = Log.isLoggable(TAG + ".VOL", Log.DEBUG);
@@ -528,6 +533,8 @@
private AudioOrientationEventListener mOrientationListener;
+ private static Long mLastDeviceConnectMsgTime = new Long(0);
+
///////////////////////////////////////////////////////////////////////////
// Construction
///////////////////////////////////////////////////////////////////////////
@@ -735,15 +742,17 @@
}
private void checkAllAliasStreamVolumes() {
- int numStreamTypes = AudioSystem.getNumStreamTypes();
- for (int streamType = 0; streamType < numStreamTypes; streamType++) {
- if (streamType != mStreamVolumeAlias[streamType]) {
- mStreamStates[streamType].
+ synchronized (VolumeStreamState.class) {
+ int numStreamTypes = AudioSystem.getNumStreamTypes();
+ for (int streamType = 0; streamType < numStreamTypes; streamType++) {
+ if (streamType != mStreamVolumeAlias[streamType]) {
+ mStreamStates[streamType].
setAllIndexes(mStreamStates[mStreamVolumeAlias[streamType]]);
- }
- // apply stream volume
- if (!mStreamStates[streamType].isMuted()) {
- mStreamStates[streamType].applyAllVolumes();
+ }
+ // apply stream volume
+ if (!mStreamStates[streamType].isMuted_syncVSS()) {
+ mStreamStates[streamType].applyAllVolumes();
+ }
}
}
}
@@ -1515,7 +1524,9 @@
/** get stream mute state. */
public boolean isStreamMute(int streamType) {
- return mStreamStates[streamType].isMuted();
+ synchronized (VolumeStreamState.class) {
+ return mStreamStates[streamType].isMuted_syncVSS();
+ }
}
private class RmtSbmxFullVolDeathHandler implements IBinder.DeathRecipient {
@@ -1653,17 +1664,19 @@
public int getStreamVolume(int streamType) {
ensureValidStreamType(streamType);
int device = getDeviceForStream(streamType);
- int index = mStreamStates[streamType].getIndex(device);
+ synchronized (VolumeStreamState.class) {
+ int index = mStreamStates[streamType].getIndex(device);
- // by convention getStreamVolume() returns 0 when a stream is muted.
- if (mStreamStates[streamType].isMuted()) {
- index = 0;
+ // by convention getStreamVolume() returns 0 when a stream is muted.
+ if (mStreamStates[streamType].isMuted_syncVSS()) {
+ index = 0;
+ }
+ if (index != 0 && (mStreamVolumeAlias[streamType] == AudioSystem.STREAM_MUSIC) &&
+ (device & mFixedVolumeDevices) != 0) {
+ index = mStreamStates[streamType].getMaxIndex();
+ }
+ return (index + 5) / 10;
}
- if (index != 0 && (mStreamVolumeAlias[streamType] == AudioSystem.STREAM_MUSIC) &&
- (device & mFixedVolumeDevices) != 0) {
- index = mStreamStates[streamType].getMaxIndex();
- }
- return (index + 5) / 10;
}
public int getMasterVolume() {
@@ -1817,7 +1830,7 @@
// on voice capable devices
if (isPlatformVoice() &&
mStreamVolumeAlias[streamType] == AudioSystem.STREAM_RING) {
- synchronized (mStreamStates[streamType]) {
+ synchronized (VolumeStreamState.class) {
Set set = mStreamStates[streamType].mIndex.entrySet();
Iterator i = set.iterator();
while (i.hasNext()) {
@@ -2316,16 +2329,15 @@
continue;
}
- synchronized (streamState) {
- streamState.readSettings();
-
+ streamState.readSettings();
+ synchronized (VolumeStreamState.class) {
// unmute stream that was muted but is not affect by mute anymore
- if (streamState.isMuted() && ((!isStreamAffectedByMute(streamType) &&
+ if (streamState.isMuted_syncVSS() && ((!isStreamAffectedByMute(streamType) &&
!isStreamMutedByRingerMode(streamType)) || mUseFixedVolume)) {
int size = streamState.mDeathHandlers.size();
for (int i = 0; i < size; i++) {
streamState.mDeathHandlers.get(i).mMuteCount = 1;
- streamState.mDeathHandlers.get(i).mute(false);
+ streamState.mDeathHandlers.get(i).mute_syncVSS(false);
}
}
}
@@ -3259,8 +3271,15 @@
} else if (existingMsgPolicy == SENDMSG_NOOP && handler.hasMessages(msg)) {
return;
}
-
- handler.sendMessageDelayed(handler.obtainMessage(msg, arg1, arg2, obj), delay);
+ synchronized (mLastDeviceConnectMsgTime) {
+ long time = SystemClock.uptimeMillis() + delay;
+ handler.sendMessageAtTime(handler.obtainMessage(msg, arg1, arg2, obj), time);
+ if (msg == MSG_SET_WIRED_DEVICE_CONNECTION_STATE ||
+ msg == MSG_SET_A2DP_SRC_CONNECTION_STATE ||
+ msg == MSG_SET_A2DP_SINK_CONNECTION_STATE) {
+ mLastDeviceConnectMsgTime = time;
+ }
+ }
}
boolean checkAudioSettingsPermission(String method) {
@@ -3339,6 +3358,12 @@
// Inner classes
///////////////////////////////////////////////////////////////////////////
+ // NOTE: Locking order for synchronized objects related to volume or ringer mode management:
+ // 1 mScoclient OR mSafeMediaVolumeState
+ // 2 mSetModeDeathHandlers
+ // 3 mSettingsLock
+ // 4 VolumeStreamState.class
+ // 5 mCameraSoundForced
public class VolumeStreamState {
private final int mStreamType;
@@ -3420,9 +3445,10 @@
}
}
- public void applyDeviceVolume(int device) {
+ // must be called while synchronized VolumeStreamState.class
+ public void applyDeviceVolume_syncVSS(int device) {
int index;
- if (isMuted()) {
+ if (isMuted_syncVSS()) {
index = 0;
} else if (((device & AudioSystem.DEVICE_OUT_ALL_A2DP) != 0 && mAvrcpAbsVolSupported)
|| ((device & mFullVolumeDevices) != 0)) {
@@ -3438,7 +3464,7 @@
// apply default volume first: by convention this will reset all
// devices volumes in audio policy manager to the supplied value
int index;
- if (isMuted()) {
+ if (isMuted_syncVSS()) {
index = 0;
} else {
index = (getIndex(AudioSystem.DEVICE_OUT_DEFAULT) + 5)/10;
@@ -3451,7 +3477,7 @@
Map.Entry entry = (Map.Entry)i.next();
int device = ((Integer)entry.getKey()).intValue();
if (device != AudioSystem.DEVICE_OUT_DEFAULT) {
- if (isMuted()) {
+ if (isMuted_syncVSS()) {
index = 0;
} else if (((device & AudioSystem.DEVICE_OUT_ALL_A2DP) != 0 &&
mAvrcpAbsVolSupported)
@@ -3563,12 +3589,12 @@
public void mute(IBinder cb, boolean state) {
synchronized (VolumeStreamState.class) {
- VolumeDeathHandler handler = getDeathHandler(cb, state);
+ VolumeDeathHandler handler = getDeathHandler_syncVSS(cb, state);
if (handler == null) {
Log.e(TAG, "Could not get client death handler for stream: "+mStreamType);
return;
}
- handler.mute(state);
+ handler.mute_syncVSS(state);
}
}
@@ -3590,7 +3616,7 @@
|| (((device & mFixedVolumeDevices) != 0) && index != 0)) {
entry.setValue(mIndexMax);
}
- applyDeviceVolume(device);
+ applyDeviceVolume_syncVSS(device);
}
}
}
@@ -3614,8 +3640,8 @@
mICallback = cb;
}
- // must be called while synchronized on parent VolumeStreamState
- public void mute(boolean state) {
+ // must be called while synchronized VolumeStreamState.class
+ public void mute_syncVSS(boolean state) {
boolean updateVolume = false;
if (state) {
if (mMuteCount == 0) {
@@ -3627,7 +3653,7 @@
}
VolumeStreamState.this.mDeathHandlers.add(this);
// If the stream is not yet muted by any client, set level to 0
- if (!VolumeStreamState.this.isMuted()) {
+ if (!VolumeStreamState.this.isMuted_syncVSS()) {
updateVolume = true;
}
} catch (RemoteException e) {
@@ -3651,7 +3677,7 @@
if (mICallback != null) {
mICallback.unlinkToDeath(this, 0);
}
- if (!VolumeStreamState.this.isMuted()) {
+ if (!VolumeStreamState.this.isMuted_syncVSS()) {
updateVolume = true;
}
}
@@ -3669,15 +3695,17 @@
public void binderDied() {
Log.w(TAG, "Volume service client died for stream: "+mStreamType);
- if (mMuteCount != 0) {
- // Reset all active mute requests from this client.
- mMuteCount = 1;
- mute(false);
+ synchronized (VolumeStreamState.class) {
+ if (mMuteCount != 0) {
+ // Reset all active mute requests from this client.
+ mMuteCount = 1;
+ mute_syncVSS(false);
+ }
}
}
}
- private synchronized int muteCount() {
+ private int muteCount() {
int count = 0;
int size = mDeathHandlers.size();
for (int i = 0; i < size; i++) {
@@ -3686,12 +3714,13 @@
return count;
}
- private synchronized boolean isMuted() {
+ // must be called while synchronized VolumeStreamState.class
+ private boolean isMuted_syncVSS() {
return muteCount() != 0;
}
- // only called by mute() which is already synchronized
- private VolumeDeathHandler getDeathHandler(IBinder cb, boolean state) {
+ // must be called while synchronized VolumeStreamState.class
+ private VolumeDeathHandler getDeathHandler_syncVSS(IBinder cb, boolean state) {
VolumeDeathHandler handler;
int size = mDeathHandlers.size();
for (int i = 0; i < size; i++) {
@@ -3768,25 +3797,26 @@
private void setDeviceVolume(VolumeStreamState streamState, int device) {
- // Apply volume
- streamState.applyDeviceVolume(device);
+ synchronized (VolumeStreamState.class) {
+ // Apply volume
+ streamState.applyDeviceVolume_syncVSS(device);
- // Apply change to all streams using this one as alias
- int numStreamTypes = AudioSystem.getNumStreamTypes();
- for (int streamType = numStreamTypes - 1; streamType >= 0; streamType--) {
- if (streamType != streamState.mStreamType &&
- mStreamVolumeAlias[streamType] == streamState.mStreamType) {
- // Make sure volume is also maxed out on A2DP device for aliased stream
- // that may have a different device selected
- int streamDevice = getDeviceForStream(streamType);
- if ((device != streamDevice) && mAvrcpAbsVolSupported &&
- ((device & AudioSystem.DEVICE_OUT_ALL_A2DP) != 0)) {
- mStreamStates[streamType].applyDeviceVolume(device);
+ // Apply change to all streams using this one as alias
+ int numStreamTypes = AudioSystem.getNumStreamTypes();
+ for (int streamType = numStreamTypes - 1; streamType >= 0; streamType--) {
+ if (streamType != streamState.mStreamType &&
+ mStreamVolumeAlias[streamType] == streamState.mStreamType) {
+ // Make sure volume is also maxed out on A2DP device for aliased stream
+ // that may have a different device selected
+ int streamDevice = getDeviceForStream(streamType);
+ if ((device != streamDevice) && mAvrcpAbsVolSupported &&
+ ((device & AudioSystem.DEVICE_OUT_ALL_A2DP) != 0)) {
+ mStreamStates[streamType].applyDeviceVolume_syncVSS(device);
+ }
+ mStreamStates[streamType].applyDeviceVolume_syncVSS(streamDevice);
}
- mStreamStates[streamType].applyDeviceVolume(streamDevice);
}
}
-
// Post a persist volume msg
sendMsg(mAudioHandler,
MSG_PERSIST_VOLUME,
@@ -4566,7 +4596,12 @@
if (mAudioHandler.hasMessages(MSG_SET_A2DP_SRC_CONNECTION_STATE) ||
mAudioHandler.hasMessages(MSG_SET_A2DP_SINK_CONNECTION_STATE) ||
mAudioHandler.hasMessages(MSG_SET_WIRED_DEVICE_CONNECTION_STATE)) {
- delay = 1000;
+ synchronized (mLastDeviceConnectMsgTime) {
+ long time = SystemClock.uptimeMillis();
+ if (mLastDeviceConnectMsgTime > time) {
+ delay = (int)(mLastDeviceConnectMsgTime - time);
+ }
+ }
}
return delay;
}
@@ -5027,42 +5062,45 @@
boolean cameraSoundForced = mContext.getResources().getBoolean(
com.android.internal.R.bool.config_camera_sound_forced);
synchronized (mSettingsLock) {
+ boolean cameraSoundForcedChanged = false;
synchronized (mCameraSoundForced) {
if (cameraSoundForced != mCameraSoundForced) {
mCameraSoundForced = cameraSoundForced;
-
- if (!isPlatformTelevision()) {
- VolumeStreamState s = mStreamStates[AudioSystem.STREAM_SYSTEM_ENFORCED];
- if (cameraSoundForced) {
- s.setAllIndexesToMax();
- mRingerModeAffectedStreams &=
- ~(1 << AudioSystem.STREAM_SYSTEM_ENFORCED);
- } else {
- s.setAllIndexes(mStreamStates[AudioSystem.STREAM_SYSTEM]);
- mRingerModeAffectedStreams |=
- (1 << AudioSystem.STREAM_SYSTEM_ENFORCED);
- }
- // take new state into account for streams muted by ringer mode
- setRingerModeInt(getRingerMode(), false);
- }
-
- sendMsg(mAudioHandler,
- MSG_SET_FORCE_USE,
- SENDMSG_QUEUE,
- AudioSystem.FOR_SYSTEM,
- cameraSoundForced ?
- AudioSystem.FORCE_SYSTEM_ENFORCED : AudioSystem.FORCE_NONE,
- null,
- 0);
-
- sendMsg(mAudioHandler,
- MSG_SET_ALL_VOLUMES,
- SENDMSG_QUEUE,
- 0,
- 0,
- mStreamStates[AudioSystem.STREAM_SYSTEM_ENFORCED], 0);
+ cameraSoundForcedChanged = true;
}
}
+ if (cameraSoundForcedChanged) {
+ if (!isPlatformTelevision()) {
+ VolumeStreamState s = mStreamStates[AudioSystem.STREAM_SYSTEM_ENFORCED];
+ if (cameraSoundForced) {
+ s.setAllIndexesToMax();
+ mRingerModeAffectedStreams &=
+ ~(1 << AudioSystem.STREAM_SYSTEM_ENFORCED);
+ } else {
+ s.setAllIndexes(mStreamStates[AudioSystem.STREAM_SYSTEM]);
+ mRingerModeAffectedStreams |=
+ (1 << AudioSystem.STREAM_SYSTEM_ENFORCED);
+ }
+ // take new state into account for streams muted by ringer mode
+ setRingerModeInt(getRingerMode(), false);
+ }
+
+ sendMsg(mAudioHandler,
+ MSG_SET_FORCE_USE,
+ SENDMSG_QUEUE,
+ AudioSystem.FOR_SYSTEM,
+ cameraSoundForced ?
+ AudioSystem.FORCE_SYSTEM_ENFORCED : AudioSystem.FORCE_NONE,
+ null,
+ 0);
+
+ sendMsg(mAudioHandler,
+ MSG_SET_ALL_VOLUMES,
+ SENDMSG_QUEUE,
+ 0,
+ 0,
+ mStreamStates[AudioSystem.STREAM_SYSTEM_ENFORCED], 0);
+ }
}
mVolumeController.setLayoutDirection(config.getLayoutDirection());
} catch (Exception e) {
@@ -5634,31 +5672,33 @@
//==========================================================================================
// Audio policy management
//==========================================================================================
- public boolean registerAudioPolicy(AudioPolicyConfig policyConfig, IBinder cb) {
+ public String registerAudioPolicy(AudioPolicyConfig policyConfig, IBinder cb) {
//Log.v(TAG, "registerAudioPolicy for " + cb + " got policy:" + policyConfig);
+ String regId = null;
boolean hasPermissionForPolicy =
(PackageManager.PERMISSION_GRANTED == mContext.checkCallingOrSelfPermission(
android.Manifest.permission.MODIFY_AUDIO_ROUTING));
if (!hasPermissionForPolicy) {
Slog.w(TAG, "Can't register audio policy for pid " + Binder.getCallingPid() + " / uid "
+ Binder.getCallingUid() + ", need MODIFY_AUDIO_ROUTING");
- return false;
+ return null;
}
synchronized (mAudioPolicies) {
- AudioPolicyProxy app = new AudioPolicyProxy(policyConfig, cb);
try {
+ AudioPolicyProxy app = new AudioPolicyProxy(policyConfig, cb);
cb.linkToDeath(app, 0/*flags*/);
+ regId = app.connectMixes();
mAudioPolicies.put(cb, app);
} catch (RemoteException e) {
// audio policy owner has already died!
Slog.w(TAG, "Audio policy registration failed, could not link to " + cb +
" binder death", e);
- return false;
+ return null;
}
}
- // TODO implement registration with native audio policy (including permission check)
- return true;
+ return regId;
}
+
public void unregisterAudioPolicyAsync(IBinder cb) {
synchronized (mAudioPolicies) {
AudioPolicyProxy app = mAudioPolicies.remove(cb);
@@ -5668,27 +5708,59 @@
} else {
cb.unlinkToDeath(app, 0/*flags*/);
}
+ app.disconnectMixes();
}
- // TODO implement registration with native audio policy
+ // TODO implement clearing mix attribute matching info in native audio policy
}
- public class AudioPolicyProxy implements IBinder.DeathRecipient {
+ /**
+ * This internal class inherits from AudioPolicyConfig which contains all the mixes and
+ * their configurations.
+ */
+ public class AudioPolicyProxy extends AudioPolicyConfig implements IBinder.DeathRecipient {
private static final String TAG = "AudioPolicyProxy";
AudioPolicyConfig mConfig;
IBinder mToken;
AudioPolicyProxy(AudioPolicyConfig config, IBinder token) {
- mConfig = config;
+ super(config);
+ setRegistration(new String(config.toString() + ":ap:" + mAudioPolicyCounter++));
mToken = token;
}
public void binderDied() {
synchronized (mAudioPolicies) {
- Log.v(TAG, "audio policy " + mToken + " died");
+ Log.i(TAG, "audio policy " + mToken + " died");
mAudioPolicies.remove(mToken);
+ disconnectMixes();
+ }
+ }
+
+ String connectMixes() {
+ updateMixes(AudioSystem.DEVICE_STATE_AVAILABLE);
+ return mRegistrationId;
+ }
+
+ void disconnectMixes() {
+ updateMixes(AudioSystem.DEVICE_STATE_UNAVAILABLE);
+ }
+
+ void updateMixes(int connectionState) {
+ for (AudioMix mix : mMixes) {
+ // TODO implement sending the mix attribute matching info to native audio policy
+ if (DEBUG_AP) {
+ Log.v(TAG, "AudioPolicyProxy connect mix state=" + connectionState
+ + " addr=" + mix.getRegistration()); }
+ AudioSystem.setDeviceConnectionState(AudioSystem.DEVICE_IN_REMOTE_SUBMIX,
+ connectionState,
+ mix.getRegistration());
+ AudioSystem.setDeviceConnectionState(AudioSystem.DEVICE_OUT_REMOTE_SUBMIX,
+ connectionState,
+ mix.getRegistration());
}
}
};
private HashMap<IBinder, AudioPolicyProxy> mAudioPolicies =
new HashMap<IBinder, AudioPolicyProxy>();
+ private int mAudioPolicyCounter = 0; // always accessed synchronized on mAudioPolicies
}
diff --git a/media/java/android/media/IAudioService.aidl b/media/java/android/media/IAudioService.aidl
index 2d8042c..317cc21 100644
--- a/media/java/android/media/IAudioService.aidl
+++ b/media/java/android/media/IAudioService.aidl
@@ -207,6 +207,6 @@
boolean isHdmiSystemAudioSupported();
- boolean registerAudioPolicy(in AudioPolicyConfig policyConfig, IBinder cb);
+ String registerAudioPolicy(in AudioPolicyConfig policyConfig, IBinder cb);
oneway void unregisterAudioPolicyAsync(in IBinder cb);
}
diff --git a/media/java/android/media/MediaDrm.java b/media/java/android/media/MediaDrm.java
index 3b8cb19..7959841 100644
--- a/media/java/android/media/MediaDrm.java
+++ b/media/java/android/media/MediaDrm.java
@@ -572,6 +572,14 @@
*/
public native List<byte[]> getSecureStops();
+ /**
+ * Access secure stop by secure stop ID.
+ *
+ * @param ssid - The secure stop ID provided by the license server.
+ *
+ * @hide - not part of the public API at this time
+ */
+ public native byte[] getSecureStop(byte[] ssid);
/**
* Process the SecureStop server response message ssRelease. After authenticating
@@ -581,6 +589,12 @@
*/
public native void releaseSecureStops(byte[] ssRelease);
+ /**
+ * Remove all secure stops without requiring interaction with the server.
+ *
+ * @hide - not part of the public API at this time
+ */
+ public native void releaseAllSecureStops();
/**
* String property name: identifies the maker of the DRM engine plugin
diff --git a/media/java/android/media/audiopolicy/AudioMix.java b/media/java/android/media/audiopolicy/AudioMix.java
index f7967f1..bb52682 100644
--- a/media/java/android/media/audiopolicy/AudioMix.java
+++ b/media/java/android/media/audiopolicy/AudioMix.java
@@ -24,13 +24,14 @@
import java.lang.annotation.RetentionPolicy;
/**
- * @hide CANDIDATE FOR PUBLIC API
+ * @hide
*/
public class AudioMix {
private AudioMixingRule mRule;
private AudioFormat mFormat;
private int mRouteFlags;
+ private String mRegistrationId;
/**
* All parameters are guaranteed valid through the Builder.
@@ -39,6 +40,7 @@
mRule = rule;
mFormat = format;
mRouteFlags = routeFlags;
+ mRegistrationId = null;
}
/**
@@ -65,6 +67,15 @@
return mRule;
}
+ void setRegistration(String regId) {
+ mRegistrationId = regId;
+ }
+
+ /** @hide */
+ public String getRegistration() {
+ return mRegistrationId;
+ }
+
/** @hide */
@IntDef(flag = true,
value = { ROUTE_FLAG_RENDER, ROUTE_FLAG_LOOP_BACK } )
diff --git a/media/java/android/media/audiopolicy/AudioMixingRule.java b/media/java/android/media/audiopolicy/AudioMixingRule.java
index ced7881..2e06a80 100644
--- a/media/java/android/media/audiopolicy/AudioMixingRule.java
+++ b/media/java/android/media/audiopolicy/AudioMixingRule.java
@@ -23,7 +23,7 @@
/**
- * @hide CANDIDATE FOR PUBLIC API
+ * @hide
*
* Here's an example of creating a mixing rule for all media playback:
* <pre>
diff --git a/media/java/android/media/audiopolicy/AudioPolicy.java b/media/java/android/media/audiopolicy/AudioPolicy.java
index 314eb88..255d828 100644
--- a/media/java/android/media/audiopolicy/AudioPolicy.java
+++ b/media/java/android/media/audiopolicy/AudioPolicy.java
@@ -17,18 +17,26 @@
package android.media.audiopolicy;
import android.annotation.IntDef;
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.media.AudioAttributes;
import android.media.AudioFormat;
import android.media.AudioManager;
+import android.media.AudioRecord;
+import android.media.AudioSystem;
+import android.media.AudioTrack;
+import android.media.MediaRecorder;
import android.os.Binder;
import android.os.IBinder;
import android.util.Log;
+import android.util.Slog;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
/**
- * @hide CANDIDATE FOR PUBLIC API
+ * @hide
* AudioPolicy provides access to the management of audio routing and audio focus.
*/
public class AudioPolicy {
@@ -49,11 +57,13 @@
public static final int POLICY_STATUS_REGISTERED = 2;
private int mStatus;
- private AudioPolicyStatusListener mStatusListener = null;
+ private String mRegistrationId;
+ private AudioPolicyStatusListener mStatusListener;
private final IBinder mToken = new Binder();
/** @hide */
public IBinder token() { return mToken; }
+ private Context mContext;
private AudioPolicyConfig mConfig;
/** @hide */
@@ -62,13 +72,14 @@
/**
* The parameter is guaranteed non-null through the Builder
*/
- private AudioPolicy(AudioPolicyConfig config) {
+ private AudioPolicy(AudioPolicyConfig config, Context context) {
mConfig = config;
if (mConfig.mMixes.isEmpty()) {
mStatus = POLICY_STATUS_INVALID;
} else {
mStatus = POLICY_STATUS_UNREGISTERED;
}
+ mContext = context;
}
/**
@@ -76,12 +87,15 @@
*/
public static class Builder {
private ArrayList<AudioMix> mMixes;
+ private Context mContext;
/**
* Constructs a new Builder with no audio mixes.
+ * @param context the context for the policy
*/
- public Builder() {
+ public Builder(Context context) {
mMixes = new ArrayList<AudioMix>();
+ mContext = context;
}
/**
@@ -99,10 +113,115 @@
}
public AudioPolicy build() {
- return new AudioPolicy(new AudioPolicyConfig(mMixes));
+ return new AudioPolicy(new AudioPolicyConfig(mMixes), mContext);
}
}
+ /** @hide */
+ public void setRegistration(String regId) {
+ mRegistrationId = regId;
+ mConfig.setRegistration(regId);
+ }
+
+ private boolean policyReadyToUse() {
+ if (mContext == null) {
+ Log.e(TAG, "Cannot use AudioPolicy without context");
+ return false;
+ }
+ if (mRegistrationId == null) {
+ Log.e(TAG, "Cannot use unregistered AudioPolicy");
+ return false;
+ }
+ if (!(PackageManager.PERMISSION_GRANTED == mContext.checkCallingOrSelfPermission(
+ android.Manifest.permission.MODIFY_AUDIO_ROUTING))) {
+ Slog.w(TAG, "Cannot use AudioPolicy for pid " + Binder.getCallingPid() + " / uid "
+ + Binder.getCallingUid() + ", needs MODIFY_AUDIO_ROUTING");
+ return false;
+ }
+ return true;
+ }
+
+ private void checkMixReadyToUse(AudioMix mix, boolean forTrack)
+ throws IllegalArgumentException{
+ if (mix == null) {
+ String msg = forTrack ? "Invalid null AudioMix for AudioTrack creation"
+ : "Invalid null AudioMix for AudioRecord creation";
+ throw new IllegalArgumentException(msg);
+ }
+ if (!mConfig.mMixes.contains(mix)) {
+ throw new IllegalArgumentException("Invalid mix: not part of this policy");
+ }
+ if ((mix.getRouteFlags() & AudioMix.ROUTE_FLAG_LOOP_BACK) != AudioMix.ROUTE_FLAG_LOOP_BACK)
+ {
+ throw new IllegalArgumentException("Invalid AudioMix: not defined for loop back");
+ }
+ }
+
+ /**
+ * @hide
+ * Create an {@link AudioRecord} instance that is associated with the given {@link AudioMix}.
+ * Audio buffers recorded through the created instance will contain the mix of the audio
+ * streams that fed the given mixer.
+ * @param mix a non-null {@link AudioMix} instance whose routing flags was defined with
+ * {@link AudioMix#ROUTE_FLAG_LOOP_BACK}, previously added to this policy.
+ * @return a new {@link AudioRecord} instance whose data format is the one defined in the
+ * {@link AudioMix}, or null if this policy was not successfully registered
+ * with {@link AudioManager#registerAudioPolicy(AudioPolicy)}.
+ * @throws IllegalArgumentException
+ */
+ public AudioRecord createAudioRecordSink(AudioMix mix) throws IllegalArgumentException {
+ if (!policyReadyToUse()) {
+ Log.e(TAG, "Cannot create AudioRecord sink for AudioMix");
+ return null;
+ }
+ checkMixReadyToUse(mix, false/*not for an AudioTrack*/);
+ // create the AudioRecord, configured for loop back, using the same format as the mix
+ AudioRecord ar = new AudioRecord(
+ new AudioAttributes.Builder()
+ .setInternalCapturePreset(MediaRecorder.AudioSource.REMOTE_SUBMIX)
+ .addTag(mix.getRegistration())
+ .build(),
+ mix.getFormat(),
+ AudioRecord.getMinBufferSize(mix.getFormat().getSampleRate(),
+ // using stereo for buffer size to avoid the current poor support for masks
+ AudioFormat.CHANNEL_IN_STEREO, mix.getFormat().getEncoding()),
+ AudioManager.AUDIO_SESSION_ID_GENERATE
+ );
+ return ar;
+ }
+
+ /**
+ * @hide
+ * Create an {@link AudioTrack} instance that is associated with the given {@link AudioMix}.
+ * Audio buffers played through the created instance will be sent to the given mix
+ * to be recorded through the recording APIs.
+ * @param mix a non-null {@link AudioMix} instance whose routing flags was defined with
+ * {@link AudioMix#ROUTE_FLAG_LOOP_BACK}, previously added to this policy.
+ * @returna new {@link AudioTrack} instance whose data format is the one defined in the
+ * {@link AudioMix}, or null if this policy was not successfully registered
+ * with {@link AudioManager#registerAudioPolicy(AudioPolicy)}.
+ * @throws IllegalArgumentException
+ */
+ public AudioTrack createAudioTrackSource(AudioMix mix) throws IllegalArgumentException {
+ if (!policyReadyToUse()) {
+ Log.e(TAG, "Cannot create AudioTrack source for AudioMix");
+ return null;
+ }
+ checkMixReadyToUse(mix, true/*for an AudioTrack*/);
+ // create the AudioTrack, configured for loop back, using the same format as the mix
+ AudioTrack at = new AudioTrack(
+ new AudioAttributes.Builder()
+ .setUsage(AudioAttributes.USAGE_VIRTUAL_SOURCE)
+ .addTag(mix.getRegistration())
+ .build(),
+ mix.getFormat(),
+ AudioTrack.getMinBufferSize(mix.getFormat().getSampleRate(),
+ mix.getFormat().getChannelMask(), mix.getFormat().getEncoding()),
+ AudioTrack.MODE_STREAM,
+ AudioManager.AUDIO_SESSION_ID_GENERATE
+ );
+ return at;
+ }
public int getStatus() {
return mStatus;
@@ -118,10 +237,9 @@
}
/** @hide */
- @Override
- public String toString () {
+ public String toLogFriendlyString() {
String textDump = new String("android.media.audiopolicy.AudioPolicy:\n");
- textDump += "config=" + mConfig.toString();
+ textDump += "config=" + mConfig.toLogFriendlyString();
return (textDump);
}
diff --git a/media/java/android/media/audiopolicy/AudioPolicyConfig.java b/media/java/android/media/audiopolicy/AudioPolicyConfig.java
index 2fc6d58..a9a4175 100644
--- a/media/java/android/media/audiopolicy/AudioPolicyConfig.java
+++ b/media/java/android/media/audiopolicy/AudioPolicyConfig.java
@@ -36,7 +36,13 @@
private static final String TAG = "AudioPolicyConfig";
- ArrayList<AudioMix> mMixes;
+ protected ArrayList<AudioMix> mMixes;
+
+ protected String mRegistrationId = null;
+
+ protected AudioPolicyConfig(AudioPolicyConfig conf) {
+ mMixes = conf.mMixes;
+ }
AudioPolicyConfig(ArrayList<AudioMix> mixes) {
mMixes = mixes;
@@ -117,7 +123,6 @@
}
}
- /** @hide */
public static final Parcelable.Creator<AudioPolicyConfig> CREATOR
= new Parcelable.Creator<AudioPolicyConfig>() {
/**
@@ -133,9 +138,7 @@
}
};
- /** @hide */
- @Override
- public String toString () {
+ public String toLogFriendlyString () {
String textDump = new String("android.media.audiopolicy.AudioPolicyConfig:\n");
textDump += mMixes.size() + " AudioMix:\n";
for(AudioMix mix : mMixes) {
@@ -166,4 +169,13 @@
}
return textDump;
}
+
+ public void setRegistration(String regId) {
+ mRegistrationId = regId;
+ int mixIndex = 0;
+ for (AudioMix mix : mMixes) {
+ mix.setRegistration(mRegistrationId + "mix:" + mixIndex++);
+ }
+ }
+
}
diff --git a/media/java/android/media/session/MediaSession.java b/media/java/android/media/session/MediaSession.java
index 86da80a..973527f 100644
--- a/media/java/android/media/session/MediaSession.java
+++ b/media/java/android/media/session/MediaSession.java
@@ -286,7 +286,9 @@
if (volumeProvider == null) {
throw new IllegalArgumentException("volumeProvider may not be null!");
}
- mVolumeProvider = volumeProvider;
+ synchronized (mLock) {
+ mVolumeProvider = volumeProvider;
+ }
volumeProvider.setCallback(new VolumeProvider.Callback() {
@Override
public void onVolumeChanged(VolumeProvider volumeProvider) {
@@ -449,6 +451,27 @@
}
/**
+ * Set the style of rating used by this session. Apps trying to set the
+ * rating should use this style. Must be one of the following:
+ * <ul>
+ * <li>{@link Rating#RATING_NONE}</li>
+ * <li>{@link Rating#RATING_3_STARS}</li>
+ * <li>{@link Rating#RATING_4_STARS}</li>
+ * <li>{@link Rating#RATING_5_STARS}</li>
+ * <li>{@link Rating#RATING_HEART}</li>
+ * <li>{@link Rating#RATING_PERCENTAGE}</li>
+ * <li>{@link Rating#RATING_THUMB_UP_DOWN}</li>
+ * </ul>
+ */
+ public void setRatingType(int type) {
+ try {
+ mBinder.setRatingType(type);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Error in setRatingType.", e);
+ }
+ }
+
+ /**
* Set some extras that can be associated with the {@link MediaSession}. No assumptions should
* be made as to how a {@link MediaController} will handle these extras.
* Keys should be fully qualified (e.g. com.example.MY_EXTRA) to avoid conflicts.
@@ -470,9 +493,11 @@
* @hide
*/
public void notifyRemoteVolumeChanged(VolumeProvider provider) {
- if (provider == null || provider != mVolumeProvider) {
- Log.w(TAG, "Received update from stale volume provider");
- return;
+ synchronized (mLock) {
+ if (provider == null || provider != mVolumeProvider) {
+ Log.w(TAG, "Received update from stale volume provider");
+ return;
+ }
}
try {
mBinder.setCurrentVolume(provider.getCurrentVolume());
@@ -537,6 +562,14 @@
postToCallback(CallbackMessageHandler.MSG_MEDIA_BUTTON, mediaButtonIntent);
}
+ private void dispatchAdjustVolume(int direction) {
+ postToCallback(CallbackMessageHandler.MSG_ADJUST_VOLUME, direction);
+ }
+
+ private void dispatchSetVolumeTo(int volume) {
+ postToCallback(CallbackMessageHandler.MSG_SET_VOLUME, volume);
+ }
+
private void postToCallback(int what) {
postToCallback(what, null);
}
@@ -988,9 +1021,7 @@
public void onAdjustVolume(int direction) {
MediaSession session = mMediaSession.get();
if (session != null) {
- if (session.mVolumeProvider != null) {
- session.mVolumeProvider.onAdjustVolume(direction);
- }
+ session.dispatchAdjustVolume(direction);
}
}
@@ -998,9 +1029,7 @@
public void onSetVolumeTo(int value) {
MediaSession session = mMediaSession.get();
if (session != null) {
- if (session.mVolumeProvider != null) {
- session.mVolumeProvider.onSetVolumeTo(value);
- }
+ session.dispatchSetVolumeTo(value);
}
}
@@ -1117,6 +1146,8 @@
private static final int MSG_CUSTOM_ACTION = 13;
private static final int MSG_MEDIA_BUTTON = 14;
private static final int MSG_COMMAND = 15;
+ private static final int MSG_ADJUST_VOLUME = 16;
+ private static final int MSG_SET_VOLUME = 17;
private MediaSession.Callback mCallback;
@@ -1145,6 +1176,7 @@
@Override
public void handleMessage(Message msg) {
+ VolumeProvider vp;
switch (msg.what) {
case MSG_PLAY:
mCallback.onPlay();
@@ -1192,6 +1224,22 @@
Command cmd = (Command) msg.obj;
mCallback.onCommand(cmd.command, cmd.extras, cmd.stub);
break;
+ case MSG_ADJUST_VOLUME:
+ synchronized (mLock) {
+ vp = mVolumeProvider;
+ }
+ if (vp != null) {
+ vp.onAdjustVolume((int) msg.obj);
+ }
+ break;
+ case MSG_SET_VOLUME:
+ synchronized (mLock) {
+ vp = mVolumeProvider;
+ }
+ if (vp != null) {
+ vp.onSetVolumeTo((int) msg.obj);
+ }
+ break;
}
}
}
diff --git a/media/java/android/media/session/PlaybackState.java b/media/java/android/media/session/PlaybackState.java
index 267d1ff..54d0acd 100644
--- a/media/java/android/media/session/PlaybackState.java
+++ b/media/java/android/media/session/PlaybackState.java
@@ -16,6 +16,7 @@
package android.media.session;
import android.annotation.DrawableRes;
+import android.annotation.Nullable;
import android.media.RemoteControlClient;
import android.os.Bundle;
import android.os.Parcel;
@@ -232,11 +233,12 @@
private final CharSequence mErrorMessage;
private final long mUpdateTime;
private final long mActiveItemId;
+ private final Bundle mExtras;
private PlaybackState(int state, long position, long updateTime, float speed,
long bufferedPosition, long transportControls,
List<PlaybackState.CustomAction> customActions, long activeItemId,
- CharSequence error) {
+ CharSequence error, Bundle extras) {
mState = state;
mPosition = position;
mSpeed = speed;
@@ -246,6 +248,7 @@
mCustomActions = new ArrayList<>(customActions);
mActiveItemId = activeItemId;
mErrorMessage = error;
+ mExtras = extras;
}
private PlaybackState(Parcel in) {
@@ -258,7 +261,7 @@
mCustomActions = in.createTypedArrayList(CustomAction.CREATOR);
mActiveItemId = in.readLong();
mErrorMessage = in.readCharSequence();
-
+ mExtras = in.readBundle();
}
@Override
@@ -293,6 +296,7 @@
dest.writeTypedList(mCustomActions);
dest.writeLong(mActiveItemId);
dest.writeCharSequence(mErrorMessage);
+ dest.writeBundle(mExtras);
}
/**
@@ -306,6 +310,7 @@
* <li> {@link PlaybackState#STATE_REWINDING}</li>
* <li> {@link PlaybackState#STATE_BUFFERING}</li>
* <li> {@link PlaybackState#STATE_ERROR}</li>
+ * </ul>
*/
public int getState() {
return mState;
@@ -394,6 +399,15 @@
}
/**
+ * Get any custom extras that were set on this playback state.
+ *
+ * @return The extras for this state or null.
+ */
+ public @Nullable Bundle getExtras() {
+ return mExtras;
+ }
+
+ /**
* Get the {@link PlaybackState} state for the given
* {@link RemoteControlClient} state.
*
@@ -737,6 +751,7 @@
private CharSequence mErrorMessage;
private long mUpdateTime;
private long mActiveItemId = MediaSession.QueueItem.UNKNOWN_ID;
+ private Bundle mExtras;
/**
* Creates an initially empty state builder.
@@ -765,6 +780,7 @@
mErrorMessage = from.mErrorMessage;
mUpdateTime = from.mUpdateTime;
mActiveItemId = from.mActiveItemId;
+ mExtras = from.mExtras;
}
/**
@@ -947,13 +963,25 @@
}
/**
- * Build and return the {@link PlaybackState} instance with these values.
+ * Set any custom extras to be included with the playback state.
+ *
+ * @param extras The extras to include.
+ * @return this
+ */
+ public Builder setExtras(Bundle extras) {
+ mExtras = extras;
+ return this;
+ }
+
+ /**
+ * Build and return the {@link PlaybackState} instance with these
+ * values.
*
* @return A new state instance.
*/
public PlaybackState build() {
return new PlaybackState(mState, mPosition, mUpdateTime, mSpeed, mBufferedPosition,
- mActions, mCustomActions, mActiveItemId, mErrorMessage);
+ mActions, mCustomActions, mActiveItemId, mErrorMessage, mExtras);
}
}
}
diff --git a/media/java/android/media/tv/TvContract.java b/media/java/android/media/tv/TvContract.java
index 691df77..5b92266 100644
--- a/media/java/android/media/tv/TvContract.java
+++ b/media/java/android/media/tv/TvContract.java
@@ -856,6 +856,9 @@
/**
* The start time of this TV program, in milliseconds since the epoch.
* <p>
+ * The value should be equal to or larger than {@link #COLUMN_END_TIME_UTC_MILLIS} of the
+ * previous program in the same channel.
+ * </p><p>
* Type: INTEGER (long)
* </p>
*/
@@ -864,6 +867,9 @@
/**
* The end time of this TV program, in milliseconds since the epoch.
* <p>
+ * The value should be equal to or less than {@link #COLUMN_START_TIME_UTC_MILLIS} of the
+ * next program in the same channel.
+ * </p><p>
* Type: INTEGER (long)
* </p>
*/
diff --git a/media/java/android/media/tv/TvInputService.java b/media/java/android/media/tv/TvInputService.java
index 0ca5810..93cca2f 100644
--- a/media/java/android/media/tv/TvInputService.java
+++ b/media/java/android/media/tv/TvInputService.java
@@ -159,15 +159,6 @@
}
/**
- * Get the number of callbacks that are registered.
- * @hide
- */
- @VisibleForTesting
- public final int getRegisteredCallbackCount() {
- return mCallbacks.getRegisteredCallbackCount();
- }
-
- /**
* Returns a concrete implementation of {@link Session}.
* <p>
* May return {@code null} if this TV input service fails to create a session for some reason.
@@ -550,13 +541,14 @@
* @param left Left position in pixels, relative to the overlay view.
* @param top Top position in pixels, relative to the overlay view.
* @param right Right position in pixels, relative to the overlay view.
- * @param bottm Bottom position in pixels, relative to the overlay view.
+ * @param bottom Bottom position in pixels, relative to the overlay view.
* @see #onOverlayViewSizeChanged
* @hide
*/
@SystemApi
- public void layoutSurface(final int left, final int top, final int right, final int bottm) {
- if (left > right || top > bottm) {
+ public void layoutSurface(final int left, final int top, final int right,
+ final int bottom) {
+ if (left > right || top > bottom) {
throw new IllegalArgumentException("Invalid parameter");
}
executeOrPostRunnable(new Runnable() {
@@ -564,8 +556,8 @@
public void run() {
try {
if (DEBUG) Log.d(TAG, "layoutSurface (l=" + left + ", t=" + top + ", r="
- + right + ", b=" + bottm + ",)");
- mSessionCallback.onLayoutSurface(left, top, right, bottm);
+ + right + ", b=" + bottom + ",)");
+ mSessionCallback.onLayoutSurface(left, top, right, bottom);
} catch (RemoteException e) {
Log.w(TAG, "error in layoutSurface");
}
diff --git a/media/java/android/service/media/MediaBrowserService.java b/media/java/android/service/media/MediaBrowserService.java
index d50be42..0754fd4 100644
--- a/media/java/android/service/media/MediaBrowserService.java
+++ b/media/java/android/service/media/MediaBrowserService.java
@@ -101,7 +101,6 @@
* be thrown.
*
* @see MediaBrowserService#onLoadChildren
- * @see MediaBrowserService#onLoadIcon
*/
public class Result<T> {
private Object mDebug;
diff --git a/media/jni/android_media_MediaDrm.cpp b/media/jni/android_media_MediaDrm.cpp
index 0fed27e..8e07ec0 100644
--- a/media/jni/android_media_MediaDrm.cpp
+++ b/media/jni/android_media_MediaDrm.cpp
@@ -1003,6 +1003,27 @@
return ListOfVectorsToArrayListOfByteArray(env, secureStops);
}
+static jbyteArray android_media_MediaDrm_getSecureStop(
+ JNIEnv *env, jobject thiz, jbyteArray ssid) {
+ sp<IDrm> drm = GetDrm(env, thiz);
+
+ if (drm == NULL) {
+ jniThrowException(env, "java/lang/IllegalStateException",
+ "MediaDrm obj is null");
+ return NULL;
+ }
+
+ Vector<uint8_t> secureStop;
+
+ status_t err = drm->getSecureStop(JByteArrayToVector(env, ssid), secureStop);
+
+ if (throwExceptionAsNecessary(env, err, "Failed to get secure stop")) {
+ return NULL;
+ }
+
+ return VectorToJByteArray(env, secureStop);
+}
+
static void android_media_MediaDrm_releaseSecureStops(
JNIEnv *env, jobject thiz, jbyteArray jssRelease) {
sp<IDrm> drm = GetDrm(env, thiz);
@@ -1020,6 +1041,21 @@
throwExceptionAsNecessary(env, err, "Failed to release secure stops");
}
+static void android_media_MediaDrm_releaseAllSecureStops(
+ JNIEnv *env, jobject thiz) {
+ sp<IDrm> drm = GetDrm(env, thiz);
+
+ if (drm == NULL) {
+ jniThrowException(env, "java/lang/IllegalStateException",
+ "MediaDrm obj is null");
+ return;
+ }
+
+ status_t err = drm->releaseAllSecureStops();
+
+ throwExceptionAsNecessary(env, err, "Failed to release all secure stops");
+}
+
static jstring android_media_MediaDrm_getPropertyString(
JNIEnv *env, jobject thiz, jstring jname) {
sp<IDrm> drm = GetDrm(env, thiz);
@@ -1384,9 +1420,15 @@
{ "getSecureStops", "()Ljava/util/List;",
(void *)android_media_MediaDrm_getSecureStops },
+ { "getSecureStop", "([B)[B",
+ (void *)android_media_MediaDrm_getSecureStop },
+
{ "releaseSecureStops", "([B)V",
(void *)android_media_MediaDrm_releaseSecureStops },
+ { "releaseAllSecureStops", "()V",
+ (void *)android_media_MediaDrm_releaseAllSecureStops },
+
{ "getPropertyString", "(Ljava/lang/String;)Ljava/lang/String;",
(void *)android_media_MediaDrm_getPropertyString },
diff --git a/media/jni/audioeffect/android_media_AudioEffect.cpp b/media/jni/audioeffect/android_media_AudioEffect.cpp
index c9cefbd..c364d469 100644
--- a/media/jni/audioeffect/android_media_AudioEffect.cpp
+++ b/media/jni/audioeffect/android_media_AudioEffect.cpp
@@ -803,28 +803,12 @@
android_media_AudioEffect_native_queryPreProcessings(JNIEnv *env, jclass clazz __unused,
jint audioSession)
{
- // kDefaultNumEffects is a "reasonable" value ensuring that only one query will be enough on
- // most devices to get all active audio pre processing on a given session.
- static const uint32_t kDefaultNumEffects = 5;
-
- effect_descriptor_t *descriptors = new effect_descriptor_t[kDefaultNumEffects];
- uint32_t numEffects = kDefaultNumEffects;
+ effect_descriptor_t *descriptors = new effect_descriptor_t[AudioEffect::kMaxPreProcessing];
+ uint32_t numEffects = AudioEffect::kMaxPreProcessing;
status_t status = AudioEffect::queryDefaultPreProcessing(audioSession,
descriptors,
&numEffects);
- if ((status != NO_ERROR && status != NO_MEMORY) ||
- numEffects == 0) {
- delete[] descriptors;
- return NULL;
- }
- if (status == NO_MEMORY) {
- delete [] descriptors;
- descriptors = new effect_descriptor_t[numEffects];
- status = AudioEffect::queryDefaultPreProcessing(audioSession,
- descriptors,
- &numEffects);
- }
if (status != NO_ERROR || numEffects == 0) {
delete[] descriptors;
return NULL;
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java
index 1c6dc2c..aa5819e 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java
@@ -518,7 +518,7 @@
* Determine whether the device is plugged in (USB, power, or wireless).
* @return true if the device is plugged in.
*/
- boolean isPluggedIn() {
+ public boolean isPluggedIn() {
return plugged == BatteryManager.BATTERY_PLUGGED_AC
|| plugged == BatteryManager.BATTERY_PLUGGED_USB
|| plugged == BatteryManager.BATTERY_PLUGGED_WIRELESS;
diff --git a/packages/Keyguard/test/SampleTrustAgent/src/com/android/trustagent/test/SampleTrustAgent.java b/packages/Keyguard/test/SampleTrustAgent/src/com/android/trustagent/test/SampleTrustAgent.java
index c650a0f..09c7165 100644
--- a/packages/Keyguard/test/SampleTrustAgent/src/com/android/trustagent/test/SampleTrustAgent.java
+++ b/packages/Keyguard/test/SampleTrustAgent/src/com/android/trustagent/test/SampleTrustAgent.java
@@ -21,7 +21,7 @@
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
-import android.os.Bundle;
+import android.os.PersistableBundle;
import android.preference.PreferenceManager;
import android.service.trust.TrustAgentService;
import android.support.v4.content.LocalBroadcastManager;
@@ -90,8 +90,15 @@
}
@Override
- public boolean onSetTrustAgentFeaturesEnabled(Bundle options) {
- Log.v(TAG, "Policy options received: " + options.getStringArrayList(KEY_FEATURES));
+ public boolean onConfigure(Configuration config) {
+ if (config != null && config.options != null) {
+ for (int i = 0; i < config.options.size(); i++) {
+ PersistableBundle options = config.options.get(i);
+ Log.v(TAG, "Policy options received: " + options.toString());
+ }
+ } else {
+ Log.w(TAG, "onConfigure() called with no options");
+ }
// TODO: Handle options
return true; // inform DPM that we support it
}
diff --git a/packages/PrintSpooler/src/com/android/printspooler/model/OpenDocumentCallback.java b/packages/PrintSpooler/src/com/android/printspooler/model/OpenDocumentCallback.java
new file mode 100644
index 0000000..50f424a
--- /dev/null
+++ b/packages/PrintSpooler/src/com/android/printspooler/model/OpenDocumentCallback.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.printspooler.model;
+
+/**
+ * Callbacks interface for opening a file.
+ */
+public interface OpenDocumentCallback {
+ public static final int ERROR_MALFORMED_PDF_FILE = -1;
+ public static final int ERROR_SECURE_PDF_FILE = -2;
+
+ /**
+ * Called after the file is opened.
+ */
+ public void onSuccess();
+
+ /**
+ * Called after opening the file failed.
+ *
+ * @param error The error.
+ */
+ public void onFailure(int error);
+}
diff --git a/packages/PrintSpooler/src/com/android/printspooler/model/PageContentRepository.java b/packages/PrintSpooler/src/com/android/printspooler/model/PageContentRepository.java
index 35930cd..882b364 100644
--- a/packages/PrintSpooler/src/com/android/printspooler/model/PageContentRepository.java
+++ b/packages/PrintSpooler/src/com/android/printspooler/model/PageContentRepository.java
@@ -78,13 +78,8 @@
public void onPageContentAvailable(BitmapDrawable content);
}
- public interface OnMalformedPdfFileListener {
- public void onMalformedPdfFile();
- }
-
- public PageContentRepository(Context context,
- OnMalformedPdfFileListener malformedPdfFileListener) {
- mRenderer = new AsyncRenderer(context, malformedPdfFileListener);
+ public PageContentRepository(Context context) {
+ mRenderer = new AsyncRenderer(context);
mState = STATE_CLOSED;
if (DEBUG) {
Log.i(LOG_TAG, "STATE_CLOSED");
@@ -92,7 +87,7 @@
mCloseGuard.open("destroy");
}
- public void open(ParcelFileDescriptor source, final Runnable callback) {
+ public void open(ParcelFileDescriptor source, final OpenDocumentCallback callback) {
throwIfNotClosed();
mState = STATE_OPENED;
if (DEBUG) {
@@ -412,8 +407,6 @@
private final ArrayMap<Integer, RenderPageTask> mPageToRenderTaskMap = new ArrayMap<>();
- private final OnMalformedPdfFileListener mOnMalformedPdfFileListener;
-
private int mPageCount = PrintDocumentInfo.PAGE_COUNT_UNKNOWN;
@GuardedBy("mLock")
@@ -422,9 +415,8 @@
private boolean mBoundToService;
private boolean mDestroyed;
- public AsyncRenderer(Context context, OnMalformedPdfFileListener malformedPdfFileListener) {
+ public AsyncRenderer(Context context) {
mContext = context;
- mOnMalformedPdfFileListener = malformedPdfFileListener;
ActivityManager activityManager = (ActivityManager)
mContext.getSystemService(Context.ACTIVITY_SERVICE);
@@ -447,7 +439,7 @@
}
}
- public void open(final ParcelFileDescriptor source, final Runnable callback) {
+ public void open(final ParcelFileDescriptor source, final OpenDocumentCallback callback) {
// Opening a new document invalidates the cache as it has pages
// from the last document. We keep the cache even when the document
// is closed to show pages while the other side is writing the new
@@ -483,7 +475,7 @@
return mRenderer.openDocument(source);
} catch (RemoteException re) {
Log.e(LOG_TAG, "Cannot open PDF document");
- return PdfManipulationService.MALFORMED_PDF_FILE_ERROR;
+ return PdfManipulationService.ERROR_MALFORMED_PDF_FILE;
} finally {
// Close the fd as we passed it to another process
// which took ownership.
@@ -494,14 +486,25 @@
@Override
public void onPostExecute(Integer pageCount) {
- if (pageCount == PdfManipulationService.MALFORMED_PDF_FILE_ERROR) {
- mOnMalformedPdfFileListener.onMalformedPdfFile();
- mPageCount = PrintDocumentInfo.PAGE_COUNT_UNKNOWN;
- } else {
- mPageCount = pageCount;
- }
- if (callback != null) {
- callback.run();
+ switch (pageCount) {
+ case PdfManipulationService.ERROR_MALFORMED_PDF_FILE: {
+ mPageCount = PrintDocumentInfo.PAGE_COUNT_UNKNOWN;
+ if (callback != null) {
+ callback.onFailure(OpenDocumentCallback.ERROR_MALFORMED_PDF_FILE);
+ }
+ } break;
+ case PdfManipulationService.ERROR_SECURE_PDF_FILE: {
+ mPageCount = PrintDocumentInfo.PAGE_COUNT_UNKNOWN;
+ if (callback != null) {
+ callback.onFailure(OpenDocumentCallback.ERROR_SECURE_PDF_FILE);
+ }
+ } break;
+ default: {
+ mPageCount = pageCount;
+ if (callback != null) {
+ callback.onSuccess();
+ }
+ } break;
}
}
}.executeOnExecutor(AsyncTask.SERIAL_EXECUTOR);
diff --git a/packages/PrintSpooler/src/com/android/printspooler/model/RemotePrintDocument.java b/packages/PrintSpooler/src/com/android/printspooler/model/RemotePrintDocument.java
index f6ace41..1b6e9ce 100644
--- a/packages/PrintSpooler/src/com/android/printspooler/model/RemotePrintDocument.java
+++ b/packages/PrintSpooler/src/com/android/printspooler/model/RemotePrintDocument.java
@@ -304,6 +304,18 @@
disconnectFromRemoteDocument();
}
+ public void kill(String reason) {
+ if (DEBUG) {
+ Log.i(LOG_TAG, "[CALLED] kill()");
+ }
+
+ try {
+ mPrintDocumentAdapter.kill(reason);
+ } catch (RemoteException re) {
+ Log.e(LOG_TAG, "Error calling kill()", re);
+ }
+ }
+
public boolean isUpdating() {
return mState == STATE_UPDATING || mState == STATE_CANCELING;
}
diff --git a/packages/PrintSpooler/src/com/android/printspooler/renderer/IPdfEditor.aidl b/packages/PrintSpooler/src/com/android/printspooler/renderer/IPdfEditor.aidl
index b450ccb..01cabe1 100644
--- a/packages/PrintSpooler/src/com/android/printspooler/renderer/IPdfEditor.aidl
+++ b/packages/PrintSpooler/src/com/android/printspooler/renderer/IPdfEditor.aidl
@@ -18,6 +18,7 @@
import android.os.ParcelFileDescriptor;
import android.print.PageRange;
+import android.print.PrintAttributes;
/**
* Interface for communication with a remote pdf editor.
@@ -25,6 +26,7 @@
interface IPdfEditor {
int openDocument(in ParcelFileDescriptor source);
void removePages(in PageRange[] pages);
+ void applyPrintAttributes(in PrintAttributes attributes);
void write(in ParcelFileDescriptor destination);
void closeDocument();
}
diff --git a/packages/PrintSpooler/src/com/android/printspooler/renderer/PdfManipulationService.java b/packages/PrintSpooler/src/com/android/printspooler/renderer/PdfManipulationService.java
index 00e5051..7db2074 100644
--- a/packages/PrintSpooler/src/com/android/printspooler/renderer/PdfManipulationService.java
+++ b/packages/PrintSpooler/src/com/android/printspooler/renderer/PdfManipulationService.java
@@ -47,7 +47,9 @@
public static final String ACTION_GET_EDITOR =
"com.android.printspooler.renderer.ACTION_GET_EDITOR";
- public static final int MALFORMED_PDF_FILE_ERROR = -2;
+ public static final int ERROR_MALFORMED_PDF_FILE = -2;
+
+ public static final int ERROR_SECURE_PDF_FILE = -3;
private static final String LOG_TAG = "PdfManipulationService";
private static final boolean DEBUG = false;
@@ -87,10 +89,14 @@
}
mRenderer = new PdfRenderer(source);
return mRenderer.getPageCount();
- } catch (IOException|IllegalStateException e) {
+ } catch (IOException | IllegalStateException e) {
IoUtils.closeQuietly(source);
Log.e(LOG_TAG, "Cannot open file", e);
- return MALFORMED_PDF_FILE_ERROR;
+ return ERROR_MALFORMED_PDF_FILE;
+ } catch (SecurityException e) {
+ IoUtils.closeQuietly(source);
+ Log.e(LOG_TAG, "Cannot open file", e);
+ return ERROR_SECURE_PDF_FILE;
}
}
}
@@ -217,7 +223,7 @@
}
mEditor = new PdfEditor(source);
return mEditor.getPageCount();
- } catch (IOException|IllegalStateException e) {
+ } catch (IOException | IllegalStateException e) {
IoUtils.closeQuietly(source);
Log.e(LOG_TAG, "Cannot open file", e);
throw new RemoteException(e.toString());
@@ -246,6 +252,111 @@
}
@Override
+ public void applyPrintAttributes(PrintAttributes attributes) {
+ synchronized (mLock) {
+ throwIfNotOpened();
+ if (DEBUG) {
+ Log.i(LOG_TAG, "applyPrintAttributes()");
+ }
+
+ Rect mediaBox = new Rect();
+ Rect cropBox = new Rect();
+ Matrix transform = new Matrix();
+
+ final boolean contentPortrait = attributes.getMediaSize().isPortrait();
+
+ final boolean layoutDirectionRtl = getResources().getConfiguration()
+ .getLayoutDirection() == View.LAYOUT_DIRECTION_RTL;
+
+ // We do not want to rotate the media box, so take into account orientation.
+ final int dstWidthPts = contentPortrait
+ ? pointsFromMils(attributes.getMediaSize().getWidthMils())
+ : pointsFromMils(attributes.getMediaSize().getHeightMils());
+ final int dstHeightPts = contentPortrait
+ ? pointsFromMils(attributes.getMediaSize().getHeightMils())
+ : pointsFromMils(attributes.getMediaSize().getWidthMils());
+
+ final boolean scaleForPrinting = mEditor.shouldScaleForPrinting();
+
+ final int pageCount = mEditor.getPageCount();
+ for (int i = 0; i < pageCount; i++) {
+ if (!mEditor.getPageMediaBox(i, mediaBox)) {
+ Log.e(LOG_TAG, "Malformed PDF file");
+ return;
+ }
+
+ final int srcWidthPts = mediaBox.width();
+ final int srcHeightPts = mediaBox.height();
+
+ // Update the media box with the desired size.
+ mediaBox.right = dstWidthPts;
+ mediaBox.bottom = dstHeightPts;
+ mEditor.setPageMediaBox(i, mediaBox);
+
+ // Make sure content is top-left after media box resize.
+ transform.setTranslate(0, srcHeightPts - dstHeightPts);
+
+ // Rotate the content if in landscape.
+ if (!contentPortrait) {
+ transform.postRotate(270);
+ transform.postTranslate(0, dstHeightPts);
+ }
+
+ // Scale the content if document allows it.
+ final float scale;
+ if (scaleForPrinting) {
+ if (contentPortrait) {
+ scale = Math.min((float) dstWidthPts / srcWidthPts,
+ (float) dstHeightPts / srcHeightPts);
+ transform.postScale(scale, scale);
+ } else {
+ scale = Math.min((float) dstWidthPts / srcHeightPts,
+ (float) dstHeightPts / srcWidthPts);
+ transform.postScale(scale, scale, mediaBox.left, mediaBox.bottom);
+ }
+ } else {
+ scale = 1.0f;
+ }
+
+ // Update the crop box relatively to the media box change, if needed.
+ if (mEditor.getPageCropBox(i, cropBox)) {
+ cropBox.left = (int) (cropBox.left * scale + 0.5f);
+ cropBox.top = (int) (cropBox.top * scale + 0.5f);
+ cropBox.right = (int) (cropBox.right * scale + 0.5f);
+ cropBox.bottom = (int) (cropBox.bottom * scale + 0.5f);
+ cropBox.intersect(mediaBox);
+ mEditor.setPageCropBox(i, cropBox);
+ }
+
+ // If in RTL mode put the content in the logical top-right corner.
+ if (layoutDirectionRtl) {
+ final float dx = contentPortrait
+ ? dstWidthPts - (int) (srcWidthPts * scale + 0.5f) : 0;
+ final float dy = contentPortrait
+ ? 0 : - (dstHeightPts - (int) (srcWidthPts * scale + 0.5f));
+ transform.postTranslate(dx, dy);
+ }
+
+ // Adjust the physical margins if needed.
+ Margins minMargins = attributes.getMinMargins();
+ final int paddingLeftPts = pointsFromMils(minMargins.getLeftMils());
+ final int paddingTopPts = pointsFromMils(minMargins.getTopMils());
+ final int paddingRightPts = pointsFromMils(minMargins.getRightMils());
+ final int paddingBottomPts = pointsFromMils(minMargins.getBottomMils());
+
+ Rect clip = new Rect(mediaBox);
+ clip.left += paddingLeftPts;
+ clip.top += paddingTopPts;
+ clip.right -= paddingRightPts;
+ clip.bottom -= paddingBottomPts;
+
+ // Apply the accumulated transforms.
+ mEditor.setTransformAndClip(i, transform, clip);
+ }
+ }
+ }
+
+ @Override
public void write(ParcelFileDescriptor destination) throws RemoteException {
synchronized (mLock) {
try {
diff --git a/packages/PrintSpooler/src/com/android/printspooler/ui/PageAdapter.java b/packages/PrintSpooler/src/com/android/printspooler/ui/PageAdapter.java
index aa79568..0d2e736 100644
--- a/packages/PrintSpooler/src/com/android/printspooler/ui/PageAdapter.java
+++ b/packages/PrintSpooler/src/com/android/printspooler/ui/PageAdapter.java
@@ -37,6 +37,7 @@
import android.view.View.MeasureSpec;
import android.widget.TextView;
import com.android.printspooler.R;
+import com.android.printspooler.model.OpenDocumentCallback;
import com.android.printspooler.model.PageContentRepository;
import com.android.printspooler.model.PageContentRepository.PageContentProvider;
import com.android.printspooler.util.PageRangeUtils;
@@ -51,8 +52,7 @@
/**
* This class represents the adapter for the pages in the print preview list.
*/
-public final class PageAdapter extends Adapter implements
- PageContentRepository.OnMalformedPdfFileListener {
+public final class PageAdapter extends Adapter {
private static final String LOG_TAG = "PageAdapter";
private static final int MAX_PREVIEW_PAGES_BATCH = 50;
@@ -113,6 +113,7 @@
public interface ContentCallbacks {
public void onRequestContentUpdate();
public void onMalformedPdfFile();
+ public void onSecurePdfFile();
}
public interface PreviewArea {
@@ -127,7 +128,7 @@
mCallbacks = callbacks;
mLayoutInflater = (LayoutInflater) context.getSystemService(
Context.LAYOUT_INFLATER_SERVICE);
- mPageContentRepository = new PageContentRepository(context, this);
+ mPageContentRepository = new PageContentRepository(context);
mPreviewPageMargin = mContext.getResources().getDimensionPixelSize(
R.dimen.preview_page_margin);
@@ -156,11 +157,6 @@
}
}
- @Override
- public void onMalformedPdfFile() {
- mCallbacks.onMalformedPdfFile();
- }
-
public void onOrientationChanged() {
mColumnCount = mContext.getResources().getInteger(
R.integer.preview_page_per_row_count);
@@ -181,12 +177,25 @@
if (DEBUG) {
Log.i(LOG_TAG, "STATE_OPENED");
}
- mPageContentRepository.open(source, new Runnable() {
+ mPageContentRepository.open(source, new OpenDocumentCallback() {
@Override
- public void run() {
+ public void onSuccess() {
notifyDataSetChanged();
callback.run();
}
+
+ @Override
+ public void onFailure(int error) {
+ switch (error) {
+ case OpenDocumentCallback.ERROR_MALFORMED_PDF_FILE: {
+ mCallbacks.onMalformedPdfFile();
+ } break;
+
+ case OpenDocumentCallback.ERROR_SECURE_PDF_FILE: {
+ mCallbacks.onSecurePdfFile();
+ } break;
+ }
+ }
});
}
diff --git a/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java b/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java
index 15ea9a7..b76a9cd 100644
--- a/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java
+++ b/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java
@@ -378,7 +378,7 @@
return true;
}
- if (mState == STATE_PRINT_CANCELED ||mState == STATE_PRINT_CONFIRMED
+ if (mState == STATE_PRINT_CANCELED || mState == STATE_PRINT_CONFIRMED
|| mState == STATE_PRINT_COMPLETED) {
return true;
}
@@ -405,12 +405,23 @@
@Override
public void onMalformedPdfFile() {
+ onPrintDocumentError("Cannot print a malformed PDF file");
+ }
+
+ @Override
+ public void onSecurePdfFile() {
+ onPrintDocumentError("Cannot print a password protected PDF file");
+ }
+
+ private void onPrintDocumentError(String message) {
mProgressMessageController.cancel();
ensureErrorUiShown(null, PrintErrorFragment.ACTION_RETRY);
setState(STATE_UPDATE_FAILED);
updateOptionsUi();
+
+ mPrintedDocument.kill(message);
}
@Override
@@ -592,7 +603,7 @@
mDestinationSpinner.post(new Runnable() {
@Override
public void run() {
- shredPagesAndFinish(uri);
+ transformDocumentAndFinish(uri);
}
});
} else if (resultCode == RESULT_CANCELED) {
@@ -922,7 +933,7 @@
if (mCurrentPrinter == mDestinationSpinnerAdapter.getPdfPrinter()) {
startCreateDocumentActivity();
} else {
- shredPagesAndFinish(null);
+ transformDocumentAndFinish(null);
}
}
@@ -1597,8 +1608,11 @@
return true;
}
- private void shredPagesAndFinish(final Uri writeToUri) {
- new PageShredder(this, mPrintJob, mFileProvider, new Runnable() {
+ private void transformDocumentAndFinish(final Uri writeToUri) {
+ // If saving to PDF, apply the attibutes as we are acting as a print service.
+ PrintAttributes attributes = mDestinationSpinnerAdapter.getPdfPrinter() == mCurrentPrinter
+ ? mPrintJob.getAttributes() : null;
+ new DocumentTransformer(this, mPrintJob, mFileProvider, attributes, new Runnable() {
@Override
public void run() {
if (writeToUri != null) {
@@ -1606,7 +1620,7 @@
}
doFinish();
}
- }).shred();
+ }).transform();
}
private void doFinish() {
@@ -2329,7 +2343,7 @@
}
}
- private static final class PageShredder implements ServiceConnection {
+ private static final class DocumentTransformer implements ServiceConnection {
private static final String TEMP_FILE_PREFIX = "print_job";
private static final String TEMP_FILE_EXTENSION = ".pdf";
@@ -2341,20 +2355,24 @@
private final PageRange[] mPagesToShred;
+ private final PrintAttributes mAttributesToApply;
+
private final Runnable mCallback;
- public PageShredder(Context context, PrintJobInfo printJob,
- MutexFileProvider fileProvider, Runnable callback) {
+ public DocumentTransformer(Context context, PrintJobInfo printJob,
+ MutexFileProvider fileProvider, PrintAttributes attributes,
+ Runnable callback) {
mContext = context;
mPrintJob = printJob;
mFileProvider = fileProvider;
mCallback = callback;
mPagesToShred = computePagesToShred(mPrintJob);
+ mAttributesToApply = attributes;
}
- public void shred() {
+ public void transform() {
// If we have only the pages we want, done.
- if (mPagesToShred.length <= 0) {
+ if (mPagesToShred.length <= 0 && mAttributesToApply == null) {
mCallback.run();
return;
}
@@ -2376,14 +2394,14 @@
// final and this code is the last one to touch
// them as shredding is the very last step, so the
// UI is not interactive at this point.
- shredPages(editor);
+ doTransform(editor);
updatePrintJob();
return null;
}
@Override
protected void onPostExecute(Void aVoid) {
- mContext.unbindService(PageShredder.this);
+ mContext.unbindService(DocumentTransformer.this);
mCallback.run();
}
}.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
@@ -2394,7 +2412,7 @@
/* do nothing */
}
- private void shredPages(IPdfEditor editor) {
+ private void doTransform(IPdfEditor editor) {
File tempFile = null;
ParcelFileDescriptor src = null;
ParcelFileDescriptor dst = null;
@@ -2413,6 +2431,11 @@
// Drop the pages.
editor.removePages(mPagesToShred);
+ // Apply print attributes if needed.
+ if (mAttributesToApply != null) {
+ editor.applyPrintAttributes(mAttributesToApply);
+ }
+
// Write the modified PDF to a temp file.
tempFile = File.createTempFile(TEMP_FILE_PREFIX, TEMP_FILE_EXTENSION,
mContext.getCacheDir());
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java b/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
index eea97ea..9bfcadb 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
@@ -71,7 +71,7 @@
// database gets upgraded properly. At a minimum, please confirm that 'upgradeVersion'
// is properly propagated through your change. Not doing so will result in a loss of user
// settings.
- private static final int DATABASE_VERSION = 116;
+ private static final int DATABASE_VERSION = 117;
private Context mContext;
private int mUserHandle;
@@ -1865,6 +1865,20 @@
upgradeVersion = 116;
}
+ if (upgradeVersion < 117) {
+ db.beginTransaction();
+ try {
+ String[] systemToSecure = {
+ Settings.Secure.LOCK_TO_APP_EXIT_LOCKED
+ };
+ moveSettingsToNewTable(db, TABLE_SYSTEM, TABLE_SECURE, systemToSecure, true);
+ db.setTransactionSuccessful();
+ } finally {
+ db.endTransaction();
+ }
+ upgradeVersion = 117;
+ }
+
// *** Remember to update DATABASE_VERSION above!
if (upgradeVersion != currentVersion) {
diff --git a/packages/SystemUI/res/anim/ic_invert_colors_disable_animation_cross_1.xml b/packages/SystemUI/res/anim/ic_invert_colors_disable_animation_cross_1.xml
new file mode 100644
index 0000000..a49ebf8
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_invert_colors_disable_animation_cross_1.xml
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<set xmlns:android="http://schemas.android.com/apk/res/android" >
+ <set
+ android:ordering="sequentially" >
+ <objectAnimator
+ android:duration="200"
+ android:propertyName="pathData"
+ android:valueFrom="M 7.54049682617,3.9430847168 c 0.0,0.0 0.324981689453,0.399978637695 0.324981689453,0.399978637695 "
+ android:valueTo="M 7.54049682617,3.9430847168 c 0.0,0.0 0.324981689453,0.399978637695 0.324981689453,0.399978637695 "
+ android:valueType="pathType"
+ android:interpolator="@android:interpolator/linear" />
+ <objectAnimator
+ android:duration="350"
+ android:propertyName="pathData"
+ android:valueFrom="M 7.54049682617,3.9430847168 c 0.0,0.0 0.324981689453,0.399978637695 0.324981689453,0.399978637695 "
+ android:valueTo="M 7.54049682617,3.9430847168 c 0.0,0.0 31.5749816895,31.4499664307 31.5749816895,31.4499664307 "
+ android:valueType="pathType"
+ android:interpolator="@interpolator/ic_invert_colors_disable_cross_1_pathdata_interpolator" />
+ </set>
+ <set
+ android:ordering="sequentially" >
+ <objectAnimator
+ android:duration="200"
+ android:propertyName="strokeAlpha"
+ android:valueFrom="0"
+ android:valueTo="0"
+ android:interpolator="@android:interpolator/linear" />
+ <objectAnimator
+ android:duration="17"
+ android:propertyName="strokeAlpha"
+ android:valueFrom="0"
+ android:valueTo="1"
+ android:interpolator="@android:interpolator/linear" />
+ </set>
+</set>
diff --git a/packages/SystemUI/res/anim/ic_invert_colors_disable_animation_icon.xml b/packages/SystemUI/res/anim/ic_invert_colors_disable_animation_icon.xml
new file mode 100644
index 0000000..9cc3b8e
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_invert_colors_disable_animation_icon.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<set xmlns:android="http://schemas.android.com/apk/res/android" >
+ <set
+ android:ordering="sequentially" >
+ <objectAnimator
+ android:duration="200"
+ android:propertyName="alpha"
+ android:valueFrom="1"
+ android:valueTo="1"
+ android:interpolator="@android:interpolator/fast_out_slow_in" />
+ <objectAnimator
+ android:duration="350"
+ android:propertyName="alpha"
+ android:valueFrom="1"
+ android:valueTo="0.5"
+ android:interpolator="@android:interpolator/fast_out_slow_in" />
+ </set>
+</set>
diff --git a/packages/SystemUI/res/anim/ic_invert_colors_disable_animation_mask.xml b/packages/SystemUI/res/anim/ic_invert_colors_disable_animation_mask.xml
new file mode 100644
index 0000000..605ef90
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_invert_colors_disable_animation_mask.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<set xmlns:android="http://schemas.android.com/apk/res/android" >
+ <set
+ android:ordering="sequentially" >
+ <objectAnimator
+ android:duration="200"
+ android:propertyName="pathData"
+ android:valueFrom="M 37.8337860107,-40.4599914551 c 0.0,0.0 -35.8077850342,31.5523681641 -35.8077850342,31.5523681641 c 0.0,0.0 9.55097961426,9.55285644531 9.55097961426,9.55285644531 c 0.0,0.0 -2.61698913574,2.09387207031 -2.61698913574,2.09387207031 c 0.0,0.0 -9.75096130371,-9.56428527832 -9.75096130371,-9.56428527832 c 0.0,0.0 -34.6200408936,25.4699249268 -34.6200408936,25.4699249268 c 0.0,0.0 55.9664764404,69.742401123 55.9664764404,69.742401123 c 0.0,0.0 73.2448120117,-59.1047973633 73.2448120117,-59.1047973633 c 0.0,0.0 -55.9664916992,-69.7423400879 -55.9664916992,-69.7423400879 Z"
+ android:valueTo="M 37.8337860107,-40.4599914551 c 0.0,0.0 -35.8077850342,31.5523681641 -35.8077850342,31.5523681641 c 0.0,0.0 9.55097961426,9.55285644531 9.55097961426,9.55285644531 c 0.0,0.0 -2.61698913574,2.09387207031 -2.61698913574,2.09387207031 c 0.0,0.0 -9.75096130371,-9.56428527832 -9.75096130371,-9.56428527832 c 0.0,0.0 -34.6200408936,25.4699249268 -34.6200408936,25.4699249268 c 0.0,0.0 55.9664764404,69.742401123 55.9664764404,69.742401123 c 0.0,0.0 73.2448120117,-59.1047973633 73.2448120117,-59.1047973633 c 0.0,0.0 -55.9664916992,-69.7423400879 -55.9664916992,-69.7423400879 Z"
+ android:valueType="pathType"
+ android:interpolator="@android:interpolator/fast_out_slow_in" />
+ <objectAnimator
+ android:duration="350"
+ android:propertyName="pathData"
+ android:valueFrom="M 37.8337860107,-40.4599914551 c 0.0,0.0 -35.8077850342,31.5523681641 -35.8077850342,31.5523681641 c 0.0,0.0 9.55097961426,9.55285644531 9.55097961426,9.55285644531 c 0.0,0.0 -2.61698913574,2.09387207031 -2.61698913574,2.09387207031 c 0.0,0.0 -9.75096130371,-9.56428527832 -9.75096130371,-9.56428527832 c 0.0,0.0 -34.6200408936,25.4699249268 -34.6200408936,25.4699249268 c 0.0,0.0 55.9664764404,69.742401123 55.9664764404,69.742401123 c 0.0,0.0 73.2448120117,-59.1047973633 73.2448120117,-59.1047973633 c 0.0,0.0 -55.9664916992,-69.7423400879 -55.9664916992,-69.7423400879 Z"
+ android:valueTo="M 37.8337860107,-40.3974914551 c 0.0,0.0 -35.8077850342,31.5523681641 -35.8077850342,31.5523681641 c 0.0,0.0 40.9884796143,40.9278411865 40.9884796143,40.9278411865 c 0.0,0.0 -2.61700439453,2.0938873291 -2.61700439453,2.0938873291 c 0.0,0.0 -41.1884460449,-40.9392852783 -41.1884460449,-40.9392852783 c 0.0,0.0 -34.6200408936,25.4699249268 -34.6200408936,25.4699249268 c 0.0,0.0 55.9664764404,69.742401123 55.9664764404,69.742401123 c 0.0,0.0 73.2448120117,-59.1047973633 73.2448120117,-59.1047973633 c 0.0,0.0 -55.9664916992,-69.7423400879 -55.9664916992,-69.7423400879 Z"
+ android:valueType="pathType"
+ android:interpolator="@android:interpolator/fast_out_slow_in" />
+ </set>
+</set>
diff --git a/packages/SystemUI/res/anim/ic_invert_colors_disable_animation_root.xml b/packages/SystemUI/res/anim/ic_invert_colors_disable_animation_root.xml
new file mode 100644
index 0000000..770c401
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_invert_colors_disable_animation_root.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<set xmlns:android="http://schemas.android.com/apk/res/android" >
+ <objectAnimator
+ android:duration="350"
+ android:propertyName="alpha"
+ android:valueFrom="1.0"
+ android:valueTo="0.3"
+ android:interpolator="@android:interpolator/fast_out_slow_in" />
+</set>
diff --git a/packages/SystemUI/res/anim/ic_invert_colors_enable_animation_cross_1.xml b/packages/SystemUI/res/anim/ic_invert_colors_enable_animation_cross_1.xml
new file mode 100644
index 0000000..94f54b6
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_invert_colors_enable_animation_cross_1.xml
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<set xmlns:android="http://schemas.android.com/apk/res/android" >
+ <set
+ android:ordering="sequentially" >
+ <objectAnimator
+ android:duration="200"
+ android:propertyName="pathData"
+ android:valueFrom="M 7.54049682617,3.9430847168 c 0.0,0.0 31.5749816895,31.4499664307 31.5749816895,31.4499664307 "
+ android:valueTo="M 7.54049682617,3.9430847168 c 0.0,0.0 31.5749816895,31.4499664307 31.5749816895,31.4499664307 "
+ android:valueType="pathType"
+ android:interpolator="@android:interpolator/linear" />
+ <objectAnimator
+ android:duration="350"
+ android:propertyName="pathData"
+ android:valueFrom="M 7.54049682617,3.9430847168 c 0.0,0.0 31.5749816895,31.4499664307 31.5749816895,31.4499664307 "
+ android:valueTo="M 7.54049682617,3.9430847168 c 0.0,0.0 0.324981689453,0.399978637695 0.324981689453,0.399978637695 "
+ android:valueType="pathType"
+ android:interpolator="@interpolator/ic_invert_colors_enable_cross_1_pathdata_interpolator" />
+ </set>
+ <set
+ android:ordering="sequentially" >
+ <objectAnimator
+ android:duration="533"
+ android:propertyName="strokeAlpha"
+ android:valueFrom="1"
+ android:valueTo="1"
+ android:interpolator="@android:interpolator/linear" />
+ <objectAnimator
+ android:duration="17"
+ android:propertyName="strokeAlpha"
+ android:valueFrom="1"
+ android:valueTo="0"
+ android:interpolator="@android:interpolator/linear" />
+ </set>
+</set>
diff --git a/packages/SystemUI/res/anim/ic_invert_colors_enable_animation_icon.xml b/packages/SystemUI/res/anim/ic_invert_colors_enable_animation_icon.xml
new file mode 100644
index 0000000..50a1af6
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_invert_colors_enable_animation_icon.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<set xmlns:android="http://schemas.android.com/apk/res/android" >
+ <set
+ android:ordering="sequentially" >
+ <objectAnimator
+ android:duration="200"
+ android:propertyName="alpha"
+ android:valueFrom="0.54"
+ android:valueTo="0.54"
+ android:interpolator="@android:interpolator/fast_out_slow_in" />
+ <objectAnimator
+ android:duration="350"
+ android:propertyName="alpha"
+ android:valueFrom="0.54"
+ android:valueTo="1"
+ android:interpolator="@android:interpolator/fast_out_slow_in" />
+ </set>
+</set>
diff --git a/packages/SystemUI/res/anim/ic_invert_colors_enable_animation_mask.xml b/packages/SystemUI/res/anim/ic_invert_colors_enable_animation_mask.xml
new file mode 100644
index 0000000..9531cd9
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_invert_colors_enable_animation_mask.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<set xmlns:android="http://schemas.android.com/apk/res/android" >
+ <set
+ android:ordering="sequentially" >
+ <objectAnimator
+ android:duration="200"
+ android:propertyName="pathData"
+ android:valueFrom="M 37.8337860107,-40.3974914551 c 0.0,0.0 -35.8077850342,31.5523681641 -35.8077850342,31.5523681641 c 0.0,0.0 40.9884796143,40.9278411865 40.9884796143,40.9278411865 c 0.0,0.0 -2.61700439453,2.0938873291 -2.61700439453,2.0938873291 c 0.0,0.0 -41.1884460449,-40.9392852783 -41.1884460449,-40.9392852783 c 0.0,0.0 -34.6200408936,25.4699249268 -34.6200408936,25.4699249268 c 0.0,0.0 55.9664764404,69.742401123 55.9664764404,69.742401123 c 0.0,0.0 73.2448120117,-59.1047973633 73.2448120117,-59.1047973633 c 0.0,0.0 -55.9664916992,-69.7423400879 -55.9664916992,-69.7423400879 Z"
+ android:valueTo="M 37.8337860107,-40.3974914551 c 0.0,0.0 -35.8077850342,31.5523681641 -35.8077850342,31.5523681641 c 0.0,0.0 40.9884796143,40.9278411865 40.9884796143,40.9278411865 c 0.0,0.0 -2.61700439453,2.0938873291 -2.61700439453,2.0938873291 c 0.0,0.0 -41.1884460449,-40.9392852783 -41.1884460449,-40.9392852783 c 0.0,0.0 -34.6200408936,25.4699249268 -34.6200408936,25.4699249268 c 0.0,0.0 55.9664764404,69.742401123 55.9664764404,69.742401123 c 0.0,0.0 73.2448120117,-59.1047973633 73.2448120117,-59.1047973633 c 0.0,0.0 -55.9664916992,-69.7423400879 -55.9664916992,-69.7423400879 Z"
+ android:valueType="pathType"
+ android:interpolator="@android:interpolator/linear" />
+ <objectAnimator
+ android:duration="350"
+ android:propertyName="pathData"
+ android:valueFrom="M 37.8337860107,-40.3974914551 c 0.0,0.0 -35.8077850342,31.5523681641 -35.8077850342,31.5523681641 c 0.0,0.0 40.9884796143,40.9278411865 40.9884796143,40.9278411865 c 0.0,0.0 -2.61700439453,2.0938873291 -2.61700439453,2.0938873291 c 0.0,0.0 -41.1884460449,-40.9392852783 -41.1884460449,-40.9392852783 c 0.0,0.0 -34.6200408936,25.4699249268 -34.6200408936,25.4699249268 c 0.0,0.0 55.9664764404,69.742401123 55.9664764404,69.742401123 c 0.0,0.0 73.2448120117,-59.1047973633 73.2448120117,-59.1047973633 c 0.0,0.0 -55.9664916992,-69.7423400879 -55.9664916992,-69.7423400879 Z"
+ android:valueTo="M 37.8337860107,-40.4599914551 c 0.0,0.0 -35.8077850342,31.5523681641 -35.8077850342,31.5523681641 c 0.0,0.0 9.55097961426,9.55285644531 9.55097961426,9.55285644531 c 0.0,0.0 -2.61698913574,2.09387207031 -2.61698913574,2.09387207031 c 0.0,0.0 -9.75096130371,-9.56428527832 -9.75096130371,-9.56428527832 c 0.0,0.0 -34.6200408936,25.4699249268 -34.6200408936,25.4699249268 c 0.0,0.0 55.9664764404,69.742401123 55.9664764404,69.742401123 c 0.0,0.0 73.2448120117,-59.1047973633 73.2448120117,-59.1047973633 c 0.0,0.0 -55.9664916992,-69.7423400879 -55.9664916992,-69.7423400879 Z"
+ android:valueType="pathType"
+ android:interpolator="@interpolator/ic_invert_colors_enable_mask_pathdata_interpolator" />
+ </set>
+</set>
diff --git a/packages/SystemUI/res/anim/ic_invert_colors_enable_animation_root.xml b/packages/SystemUI/res/anim/ic_invert_colors_enable_animation_root.xml
new file mode 100644
index 0000000..387ca29
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_invert_colors_enable_animation_root.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<set xmlns:android="http://schemas.android.com/apk/res/android" >
+ <objectAnimator
+ android:duration="350"
+ android:propertyName="alpha"
+ android:valueFrom="0.3"
+ android:valueTo="1.0"
+ android:interpolator="@android:interpolator/fast_out_slow_in" />
+</set>
diff --git a/packages/SystemUI/res/anim/ic_landscape_from_auto_rotate_animation_arrow_bottom.xml b/packages/SystemUI/res/anim/ic_landscape_from_auto_rotate_animation_arrow_bottom.xml
new file mode 100644
index 0000000..9add90c
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_landscape_from_auto_rotate_animation_arrow_bottom.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<set xmlns:android="http://schemas.android.com/apk/res/android" >
+ <set
+ android:ordering="sequentially" >
+ <objectAnimator
+ android:duration="567"
+ android:propertyName="fillAlpha"
+ android:valueFrom="1"
+ android:valueTo="1"
+ android:interpolator="@android:interpolator/linear" />
+ <objectAnimator
+ android:duration="33"
+ android:propertyName="fillAlpha"
+ android:valueFrom="1"
+ android:valueTo="0"
+ android:interpolator="@android:interpolator/linear" />
+ </set>
+</set>
diff --git a/packages/SystemUI/res/anim/ic_landscape_from_auto_rotate_animation_arrow_top.xml b/packages/SystemUI/res/anim/ic_landscape_from_auto_rotate_animation_arrow_top.xml
new file mode 100644
index 0000000..9add90c
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_landscape_from_auto_rotate_animation_arrow_top.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<set xmlns:android="http://schemas.android.com/apk/res/android" >
+ <set
+ android:ordering="sequentially" >
+ <objectAnimator
+ android:duration="567"
+ android:propertyName="fillAlpha"
+ android:valueFrom="1"
+ android:valueTo="1"
+ android:interpolator="@android:interpolator/linear" />
+ <objectAnimator
+ android:duration="33"
+ android:propertyName="fillAlpha"
+ android:valueFrom="1"
+ android:valueTo="0"
+ android:interpolator="@android:interpolator/linear" />
+ </set>
+</set>
diff --git a/packages/SystemUI/res/anim/ic_landscape_from_auto_rotate_animation_arrows.xml b/packages/SystemUI/res/anim/ic_landscape_from_auto_rotate_animation_arrows.xml
new file mode 100644
index 0000000..6c4e1335
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_landscape_from_auto_rotate_animation_arrows.xml
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<set xmlns:android="http://schemas.android.com/apk/res/android" >
+ <set
+ android:ordering="sequentially" >
+ <objectAnimator
+ android:duration="317"
+ android:propertyName="scaleX"
+ android:valueFrom="1"
+ android:valueTo="1"
+ android:interpolator="@android:interpolator/linear" />
+ <objectAnimator
+ android:duration="333"
+ android:propertyName="scaleX"
+ android:valueFrom="1"
+ android:valueTo="0.9"
+ android:interpolator="@android:interpolator/linear" />
+ </set>
+ <set
+ android:ordering="sequentially" >
+ <objectAnimator
+ android:duration="317"
+ android:propertyName="scaleY"
+ android:valueFrom="1"
+ android:valueTo="1"
+ android:interpolator="@android:interpolator/linear" />
+ <objectAnimator
+ android:duration="333"
+ android:propertyName="scaleY"
+ android:valueFrom="1"
+ android:valueTo="0.9"
+ android:interpolator="@android:interpolator/linear" />
+ </set>
+ <set
+ android:ordering="sequentially" >
+ <objectAnimator
+ android:duration="200"
+ android:propertyName="rotation"
+ android:valueFrom="0"
+ android:valueTo="0"
+ android:interpolator="@android:interpolator/linear" />
+ <objectAnimator
+ android:duration="450"
+ android:propertyName="rotation"
+ android:valueFrom="0"
+ android:valueTo="-135"
+ android:interpolator="@interpolator/ic_landscape_from_auto_rotate_arrows_rotation_interpolator" />
+ </set>
+</set>
diff --git a/packages/SystemUI/res/anim/ic_landscape_from_auto_rotate_animation_body.xml b/packages/SystemUI/res/anim/ic_landscape_from_auto_rotate_animation_body.xml
new file mode 100644
index 0000000..a8f5ce0
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_landscape_from_auto_rotate_animation_body.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<set xmlns:android="http://schemas.android.com/apk/res/android" >
+ <set
+ android:ordering="sequentially" >
+ <objectAnimator
+ android:duration="267"
+ android:propertyName="pathData"
+ android:valueFrom="M -3.5,-20.5 c -1.19999694824,-1.19999694824 -3.10000610352,-1.19999694824 -4.19999694824,0.0 c 0.0,0.0 -12.8000030518,12.6999969482 -12.8000030518,12.6999969482 c -1.19999694824,1.19999694824 -1.19999694824,3.10000610352 0.0,4.19999694824 c 0.0,0.0 24.0,24.0000152588 24.0,24.0000152588 c 1.19999694824,1.19999694824 3.10000610352,1.19999694824 4.19999694824,0.0 c 0.0,0.0 12.6999969482,-12.700012207 12.6999969482,-12.700012207 c 1.20001220703,-1.19999694824 1.20001220703,-3.09999084473 0.0,-4.19999694824 c 0.0,0.0 -23.8999938965,-24.0 -23.8999938965,-24.0 Z M 2.84999084473,15.5500183105 c 0.0,0.0 -18.6000061035,-18.5000457764 -18.6000061035,-18.5000457764 c 0.0,0.0 12.5999908447,-12.8000030518 12.5999908447,-12.8000030518 c 0.0,0.0 18.6000213623,18.5000457764 18.6000213623,18.5000457764 c 0.0,0.0 -12.6000061035,12.8000030518 -12.6000061035,12.8000030518 Z"
+ android:valueTo="M -3.5,-20.5 c -1.19999694824,-1.19999694824 -3.10000610352,-1.19999694824 -4.19999694824,0.0 c 0.0,0.0 -12.8000030518,12.6999969482 -12.8000030518,12.6999969482 c -1.19999694824,1.19999694824 -1.19999694824,3.10000610352 0.0,4.19999694824 c 0.0,0.0 24.0,24.0000152588 24.0,24.0000152588 c 1.19999694824,1.19999694824 3.10000610352,1.19999694824 4.19999694824,0.0 c 0.0,0.0 12.6999969482,-12.700012207 12.6999969482,-12.700012207 c 1.20001220703,-1.19999694824 1.20001220703,-3.09999084473 0.0,-4.19999694824 c 0.0,0.0 -23.8999938965,-24.0 -23.8999938965,-24.0 Z M 2.84999084473,15.5500183105 c 0.0,0.0 -18.6000061035,-18.5000457764 -18.6000061035,-18.5000457764 c 0.0,0.0 12.5999908447,-12.8000030518 12.5999908447,-12.8000030518 c 0.0,0.0 18.6000213623,18.5000457764 18.6000213623,18.5000457764 c 0.0,0.0 -12.6000061035,12.8000030518 -12.6000061035,12.8000030518 Z"
+ android:valueType="pathType"
+ android:interpolator="@android:interpolator/fast_out_slow_in" />
+ <objectAnimator
+ android:duration="217"
+ android:propertyName="pathData"
+ android:valueFrom="M -3.5,-20.5 c -1.19999694824,-1.19999694824 -3.10000610352,-1.19999694824 -4.19999694824,0.0 c 0.0,0.0 -12.8000030518,12.6999969482 -12.8000030518,12.6999969482 c -1.19999694824,1.19999694824 -1.19999694824,3.10000610352 0.0,4.19999694824 c 0.0,0.0 24.0,24.0000152588 24.0,24.0000152588 c 1.19999694824,1.19999694824 3.10000610352,1.19999694824 4.19999694824,0.0 c 0.0,0.0 12.6999969482,-12.700012207 12.6999969482,-12.700012207 c 1.20001220703,-1.19999694824 1.20001220703,-3.09999084473 0.0,-4.19999694824 c 0.0,0.0 -23.8999938965,-24.0 -23.8999938965,-24.0 Z M 2.84999084473,15.5500183105 c 0.0,0.0 -18.6000061035,-18.5000457764 -18.6000061035,-18.5000457764 c 0.0,0.0 12.5999908447,-12.8000030518 12.5999908447,-12.8000030518 c 0.0,0.0 18.6000213623,18.5000457764 18.6000213623,18.5000457764 c 0.0,0.0 -12.6000061035,12.8000030518 -12.6000061035,12.8000030518 Z"
+ android:valueTo="M -3.34053039551,-22.9980926514 c -1.3207244873,-1.3207244873 -3.46876525879,-1.26383972168 -4.74829101563,0.125762939453 c 0.0,0.0 -14.8512420654,14.7411804199 -14.8512420654,14.7411804199 c -1.39259338379,1.392578125 -1.44947814941,3.54061889648 -0.125762939453,4.74827575684 c 0.0,0.0 26.4143981934,26.4144134521 26.4143981934,26.4144134521 c 1.3207244873,1.3207244873 3.46876525879,1.26382446289 4.74829101562,-0.125762939453 c 0.0,0.0 14.7381896973,-14.7381896973 14.7381896973,-14.7381896973 c 1.392578125,-1.39259338379 1.44947814941,-3.54061889648 0.125762939453,-4.74829101562 c 0.0,0.0 -26.3013458252,-26.417388916 -26.3013458252,-26.417388916 Z M 2.87156677246,16.9857940674 c 0.0,0.0 -19.7573547363,-19.7573699951 -19.7573547363,-19.7573699951 c 0.0,0.0 14.0142059326,-14.2142181396 14.0142059326,-14.2142181396 c 0.0,0.0 19.7573699951,19.7573699951 19.7573699951,19.7573699951 c 0.0,0.0 -14.0142211914,14.2142181396 -14.0142211914,14.2142181396 Z"
+ android:valueType="pathType"
+ android:interpolator="@android:interpolator/fast_out_slow_in" />
+ </set>
+</set>
diff --git a/packages/SystemUI/res/anim/ic_landscape_from_auto_rotate_animation_device.xml b/packages/SystemUI/res/anim/ic_landscape_from_auto_rotate_animation_device.xml
new file mode 100644
index 0000000..b9bb42d
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_landscape_from_auto_rotate_animation_device.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<set xmlns:android="http://schemas.android.com/apk/res/android" >
+ <set
+ android:ordering="sequentially" >
+ <objectAnimator
+ android:duration="200"
+ android:propertyName="rotation"
+ android:valueFrom="0"
+ android:valueTo="0"
+ android:interpolator="@android:interpolator/fast_out_slow_in" />
+ <objectAnimator
+ android:duration="400"
+ android:propertyName="rotation"
+ android:valueFrom="0"
+ android:valueTo="-45"
+ android:interpolator="@android:interpolator/fast_out_slow_in" />
+ </set>
+</set>
diff --git a/packages/SystemUI/res/anim/ic_landscape_to_auto_rotate_animation_arrow_bottom.xml b/packages/SystemUI/res/anim/ic_landscape_to_auto_rotate_animation_arrow_bottom.xml
new file mode 100644
index 0000000..b8823a9
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_landscape_to_auto_rotate_animation_arrow_bottom.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<set xmlns:android="http://schemas.android.com/apk/res/android" >
+ <set
+ android:ordering="sequentially" >
+ <objectAnimator
+ android:duration="250"
+ android:propertyName="fillAlpha"
+ android:valueFrom="0"
+ android:valueTo="0"
+ android:interpolator="@android:interpolator/linear" />
+ <objectAnimator
+ android:duration="33"
+ android:propertyName="fillAlpha"
+ android:valueFrom="0"
+ android:valueTo="1"
+ android:interpolator="@android:interpolator/linear" />
+ </set>
+</set>
diff --git a/packages/SystemUI/res/anim/ic_landscape_to_auto_rotate_animation_arrow_top.xml b/packages/SystemUI/res/anim/ic_landscape_to_auto_rotate_animation_arrow_top.xml
new file mode 100644
index 0000000..b8823a9
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_landscape_to_auto_rotate_animation_arrow_top.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<set xmlns:android="http://schemas.android.com/apk/res/android" >
+ <set
+ android:ordering="sequentially" >
+ <objectAnimator
+ android:duration="250"
+ android:propertyName="fillAlpha"
+ android:valueFrom="0"
+ android:valueTo="0"
+ android:interpolator="@android:interpolator/linear" />
+ <objectAnimator
+ android:duration="33"
+ android:propertyName="fillAlpha"
+ android:valueFrom="0"
+ android:valueTo="1"
+ android:interpolator="@android:interpolator/linear" />
+ </set>
+</set>
diff --git a/packages/SystemUI/res/anim/ic_landscape_to_auto_rotate_animation_arrows.xml b/packages/SystemUI/res/anim/ic_landscape_to_auto_rotate_animation_arrows.xml
new file mode 100644
index 0000000..14c2776
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_landscape_to_auto_rotate_animation_arrows.xml
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<set xmlns:android="http://schemas.android.com/apk/res/android" >
+ <set
+ android:ordering="sequentially" >
+ <objectAnimator
+ android:duration="200"
+ android:propertyName="scaleX"
+ android:valueFrom="0.9"
+ android:valueTo="0.9"
+ android:interpolator="@android:interpolator/linear" />
+ <objectAnimator
+ android:duration="333"
+ android:propertyName="scaleX"
+ android:valueFrom="0.9"
+ android:valueTo="1"
+ android:interpolator="@android:interpolator/linear" />
+ </set>
+ <set
+ android:ordering="sequentially" >
+ <objectAnimator
+ android:duration="200"
+ android:propertyName="scaleY"
+ android:valueFrom="0.9"
+ android:valueTo="0.9"
+ android:interpolator="@android:interpolator/linear" />
+ <objectAnimator
+ android:duration="333"
+ android:propertyName="scaleY"
+ android:valueFrom="0.9"
+ android:valueTo="1"
+ android:interpolator="@android:interpolator/linear" />
+ </set>
+ <set
+ android:ordering="sequentially" >
+ <objectAnimator
+ android:duration="200"
+ android:propertyName="rotation"
+ android:valueFrom="-135"
+ android:valueTo="-135"
+ android:interpolator="@android:interpolator/linear" />
+ <objectAnimator
+ android:duration="450"
+ android:propertyName="rotation"
+ android:valueFrom="-135"
+ android:valueTo="0"
+ android:interpolator="@interpolator/ic_landscape_to_auto_rotate_arrows_rotation_interpolator" />
+ </set>
+</set>
diff --git a/packages/SystemUI/res/anim/ic_landscape_to_auto_rotate_animation_body.xml b/packages/SystemUI/res/anim/ic_landscape_to_auto_rotate_animation_body.xml
new file mode 100644
index 0000000..ea8f979
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_landscape_to_auto_rotate_animation_body.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<set xmlns:android="http://schemas.android.com/apk/res/android" >
+ <set
+ android:ordering="sequentially" >
+ <objectAnimator
+ android:duration="267"
+ android:propertyName="pathData"
+ android:valueFrom="M -3.34053039551,-22.9980926514 c -1.3207244873,-1.3207244873 -3.46876525879,-1.26383972168 -4.74829101563,0.125762939453 c 0.0,0.0 -14.8512420654,14.7411804199 -14.8512420654,14.7411804199 c -1.39259338379,1.392578125 -1.44947814941,3.54061889648 -0.125762939453,4.74827575684 c 0.0,0.0 26.4143981934,26.4144134521 26.4143981934,26.4144134521 c 1.3207244873,1.3207244873 3.46876525879,1.26382446289 4.74829101562,-0.125762939453 c 0.0,0.0 14.7381896973,-14.7381896973 14.7381896973,-14.7381896973 c 1.392578125,-1.39259338379 1.44947814941,-3.54061889648 0.125762939453,-4.74829101562 c 0.0,0.0 -26.3013458252,-26.417388916 -26.3013458252,-26.417388916 Z M 2.87156677246,16.9857940674 c 0.0,0.0 -19.7573547363,-19.7573699951 -19.7573547363,-19.7573699951 c 0.0,0.0 14.0142059326,-14.2142181396 14.0142059326,-14.2142181396 c 0.0,0.0 19.7573699951,19.7573699951 19.7573699951,19.7573699951 c 0.0,0.0 -14.0142211914,14.2142181396 -14.0142211914,14.2142181396 Z"
+ android:valueTo="M -3.34053039551,-22.9980926514 c -1.3207244873,-1.3207244873 -3.46876525879,-1.26383972168 -4.74829101563,0.125762939453 c 0.0,0.0 -14.8512420654,14.7411804199 -14.8512420654,14.7411804199 c -1.39259338379,1.392578125 -1.44947814941,3.54061889648 -0.125762939453,4.74827575684 c 0.0,0.0 26.4143981934,26.4144134521 26.4143981934,26.4144134521 c 1.3207244873,1.3207244873 3.46876525879,1.26382446289 4.74829101562,-0.125762939453 c 0.0,0.0 14.7381896973,-14.7381896973 14.7381896973,-14.7381896973 c 1.392578125,-1.39259338379 1.44947814941,-3.54061889648 0.125762939453,-4.74829101562 c 0.0,0.0 -26.3013458252,-26.417388916 -26.3013458252,-26.417388916 Z M 2.87156677246,16.9857940674 c 0.0,0.0 -19.7573547363,-19.7573699951 -19.7573547363,-19.7573699951 c 0.0,0.0 14.0142059326,-14.2142181396 14.0142059326,-14.2142181396 c 0.0,0.0 19.7573699951,19.7573699951 19.7573699951,19.7573699951 c 0.0,0.0 -14.0142211914,14.2142181396 -14.0142211914,14.2142181396 Z"
+ android:valueType="pathType"
+ android:interpolator="@android:interpolator/fast_out_slow_in" />
+ <objectAnimator
+ android:duration="217"
+ android:propertyName="pathData"
+ android:valueFrom="M -3.34053039551,-22.9980926514 c -1.3207244873,-1.3207244873 -3.46876525879,-1.26383972168 -4.74829101563,0.125762939453 c 0.0,0.0 -14.8512420654,14.7411804199 -14.8512420654,14.7411804199 c -1.39259338379,1.392578125 -1.44947814941,3.54061889648 -0.125762939453,4.74827575684 c 0.0,0.0 26.4143981934,26.4144134521 26.4143981934,26.4144134521 c 1.3207244873,1.3207244873 3.46876525879,1.26382446289 4.74829101562,-0.125762939453 c 0.0,0.0 14.7381896973,-14.7381896973 14.7381896973,-14.7381896973 c 1.392578125,-1.39259338379 1.44947814941,-3.54061889648 0.125762939453,-4.74829101562 c 0.0,0.0 -26.3013458252,-26.417388916 -26.3013458252,-26.417388916 Z M 2.87156677246,16.9857940674 c 0.0,0.0 -19.7573547363,-19.7573699951 -19.7573547363,-19.7573699951 c 0.0,0.0 14.0142059326,-14.2142181396 14.0142059326,-14.2142181396 c 0.0,0.0 19.7573699951,19.7573699951 19.7573699951,19.7573699951 c 0.0,0.0 -14.0142211914,14.2142181396 -14.0142211914,14.2142181396 Z"
+ android:valueTo="M -3.5,-20.5 c -1.19999694824,-1.19999694824 -3.10000610352,-1.19999694824 -4.19999694824,0.0 c 0.0,0.0 -12.8000030518,12.6999969482 -12.8000030518,12.6999969482 c -1.19999694824,1.19999694824 -1.19999694824,3.10000610352 0.0,4.19999694824 c 0.0,0.0 24.0,24.0000152588 24.0,24.0000152588 c 1.19999694824,1.19999694824 3.10000610352,1.19999694824 4.19999694824,0.0 c 0.0,0.0 12.6999969482,-12.700012207 12.6999969482,-12.700012207 c 1.20001220703,-1.19999694824 1.20001220703,-3.09999084473 0.0,-4.19999694824 c 0.0,0.0 -23.8999938965,-24.0 -23.8999938965,-24.0 Z M 2.84999084473,15.5500183105 c 0.0,0.0 -18.6000061035,-18.5000457764 -18.6000061035,-18.5000457764 c 0.0,0.0 12.5999908447,-12.8000030518 12.5999908447,-12.8000030518 c 0.0,0.0 18.6000213623,18.5000457764 18.6000213623,18.5000457764 c 0.0,0.0 -12.6000061035,12.8000030518 -12.6000061035,12.8000030518 Z"
+ android:valueType="pathType"
+ android:interpolator="@android:interpolator/fast_out_slow_in" />
+ </set>
+</set>
diff --git a/packages/SystemUI/res/anim/ic_landscape_to_auto_rotate_animation_device.xml b/packages/SystemUI/res/anim/ic_landscape_to_auto_rotate_animation_device.xml
new file mode 100644
index 0000000..4e3a356
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_landscape_to_auto_rotate_animation_device.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<set xmlns:android="http://schemas.android.com/apk/res/android" >
+ <set
+ android:ordering="sequentially" >
+ <objectAnimator
+ android:duration="200"
+ android:propertyName="rotation"
+ android:valueFrom="-45"
+ android:valueTo="-45"
+ android:interpolator="@android:interpolator/fast_out_slow_in" />
+ <objectAnimator
+ android:duration="400"
+ android:propertyName="rotation"
+ android:valueFrom="-45"
+ android:valueTo="0"
+ android:interpolator="@android:interpolator/fast_out_slow_in" />
+ </set>
+</set>
diff --git a/packages/SystemUI/res/anim/ic_portrait_from_auto_rotate_animation_arrow_bottom.xml b/packages/SystemUI/res/anim/ic_portrait_from_auto_rotate_animation_arrow_bottom.xml
new file mode 100644
index 0000000..d05c4e1
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_portrait_from_auto_rotate_animation_arrow_bottom.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<set xmlns:android="http://schemas.android.com/apk/res/android" >
+ <set
+ android:ordering="sequentially" >
+ <objectAnimator
+ android:duration="600"
+ android:propertyName="fillAlpha"
+ android:valueFrom="1"
+ android:valueTo="1"
+ android:interpolator="@android:interpolator/linear" />
+ <objectAnimator
+ android:duration="83"
+ android:propertyName="fillAlpha"
+ android:valueFrom="1"
+ android:valueTo="0"
+ android:interpolator="@android:interpolator/linear" />
+ </set>
+</set>
diff --git a/packages/SystemUI/res/anim/ic_portrait_from_auto_rotate_animation_arrow_top.xml b/packages/SystemUI/res/anim/ic_portrait_from_auto_rotate_animation_arrow_top.xml
new file mode 100644
index 0000000..d05c4e1
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_portrait_from_auto_rotate_animation_arrow_top.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<set xmlns:android="http://schemas.android.com/apk/res/android" >
+ <set
+ android:ordering="sequentially" >
+ <objectAnimator
+ android:duration="600"
+ android:propertyName="fillAlpha"
+ android:valueFrom="1"
+ android:valueTo="1"
+ android:interpolator="@android:interpolator/linear" />
+ <objectAnimator
+ android:duration="83"
+ android:propertyName="fillAlpha"
+ android:valueFrom="1"
+ android:valueTo="0"
+ android:interpolator="@android:interpolator/linear" />
+ </set>
+</set>
diff --git a/packages/SystemUI/res/anim/ic_portrait_from_auto_rotate_animation_arrows.xml b/packages/SystemUI/res/anim/ic_portrait_from_auto_rotate_animation_arrows.xml
new file mode 100644
index 0000000..8bcbf1e
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_portrait_from_auto_rotate_animation_arrows.xml
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<set xmlns:android="http://schemas.android.com/apk/res/android" >
+ <set
+ android:ordering="sequentially" >
+ <objectAnimator
+ android:duration="317"
+ android:propertyName="scaleX"
+ android:valueFrom="1"
+ android:valueTo="1"
+ android:interpolator="@android:interpolator/linear" />
+ <objectAnimator
+ android:duration="333"
+ android:propertyName="scaleX"
+ android:valueFrom="1"
+ android:valueTo="0.9"
+ android:interpolator="@android:interpolator/linear" />
+ </set>
+ <set
+ android:ordering="sequentially" >
+ <objectAnimator
+ android:duration="317"
+ android:propertyName="scaleY"
+ android:valueFrom="1"
+ android:valueTo="1"
+ android:interpolator="@android:interpolator/linear" />
+ <objectAnimator
+ android:duration="333"
+ android:propertyName="scaleY"
+ android:valueFrom="1"
+ android:valueTo="0.9"
+ android:interpolator="@android:interpolator/linear" />
+ </set>
+ <set
+ android:ordering="sequentially" >
+ <objectAnimator
+ android:duration="200"
+ android:propertyName="rotation"
+ android:valueFrom="0"
+ android:valueTo="0"
+ android:interpolator="@android:interpolator/fast_out_slow_in" />
+ <objectAnimator
+ android:duration="617"
+ android:propertyName="rotation"
+ android:valueFrom="0"
+ android:valueTo="-221"
+ android:interpolator="@android:interpolator/fast_out_slow_in" />
+ </set>
+</set>
diff --git a/packages/SystemUI/res/anim/ic_portrait_from_auto_rotate_animation_device.xml b/packages/SystemUI/res/anim/ic_portrait_from_auto_rotate_animation_device.xml
new file mode 100644
index 0000000..79b1827
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_portrait_from_auto_rotate_animation_device.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<set xmlns:android="http://schemas.android.com/apk/res/android" >
+ <set
+ android:ordering="sequentially" >
+ <objectAnimator
+ android:duration="200"
+ android:propertyName="rotation"
+ android:valueFrom="0"
+ android:valueTo="0"
+ android:interpolator="@android:interpolator/fast_out_slow_in" />
+ <objectAnimator
+ android:duration="400"
+ android:propertyName="rotation"
+ android:valueFrom="0"
+ android:valueTo="-135"
+ android:interpolator="@android:interpolator/fast_out_slow_in" />
+ </set>
+</set>
diff --git a/packages/SystemUI/res/anim/ic_portrait_from_auto_rotate_animation_device_1.xml b/packages/SystemUI/res/anim/ic_portrait_from_auto_rotate_animation_device_1.xml
new file mode 100644
index 0000000..a8f5ce0
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_portrait_from_auto_rotate_animation_device_1.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<set xmlns:android="http://schemas.android.com/apk/res/android" >
+ <set
+ android:ordering="sequentially" >
+ <objectAnimator
+ android:duration="267"
+ android:propertyName="pathData"
+ android:valueFrom="M -3.5,-20.5 c -1.19999694824,-1.19999694824 -3.10000610352,-1.19999694824 -4.19999694824,0.0 c 0.0,0.0 -12.8000030518,12.6999969482 -12.8000030518,12.6999969482 c -1.19999694824,1.19999694824 -1.19999694824,3.10000610352 0.0,4.19999694824 c 0.0,0.0 24.0,24.0000152588 24.0,24.0000152588 c 1.19999694824,1.19999694824 3.10000610352,1.19999694824 4.19999694824,0.0 c 0.0,0.0 12.6999969482,-12.700012207 12.6999969482,-12.700012207 c 1.20001220703,-1.19999694824 1.20001220703,-3.09999084473 0.0,-4.19999694824 c 0.0,0.0 -23.8999938965,-24.0 -23.8999938965,-24.0 Z M 2.84999084473,15.5500183105 c 0.0,0.0 -18.6000061035,-18.5000457764 -18.6000061035,-18.5000457764 c 0.0,0.0 12.5999908447,-12.8000030518 12.5999908447,-12.8000030518 c 0.0,0.0 18.6000213623,18.5000457764 18.6000213623,18.5000457764 c 0.0,0.0 -12.6000061035,12.8000030518 -12.6000061035,12.8000030518 Z"
+ android:valueTo="M -3.5,-20.5 c -1.19999694824,-1.19999694824 -3.10000610352,-1.19999694824 -4.19999694824,0.0 c 0.0,0.0 -12.8000030518,12.6999969482 -12.8000030518,12.6999969482 c -1.19999694824,1.19999694824 -1.19999694824,3.10000610352 0.0,4.19999694824 c 0.0,0.0 24.0,24.0000152588 24.0,24.0000152588 c 1.19999694824,1.19999694824 3.10000610352,1.19999694824 4.19999694824,0.0 c 0.0,0.0 12.6999969482,-12.700012207 12.6999969482,-12.700012207 c 1.20001220703,-1.19999694824 1.20001220703,-3.09999084473 0.0,-4.19999694824 c 0.0,0.0 -23.8999938965,-24.0 -23.8999938965,-24.0 Z M 2.84999084473,15.5500183105 c 0.0,0.0 -18.6000061035,-18.5000457764 -18.6000061035,-18.5000457764 c 0.0,0.0 12.5999908447,-12.8000030518 12.5999908447,-12.8000030518 c 0.0,0.0 18.6000213623,18.5000457764 18.6000213623,18.5000457764 c 0.0,0.0 -12.6000061035,12.8000030518 -12.6000061035,12.8000030518 Z"
+ android:valueType="pathType"
+ android:interpolator="@android:interpolator/fast_out_slow_in" />
+ <objectAnimator
+ android:duration="217"
+ android:propertyName="pathData"
+ android:valueFrom="M -3.5,-20.5 c -1.19999694824,-1.19999694824 -3.10000610352,-1.19999694824 -4.19999694824,0.0 c 0.0,0.0 -12.8000030518,12.6999969482 -12.8000030518,12.6999969482 c -1.19999694824,1.19999694824 -1.19999694824,3.10000610352 0.0,4.19999694824 c 0.0,0.0 24.0,24.0000152588 24.0,24.0000152588 c 1.19999694824,1.19999694824 3.10000610352,1.19999694824 4.19999694824,0.0 c 0.0,0.0 12.6999969482,-12.700012207 12.6999969482,-12.700012207 c 1.20001220703,-1.19999694824 1.20001220703,-3.09999084473 0.0,-4.19999694824 c 0.0,0.0 -23.8999938965,-24.0 -23.8999938965,-24.0 Z M 2.84999084473,15.5500183105 c 0.0,0.0 -18.6000061035,-18.5000457764 -18.6000061035,-18.5000457764 c 0.0,0.0 12.5999908447,-12.8000030518 12.5999908447,-12.8000030518 c 0.0,0.0 18.6000213623,18.5000457764 18.6000213623,18.5000457764 c 0.0,0.0 -12.6000061035,12.8000030518 -12.6000061035,12.8000030518 Z"
+ android:valueTo="M -3.34053039551,-22.9980926514 c -1.3207244873,-1.3207244873 -3.46876525879,-1.26383972168 -4.74829101563,0.125762939453 c 0.0,0.0 -14.8512420654,14.7411804199 -14.8512420654,14.7411804199 c -1.39259338379,1.392578125 -1.44947814941,3.54061889648 -0.125762939453,4.74827575684 c 0.0,0.0 26.4143981934,26.4144134521 26.4143981934,26.4144134521 c 1.3207244873,1.3207244873 3.46876525879,1.26382446289 4.74829101562,-0.125762939453 c 0.0,0.0 14.7381896973,-14.7381896973 14.7381896973,-14.7381896973 c 1.392578125,-1.39259338379 1.44947814941,-3.54061889648 0.125762939453,-4.74829101562 c 0.0,0.0 -26.3013458252,-26.417388916 -26.3013458252,-26.417388916 Z M 2.87156677246,16.9857940674 c 0.0,0.0 -19.7573547363,-19.7573699951 -19.7573547363,-19.7573699951 c 0.0,0.0 14.0142059326,-14.2142181396 14.0142059326,-14.2142181396 c 0.0,0.0 19.7573699951,19.7573699951 19.7573699951,19.7573699951 c 0.0,0.0 -14.0142211914,14.2142181396 -14.0142211914,14.2142181396 Z"
+ android:valueType="pathType"
+ android:interpolator="@android:interpolator/fast_out_slow_in" />
+ </set>
+</set>
diff --git a/packages/SystemUI/res/anim/ic_portrait_to_auto_rotate_animation_arrow_bottom.xml b/packages/SystemUI/res/anim/ic_portrait_to_auto_rotate_animation_arrow_bottom.xml
new file mode 100644
index 0000000..c3ae6c1
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_portrait_to_auto_rotate_animation_arrow_bottom.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<set xmlns:android="http://schemas.android.com/apk/res/android" >
+ <set
+ android:ordering="sequentially" >
+ <objectAnimator
+ android:duration="250"
+ android:propertyName="fillAlpha"
+ android:valueFrom="0"
+ android:valueTo="0"
+ android:interpolator="@android:interpolator/linear" />
+ <objectAnimator
+ android:duration="83"
+ android:propertyName="fillAlpha"
+ android:valueFrom="0"
+ android:valueTo="1"
+ android:interpolator="@android:interpolator/linear" />
+ </set>
+</set>
diff --git a/packages/SystemUI/res/anim/ic_portrait_to_auto_rotate_animation_arrow_top.xml b/packages/SystemUI/res/anim/ic_portrait_to_auto_rotate_animation_arrow_top.xml
new file mode 100644
index 0000000..c3ae6c1
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_portrait_to_auto_rotate_animation_arrow_top.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<set xmlns:android="http://schemas.android.com/apk/res/android" >
+ <set
+ android:ordering="sequentially" >
+ <objectAnimator
+ android:duration="250"
+ android:propertyName="fillAlpha"
+ android:valueFrom="0"
+ android:valueTo="0"
+ android:interpolator="@android:interpolator/linear" />
+ <objectAnimator
+ android:duration="83"
+ android:propertyName="fillAlpha"
+ android:valueFrom="0"
+ android:valueTo="1"
+ android:interpolator="@android:interpolator/linear" />
+ </set>
+</set>
diff --git a/packages/SystemUI/res/anim/ic_portrait_to_auto_rotate_animation_arrows.xml b/packages/SystemUI/res/anim/ic_portrait_to_auto_rotate_animation_arrows.xml
new file mode 100644
index 0000000..fde172a
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_portrait_to_auto_rotate_animation_arrows.xml
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<set xmlns:android="http://schemas.android.com/apk/res/android" >
+ <set
+ android:ordering="sequentially" >
+ <objectAnimator
+ android:duration="333"
+ android:propertyName="scaleX"
+ android:valueFrom="0.9"
+ android:valueTo="0.9"
+ android:interpolator="@android:interpolator/linear" />
+ <objectAnimator
+ android:duration="333"
+ android:propertyName="scaleX"
+ android:valueFrom="0.9"
+ android:valueTo="1"
+ android:interpolator="@android:interpolator/linear" />
+ </set>
+ <set
+ android:ordering="sequentially" >
+ <objectAnimator
+ android:duration="333"
+ android:propertyName="scaleY"
+ android:valueFrom="0.9"
+ android:valueTo="0.9"
+ android:interpolator="@android:interpolator/linear" />
+ <objectAnimator
+ android:duration="333"
+ android:propertyName="scaleY"
+ android:valueFrom="0.9"
+ android:valueTo="1"
+ android:interpolator="@android:interpolator/linear" />
+ </set>
+ <set
+ android:ordering="sequentially" >
+ <objectAnimator
+ android:duration="200"
+ android:propertyName="rotation"
+ android:valueFrom="-221"
+ android:valueTo="-221"
+ android:interpolator="@android:interpolator/fast_out_slow_in" />
+ <objectAnimator
+ android:duration="617"
+ android:propertyName="rotation"
+ android:valueFrom="-221"
+ android:valueTo="0"
+ android:interpolator="@android:interpolator/fast_out_slow_in" />
+ </set>
+</set>
diff --git a/packages/SystemUI/res/anim/ic_portrait_to_auto_rotate_animation_device.xml b/packages/SystemUI/res/anim/ic_portrait_to_auto_rotate_animation_device.xml
new file mode 100644
index 0000000..accf16d
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_portrait_to_auto_rotate_animation_device.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<set xmlns:android="http://schemas.android.com/apk/res/android" >
+ <set
+ android:ordering="sequentially" >
+ <objectAnimator
+ android:duration="250"
+ android:propertyName="rotation"
+ android:valueFrom="-135"
+ android:valueTo="-135"
+ android:interpolator="@android:interpolator/fast_out_slow_in" />
+ <objectAnimator
+ android:duration="400"
+ android:propertyName="rotation"
+ android:valueFrom="-135"
+ android:valueTo="0"
+ android:interpolator="@android:interpolator/fast_out_slow_in" />
+ </set>
+</set>
diff --git a/packages/SystemUI/res/anim/ic_portrait_to_auto_rotate_animation_device_1.xml b/packages/SystemUI/res/anim/ic_portrait_to_auto_rotate_animation_device_1.xml
new file mode 100644
index 0000000..15c6705
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_portrait_to_auto_rotate_animation_device_1.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<set xmlns:android="http://schemas.android.com/apk/res/android" >
+ <set
+ android:ordering="sequentially" >
+ <objectAnimator
+ android:duration="250"
+ android:propertyName="pathData"
+ android:valueFrom="M -3.34053039551,-22.9980926514 c -1.3207244873,-1.3207244873 -3.46876525879,-1.26383972168 -4.74829101563,0.125762939453 c 0.0,0.0 -14.8512420654,14.7411804199 -14.8512420654,14.7411804199 c -1.39259338379,1.392578125 -1.44947814941,3.54061889648 -0.125762939453,4.74827575684 c 0.0,0.0 26.4143981934,26.4144134521 26.4143981934,26.4144134521 c 1.3207244873,1.3207244873 3.46876525879,1.26382446289 4.74829101562,-0.125762939453 c 0.0,0.0 14.7381896973,-14.7381896973 14.7381896973,-14.7381896973 c 1.392578125,-1.39259338379 1.44947814941,-3.54061889648 0.125762939453,-4.74829101562 c 0.0,0.0 -26.3013458252,-26.417388916 -26.3013458252,-26.417388916 Z M 2.87156677246,16.9857940674 c 0.0,0.0 -19.7573547363,-19.7573699951 -19.7573547363,-19.7573699951 c 0.0,0.0 14.0142059326,-14.2142181396 14.0142059326,-14.2142181396 c 0.0,0.0 19.7573699951,19.7573699951 19.7573699951,19.7573699951 c 0.0,0.0 -14.0142211914,14.2142181396 -14.0142211914,14.2142181396 Z"
+ android:valueTo="M -3.34053039551,-22.9980926514 c -1.3207244873,-1.3207244873 -3.46876525879,-1.26383972168 -4.74829101563,0.125762939453 c 0.0,0.0 -14.8512420654,14.7411804199 -14.8512420654,14.7411804199 c -1.39259338379,1.392578125 -1.44947814941,3.54061889648 -0.125762939453,4.74827575684 c 0.0,0.0 26.4143981934,26.4144134521 26.4143981934,26.4144134521 c 1.3207244873,1.3207244873 3.46876525879,1.26382446289 4.74829101562,-0.125762939453 c 0.0,0.0 14.7381896973,-14.7381896973 14.7381896973,-14.7381896973 c 1.392578125,-1.39259338379 1.44947814941,-3.54061889648 0.125762939453,-4.74829101562 c 0.0,0.0 -26.3013458252,-26.417388916 -26.3013458252,-26.417388916 Z M 2.87156677246,16.9857940674 c 0.0,0.0 -19.7573547363,-19.7573699951 -19.7573547363,-19.7573699951 c 0.0,0.0 14.0142059326,-14.2142181396 14.0142059326,-14.2142181396 c 0.0,0.0 19.7573699951,19.7573699951 19.7573699951,19.7573699951 c 0.0,0.0 -14.0142211914,14.2142181396 -14.0142211914,14.2142181396 Z"
+ android:valueType="pathType"
+ android:interpolator="@android:interpolator/fast_out_slow_in" />
+ <objectAnimator
+ android:duration="500"
+ android:propertyName="pathData"
+ android:valueFrom="M -3.34053039551,-22.9980926514 c -1.3207244873,-1.3207244873 -3.46876525879,-1.26383972168 -4.74829101563,0.125762939453 c 0.0,0.0 -14.8512420654,14.7411804199 -14.8512420654,14.7411804199 c -1.39259338379,1.392578125 -1.44947814941,3.54061889648 -0.125762939453,4.74827575684 c 0.0,0.0 26.4143981934,26.4144134521 26.4143981934,26.4144134521 c 1.3207244873,1.3207244873 3.46876525879,1.26382446289 4.74829101562,-0.125762939453 c 0.0,0.0 14.7381896973,-14.7381896973 14.7381896973,-14.7381896973 c 1.392578125,-1.39259338379 1.44947814941,-3.54061889648 0.125762939453,-4.74829101562 c 0.0,0.0 -26.3013458252,-26.417388916 -26.3013458252,-26.417388916 Z M 2.87156677246,16.9857940674 c 0.0,0.0 -19.7573547363,-19.7573699951 -19.7573547363,-19.7573699951 c 0.0,0.0 14.0142059326,-14.2142181396 14.0142059326,-14.2142181396 c 0.0,0.0 19.7573699951,19.7573699951 19.7573699951,19.7573699951 c 0.0,0.0 -14.0142211914,14.2142181396 -14.0142211914,14.2142181396 Z"
+ android:valueTo="M -3.5,-20.5 c -1.19999694824,-1.19999694824 -3.10000610352,-1.19999694824 -4.19999694824,0.0 c 0.0,0.0 -12.8000030518,12.6999969482 -12.8000030518,12.6999969482 c -1.19999694824,1.19999694824 -1.19999694824,3.10000610352 0.0,4.19999694824 c 0.0,0.0 24.0,24.0000152588 24.0,24.0000152588 c 1.19999694824,1.19999694824 3.10000610352,1.19999694824 4.19999694824,0.0 c 0.0,0.0 12.6999969482,-12.700012207 12.6999969482,-12.700012207 c 1.20001220703,-1.19999694824 1.20001220703,-3.09999084473 0.0,-4.19999694824 c 0.0,0.0 -23.8999938965,-24.0 -23.8999938965,-24.0 Z M 2.84999084473,15.5500183105 c 0.0,0.0 -18.6000061035,-18.5000457764 -18.6000061035,-18.5000457764 c 0.0,0.0 12.5999908447,-12.8000030518 12.5999908447,-12.8000030518 c 0.0,0.0 18.6000213623,18.5000457764 18.6000213623,18.5000457764 c 0.0,0.0 -12.6000061035,12.8000030518 -12.6000061035,12.8000030518 Z"
+ android:valueType="pathType"
+ android:interpolator="@android:interpolator/fast_out_slow_in" />
+ </set>
+</set>
diff --git a/packages/SystemUI/res/anim/ic_signal_airplane_disable_animation_cross_1.xml b/packages/SystemUI/res/anim/ic_signal_airplane_disable_animation_cross_1.xml
new file mode 100644
index 0000000..553da1a
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_signal_airplane_disable_animation_cross_1.xml
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<set xmlns:android="http://schemas.android.com/apk/res/android" >
+ <set
+ android:ordering="sequentially" >
+ <objectAnimator
+ android:duration="200"
+ android:propertyName="pathData"
+ android:valueFrom="M 7.54049682617,3.9430847168 c 0.0,0.0 0.324981689453,0.399978637695 0.324981689453,0.399978637695 "
+ android:valueTo="M 7.54049682617,3.9430847168 c 0.0,0.0 0.324981689453,0.399978637695 0.324981689453,0.399978637695 "
+ android:valueType="pathType"
+ android:interpolator="@android:interpolator/linear" />
+ <objectAnimator
+ android:duration="350"
+ android:propertyName="pathData"
+ android:valueFrom="M 7.54049682617,3.9430847168 c 0.0,0.0 0.324981689453,0.399978637695 0.324981689453,0.399978637695 "
+ android:valueTo="M 7.54049682617,3.9430847168 c 0.0,0.0 31.5749816895,31.4499664307 31.5749816895,31.4499664307 "
+ android:valueType="pathType"
+ android:interpolator="@interpolator/ic_signal_airplane_disable_cross_1_pathdata_interpolator" />
+ </set>
+ <set
+ android:ordering="sequentially" >
+ <objectAnimator
+ android:duration="200"
+ android:propertyName="strokeAlpha"
+ android:valueFrom="0"
+ android:valueTo="0"
+ android:interpolator="@android:interpolator/linear" />
+ <objectAnimator
+ android:duration="17"
+ android:propertyName="strokeAlpha"
+ android:valueFrom="0"
+ android:valueTo="1"
+ android:interpolator="@android:interpolator/linear" />
+ </set>
+</set>
diff --git a/packages/SystemUI/res/anim/ic_signal_airplane_disable_animation_ic_signal_airplane.xml b/packages/SystemUI/res/anim/ic_signal_airplane_disable_animation_ic_signal_airplane.xml
new file mode 100644
index 0000000..9cc3b8e
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_signal_airplane_disable_animation_ic_signal_airplane.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<set xmlns:android="http://schemas.android.com/apk/res/android" >
+ <set
+ android:ordering="sequentially" >
+ <objectAnimator
+ android:duration="200"
+ android:propertyName="alpha"
+ android:valueFrom="1"
+ android:valueTo="1"
+ android:interpolator="@android:interpolator/fast_out_slow_in" />
+ <objectAnimator
+ android:duration="350"
+ android:propertyName="alpha"
+ android:valueFrom="1"
+ android:valueTo="0.5"
+ android:interpolator="@android:interpolator/fast_out_slow_in" />
+ </set>
+</set>
diff --git a/packages/SystemUI/res/anim/ic_signal_airplane_disable_animation_mask.xml b/packages/SystemUI/res/anim/ic_signal_airplane_disable_animation_mask.xml
new file mode 100644
index 0000000..605ef90
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_signal_airplane_disable_animation_mask.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<set xmlns:android="http://schemas.android.com/apk/res/android" >
+ <set
+ android:ordering="sequentially" >
+ <objectAnimator
+ android:duration="200"
+ android:propertyName="pathData"
+ android:valueFrom="M 37.8337860107,-40.4599914551 c 0.0,0.0 -35.8077850342,31.5523681641 -35.8077850342,31.5523681641 c 0.0,0.0 9.55097961426,9.55285644531 9.55097961426,9.55285644531 c 0.0,0.0 -2.61698913574,2.09387207031 -2.61698913574,2.09387207031 c 0.0,0.0 -9.75096130371,-9.56428527832 -9.75096130371,-9.56428527832 c 0.0,0.0 -34.6200408936,25.4699249268 -34.6200408936,25.4699249268 c 0.0,0.0 55.9664764404,69.742401123 55.9664764404,69.742401123 c 0.0,0.0 73.2448120117,-59.1047973633 73.2448120117,-59.1047973633 c 0.0,0.0 -55.9664916992,-69.7423400879 -55.9664916992,-69.7423400879 Z"
+ android:valueTo="M 37.8337860107,-40.4599914551 c 0.0,0.0 -35.8077850342,31.5523681641 -35.8077850342,31.5523681641 c 0.0,0.0 9.55097961426,9.55285644531 9.55097961426,9.55285644531 c 0.0,0.0 -2.61698913574,2.09387207031 -2.61698913574,2.09387207031 c 0.0,0.0 -9.75096130371,-9.56428527832 -9.75096130371,-9.56428527832 c 0.0,0.0 -34.6200408936,25.4699249268 -34.6200408936,25.4699249268 c 0.0,0.0 55.9664764404,69.742401123 55.9664764404,69.742401123 c 0.0,0.0 73.2448120117,-59.1047973633 73.2448120117,-59.1047973633 c 0.0,0.0 -55.9664916992,-69.7423400879 -55.9664916992,-69.7423400879 Z"
+ android:valueType="pathType"
+ android:interpolator="@android:interpolator/fast_out_slow_in" />
+ <objectAnimator
+ android:duration="350"
+ android:propertyName="pathData"
+ android:valueFrom="M 37.8337860107,-40.4599914551 c 0.0,0.0 -35.8077850342,31.5523681641 -35.8077850342,31.5523681641 c 0.0,0.0 9.55097961426,9.55285644531 9.55097961426,9.55285644531 c 0.0,0.0 -2.61698913574,2.09387207031 -2.61698913574,2.09387207031 c 0.0,0.0 -9.75096130371,-9.56428527832 -9.75096130371,-9.56428527832 c 0.0,0.0 -34.6200408936,25.4699249268 -34.6200408936,25.4699249268 c 0.0,0.0 55.9664764404,69.742401123 55.9664764404,69.742401123 c 0.0,0.0 73.2448120117,-59.1047973633 73.2448120117,-59.1047973633 c 0.0,0.0 -55.9664916992,-69.7423400879 -55.9664916992,-69.7423400879 Z"
+ android:valueTo="M 37.8337860107,-40.3974914551 c 0.0,0.0 -35.8077850342,31.5523681641 -35.8077850342,31.5523681641 c 0.0,0.0 40.9884796143,40.9278411865 40.9884796143,40.9278411865 c 0.0,0.0 -2.61700439453,2.0938873291 -2.61700439453,2.0938873291 c 0.0,0.0 -41.1884460449,-40.9392852783 -41.1884460449,-40.9392852783 c 0.0,0.0 -34.6200408936,25.4699249268 -34.6200408936,25.4699249268 c 0.0,0.0 55.9664764404,69.742401123 55.9664764404,69.742401123 c 0.0,0.0 73.2448120117,-59.1047973633 73.2448120117,-59.1047973633 c 0.0,0.0 -55.9664916992,-69.7423400879 -55.9664916992,-69.7423400879 Z"
+ android:valueType="pathType"
+ android:interpolator="@android:interpolator/fast_out_slow_in" />
+ </set>
+</set>
diff --git a/packages/SystemUI/res/anim/ic_signal_airplane_disable_animation_root.xml b/packages/SystemUI/res/anim/ic_signal_airplane_disable_animation_root.xml
new file mode 100644
index 0000000..770c401
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_signal_airplane_disable_animation_root.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<set xmlns:android="http://schemas.android.com/apk/res/android" >
+ <objectAnimator
+ android:duration="350"
+ android:propertyName="alpha"
+ android:valueFrom="1.0"
+ android:valueTo="0.3"
+ android:interpolator="@android:interpolator/fast_out_slow_in" />
+</set>
diff --git a/packages/SystemUI/res/anim/ic_signal_airplane_enable_animation_cross_1.xml b/packages/SystemUI/res/anim/ic_signal_airplane_enable_animation_cross_1.xml
new file mode 100644
index 0000000..87cbaec
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_signal_airplane_enable_animation_cross_1.xml
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<set xmlns:android="http://schemas.android.com/apk/res/android" >
+ <set
+ android:ordering="sequentially" >
+ <objectAnimator
+ android:duration="200"
+ android:propertyName="pathData"
+ android:valueFrom="M 7.54049682617,3.9430847168 c 0.0,0.0 31.5749816895,31.4499664307 31.5749816895,31.4499664307 "
+ android:valueTo="M 7.54049682617,3.9430847168 c 0.0,0.0 31.5749816895,31.4499664307 31.5749816895,31.4499664307 "
+ android:valueType="pathType"
+ android:interpolator="@android:interpolator/linear" />
+ <objectAnimator
+ android:duration="350"
+ android:propertyName="pathData"
+ android:valueFrom="M 7.54049682617,3.9430847168 c 0.0,0.0 31.5749816895,31.4499664307 31.5749816895,31.4499664307 "
+ android:valueTo="M 7.54049682617,3.9430847168 c 0.0,0.0 0.324981689453,0.399978637695 0.324981689453,0.399978637695 "
+ android:valueType="pathType"
+ android:interpolator="@interpolator/ic_signal_airplane_enable_cross_1_pathdata_interpolator" />
+ </set>
+ <set
+ android:ordering="sequentially" >
+ <objectAnimator
+ android:duration="533"
+ android:propertyName="strokeAlpha"
+ android:valueFrom="1"
+ android:valueTo="1"
+ android:interpolator="@android:interpolator/linear" />
+ <objectAnimator
+ android:duration="17"
+ android:propertyName="strokeAlpha"
+ android:valueFrom="1"
+ android:valueTo="0"
+ android:interpolator="@android:interpolator/linear" />
+ </set>
+</set>
diff --git a/packages/SystemUI/res/anim/ic_signal_airplane_enable_animation_ic_signal_airplane.xml b/packages/SystemUI/res/anim/ic_signal_airplane_enable_animation_ic_signal_airplane.xml
new file mode 100644
index 0000000..5fdb2a0
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_signal_airplane_enable_animation_ic_signal_airplane.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<set xmlns:android="http://schemas.android.com/apk/res/android" >
+ <set
+ android:ordering="sequentially" >
+ <objectAnimator
+ android:duration="200"
+ android:propertyName="alpha"
+ android:valueFrom="0.5"
+ android:valueTo="0.5"
+ android:interpolator="@android:interpolator/fast_out_slow_in" />
+ <objectAnimator
+ android:duration="350"
+ android:propertyName="alpha"
+ android:valueFrom="0.5"
+ android:valueTo="1"
+ android:interpolator="@android:interpolator/fast_out_slow_in" />
+ </set>
+</set>
diff --git a/packages/SystemUI/res/anim/ic_signal_airplane_enable_animation_mask.xml b/packages/SystemUI/res/anim/ic_signal_airplane_enable_animation_mask.xml
new file mode 100644
index 0000000..56e0d1c
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_signal_airplane_enable_animation_mask.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<set xmlns:android="http://schemas.android.com/apk/res/android" >
+ <set
+ android:ordering="sequentially" >
+ <objectAnimator
+ android:duration="200"
+ android:propertyName="pathData"
+ android:valueFrom="M 37.8337860107,-40.3974914551 c 0.0,0.0 -35.8077850342,31.5523681641 -35.8077850342,31.5523681641 c 0.0,0.0 40.9884796143,40.9278411865 40.9884796143,40.9278411865 c 0.0,0.0 -2.61700439453,2.0938873291 -2.61700439453,2.0938873291 c 0.0,0.0 -41.1884460449,-40.9392852783 -41.1884460449,-40.9392852783 c 0.0,0.0 -34.6200408936,25.4699249268 -34.6200408936,25.4699249268 c 0.0,0.0 55.9664764404,69.742401123 55.9664764404,69.742401123 c 0.0,0.0 73.2448120117,-59.1047973633 73.2448120117,-59.1047973633 c 0.0,0.0 -55.9664916992,-69.7423400879 -55.9664916992,-69.7423400879 Z"
+ android:valueTo="M 37.8337860107,-40.3974914551 c 0.0,0.0 -35.8077850342,31.5523681641 -35.8077850342,31.5523681641 c 0.0,0.0 40.9884796143,40.9278411865 40.9884796143,40.9278411865 c 0.0,0.0 -2.61700439453,2.0938873291 -2.61700439453,2.0938873291 c 0.0,0.0 -41.1884460449,-40.9392852783 -41.1884460449,-40.9392852783 c 0.0,0.0 -34.6200408936,25.4699249268 -34.6200408936,25.4699249268 c 0.0,0.0 55.9664764404,69.742401123 55.9664764404,69.742401123 c 0.0,0.0 73.2448120117,-59.1047973633 73.2448120117,-59.1047973633 c 0.0,0.0 -55.9664916992,-69.7423400879 -55.9664916992,-69.7423400879 Z"
+ android:valueType="pathType"
+ android:interpolator="@android:interpolator/linear" />
+ <objectAnimator
+ android:duration="350"
+ android:propertyName="pathData"
+ android:valueFrom="M 37.8337860107,-40.3974914551 c 0.0,0.0 -35.8077850342,31.5523681641 -35.8077850342,31.5523681641 c 0.0,0.0 40.9884796143,40.9278411865 40.9884796143,40.9278411865 c 0.0,0.0 -2.61700439453,2.0938873291 -2.61700439453,2.0938873291 c 0.0,0.0 -41.1884460449,-40.9392852783 -41.1884460449,-40.9392852783 c 0.0,0.0 -34.6200408936,25.4699249268 -34.6200408936,25.4699249268 c 0.0,0.0 55.9664764404,69.742401123 55.9664764404,69.742401123 c 0.0,0.0 73.2448120117,-59.1047973633 73.2448120117,-59.1047973633 c 0.0,0.0 -55.9664916992,-69.7423400879 -55.9664916992,-69.7423400879 Z"
+ android:valueTo="M 37.8337860107,-40.4599914551 c 0.0,0.0 -35.8077850342,31.5523681641 -35.8077850342,31.5523681641 c 0.0,0.0 9.55097961426,9.55285644531 9.55097961426,9.55285644531 c 0.0,0.0 -2.61698913574,2.09387207031 -2.61698913574,2.09387207031 c 0.0,0.0 -9.75096130371,-9.56428527832 -9.75096130371,-9.56428527832 c 0.0,0.0 -34.6200408936,25.4699249268 -34.6200408936,25.4699249268 c 0.0,0.0 55.9664764404,69.742401123 55.9664764404,69.742401123 c 0.0,0.0 73.2448120117,-59.1047973633 73.2448120117,-59.1047973633 c 0.0,0.0 -55.9664916992,-69.7423400879 -55.9664916992,-69.7423400879 Z"
+ android:valueType="pathType"
+ android:interpolator="@interpolator/ic_signal_airplane_enable_mask_pathdata_interpolator" />
+ </set>
+</set>
diff --git a/packages/SystemUI/res/anim/ic_signal_airplane_enable_animation_root.xml b/packages/SystemUI/res/anim/ic_signal_airplane_enable_animation_root.xml
new file mode 100644
index 0000000..387ca29
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_signal_airplane_enable_animation_root.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<set xmlns:android="http://schemas.android.com/apk/res/android" >
+ <objectAnimator
+ android:duration="350"
+ android:propertyName="alpha"
+ android:valueFrom="0.3"
+ android:valueTo="1.0"
+ android:interpolator="@android:interpolator/fast_out_slow_in" />
+</set>
diff --git a/packages/SystemUI/res/anim/ic_signal_flashlight_disable_animation_cross_1.xml b/packages/SystemUI/res/anim/ic_signal_flashlight_disable_animation_cross_1.xml
new file mode 100644
index 0000000..aff3567
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_signal_flashlight_disable_animation_cross_1.xml
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<set xmlns:android="http://schemas.android.com/apk/res/android" >
+ <set
+ android:ordering="sequentially" >
+ <objectAnimator
+ android:duration="200"
+ android:propertyName="pathData"
+ android:valueFrom="M 8.34049987793,5.6930847168 c 0.0,0.0 0.274993896484,0.29997253418 0.274993896484,0.29997253418 "
+ android:valueTo="M 8.34049987793,5.6930847168 c 0.0,0.0 0.274993896484,0.29997253418 0.274993896484,0.29997253418 "
+ android:valueType="pathType"
+ android:interpolator="@android:interpolator/fast_out_slow_in" />
+ <objectAnimator
+ android:duration="350"
+ android:propertyName="pathData"
+ android:valueFrom="M 8.34049987793,5.6930847168 c 0.0,0.0 0.274993896484,0.29997253418 0.274993896484,0.29997253418 "
+ android:valueTo="M 8.34049987793,5.6930847168 c 0.0,0.0 29.7749786377,29.7999725342 29.7749786377,29.7999725342 "
+ android:valueType="pathType"
+ android:interpolator="@android:interpolator/fast_out_slow_in" />
+ </set>
+ <set
+ android:ordering="sequentially" >
+ <objectAnimator
+ android:duration="200"
+ android:propertyName="strokeAlpha"
+ android:valueFrom="0"
+ android:valueTo="0"
+ android:interpolator="@android:interpolator/linear" />
+ <objectAnimator
+ android:duration="17"
+ android:propertyName="strokeAlpha"
+ android:valueFrom="0"
+ android:valueTo="1"
+ android:interpolator="@android:interpolator/linear" />
+ </set>
+</set>
diff --git a/packages/SystemUI/res/anim/ic_signal_flashlight_disable_animation_ic_signal_flashlight.xml b/packages/SystemUI/res/anim/ic_signal_flashlight_disable_animation_ic_signal_flashlight.xml
new file mode 100644
index 0000000..9cc3b8e
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_signal_flashlight_disable_animation_ic_signal_flashlight.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<set xmlns:android="http://schemas.android.com/apk/res/android" >
+ <set
+ android:ordering="sequentially" >
+ <objectAnimator
+ android:duration="200"
+ android:propertyName="alpha"
+ android:valueFrom="1"
+ android:valueTo="1"
+ android:interpolator="@android:interpolator/fast_out_slow_in" />
+ <objectAnimator
+ android:duration="350"
+ android:propertyName="alpha"
+ android:valueFrom="1"
+ android:valueTo="0.5"
+ android:interpolator="@android:interpolator/fast_out_slow_in" />
+ </set>
+</set>
diff --git a/packages/SystemUI/res/anim/ic_signal_flashlight_disable_animation_mask.xml b/packages/SystemUI/res/anim/ic_signal_flashlight_disable_animation_mask.xml
new file mode 100644
index 0000000..31583f2
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_signal_flashlight_disable_animation_mask.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<set xmlns:android="http://schemas.android.com/apk/res/android" >
+ <set
+ android:ordering="sequentially" >
+ <objectAnimator
+ android:duration="200"
+ android:propertyName="pathData"
+ android:valueFrom="M 37.8337860107,-39.2849731445 c 0.0,0.0 -35.8077850342,31.5523681641 -35.8077850342,31.5523681641 c 0.0,0.0 9.55097961426,9.55285644531 9.55097961426,9.55285644531 c 0.0,0.0 -2.61698913574,2.09387207031 -2.61698913574,2.09387207031 c 0.0,0.0 -9.75096130371,-9.56428527832 -9.75096130371,-9.56428527832 c 0.0,0.0 -34.6200408936,25.4699249268 -34.6200408936,25.4699249268 c 0.0,0.0 55.9664764404,69.742401123 55.9664764404,69.742401123 c 0.0,0.0 73.2448120117,-59.1047973633 73.2448120117,-59.1047973633 c 0.0,0.0 -55.9664916992,-69.7423400879 -55.9664916992,-69.7423400879 Z"
+ android:valueTo="M 37.8337860107,-39.2849731445 c 0.0,0.0 -35.8077850342,31.5523681641 -35.8077850342,31.5523681641 c 0.0,0.0 9.55097961426,9.55285644531 9.55097961426,9.55285644531 c 0.0,0.0 -2.61698913574,2.09387207031 -2.61698913574,2.09387207031 c 0.0,0.0 -9.75096130371,-9.56428527832 -9.75096130371,-9.56428527832 c 0.0,0.0 -34.6200408936,25.4699249268 -34.6200408936,25.4699249268 c 0.0,0.0 55.9664764404,69.742401123 55.9664764404,69.742401123 c 0.0,0.0 73.2448120117,-59.1047973633 73.2448120117,-59.1047973633 c 0.0,0.0 -55.9664916992,-69.7423400879 -55.9664916992,-69.7423400879 Z"
+ android:valueType="pathType"
+ android:interpolator="@android:interpolator/fast_out_slow_in" />
+ <objectAnimator
+ android:duration="350"
+ android:propertyName="pathData"
+ android:valueFrom="M 37.8337860107,-39.2849731445 c 0.0,0.0 -35.8077850342,31.5523681641 -35.8077850342,31.5523681641 c 0.0,0.0 9.55097961426,9.55285644531 9.55097961426,9.55285644531 c 0.0,0.0 -2.61698913574,2.09387207031 -2.61698913574,2.09387207031 c 0.0,0.0 -9.75096130371,-9.56428527832 -9.75096130371,-9.56428527832 c 0.0,0.0 -34.6200408936,25.4699249268 -34.6200408936,25.4699249268 c 0.0,0.0 55.9664764404,69.742401123 55.9664764404,69.742401123 c 0.0,0.0 73.2448120117,-59.1047973633 73.2448120117,-59.1047973633 c 0.0,0.0 -55.9664916992,-69.7423400879 -55.9664916992,-69.7423400879 Z"
+ android:valueTo="M 37.8337860107,-39.2975769043 c 0.0,0.0 -35.8077850342,31.5523681641 -35.8077850342,31.5523681641 c 0.0,0.0 40.9884796143,40.9278411865 40.9884796143,40.9278411865 c 0.0,0.0 -2.61700439453,2.0938873291 -2.61700439453,2.0938873291 c 0.0,0.0 -41.1884460449,-40.9392852783 -41.1884460449,-40.9392852783 c 0.0,0.0 -34.6200408936,25.4699249268 -34.6200408936,25.4699249268 c 0.0,0.0 55.9664764404,69.742401123 55.9664764404,69.742401123 c 0.0,0.0 73.2448120117,-59.1047973633 73.2448120117,-59.1047973633 c 0.0,0.0 -55.9664916992,-69.7423400879 -55.9664916992,-69.7423400879 Z"
+ android:valueType="pathType"
+ android:interpolator="@android:interpolator/fast_out_slow_in" />
+ </set>
+</set>
diff --git a/packages/SystemUI/res/anim/ic_signal_flashlight_disable_animation_root.xml b/packages/SystemUI/res/anim/ic_signal_flashlight_disable_animation_root.xml
new file mode 100644
index 0000000..770c401
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_signal_flashlight_disable_animation_root.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<set xmlns:android="http://schemas.android.com/apk/res/android" >
+ <objectAnimator
+ android:duration="350"
+ android:propertyName="alpha"
+ android:valueFrom="1.0"
+ android:valueTo="0.3"
+ android:interpolator="@android:interpolator/fast_out_slow_in" />
+</set>
diff --git a/packages/SystemUI/res/anim/ic_signal_flashlight_enable_animation_cross_1.xml b/packages/SystemUI/res/anim/ic_signal_flashlight_enable_animation_cross_1.xml
new file mode 100644
index 0000000..c923015
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_signal_flashlight_enable_animation_cross_1.xml
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<set xmlns:android="http://schemas.android.com/apk/res/android" >
+ <set
+ android:ordering="sequentially" >
+ <objectAnimator
+ android:duration="200"
+ android:propertyName="pathData"
+ android:valueFrom="M 8.34049987793,5.6930847168 c 0.0,0.0 29.7749786377,29.7999725342 29.7749786377,29.7999725342 "
+ android:valueTo="M 8.34049987793,5.6930847168 c 0.0,0.0 29.7749786377,29.7999725342 29.7749786377,29.7999725342 "
+ android:valueType="pathType"
+ android:interpolator="@android:interpolator/linear" />
+ <objectAnimator
+ android:duration="350"
+ android:propertyName="pathData"
+ android:valueFrom="M 8.34049987793,5.6930847168 c 0.0,0.0 29.7749786377,29.7999725342 29.7749786377,29.7999725342 "
+ android:valueTo="M 8.34049987793,5.6930847168 c 0.0,0.0 0.274993896484,0.29997253418 0.274993896484,0.29997253418 "
+ android:valueType="pathType"
+ android:interpolator="@interpolator/ic_signal_flashlight_enable_cross_1_pathdata_interpolator" />
+ </set>
+ <set
+ android:ordering="sequentially" >
+ <objectAnimator
+ android:duration="533"
+ android:propertyName="strokeAlpha"
+ android:valueFrom="1"
+ android:valueTo="1"
+ android:interpolator="@android:interpolator/linear" />
+ <objectAnimator
+ android:duration="17"
+ android:propertyName="strokeAlpha"
+ android:valueFrom="1"
+ android:valueTo="0"
+ android:interpolator="@android:interpolator/linear" />
+ </set>
+</set>
diff --git a/packages/SystemUI/res/anim/ic_signal_flashlight_enable_animation_ic_signal_flashlight.xml b/packages/SystemUI/res/anim/ic_signal_flashlight_enable_animation_ic_signal_flashlight.xml
new file mode 100644
index 0000000..5fdb2a0
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_signal_flashlight_enable_animation_ic_signal_flashlight.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<set xmlns:android="http://schemas.android.com/apk/res/android" >
+ <set
+ android:ordering="sequentially" >
+ <objectAnimator
+ android:duration="200"
+ android:propertyName="alpha"
+ android:valueFrom="0.5"
+ android:valueTo="0.5"
+ android:interpolator="@android:interpolator/fast_out_slow_in" />
+ <objectAnimator
+ android:duration="350"
+ android:propertyName="alpha"
+ android:valueFrom="0.5"
+ android:valueTo="1"
+ android:interpolator="@android:interpolator/fast_out_slow_in" />
+ </set>
+</set>
diff --git a/packages/SystemUI/res/anim/ic_signal_flashlight_enable_animation_mask.xml b/packages/SystemUI/res/anim/ic_signal_flashlight_enable_animation_mask.xml
new file mode 100644
index 0000000..650d89f
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_signal_flashlight_enable_animation_mask.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<set xmlns:android="http://schemas.android.com/apk/res/android" >
+ <set
+ android:ordering="sequentially" >
+ <objectAnimator
+ android:duration="200"
+ android:propertyName="pathData"
+ android:valueFrom="M 37.8337860107,-39.2975769043 c 0.0,0.0 -35.8077850342,31.5523681641 -35.8077850342,31.5523681641 c 0.0,0.0 40.9884796143,40.9278411865 40.9884796143,40.9278411865 c 0.0,0.0 -2.61700439453,2.0938873291 -2.61700439453,2.0938873291 c 0.0,0.0 -41.1884460449,-40.9392852783 -41.1884460449,-40.9392852783 c 0.0,0.0 -34.6200408936,25.4699249268 -34.6200408936,25.4699249268 c 0.0,0.0 55.9664764404,69.742401123 55.9664764404,69.742401123 c 0.0,0.0 73.2448120117,-59.1047973633 73.2448120117,-59.1047973633 c 0.0,0.0 -55.9664916992,-69.7423400879 -55.9664916992,-69.7423400879 Z"
+ android:valueTo="M 37.8337860107,-39.2975769043 c 0.0,0.0 -35.8077850342,31.5523681641 -35.8077850342,31.5523681641 c 0.0,0.0 40.9884796143,40.9278411865 40.9884796143,40.9278411865 c 0.0,0.0 -2.61700439453,2.0938873291 -2.61700439453,2.0938873291 c 0.0,0.0 -41.1884460449,-40.9392852783 -41.1884460449,-40.9392852783 c 0.0,0.0 -34.6200408936,25.4699249268 -34.6200408936,25.4699249268 c 0.0,0.0 55.9664764404,69.742401123 55.9664764404,69.742401123 c 0.0,0.0 73.2448120117,-59.1047973633 73.2448120117,-59.1047973633 c 0.0,0.0 -55.9664916992,-69.7423400879 -55.9664916992,-69.7423400879 Z"
+ android:valueType="pathType"
+ android:interpolator="@android:interpolator/linear" />
+ <objectAnimator
+ android:duration="350"
+ android:propertyName="pathData"
+ android:valueFrom="M 37.8337860107,-39.2975769043 c 0.0,0.0 -35.8077850342,31.5523681641 -35.8077850342,31.5523681641 c 0.0,0.0 40.9884796143,40.9278411865 40.9884796143,40.9278411865 c 0.0,0.0 -2.61700439453,2.0938873291 -2.61700439453,2.0938873291 c 0.0,0.0 -41.1884460449,-40.9392852783 -41.1884460449,-40.9392852783 c 0.0,0.0 -34.6200408936,25.4699249268 -34.6200408936,25.4699249268 c 0.0,0.0 55.9664764404,69.742401123 55.9664764404,69.742401123 c 0.0,0.0 73.2448120117,-59.1047973633 73.2448120117,-59.1047973633 c 0.0,0.0 -55.9664916992,-69.7423400879 -55.9664916992,-69.7423400879 Z"
+ android:valueTo="M 37.8337860107,-39.2849731445 c 0.0,0.0 -35.8077850342,31.5523681641 -35.8077850342,31.5523681641 c 0.0,0.0 9.55097961426,9.55285644531 9.55097961426,9.55285644531 c 0.0,0.0 -2.61698913574,2.09387207031 -2.61698913574,2.09387207031 c 0.0,0.0 -9.75096130371,-9.56428527832 -9.75096130371,-9.56428527832 c 0.0,0.0 -34.6200408936,25.4699249268 -34.6200408936,25.4699249268 c 0.0,0.0 55.9664764404,69.742401123 55.9664764404,69.742401123 c 0.0,0.0 73.2448120117,-59.1047973633 73.2448120117,-59.1047973633 c 0.0,0.0 -55.9664916992,-69.7423400879 -55.9664916992,-69.7423400879 Z"
+ android:valueType="pathType"
+ android:interpolator="@interpolator/ic_signal_flashlight_enable_mask_pathdata_interpolator" />
+ </set>
+</set>
diff --git a/packages/SystemUI/res/anim/ic_signal_flashlight_enable_animation_root.xml b/packages/SystemUI/res/anim/ic_signal_flashlight_enable_animation_root.xml
new file mode 100644
index 0000000..387ca29
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_signal_flashlight_enable_animation_root.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<set xmlns:android="http://schemas.android.com/apk/res/android" >
+ <objectAnimator
+ android:duration="350"
+ android:propertyName="alpha"
+ android:valueFrom="0.3"
+ android:valueTo="1.0"
+ android:interpolator="@android:interpolator/fast_out_slow_in" />
+</set>
diff --git a/packages/SystemUI/res/anim/ic_signal_location_disable_animation_cross_1.xml b/packages/SystemUI/res/anim/ic_signal_location_disable_animation_cross_1.xml
new file mode 100644
index 0000000..73283a8
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_signal_location_disable_animation_cross_1.xml
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<set xmlns:android="http://schemas.android.com/apk/res/android" >
+ <set
+ android:ordering="sequentially" >
+ <objectAnimator
+ android:duration="200"
+ android:propertyName="pathData"
+ android:valueFrom="M 6.44050598145,1.9430847168 c 0.0,0.0 0.374984741211,0.399978637695 0.374984741211,0.399978637695 "
+ android:valueTo="M 6.44050598145,1.9430847168 c 0.0,0.0 0.374984741211,0.399978637695 0.374984741211,0.399978637695 "
+ android:valueType="pathType"
+ android:interpolator="@android:interpolator/fast_out_slow_in" />
+ <objectAnimator
+ android:duration="350"
+ android:propertyName="pathData"
+ android:valueFrom="M 6.44050598145,1.9430847168 c 0.0,0.0 0.374984741211,0.399978637695 0.374984741211,0.399978637695 "
+ android:valueTo="M 6.44050598145,1.9430847168 c 0.0,0.0 33.5749816895,33.4499664307 33.5749816895,33.4499664307 "
+ android:valueType="pathType"
+ android:interpolator="@android:interpolator/fast_out_slow_in" />
+ </set>
+ <set
+ android:ordering="sequentially" >
+ <objectAnimator
+ android:duration="200"
+ android:propertyName="strokeAlpha"
+ android:valueFrom="0"
+ android:valueTo="0"
+ android:interpolator="@android:interpolator/linear" />
+ <objectAnimator
+ android:duration="17"
+ android:propertyName="strokeAlpha"
+ android:valueFrom="0"
+ android:valueTo="1"
+ android:interpolator="@android:interpolator/linear" />
+ </set>
+</set>
diff --git a/packages/SystemUI/res/anim/ic_signal_location_disable_animation_ic_signal_location.xml b/packages/SystemUI/res/anim/ic_signal_location_disable_animation_ic_signal_location.xml
new file mode 100644
index 0000000..9cc3b8e
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_signal_location_disable_animation_ic_signal_location.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<set xmlns:android="http://schemas.android.com/apk/res/android" >
+ <set
+ android:ordering="sequentially" >
+ <objectAnimator
+ android:duration="200"
+ android:propertyName="alpha"
+ android:valueFrom="1"
+ android:valueTo="1"
+ android:interpolator="@android:interpolator/fast_out_slow_in" />
+ <objectAnimator
+ android:duration="350"
+ android:propertyName="alpha"
+ android:valueFrom="1"
+ android:valueTo="0.5"
+ android:interpolator="@android:interpolator/fast_out_slow_in" />
+ </set>
+</set>
diff --git a/packages/SystemUI/res/anim/ic_signal_location_disable_animation_mask.xml b/packages/SystemUI/res/anim/ic_signal_location_disable_animation_mask.xml
new file mode 100644
index 0000000..7ef7b5b
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_signal_location_disable_animation_mask.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<set xmlns:android="http://schemas.android.com/apk/res/android" >
+ <set
+ android:ordering="sequentially" >
+ <objectAnimator
+ android:duration="200"
+ android:propertyName="pathData"
+ android:valueFrom="M 38.8337860107,-40.4599914551 c 0.0,0.0 -35.8077850342,31.5523681641 -35.8077850342,31.5523681641 c 0.0,0.0 7.3759765625,7.55284118652 7.3759765625,7.55284118652 c 0.0,0.0 -2.61698913574,2.0938873291 -2.61698913574,2.0938873291 c 0.0,0.0 -7.57595825195,-7.56428527832 -7.57595825195,-7.56428527832 c 0.0,0.0 -34.6200408936,25.4699249268 -34.6200408936,25.4699249268 c 0.0,0.0 55.9664764404,69.742401123 55.9664764404,69.742401123 c 0.0,0.0 73.2448120117,-59.1047973633 73.2448120117,-59.1047973633 c 0.0,0.0 -55.9664916992,-69.7423400879 -55.9664916992,-69.7423400879 Z"
+ android:valueTo="M 38.8337860107,-40.4599914551 c 0.0,0.0 -35.8077850342,31.5523681641 -35.8077850342,31.5523681641 c 0.0,0.0 7.3759765625,7.55284118652 7.3759765625,7.55284118652 c 0.0,0.0 -2.61698913574,2.0938873291 -2.61698913574,2.0938873291 c 0.0,0.0 -7.57595825195,-7.56428527832 -7.57595825195,-7.56428527832 c 0.0,0.0 -34.6200408936,25.4699249268 -34.6200408936,25.4699249268 c 0.0,0.0 55.9664764404,69.742401123 55.9664764404,69.742401123 c 0.0,0.0 73.2448120117,-59.1047973633 73.2448120117,-59.1047973633 c 0.0,0.0 -55.9664916992,-69.7423400879 -55.9664916992,-69.7423400879 Z"
+ android:valueType="pathType"
+ android:interpolator="@android:interpolator/fast_out_slow_in" />
+ <objectAnimator
+ android:duration="350"
+ android:propertyName="pathData"
+ android:valueFrom="M 38.8337860107,-40.4599914551 c 0.0,0.0 -35.8077850342,31.5523681641 -35.8077850342,31.5523681641 c 0.0,0.0 7.3759765625,7.55284118652 7.3759765625,7.55284118652 c 0.0,0.0 -2.61698913574,2.0938873291 -2.61698913574,2.0938873291 c 0.0,0.0 -7.57595825195,-7.56428527832 -7.57595825195,-7.56428527832 c 0.0,0.0 -34.6200408936,25.4699249268 -34.6200408936,25.4699249268 c 0.0,0.0 55.9664764404,69.742401123 55.9664764404,69.742401123 c 0.0,0.0 73.2448120117,-59.1047973633 73.2448120117,-59.1047973633 c 0.0,0.0 -55.9664916992,-69.7423400879 -55.9664916992,-69.7423400879 Z"
+ android:valueTo="M 38.8337860107,-40.3974914551 c 0.0,0.0 -35.8077850342,31.5523681641 -35.8077850342,31.5523681641 c 0.0,0.0 40.9884796143,41.1153411865 40.9884796143,41.1153411865 c 0.0,0.0 -2.61700439453,2.0938873291 -2.61700439453,2.0938873291 c 0.0,0.0 -41.1884460449,-41.1267852783 -41.1884460449,-41.1267852783 c 0.0,0.0 -34.6200408936,25.4699249268 -34.6200408936,25.4699249268 c 0.0,0.0 55.9664764404,69.742401123 55.9664764404,69.742401123 c 0.0,0.0 73.2448120117,-59.1047973633 73.2448120117,-59.1047973633 c 0.0,0.0 -55.9664916992,-69.7423400879 -55.9664916992,-69.7423400879 Z"
+ android:valueType="pathType"
+ android:interpolator="@android:interpolator/fast_out_slow_in" />
+ </set>
+</set>
diff --git a/packages/SystemUI/res/anim/ic_signal_location_disable_animation_root.xml b/packages/SystemUI/res/anim/ic_signal_location_disable_animation_root.xml
new file mode 100644
index 0000000..770c401
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_signal_location_disable_animation_root.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<set xmlns:android="http://schemas.android.com/apk/res/android" >
+ <objectAnimator
+ android:duration="350"
+ android:propertyName="alpha"
+ android:valueFrom="1.0"
+ android:valueTo="0.3"
+ android:interpolator="@android:interpolator/fast_out_slow_in" />
+</set>
diff --git a/packages/SystemUI/res/anim/ic_signal_location_enable_animation_cross_1.xml b/packages/SystemUI/res/anim/ic_signal_location_enable_animation_cross_1.xml
new file mode 100644
index 0000000..f4fc20e
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_signal_location_enable_animation_cross_1.xml
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<set xmlns:android="http://schemas.android.com/apk/res/android" >
+ <set
+ android:ordering="sequentially" >
+ <objectAnimator
+ android:duration="200"
+ android:propertyName="pathData"
+ android:valueFrom="M 6.44050598145,1.9430847168 c 0.0,0.0 33.5749816895,33.4499664307 33.5749816895,33.4499664307 "
+ android:valueTo="M 6.44050598145,1.9430847168 c 0.0,0.0 33.5749816895,33.4499664307 33.5749816895,33.4499664307 "
+ android:valueType="pathType"
+ android:interpolator="@android:interpolator/linear" />
+ <objectAnimator
+ android:duration="350"
+ android:propertyName="pathData"
+ android:valueFrom="M 6.44050598145,1.9430847168 c 0.0,0.0 33.5749816895,33.4499664307 33.5749816895,33.4499664307 "
+ android:valueTo="M 6.44050598145,1.9430847168 c 0.0,0.0 0.374984741211,0.399978637695 0.374984741211,0.399978637695 "
+ android:valueType="pathType"
+ android:interpolator="@interpolator/ic_signal_location_enable_cross_1_pathdata_interpolator" />
+ </set>
+ <set
+ android:ordering="sequentially" >
+ <objectAnimator
+ android:duration="533"
+ android:propertyName="strokeAlpha"
+ android:valueFrom="1"
+ android:valueTo="1"
+ android:interpolator="@android:interpolator/linear" />
+ <objectAnimator
+ android:duration="17"
+ android:propertyName="strokeAlpha"
+ android:valueFrom="1"
+ android:valueTo="0"
+ android:interpolator="@android:interpolator/linear" />
+ </set>
+</set>
diff --git a/packages/SystemUI/res/anim/ic_signal_location_enable_animation_ic_signal_location.xml b/packages/SystemUI/res/anim/ic_signal_location_enable_animation_ic_signal_location.xml
new file mode 100644
index 0000000..5fdb2a0
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_signal_location_enable_animation_ic_signal_location.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<set xmlns:android="http://schemas.android.com/apk/res/android" >
+ <set
+ android:ordering="sequentially" >
+ <objectAnimator
+ android:duration="200"
+ android:propertyName="alpha"
+ android:valueFrom="0.5"
+ android:valueTo="0.5"
+ android:interpolator="@android:interpolator/fast_out_slow_in" />
+ <objectAnimator
+ android:duration="350"
+ android:propertyName="alpha"
+ android:valueFrom="0.5"
+ android:valueTo="1"
+ android:interpolator="@android:interpolator/fast_out_slow_in" />
+ </set>
+</set>
diff --git a/packages/SystemUI/res/anim/ic_signal_location_enable_animation_mask.xml b/packages/SystemUI/res/anim/ic_signal_location_enable_animation_mask.xml
new file mode 100644
index 0000000..b825eb9
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_signal_location_enable_animation_mask.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<set xmlns:android="http://schemas.android.com/apk/res/android" >
+ <set
+ android:ordering="sequentially" >
+ <objectAnimator
+ android:duration="200"
+ android:propertyName="pathData"
+ android:valueFrom="M 38.8337860107,-40.3974914551 c 0.0,0.0 -35.8077850342,31.5523681641 -35.8077850342,31.5523681641 c 0.0,0.0 40.9884796143,41.1153411865 40.9884796143,41.1153411865 c 0.0,0.0 -2.61700439453,2.0938873291 -2.61700439453,2.0938873291 c 0.0,0.0 -41.1884460449,-41.1267852783 -41.1884460449,-41.1267852783 c 0.0,0.0 -34.6200408936,25.4699249268 -34.6200408936,25.4699249268 c 0.0,0.0 55.9664764404,69.742401123 55.9664764404,69.742401123 c 0.0,0.0 73.2448120117,-59.1047973633 73.2448120117,-59.1047973633 c 0.0,0.0 -55.9664916992,-69.7423400879 -55.9664916992,-69.7423400879 Z"
+ android:valueTo="M 38.8337860107,-40.3974914551 c 0.0,0.0 -35.8077850342,31.5523681641 -35.8077850342,31.5523681641 c 0.0,0.0 40.9884796143,41.1153411865 40.9884796143,41.1153411865 c 0.0,0.0 -2.61700439453,2.0938873291 -2.61700439453,2.0938873291 c 0.0,0.0 -41.1884460449,-41.1267852783 -41.1884460449,-41.1267852783 c 0.0,0.0 -34.6200408936,25.4699249268 -34.6200408936,25.4699249268 c 0.0,0.0 55.9664764404,69.742401123 55.9664764404,69.742401123 c 0.0,0.0 73.2448120117,-59.1047973633 73.2448120117,-59.1047973633 c 0.0,0.0 -55.9664916992,-69.7423400879 -55.9664916992,-69.7423400879 Z"
+ android:valueType="pathType"
+ android:interpolator="@android:interpolator/linear" />
+ <objectAnimator
+ android:duration="350"
+ android:propertyName="pathData"
+ android:valueFrom="M 38.8337860107,-40.3974914551 c 0.0,0.0 -35.8077850342,31.5523681641 -35.8077850342,31.5523681641 c 0.0,0.0 40.9884796143,41.1153411865 40.9884796143,41.1153411865 c 0.0,0.0 -2.61700439453,2.0938873291 -2.61700439453,2.0938873291 c 0.0,0.0 -41.1884460449,-41.1267852783 -41.1884460449,-41.1267852783 c 0.0,0.0 -34.6200408936,25.4699249268 -34.6200408936,25.4699249268 c 0.0,0.0 55.9664764404,69.742401123 55.9664764404,69.742401123 c 0.0,0.0 73.2448120117,-59.1047973633 73.2448120117,-59.1047973633 c 0.0,0.0 -55.9664916992,-69.7423400879 -55.9664916992,-69.7423400879 Z"
+ android:valueTo="M 38.8337860107,-40.4599914551 c 0.0,0.0 -35.8077850342,31.5523681641 -35.8077850342,31.5523681641 c 0.0,0.0 7.3759765625,7.55284118652 7.3759765625,7.55284118652 c 0.0,0.0 -2.61698913574,2.0938873291 -2.61698913574,2.0938873291 c 0.0,0.0 -7.57595825195,-7.56428527832 -7.57595825195,-7.56428527832 c 0.0,0.0 -34.6200408936,25.4699249268 -34.6200408936,25.4699249268 c 0.0,0.0 55.9664764404,69.742401123 55.9664764404,69.742401123 c 0.0,0.0 73.2448120117,-59.1047973633 73.2448120117,-59.1047973633 c 0.0,0.0 -55.9664916992,-69.7423400879 -55.9664916992,-69.7423400879 Z"
+ android:valueType="pathType"
+ android:interpolator="@interpolator/ic_signal_location_enable_mask_pathdata_interpolator" />
+ </set>
+</set>
diff --git a/packages/SystemUI/res/anim/ic_signal_location_enable_animation_root.xml b/packages/SystemUI/res/anim/ic_signal_location_enable_animation_root.xml
new file mode 100644
index 0000000..387ca29
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_signal_location_enable_animation_root.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<set xmlns:android="http://schemas.android.com/apk/res/android" >
+ <objectAnimator
+ android:duration="350"
+ android:propertyName="alpha"
+ android:valueFrom="0.3"
+ android:valueTo="1.0"
+ android:interpolator="@android:interpolator/fast_out_slow_in" />
+</set>
diff --git a/packages/SystemUI/res/drawable/ic_dismiss_all.xml b/packages/SystemUI/res/drawable/ic_dismiss_all.xml
index 8e5e572..c32e5b11 100644
--- a/packages/SystemUI/res/drawable/ic_dismiss_all.xml
+++ b/packages/SystemUI/res/drawable/ic_dismiss_all.xml
@@ -16,6 +16,7 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
+ android:autoMirrored="true"
android:viewportWidth="48.0"
android:viewportHeight="48.0">
<path
diff --git a/packages/SystemUI/res/drawable/ic_invert_colors_disable.xml b/packages/SystemUI/res/drawable/ic_invert_colors_disable.xml
new file mode 100644
index 0000000..f901e86
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_invert_colors_disable.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:name="root"
+ android:alpha="1.0"
+ android:height="48dp"
+ android:width="48dp"
+ android:viewportHeight="48"
+ android:viewportWidth="48" >
+ <group
+ android:name="icon"
+ android:translateX="21.9995"
+ android:translateY="25.73401" >
+ <group
+ android:name="icon_pivot"
+ android:translateX="-23.21545"
+ android:translateY="-18.86649" >
+ <clip-path
+ android:name="mask"
+ android:pathData="M 37.8337860107,-40.4599914551 c 0.0,0.0 -35.8077850342,31.5523681641 -35.8077850342,31.5523681641 c 0.0,0.0 9.55097961426,9.55285644531 9.55097961426,9.55285644531 c 0.0,0.0 -2.61698913574,2.09387207031 -2.61698913574,2.09387207031 c 0.0,0.0 -9.75096130371,-9.56428527832 -9.75096130371,-9.56428527832 c 0.0,0.0 -34.6200408936,25.4699249268 -34.6200408936,25.4699249268 c 0.0,0.0 55.9664764404,69.742401123 55.9664764404,69.742401123 c 0.0,0.0 73.2448120117,-59.1047973633 73.2448120117,-59.1047973633 c 0.0,0.0 -55.9664916992,-69.7423400879 -55.9664916992,-69.7423400879 Z" />
+ <group
+ android:name="cross" >
+ <path
+ android:name="cross_1"
+ android:pathData="M 7.54049682617,3.9430847168 c 0.0,0.0 0.324981689453,0.399978637695 0.324981689453,0.399978637695 "
+ android:strokeColor="#FFFFFFFF"
+ android:strokeAlpha="0"
+ android:strokeWidth="3.5"
+ android:fillColor="#00000000" />
+ </group>
+ <group
+ android:name="ink_drop"
+ android:translateY="-6.8" >
+ <path
+ android:name="outer_drop"
+ android:pathData="M 35.3000030518,15.8999938965 c 0.0,0.0 -11.3000030518,-11.3999938965 -11.3000030518,-11.3999938965 c 0,0.0 -11.3000030518,11.3999938965 -11.3000030518,11.3999938965 c -6.19999694824,6.20001220703 -6.19999694824,16.4000091553 0.0,22.6000061035 c 3.10000610352,3.10000610352 7.19999694824,4.69999694824 11.3000030518,4.69999694824 c 4.10000610352,0.0 8.19999694824,-1.59999084473 11.3000030518,-4.69999694824 c 6.30000305176,-6.30000305176 6.30000305176,-16.3999938965 0.0,-22.6000061035 Z M 24,39.1999969482 c 0,0.0 0,0.0 0,0.0 c -3.19999694824,0.0 -6.19999694824,-1.19999694824 -8.5,-3.5 c -2.30000305176,-2.29998779297 -3.5,-5.30000305176 -3.5,-8.5 c 0,-3.19999694824 1.19999694824,-6.19999694824 3.5,-8.5 c 0.0,0.0 8.5,-8.5 8.5,-8.5 c 0,0.0 0,29.0 0,29.0 Z"
+ android:fillColor="#FFFFFFFF"
+ android:fillAlpha="1" />
+ </group>
+ </group>
+ </group>
+</vector>
diff --git a/packages/SystemUI/res/drawable/ic_invert_colors_disable_animation.xml b/packages/SystemUI/res/drawable/ic_invert_colors_disable_animation.xml
new file mode 100644
index 0000000..2e26d42
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_invert_colors_disable_animation.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:drawable="@drawable/ic_invert_colors_disable" >
+ <target
+ android:name="root"
+ android:animation="@anim/ic_invert_colors_disable_animation_root" />
+ <target
+ android:name="icon"
+ android:animation="@anim/ic_invert_colors_disable_animation_icon" />
+ <target
+ android:name="mask"
+ android:animation="@anim/ic_invert_colors_disable_animation_mask" />
+ <target
+ android:name="cross_1"
+ android:animation="@anim/ic_invert_colors_disable_animation_cross_1" />
+</animated-vector>
diff --git a/packages/SystemUI/res/drawable/ic_invert_colors_enable.xml b/packages/SystemUI/res/drawable/ic_invert_colors_enable.xml
new file mode 100644
index 0000000..730ecc4
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_invert_colors_enable.xml
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:name="root"
+ android:alpha="0.3"
+ android:height="48dp"
+ android:width="48dp"
+ android:viewportHeight="48"
+ android:viewportWidth="48" >
+ <group
+ android:name="icon"
+ android:translateX="21.9995"
+ android:translateY="25.73401"
+ android:alpha="0.54" >
+ <group
+ android:name="icon_pivot"
+ android:translateX="-23.21545"
+ android:translateY="-18.86649" >
+ <clip-path
+ android:name="mask"
+ android:pathData="M 37.8337860107,-40.3974914551 c 0.0,0.0 -35.8077850342,31.5523681641 -35.8077850342,31.5523681641 c 0.0,0.0 40.9884796143,40.9278411865 40.9884796143,40.9278411865 c 0.0,0.0 -2.61700439453,2.0938873291 -2.61700439453,2.0938873291 c 0.0,0.0 -41.1884460449,-40.9392852783 -41.1884460449,-40.9392852783 c 0.0,0.0 -34.6200408936,25.4699249268 -34.6200408936,25.4699249268 c 0.0,0.0 55.9664764404,69.742401123 55.9664764404,69.742401123 c 0.0,0.0 73.2448120117,-59.1047973633 73.2448120117,-59.1047973633 c 0.0,0.0 -55.9664916992,-69.7423400879 -55.9664916992,-69.7423400879 Z" />
+ <group
+ android:name="cross" >
+ <path
+ android:name="cross_1"
+ android:pathData="M 7.54049682617,3.9430847168 c 0.0,0.0 31.5749816895,31.4499664307 31.5749816895,31.4499664307 "
+ android:strokeColor="#FFFFFFFF"
+ android:strokeAlpha="1"
+ android:strokeWidth="3.5"
+ android:fillColor="#00000000" />
+ </group>
+ <group
+ android:name="ink_drop"
+ android:translateY="-6.8" >
+ <path
+ android:name="outer_drop"
+ android:pathData="M 35.3000030518,15.8999938965 c 0.0,0.0 -11.3000030518,-11.3999938965 -11.3000030518,-11.3999938965 c 0,0.0 -11.3000030518,11.3999938965 -11.3000030518,11.3999938965 c -6.19999694824,6.20001220703 -6.19999694824,16.4000091553 0.0,22.6000061035 c 3.10000610352,3.10000610352 7.19999694824,4.69999694824 11.3000030518,4.69999694824 c 4.10000610352,0.0 8.19999694824,-1.59999084473 11.3000030518,-4.69999694824 c 6.30000305176,-6.30000305176 6.30000305176,-16.3999938965 0.0,-22.6000061035 Z M 24,39.1999969482 c 0,0.0 0,0.0 0,0.0 c -3.19999694824,0.0 -6.19999694824,-1.19999694824 -8.5,-3.5 c -2.30000305176,-2.29998779297 -3.5,-5.30000305176 -3.5,-8.5 c 0,-3.19999694824 1.19999694824,-6.19999694824 3.5,-8.5 c 0.0,0.0 8.5,-8.5 8.5,-8.5 c 0,0.0 0,29.0 0,29.0 Z"
+ android:fillColor="#FFFFFFFF"
+ android:fillAlpha="1" />
+ </group>
+ </group>
+ </group>
+</vector>
diff --git a/packages/SystemUI/res/drawable/ic_invert_colors_enable_animation.xml b/packages/SystemUI/res/drawable/ic_invert_colors_enable_animation.xml
new file mode 100644
index 0000000..a709efb
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_invert_colors_enable_animation.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:drawable="@drawable/ic_invert_colors_enable" >
+ <target
+ android:name="root"
+ android:animation="@anim/ic_invert_colors_enable_animation_root" />
+ <target
+ android:name="icon"
+ android:animation="@anim/ic_invert_colors_enable_animation_icon" />
+ <target
+ android:name="mask"
+ android:animation="@anim/ic_invert_colors_enable_animation_mask" />
+ <target
+ android:name="cross_1"
+ android:animation="@anim/ic_invert_colors_enable_animation_cross_1" />
+</animated-vector>
diff --git a/packages/SystemUI/res/drawable/ic_landscape_from_auto_rotate.xml b/packages/SystemUI/res/drawable/ic_landscape_from_auto_rotate.xml
new file mode 100644
index 0000000..bc545ba
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_landscape_from_auto_rotate.xml
@@ -0,0 +1,62 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:height="48dp"
+ android:width="48dp"
+ android:viewportHeight="48"
+ android:viewportWidth="48" >
+ <group
+ android:name="ic_screen_rotation_48px_outlines"
+ android:translateX="24"
+ android:translateY="24" >
+ <group
+ android:name="ic_screen_rotation_48px_outlines_pivot"
+ android:translateX="-24.15"
+ android:translateY="-24.25" >
+ <group
+ android:name="arrows"
+ android:translateX="24.1"
+ android:translateY="24.1" >
+ <group
+ android:name="arrows_pivot"
+ android:translateX="-24.1"
+ android:translateY="-24.1" >
+ <path
+ android:name="arrow_top"
+ android:pathData="M 33.1499938965,5.25 c 6.5,3.10000610352 11.1999969482,9.40000915527 11.8999938965,17.0 c 0.0,0.0 3.00001525879,0.0 3.00001525879,0.0 c -1.00001525879,-12.3000030518 -11.3000030518,-22.0 -23.9000091553,-22.0 c -0.399993896484,0.0 -0.899993896484,0.0 -1.30000305176,0.100006103516 c 0.0,0.0 7.60000610352,7.59999084473 7.60000610352,7.59999084473 c 0.0,0.0 2.69999694824,-2.69999694824 2.69999694824,-2.69999694824 Z"
+ android:fillColor="#FFFFFFFF"
+ android:fillAlpha="1" />
+ <path
+ android:name="arrow_bottom"
+ android:pathData="M 15.1499938965,43.25 c -6.5,-3.09999084473 -11.1999969482,-9.5 -11.8999938965,-17.0 c 0.0,0.0 -3.0,0.0 -3.0,0.0 c 1.0,12.3000030518 11.299987793,22.0 23.8999938965,22.0 c 0.399993896484,0.0 0.899993896484,0.0 1.30000305176,-0.0999908447266 c 0.0,0.0 -7.60000610352,-7.60000610352 -7.60000610352,-7.60000610352 c 0.0,0.0 -2.69999694824,2.69999694824 -2.69999694824,2.69999694824 Z"
+ android:fillColor="#FFFFFFFF"
+ android:fillAlpha="1" />
+ </group>
+ </group>
+ <group
+ android:name="device"
+ android:translateX="24.14999"
+ android:translateY="24.25" >
+ <path
+ android:name="body"
+ android:pathData="M -3.5,-20.5 c -1.19999694824,-1.19999694824 -3.10000610352,-1.19999694824 -4.19999694824,0.0 c 0.0,0.0 -12.8000030518,12.6999969482 -12.8000030518,12.6999969482 c -1.19999694824,1.19999694824 -1.19999694824,3.10000610352 0.0,4.19999694824 c 0.0,0.0 24.0,24.0000152588 24.0,24.0000152588 c 1.19999694824,1.19999694824 3.10000610352,1.19999694824 4.19999694824,0.0 c 0.0,0.0 12.6999969482,-12.700012207 12.6999969482,-12.700012207 c 1.20001220703,-1.19999694824 1.20001220703,-3.09999084473 0.0,-4.19999694824 c 0.0,0.0 -23.8999938965,-24.0 -23.8999938965,-24.0 Z M 2.84999084473,15.5500183105 c 0.0,0.0 -18.6000061035,-18.5000457764 -18.6000061035,-18.5000457764 c 0.0,0.0 12.5999908447,-12.8000030518 12.5999908447,-12.8000030518 c 0.0,0.0 18.6000213623,18.5000457764 18.6000213623,18.5000457764 c 0.0,0.0 -12.6000061035,12.8000030518 -12.6000061035,12.8000030518 Z"
+ android:fillColor="#FFFFFFFF"
+ android:fillAlpha="1" />
+ </group>
+ </group>
+ </group>
+</vector>
diff --git a/packages/SystemUI/res/drawable/ic_landscape_from_auto_rotate_animation.xml b/packages/SystemUI/res/drawable/ic_landscape_from_auto_rotate_animation.xml
new file mode 100644
index 0000000..400a28b
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_landscape_from_auto_rotate_animation.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:drawable="@drawable/ic_landscape_from_auto_rotate" >
+ <target
+ android:name="arrows"
+ android:animation="@anim/ic_landscape_from_auto_rotate_animation_arrows" />
+ <target
+ android:name="arrow_top"
+ android:animation="@anim/ic_landscape_from_auto_rotate_animation_arrow_top" />
+ <target
+ android:name="arrow_bottom"
+ android:animation="@anim/ic_landscape_from_auto_rotate_animation_arrow_bottom" />
+ <target
+ android:name="device"
+ android:animation="@anim/ic_landscape_from_auto_rotate_animation_device" />
+ <target
+ android:name="body"
+ android:animation="@anim/ic_landscape_from_auto_rotate_animation_body" />
+</animated-vector>
diff --git a/packages/SystemUI/res/drawable/ic_landscape_to_auto_rotate.xml b/packages/SystemUI/res/drawable/ic_landscape_to_auto_rotate.xml
new file mode 100644
index 0000000..0bd75d1
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_landscape_to_auto_rotate.xml
@@ -0,0 +1,66 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:height="48dp"
+ android:width="48dp"
+ android:viewportHeight="48"
+ android:viewportWidth="48" >
+ <group
+ android:name="ic_screen_rotation_48px_outlines"
+ android:translateX="24"
+ android:translateY="24" >
+ <group
+ android:name="ic_screen_rotation_48px_outlines_pivot"
+ android:translateX="-24.15"
+ android:translateY="-24.25" >
+ <group
+ android:name="arrows"
+ android:translateX="24.1"
+ android:translateY="24.1"
+ android:scaleX="0.9"
+ android:scaleY="0.9"
+ android:rotation="-135" >
+ <group
+ android:name="arrows_pivot"
+ android:translateX="-24.1"
+ android:translateY="-24.1" >
+ <path
+ android:name="arrow_top"
+ android:pathData="M 33.1499938965,5.25 c 6.5,3.10000610352 11.1999969482,9.40000915527 11.8999938965,17.0 c 0.0,0.0 3.00001525879,0.0 3.00001525879,0.0 c -1.00001525879,-12.3000030518 -11.3000030518,-22.0 -23.9000091553,-22.0 c -0.399993896484,0.0 -0.899993896484,0.0 -1.30000305176,0.100006103516 c 0.0,0.0 7.60000610352,7.59999084473 7.60000610352,7.59999084473 c 0.0,0.0 2.69999694824,-2.69999694824 2.69999694824,-2.69999694824 Z"
+ android:fillColor="#FFFFFFFF"
+ android:fillAlpha="0" />
+ <path
+ android:name="arrow_bottom"
+ android:pathData="M 15.1499938965,43.25 c -6.5,-3.09999084473 -11.1999969482,-9.5 -11.8999938965,-17.0 c 0.0,0.0 -3.0,0.0 -3.0,0.0 c 1.0,12.3000030518 11.299987793,22.0 23.8999938965,22.0 c 0.399993896484,0.0 0.899993896484,0.0 1.30000305176,-0.0999908447266 c 0.0,0.0 -7.60000610352,-7.60000610352 -7.60000610352,-7.60000610352 c 0.0,0.0 -2.69999694824,2.69999694824 -2.69999694824,2.69999694824 Z"
+ android:fillColor="#FFFFFFFF"
+ android:fillAlpha="0" />
+ </group>
+ </group>
+ <group
+ android:name="device"
+ android:translateX="24.14999"
+ android:translateY="24.25"
+ android:rotation="-45" >
+ <path
+ android:name="body"
+ android:pathData="M -3.34053039551,-22.9980926514 c -1.3207244873,-1.3207244873 -3.46876525879,-1.26383972168 -4.74829101563,0.125762939453 c 0.0,0.0 -14.8512420654,14.7411804199 -14.8512420654,14.7411804199 c -1.39259338379,1.392578125 -1.44947814941,3.54061889648 -0.125762939453,4.74827575684 c 0.0,0.0 26.4143981934,26.4144134521 26.4143981934,26.4144134521 c 1.3207244873,1.3207244873 3.46876525879,1.26382446289 4.74829101562,-0.125762939453 c 0.0,0.0 14.7381896973,-14.7381896973 14.7381896973,-14.7381896973 c 1.392578125,-1.39259338379 1.44947814941,-3.54061889648 0.125762939453,-4.74829101562 c 0.0,0.0 -26.3013458252,-26.417388916 -26.3013458252,-26.417388916 Z M 2.87156677246,16.9857940674 c 0.0,0.0 -19.7573547363,-19.7573699951 -19.7573547363,-19.7573699951 c 0.0,0.0 14.0142059326,-14.2142181396 14.0142059326,-14.2142181396 c 0.0,0.0 19.7573699951,19.7573699951 19.7573699951,19.7573699951 c 0.0,0.0 -14.0142211914,14.2142181396 -14.0142211914,14.2142181396 Z"
+ android:fillColor="#FFFFFFFF"
+ android:fillAlpha="1" />
+ </group>
+ </group>
+ </group>
+</vector>
diff --git a/packages/SystemUI/res/drawable/ic_landscape_to_auto_rotate_animation.xml b/packages/SystemUI/res/drawable/ic_landscape_to_auto_rotate_animation.xml
new file mode 100644
index 0000000..5263eb4
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_landscape_to_auto_rotate_animation.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:drawable="@drawable/ic_landscape_to_auto_rotate" >
+ <target
+ android:name="arrows"
+ android:animation="@anim/ic_landscape_to_auto_rotate_animation_arrows" />
+ <target
+ android:name="arrow_top"
+ android:animation="@anim/ic_landscape_to_auto_rotate_animation_arrow_top" />
+ <target
+ android:name="arrow_bottom"
+ android:animation="@anim/ic_landscape_to_auto_rotate_animation_arrow_bottom" />
+ <target
+ android:name="device"
+ android:animation="@anim/ic_landscape_to_auto_rotate_animation_device" />
+ <target
+ android:name="body"
+ android:animation="@anim/ic_landscape_to_auto_rotate_animation_body" />
+</animated-vector>
diff --git a/packages/SystemUI/res/drawable/ic_portrait_from_auto_rotate.xml b/packages/SystemUI/res/drawable/ic_portrait_from_auto_rotate.xml
new file mode 100644
index 0000000..1805a8e
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_portrait_from_auto_rotate.xml
@@ -0,0 +1,62 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:height="48dp"
+ android:width="48dp"
+ android:viewportHeight="48"
+ android:viewportWidth="48" >
+ <group
+ android:name="ic_screen_rotation_48px_outlines"
+ android:translateX="24"
+ android:translateY="24" >
+ <group
+ android:name="ic_screen_rotation_48px_outlines_pivot"
+ android:translateX="-24.15"
+ android:translateY="-24.25" >
+ <group
+ android:name="arrows"
+ android:translateX="24.1"
+ android:translateY="24.1" >
+ <group
+ android:name="arrows_pivot"
+ android:translateX="-24.1"
+ android:translateY="-24.1" >
+ <path
+ android:name="arrow_top"
+ android:pathData="M 33.1499938965,5.25 c 6.5,3.10000610352 11.1999969482,9.40000915527 11.8999938965,17.0 c 0.0,0.0 3.00001525879,0.0 3.00001525879,0.0 c -1.00001525879,-12.3000030518 -11.3000030518,-22.0 -23.9000091553,-22.0 c -0.399993896484,0.0 -0.899993896484,0.0 -1.30000305176,0.100006103516 c 0.0,0.0 7.60000610352,7.59999084473 7.60000610352,7.59999084473 c 0.0,0.0 2.69999694824,-2.69999694824 2.69999694824,-2.69999694824 Z"
+ android:fillColor="#FFFFFFFF"
+ android:fillAlpha="1" />
+ <path
+ android:name="arrow_bottom"
+ android:pathData="M 15.1499938965,43.25 c -6.5,-3.09999084473 -11.1999969482,-9.5 -11.8999938965,-17.0 c 0.0,0.0 -3.0,0.0 -3.0,0.0 c 1.0,12.3000030518 11.299987793,22.0 23.8999938965,22.0 c 0.399993896484,0.0 0.899993896484,0.0 1.30000305176,-0.0999908447266 c 0.0,0.0 -7.60000610352,-7.60000610352 -7.60000610352,-7.60000610352 c 0.0,0.0 -2.69999694824,2.69999694824 -2.69999694824,2.69999694824 Z"
+ android:fillColor="#FFFFFFFF"
+ android:fillAlpha="1" />
+ </group>
+ </group>
+ <group
+ android:name="device"
+ android:translateX="24.14999"
+ android:translateY="24.25" >
+ <path
+ android:name="device_1"
+ android:pathData="M -3.5,-20.5 c -1.19999694824,-1.19999694824 -3.10000610352,-1.19999694824 -4.19999694824,0.0 c 0.0,0.0 -12.8000030518,12.6999969482 -12.8000030518,12.6999969482 c -1.19999694824,1.19999694824 -1.19999694824,3.10000610352 0.0,4.19999694824 c 0.0,0.0 24.0,24.0000152588 24.0,24.0000152588 c 1.19999694824,1.19999694824 3.10000610352,1.19999694824 4.19999694824,0.0 c 0.0,0.0 12.6999969482,-12.700012207 12.6999969482,-12.700012207 c 1.20001220703,-1.19999694824 1.20001220703,-3.09999084473 0.0,-4.19999694824 c 0.0,0.0 -23.8999938965,-24.0 -23.8999938965,-24.0 Z M 2.84999084473,15.5500183105 c 0.0,0.0 -18.6000061035,-18.5000457764 -18.6000061035,-18.5000457764 c 0.0,0.0 12.5999908447,-12.8000030518 12.5999908447,-12.8000030518 c 0.0,0.0 18.6000213623,18.5000457764 18.6000213623,18.5000457764 c 0.0,0.0 -12.6000061035,12.8000030518 -12.6000061035,12.8000030518 Z"
+ android:fillColor="#FFFFFFFF"
+ android:fillAlpha="1" />
+ </group>
+ </group>
+ </group>
+</vector>
diff --git a/packages/SystemUI/res/drawable/ic_portrait_from_auto_rotate_animation.xml b/packages/SystemUI/res/drawable/ic_portrait_from_auto_rotate_animation.xml
new file mode 100644
index 0000000..565ef26
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_portrait_from_auto_rotate_animation.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:drawable="@drawable/ic_portrait_from_auto_rotate" >
+ <target
+ android:name="arrows"
+ android:animation="@anim/ic_portrait_from_auto_rotate_animation_arrows" />
+ <target
+ android:name="arrow_top"
+ android:animation="@anim/ic_portrait_from_auto_rotate_animation_arrow_top" />
+ <target
+ android:name="arrow_bottom"
+ android:animation="@anim/ic_portrait_from_auto_rotate_animation_arrow_bottom" />
+ <target
+ android:name="device"
+ android:animation="@anim/ic_portrait_from_auto_rotate_animation_device" />
+ <target
+ android:name="device_1"
+ android:animation="@anim/ic_portrait_from_auto_rotate_animation_device_1" />
+</animated-vector>
diff --git a/packages/SystemUI/res/drawable/ic_portrait_to_auto_rotate.xml b/packages/SystemUI/res/drawable/ic_portrait_to_auto_rotate.xml
new file mode 100644
index 0000000..feb3025
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_portrait_to_auto_rotate.xml
@@ -0,0 +1,66 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:height="48dp"
+ android:width="48dp"
+ android:viewportHeight="48"
+ android:viewportWidth="48" >
+ <group
+ android:name="ic_screen_rotation_48px_outlines"
+ android:translateX="24"
+ android:translateY="24" >
+ <group
+ android:name="ic_screen_rotation_48px_outlines_pivot"
+ android:translateX="-24.15"
+ android:translateY="-24.25" >
+ <group
+ android:name="arrows"
+ android:translateX="24.1"
+ android:translateY="24.1"
+ android:scaleX="0.9"
+ android:scaleY="0.9"
+ android:rotation="-221" >
+ <group
+ android:name="arrows_pivot"
+ android:translateX="-24.1"
+ android:translateY="-24.1" >
+ <path
+ android:name="arrow_top"
+ android:pathData="M 33.1499938965,5.25 c 6.5,3.10000610352 11.1999969482,9.40000915527 11.8999938965,17.0 c 0.0,0.0 3.00001525879,0.0 3.00001525879,0.0 c -1.00001525879,-12.3000030518 -11.3000030518,-22.0 -23.9000091553,-22.0 c -0.399993896484,0.0 -0.899993896484,0.0 -1.30000305176,0.100006103516 c 0.0,0.0 7.60000610352,7.59999084473 7.60000610352,7.59999084473 c 0.0,0.0 2.69999694824,-2.69999694824 2.69999694824,-2.69999694824 Z"
+ android:fillColor="#FFFFFFFF"
+ android:fillAlpha="0" />
+ <path
+ android:name="arrow_bottom"
+ android:pathData="M 15.1499938965,43.25 c -6.5,-3.09999084473 -11.1999969482,-9.5 -11.8999938965,-17.0 c 0.0,0.0 -3.0,0.0 -3.0,0.0 c 1.0,12.3000030518 11.299987793,22.0 23.8999938965,22.0 c 0.399993896484,0.0 0.899993896484,0.0 1.30000305176,-0.0999908447266 c 0.0,0.0 -7.60000610352,-7.60000610352 -7.60000610352,-7.60000610352 c 0.0,0.0 -2.69999694824,2.69999694824 -2.69999694824,2.69999694824 Z"
+ android:fillColor="#FFFFFFFF"
+ android:fillAlpha="0" />
+ </group>
+ </group>
+ <group
+ android:name="device"
+ android:translateX="24.14999"
+ android:translateY="24.25"
+ android:rotation="-135" >
+ <path
+ android:name="device_1"
+ android:pathData="M -3.34053039551,-22.9980926514 c -1.3207244873,-1.3207244873 -3.46876525879,-1.26383972168 -4.74829101563,0.125762939453 c 0.0,0.0 -14.8512420654,14.7411804199 -14.8512420654,14.7411804199 c -1.39259338379,1.392578125 -1.44947814941,3.54061889648 -0.125762939453,4.74827575684 c 0.0,0.0 26.4143981934,26.4144134521 26.4143981934,26.4144134521 c 1.3207244873,1.3207244873 3.46876525879,1.26382446289 4.74829101562,-0.125762939453 c 0.0,0.0 14.7381896973,-14.7381896973 14.7381896973,-14.7381896973 c 1.392578125,-1.39259338379 1.44947814941,-3.54061889648 0.125762939453,-4.74829101562 c 0.0,0.0 -26.3013458252,-26.417388916 -26.3013458252,-26.417388916 Z M 2.87156677246,16.9857940674 c 0.0,0.0 -19.7573547363,-19.7573699951 -19.7573547363,-19.7573699951 c 0.0,0.0 14.0142059326,-14.2142181396 14.0142059326,-14.2142181396 c 0.0,0.0 19.7573699951,19.7573699951 19.7573699951,19.7573699951 c 0.0,0.0 -14.0142211914,14.2142181396 -14.0142211914,14.2142181396 Z"
+ android:fillColor="#FFFFFFFF"
+ android:fillAlpha="1" />
+ </group>
+ </group>
+ </group>
+</vector>
diff --git a/packages/SystemUI/res/drawable/ic_portrait_to_auto_rotate_animation.xml b/packages/SystemUI/res/drawable/ic_portrait_to_auto_rotate_animation.xml
new file mode 100644
index 0000000..f75617f
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_portrait_to_auto_rotate_animation.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:drawable="@drawable/ic_portrait_to_auto_rotate" >
+ <target
+ android:name="arrows"
+ android:animation="@anim/ic_portrait_to_auto_rotate_animation_arrows" />
+ <target
+ android:name="arrow_top"
+ android:animation="@anim/ic_portrait_to_auto_rotate_animation_arrow_top" />
+ <target
+ android:name="arrow_bottom"
+ android:animation="@anim/ic_portrait_to_auto_rotate_animation_arrow_bottom" />
+ <target
+ android:name="device"
+ android:animation="@anim/ic_portrait_to_auto_rotate_animation_device" />
+ <target
+ android:name="device_1"
+ android:animation="@anim/ic_portrait_to_auto_rotate_animation_device_1" />
+</animated-vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_airplane_off.xml b/packages/SystemUI/res/drawable/ic_qs_airplane_off.xml
deleted file mode 100644
index 79a9d409..0000000
--- a/packages/SystemUI/res/drawable/ic_qs_airplane_off.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<!--
-Copyright (C) 2014 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="64dp"
- android:height="64dp"
- android:viewportWidth="48.0"
- android:viewportHeight="48.0">
-
- <path
- android:fillColor="#4DFFFFFF"
- android:pathData="M26.0,18.0L26.0,7.0c0.0,-1.7 -1.3,-3.0 -3.0,-3.0c-1.7,0.0 -3.0,1.3 -3.0,3.0l0.0,7.4L35.7,30.0l6.3,2.0l0.0,-4.0L26.0,18.0zM6.0,10.5l10.0,10.0L4.0,28.0l0.0,4.0l16.0,-5.0l0.0,11.0l-4.0,3.0l0.0,3.0l7.0,-2.0l7.0,2.0l0.0,-3.0l-4.0,-3.0l0.0,-7.5L37.5,42.0l2.5,-2.5L8.5,8.0L6.0,10.5z"/>
-</vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_airplane_on.xml b/packages/SystemUI/res/drawable/ic_qs_airplane_on.xml
deleted file mode 100644
index 5d5d257..0000000
--- a/packages/SystemUI/res/drawable/ic_qs_airplane_on.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<!--
-Copyright (C) 2014 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="64dp"
- android:height="64dp"
- android:viewportWidth="48.0"
- android:viewportHeight="48.0">
-
- <path
- android:fillColor="#FFFFFFFF"
- android:pathData="M20.4,18.0"/>
- <path
- android:fillColor="#FFFFFFFF"
- android:pathData="M42.0,32.0l0.0,-4.0L26.0,18.0L26.0,7.0c0.0,-1.7 -1.3,-3.0 -3.0,-3.0c-1.7,0.0 -3.0,1.3 -3.0,3.0l0.0,11.0L4.0,28.0l0.0,4.0l16.0,-5.0l0.0,11.0l-4.0,3.0l0.0,3.0l7.0,-2.0l7.0,2.0l0.0,-3.0l-4.0,-3.0L26.0,27.0L42.0,32.0z"/>
-</vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_flashlight_off.xml b/packages/SystemUI/res/drawable/ic_qs_flashlight_off.xml
deleted file mode 100644
index d4bd76f..0000000
--- a/packages/SystemUI/res/drawable/ic_qs_flashlight_off.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<!--
-Copyright (C) 2014 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="64.0dp"
- android:height="64.0dp"
- android:viewportWidth="48.0"
- android:viewportHeight="48.0">
-
- <path
- android:fillColor="#4DFFFFFF"
- android:pathData="M14.708,11.394l14.899,14.9l0.0,-6.771c4.359,-2.353 3.831,-7.489 3.831,-7.489l0.0,-0.64L14.708,11.393998z"/>
- <path
- android:fillColor="#4DFFFFFF"
- android:pathData="M14.568,4.0l18.87,0.0l0.0,3.917l-18.87,0.0z"/>
- <path
- android:fillColor="#4DFFFFFF"
- android:pathData="M38.284,39.427l-29.767,-29.766998 -2.4750004,2.4750004 12.351999,12.351 0.0,19.514 11.213001,0.0 0.0,-8.300999 6.2019978,6.2019997z"/>
-</vector>
\ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/ic_qs_flashlight_on.xml b/packages/SystemUI/res/drawable/ic_qs_flashlight_on.xml
deleted file mode 100644
index 5514b44c..0000000
--- a/packages/SystemUI/res/drawable/ic_qs_flashlight_on.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<!--
-Copyright (C) 2014 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="64.0dp"
- android:height="64.0dp"
- android:viewportWidth="48.0"
- android:viewportHeight="48.0">
-
- <path
- android:fillColor="#FFFFFFFF"
- android:pathData="M33.438,12.034l0.0,-0.64l-18.87,0.0l0.0,0.64c0.0,0.0 -0.581,5.189 3.826,7.523L18.394,44.0l11.213,0.0L29.606998,19.523C33.966,17.17 33.438,12.034 33.438,12.034zM24.0,27.697c-1.523,0.0 -2.757,-1.234 -2.757,-2.757c0.0,-1.523 1.234,-2.757 2.757,-2.757c1.523,0.0 2.757,1.234 2.757,2.757C26.757,26.462 25.523,27.697 24.0,27.697z"/>
- <path
- android:fillColor="#FFFFFFFF"
- android:pathData="M14.568,4.0l18.87,0.0l0.0,3.917l-18.87,0.0z"/>
-</vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_inversion_off.xml b/packages/SystemUI/res/drawable/ic_qs_inversion_off.xml
deleted file mode 100644
index 4237b63..0000000
--- a/packages/SystemUI/res/drawable/ic_qs_inversion_off.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<!--
-Copyright (C) 2014 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="64dp"
- android:height="64dp"
- android:viewportWidth="48.0"
- android:viewportHeight="48.0">
-
- <path
- android:fillColor="#4DFFFFFF"
- android:pathData="M41.3,41.7L36.6,37.0L24.0,24.5l-7.1,-7.1L14.0,14.5L8.5,9.0L6.0,11.5l5.6,5.6c-5.1,6.3 -4.7,15.5 1.1,21.4c3.1,3.1 7.2,4.7 11.3,4.7c3.6,0.0 7.1,-1.2 10.1,-3.6l5.4,5.4l2.5,-2.5L41.3,41.7zM24.0,39.2c-3.2,0.0 -6.2,-1.2 -8.5,-3.5c-2.3,-2.3 -3.5,-5.3 -3.5,-8.5c0.0,-2.6 0.9,-5.1 2.4,-7.2l9.6,9.6L24.0,39.2zM24.0,10.2l0.0,9.2l14.5,14.5c2.7,-5.9 1.7,-13.1 -3.2,-18.0L24.0,4.5l0.0,0.0l0.0,0.0L16.6,12.0l2.8,2.8L24.0,10.2z"/>
-</vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_inversion_on.xml b/packages/SystemUI/res/drawable/ic_qs_inversion_on.xml
deleted file mode 100644
index 860e769..0000000
--- a/packages/SystemUI/res/drawable/ic_qs_inversion_on.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<!--
-Copyright (C) 2014 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="64dp"
- android:height="64dp"
- android:viewportWidth="48.0"
- android:viewportHeight="48.0">
-
- <path
- android:fillColor="#FFFFFFFF"
- android:pathData="M35.3,15.9L24.0,4.5l0.0,0.0l0.0,0.0L12.7,15.9c-6.2,6.2 -6.2,16.4 0.0,22.6c3.1,3.1 7.2,4.7 11.3,4.7s8.2,-1.6 11.3,-4.7C41.6,32.2 41.6,22.1 35.3,15.9zM24.0,39.2L24.0,39.2c-3.2,0.0 -6.2,-1.2 -8.5,-3.5c-2.3,-2.3 -3.5,-5.3 -3.5,-8.5s1.2,-6.2 3.5,-8.5l8.5,-8.5L24.0,39.2z"/>
-</vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_location_off.xml b/packages/SystemUI/res/drawable/ic_qs_location_off.xml
deleted file mode 100644
index e0fe12e..0000000
--- a/packages/SystemUI/res/drawable/ic_qs_location_off.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<!--
-Copyright (C) 2014 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="64dp"
- android:height="64dp"
- android:viewportWidth="48.0"
- android:viewportHeight="48.0">
-
- <path
- android:fillColor="#4DFFFFFF"
- android:pathData="M24.0,13.0c2.8,0.0 5.0,2.2 5.0,5.0c0.0,1.5 -0.7,2.8 -1.7,3.7l7.3,7.3c2.0,-3.7 3.4,-7.6 3.4,-11.0c0.0,-7.7 -6.3,-14.0 -14.0,-14.0c-4.0,0.0 -7.5,1.6 -10.1,4.3l6.4,6.4C21.2,13.6 22.5,13.0 24.0,13.0zM32.7,32.2l-9.3,-9.3l-0.2,-0.2L6.5,6.0L4.0,8.5l6.4,6.4c-0.2,1.0 -0.4,2.0 -0.4,3.1c0.0,10.5 14.0,26.0 14.0,26.0s3.3,-3.7 6.8,-8.7l6.7,6.7l2.5,-2.5L32.7,32.2z"/>
- <path
- android:pathData="M23.5,22.9l0.0,0.0 -0.20000076,-0.19999886z"
- android:fillColor="#4DFFFFFF"/>
-</vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_location_on.xml b/packages/SystemUI/res/drawable/ic_qs_location_on.xml
deleted file mode 100644
index 6a7cd53..0000000
--- a/packages/SystemUI/res/drawable/ic_qs_location_on.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<!--
-Copyright (C) 2014 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="64dp"
- android:height="64dp"
- android:viewportWidth="48.0"
- android:viewportHeight="48.0">
-
- <path
- android:fillColor="#FFFFFFFF"
- android:pathData="M24.0,4.0c-7.7,0.0 -14.0,6.3 -14.0,14.0c0.0,10.5 14.0,26.0 14.0,26.0s14.0,-15.5 14.0,-26.0C38.0,10.3 31.7,4.0 24.0,4.0zM24.0,23.0c-2.8,0.0 -5.0,-2.2 -5.0,-5.0s2.2,-5.0 5.0,-5.0c2.8,0.0 5.0,2.2 5.0,5.0S26.8,23.0 24.0,23.0z"/>
-</vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_rotation_landscape.xml b/packages/SystemUI/res/drawable/ic_qs_rotation_landscape.xml
deleted file mode 100644
index 4bb3668..0000000
--- a/packages/SystemUI/res/drawable/ic_qs_rotation_landscape.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<!--
-Copyright (C) 2014 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="64dp"
- android:height="64dp"
- android:viewportWidth="48.0"
- android:viewportHeight="48.0">
-
- <path
- android:fillColor="#FFFFFFFF"
- android:pathData="M2.0,14.0l0.0,20.0c0.0,2.2 1.8,4.0 4.0,4.0l36.0,0.0c2.2,0.0 4.0,-1.8 4.0,-4.0L46.0,14.0c0.0,-2.2 -1.8,-4.0 -4.0,-4.0L6.0,10.0C3.8,10.0 2.0,11.8 2.0,14.0zM38.0,14.0l0.0,20.0L10.0,34.0L10.0,14.0L38.0,14.0z"/>
-</vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_rotation_portrait.xml b/packages/SystemUI/res/drawable/ic_qs_rotation_portrait.xml
deleted file mode 100644
index f0878c7..0000000
--- a/packages/SystemUI/res/drawable/ic_qs_rotation_portrait.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<!--
-Copyright (C) 2014 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="64dp"
- android:height="64dp"
- android:viewportWidth="48.0"
- android:viewportHeight="48.0">
-
- <path
- android:fillColor="#FFFFFFFF"
- android:pathData="M34.0,2.0L14.0,2.0c-2.2,0.0 -4.0,1.8 -4.0,4.0l0.0,36.0c0.0,2.2 1.8,4.0 4.0,4.0l20.0,0.0c2.2,0.0 4.0,-1.8 4.0,-4.0L38.0,6.0C38.0,3.8 36.2,2.0 34.0,2.0zM34.0,38.0L14.0,38.0L14.0,10.0l20.0,0.0L34.0,38.0z"/>
-</vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_rotation_unlocked.xml b/packages/SystemUI/res/drawable/ic_qs_rotation_unlocked.xml
deleted file mode 100644
index 94b3a6b..0000000
--- a/packages/SystemUI/res/drawable/ic_qs_rotation_unlocked.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<!--
-Copyright (C) 2014 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="64dp"
- android:height="64dp"
- android:viewportWidth="24.0"
- android:viewportHeight="24.0">
- <path
- android:fillColor="#FFFFFFFF"
- android:pathData="M16.600000,2.500000c3.300000,1.500000 5.600000,4.700000 6.000000,8.500000l1.500000,0.000000c-0.600000,-6.200000 -5.700000,-11.000000 -12.000000,-11.000000c-0.200000,0.000000 -0.400000,0.000000 -0.700000,0.000000l3.800000,3.800000L16.600000,2.500000zM10.300000,1.700000c-0.600000,-0.600000 -1.500000,-0.600000 -2.100000,0.000000L1.800000,8.100000c-0.600000,0.600000 -0.600000,1.500000 0.000000,2.100000l12.000000,12.000000c0.600000,0.600000 1.500000,0.600000 2.100000,0.000000l6.400000,-6.400000c0.600000,-0.600000 0.600000,-1.500000 0.000000,-2.100000L10.300000,1.700000zM13.400000,19.700001l-9.200000,-9.200000l6.400000,-6.400000l9.200000,9.200000L13.400000,19.700001zM7.600000,21.500000C4.300000,20.000000 2.000000,16.799999 1.600000,13.000000L0.200000,13.000000c0.500000,6.200000 5.600000,11.000000 11.900000,11.000000c0.200000,0.000000 0.400000,0.000000 0.700000,0.000000L9.000000,20.200001L7.600000,21.500000z"/>
-</vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_signal_1.xml b/packages/SystemUI/res/drawable/ic_qs_signal_1.xml
index adbda4a..7fb423e 100644
--- a/packages/SystemUI/res/drawable/ic_qs_signal_1.xml
+++ b/packages/SystemUI/res/drawable/ic_qs_signal_1.xml
@@ -21,14 +21,14 @@
android:viewportHeight="24.0">
<path
android:fillColor="#FFFFFFFF"
- android:pathData="M19.700001,20.000000l2.000000,0.000000l0.000000,2.000000l-2.000000,0.000000z"/>
+ android:pathData="M19.7,20.0l2.0,0.0l0.0,2.0l-2.0,0.0z"/>
<path
android:fillColor="#FFFFFFFF"
- android:pathData="M19.700001,10.000000l2.000000,0.000000l0.000000,8.100000l-2.000000,0.000000z"/>
+ android:pathData="M19.7,10.0l2.0,0.0l0.0,8.1l-2.0,0.0z"/>
+ <path
+ android:fillColor="#4DFFFFFF"
+ android:pathData="M17.7,8.0l4.299999,0.0 0.0,-6.0 -20.0,20.0 15.700001,0.0z"/>
<path
android:fillColor="#FFFFFFFF"
- android:pathData="M11.300000,12.700000l-9.300000,9.300000 9.300000,0.000000z"/>
- <path
- android:pathData="M17.700001,8.000000l4.299999,0.000000 0.000000,-6.000000 -20.000000,20.000000 15.700001,0.000000z"
- android:fillColor="#4DFFFFFF"/>
+ android:pathData="M10.1,13.9l-8.1,8.1 8.1,0.0z"/>
</vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_signal_full_1.xml b/packages/SystemUI/res/drawable/ic_qs_signal_full_1.xml
index a71e33a..8baa4eb 100644
--- a/packages/SystemUI/res/drawable/ic_qs_signal_full_1.xml
+++ b/packages/SystemUI/res/drawable/ic_qs_signal_full_1.xml
@@ -21,8 +21,8 @@
android:viewportHeight="24.0">
<path
android:fillColor="#4DFFFFFF"
- android:pathData="M2.000000,22.000000l20.000000,0.000000 0.000000,-20.000000z"/>
+ android:pathData="M2.0,22.0l20.0,0.0 0.0,-20.0z"/>
<path
android:fillColor="#FFFFFFFF"
- android:pathData="M11.300000,12.700000l-9.300000,9.300000 9.300000,0.000000z"/>
+ android:pathData="M10.1,13.9l-8.1,8.1 8.1,0.0z"/>
</vector>
diff --git a/packages/SystemUI/res/drawable/ic_signal_airplane_disable.xml b/packages/SystemUI/res/drawable/ic_signal_airplane_disable.xml
new file mode 100644
index 0000000..09a67e1
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_signal_airplane_disable.xml
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:name="root"
+ android:alpha="1.0"
+ android:height="48dp"
+ android:width="48dp"
+ android:viewportHeight="48"
+ android:viewportWidth="48" >
+ <group
+ android:name="ic_signal_airplane"
+ android:translateX="21.9995"
+ android:translateY="25.73401" >
+ <group
+ android:name="ic_signal_airplane_pivot"
+ android:translateX="-23.21545"
+ android:translateY="-18.86649" >
+ <clip-path
+ android:name="mask"
+ android:pathData="M 37.8337860107,-40.4599914551 c 0.0,0.0 -35.8077850342,31.5523681641 -35.8077850342,31.5523681641 c 0.0,0.0 9.55097961426,9.55285644531 9.55097961426,9.55285644531 c 0.0,0.0 -2.61698913574,2.09387207031 -2.61698913574,2.09387207031 c 0.0,0.0 -9.75096130371,-9.56428527832 -9.75096130371,-9.56428527832 c 0.0,0.0 -34.6200408936,25.4699249268 -34.6200408936,25.4699249268 c 0.0,0.0 55.9664764404,69.742401123 55.9664764404,69.742401123 c 0.0,0.0 73.2448120117,-59.1047973633 73.2448120117,-59.1047973633 c 0.0,0.0 -55.9664916992,-69.7423400879 -55.9664916992,-69.7423400879 Z" />
+ <group
+ android:name="cross" >
+ <path
+ android:name="cross_1"
+ android:pathData="M 7.54049682617,3.9430847168 c 0.0,0.0 0.324981689453,0.399978637695 0.324981689453,0.399978637695 "
+ android:strokeColor="#FFFFFFFF"
+ android:strokeAlpha="0"
+ android:strokeWidth="3.5"
+ android:fillColor="#00000000" />
+ </group>
+ <group
+ android:name="plane"
+ android:translateX="23.481"
+ android:translateY="18.71151" >
+ <path
+ android:name="plane_1"
+ android:pathData="M 18.9439849854,7.98849487305 c 0.0,0.0 0.0,-4.0 0.0,-4.0 c 0.0,0.0 -16.0,-10.0 -16.0,-10.0 c 0.0,0.0 0.0,-11.0 0.0,-11.0 c 0.0,-1.70001220703 -1.30000305176,-3.0 -3.0,-3.0 c -1.69999694824,0.0 -3.0,1.29998779297 -3.0,3.0 c 0.0,0.0 0.0,11.0 0.0,11.0 c 0.0,0.0 -16.0,10.0 -16.0,10.0 c 0.0,0.0 0.0,4.0 0.0,4.0 c 0.0,0.0 16.0,-5.0 16.0,-5.0 c 0.0,0.0 0.0,11.0 0.0,11.0 c 0.0,0.0 -4.0,3.0 -4.0,3.0 c 0.0,0.0 0.0,3.0 0.0,3.0 c 0.0,0.0 7.0,-2.0 7.0,-2.0 c 0.0,0.0 7.0,2.0 7.0,2.0 c 0.0,0.0 0.0,-3.0 0.0,-3.0 c 0.0,0.0 -4.0,-3.0 -4.0,-3.0 c 0.0,0.0 0.0,-11.0 0.0,-11.0 c 0.0,0.0 16.0,5.0 16.0,5.0 Z"
+ android:fillColor="#FFFFFFFF"
+ android:fillAlpha="1" />
+ </group>
+ </group>
+ </group>
+</vector>
diff --git a/packages/SystemUI/res/drawable/ic_signal_airplane_disable_animation.xml b/packages/SystemUI/res/drawable/ic_signal_airplane_disable_animation.xml
new file mode 100644
index 0000000..3e838e2
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_signal_airplane_disable_animation.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:drawable="@drawable/ic_signal_airplane_disable" >
+ <target
+ android:name="root"
+ android:animation="@anim/ic_signal_airplane_disable_animation_root" />
+ <target
+ android:name="ic_signal_airplane"
+ android:animation="@anim/ic_signal_airplane_disable_animation_ic_signal_airplane" />
+ <target
+ android:name="mask"
+ android:animation="@anim/ic_signal_airplane_disable_animation_mask" />
+ <target
+ android:name="cross_1"
+ android:animation="@anim/ic_signal_airplane_disable_animation_cross_1" />
+</animated-vector>
diff --git a/packages/SystemUI/res/drawable/ic_signal_airplane_enable.xml b/packages/SystemUI/res/drawable/ic_signal_airplane_enable.xml
new file mode 100644
index 0000000..ea3a15b
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_signal_airplane_enable.xml
@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:name="root"
+ android:alpha="0.3"
+ android:height="48dp"
+ android:width="48dp"
+ android:viewportHeight="48"
+ android:viewportWidth="48" >
+ <group
+ android:name="ic_signal_airplane"
+ android:translateX="21.9995"
+ android:translateY="25.73401"
+ android:alpha="0.3" >
+ <group
+ android:name="ic_signal_airplane_pivot"
+ android:translateX="-23.21545"
+ android:translateY="-18.86649" >
+ <clip-path
+ android:name="mask"
+ android:pathData="M 37.8337860107,-40.3974914551 c 0.0,0.0 -35.8077850342,31.5523681641 -35.8077850342,31.5523681641 c 0.0,0.0 40.9884796143,40.9278411865 40.9884796143,40.9278411865 c 0.0,0.0 -2.61700439453,2.0938873291 -2.61700439453,2.0938873291 c 0.0,0.0 -41.1884460449,-40.9392852783 -41.1884460449,-40.9392852783 c 0.0,0.0 -34.6200408936,25.4699249268 -34.6200408936,25.4699249268 c 0.0,0.0 55.9664764404,69.742401123 55.9664764404,69.742401123 c 0.0,0.0 73.2448120117,-59.1047973633 73.2448120117,-59.1047973633 c 0.0,0.0 -55.9664916992,-69.7423400879 -55.9664916992,-69.7423400879 Z" />
+ <group
+ android:name="cross" >
+ <path
+ android:name="cross_1"
+ android:pathData="M 7.54049682617,3.9430847168 c 0.0,0.0 31.5749816895,31.4499664307 31.5749816895,31.4499664307 "
+ android:strokeColor="#FFFFFFFF"
+ android:strokeAlpha="1"
+ android:strokeWidth="3.5"
+ android:fillColor="#00000000" />
+ </group>
+ <group
+ android:name="plane"
+ android:translateX="23.481"
+ android:translateY="18.71151" >
+ <path
+ android:name="plane_1"
+ android:pathData="M 18.9439849854,7.98849487305 c 0.0,0.0 0.0,-4.0 0.0,-4.0 c 0.0,0.0 -16.0,-10.0 -16.0,-10.0 c 0.0,0.0 0.0,-11.0 0.0,-11.0 c 0.0,-1.70001220703 -1.30000305176,-3.0 -3.0,-3.0 c -1.69999694824,0.0 -3.0,1.29998779297 -3.0,3.0 c 0.0,0.0 0.0,11.0 0.0,11.0 c 0.0,0.0 -16.0,10.0 -16.0,10.0 c 0.0,0.0 0.0,4.0 0.0,4.0 c 0.0,0.0 16.0,-5.0 16.0,-5.0 c 0.0,0.0 0.0,11.0 0.0,11.0 c 0.0,0.0 -4.0,3.0 -4.0,3.0 c 0.0,0.0 0.0,3.0 0.0,3.0 c 0.0,0.0 7.0,-2.0 7.0,-2.0 c 0.0,0.0 7.0,2.0 7.0,2.0 c 0.0,0.0 0.0,-3.0 0.0,-3.0 c 0.0,0.0 -4.0,-3.0 -4.0,-3.0 c 0.0,0.0 0.0,-11.0 0.0,-11.0 c 0.0,0.0 16.0,5.0 16.0,5.0 Z"
+ android:fillColor="#FFFFFFFF"
+ android:fillAlpha="1" />
+ </group>
+ </group>
+ </group>
+</vector>
diff --git a/packages/SystemUI/res/drawable/ic_signal_airplane_enable_animation.xml b/packages/SystemUI/res/drawable/ic_signal_airplane_enable_animation.xml
new file mode 100644
index 0000000..d64b199
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_signal_airplane_enable_animation.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:drawable="@drawable/ic_signal_airplane_enable" >
+ <target
+ android:name="root"
+ android:animation="@anim/ic_signal_airplane_enable_animation_root" />
+ <target
+ android:name="ic_signal_airplane"
+ android:animation="@anim/ic_signal_airplane_enable_animation_ic_signal_airplane" />
+ <target
+ android:name="mask"
+ android:animation="@anim/ic_signal_airplane_enable_animation_mask" />
+ <target
+ android:name="cross_1"
+ android:animation="@anim/ic_signal_airplane_enable_animation_cross_1" />
+</animated-vector>
diff --git a/packages/SystemUI/res/drawable/ic_signal_flashlight_disable.xml b/packages/SystemUI/res/drawable/ic_signal_flashlight_disable.xml
new file mode 100644
index 0000000..35844b7
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_signal_flashlight_disable.xml
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:name="root"
+ android:alpha="1.0"
+ android:height="48dp"
+ android:width="48dp"
+ android:viewportHeight="48"
+ android:viewportWidth="48" >
+ <group
+ android:name="ic_signal_flashlight"
+ android:translateX="21.9995"
+ android:translateY="25.73401" >
+ <group
+ android:name="ic_signal_flashlight_pivot"
+ android:translateX="-23.21545"
+ android:translateY="-18.86649" >
+ <clip-path
+ android:name="mask"
+ android:pathData="M 37.8337860107,-39.2849731445 c 0.0,0.0 -35.8077850342,31.5523681641 -35.8077850342,31.5523681641 c 0.0,0.0 9.55097961426,9.55285644531 9.55097961426,9.55285644531 c 0.0,0.0 -2.61698913574,2.09387207031 -2.61698913574,2.09387207031 c 0.0,0.0 -9.75096130371,-9.56428527832 -9.75096130371,-9.56428527832 c 0.0,0.0 -34.6200408936,25.4699249268 -34.6200408936,25.4699249268 c 0.0,0.0 55.9664764404,69.742401123 55.9664764404,69.742401123 c 0.0,0.0 73.2448120117,-59.1047973633 73.2448120117,-59.1047973633 c 0.0,0.0 -55.9664916992,-69.7423400879 -55.9664916992,-69.7423400879 Z" />
+ <group
+ android:name="cross" >
+ <path
+ android:name="cross_1"
+ android:pathData="M 8.34049987793,5.6930847168 c 0.0,0.0 0.274993896484,0.29997253418 0.274993896484,0.29997253418 "
+ android:strokeColor="#FFFFFFFF"
+ android:strokeAlpha="0"
+ android:strokeWidth="3.5"
+ android:fillColor="#00000000" />
+ </group>
+ <group
+ android:name="flashlight"
+ android:translateX="25.06235"
+ android:translateY="22.48294" >
+ <path
+ android:name="light"
+ android:pathData="M -9.40809631348,-23.6970062256 c 0.0,0.0 18.8699951172,0.0 18.8699951172,0.0 c 0.0,0.0 0.0,3.91700744629 0.0,3.91700744629 c 0.0,0.0 -18.8699951172,0.0 -18.8699951172,0.0 c 0.0,0.0 0.0,-3.91700744629 0.0,-3.91700744629 Z M 9.4615020752,-15.6629943848 c 0.0,0.0 0.0,-0.639999389648 0.0,-0.639999389649 c 0.0,0.0 -18.8699951172,0.0 -18.8699951172,0.0 c 0.0,0.0 0.0,0.639999389648 0.0,0.639999389649 c 0.0,0.0 -0.581008911133,5.18899536133 3.82598876953,7.52299499512 c 0.0,0.0 0.0,24.4429931641 0.0,24.4429931641 c 0.0,0.0 11.2129974365,0.0 11.2129974365,0.0 c 0.0,0.0 0.0,-24.4769897461 0.0,-24.4769897461 c 4.35900878906,-2.35301208496 3.83100891113,-7.48899841309 3.83100891113,-7.48899841309 Z M 0.0234985351562,0 c -1.52299499512,0 -2.75700378418,-1.23399353027 -2.75700378418,-2.75700378418 c 0.0,-1.52299499512 1.23400878906,-2.75700378418 2.75700378418,-2.75700378418 c 1.52299499512,0.0 2.75700378418,1.23400878906 2.75700378418,2.75700378418 c 0.0,1.52200317383 -1.23400878906,2.75700378418 -2.75700378418,2.75700378418 Z"
+ android:fillColor="#FFFFFFFF"
+ android:fillAlpha="1" />
+ </group>
+ </group>
+ </group>
+</vector>
diff --git a/packages/SystemUI/res/drawable/ic_signal_flashlight_disable_animation.xml b/packages/SystemUI/res/drawable/ic_signal_flashlight_disable_animation.xml
new file mode 100644
index 0000000..6d787ab
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_signal_flashlight_disable_animation.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:drawable="@drawable/ic_signal_flashlight_disable" >
+ <target
+ android:name="root"
+ android:animation="@anim/ic_signal_flashlight_disable_animation_root" />
+ <target
+ android:name="ic_signal_flashlight"
+ android:animation="@anim/ic_signal_flashlight_disable_animation_ic_signal_flashlight" />
+ <target
+ android:name="mask"
+ android:animation="@anim/ic_signal_flashlight_disable_animation_mask" />
+ <target
+ android:name="cross_1"
+ android:animation="@anim/ic_signal_flashlight_disable_animation_cross_1" />
+</animated-vector>
diff --git a/packages/SystemUI/res/drawable/ic_signal_flashlight_enable.xml b/packages/SystemUI/res/drawable/ic_signal_flashlight_enable.xml
new file mode 100644
index 0000000..93e97ee
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_signal_flashlight_enable.xml
@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:name="root"
+ android:alpha="0.3"
+ android:height="48dp"
+ android:width="48dp"
+ android:viewportHeight="48"
+ android:viewportWidth="48" >
+ <group
+ android:name="ic_signal_flashlight"
+ android:translateX="21.9995"
+ android:translateY="25.73401"
+ android:alpha="0.3" >
+ <group
+ android:name="ic_signal_flashlight_pivot"
+ android:translateX="-23.21545"
+ android:translateY="-18.86649" >
+ <clip-path
+ android:name="mask"
+ android:pathData="M 37.8337860107,-39.2975769043 c 0.0,0.0 -35.8077850342,31.5523681641 -35.8077850342,31.5523681641 c 0.0,0.0 40.9884796143,40.9278411865 40.9884796143,40.9278411865 c 0.0,0.0 -2.61700439453,2.0938873291 -2.61700439453,2.0938873291 c 0.0,0.0 -41.1884460449,-40.9392852783 -41.1884460449,-40.9392852783 c 0.0,0.0 -34.6200408936,25.4699249268 -34.6200408936,25.4699249268 c 0.0,0.0 55.9664764404,69.742401123 55.9664764404,69.742401123 c 0.0,0.0 73.2448120117,-59.1047973633 73.2448120117,-59.1047973633 c 0.0,0.0 -55.9664916992,-69.7423400879 -55.9664916992,-69.7423400879 Z" />
+ <group
+ android:name="cross" >
+ <path
+ android:name="cross_1"
+ android:pathData="M 8.34049987793,5.6930847168 c 0.0,0.0 29.7749786377,29.7999725342 29.7749786377,29.7999725342 "
+ android:strokeColor="#FFFFFFFF"
+ android:strokeAlpha="1"
+ android:strokeWidth="3.5"
+ android:fillColor="#00000000" />
+ </group>
+ <group
+ android:name="flashlight"
+ android:translateX="25.06235"
+ android:translateY="22.48294" >
+ <path
+ android:name="light"
+ android:pathData="M -9.40809631348,-23.6970062256 c 0.0,0.0 18.8699951172,0.0 18.8699951172,0.0 c 0.0,0.0 0.0,3.91700744629 0.0,3.91700744629 c 0.0,0.0 -18.8699951172,0.0 -18.8699951172,0.0 c 0.0,0.0 0.0,-3.91700744629 0.0,-3.91700744629 Z M 9.4615020752,-15.6629943848 c 0.0,0.0 0.0,-0.639999389648 0.0,-0.639999389649 c 0.0,0.0 -18.8699951172,0.0 -18.8699951172,0.0 c 0.0,0.0 0.0,0.639999389648 0.0,0.639999389649 c 0.0,0.0 -0.581008911133,5.18899536133 3.82598876953,7.52299499512 c 0.0,0.0 0.0,24.4429931641 0.0,24.4429931641 c 0.0,0.0 11.2129974365,0.0 11.2129974365,0.0 c 0.0,0.0 0.0,-24.4769897461 0.0,-24.4769897461 c 4.35900878906,-2.35301208496 3.83100891113,-7.48899841309 3.83100891113,-7.48899841309 Z M 0.0234985351562,0 c -1.52299499512,0 -2.75700378418,-1.23399353027 -2.75700378418,-2.75700378418 c 0.0,-1.52299499512 1.23400878906,-2.75700378418 2.75700378418,-2.75700378418 c 1.52299499512,0.0 2.75700378418,1.23400878906 2.75700378418,2.75700378418 c 0.0,1.52200317383 -1.23400878906,2.75700378418 -2.75700378418,2.75700378418 Z"
+ android:fillColor="#FFFFFFFF"
+ android:fillAlpha="1" />
+ </group>
+ </group>
+ </group>
+</vector>
diff --git a/packages/SystemUI/res/drawable/ic_signal_flashlight_enable_animation.xml b/packages/SystemUI/res/drawable/ic_signal_flashlight_enable_animation.xml
new file mode 100644
index 0000000..dcfba7d
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_signal_flashlight_enable_animation.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:drawable="@drawable/ic_signal_flashlight_enable" >
+ <target
+ android:name="root"
+ android:animation="@anim/ic_signal_flashlight_enable_animation_root" />
+ <target
+ android:name="ic_signal_flashlight"
+ android:animation="@anim/ic_signal_flashlight_enable_animation_ic_signal_flashlight" />
+ <target
+ android:name="mask"
+ android:animation="@anim/ic_signal_flashlight_enable_animation_mask" />
+ <target
+ android:name="cross_1"
+ android:animation="@anim/ic_signal_flashlight_enable_animation_cross_1" />
+</animated-vector>
diff --git a/packages/SystemUI/res/drawable/ic_signal_location_disable.xml b/packages/SystemUI/res/drawable/ic_signal_location_disable.xml
new file mode 100644
index 0000000..439851d
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_signal_location_disable.xml
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:name="root"
+ android:alpha="1.0"
+ android:height="48dp"
+ android:width="48dp"
+ android:viewportHeight="48"
+ android:viewportWidth="48" >
+ <group
+ android:name="ic_signal_location"
+ android:translateX="21.9995"
+ android:translateY="25.73401" >
+ <group
+ android:name="ic_signal_location_pivot"
+ android:translateX="-23.21545"
+ android:translateY="-18.86649" >
+ <clip-path
+ android:name="mask"
+ android:pathData="M 38.8337860107,-40.4599914551 c 0.0,0.0 -35.8077850342,31.5523681641 -35.8077850342,31.5523681641 c 0.0,0.0 7.3759765625,7.55284118652 7.3759765625,7.55284118652 c 0.0,0.0 -2.61698913574,2.0938873291 -2.61698913574,2.0938873291 c 0.0,0.0 -7.57595825195,-7.56428527832 -7.57595825195,-7.56428527832 c 0.0,0.0 -34.6200408936,25.4699249268 -34.6200408936,25.4699249268 c 0.0,0.0 55.9664764404,69.742401123 55.9664764404,69.742401123 c 0.0,0.0 73.2448120117,-59.1047973633 73.2448120117,-59.1047973633 c 0.0,0.0 -55.9664916992,-69.7423400879 -55.9664916992,-69.7423400879 Z" />
+ <group
+ android:name="cross" >
+ <path
+ android:name="cross_1"
+ android:pathData="M 6.44050598145,1.9430847168 c 0.0,0.0 0.374984741211,0.399978637695 0.374984741211,0.399978637695 "
+ android:strokeColor="#FFFFFFFF"
+ android:strokeAlpha="0"
+ android:strokeWidth="3.5"
+ android:fillColor="#00000000" />
+ </group>
+ <group
+ android:name="location"
+ android:translateX="23.481"
+ android:translateY="18.71151" >
+ <path
+ android:name="pin"
+ android:pathData="M 1.76899719238,-20.011505127 c -7.69999694824,0.0 -14.0,6.30000305176 -14.0,14.0 c 0.0,10.5 14.0,26.0 14.0,26.0 c 0.0,0.0 14.0,-15.5 14.0,-26.0 c 0.0,-7.69999694824 -6.30000305176,-14.0 -14.0,-14.0 Z M 1.76899719238,-1.01150512695 c -2.80000305176,0.0 -5.0,-2.19999694824 -5.0,-5.0 c 0.0,-2.80000305176 2.19999694824,-5.0 5.0,-5.0 c 2.80000305176,0.0 5.0,2.19999694824 5.0,5.0 c 0.0,2.80000305176 -2.19999694824,5.0 -5.0,5.0 Z"
+ android:fillColor="#FFFFFFFF"
+ android:fillAlpha="1" />
+ </group>
+ </group>
+ </group>
+</vector>
diff --git a/packages/SystemUI/res/drawable/ic_signal_location_disable_animation.xml b/packages/SystemUI/res/drawable/ic_signal_location_disable_animation.xml
new file mode 100644
index 0000000..a219c54
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_signal_location_disable_animation.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:drawable="@drawable/ic_signal_location_disable" >
+ <target
+ android:name="root"
+ android:animation="@anim/ic_signal_location_disable_animation_root" />
+ <target
+ android:name="ic_signal_location"
+ android:animation="@anim/ic_signal_location_disable_animation_ic_signal_location" />
+ <target
+ android:name="mask"
+ android:animation="@anim/ic_signal_location_disable_animation_mask" />
+ <target
+ android:name="cross_1"
+ android:animation="@anim/ic_signal_location_disable_animation_cross_1" />
+</animated-vector>
diff --git a/packages/SystemUI/res/drawable/ic_signal_location_enable.xml b/packages/SystemUI/res/drawable/ic_signal_location_enable.xml
new file mode 100644
index 0000000..c800ef4
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_signal_location_enable.xml
@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:name="root"
+ android:alpha="0.3"
+ android:height="48dp"
+ android:width="48dp"
+ android:viewportHeight="48"
+ android:viewportWidth="48" >
+ <group
+ android:name="ic_signal_location"
+ android:translateX="21.9995"
+ android:translateY="25.73401"
+ android:alpha="0.3" >
+ <group
+ android:name="ic_signal_location_pivot"
+ android:translateX="-23.21545"
+ android:translateY="-18.86649" >
+ <clip-path
+ android:name="mask"
+ android:pathData="M 38.8337860107,-40.3974914551 c 0.0,0.0 -35.8077850342,31.5523681641 -35.8077850342,31.5523681641 c 0.0,0.0 40.9884796143,41.1153411865 40.9884796143,41.1153411865 c 0.0,0.0 -2.61700439453,2.0938873291 -2.61700439453,2.0938873291 c 0.0,0.0 -41.1884460449,-41.1267852783 -41.1884460449,-41.1267852783 c 0.0,0.0 -34.6200408936,25.4699249268 -34.6200408936,25.4699249268 c 0.0,0.0 55.9664764404,69.742401123 55.9664764404,69.742401123 c 0.0,0.0 73.2448120117,-59.1047973633 73.2448120117,-59.1047973633 c 0.0,0.0 -55.9664916992,-69.7423400879 -55.9664916992,-69.7423400879 Z" />
+ <group
+ android:name="cross" >
+ <path
+ android:name="cross_1"
+ android:pathData="M 6.44050598145,1.9430847168 c 0.0,0.0 33.5749816895,33.4499664307 33.5749816895,33.4499664307 "
+ android:strokeColor="#FFFFFFFF"
+ android:strokeAlpha="1"
+ android:strokeWidth="3.5"
+ android:fillColor="#00000000" />
+ </group>
+ <group
+ android:name="location"
+ android:translateX="23.481"
+ android:translateY="18.71151" >
+ <path
+ android:name="pin"
+ android:pathData="M 1.76899719238,-20.011505127 c -7.69999694824,0.0 -14.0,6.30000305176 -14.0,14.0 c 0.0,10.5 14.0,26.0 14.0,26.0 c 0.0,0.0 14.0,-15.5 14.0,-26.0 c 0.0,-7.69999694824 -6.30000305176,-14.0 -14.0,-14.0 Z M 1.76899719238,-1.01150512695 c -2.80000305176,0.0 -5.0,-2.19999694824 -5.0,-5.0 c 0.0,-2.80000305176 2.19999694824,-5.0 5.0,-5.0 c 2.80000305176,0.0 5.0,2.19999694824 5.0,5.0 c 0.0,2.80000305176 -2.19999694824,5.0 -5.0,5.0 Z"
+ android:fillColor="#FFFFFFFF"
+ android:fillAlpha="1" />
+ </group>
+ </group>
+ </group>
+</vector>
diff --git a/packages/SystemUI/res/drawable/ic_signal_location_enable_animation.xml b/packages/SystemUI/res/drawable/ic_signal_location_enable_animation.xml
new file mode 100644
index 0000000..bbc1d73
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_signal_location_enable_animation.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:drawable="@drawable/ic_signal_location_enable" >
+ <target
+ android:name="root"
+ android:animation="@anim/ic_signal_location_enable_animation_root" />
+ <target
+ android:name="ic_signal_location"
+ android:animation="@anim/ic_signal_location_enable_animation_ic_signal_location" />
+ <target
+ android:name="mask"
+ android:animation="@anim/ic_signal_location_enable_animation_mask" />
+ <target
+ android:name="cross_1"
+ android:animation="@anim/ic_signal_location_enable_animation_cross_1" />
+</animated-vector>
diff --git a/packages/SystemUI/res/drawable/stat_sys_signal_1.xml b/packages/SystemUI/res/drawable/stat_sys_signal_1.xml
index a53e946..d1124ee 100644
--- a/packages/SystemUI/res/drawable/stat_sys_signal_1.xml
+++ b/packages/SystemUI/res/drawable/stat_sys_signal_1.xml
@@ -21,14 +21,14 @@
android:viewportHeight="24.0">
<path
android:fillColor="#FFFFFFFF"
- android:pathData="M19.700001,20.000000l2.000000,0.000000l0.000000,2.000000l-2.000000,0.000000z"/>
+ android:pathData="M19.7,20.0l2.0,0.0l0.0,2.0l-2.0,0.0z"/>
<path
android:fillColor="#FFFFFFFF"
- android:pathData="M19.700001,10.000000l2.000000,0.000000l0.000000,8.100000l-2.000000,0.000000z"/>
+ android:pathData="M19.7,10.0l2.0,0.0l0.0,8.1l-2.0,0.0z"/>
+ <path
+ android:fillColor="#4DFFFFFF"
+ android:pathData="M17.7,8.0l4.299999,0.0 0.0,-6.0 -20.0,20.0 15.700001,0.0z"/>
<path
android:fillColor="#FFFFFFFF"
- android:pathData="M11.300000,12.700000l-9.300000,9.300000 9.300000,0.000000z"/>
- <path
- android:pathData="M17.700001,8.000000l4.299999,0.000000 0.000000,-6.000000 -20.000000,20.000000 15.700001,0.000000z"
- android:fillColor="#4DFFFFFF"/>
+ android:pathData="M10.1,13.9l-8.1,8.1 8.1,0.0z"/>
</vector>
diff --git a/packages/SystemUI/res/drawable/stat_sys_signal_1_fully.xml b/packages/SystemUI/res/drawable/stat_sys_signal_1_fully.xml
index 6bc55cd..29eda94 100644
--- a/packages/SystemUI/res/drawable/stat_sys_signal_1_fully.xml
+++ b/packages/SystemUI/res/drawable/stat_sys_signal_1_fully.xml
@@ -21,8 +21,8 @@
android:viewportHeight="24.0">
<path
android:fillColor="#4DFFFFFF"
- android:pathData="M2.000000,22.000000l20.000000,0.000000 0.000000,-20.000000z"/>
+ android:pathData="M2.0,22.0l20.0,0.0 0.0,-20.0z"/>
<path
android:fillColor="#FFFFFFFF"
- android:pathData="M11.300000,12.700000l-9.300000,9.300000 9.300000,0.000000z"/>
+ android:pathData="M10.1,13.9l-8.1,8.1 8.1,0.0z"/>
</vector>
diff --git a/packages/SystemUI/res/interpolator/ic_invert_colors_disable_cross_1_pathdata_interpolator.xml b/packages/SystemUI/res/interpolator/ic_invert_colors_disable_cross_1_pathdata_interpolator.xml
new file mode 100644
index 0000000..bc0442f
--- /dev/null
+++ b/packages/SystemUI/res/interpolator/ic_invert_colors_disable_cross_1_pathdata_interpolator.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<pathInterpolator xmlns:android="http://schemas.android.com/apk/res/android"
+ android:pathData="M 0,0 c 0.166666667,0 0.2,1 1,1" />
diff --git a/packages/SystemUI/res/interpolator/ic_invert_colors_enable_cross_1_pathdata_interpolator.xml b/packages/SystemUI/res/interpolator/ic_invert_colors_enable_cross_1_pathdata_interpolator.xml
new file mode 100644
index 0000000..bc90d28
--- /dev/null
+++ b/packages/SystemUI/res/interpolator/ic_invert_colors_enable_cross_1_pathdata_interpolator.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<pathInterpolator xmlns:android="http://schemas.android.com/apk/res/android"
+ android:pathData="M 0,0 c 0.8,0 0.833333333,1 1,1" />
diff --git a/packages/SystemUI/res/interpolator/ic_invert_colors_enable_mask_pathdata_interpolator.xml b/packages/SystemUI/res/interpolator/ic_invert_colors_enable_mask_pathdata_interpolator.xml
new file mode 100644
index 0000000..f7072f2
--- /dev/null
+++ b/packages/SystemUI/res/interpolator/ic_invert_colors_enable_mask_pathdata_interpolator.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<pathInterpolator xmlns:android="http://schemas.android.com/apk/res/android"
+ android:pathData="M 0,0 c 0.8,0 0.6,1 1,1" />
diff --git a/packages/SystemUI/res/interpolator/ic_landscape_from_auto_rotate_arrows_rotation_interpolator.xml b/packages/SystemUI/res/interpolator/ic_landscape_from_auto_rotate_arrows_rotation_interpolator.xml
new file mode 100644
index 0000000..76f5667
--- /dev/null
+++ b/packages/SystemUI/res/interpolator/ic_landscape_from_auto_rotate_arrows_rotation_interpolator.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<pathInterpolator xmlns:android="http://schemas.android.com/apk/res/android"
+ android:pathData="M 0,0 c 0.458031162,0 0.299442342,0.748308635 1,1" />
diff --git a/packages/SystemUI/res/interpolator/ic_landscape_to_auto_rotate_arrows_rotation_interpolator.xml b/packages/SystemUI/res/interpolator/ic_landscape_to_auto_rotate_arrows_rotation_interpolator.xml
new file mode 100644
index 0000000..ac27e4d
--- /dev/null
+++ b/packages/SystemUI/res/interpolator/ic_landscape_to_auto_rotate_arrows_rotation_interpolator.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<pathInterpolator xmlns:android="http://schemas.android.com/apk/res/android"
+ android:pathData="M 0,0 c 0.4,0.143709151 0.2,1 1,1" />
diff --git a/packages/SystemUI/res/interpolator/ic_signal_airplane_disable_cross_1_pathdata_interpolator.xml b/packages/SystemUI/res/interpolator/ic_signal_airplane_disable_cross_1_pathdata_interpolator.xml
new file mode 100644
index 0000000..bc0442f
--- /dev/null
+++ b/packages/SystemUI/res/interpolator/ic_signal_airplane_disable_cross_1_pathdata_interpolator.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<pathInterpolator xmlns:android="http://schemas.android.com/apk/res/android"
+ android:pathData="M 0,0 c 0.166666667,0 0.2,1 1,1" />
diff --git a/packages/SystemUI/res/interpolator/ic_signal_airplane_enable_cross_1_pathdata_interpolator.xml b/packages/SystemUI/res/interpolator/ic_signal_airplane_enable_cross_1_pathdata_interpolator.xml
new file mode 100644
index 0000000..bc90d28
--- /dev/null
+++ b/packages/SystemUI/res/interpolator/ic_signal_airplane_enable_cross_1_pathdata_interpolator.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<pathInterpolator xmlns:android="http://schemas.android.com/apk/res/android"
+ android:pathData="M 0,0 c 0.8,0 0.833333333,1 1,1" />
diff --git a/packages/SystemUI/res/interpolator/ic_signal_airplane_enable_mask_pathdata_interpolator.xml b/packages/SystemUI/res/interpolator/ic_signal_airplane_enable_mask_pathdata_interpolator.xml
new file mode 100644
index 0000000..f7072f2
--- /dev/null
+++ b/packages/SystemUI/res/interpolator/ic_signal_airplane_enable_mask_pathdata_interpolator.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<pathInterpolator xmlns:android="http://schemas.android.com/apk/res/android"
+ android:pathData="M 0,0 c 0.8,0 0.6,1 1,1" />
diff --git a/packages/SystemUI/res/interpolator/ic_signal_flashlight_enable_cross_1_pathdata_interpolator.xml b/packages/SystemUI/res/interpolator/ic_signal_flashlight_enable_cross_1_pathdata_interpolator.xml
new file mode 100644
index 0000000..f7072f2
--- /dev/null
+++ b/packages/SystemUI/res/interpolator/ic_signal_flashlight_enable_cross_1_pathdata_interpolator.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<pathInterpolator xmlns:android="http://schemas.android.com/apk/res/android"
+ android:pathData="M 0,0 c 0.8,0 0.6,1 1,1" />
diff --git a/packages/SystemUI/res/interpolator/ic_signal_flashlight_enable_mask_pathdata_interpolator.xml b/packages/SystemUI/res/interpolator/ic_signal_flashlight_enable_mask_pathdata_interpolator.xml
new file mode 100644
index 0000000..f7072f2
--- /dev/null
+++ b/packages/SystemUI/res/interpolator/ic_signal_flashlight_enable_mask_pathdata_interpolator.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<pathInterpolator xmlns:android="http://schemas.android.com/apk/res/android"
+ android:pathData="M 0,0 c 0.8,0 0.6,1 1,1" />
diff --git a/packages/SystemUI/res/interpolator/ic_signal_location_enable_cross_1_pathdata_interpolator.xml b/packages/SystemUI/res/interpolator/ic_signal_location_enable_cross_1_pathdata_interpolator.xml
new file mode 100644
index 0000000..f7072f2
--- /dev/null
+++ b/packages/SystemUI/res/interpolator/ic_signal_location_enable_cross_1_pathdata_interpolator.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<pathInterpolator xmlns:android="http://schemas.android.com/apk/res/android"
+ android:pathData="M 0,0 c 0.8,0 0.6,1 1,1" />
diff --git a/packages/SystemUI/res/interpolator/ic_signal_location_enable_mask_pathdata_interpolator.xml b/packages/SystemUI/res/interpolator/ic_signal_location_enable_mask_pathdata_interpolator.xml
new file mode 100644
index 0000000..f7072f2
--- /dev/null
+++ b/packages/SystemUI/res/interpolator/ic_signal_location_enable_mask_pathdata_interpolator.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<pathInterpolator xmlns:android="http://schemas.android.com/apk/res/android"
+ android:pathData="M 0,0 c 0.8,0 0.6,1 1,1" />
diff --git a/packages/SystemUI/res/values-da/strings.xml b/packages/SystemUI/res/values-da/strings.xml
index ae8ccf3..6770cba 100644
--- a/packages/SystemUI/res/values-da/strings.xml
+++ b/packages/SystemUI/res/values-da/strings.xml
@@ -275,7 +275,7 @@
<string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"Advarsel ved <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string>
<string name="recents_empty_message" msgid="8682129509540827999">"Dine seneste skærme vises her"</string>
<string name="recents_app_info_button_label" msgid="2890317189376000030">"Oplysninger om applikationen"</string>
- <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"skærmfastholdelse"</string>
+ <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"bliv i app"</string>
<string name="recents_search_bar_label" msgid="8074997400187836677">"søg"</string>
<string name="recents_launch_error_message" msgid="2969287838120550506">"<xliff:g id="APP">%s</xliff:g> kunne ikke startes."</string>
<string name="expanded_header_battery_charged" msgid="5945855970267657951">"Opladet"</string>
diff --git a/packages/SystemUI/res/values-hr/strings.xml b/packages/SystemUI/res/values-hr/strings.xml
index 101b4cd..bffb405 100644
--- a/packages/SystemUI/res/values-hr/strings.xml
+++ b/packages/SystemUI/res/values-hr/strings.xml
@@ -275,7 +275,7 @@
<string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"Upozorenje <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string>
<string name="recents_empty_message" msgid="8682129509540827999">"Ovdje se pojavljuju vaši nedavni zasloni"</string>
<string name="recents_app_info_button_label" msgid="2890317189376000030">"Informacije o aplikaciji"</string>
- <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"prikačivanje zaslona"</string>
+ <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"prikvačivanje zaslona"</string>
<string name="recents_search_bar_label" msgid="8074997400187836677">"pretraži"</string>
<string name="recents_launch_error_message" msgid="2969287838120550506">"Aplikacija <xliff:g id="APP">%s</xliff:g> nije pokrenuta."</string>
<string name="expanded_header_battery_charged" msgid="5945855970267657951">"Napunjeno"</string>
diff --git a/packages/SystemUI/res/values-ka-rGE/strings.xml b/packages/SystemUI/res/values-ka-rGE/strings.xml
index 9f4163f..5bf4867 100644
--- a/packages/SystemUI/res/values-ka-rGE/strings.xml
+++ b/packages/SystemUI/res/values-ka-rGE/strings.xml
@@ -275,8 +275,7 @@
<string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"<xliff:g id="DATA_LIMIT">%s</xliff:g> გაფრთხილება"</string>
<string name="recents_empty_message" msgid="8682129509540827999">"თქვენი ბოლო ეკრანები აქ გამოჩნდება"</string>
<string name="recents_app_info_button_label" msgid="2890317189376000030">"აპლიკაციის შესახებ"</string>
- <!-- no translation found for recents_lock_to_app_button_label (6942899049072506044) -->
- <skip />
+ <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"ეკრანზე ჩამაგრება"</string>
<string name="recents_search_bar_label" msgid="8074997400187836677">"ძიება"</string>
<string name="recents_launch_error_message" msgid="2969287838120550506">"<xliff:g id="APP">%s</xliff:g>-ის გამოძახება ვერ მოხერხდა."</string>
<string name="expanded_header_battery_charged" msgid="5945855970267657951">"დატენილია"</string>
diff --git a/packages/SystemUI/res/values-kn-rIN/strings.xml b/packages/SystemUI/res/values-kn-rIN/strings.xml
index 99d8acd..ba13260 100644
--- a/packages/SystemUI/res/values-kn-rIN/strings.xml
+++ b/packages/SystemUI/res/values-kn-rIN/strings.xml
@@ -275,7 +275,7 @@
<string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"<xliff:g id="DATA_LIMIT">%s</xliff:g> ಎಚ್ಚರಿಕೆ"</string>
<string name="recents_empty_message" msgid="8682129509540827999">"ನಿಮ್ಮ ಇತ್ತೀಚಿನ ಪರದೆಗಳು ಇಲ್ಲಿ ಕಾಣಿಸಿಕೊಳ್ಳುತ್ತವೆ"</string>
<string name="recents_app_info_button_label" msgid="2890317189376000030">"ಅಪ್ಲಿಕೇಶನ್ ಮಾಹಿತಿ"</string>
- <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"ಪರದೆ ಪಿನ್ನಿಂಗ್"</string>
+ <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"ಸ್ಕ್ರೀನ್ ಪಿನ್ನಿಂಗ್"</string>
<string name="recents_search_bar_label" msgid="8074997400187836677">"ಹುಡುಕಾಟ"</string>
<string name="recents_launch_error_message" msgid="2969287838120550506">"<xliff:g id="APP">%s</xliff:g> ಪ್ರಾರಂಭಿಸಲು ಸಾದ್ಯವಿಲ್ಲ."</string>
<string name="expanded_header_battery_charged" msgid="5945855970267657951">"ಚಾರ್ಜ್ ಆಗಿದೆ"</string>
diff --git a/packages/SystemUI/res/values-ne-rNP/strings.xml b/packages/SystemUI/res/values-ne-rNP/strings.xml
index 6caf070..4365cd5 100644
--- a/packages/SystemUI/res/values-ne-rNP/strings.xml
+++ b/packages/SystemUI/res/values-ne-rNP/strings.xml
@@ -26,8 +26,8 @@
<string name="status_bar_no_recent_apps" msgid="7374907845131203189">"तपाईँको हालको स्क्रिन यहाँ प्रकट हुन्छ"</string>
<string name="status_bar_accessibility_dismiss_recents" msgid="4576076075226540105">"नयाँ अनुप्रयोगहरू खारेज गर्नुहोस्"</string>
<plurals name="status_bar_accessibility_recent_apps">
- <item quantity="one" msgid="3969335317929254918">"अवलोकन मा १ पर्दा"</item>
- <item quantity="other" msgid="5523506463832158203">"अवलोकन मा %%d स्क्रीन"</item>
+ <item quantity="one" msgid="3969335317929254918">"सारांशमा 1 पर्दा"</item>
+ <item quantity="other" msgid="5523506463832158203">"सारांशमा %d पर्दाहरू"</item>
</plurals>
<string name="status_bar_no_notifications_title" msgid="4755261167193833213">"कुनै सूचनाहरू छैन"</string>
<string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"चलिरहेको"</string>
@@ -80,7 +80,7 @@
<string name="accessibility_back" msgid="567011538994429120">"पछाडि"</string>
<string name="accessibility_home" msgid="8217216074895377641">"गृह"</string>
<string name="accessibility_menu" msgid="316839303324695949">"मेनु"</string>
- <string name="accessibility_recent" msgid="5208608566793607626">"अवलोकन"</string>
+ <string name="accessibility_recent" msgid="5208608566793607626">"सारांश"</string>
<string name="accessibility_search_light" msgid="1103867596330271848">"खोज्नुहोस्"</string>
<string name="accessibility_camera_button" msgid="8064671582820358152">"क्यामेरा"</string>
<string name="accessibility_phone_button" msgid="6738112589538563574">"फोन"</string>
@@ -165,7 +165,7 @@
<string name="accessibility_desc_quick_settings" msgid="6186378411582437046">"द्रुत सेटिङहरू"</string>
<string name="accessibility_desc_lock_screen" msgid="5625143713611759164">"स्क्रीन बन्द गर्नुहोस्।"</string>
<string name="accessibility_desc_settings" msgid="3417884241751434521">"सेटिङहरू"</string>
- <string name="accessibility_desc_recent_apps" msgid="4876900986661819788">"अवलोकन।"</string>
+ <string name="accessibility_desc_recent_apps" msgid="4876900986661819788">"सारांश।"</string>
<string name="accessibility_quick_settings_user" msgid="1104846699869476855">"प्रयोगकर्ता <xliff:g id="USER">%s</xliff:g>।"</string>
<string name="accessibility_quick_settings_wifi" msgid="5518210213118181692">"<xliff:g id="SIGNAL">%1$s</xliff:g>।"</string>
<string name="accessibility_quick_settings_wifi_changed_off" msgid="8716484460897819400">"वाइफाइ बन्द गरियो।"</string>
diff --git a/packages/SystemUI/res/values-zh-rTW/strings.xml b/packages/SystemUI/res/values-zh-rTW/strings.xml
index 773ce0f..a9dcc39 100644
--- a/packages/SystemUI/res/values-zh-rTW/strings.xml
+++ b/packages/SystemUI/res/values-zh-rTW/strings.xml
@@ -298,7 +298,7 @@
<string name="speed_bump_explanation" msgid="1288875699658819755">"較不緊急的通知會顯示在下方"</string>
<string name="notification_tap_again" msgid="8524949573675922138">"再次輕觸即可開啟"</string>
<string name="keyguard_unlock" msgid="8043466894212841998">"向上滑動即可解鎖"</string>
- <string name="phone_hint" msgid="3101468054914424646">"向左滑動可使用手機功能"</string>
+ <string name="phone_hint" msgid="3101468054914424646">"向右滑動可使用手機功能"</string>
<string name="camera_hint" msgid="5241441720959174226">"向左滑動可使用相機功能"</string>
<string name="interruption_level_none" msgid="3831278883136066646">"無"</string>
<string name="interruption_level_priority" msgid="6517366750688942030">"優先"</string>
diff --git a/packages/SystemUI/res/values/ids.xml b/packages/SystemUI/res/values/ids.xml
index 4e93cd8..4a9eb55 100644
--- a/packages/SystemUI/res/values/ids.xml
+++ b/packages/SystemUI/res/values/ids.xml
@@ -35,5 +35,6 @@
<item type="id" name="top_inset_animator_start_value_tag"/>
<item type="id" name="height_animator_start_value_tag"/>
<item type="id" name="doze_saved_filter_tag"/>
+ <item type="id" name="qs_icon_tag"/>
</resources>
diff --git a/packages/SystemUI/src/com/android/systemui/ExpandHelper.java b/packages/SystemUI/src/com/android/systemui/ExpandHelper.java
index 0f8fe1c..d42ac612 100644
--- a/packages/SystemUI/src/com/android/systemui/ExpandHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/ExpandHelper.java
@@ -351,6 +351,9 @@
mVelocityTracker.addMovement(event);
break;
case MotionEvent.ACTION_MOVE:
+ if (mVelocityTracker == null) {
+ mVelocityTracker = VelocityTracker.obtain();
+ }
mVelocityTracker.addMovement(event);
break;
default:
diff --git a/packages/SystemUI/src/com/android/systemui/SwipeHelper.java b/packages/SystemUI/src/com/android/systemui/SwipeHelper.java
index 0d393bf..f206e56 100644
--- a/packages/SystemUI/src/com/android/systemui/SwipeHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/SwipeHelper.java
@@ -311,11 +311,14 @@
final View animView = mCallback.getChildContentView(view);
final boolean canAnimViewBeDismissed = mCallback.canChildBeDismissed(view);
float newPos;
+ boolean isLayoutRtl = view.getLayoutDirection() == View.LAYOUT_DIRECTION_RTL;
if (velocity < 0
|| (velocity == 0 && getTranslation(animView) < 0)
// if we use the Menu to dismiss an item in landscape, animate up
- || (velocity == 0 && getTranslation(animView) == 0 && mSwipeDirection == Y)) {
+ || (velocity == 0 && getTranslation(animView) == 0 && mSwipeDirection == Y)
+ // if the language is rtl we prefer swiping to the left
+ || (velocity == 0 && getTranslation(animView) == 0 && isLayoutRtl)) {
newPos = -getSize(animView);
} else {
newPos = getSize(animView);
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
index 4af8499..172aaf6 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
@@ -364,7 +364,7 @@
// only force lock screen in case of missing sim if user hasn't
// gone through setup wizard
synchronized (this) {
- if (!mUpdateMonitor.isDeviceProvisioned()) {
+ if (shouldWaitForProvisioning()) {
if (!isShowing()) {
if (DEBUG) Log.d(TAG, "ICC_ABSENT isn't showing,"
+ " we need to show the keyguard since the "
@@ -493,8 +493,7 @@
mLockPatternUtils.setCurrentUser(ActivityManager.getCurrentUser());
// Assume keyguard is showing (unless it's disabled) until we know for sure...
- mShowing = (mUpdateMonitor.isDeviceProvisioned() || mLockPatternUtils.isSecure())
- && !mLockPatternUtils.isLockScreenDisabled();
+ mShowing = !shouldWaitForProvisioning() && !mLockPatternUtils.isLockScreenDisabled();
mStatusBarKeyguardViewManager = new StatusBarKeyguardViewManager(mContext,
mViewMediatorCallback, mLockPatternUtils);
@@ -783,7 +782,7 @@
public void verifyUnlock(IKeyguardExitCallback callback) {
synchronized (this) {
if (DEBUG) Log.d(TAG, "verifyUnlock");
- if (!mUpdateMonitor.isDeviceProvisioned()) {
+ if (shouldWaitForProvisioning()) {
// don't allow this api when the device isn't provisioned
if (DEBUG) Log.d(TAG, "ignoring because device isn't provisioned");
try {
@@ -873,7 +872,7 @@
* was suppressed by an app that disabled the keyguard or we haven't been provisioned yet.
*/
public boolean isInputRestricted() {
- return mShowing || mNeedToReshowWhenReenabled || !mUpdateMonitor.isDeviceProvisioned();
+ return mShowing || mNeedToReshowWhenReenabled || shouldWaitForProvisioning();
}
/**
@@ -905,14 +904,13 @@
// if the setup wizard hasn't run yet, don't show
final boolean requireSim = !SystemProperties.getBoolean("keyguard.no_require_sim",
false);
- final boolean provisioned = mUpdateMonitor.isDeviceProvisioned();
final IccCardConstants.State state = mUpdateMonitor.getSimState();
final boolean lockedOrMissing = state.isPinLocked()
|| ((state == IccCardConstants.State.ABSENT
|| state == IccCardConstants.State.PERM_DISABLED)
&& requireSim);
- if (!lockedOrMissing && !provisioned) {
+ if (!lockedOrMissing && shouldWaitForProvisioning()) {
if (DEBUG) Log.d(TAG, "doKeyguard: not showing because device isn't provisioned"
+ " and the sim is not locked or missing");
return;
@@ -935,6 +933,10 @@
showLocked(options);
}
+ private boolean shouldWaitForProvisioning() {
+ return !mUpdateMonitor.isDeviceProvisioned() && !isSecure();
+ }
+
/**
* Dismiss the keyguard through the security layers.
*/
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
index 54a8414..1ddd352 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
@@ -203,7 +203,7 @@
}
}
- private void refreshAllTiles() {
+ public void refreshAllTiles() {
for (TileRecord r : mRecords) {
r.tile.refreshState();
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSTile.java b/packages/SystemUI/src/com/android/systemui/qs/QSTile.java
index 6ef6e9e..2a66484 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSTile.java
@@ -18,11 +18,13 @@
import android.content.Context;
import android.content.Intent;
+import android.graphics.drawable.AnimatedVectorDrawable;
import android.graphics.drawable.Drawable;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.util.Log;
+import android.util.SparseArray;
import android.view.View;
import android.view.ViewGroup;
@@ -299,10 +301,91 @@
}
}
+ public static abstract class Icon {
+ abstract public Drawable getDrawable(Context context);
+
+ @Override
+ public int hashCode() {
+ return Icon.class.hashCode();
+ }
+ }
+
+ public static class ResourceIcon extends Icon {
+ private static final SparseArray<Icon> ICONS = new SparseArray<Icon>();
+
+ private final int mResId;
+
+ private ResourceIcon(int resId) {
+ mResId = resId;
+ }
+
+ public static Icon get(int resId) {
+ Icon icon = ICONS.get(resId);
+ if (icon == null) {
+ icon = new ResourceIcon(resId);
+ ICONS.put(resId, icon);
+ }
+ return icon;
+ }
+
+ @Override
+ public Drawable getDrawable(Context context) {
+ return context.getDrawable(mResId);
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ return o instanceof ResourceIcon && ((ResourceIcon) o).mResId == mResId;
+ }
+
+ @Override
+ public String toString() {
+ return String.format("ResourceIcon[resId=0x%08x]", mResId);
+ }
+ }
+
+ protected class AnimationIcon extends ResourceIcon {
+ private boolean mAllowAnimation;
+
+ public AnimationIcon(int resId) {
+ super(resId);
+ }
+
+ public void setAllowAnimation(boolean allowAnimation) {
+ mAllowAnimation = allowAnimation;
+ }
+
+ @Override
+ public Drawable getDrawable(Context context) {
+ // workaround: get a clean state for every new AVD
+ final AnimatedVectorDrawable d = (AnimatedVectorDrawable) super.getDrawable(context)
+ .getConstantState().newDrawable();
+ d.start();
+ if (mAllowAnimation) {
+ mAllowAnimation = false;
+ } else {
+ d.stop(); // skip directly to end state
+ }
+ return d;
+ }
+ }
+
+ protected enum UserBoolean {
+ USER_TRUE(true, true),
+ USER_FALSE(true, false),
+ BACKGROUND_TRUE(false, true),
+ BACKGROUND_FALSE(false, false);
+ public final boolean value;
+ public final boolean userInitiated;
+ private UserBoolean(boolean userInitiated, boolean value) {
+ this.value = value;
+ this.userInitiated = userInitiated;
+ }
+ }
+
public static class State {
public boolean visible;
- public int iconId;
- public Drawable icon;
+ public Icon icon;
public String label;
public String contentDescription;
public String dualLabelContentDescription;
@@ -312,7 +395,6 @@
if (other == null) throw new IllegalArgumentException();
if (!other.getClass().equals(getClass())) throw new IllegalArgumentException();
final boolean changed = other.visible != visible
- || other.iconId != iconId
|| !Objects.equals(other.icon, icon)
|| !Objects.equals(other.label, label)
|| !Objects.equals(other.contentDescription, contentDescription)
@@ -320,7 +402,6 @@
|| !Objects.equals(other.dualLabelContentDescription,
dualLabelContentDescription);
other.visible = visible;
- other.iconId = iconId;
other.icon = icon;
other.label = label;
other.contentDescription = contentDescription;
@@ -335,9 +416,8 @@
}
protected StringBuilder toStringBuilder() {
- final StringBuilder sb = new StringBuilder( getClass().getSimpleName()).append('[');
+ final StringBuilder sb = new StringBuilder(getClass().getSimpleName()).append('[');
sb.append("visible=").append(visible);
- sb.append(",iconId=").append(iconId);
sb.append(",icon=").append(icon);
sb.append(",label=").append(label);
sb.append(",contentDescription=").append(contentDescription);
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSTileView.java b/packages/SystemUI/src/com/android/systemui/qs/QSTileView.java
index d5c90d0..3d0f47c 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSTileView.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSTileView.java
@@ -21,6 +21,7 @@
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.Typeface;
+import android.graphics.drawable.Animatable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.RippleDrawable;
import android.os.Handler;
@@ -39,6 +40,8 @@
import com.android.systemui.R;
import com.android.systemui.qs.QSTile.State;
+import java.util.Objects;
+
/** View that represents a standard quick settings tile. **/
public class QSTileView extends ViewGroup {
private static final Typeface CONDENSED = Typeface.create("sans-serif-condensed",
@@ -60,6 +63,7 @@
private boolean mDual;
private OnClickListener mClickPrimary;
private OnClickListener mClickSecondary;
+ private Drawable mTileBackground;
private RippleDrawable mRipple;
public QSTileView(Context context) {
@@ -72,6 +76,7 @@
mTilePaddingBelowIconPx = res.getDimensionPixelSize(R.dimen.qs_tile_padding_below_icon);
mDualTileVerticalPaddingPx =
res.getDimensionPixelSize(R.dimen.qs_dual_tile_padding_vertical);
+ mTileBackground = newTileBackground();
recreateLabel();
setClipChildren(false);
@@ -172,22 +177,21 @@
if (changed) {
recreateLabel();
}
- Drawable tileBackground = getTileBackground();
- if (tileBackground instanceof RippleDrawable) {
- setRipple((RippleDrawable) tileBackground);
+ if (mTileBackground instanceof RippleDrawable) {
+ setRipple((RippleDrawable) mTileBackground);
}
if (dual) {
mTopBackgroundView.setOnClickListener(mClickPrimary);
setOnClickListener(null);
setClickable(false);
setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_NO);
- mTopBackgroundView.setBackground(tileBackground);
+ mTopBackgroundView.setBackground(mTileBackground);
} else {
mTopBackgroundView.setOnClickListener(null);
mTopBackgroundView.setClickable(false);
setOnClickListener(mClickPrimary);
setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_YES);
- setBackground(tileBackground);
+ setBackground(mTileBackground);
}
mTopBackgroundView.setFocusable(dual);
setFocusable(!dual);
@@ -214,7 +218,7 @@
return icon;
}
- private Drawable getTileBackground() {
+ private Drawable newTileBackground() {
final int[] attrs = new int[] { android.R.attr.selectableItemBackgroundBorderless };
final TypedArray ta = mContext.obtainStyledAttributes(attrs);
final Drawable d = ta.getDrawable(0);
@@ -285,16 +289,7 @@
protected void handleStateChanged(QSTile.State state) {
if (mIcon instanceof ImageView) {
- ImageView iv = (ImageView) mIcon;
- if (state.icon != null) {
- iv.setImageDrawable(state.icon);
- } else if (state.iconId > 0) {
- iv.setImageResource(state.iconId);
- }
- Drawable drawable = iv.getDrawable();
- if (state.autoMirrorDrawable && drawable != null) {
- drawable.setAutoMirrored(true);
- }
+ setIcon((ImageView) mIcon, state);
}
if (mDual) {
mDualLabel.setText(state.label);
@@ -306,6 +301,22 @@
}
}
+ protected void setIcon(ImageView iv, QSTile.State state) {
+ if (!Objects.equals(state.icon, iv.getTag(R.id.qs_icon_tag))) {
+ Drawable d = state.icon != null ? state.icon.getDrawable(mContext) : null;
+ if (d != null && state.autoMirrorDrawable) {
+ d.setAutoMirrored(true);
+ }
+ iv.setImageDrawable(d);
+ iv.setTag(R.id.qs_icon_tag, state.icon);
+ if (d instanceof Animatable) {
+ if (!iv.isShown()) {
+ ((Animatable) d).stop(); // skip directly to end state
+ }
+ }
+ }
+ }
+
public void onStateChanged(QSTile.State state) {
mHandler.obtainMessage(H.STATE_CHANGED, state).sendToTarget();
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/SignalTileView.java b/packages/SystemUI/src/com/android/systemui/qs/SignalTileView.java
index cfcd74e..9ac7944 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/SignalTileView.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/SignalTileView.java
@@ -104,7 +104,7 @@
protected void handleStateChanged(QSTile.State state) {
super.handleStateChanged(state);
final SignalState s = (SignalState) state;
- mSignal.setImageResource(s.iconId);
+ setIcon(mSignal, s);
if (s.overlayIconId > 0) {
mOverlay.setVisibility(VISIBLE);
mOverlay.setImageResource(s.overlayIconId);
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/AirplaneModeTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/AirplaneModeTile.java
index 51401c8..2dd02a5 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/AirplaneModeTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/AirplaneModeTile.java
@@ -29,6 +29,10 @@
/** Quick settings tile: Airplane mode **/
public class AirplaneModeTile extends QSTile<QSTile.BooleanState> {
+ private final AnimationIcon mEnable =
+ new AnimationIcon(R.drawable.ic_signal_airplane_enable_animation);
+ private final AnimationIcon mDisable =
+ new AnimationIcon(R.drawable.ic_signal_airplane_disable_animation);
private final GlobalSetting mSetting;
private boolean mListening;
@@ -52,6 +56,8 @@
@Override
public void handleClick() {
setEnabled(!mState.value);
+ mEnable.setAllowAnimation(true);
+ mDisable.setAllowAnimation(true);
}
private void setEnabled(boolean enabled) {
@@ -68,11 +74,11 @@
state.visible = true;
state.label = mContext.getString(R.string.quick_settings_airplane_mode_label);
if (airplaneMode) {
- state.iconId = R.drawable.ic_qs_airplane_on;
+ state.icon = mEnable;
state.contentDescription = mContext.getString(
R.string.accessibility_quick_settings_airplane_on);
} else {
- state.iconId = R.drawable.ic_qs_airplane_off;
+ state.icon = mDisable;
state.contentDescription = mContext.getString(
R.string.accessibility_quick_settings_airplane_off);
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java
index 84bfb8f..4d77348 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java
@@ -92,17 +92,17 @@
if (enabled) {
state.label = null;
if (connected) {
- state.iconId = R.drawable.ic_qs_bluetooth_connected;
+ state.icon = ResourceIcon.get(R.drawable.ic_qs_bluetooth_connected);
state.contentDescription = mContext.getString(
R.string.accessibility_quick_settings_bluetooth_connected);
state.label = mController.getLastDeviceName();
} else if (connecting) {
- state.iconId = R.drawable.ic_qs_bluetooth_connecting;
+ state.icon = ResourceIcon.get(R.drawable.ic_qs_bluetooth_connecting);
state.contentDescription = mContext.getString(
R.string.accessibility_quick_settings_bluetooth_connecting);
state.label = mContext.getString(R.string.quick_settings_bluetooth_label);
} else {
- state.iconId = R.drawable.ic_qs_bluetooth_on;
+ state.icon = ResourceIcon.get(R.drawable.ic_qs_bluetooth_on);
state.contentDescription = mContext.getString(
R.string.accessibility_quick_settings_bluetooth_on);
}
@@ -110,7 +110,7 @@
state.label = mContext.getString(R.string.quick_settings_bluetooth_label);
}
} else {
- state.iconId = R.drawable.ic_qs_bluetooth_off;
+ state.icon = ResourceIcon.get(R.drawable.ic_qs_bluetooth_off);
state.label = mContext.getString(R.string.quick_settings_bluetooth_label);
state.contentDescription = mContext.getString(
R.string.accessibility_quick_settings_bluetooth_off);
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java
index 8304291..5bf6fb5 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java
@@ -107,7 +107,8 @@
if (!state.value && connecting) {
state.label = mContext.getString(R.string.quick_settings_connecting);
}
- state.iconId = state.value ? R.drawable.ic_qs_cast_on : R.drawable.ic_qs_cast_off;
+ state.icon = ResourceIcon.get(state.value ? R.drawable.ic_qs_cast_on
+ : R.drawable.ic_qs_cast_off);
mDetailAdapter.updateItems(devices);
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java
index 359a259..178590b 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java
@@ -87,16 +87,17 @@
if (cb == null) return;
final Resources r = mContext.getResources();
- state.iconId = cb.noSim ? R.drawable.ic_qs_no_sim
+ final int iconId = cb.noSim ? R.drawable.ic_qs_no_sim
: !cb.enabled || cb.airplaneModeEnabled ? R.drawable.ic_qs_signal_disabled
: cb.mobileSignalIconId > 0 ? cb.mobileSignalIconId
: R.drawable.ic_qs_signal_no_signal;
+ state.icon = ResourceIcon.get(iconId);
state.isOverlayIconWide = cb.isDataTypeIconWide;
state.autoMirrorDrawable = !cb.noSim;
state.overlayIconId = cb.enabled && (cb.dataTypeIconId > 0) && !cb.wifiConnected
? cb.dataTypeIconId
: 0;
- state.filter = state.iconId != R.drawable.ic_qs_no_sim;
+ state.filter = iconId != R.drawable.ic_qs_no_sim;
state.activityIn = cb.enabled && cb.activityIn;
state.activityOut = cb.enabled && cb.activityOut;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/ColorInversionTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/ColorInversionTile.java
index 7ba1dc0..a19c29f 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/ColorInversionTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/ColorInversionTile.java
@@ -26,6 +26,10 @@
/** Quick settings tile: Invert colors **/
public class ColorInversionTile extends QSTile<QSTile.BooleanState> {
+ private final AnimationIcon mEnable
+ = new AnimationIcon(R.drawable.ic_invert_colors_enable_animation);
+ private final AnimationIcon mDisable
+ = new AnimationIcon(R.drawable.ic_invert_colors_disable_animation);
private final SecureSetting mSetting;
private final UsageTracker mUsageTracker;
@@ -79,6 +83,8 @@
@Override
protected void handleClick() {
mSetting.setValue(mState.value ? 0 : 1);
+ mEnable.setAllowAnimation(true);
+ mDisable.setAllowAnimation(true);
}
@Override
@@ -88,7 +94,7 @@
state.visible = enabled || mUsageTracker.isRecentlyUsed();
state.value = enabled;
state.label = mContext.getString(R.string.quick_settings_inversion_label);
- state.iconId = enabled ? R.drawable.ic_qs_inversion_on : R.drawable.ic_qs_inversion_off;
+ state.icon = enabled ? mEnable : mDisable;
}
@Override
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 e6b7f02..5c1a317 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/FlashlightTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/FlashlightTile.java
@@ -31,6 +31,10 @@
* still available because it was recently on. */
private static final long RECENTLY_ON_DURATION_MILLIS = 500;
+ private final AnimationIcon mEnable
+ = new AnimationIcon(R.drawable.ic_signal_flashlight_enable_animation);
+ private final AnimationIcon mDisable
+ = new AnimationIcon(R.drawable.ic_signal_flashlight_disable_animation);
private final FlashlightController mFlashlightController;
private long mWasLastOn;
@@ -66,7 +70,7 @@
}
boolean newState = !mState.value;
mFlashlightController.setFlashlight(newState);
- refreshState(newState);
+ refreshState(newState ? UserBoolean.USER_TRUE : UserBoolean.USER_FALSE);
}
@Override
@@ -75,8 +79,8 @@
mWasLastOn = SystemClock.uptimeMillis();
}
- if (arg instanceof Boolean) {
- state.value = (Boolean) arg;
+ if (arg instanceof UserBoolean) {
+ state.value = ((UserBoolean) arg).value;
}
if (!state.value && mWasLastOn != 0) {
@@ -92,8 +96,9 @@
// the camera is not available while it is being used for the flashlight.
state.visible = mWasLastOn != 0 || mFlashlightController.isAvailable();
state.label = mHost.getContext().getString(R.string.quick_settings_flashlight_label);
- state.iconId = state.value
- ? R.drawable.ic_qs_flashlight_on : R.drawable.ic_qs_flashlight_off;
+ final AnimationIcon icon = state.value ? mEnable : mDisable;
+ icon.setAllowAnimation(arg instanceof UserBoolean && ((UserBoolean) arg).userInitiated);
+ state.icon = icon;
int onOrOffId = state.value
? R.string.accessibility_quick_settings_flashlight_on
: R.string.accessibility_quick_settings_flashlight_off;
@@ -111,12 +116,12 @@
@Override
public void onFlashlightOff() {
- refreshState(false);
+ refreshState(UserBoolean.BACKGROUND_FALSE);
}
@Override
public void onFlashlightError() {
- refreshState(false);
+ refreshState(UserBoolean.BACKGROUND_FALSE);
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/HotspotTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/HotspotTile.java
index b30a1d3..64dab85 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/HotspotTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/HotspotTile.java
@@ -71,8 +71,8 @@
state.label = mContext.getString(R.string.quick_settings_hotspot_label);
state.value = mController.isHotspotEnabled();
- state.iconId = state.visible && state.value ? R.drawable.ic_qs_hotspot_on
- : R.drawable.ic_qs_hotspot_off;
+ state.icon = ResourceIcon.get(state.visible && state.value ? R.drawable.ic_qs_hotspot_on
+ : R.drawable.ic_qs_hotspot_off);
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/IntentTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/IntentTile.java
index 58587e6..6fb9cd8 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/IntentTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/IntentTile.java
@@ -31,6 +31,9 @@
import com.android.systemui.qs.QSTile;
+import java.util.Arrays;
+import java.util.Objects;
+
public class IntentTile extends QSTile<QSTile.State> {
public static final String PREFIX = "intent(";
@@ -96,13 +99,11 @@
state.visible = intent.getBooleanExtra("visible", true);
state.contentDescription = intent.getStringExtra("contentDescription");
state.label = intent.getStringExtra("label");
- state.iconId = 0;
state.icon = null;
final byte[] iconBitmap = intent.getByteArrayExtra("iconBitmap");
if (iconBitmap != null) {
try {
- final Bitmap b = BitmapFactory.decodeByteArray(iconBitmap, 0, iconBitmap.length);
- state.icon = new BitmapDrawable(mContext.getResources(), b);
+ state.icon = new BytesIcon(iconBitmap);
} catch (Throwable t) {
Log.w(TAG, "Error loading icon bitmap, length " + iconBitmap.length, t);
}
@@ -111,9 +112,9 @@
if (iconId != 0) {
final String iconPackage = intent.getStringExtra("iconPackage");
if (!TextUtils.isEmpty(iconPackage)) {
- state.icon = getPackageDrawable(iconPackage, iconId);
+ state.icon = new PackageDrawableIcon(iconPackage, iconId);
} else {
- state.iconId = iconId;
+ state.icon = ResourceIcon.get(iconId);
}
}
}
@@ -121,19 +122,66 @@
mOnClickUri = intent.getStringExtra("onClickUri");
}
- private Drawable getPackageDrawable(String pkg, int id) {
- try {
- return mContext.createPackageContext(pkg, 0).getDrawable(id);
- } catch (Throwable t) {
- Log.w(TAG, "Error loading package drawable pkg=" + pkg + " id=" + id, t);
- return null;
- }
- }
-
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
refreshState(intent);
}
};
+
+ private static class BytesIcon extends Icon {
+ private final byte[] mBytes;
+
+ public BytesIcon(byte[] bytes) {
+ mBytes = bytes;
+ }
+
+ @Override
+ public Drawable getDrawable(Context context) {
+ final Bitmap b = BitmapFactory.decodeByteArray(mBytes, 0, mBytes.length);
+ return new BitmapDrawable(context.getResources(), b);
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ return o instanceof BytesIcon && Arrays.equals(((BytesIcon) o).mBytes, mBytes);
+ }
+
+ @Override
+ public String toString() {
+ return String.format("BytesIcon[len=%s]", mBytes.length);
+ }
+ }
+
+ private class PackageDrawableIcon extends Icon {
+ private final String mPackage;
+ private final int mResId;
+
+ public PackageDrawableIcon(String pkg, int resId) {
+ mPackage = pkg;
+ mResId = resId;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (!(o instanceof PackageDrawableIcon)) return false;
+ final PackageDrawableIcon other = (PackageDrawableIcon) o;
+ return Objects.equals(other.mPackage, mPackage) && other.mResId == mResId;
+ }
+
+ @Override
+ public Drawable getDrawable(Context context) {
+ try {
+ return context.createPackageContext(mPackage, 0).getDrawable(mResId);
+ } catch (Throwable t) {
+ Log.w(TAG, "Error loading package drawable pkg=" + mPackage + " id=" + mResId, t);
+ return null;
+ }
+ }
+
+ @Override
+ public String toString() {
+ return String.format("PackageDrawableIcon[pkg=%s,id=0x%08x]", mPackage, mResId);
+ }
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/LocationTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/LocationTile.java
index d1dc5d2..11ec722 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/LocationTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/LocationTile.java
@@ -25,6 +25,11 @@
/** Quick settings tile: Location **/
public class LocationTile extends QSTile<QSTile.BooleanState> {
+ private final AnimationIcon mEnable =
+ new AnimationIcon(R.drawable.ic_signal_location_enable_animation);
+ private final AnimationIcon mDisable =
+ new AnimationIcon(R.drawable.ic_signal_location_disable_animation);
+
private final LocationController mController;
private final KeyguardMonitor mKeyguard;
private final Callback mCallback = new Callback();
@@ -55,6 +60,8 @@
protected void handleClick() {
final boolean wasEnabled = (Boolean) mState.value;
mController.setLocationEnabled(!wasEnabled);
+ mEnable.setAllowAnimation(true);
+ mDisable.setAllowAnimation(true);
}
@Override
@@ -67,12 +74,12 @@
state.visible = !mKeyguard.isShowing();
state.value = locationEnabled;
if (locationEnabled) {
- state.iconId = R.drawable.ic_qs_location_on;
+ state.icon = mEnable;
state.label = mContext.getString(R.string.quick_settings_location_label);
state.contentDescription = mContext.getString(
R.string.accessibility_quick_settings_location_on);
} else {
- state.iconId = R.drawable.ic_qs_location_off;
+ state.icon = mDisable;
state.label = mContext.getString(R.string.quick_settings_location_label);
state.contentDescription = mContext.getString(
R.string.accessibility_quick_settings_location_off);
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/RotationLockTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/RotationLockTile.java
index ae40a4d..f46b9a6 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/RotationLockTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/RotationLockTile.java
@@ -17,7 +17,6 @@
package com.android.systemui.qs.tiles;
import android.content.res.Configuration;
-import android.content.res.Resources;
import com.android.systemui.R;
import com.android.systemui.qs.QSTile;
@@ -26,6 +25,15 @@
/** Quick settings tile: Rotation **/
public class RotationLockTile extends QSTile<QSTile.BooleanState> {
+ private final AnimationIcon mPortraitToAuto
+ = new AnimationIcon(R.drawable.ic_portrait_to_auto_rotate_animation);
+ private final AnimationIcon mAutoToPortrait
+ = new AnimationIcon(R.drawable.ic_portrait_from_auto_rotate_animation);
+
+ private final AnimationIcon mLandscapeToAuto
+ = new AnimationIcon(R.drawable.ic_landscape_to_auto_rotate_animation);
+ private final AnimationIcon mAutoToLandscape
+ = new AnimationIcon(R.drawable.ic_landscape_from_auto_rotate_animation);
private final RotationLockController mController;
@@ -51,30 +59,34 @@
@Override
protected void handleClick() {
if (mController == null) return;
- mController.setRotationLocked(!mState.value);
+ final boolean newState = !mState.value;
+ mController.setRotationLocked(newState);
+ refreshState(newState ? UserBoolean.USER_TRUE : UserBoolean.USER_FALSE);
}
@Override
protected void handleUpdateState(BooleanState state, Object arg) {
if (mController == null) return;
- final boolean rotationLocked = mController.isRotationLocked();
+ final boolean rotationLocked = arg != null ? ((UserBoolean) arg).value
+ : mController.isRotationLocked();
+ final boolean userInitiated = arg != null ? ((UserBoolean) arg).userInitiated : false;
state.visible = mController.isRotationLockAffordanceVisible();
- final Resources res = mContext.getResources();
state.value = rotationLocked;
+ final boolean portrait = mContext.getResources().getConfiguration().orientation
+ != Configuration.ORIENTATION_LANDSCAPE;
+ final AnimationIcon icon;
if (rotationLocked) {
- final boolean portrait = res.getConfiguration().orientation
- != Configuration.ORIENTATION_LANDSCAPE;
final int label = portrait ? R.string.quick_settings_rotation_locked_portrait_label
: R.string.quick_settings_rotation_locked_landscape_label;
- final int icon = portrait ? R.drawable.ic_qs_rotation_portrait
- : R.drawable.ic_qs_rotation_landscape;
state.label = mContext.getString(label);
- state.icon = mContext.getDrawable(icon);
+ icon = portrait ? mAutoToPortrait : mAutoToLandscape;
} else {
state.label = mContext.getString(R.string.quick_settings_rotation_unlocked_label);
- state.icon = res.getDrawable(R.drawable.ic_qs_rotation_unlocked);
+ icon = portrait ? mPortraitToAuto : mLandscapeToAuto;
}
- state.contentDescription = getAccessibilityString(
+ icon.setAllowAnimation(userInitiated);
+ state.icon = icon;
+ state.contentDescription = getAccessibilityString(rotationLocked,
R.string.accessibility_rotation_lock_on_portrait,
R.string.accessibility_rotation_lock_on_landscape,
R.string.accessibility_rotation_lock_off);
@@ -83,14 +95,16 @@
/**
* Get the correct accessibility string based on the state
*
+ * @param locked Whether or not rotation is locked.
* @param idWhenPortrait The id which should be used when locked in portrait.
* @param idWhenLandscape The id which should be used when locked in landscape.
* @param idWhenOff The id which should be used when the rotation lock is off.
* @return
*/
- private String getAccessibilityString(int idWhenPortrait, int idWhenLandscape, int idWhenOff) {
+ private String getAccessibilityString(boolean locked, int idWhenPortrait, int idWhenLandscape,
+ int idWhenOff) {
int stringID;
- if (mState.value) {
+ if (locked) {
final boolean portrait = mContext.getResources().getConfiguration().orientation
!= Configuration.ORIENTATION_LANDSCAPE;
stringID = portrait ? idWhenPortrait: idWhenLandscape;
@@ -102,7 +116,7 @@
@Override
protected String composeChangeAnnouncement() {
- return getAccessibilityString(
+ return getAccessibilityString(mState.value,
R.string.accessibility_rotation_lock_on_portrait_changed,
R.string.accessibility_rotation_lock_on_landscape_changed,
R.string.accessibility_rotation_lock_off_changed);
@@ -111,7 +125,8 @@
private final RotationLockControllerCallback mCallback = new RotationLockControllerCallback() {
@Override
public void onRotationLockStateChanged(boolean rotationLocked, boolean affordanceVisible) {
- refreshState();
+ refreshState(rotationLocked ? UserBoolean.BACKGROUND_TRUE
+ : UserBoolean.BACKGROUND_FALSE);
}
};
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java
index 20c4ee8..7aa884e 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java
@@ -120,19 +120,19 @@
final String signalContentDescription;
final Resources r = mContext.getResources();
if (!state.enabled) {
- state.iconId = R.drawable.ic_qs_wifi_disabled;
+ state.icon = ResourceIcon.get(R.drawable.ic_qs_wifi_disabled);
state.label = r.getString(R.string.quick_settings_wifi_label);
signalContentDescription = r.getString(R.string.accessibility_wifi_off);
} else if (wifiConnected) {
- state.iconId = cb.wifiSignalIconId;
+ state.icon = ResourceIcon.get(cb.wifiSignalIconId);
state.label = removeDoubleQuotes(cb.enabledDesc);
signalContentDescription = cb.wifiSignalContentDescription;
} else if (wifiNotConnected) {
- state.iconId = R.drawable.ic_qs_wifi_0;
+ state.icon = ResourceIcon.get(R.drawable.ic_qs_wifi_0);
state.label = r.getString(R.string.quick_settings_wifi_label);
signalContentDescription = r.getString(R.string.accessibility_no_wifi);
} else {
- state.iconId = R.drawable.ic_qs_wifi_no_network;
+ state.icon = ResourceIcon.get(R.drawable.ic_qs_wifi_no_network);
state.label = r.getString(R.string.quick_settings_wifi_label);
signalContentDescription = r.getString(R.string.accessibility_wifi_off);
}
diff --git a/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java b/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java
index 2a782cc..4c3460e 100644
--- a/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java
@@ -728,7 +728,7 @@
final ActivityManager am = (ActivityManager)
getContext().getSystemService(Context.ACTIVITY_SERVICE);
if (am != null) {
- am.removeTask(ad.persistentTaskId, ActivityManager.REMOVE_TASK_KILL_PROCESS);
+ am.removeTask(ad.persistentTaskId);
// Accessibility feedback
setContentDescription(
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 71a3ef1..b661385 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java
@@ -291,18 +291,18 @@
}
}
- /** Removes the task and kills the process */
- public void removeTask(int taskId, boolean isDocument) {
+ /** Removes the task */
+ public void removeTask(int taskId) {
if (mAm == null) return;
if (Constants.DebugFlags.App.EnableSystemServicesProxy) return;
- // Remove the task, and only kill the process if it is not a document
- mAm.removeTask(taskId, isDocument ? 0 : ActivityManager.REMOVE_TASK_KILL_PROCESS);
+ // Remove the task.
+ mAm.removeTask(taskId);
}
/**
* Returns the activity info for a given component name.
- *
+ *
* @param cn The component name of the activity.
* @param userId The userId of the user that this is for.
*/
diff --git a/packages/SystemUI/src/com/android/systemui/recents/misc/Utilities.java b/packages/SystemUI/src/com/android/systemui/recents/misc/Utilities.java
index a0dee07..e1179fa 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/misc/Utilities.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/misc/Utilities.java
@@ -17,7 +17,6 @@
package com.android.systemui.recents.misc;
import android.animation.Animator;
-import android.content.Intent;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Rect;
@@ -184,12 +183,6 @@
sPropertyMethod.invoke(null, property, value);
}
- /** Returns whether the specified intent is a document. */
- public static boolean isDocument(Intent intent) {
- int flags = intent.getFlags();
- return (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) == Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
- }
-
/**
* Cancels an animation ensuring that if it has listeners, onCancel and onEnd
* are not called.
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java
index 6b0d306..ff0330d 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java
@@ -34,7 +34,6 @@
import com.android.systemui.recents.Constants;
import com.android.systemui.recents.RecentsConfiguration;
import com.android.systemui.recents.misc.SystemServicesProxy;
-import com.android.systemui.recents.misc.Utilities;
import com.android.systemui.recents.model.RecentsPackageMonitor;
import com.android.systemui.recents.model.RecentsTaskLoader;
import com.android.systemui.recents.model.Task;
@@ -522,8 +521,7 @@
loader.deleteTaskData(t, false);
// Remove the old task from activity manager
- RecentsTaskLoader.getInstance().getSystemServicesProxy().removeTask(t.key.id,
- Utilities.isDocument(t.key.baseIntent));
+ RecentsTaskLoader.getInstance().getSystemServicesProxy().removeTask(t.key.id);
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ActivatableNotificationView.java b/packages/SystemUI/src/com/android/systemui/statusbar/ActivatableNotificationView.java
index e4faa6a..02b9378 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/ActivatableNotificationView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/ActivatableNotificationView.java
@@ -508,7 +508,7 @@
if (mAppearAnimator != null) {
mAppearAnimator.cancel();
}
- mAnimationTranslationY = translationDirection * mActualHeight;
+ mAnimationTranslationY = translationDirection * getActualHeight();
if (mAppearAnimationFraction == -1.0f) {
// not initialized yet, we start anew
if (isAppearing) {
@@ -601,14 +601,15 @@
float top;
float bottom;
+ final int actualHeight = getActualHeight();
if (mAnimationTranslationY > 0.0f) {
- bottom = mActualHeight - heightFraction * mAnimationTranslationY * 0.1f
+ bottom = actualHeight - heightFraction * mAnimationTranslationY * 0.1f
- translateYTotalAmount;
top = bottom * heightFraction;
} else {
- top = heightFraction * (mActualHeight + mAnimationTranslationY) * 0.1f -
+ top = heightFraction * (actualHeight + mAnimationTranslationY) * 0.1f -
translateYTotalAmount;
- bottom = mActualHeight * (1 - heightFraction) + top * heightFraction;
+ bottom = actualHeight * (1 - heightFraction) + top * heightFraction;
}
mAppearAnimationRect.set(left, top, right, bottom);
setOutlineRect(left, top + mAppearAnimationTranslation, right,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
index 09d0b5d..7bbf9e2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
@@ -159,9 +159,6 @@
protected HeadsUpNotificationView mHeadsUpNotificationView;
protected int mHeadsUpNotificationDecay;
- // used to notify status bar for suppressing notification LED
- protected boolean mPanelSlightlyVisible;
-
// Search panel
protected SearchPanelView mSearchPanelView;
@@ -173,6 +170,20 @@
// on-screen navigation buttons
protected NavigationBarView mNavigationBarView = null;
+
+ protected Boolean mScreenOn;
+
+ // The second field is a bit different from the first one because it only listens to screen on/
+ // screen of events from Keyguard. We need this so we don't have a race condition with the
+ // broadcast. In the future, we should remove the first field altogether and rename the second
+ // field.
+ protected boolean mScreenOnFromKeyguard;
+
+ protected boolean mVisible;
+
+ // mScreenOnFromKeyguard && mVisible.
+ private boolean mVisibleToUser;
+
private Locale mLocale;
private float mFontScale;
@@ -1599,28 +1610,41 @@
}
}
+ protected void visibilityChanged(boolean visible) {
+ if (mVisible != visible) {
+ mVisible = visible;
+ if (!visible) {
+ dismissPopups();
+ }
+ }
+ updateVisibleToUser();
+ }
+
+ protected void updateVisibleToUser() {
+ boolean oldVisibleToUser = mVisibleToUser;
+ mVisibleToUser = mVisible && mScreenOnFromKeyguard;
+
+ if (oldVisibleToUser != mVisibleToUser) {
+ handleVisibleToUserChanged(mVisibleToUser);
+ }
+ }
+
/**
- * The LEDs are turned o)ff when the notification panel is shown, even just a little bit.
+ * The LEDs are turned off when the notification panel is shown, even just a little bit.
* This was added last-minute and is inconsistent with the way the rest of the notifications
* are handled, because the notification isn't really cancelled. The lights are just
* turned off. If any other notifications happen, the lights will turn back on. Steve says
* this is what he wants. (see bug 1131461)
*/
- protected void visibilityChanged(boolean visible) {
- if (mPanelSlightlyVisible != visible) {
- mPanelSlightlyVisible = visible;
- if (!visible) {
- dismissPopups();
+ protected void handleVisibleToUserChanged(boolean visibleToUser) {
+ try {
+ if (visibleToUser) {
+ mBarService.onPanelRevealed();
+ } else {
+ mBarService.onPanelHidden();
}
- try {
- if (visible) {
- mBarService.onPanelRevealed();
- } else {
- mBarService.onPanelHidden();
- }
- } catch (RemoteException ex) {
- // Won't fail unless the world has ended.
- }
+ } catch (RemoteException ex) {
+ // Won't fail unless the world has ended.
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/DismissView.java b/packages/SystemUI/src/com/android/systemui/statusbar/DismissView.java
index 897dbf2..479c2fb 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/DismissView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/DismissView.java
@@ -36,4 +36,11 @@
public void setOnButtonClickListener(OnClickListener listener) {
mContent.setOnClickListener(listener);
}
+
+ public boolean isOnEmptySpace(float touchX, float touchY) {
+ return touchX < mContent.getX()
+ || touchX > mContent.getX() + mContent.getWidth()
+ || touchY < mContent.getY()
+ || touchY > mContent.getY() + mContent.getHeight();
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/DismissViewImageButton.java b/packages/SystemUI/src/com/android/systemui/statusbar/DismissViewImageButton.java
index d55b0b3..35fd688 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/DismissViewImageButton.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/DismissViewImageButton.java
@@ -61,4 +61,9 @@
outRect.top += translationY;
outRect.bottom += translationY;
}
+
+ @Override
+ public boolean hasOverlappingRendering() {
+ return false;
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
index 556c423..a4e5e74 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
@@ -23,10 +23,8 @@
import android.service.notification.StatusBarNotification;
import android.util.AttributeSet;
import android.view.View;
-import android.view.ViewGroup;
import android.view.ViewStub;
import android.view.accessibility.AccessibilityEvent;
-
import android.widget.ImageView;
import com.android.systemui.R;
@@ -156,9 +154,9 @@
}
public void resetHeight() {
+ super.resetHeight();
mMaxExpandHeight = 0;
mWasReset = true;
- mActualHeight = 0;
onHeightReset();
requestLayout();
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableOutlineView.java b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableOutlineView.java
index f85d32b..a18fff2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableOutlineView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableOutlineView.java
@@ -41,7 +41,7 @@
outline.setRect(0,
mClipTopAmount,
getWidth(),
- Math.max(mActualHeight, mClipTopAmount));
+ Math.max(getActualHeight(), mClipTopAmount));
} else {
outline.setRect(mOutlineRect);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableView.java b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableView.java
index c8f756e..edfbe86 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableView.java
@@ -36,7 +36,7 @@
private final int mMaxNotificationHeight;
private OnHeightChangedListener mOnHeightChangedListener;
- protected int mActualHeight;
+ private int mActualHeight;
protected int mClipTopAmount;
private boolean mActualHeightInitialized;
private ArrayList<View> mMatchParentViews = new ArrayList<View>();
@@ -103,6 +103,11 @@
}
}
+ protected void resetHeight() {
+ mActualHeight = 0;
+ mActualHeightInitialized = false;
+ }
+
protected int getInitialHeight() {
return getHeight();
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
index ce35e4b..992aa9f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
@@ -162,8 +162,9 @@
KeyguardUpdateMonitorCallback mUpdateMonitor = new KeyguardUpdateMonitorCallback() {
@Override
public void onRefreshBatteryInfo(KeyguardUpdateMonitor.BatteryStatus status) {
- mPowerPluggedIn = status.status == BatteryManager.BATTERY_STATUS_CHARGING
+ boolean isChargingOrFull = status.status == BatteryManager.BATTERY_STATUS_CHARGING
|| status.status == BatteryManager.BATTERY_STATUS_FULL;
+ mPowerPluggedIn = status.isPluggedIn() && isChargingOrFull;
mPowerCharged = status.isCharged();
updateIndication();
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationBackgroundView.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationBackgroundView.java
index 5db680a..0fc46e9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationBackgroundView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationBackgroundView.java
@@ -23,9 +23,7 @@
import android.graphics.drawable.Drawable;
import android.graphics.drawable.RippleDrawable;
import android.util.AttributeSet;
-import android.view.MotionEvent;
import android.view.View;
-import com.android.systemui.R;
/**
* A view that can be used for both the dimmed and normal background of an notification.
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java
index 502490f..9b11f9b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java
@@ -27,11 +27,11 @@
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.view.View;
+import android.view.ViewTreeObserver;
import android.view.animation.Interpolator;
import android.view.animation.LinearInterpolator;
import android.widget.FrameLayout;
import android.widget.ImageView;
-
import com.android.systemui.R;
/**
@@ -60,6 +60,16 @@
private boolean mDark;
private final Paint mFadePaint = new Paint();
+ private boolean mAnimate;
+ private ViewTreeObserver.OnPreDrawListener mEnableAnimationPredrawListener
+ = new ViewTreeObserver.OnPreDrawListener() {
+ @Override
+ public boolean onPreDraw() {
+ mAnimate = true;
+ getViewTreeObserver().removeOnPreDrawListener(this);
+ return true;
+ }
+ };
public NotificationContentView(Context context, AttributeSet attrs) {
super(context, attrs);
@@ -73,6 +83,12 @@
updateClipping();
}
+ @Override
+ protected void onFinishInflate() {
+ super.onFinishInflate();
+ updateVisibility();
+ }
+
public void reset() {
if (mContractedChild != null) {
mContractedChild.animate().cancel();
@@ -117,9 +133,31 @@
selectLayout(false /* animate */, true /* force */);
}
+ @Override
+ protected void onVisibilityChanged(View changedView, int visibility) {
+ super.onVisibilityChanged(changedView, visibility);
+ updateVisibility();
+ }
+
+ private void updateVisibility() {
+ setVisible(isShown());
+ }
+
+ private void setVisible(final boolean isVisible) {
+ if (isVisible) {
+
+ // We only animate if we are drawn at least once, otherwise the view might animate when
+ // it's shown the first time
+ getViewTreeObserver().addOnPreDrawListener(mEnableAnimationPredrawListener);
+ } else {
+ getViewTreeObserver().removeOnPreDrawListener(mEnableAnimationPredrawListener);
+ mAnimate = false;
+ }
+ }
+
public void setActualHeight(int actualHeight) {
mActualHeight = actualHeight;
- selectLayout(true /* animate */, false /* force */);
+ selectLayout(mAnimate /* animate */, false /* force */);
updateClipping();
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/BarTransitions.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/BarTransitions.java
index 32fb567..e89e15d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/BarTransitions.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/BarTransitions.java
@@ -45,6 +45,7 @@
public static final int MODE_LIGHTS_OUT = 3;
public static final int MODE_TRANSPARENT = 4;
public static final int MODE_WARNING = 5;
+ public static final int MODE_LIGHTS_OUT_TRANSPARENT = 6;
public static final int LIGHTS_IN_DURATION = 250;
public static final int LIGHTS_OUT_DURATION = 750;
@@ -75,6 +76,9 @@
|| mode == MODE_TRANSPARENT)) {
mode = MODE_OPAQUE;
}
+ if (!HIGH_END && (mode == MODE_LIGHTS_OUT_TRANSPARENT)) {
+ mode = MODE_LIGHTS_OUT;
+ }
if (mMode == mode) return;
int oldMode = mMode;
mMode = mode;
@@ -102,6 +106,7 @@
if (mode == MODE_LIGHTS_OUT) return "MODE_LIGHTS_OUT";
if (mode == MODE_TRANSPARENT) return "MODE_TRANSPARENT";
if (mode == MODE_WARNING) return "MODE_WARNING";
+ if (mode == MODE_LIGHTS_OUT_TRANSPARENT) return "MODE_LIGHTS_OUT_TRANSPARENT";
throw new IllegalArgumentException("Unknown mode " + mode);
}
@@ -109,6 +114,10 @@
mBarBackground.finishAnimation();
}
+ protected boolean isLightsOut(int mode) {
+ return mode == MODE_LIGHTS_OUT || mode == MODE_LIGHTS_OUT_TRANSPARENT;
+ }
+
private static class BarBackgroundDrawable extends Drawable {
private final int mOpaque;
private final int mSemiTransparent;
@@ -196,7 +205,7 @@
targetColor = mSemiTransparent;
} else if (mMode == MODE_SEMI_TRANSPARENT) {
targetColor = mSemiTransparent;
- } else if (mMode == MODE_TRANSPARENT) {
+ } else if (mMode == MODE_TRANSPARENT || mMode == MODE_LIGHTS_OUT_TRANSPARENT) {
targetColor = mTransparent;
} else {
targetColor = mOpaque;
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 682c01c..6cb5bcc 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DemoStatusIcons.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DemoStatusIcons.java
@@ -159,7 +159,7 @@
}
}
StatusBarIcon icon = new StatusBarIcon(iconPkg, UserHandle.CURRENT, iconId, 0, 0, "Demo");
- StatusBarIconView v = new StatusBarIconView(getContext(), null);
+ StatusBarIconView v = new StatusBarIconView(getContext(), null, null);
v.setTag(slot);
v.set(icon);
addView(v, 0, new LinearLayout.LayoutParams(mIconSize, mIconSize));
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeParameters.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeParameters.java
index a956151..6fd6758 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeParameters.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeParameters.java
@@ -48,6 +48,7 @@
pw.print(" getDisplayStateSupported(): "); pw.println(getDisplayStateSupported());
pw.print(" getPulseDuration(): "); pw.println(getPulseDuration());
pw.print(" getPulseInDuration(): "); pw.println(getPulseInDuration());
+ pw.print(" getPulseInDelay(): "); pw.println(getPulseInDelay());
pw.print(" getPulseInVisibleDuration(): "); pw.println(getPulseVisibleDuration());
pw.print(" getPulseOutDuration(): "); pw.println(getPulseOutDuration());
pw.print(" getPulseOnSigMotion(): "); pw.println(getPulseOnSigMotion());
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarTransitions.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarTransitions.java
index f3930ba..15f6dc2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarTransitions.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarTransitions.java
@@ -84,7 +84,7 @@
applyBackButtonQuiescentAlpha(mode, animate);
// apply to lights out
- applyLightsOut(mode == MODE_LIGHTS_OUT, animate, force);
+ applyLightsOut(isLightsOut(mode), animate, force);
}
private float alphaForMode(int mode) {
@@ -171,7 +171,8 @@
applyLightsOut(false, false, false);
try {
- mBarService.setSystemUiVisibility(0, View.SYSTEM_UI_FLAG_LOW_PROFILE);
+ mBarService.setSystemUiVisibility(0, View.SYSTEM_UI_FLAG_LOW_PROFILE,
+ "LightsOutListener");
} catch (android.os.RemoteException ex) {
}
}
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 0bde7ef..bb992b0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
@@ -52,7 +52,7 @@
public class NotificationPanelView extends PanelView implements
ExpandableView.OnHeightChangedListener, ObservableScrollView.Listener,
View.OnClickListener, NotificationStackScrollLayout.OnOverscrollTopChangedListener,
- KeyguardAffordanceHelper.Callback {
+ KeyguardAffordanceHelper.Callback, NotificationStackScrollLayout.OnEmptySpaceClickListener {
// Cap and total height of Roboto font. Needs to be adjusted when font for the big clock is
// changed.
@@ -197,6 +197,7 @@
findViewById(R.id.notification_stack_scroller);
mNotificationStackScroller.setOnHeightChangedListener(this);
mNotificationStackScroller.setOverscrollTopChangedListener(this);
+ mNotificationStackScroller.setOnEmptySpaceClickListener(this);
mNotificationStackScroller.setScrollView(mScrollView);
mFastOutSlowInInterpolator = AnimationUtils.loadInterpolator(getContext(),
android.R.interpolator.fast_out_slow_in);
@@ -290,8 +291,8 @@
} else {
setQsExpansion(mQsMinExpansionHeight + mLastOverscroll);
mNotificationStackScroller.setStackHeight(getExpandedHeight());
- updateHeader();
}
+ updateHeader();
mNotificationStackScroller.updateIsSmallScreen(
mHeader.getCollapsedHeight() + mQsPeekHeight);
}
@@ -526,13 +527,15 @@
mIntercepting = false;
break;
}
+ return super.onInterceptTouchEvent(event);
+ }
- // Allow closing the whole panel when in SHADE state.
- if (mStatusBarState == StatusBarState.SHADE) {
- return super.onInterceptTouchEvent(event);
- } else {
- return !mQsExpanded && super.onInterceptTouchEvent(event);
- }
+ @Override
+ protected boolean isInContentBounds(float x, float y) {
+ float yTransformed = y - mNotificationStackScroller.getY();
+ float stackScrollerX = mNotificationStackScroller.getX();
+ return mNotificationStackScroller.isInContentBounds(yTransformed) && stackScrollerX < x
+ && x < stackScrollerX + mNotificationStackScroller.getWidth();
}
private void resetDownStates(MotionEvent event) {
@@ -636,10 +639,9 @@
}
private boolean isInQsArea(float x, float y) {
- return mStatusBarState != StatusBarState.SHADE ||
- (x >= mScrollView.getLeft() && x <= mScrollView.getRight()) &&
- (y <= mNotificationStackScroller.getBottomMostNotificationBottom()
- || y <= mQsContainer.getY() + mQsContainer.getHeight());
+ return (x >= mScrollView.getLeft() && x <= mScrollView.getRight()) &&
+ (y <= mNotificationStackScroller.getBottomMostNotificationBottom()
+ || y <= mQsContainer.getY() + mQsContainer.getHeight());
}
private void handleQsDown(MotionEvent event) {
@@ -1110,9 +1112,26 @@
}
private float calculateQsTopPadding() {
- // We can only do the smoother transition on Keyguard when we also are not collapsing from a
- // scrolled quick settings.
- if (mKeyguardShowing && mScrollYOverride == -1) {
+ if (mKeyguardShowing
+ && (mTwoFingerQsExpand || mIsExpanding && mQsExpandedWhenExpandingStarted)) {
+
+ // Either QS pushes the notifications down when fully expanded, or QS is fully above the
+ // notifications (mostly on tablets). maxNotifications denotes the normal top padding
+ // on Keyguard, maxQs denotes the top padding from the quick settings panel. We need to
+ // take the maximum and linearly interpolate with the panel expansion for a nice motion.
+ int maxNotifications = mClockPositionResult.stackScrollerPadding
+ - mClockPositionResult.stackScrollerPaddingAdjustment
+ - mNotificationTopPadding;
+ int maxQs = getTempQsMaxExpansion();
+ int max = mStatusBarState == StatusBarState.KEYGUARD
+ ? Math.max(maxNotifications, maxQs)
+ : maxQs;
+ return (int) interpolate(getExpandedFraction(),
+ mQsMinExpansionHeight, max);
+ } else if (mKeyguardShowing && mScrollYOverride == -1) {
+
+ // We can only do the smoother transition on Keyguard when we also are not collapsing
+ // from a scrolled quick settings.
return interpolate(getQsExpansionFraction(),
mNotificationStackScroller.getIntrinsicPadding() - mNotificationTopPadding,
mQsMaxExpansionHeight);
@@ -1124,7 +1143,9 @@
private void requestScrollerTopPaddingUpdate(boolean animate) {
mNotificationStackScroller.updateTopPadding(calculateQsTopPadding(),
mScrollView.getScrollY(),
- mAnimateNextTopPaddingChange || animate);
+ mAnimateNextTopPaddingChange || animate,
+ mKeyguardShowing
+ && (mTwoFingerQsExpand || mIsExpanding && mQsExpandedWhenExpandingStarted));
mAnimateNextTopPaddingChange = false;
}
@@ -1254,18 +1275,27 @@
@Override
protected void onHeightUpdated(float expandedHeight) {
- if (!mQsExpanded) {
+ if (!mQsExpanded || mTwoFingerQsExpand || mIsExpanding && mQsExpandedWhenExpandingStarted) {
positionClockAndNotifications();
}
if (mTwoFingerQsExpand || mQsExpanded && !mQsTracking && mQsExpansionAnimator == null
&& !mQsExpansionFromOverscroll) {
- float panelHeightQsCollapsed = mNotificationStackScroller.getIntrinsicPadding()
- + mNotificationStackScroller.getMinStackHeight()
- + mNotificationStackScroller.getNotificationTopPadding();
- float panelHeightQsExpanded = calculatePanelHeightQsExpanded();
- float t = (expandedHeight - panelHeightQsCollapsed)
- / (panelHeightQsExpanded - panelHeightQsCollapsed);
+ float t;
+ if (mKeyguardShowing) {
+ // On Keyguard, interpolate the QS expansion linearly to the panel expansion
+ t = expandedHeight / getMaxPanelHeight();
+ } else {
+
+ // In Shade, interpolate linearly such that QS is closed whenever panel height is
+ // minimum QS expansion + minStackHeight
+ float panelHeightQsCollapsed = mNotificationStackScroller.getIntrinsicPadding()
+ + mNotificationStackScroller.getMinStackHeight()
+ + mNotificationStackScroller.getNotificationTopPadding();
+ float panelHeightQsExpanded = calculatePanelHeightQsExpanded();
+ t = (expandedHeight - panelHeightQsCollapsed)
+ / (panelHeightQsExpanded - panelHeightQsCollapsed);
+ }
setQsExpansion(mQsMinExpansionHeight
+ t * (getTempQsMaxExpansion() - mQsMinExpansionHeight));
}
@@ -1299,8 +1329,20 @@
float notificationHeight = mNotificationStackScroller.getHeight()
- mNotificationStackScroller.getEmptyBottomMargin()
- mNotificationStackScroller.getTopPadding();
- float totalHeight = mQsMaxExpansionHeight + notificationHeight
- + mNotificationStackScroller.getNotificationTopPadding();
+
+ // When only empty shade view is visible in QS collapsed state, simulate that we would have
+ // it in expanded QS state as well so we don't run into troubles when fading the view in/out
+ // and expanding/collapsing the whole panel from/to quick settings.
+ if (mNotificationStackScroller.getNotGoneChildCount() == 0
+ && mShadeEmpty) {
+ notificationHeight = mNotificationStackScroller.getEmptyShadeViewHeight()
+ + mNotificationStackScroller.getBottomStackPeekSize()
+ + mNotificationStackScroller.getCollapseSecondCardPadding();
+ }
+ float totalHeight = Math.max(
+ mQsMaxExpansionHeight + mNotificationStackScroller.getNotificationTopPadding(),
+ mClockPositionResult.stackScrollerPadding - mTopPaddingAdjustment)
+ + notificationHeight;
if (totalHeight > mNotificationStackScroller.getHeight()) {
float fullyCollapsedHeight = mQsMaxExpansionHeight
+ mNotificationStackScroller.getMinStackHeight()
@@ -1433,7 +1475,7 @@
super.onExpandingStarted();
mNotificationStackScroller.onExpansionStarted();
mIsExpanding = true;
- mQsExpandedWhenExpandingStarted = mQsExpanded;
+ mQsExpandedWhenExpandingStarted = mQsFullyExpanded;
if (mQsExpanded) {
onQsExpansionStarted();
}
@@ -1487,11 +1529,12 @@
@Override
protected void onTrackingStarted() {
super.onTrackingStarted();
+ if (mQsFullyExpanded) {
+ mTwoFingerQsExpand = true;
+ }
if (mStatusBar.getBarState() == StatusBarState.KEYGUARD
|| mStatusBar.getBarState() == StatusBarState.SHADE_LOCKED) {
mAfforanceHelper.animateHideLeftRightIcon();
- } else if (mQsExpanded) {
- mTwoFingerQsExpand = true;
}
}
@@ -1867,4 +1910,9 @@
public void onScreenTurnedOn() {
mKeyguardStatusView.refreshTime();
}
+
+ @Override
+ public void onEmptySpaceClicked(float x, float y) {
+ onEmptySpaceClick(x);
+ }
}
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 0ddda8a..c706ef0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
@@ -70,6 +70,7 @@
private boolean mOverExpandedBeforeFling;
private boolean mTouchAboveFalsingThreshold;
private int mUnlockFalsingThreshold;
+ private boolean mTouchStartedInEmptyArea;
private ValueAnimator mHeightAnimator;
private ObjectAnimator mPeekAnimator;
@@ -284,7 +285,7 @@
|| mInitialOffsetOnTouch == 0f)) {
mTouchSlopExceeded = true;
if (waitForTouchSlop && !mTracking) {
- if (!mJustPeeked) {
+ if (!mJustPeeked && mInitialOffsetOnTouch != 0f) {
mInitialOffsetOnTouch = mExpandedHeight;
mInitialTouchX = x;
mInitialTouchY = y;
@@ -409,6 +410,7 @@
}
mInitialTouchY = y;
mInitialTouchX = x;
+ mTouchStartedInEmptyArea = !isInContentBounds(x, y);
mTouchSlopExceeded = false;
mJustPeeked = false;
mPanelClosedOnDown = mExpandedHeight == 0.0f;
@@ -432,7 +434,7 @@
case MotionEvent.ACTION_MOVE:
final float h = y - mInitialTouchY;
trackMovement(event);
- if (scrolledToBottom) {
+ if (scrolledToBottom || mTouchStartedInEmptyArea) {
if (h < -mTouchSlop && h < -Math.abs(x - mInitialTouchX)) {
cancelHeightAnimator();
mInitialOffsetOnTouch = mExpandedHeight;
@@ -452,6 +454,11 @@
return false;
}
+ /**
+ * @return Whether a pair of coordinates are inside the visible view content bounds.
+ */
+ protected abstract boolean isInContentBounds(float x, float y);
+
private void cancelHeightAnimator() {
if (mHeightAnimator != null) {
mHeightAnimator.cancel();
@@ -632,10 +639,10 @@
}
mExpandedHeight = Math.max(0, mExpandedHeight);
- onHeightUpdated(mExpandedHeight);
mExpandedFraction = Math.min(1f, fhWithoutOverExpansion == 0
? 0
: mExpandedHeight / fhWithoutOverExpansion);
+ onHeightUpdated(mExpandedHeight);
notifyBarPanelExpansionChanged();
}
@@ -903,7 +910,7 @@
*
* @return whether the panel will be expanded after the action performed by this method
*/
- private boolean onEmptySpaceClick(float x) {
+ protected boolean onEmptySpaceClick(float x) {
if (mHintAnimationRunning) {
return true;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
index eb48754..84ebcdfb 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -23,6 +23,7 @@
import static android.app.StatusBarManager.WINDOW_STATE_SHOWING;
import static android.app.StatusBarManager.windowStateToString;
import static com.android.systemui.statusbar.phone.BarTransitions.MODE_LIGHTS_OUT;
+import static com.android.systemui.statusbar.phone.BarTransitions.MODE_LIGHTS_OUT_TRANSPARENT;
import static com.android.systemui.statusbar.phone.BarTransitions.MODE_OPAQUE;
import static com.android.systemui.statusbar.phone.BarTransitions.MODE_SEMI_TRANSPARENT;
import static com.android.systemui.statusbar.phone.BarTransitions.MODE_TRANSLUCENT;
@@ -55,7 +56,6 @@
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
-import android.graphics.Xfermode;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.inputmethodservice.InputMethodService;
@@ -98,7 +98,6 @@
import android.view.WindowManager;
import android.view.WindowManagerGlobal;
import android.view.accessibility.AccessibilityEvent;
-import android.view.accessibility.AccessibilityManager;
import android.view.animation.AccelerateDecelerateInterpolator;
import android.view.animation.AccelerateInterpolator;
import android.view.animation.Animation;
@@ -409,13 +408,6 @@
private boolean mAutohideSuspended;
private int mStatusBarMode;
private int mNavigationBarMode;
- private Boolean mScreenOn;
-
- // The second field is a bit different from the first one because it only listens to screen on/
- // screen of events from Keyguard. We need this so we don't have a race condition with the
- // broadcast. In the future, we should remove the first field altogether and rename the second
- // field.
- private boolean mScreenOnFromKeyguard;
private ViewMediatorCallback mKeyguardViewMediatorCallback;
private ScrimController mScrimController;
@@ -429,7 +421,6 @@
}
}};
- private boolean mVisible;
private boolean mWaitingForKeyguardExit;
private boolean mDozing;
private boolean mScrimSrcModeEnabled;
@@ -2610,8 +2601,10 @@
}
private int barMode(int vis, int transientFlag, int translucentFlag) {
+ int lightsOutTransparent = View.SYSTEM_UI_FLAG_LOW_PROFILE | View.SYSTEM_UI_TRANSPARENT;
return (vis & transientFlag) != 0 ? MODE_SEMI_TRANSPARENT
: (vis & translucentFlag) != 0 ? MODE_TRANSLUCENT
+ : (vis & lightsOutTransparent) == lightsOutTransparent ? MODE_LIGHTS_OUT_TRANSPARENT
: (vis & View.SYSTEM_UI_TRANSPARENT) != 0 ? MODE_TRANSPARENT
: (vis & View.SYSTEM_UI_FLAG_LOW_PROFILE) != 0 ? MODE_LIGHTS_OUT
: MODE_OPAQUE;
@@ -3077,15 +3070,11 @@
notifyNavigationBarScreenOn(false);
notifyHeadsUpScreenOn(false);
finishBarAnimations();
- stopNotificationLogging();
resetUserExpandedStates();
}
else if (Intent.ACTION_SCREEN_ON.equals(action)) {
mScreenOn = true;
- // work around problem where mDisplay.getRotation() is not stable while screen is off (bug 7086018)
- repositionNavigationBar();
notifyNavigationBarScreenOn(true);
- startNotificationLoggingIfScreenOnAndVisible();
}
else if (ACTION_DEMO.equals(action)) {
Bundle bundle = intent.getExtras();
@@ -3274,14 +3263,14 @@
// Visibility reporting
@Override
- protected void visibilityChanged(boolean visible) {
- mVisible = visible;
- if (visible) {
- startNotificationLoggingIfScreenOnAndVisible();
+ protected void handleVisibleToUserChanged(boolean visibleToUser) {
+ if (visibleToUser) {
+ super.handleVisibleToUserChanged(visibleToUser);
+ startNotificationLogging();
} else {
stopNotificationLogging();
+ super.handleVisibleToUserChanged(visibleToUser);
}
- super.visibilityChanged(visible);
}
private void stopNotificationLogging() {
@@ -3296,17 +3285,15 @@
mStackScroller.setChildLocationsChangedListener(null);
}
- private void startNotificationLoggingIfScreenOnAndVisible() {
- if (mVisible && mScreenOn) {
- mStackScroller.setChildLocationsChangedListener(mNotificationLocationsChangedListener);
- // Some transitions like mScreenOn=false -> mScreenOn=true don't
- // cause the scroller to emit child location events. Hence generate
- // one ourselves to guarantee that we're reporting visible
- // notifications.
- // (Note that in cases where the scroller does emit events, this
- // additional event doesn't break anything.)
- mNotificationLocationsChangedListener.onChildLocationsChanged(mStackScroller);
- }
+ private void startNotificationLogging() {
+ mStackScroller.setChildLocationsChangedListener(mNotificationLocationsChangedListener);
+ // Some transitions like mVisibleToUser=false -> mVisibleToUser=true don't
+ // cause the scroller to emit child location events. Hence generate
+ // one ourselves to guarantee that we're reporting visible
+ // notifications.
+ // (Note that in cases where the scroller does emit events, this
+ // additional event doesn't break anything.)
+ mNotificationLocationsChangedListener.onChildLocationsChanged(mStackScroller);
}
private void logNotificationVisibilityChanges(
@@ -3611,6 +3598,12 @@
instantCollapseNotificationPanel();
}
updateKeyguardState(staying, false /* fromShadeLocked */);
+
+ // Keyguard state has changed, but QS is not listening anymore. Make sure to update the tile
+ // visibilities so next time we open the panel we know the correct height already.
+ if (mQSPanel != null) {
+ mQSPanel.refreshAllTiles();
+ }
return staying;
}
@@ -3644,9 +3637,7 @@
}
private void updatePublicMode() {
- setLockscreenPublicMode(
- (mStatusBarKeyguardViewManager.isShowing() ||
- mStatusBarKeyguardViewManager.isOccluded())
+ setLockscreenPublicMode(mStatusBarKeyguardViewManager.isShowing()
&& mStatusBarKeyguardViewManager.isSecure());
}
@@ -3942,6 +3933,7 @@
mScreenOnFromKeyguard = false;
mScreenOnComingFromTouch = false;
mStackScroller.setAnimationsEnabled(false);
+ updateVisibleToUser();
}
public void onScreenTurnedOn() {
@@ -3949,6 +3941,7 @@
mStackScroller.setAnimationsEnabled(true);
mNotificationPanel.onScreenTurnedOn();
mNotificationPanel.setTouchDisabled(false);
+ updateVisibleToUser();
}
/**
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarTransitions.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarTransitions.java
index 8520f40..fb1addf 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarTransitions.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarTransitions.java
@@ -57,19 +57,19 @@
}
private float getNonBatteryClockAlphaFor(int mode) {
- return mode == MODE_LIGHTS_OUT ? ICON_ALPHA_WHEN_LIGHTS_OUT_NON_BATTERY_CLOCK
+ return isLightsOut(mode) ? ICON_ALPHA_WHEN_LIGHTS_OUT_NON_BATTERY_CLOCK
: !isOpaque(mode) ? ICON_ALPHA_WHEN_NOT_OPAQUE
: mIconAlphaWhenOpaque;
}
private float getBatteryClockAlpha(int mode) {
- return mode == MODE_LIGHTS_OUT ? ICON_ALPHA_WHEN_LIGHTS_OUT_BATTERY_CLOCK
+ return isLightsOut(mode) ? ICON_ALPHA_WHEN_LIGHTS_OUT_BATTERY_CLOCK
: getNonBatteryClockAlphaFor(mode);
}
private boolean isOpaque(int mode) {
return !(mode == MODE_SEMI_TRANSPARENT || mode == MODE_TRANSLUCENT
- || mode == MODE_TRANSPARENT);
+ || mode == MODE_TRANSPARENT || mode == MODE_LIGHTS_OUT_TRANSPARENT);
}
@Override
@@ -94,7 +94,7 @@
animateTransitionTo(mBattery, newAlphaBC),
animateTransitionTo(mClock, newAlphaBC)
);
- if (mode == MODE_LIGHTS_OUT) {
+ if (isLightsOut(mode)) {
anims.setDuration(LIGHTS_OUT_DURATION);
}
anims.start();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QSTileHost.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QSTileHost.java
index a4db46a..45a1386 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QSTileHost.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QSTileHost.java
@@ -21,6 +21,7 @@
import android.content.res.Resources;
import android.database.ContentObserver;
import android.net.Uri;
+import android.os.Process;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Looper;
@@ -108,7 +109,8 @@
mKeyguard = keyguard;
mSecurity = security;
- final HandlerThread ht = new HandlerThread(QSTileHost.class.getSimpleName());
+ final HandlerThread ht = new HandlerThread(QSTileHost.class.getSimpleName(),
+ Process.THREAD_PRIORITY_BACKGROUND);
ht.start();
mLooper = ht.getLooper();
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 4a20406..d543cff 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
@@ -40,6 +40,7 @@
import com.android.systemui.statusbar.ExpandableNotificationRow;
import com.android.systemui.statusbar.ExpandableView;
import com.android.systemui.statusbar.SpeedBumpView;
+import com.android.systemui.statusbar.StackScrollerDecorView;
import com.android.systemui.statusbar.StatusBarState;
import com.android.systemui.statusbar.phone.PhoneStatusBar;
import com.android.systemui.statusbar.policy.ScrollAdapter;
@@ -70,6 +71,12 @@
private SwipeHelper mSwipeHelper;
private boolean mSwipingInProgress;
private int mCurrentStackHeight = Integer.MAX_VALUE;
+
+ /**
+ * mCurrentStackHeight is the actual stack height, mLastSetStackHeight is the stack height set
+ * externally from {@link #setStackHeight}
+ */
+ private float mLastSetStackHeight;
private int mOwnScrollY;
private int mMaxLayoutHeight;
@@ -84,6 +91,9 @@
private int mLastMotionY;
private int mDownX;
private int mActivePointerId;
+ private boolean mTouchIsClick;
+ private float mInitialTouchX;
+ private float mInitialTouchY;
private int mSidePaddings;
private Paint mDebugPaint;
@@ -133,6 +143,7 @@
private OnChildLocationsChangedListener mListener;
private OnOverscrollTopChangedListener mOverscrollTopChangedListener;
private ExpandableView.OnHeightChangedListener mOnHeightChangedListener;
+ private OnEmptySpaceClickListener mOnEmptySpaceClickListener;
private boolean mNeedsAnimation;
private boolean mTopPaddingNeedsAnimation;
private boolean mDimmedNeedsAnimation;
@@ -367,6 +378,9 @@
if (childViewState == null) {
return ViewState.LOCATION_UNKNOWN;
}
+ if (childViewState.gone) {
+ return ViewState.LOCATION_GONE;
+ }
return childViewState.location;
}
@@ -445,6 +459,7 @@
* @param height the new height of the stack
*/
public void setStackHeight(float height) {
+ mLastSetStackHeight = height;
setIsExpanded(height > 0.0f);
int newStackHeight = (int) height;
int minStackHeight = getMinStackHeight();
@@ -581,7 +596,9 @@
final int count = getChildCount();
for (int childIdx = 0; childIdx < count; childIdx++) {
ExpandableView slidingChild = (ExpandableView) getChildAt(childIdx);
- if (slidingChild.getVisibility() == GONE) {
+ if (slidingChild.getVisibility() == GONE
+ || slidingChild instanceof StackScrollerDecorView
+ || slidingChild == mSpeedBumpView) {
continue;
}
float childTop = slidingChild.getTranslationY();
@@ -687,6 +704,7 @@
transformTouchEvent(ev, this, mScrollView);
return mScrollView.onTouchEvent(ev);
}
+ handleEmptySpaceClick(ev);
boolean expandWantsIt = false;
if (!mSwipingInProgress && !mOnlyScrollingInThisMotion && isScrollingEnabled()) {
if (isCancelOrUp) {
@@ -1338,7 +1356,19 @@
&& initialVelocity > 0;
}
- public void updateTopPadding(float qsHeight, int scrollY, boolean animate) {
+ /**
+ * Updates the top padding of the notifications, taking {@link #getIntrinsicPadding()} into
+ * account.
+ *
+ * @param qsHeight the top padding imposed by the quick settings panel
+ * @param scrollY how much the notifications are scrolled inside the QS/notifications scroll
+ * container
+ * @param animate whether to animate the change
+ * @param ignoreIntrinsicPadding if true, {@link #getIntrinsicPadding()} is ignored and
+ * {@code qsHeight} is the final top padding
+ */
+ public void updateTopPadding(float qsHeight, int scrollY, boolean animate,
+ boolean ignoreIntrinsicPadding) {
float start = qsHeight - scrollY + mNotificationTopPadding;
float stackHeight = getHeight() - start;
int minStackHeight = getMinStackHeight();
@@ -1346,13 +1376,13 @@
float overflow = minStackHeight - stackHeight;
stackHeight = minStackHeight;
start = getHeight() - stackHeight;
- setTranslationY(overflow);
mTopPaddingOverflow = overflow;
} else {
- setTranslationY(0);
mTopPaddingOverflow = 0;
}
- setTopPadding(clampPadding((int) start), animate);
+ setTopPadding(ignoreIntrinsicPadding ? (int) start : clampPadding((int) start),
+ animate);
+ setStackHeight(mLastSetStackHeight);
}
public int getNotificationTopPadding() {
@@ -1430,6 +1460,7 @@
transformTouchEvent(ev, mScrollView, this);
}
initDownStates(ev);
+ handleEmptySpaceClick(ev);
boolean expandWantsIt = false;
if (!mSwipingInProgress && !mOnlyScrollingInThisMotion && isScrollingEnabled()) {
expandWantsIt = mExpandHelper.onInterceptTouchEvent(ev);
@@ -1448,11 +1479,31 @@
return swipeWantsIt || scrollWantsIt || expandWantsIt || super.onInterceptTouchEvent(ev);
}
+ private void handleEmptySpaceClick(MotionEvent ev) {
+ switch (ev.getActionMasked()) {
+ case MotionEvent.ACTION_MOVE:
+ if (mTouchIsClick && (Math.abs(ev.getY() - mInitialTouchY) > mTouchSlop
+ || Math.abs(ev.getX() - mInitialTouchX) > mTouchSlop )) {
+ mTouchIsClick = false;
+ }
+ break;
+ case MotionEvent.ACTION_UP:
+ if (mPhoneStatusBar.getBarState() != StatusBarState.KEYGUARD && mTouchIsClick &&
+ isBelowLastNotification(mInitialTouchX, mInitialTouchY)) {
+ mOnEmptySpaceClickListener.onEmptySpaceClicked(mInitialTouchX, mInitialTouchY);
+ }
+ break;
+ }
+ }
+
private void initDownStates(MotionEvent ev) {
if (ev.getAction() == MotionEvent.ACTION_DOWN) {
mExpandedInThisMotion = false;
mOnlyScrollingInThisMotion = !mScroller.isFinished();
mDisallowScrollingInThisMotion = false;
+ mTouchIsClick = true;
+ mInitialTouchX = ev.getX();
+ mInitialTouchY = ev.getY();
}
}
@@ -1886,7 +1937,14 @@
* @return Whether the specified motion event is actually happening over the content.
*/
private boolean isInContentBounds(MotionEvent event) {
- return event.getY() < getHeight() - getEmptyBottomMargin();
+ return isInContentBounds(event.getY());
+ }
+
+ /**
+ * @return Whether a y coordinate is inside the content.
+ */
+ public boolean isInContentBounds(float y) {
+ return y < getHeight() - getEmptyBottomMargin();
}
private void setIsBeingDragged(boolean isDragged) {
@@ -1995,6 +2053,10 @@
this.mOnHeightChangedListener = mOnHeightChangedListener;
}
+ public void setOnEmptySpaceClickListener(OnEmptySpaceClickListener listener) {
+ mOnEmptySpaceClickListener = listener;
+ }
+
public void onChildAnimationFinished() {
requestChildrenUpdate();
}
@@ -2210,6 +2272,10 @@
return height;
}
+ public int getEmptyShadeViewHeight() {
+ return mEmptyShadeView.getHeight();
+ }
+
public float getBottomMostNotificationBottom() {
final int count = getChildCount();
float max = 0;
@@ -2245,6 +2311,24 @@
}
}
+ private boolean isBelowLastNotification(float touchX, float touchY) {
+ ExpandableView lastChildNotGone = (ExpandableView) getLastChildNotGone();
+ if (lastChildNotGone == null) {
+ return touchY > mIntrinsicPadding;
+ }
+ if (lastChildNotGone != mDismissView && lastChildNotGone != mEmptyShadeView) {
+ return touchY > lastChildNotGone.getY() + lastChildNotGone.getActualHeight();
+ } else if (lastChildNotGone == mEmptyShadeView) {
+ return touchY > mEmptyShadeView.getY();
+ } else {
+ float dismissY = mDismissView.getY();
+ boolean belowDismissView = touchY > dismissY + mDismissView.getActualHeight();
+ return belowDismissView || (touchY > dismissY
+ && mDismissView.isOnEmptySpace(touchX - mDismissView.getX(),
+ touchY - dismissY));
+ }
+ }
+
/**
* A listener that is notified when some child locations might have changed.
*/
@@ -2253,6 +2337,13 @@
}
/**
+ * A listener that is notified when the empty space below the notifications is clicked on
+ */
+ public interface OnEmptySpaceClickListener {
+ public void onEmptySpaceClicked(float x, float y);
+ }
+
+ /**
* A listener that gets notified when the overscroll at the top has changed.
*/
public interface OnOverscrollTopChangedListener {
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 853628e..ddc4251 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java
@@ -200,15 +200,25 @@
// apply clipping and shadow
float newNotificationEnd = newYTranslation + newHeight;
- // In the unlocked shade we have to clip a little bit higher because of the rounded
- // corners of the notifications.
- float clippingCorrection = state.dimmed ? 0 : mRoundedRectCornerRadius * state.scale;
+ float clipHeight;
+ if (previousNotificationIsSwiped) {
+ // When the previous notification is swiped, we don't clip the content to the
+ // bottom of it.
+ clipHeight = newHeight;
+ } else {
+ clipHeight = newNotificationEnd - previousNotificationEnd;
+ clipHeight = Math.max(0.0f, clipHeight);
+ if (clipHeight != 0.0f) {
- // When the previous notification is swiped, we don't clip the content to the
- // bottom of it.
- float clipHeight = previousNotificationIsSwiped
- ? newHeight
- : newNotificationEnd - (previousNotificationEnd - clippingCorrection);
+ // In the unlocked shade we have to clip a little bit higher because of the rounded
+ // corners of the notifications, but only if we are not fully overlapped by
+ // the top card.
+ float clippingCorrection = state.dimmed
+ ? 0
+ : mRoundedRectCornerRadius * state.scale;
+ clipHeight += clippingCorrection;
+ }
+ }
updateChildClippingAndBackground(state, newHeight, clipHeight,
newHeight - (previousNotificationStart - newYTranslation));
@@ -669,7 +679,11 @@
StackScrollState.ViewState childViewState = resultState.getViewStateForView(child);
if (i < algorithmState.itemsInTopStack) {
float stackIndex = algorithmState.itemsInTopStack - i;
- stackIndex = Math.min(stackIndex, MAX_ITEMS_IN_TOP_STACK + 2);
+
+ // Ensure that the topmost item is a little bit higher than the rest when fully
+ // scrolled, to avoid drawing errors when swiping it out
+ float max = MAX_ITEMS_IN_TOP_STACK + (i == 0 ? 2.5f : 2);
+ stackIndex = Math.min(stackIndex, max);
if (i == 0 && algorithmState.itemsInTopStack < 2.0f) {
// We only have the top item and an additional item in the top stack,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollState.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollState.java
index 0967ecd..4611370 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollState.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollState.java
@@ -119,9 +119,7 @@
}
// apply alpha
- if (!becomesInvisible) {
- child.setAlpha(newAlpha);
- }
+ child.setAlpha(newAlpha);
}
// apply visibility
@@ -236,6 +234,8 @@
public static final int LOCATION_MAIN_AREA = 0x08;
public static final int LOCATION_BOTTOM_STACK_PEEKING = 0x10;
public static final int LOCATION_BOTTOM_STACK_HIDDEN = 0x20;
+ /** The view isn't layouted at all. */
+ public static final int LOCATION_GONE = 0x40;
float alpha;
float yTranslation;
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 433357e..674642b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackStateAnimator.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackStateAnimator.java
@@ -477,6 +477,7 @@
if (newEndValue == 0 && !mWasCancelled) {
child.setVisibility(View.INVISIBLE);
}
+ // remove the tag when the animation is finished
child.setTag(TAG_ANIMATOR_ALPHA, null);
child.setTag(TAG_START_ALPHA, null);
child.setTag(TAG_END_ALPHA, null);
@@ -498,13 +499,7 @@
animator.setStartDelay(delay);
}
animator.addListener(getGlobalAnimationFinishedListener());
- // remove the tag when the animation is finished
- animator.addListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationEnd(Animator animation) {
- }
- });
startAnimator(animator);
child.setTag(TAG_ANIMATOR_ALPHA, animator);
child.setTag(TAG_START_ALPHA, child.getAlpha());
diff --git a/packages/SystemUI/src/com/android/systemui/volume/ZenModePanel.java b/packages/SystemUI/src/com/android/systemui/volume/ZenModePanel.java
index c840f17..28ecbf9 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/ZenModePanel.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/ZenModePanel.java
@@ -69,6 +69,7 @@
private static final int TIME_CONDITION_INDEX = 1;
private static final int FIRST_CONDITION_INDEX = 2;
private static final float SILENT_HINT_PULSE_SCALE = 1.1f;
+ private static final long SELECT_DEFAULT_DELAY = 300;
public static final Intent ZEN_SETTINGS = new Intent(Settings.ACTION_ZEN_MODE_SETTINGS);
@@ -373,8 +374,9 @@
if (isDowntime(mSessionExitCondition) && !foundDowntime) {
bind(mSessionExitCondition, null);
}
- // ensure something is selected
- checkForDefault();
+ // ensure something is selected, after waiting for providers to respond
+ mHandler.removeMessages(H.SELECT_DEFAULT);
+ mHandler.sendEmptyMessageDelayed(H.SELECT_DEFAULT, SELECT_DEFAULT_DELAY);
}
private static boolean isDowntime(Condition c) {
@@ -385,7 +387,8 @@
return (ConditionTag) mZenConditions.getChildAt(index).getTag();
}
- private void checkForDefault() {
+ private void handleSelectDefault() {
+ if (!mExpanded) return;
// are we left without anything selected? if so, set a default
for (int i = 0; i < mZenConditions.getChildCount(); i++) {
if (getConditionTagAt(i).rb.isChecked()) {
@@ -638,6 +641,7 @@
private static final int UPDATE_CONDITIONS = 1;
private static final int EXIT_CONDITION_CHANGED = 2;
private static final int UPDATE_ZEN = 3;
+ private static final int SELECT_DEFAULT = 4;
private H() {
super(Looper.getMainLooper());
@@ -651,6 +655,8 @@
handleExitConditionChanged((Condition) msg.obj);
} else if (msg.what == UPDATE_ZEN) {
handleUpdateZen(msg.arg1);
+ } else if (msg.what == SELECT_DEFAULT) {
+ handleSelectDefault();
}
}
}
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindow.java b/policy/src/com/android/internal/policy/impl/PhoneWindow.java
index 4714826..c34316b 100644
--- a/policy/src/com/android/internal/policy/impl/PhoneWindow.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindow.java
@@ -2190,6 +2190,7 @@
private int mLastBottomInset = 0;
private int mLastRightInset = 0;
+ private int mRootScrollY = 0;
public DecorView(Context context, int featureId) {
super(context);
@@ -2891,6 +2892,7 @@
view.setId(id);
addView(view, new LayoutParams(LayoutParams.MATCH_PARENT, height,
Gravity.START | verticalGravity));
+ updateColorViewTranslations();
}
} else {
int vis = show ? VISIBLE : INVISIBLE;
@@ -2907,6 +2909,18 @@
return view;
}
+ private void updateColorViewTranslations() {
+ // Put the color views back in place when they get moved off the screen
+ // due to the the ViewRootImpl panning.
+ int rootScrollY = mRootScrollY;
+ if (mStatusColorView != null) {
+ mStatusColorView.setTranslationY(rootScrollY > 0 ? rootScrollY : 0);
+ }
+ if (mNavigationColorView != null) {
+ mNavigationColorView.setTranslationY(rootScrollY < 0 ? rootScrollY : 0);
+ }
+ }
+
private WindowInsets updateStatusGuard(WindowInsets insets) {
boolean showStatusGuard = false;
// Show the status guard when the non-overlay contextual action bar is showing
@@ -3165,6 +3179,12 @@
else PhoneWindow.this.clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
}
+ @Override
+ public void onRootViewScrollYChanged(int rootScrollY) {
+ mRootScrollY = rootScrollY;
+ updateColorViewTranslations();
+ }
+
/**
* Clears out internal reference when the action mode is destroyed.
*/
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
index fb2a17b..3c44e87 100644
--- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
@@ -48,6 +48,7 @@
import android.media.RingtoneManager;
import android.media.session.MediaSessionLegacyHelper;
import android.os.Bundle;
+import android.os.Debug;
import android.os.FactoryTest;
import android.os.Handler;
import android.os.IBinder;
@@ -116,6 +117,7 @@
import java.io.IOException;
import java.io.PrintWriter;
import java.util.HashSet;
+import java.util.List;
import static android.view.WindowManager.LayoutParams.*;
import static android.view.WindowManagerPolicy.WindowManagerFuncs.LID_ABSENT;
@@ -136,8 +138,9 @@
static final String TAG = "WindowManager";
static final boolean DEBUG = false;
static final boolean localLOGV = false;
- static final boolean DEBUG_LAYOUT = false;
static final boolean DEBUG_INPUT = false;
+ static final boolean DEBUG_KEYGUARD = false;
+ static final boolean DEBUG_LAYOUT = false;
static final boolean DEBUG_STARTING_WINDOW = false;
static final boolean DEBUG_WAKEUP = false;
static final boolean SHOW_STARTING_ANIMATIONS = true;
@@ -158,6 +161,10 @@
static final int LONG_PRESS_POWER_SHUT_OFF = 2;
static final int LONG_PRESS_POWER_SHUT_OFF_NO_CONFIRM = 3;
+ static final int MULTI_PRESS_POWER_NOTHING = 0;
+ static final int MULTI_PRESS_POWER_THEATER_MODE = 1;
+ static final int MULTI_PRESS_POWER_BRIGHTNESS_BOOST = 2;
+
// These need to match the documentation/constant in
// core/res/res/values/config.xml
static final int LONG_PRESS_HOME_NOTHING = 0;
@@ -300,12 +307,21 @@
};
GlobalActions mGlobalActions;
- volatile boolean mPowerKeyHandled; // accessed from input reader and handler thread
- boolean mPendingPowerKeyUpCanceled;
Handler mHandler;
WindowState mLastInputMethodWindow = null;
WindowState mLastInputMethodTargetWindow = null;
+ // FIXME This state is shared between the input reader and handler thread.
+ // Technically it's broken and buggy but it has been like this for many years
+ // and we have not yet seen any problems. Someday we'll rewrite this logic
+ // so that only one thread is involved in handling input policy. Unfortunately
+ // it's on a critical path for power management so we can't just post the work to the
+ // handler thread. We'll need to resolve this someday by teaching the input dispatcher
+ // to hold wakelocks during dispatch and eliminating the critical path.
+ volatile boolean mPowerKeyHandled;
+ volatile int mPowerKeyPressCounter;
+ volatile boolean mEndCallKeyHandled;
+
boolean mRecentsVisible;
int mRecentAppsHeldModifiers;
boolean mLanguageSwitchKeyPressed;
@@ -345,8 +361,10 @@
int mLidKeyboardAccessibility;
int mLidNavigationAccessibility;
boolean mLidControlsSleep;
- int mShortPressOnPowerBehavior = -1;
- int mLongPressOnPowerBehavior = -1;
+ int mShortPressOnPowerBehavior;
+ int mLongPressOnPowerBehavior;
+ int mDoublePressOnPowerBehavior;
+ int mTriplePressOnPowerBehavior;
boolean mAwake;
boolean mScreenOnEarly;
boolean mScreenOnFully;
@@ -511,18 +529,21 @@
private boolean mAllowTheaterModeWakeFromLidSwitch;
private boolean mAllowTheaterModeWakeFromWakeGesture;
+ // Whether to go to sleep entering theater mode from power button
+ private boolean mGoToSleepOnButtonPressTheaterMode;
+
// Screenshot trigger states
// Time to volume and power must be pressed within this interval of each other.
private static final long SCREENSHOT_CHORD_DEBOUNCE_DELAY_MILLIS = 150;
// Increase the chord delay when taking a screenshot from the keyguard
private static final float KEYGUARD_SCREENSHOT_CHORD_DELAY_MULTIPLIER = 2.5f;
private boolean mScreenshotChordEnabled;
- private boolean mVolumeDownKeyTriggered;
- private long mVolumeDownKeyTime;
- private boolean mVolumeDownKeyConsumedByScreenshotChord;
- private boolean mVolumeUpKeyTriggered;
- private boolean mPowerKeyTriggered;
- private long mPowerKeyTime;
+ private boolean mScreenshotChordVolumeDownKeyTriggered;
+ private long mScreenshotChordVolumeDownKeyTime;
+ private boolean mScreenshotChordVolumeDownKeyConsumed;
+ private boolean mScreenshotChordVolumeUpKeyTriggered;
+ private boolean mScreenshotChordPowerKeyTriggered;
+ private long mScreenshotChordPowerKeyTime;
/* The number of steps between min and max brightness */
private static final int BRIGHTNESS_STEPS = 10;
@@ -530,6 +551,7 @@
SettingsObserver mSettingsObserver;
ShortcutManager mShortcutManager;
PowerManager.WakeLock mBroadcastWakeLock;
+ PowerManager.WakeLock mPowerKeyWakeLock;
boolean mHavePendingMediaKeyRepeatWithWakeLock;
private int mCurrentUserId;
@@ -555,6 +577,8 @@
private static final int MSG_DISPATCH_SHOW_GLOBAL_ACTIONS = 10;
private static final int MSG_HIDE_BOOT_MESSAGE = 11;
private static final int MSG_LAUNCH_VOICE_ASSIST_WITH_WAKE_LOCK = 12;
+ private static final int MSG_POWER_DELAYED_PRESS = 13;
+ private static final int MSG_POWER_LONG_PRESS = 14;
private class PolicyHandler extends Handler {
@Override
@@ -596,6 +620,13 @@
case MSG_LAUNCH_VOICE_ASSIST_WITH_WAKE_LOCK:
launchVoiceAssistWithWakeLock(msg.arg1 != 0);
break;
+ case MSG_POWER_DELAYED_PRESS:
+ powerPress((Long)msg.obj, msg.arg1 != 0, msg.arg2);
+ finishPowerKeyPress();
+ break;
+ case MSG_POWER_LONG_PRESS:
+ powerLongPress();
+ break;
}
}
}
@@ -789,38 +820,240 @@
}
}
- private void interceptPowerKeyDown(boolean handled) {
- mPowerKeyHandled = handled;
- if (!handled) {
- mHandler.postDelayed(mPowerLongPress,
- ViewConfiguration.get(mContext).getDeviceGlobalActionKeyTimeout());
+ private void interceptPowerKeyDown(KeyEvent event, boolean interactive) {
+ // Hold a wake lock until the power key is released.
+ if (!mPowerKeyWakeLock.isHeld()) {
+ mPowerKeyWakeLock.acquire();
+ }
+
+ // Cancel multi-press detection timeout.
+ if (mPowerKeyPressCounter != 0) {
+ mHandler.removeMessages(MSG_POWER_DELAYED_PRESS);
+ }
+
+ // Detect user pressing the power button in panic when an application has
+ // taken over the whole screen.
+ boolean panic = mImmersiveModeConfirmation.onPowerKeyDown(interactive,
+ event.getDownTime(), isImmersiveMode(mLastSystemUiFlags));
+ if (panic) {
+ mHandler.post(mRequestTransientNav);
+ }
+
+ // Latch power key state to detect screenshot chord.
+ if (interactive && !mScreenshotChordPowerKeyTriggered
+ && (event.getFlags() & KeyEvent.FLAG_FALLBACK) == 0) {
+ mScreenshotChordPowerKeyTriggered = true;
+ mScreenshotChordPowerKeyTime = event.getDownTime();
+ interceptScreenshotChord();
+ }
+
+ // Stop ringing or end call if configured to do so when power is pressed.
+ TelecomManager telecomManager = getTelecommService();
+ boolean hungUp = false;
+ if (telecomManager != null) {
+ if (telecomManager.isRinging()) {
+ // Pressing Power while there's a ringing incoming
+ // call should silence the ringer.
+ telecomManager.silenceRinger();
+ } else if ((mIncallPowerBehavior
+ & Settings.Secure.INCALL_POWER_BUTTON_BEHAVIOR_HANGUP) != 0
+ && telecomManager.isInCall() && interactive) {
+ // Otherwise, if "Power button ends call" is enabled,
+ // the Power button will hang up any current active call.
+ hungUp = telecomManager.endCall();
+ }
+ }
+
+ // If the power key has still not yet been handled, then detect short
+ // press, long press, or multi press and decide what to do.
+ mPowerKeyHandled = hungUp || mScreenshotChordVolumeDownKeyTriggered
+ || mScreenshotChordVolumeUpKeyTriggered;
+ if (!mPowerKeyHandled) {
+ if (interactive) {
+ // When interactive, we're already awake.
+ // Wait for a long press or for the button to be released to decide what to do.
+ if (hasLongPressOnPowerBehavior()) {
+ Message msg = mHandler.obtainMessage(MSG_POWER_LONG_PRESS);
+ msg.setAsynchronous(true);
+ mHandler.sendMessageDelayed(msg,
+ ViewConfiguration.get(mContext).getDeviceGlobalActionKeyTimeout());
+ }
+ } else {
+ // When non-interactive, we ordinarily wake up immediately and
+ // consume the key. However on some devices we need to support multi-press
+ // without waking so we will delay handling for later in that case
+ // (at the cost of increased latency).
+ final int maxCount = getMaxMultiPressPowerCount();
+ if (maxCount <= 1) {
+ // No other actions. We can wake immediately.
+ wakeUpFromPowerKey(event.getDownTime());
+ mPowerKeyHandled = true;
+ }
+ }
}
}
- private boolean interceptPowerKeyUp(boolean canceled) {
- if (!mPowerKeyHandled) {
- mHandler.removeCallbacks(mPowerLongPress);
- return !canceled;
+ private void interceptPowerKeyUp(KeyEvent event, boolean interactive, boolean canceled) {
+ final boolean handled = canceled || mPowerKeyHandled;
+ mScreenshotChordPowerKeyTriggered = false;
+ cancelPendingScreenshotChordAction();
+ cancelPendingPowerKeyAction();
+
+ if (!handled) {
+ // Figure out how to handle the key now that it has been released.
+ mPowerKeyPressCounter += 1;
+
+ final int maxCount = getMaxMultiPressPowerCount();
+ final long eventTime = event.getDownTime();
+ if (mPowerKeyPressCounter < maxCount) {
+ // This could be a multi-press. Wait a little bit longer to confirm.
+ // Continue holding the wake lock.
+ Message msg = mHandler.obtainMessage(MSG_POWER_DELAYED_PRESS,
+ interactive ? 1 : 0, mPowerKeyPressCounter, eventTime);
+ msg.setAsynchronous(true);
+ mHandler.sendMessageDelayed(msg, ViewConfiguration.getDoubleTapTimeout());
+ return;
+ }
+
+ // No other actions. Handle it immediately.
+ powerPress(eventTime, interactive, mPowerKeyPressCounter);
}
- return false;
+
+ // Done. Reset our state.
+ finishPowerKeyPress();
+ }
+
+ private void finishPowerKeyPress() {
+ mPowerKeyPressCounter = 0;
+ if (mPowerKeyWakeLock.isHeld()) {
+ mPowerKeyWakeLock.release();
+ }
}
private void cancelPendingPowerKeyAction() {
if (!mPowerKeyHandled) {
- mHandler.removeCallbacks(mPowerLongPress);
+ mPowerKeyHandled = true;
+ mHandler.removeMessages(MSG_POWER_LONG_PRESS);
}
- if (mPowerKeyTriggered) {
- mPendingPowerKeyUpCanceled = true;
+ }
+
+ private void powerPress(long eventTime, boolean interactive, int count) {
+ if (mScreenOnEarly && !mScreenOnFully) {
+ Slog.i(TAG, "Suppressed redundant power key press while "
+ + "already in the process of turning the screen on.");
+ return;
}
+
+ if (count == 2) {
+ powerMultiPressAction(eventTime, interactive, mDoublePressOnPowerBehavior);
+ } else if (count == 3) {
+ powerMultiPressAction(eventTime, interactive, mTriplePressOnPowerBehavior);
+ } else if (!interactive) {
+ wakeUpFromPowerKey(eventTime);
+ } else {
+ switch (mShortPressOnPowerBehavior) {
+ case SHORT_PRESS_POWER_NOTHING:
+ break;
+ case SHORT_PRESS_POWER_GO_TO_SLEEP:
+ mPowerManager.goToSleep(eventTime,
+ PowerManager.GO_TO_SLEEP_REASON_POWER_BUTTON, 0);
+ break;
+ case SHORT_PRESS_POWER_REALLY_GO_TO_SLEEP:
+ mPowerManager.goToSleep(eventTime,
+ PowerManager.GO_TO_SLEEP_REASON_POWER_BUTTON,
+ PowerManager.GO_TO_SLEEP_FLAG_NO_DOZE);
+ break;
+ case SHORT_PRESS_POWER_REALLY_GO_TO_SLEEP_AND_GO_HOME:
+ mPowerManager.goToSleep(eventTime,
+ PowerManager.GO_TO_SLEEP_REASON_POWER_BUTTON,
+ PowerManager.GO_TO_SLEEP_FLAG_NO_DOZE);
+ launchHomeFromHotKey();
+ break;
+ }
+ }
+ }
+
+ private void powerMultiPressAction(long eventTime, boolean interactive, int behavior) {
+ switch (behavior) {
+ case MULTI_PRESS_POWER_NOTHING:
+ break;
+ case MULTI_PRESS_POWER_THEATER_MODE:
+ if (isTheaterModeEnabled()) {
+ Slog.i(TAG, "Toggling theater mode off.");
+ Settings.Global.putInt(mContext.getContentResolver(),
+ Settings.Global.THEATER_MODE_ON, 0);
+ if (!interactive) {
+ wakeUpFromPowerKey(eventTime);
+ }
+ } else {
+ Slog.i(TAG, "Toggling theater mode on.");
+ Settings.Global.putInt(mContext.getContentResolver(),
+ Settings.Global.THEATER_MODE_ON, 1);
+
+ if (mGoToSleepOnButtonPressTheaterMode && interactive) {
+ mPowerManager.goToSleep(eventTime,
+ PowerManager.GO_TO_SLEEP_REASON_POWER_BUTTON, 0);
+ }
+ }
+ break;
+ case MULTI_PRESS_POWER_BRIGHTNESS_BOOST:
+ mPowerManager.boostScreenBrightness(eventTime);
+ break;
+ }
+ }
+
+ private int getMaxMultiPressPowerCount() {
+ if (mTriplePressOnPowerBehavior != MULTI_PRESS_POWER_NOTHING) {
+ return 3;
+ }
+ if (mDoublePressOnPowerBehavior != MULTI_PRESS_POWER_NOTHING) {
+ return 2;
+ }
+ return 1;
+ }
+
+ private void powerLongPress() {
+ final int behavior = getResolvedLongPressOnPowerBehavior();
+ switch (behavior) {
+ case LONG_PRESS_POWER_NOTHING:
+ break;
+ case LONG_PRESS_POWER_GLOBAL_ACTIONS:
+ mPowerKeyHandled = true;
+ if (!performHapticFeedbackLw(null, HapticFeedbackConstants.LONG_PRESS, false)) {
+ performAuditoryFeedbackForAccessibilityIfNeed();
+ }
+ showGlobalActionsInternal();
+ break;
+ case LONG_PRESS_POWER_SHUT_OFF:
+ case LONG_PRESS_POWER_SHUT_OFF_NO_CONFIRM:
+ mPowerKeyHandled = true;
+ performHapticFeedbackLw(null, HapticFeedbackConstants.LONG_PRESS, false);
+ sendCloseSystemWindows(SYSTEM_DIALOG_REASON_GLOBAL_ACTIONS);
+ mWindowManagerFuncs.shutdown(behavior == LONG_PRESS_POWER_SHUT_OFF);
+ break;
+ }
+ }
+
+ private int getResolvedLongPressOnPowerBehavior() {
+ if (FactoryTest.isLongPressOnPowerOffEnabled()) {
+ return LONG_PRESS_POWER_SHUT_OFF_NO_CONFIRM;
+ }
+ return mLongPressOnPowerBehavior;
+ }
+
+ private boolean hasLongPressOnPowerBehavior() {
+ return getResolvedLongPressOnPowerBehavior() != LONG_PRESS_POWER_NOTHING;
}
private void interceptScreenshotChord() {
if (mScreenshotChordEnabled
- && mVolumeDownKeyTriggered && mPowerKeyTriggered && !mVolumeUpKeyTriggered) {
+ && mScreenshotChordVolumeDownKeyTriggered && mScreenshotChordPowerKeyTriggered
+ && !mScreenshotChordVolumeUpKeyTriggered) {
final long now = SystemClock.uptimeMillis();
- if (now <= mVolumeDownKeyTime + SCREENSHOT_CHORD_DEBOUNCE_DELAY_MILLIS
- && now <= mPowerKeyTime + SCREENSHOT_CHORD_DEBOUNCE_DELAY_MILLIS) {
- mVolumeDownKeyConsumedByScreenshotChord = true;
+ if (now <= mScreenshotChordVolumeDownKeyTime + SCREENSHOT_CHORD_DEBOUNCE_DELAY_MILLIS
+ && now <= mScreenshotChordPowerKeyTime
+ + SCREENSHOT_CHORD_DEBOUNCE_DELAY_MILLIS) {
+ mScreenshotChordVolumeDownKeyConsumed = true;
cancelPendingPowerKeyAction();
mHandler.postDelayed(mScreenshotRunnable, getScreenshotChordLongPressDelay());
@@ -841,64 +1074,14 @@
mHandler.removeCallbacks(mScreenshotRunnable);
}
- private void powerShortPress(long eventTime) {
- if (mShortPressOnPowerBehavior < 0) {
- mShortPressOnPowerBehavior = mContext.getResources().getInteger(
- com.android.internal.R.integer.config_shortPressOnPowerBehavior);
- }
-
- switch (mShortPressOnPowerBehavior) {
- case SHORT_PRESS_POWER_NOTHING:
- break;
- case SHORT_PRESS_POWER_GO_TO_SLEEP:
- mPowerManager.goToSleep(eventTime,
- PowerManager.GO_TO_SLEEP_REASON_POWER_BUTTON, 0);
- break;
- case SHORT_PRESS_POWER_REALLY_GO_TO_SLEEP:
- mPowerManager.goToSleep(eventTime,
- PowerManager.GO_TO_SLEEP_REASON_POWER_BUTTON,
- PowerManager.GO_TO_SLEEP_FLAG_NO_DOZE);
- break;
- case SHORT_PRESS_POWER_REALLY_GO_TO_SLEEP_AND_GO_HOME:
- mPowerManager.goToSleep(eventTime,
- PowerManager.GO_TO_SLEEP_REASON_POWER_BUTTON,
- PowerManager.GO_TO_SLEEP_FLAG_NO_DOZE);
- launchHomeFromHotKey();
- break;
- }
- }
-
- private final Runnable mPowerLongPress = new Runnable() {
+ private final Runnable mEndCallLongPress = new Runnable() {
@Override
public void run() {
- // The context isn't read
- if (mLongPressOnPowerBehavior < 0) {
- mLongPressOnPowerBehavior = mContext.getResources().getInteger(
- com.android.internal.R.integer.config_longPressOnPowerBehavior);
+ mEndCallKeyHandled = true;
+ if (!performHapticFeedbackLw(null, HapticFeedbackConstants.LONG_PRESS, false)) {
+ performAuditoryFeedbackForAccessibilityIfNeed();
}
- int resolvedBehavior = mLongPressOnPowerBehavior;
- if (FactoryTest.isLongPressOnPowerOffEnabled()) {
- resolvedBehavior = LONG_PRESS_POWER_SHUT_OFF_NO_CONFIRM;
- }
-
- switch (resolvedBehavior) {
- case LONG_PRESS_POWER_NOTHING:
- break;
- case LONG_PRESS_POWER_GLOBAL_ACTIONS:
- mPowerKeyHandled = true;
- if (!performHapticFeedbackLw(null, HapticFeedbackConstants.LONG_PRESS, false)) {
- performAuditoryFeedbackForAccessibilityIfNeed();
- }
- showGlobalActionsInternal();
- break;
- case LONG_PRESS_POWER_SHUT_OFF:
- case LONG_PRESS_POWER_SHUT_OFF_NO_CONFIRM:
- mPowerKeyHandled = true;
- performHapticFeedbackLw(null, HapticFeedbackConstants.LONG_PRESS, false);
- sendCloseSystemWindows(SYSTEM_DIALOG_REASON_GLOBAL_ACTIONS);
- mWindowManagerFuncs.shutdown(resolvedBehavior == LONG_PRESS_POWER_SHUT_OFF);
- break;
- }
+ showGlobalActionsInternal();
}
};
@@ -939,6 +1122,18 @@
Settings.Secure.USER_SETUP_COMPLETE, 0, UserHandle.USER_CURRENT) != 0;
}
+ private void handleShortPressOnHome() {
+ // If there's a dream running then use home to escape the dream
+ // but don't actually go home.
+ if (mDreamManagerInternal != null && mDreamManagerInternal.isDreaming()) {
+ mDreamManagerInternal.stopDream(false /*immediate*/);
+ return;
+ }
+
+ // Go home!
+ launchHomeFromHotKey();
+ }
+
private void handleLongPressOnHome() {
if (mLongPressOnHomeBehavior != LONG_PRESS_HOME_NOTHING) {
mHomeConsumed = true;
@@ -964,7 +1159,7 @@
public void run() {
if (mHomeDoubleTapPending) {
mHomeDoubleTapPending = false;
- launchHomeFromHotKey();
+ handleShortPressOnHome();
}
}
};
@@ -1007,6 +1202,8 @@
mPowerManager = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
mBroadcastWakeLock = mPowerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
"PhoneWindowManager.mBroadcastWakeLock");
+ mPowerKeyWakeLock = mPowerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
+ "PhoneWindowManager.mPowerKeyWakeLock");
mEnableShiftMenuBugReports = "1".equals(SystemProperties.get("ro.debuggable"));
mSupportAutoRotation = mContext.getResources().getBoolean(
com.android.internal.R.bool.config_supportAutoRotation);
@@ -1045,6 +1242,18 @@
mAllowTheaterModeWakeFromWakeGesture = mContext.getResources().getBoolean(
com.android.internal.R.bool.config_allowTheaterModeWakeFromGesture);
+ mGoToSleepOnButtonPressTheaterMode = mContext.getResources().getBoolean(
+ com.android.internal.R.bool.config_goToSleepOnButtonPressTheaterMode);
+
+ mShortPressOnPowerBehavior = mContext.getResources().getInteger(
+ com.android.internal.R.integer.config_shortPressOnPowerBehavior);
+ mLongPressOnPowerBehavior = mContext.getResources().getInteger(
+ com.android.internal.R.integer.config_longPressOnPowerBehavior);
+ mDoublePressOnPowerBehavior = mContext.getResources().getInteger(
+ com.android.internal.R.integer.config_doublePressOnPowerBehavior);
+ mTriplePressOnPowerBehavior = mContext.getResources().getInteger(
+ com.android.internal.R.integer.config_triplePressOnPowerBehavior);
+
readConfigurationDependentBehaviors();
mAccessibilityManager = (AccessibilityManager) context.getSystemService(
@@ -1899,11 +2108,8 @@
/** {@inheritDoc} */
@Override
public void removeStartingWindow(IBinder appToken, View window) {
- if (DEBUG_STARTING_WINDOW) {
- RuntimeException e = new RuntimeException("here");
- e.fillInStackTrace();
- Log.v(TAG, "Removing starting window for " + appToken + ": " + window, e);
- }
+ if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Removing starting window for " + appToken + ": "
+ + window + " Callers=" + Debug.getCallers(4));
if (window != null) {
WindowManager wm = (WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE);
@@ -2099,24 +2305,19 @@
boolean goingToNotificationShade) {
if (goingToNotificationShade) {
return AnimationUtils.loadAnimation(mContext, R.anim.lock_screen_behind_enter_fade_in);
- } else if (onWallpaper) {
- Animation a = AnimationUtils.loadAnimation(mContext,
- R.anim.lock_screen_behind_enter_wallpaper);
- AnimationSet set = (AnimationSet) a;
-
- // TODO: Use XML interpolators when we have log interpolators available in XML.
- set.getAnimations().get(0).setInterpolator(mLogDecelerateInterpolator);
- set.getAnimations().get(1).setInterpolator(mLogDecelerateInterpolator);
- return set;
- } else {
- Animation a = AnimationUtils.loadAnimation(mContext,
- R.anim.lock_screen_behind_enter);
- AnimationSet set = (AnimationSet) a;
-
- // TODO: Use XML interpolators when we have log interpolators available in XML.
- set.getAnimations().get(0).setInterpolator(mLogDecelerateInterpolator);
- return set;
}
+
+ AnimationSet set = (AnimationSet) AnimationUtils.loadAnimation(mContext, onWallpaper ?
+ R.anim.lock_screen_behind_enter_wallpaper :
+ R.anim.lock_screen_behind_enter);
+
+ // TODO: Use XML interpolators when we have log interpolators available in XML.
+ final List<Animation> animations = set.getAnimations();
+ for (int i = animations.size() - 1; i >= 0; --i) {
+ animations.get(i).setInterpolator(mLogDecelerateInterpolator);
+ }
+
+ return set;
}
@@ -2188,17 +2389,18 @@
// but we're not sure, then tell the dispatcher to wait a little while and
// try again later before dispatching.
if (mScreenshotChordEnabled && (flags & KeyEvent.FLAG_FALLBACK) == 0) {
- if (mVolumeDownKeyTriggered && !mPowerKeyTriggered) {
+ if (mScreenshotChordVolumeDownKeyTriggered && !mScreenshotChordPowerKeyTriggered) {
final long now = SystemClock.uptimeMillis();
- final long timeoutTime = mVolumeDownKeyTime + SCREENSHOT_CHORD_DEBOUNCE_DELAY_MILLIS;
+ final long timeoutTime = mScreenshotChordVolumeDownKeyTime
+ + SCREENSHOT_CHORD_DEBOUNCE_DELAY_MILLIS;
if (now < timeoutTime) {
return timeoutTime - now;
}
}
if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN
- && mVolumeDownKeyConsumedByScreenshotChord) {
+ && mScreenshotChordVolumeDownKeyConsumed) {
if (!down) {
- mVolumeDownKeyConsumedByScreenshotChord = false;
+ mScreenshotChordVolumeDownKeyConsumed = false;
}
return -1;
}
@@ -2241,15 +2443,7 @@
return -1;
}
- // If there's a dream running then use home to escape the dream
- // but don't actually go home.
- if (mDreamManagerInternal != null && mDreamManagerInternal.isDreaming()) {
- mDreamManagerInternal.stopDream(false /*immediate*/);
- return -1;
- }
-
- // Go home!
- launchHomeFromHotKey();
+ handleShortPressOnHome();
return -1;
}
@@ -2523,7 +2717,8 @@
return -1;
}
- if (mGlobalKeyManager.handleGlobalKey(mContext, keyCode, event)) {
+ if (isValidGlobalKey(keyCode)
+ && mGlobalKeyManager.handleGlobalKey(mContext, keyCode, event)) {
return -1;
}
@@ -4289,10 +4484,10 @@
// If the key would be handled globally, just return the result, don't worry about special
// key processing.
- if (mGlobalKeyManager.shouldHandleGlobalKey(keyCode, event)) {
+ if (isValidGlobalKey(keyCode)
+ && mGlobalKeyManager.shouldHandleGlobalKey(keyCode, event)) {
if (isWakeKey) {
- wakeUp(event.getEventTime(), keyCode == KeyEvent.KEYCODE_POWER
- ? mAllowTheaterModeWakeFromPowerKey : mAllowTheaterModeWakeFromKey);
+ wakeUp(event.getEventTime(), mAllowTheaterModeWakeFromKey);
}
return result;
}
@@ -4308,28 +4503,28 @@
case KeyEvent.KEYCODE_VOLUME_MUTE: {
if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN) {
if (down) {
- if (interactive && !mVolumeDownKeyTriggered
+ if (interactive && !mScreenshotChordVolumeDownKeyTriggered
&& (event.getFlags() & KeyEvent.FLAG_FALLBACK) == 0) {
- mVolumeDownKeyTriggered = true;
- mVolumeDownKeyTime = event.getDownTime();
- mVolumeDownKeyConsumedByScreenshotChord = false;
+ mScreenshotChordVolumeDownKeyTriggered = true;
+ mScreenshotChordVolumeDownKeyTime = event.getDownTime();
+ mScreenshotChordVolumeDownKeyConsumed = false;
cancelPendingPowerKeyAction();
interceptScreenshotChord();
}
} else {
- mVolumeDownKeyTriggered = false;
+ mScreenshotChordVolumeDownKeyTriggered = false;
cancelPendingScreenshotChordAction();
}
} else if (keyCode == KeyEvent.KEYCODE_VOLUME_UP) {
if (down) {
- if (interactive && !mVolumeUpKeyTriggered
+ if (interactive && !mScreenshotChordVolumeUpKeyTriggered
&& (event.getFlags() & KeyEvent.FLAG_FALLBACK) == 0) {
- mVolumeUpKeyTriggered = true;
+ mScreenshotChordVolumeUpKeyTriggered = true;
cancelPendingPowerKeyAction();
cancelPendingScreenshotChordAction();
}
} else {
- mVolumeUpKeyTriggered = false;
+ mScreenshotChordVolumeUpKeyTriggered = false;
cancelPendingScreenshotChordAction();
}
}
@@ -4386,20 +4581,29 @@
if (telecomManager != null) {
hungUp = telecomManager.endCall();
}
- interceptPowerKeyDown(!interactive || hungUp);
+ if (interactive && !hungUp) {
+ mEndCallKeyHandled = false;
+ mHandler.postDelayed(mEndCallLongPress,
+ ViewConfiguration.get(mContext).getDeviceGlobalActionKeyTimeout());
+ } else {
+ mEndCallKeyHandled = true;
+ }
} else {
- if (interceptPowerKeyUp(canceled)) {
- if ((mEndcallBehavior
- & Settings.System.END_BUTTON_BEHAVIOR_HOME) != 0) {
- if (goHome()) {
- break;
+ if (!mEndCallKeyHandled) {
+ mHandler.removeCallbacks(mEndCallLongPress);
+ if (!canceled) {
+ if ((mEndcallBehavior
+ & Settings.System.END_BUTTON_BEHAVIOR_HOME) != 0) {
+ if (goHome()) {
+ break;
+ }
}
- }
- if ((mEndcallBehavior
- & Settings.System.END_BUTTON_BEHAVIOR_SLEEP) != 0) {
- mPowerManager.goToSleep(event.getEventTime(),
- PowerManager.GO_TO_SLEEP_REASON_POWER_BUTTON, 0);
- isWakeKey = false;
+ if ((mEndcallBehavior
+ & Settings.System.END_BUTTON_BEHAVIOR_SLEEP) != 0) {
+ mPowerManager.goToSleep(event.getEventTime(),
+ PowerManager.GO_TO_SLEEP_REASON_POWER_BUTTON, 0);
+ isWakeKey = false;
+ }
}
}
}
@@ -4408,49 +4612,11 @@
case KeyEvent.KEYCODE_POWER: {
result &= ~ACTION_PASS_TO_USER;
+ isWakeKey = false; // wake-up will be handled separately
if (down) {
- boolean panic = mImmersiveModeConfirmation.onPowerKeyDown(interactive,
- event.getDownTime(), isImmersiveMode(mLastSystemUiFlags));
- if (panic) {
- mHandler.post(mRequestTransientNav);
- }
- if (interactive && !mPowerKeyTriggered
- && (event.getFlags() & KeyEvent.FLAG_FALLBACK) == 0) {
- mPowerKeyTriggered = true;
- mPowerKeyTime = event.getDownTime();
- interceptScreenshotChord();
- }
-
- TelecomManager telecomManager = getTelecommService();
- boolean hungUp = false;
- if (telecomManager != null) {
- if (telecomManager.isRinging()) {
- // Pressing Power while there's a ringing incoming
- // call should silence the ringer.
- telecomManager.silenceRinger();
- } else if ((mIncallPowerBehavior
- & Settings.Secure.INCALL_POWER_BUTTON_BEHAVIOR_HANGUP) != 0
- && telecomManager.isInCall() && interactive) {
- // Otherwise, if "Power button ends call" is enabled,
- // the Power button will hang up any current active call.
- hungUp = telecomManager.endCall();
- }
- }
- interceptPowerKeyDown(!interactive || hungUp
- || mVolumeDownKeyTriggered || mVolumeUpKeyTriggered);
+ interceptPowerKeyDown(event, interactive);
} else {
- mPowerKeyTriggered = false;
- cancelPendingScreenshotChordAction();
- if (interceptPowerKeyUp(canceled || mPendingPowerKeyUpCanceled)) {
- if (mScreenOnEarly && !mScreenOnFully) {
- Slog.i(TAG, "Suppressed redundant power key press while "
- + "already in the process of turning the screen on.");
- } else {
- powerShortPress(event.getEventTime());
- }
- isWakeKey = false;
- }
- mPendingPowerKeyUpCanceled = false;
+ interceptPowerKeyUp(event, interactive, canceled);
}
break;
}
@@ -4541,14 +4707,29 @@
}
if (isWakeKey) {
- wakeUp(event.getEventTime(), keyCode == KeyEvent.KEYCODE_POWER
- ? mAllowTheaterModeWakeFromPowerKey : mAllowTheaterModeWakeFromKey);
+ wakeUp(event.getEventTime(), mAllowTheaterModeWakeFromKey);
}
return result;
}
/**
+ * Returns true if the key can have global actions attached to it.
+ * We reserve all power management keys for the system since they require
+ * very careful handling.
+ */
+ private static boolean isValidGlobalKey(int keyCode) {
+ switch (keyCode) {
+ case KeyEvent.KEYCODE_POWER:
+ case KeyEvent.KEYCODE_WAKEUP:
+ case KeyEvent.KEYCODE_SLEEP:
+ return false;
+ default:
+ return true;
+ }
+ }
+
+ /**
* When the screen is off we ignore some keys that might otherwise typically
* be considered wake keys. We filter them out here.
*
@@ -4587,18 +4768,39 @@
@Override
public int interceptMotionBeforeQueueingNonInteractive(long whenNanos, int policyFlags) {
if ((policyFlags & FLAG_WAKE) != 0) {
- wakeUp(whenNanos / 1000000, mAllowTheaterModeWakeFromMotion);
- return 0;
+ if (wakeUp(whenNanos / 1000000, mAllowTheaterModeWakeFromMotion)) {
+ return 0;
+ }
}
+
if (shouldDispatchInputWhenNonInteractive()) {
return ACTION_PASS_TO_USER;
}
+
return 0;
}
private boolean shouldDispatchInputWhenNonInteractive() {
- return keyguardIsShowingTq() && mDisplay != null &&
- mDisplay.getState() != Display.STATE_OFF;
+ // Send events to keyguard while the screen is on.
+ if (keyguardIsShowingTq() && mDisplay != null && mDisplay.getState() != Display.STATE_OFF) {
+ return true;
+ }
+
+ // Send events to a dozing dream even if the screen is off since the dream
+ // is in control of the state of the screen.
+ IDreamManager dreamManager = getDreamManager();
+
+ try {
+ if (dreamManager != null && dreamManager.isDreaming()) {
+ return true;
+ }
+ } catch (RemoteException e) {
+ Slog.e(TAG, "RemoteException when checking if dreaming", e);
+ }
+
+ // Otherwise, consume events since the user can't see what is being
+ // interacted with.
+ return false;
}
void dispatchMediaKeyWithWakeLock(KeyEvent event) {
@@ -4765,12 +4967,17 @@
}
}
- private void wakeUp(long wakeTime, boolean wakeInTheaterMode) {
+ private void wakeUpFromPowerKey(long eventTime) {
+ wakeUp(eventTime, mAllowTheaterModeWakeFromPowerKey);
+ }
+
+ private boolean wakeUp(long wakeTime, boolean wakeInTheaterMode) {
if (!wakeInTheaterMode && isTheaterModeEnabled()) {
- return;
+ return false;
}
mPowerManager.wakeUp(wakeTime);
+ return true;
}
// Called on the PowerManager's Notifier thread.
@@ -4981,6 +5188,7 @@
@Override
public void dismissKeyguardLw() {
if (mKeyguardDelegate != null && mKeyguardDelegate.isShowing()) {
+ if (DEBUG_KEYGUARD) Slog.d(TAG, "PWM.dismissKeyguardLw");
mHandler.post(new Runnable() {
@Override
public void run() {
@@ -5012,6 +5220,7 @@
@Override
public void startKeyguardExitAnimation(long startTime, long fadeoutDuration) {
if (mKeyguardDelegate != null) {
+ if (DEBUG_KEYGUARD) Slog.d(TAG, "PWM.startKeyguardExitAnimation");
mKeyguardDelegate.startKeyguardExitAnimation(startTime, fadeoutDuration);
}
}
@@ -5734,7 +5943,8 @@
private int updateSystemUiVisibilityLw() {
// If there is no window focused, there will be nobody to handle the events
// anyway, so just hang on in whatever state we're in until things settle down.
- WindowState win = mFocusedWindow != null ? mFocusedWindow : mTopFullscreenOpaqueWindowState;
+ final WindowState win = mFocusedWindow != null ? mFocusedWindow
+ : mTopFullscreenOpaqueWindowState;
if (win == null) {
return 0;
}
@@ -5770,7 +5980,7 @@
try {
IStatusBarService statusbar = getStatusBarService();
if (statusbar != null) {
- statusbar.setSystemUiVisibility(visibility, 0xffffffff);
+ statusbar.setSystemUiVisibility(visibility, 0xffffffff, win.toString());
statusbar.topAppWindowChanged(needsMenu);
}
} catch (RemoteException e) {
@@ -5983,6 +6193,9 @@
pw.print(prefix);
pw.print("mShortPressOnPowerBehavior="); pw.print(mShortPressOnPowerBehavior);
pw.print(" mLongPressOnPowerBehavior="); pw.println(mLongPressOnPowerBehavior);
+ pw.print(prefix);
+ pw.print("mDoublePressOnPowerBehavior="); pw.print(mDoublePressOnPowerBehavior);
+ pw.print(" mTriplePressOnPowerBehavior="); pw.println(mTriplePressOnPowerBehavior);
pw.print(prefix); pw.print("mHasSoftInput="); pw.println(mHasSoftInput);
pw.print(prefix); pw.print("mAwake="); pw.println(mAwake);
pw.print(prefix); pw.print("mScreenOnEarly="); pw.print(mScreenOnEarly);
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index bf67461..a2d246d 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -3701,12 +3701,11 @@
private void updateCapabilities(NetworkAgentInfo networkAgent,
NetworkCapabilities networkCapabilities) {
- // TODO - turn this on in MR1 when we have more dogfooding time.
- // rematchAllNetworksAndRequests();
if (!Objects.equals(networkAgent.networkCapabilities, networkCapabilities)) {
synchronized (networkAgent) {
networkAgent.networkCapabilities = networkCapabilities;
}
+ rematchAllNetworksAndRequests(networkAgent, networkAgent.getCurrentScore());
notifyNetworkCallbacks(networkAgent, ConnectivityManager.CALLBACK_CAP_CHANGED);
}
}
diff --git a/services/core/java/com/android/server/InputMethodManagerService.java b/services/core/java/com/android/server/InputMethodManagerService.java
index 1623eac..edea274 100644
--- a/services/core/java/com/android/server/InputMethodManagerService.java
+++ b/services/core/java/com/android/server/InputMethodManagerService.java
@@ -774,7 +774,11 @@
if (defIm == null && mMethodList.size() > 0) {
defIm = InputMethodUtils.getMostApplicableDefaultIME(
mSettings.getEnabledInputMethodListLocked());
- Slog.i(TAG, "No default found, using " + defIm.getId());
+ if (defIm != null) {
+ Slog.i(TAG, "Default found, using " + defIm.getId());
+ } else {
+ Slog.i(TAG, "No default found");
+ }
}
if (defIm != null) {
setSelectedInputMethodAndSubtypeLocked(defIm, NOT_A_SUBTYPE_ID, false);
diff --git a/services/core/java/com/android/server/LockSettingsService.java b/services/core/java/com/android/server/LockSettingsService.java
index b708c3f..11ba8e8 100644
--- a/services/core/java/com/android/server/LockSettingsService.java
+++ b/services/core/java/com/android/server/LockSettingsService.java
@@ -18,49 +18,38 @@
import android.content.BroadcastReceiver;
import android.content.ContentResolver;
-import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.content.pm.UserInfo;
+import static android.Manifest.permission.ACCESS_KEYGUARD_SECURE_STORAGE;
import static android.content.Context.USER_SERVICE;
import static android.Manifest.permission.READ_PROFILE;
-import android.database.Cursor;
+
import android.database.sqlite.SQLiteDatabase;
-import android.database.sqlite.SQLiteOpenHelper;
-import android.database.sqlite.SQLiteStatement;
import android.os.Binder;
-import android.os.Environment;
import android.os.IBinder;
import android.os.Process;
import android.os.RemoteException;
import android.os.storage.IMountService;
import android.os.ServiceManager;
-import android.os.storage.StorageManager;
import android.os.SystemProperties;
import android.os.UserHandle;
import android.os.UserManager;
import android.provider.Settings;
import android.provider.Settings.Secure;
import android.provider.Settings.SettingNotFoundException;
-import android.security.KeyChain;
-import android.security.KeyChain.KeyChainConnection;
import android.security.KeyStore;
import android.text.TextUtils;
import android.util.Log;
import android.util.Slog;
-import com.android.internal.os.BackgroundThread;
import com.android.internal.widget.ILockSettings;
import com.android.internal.widget.ILockSettingsObserver;
import com.android.internal.widget.LockPatternUtils;
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.RandomAccessFile;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@@ -73,27 +62,17 @@
*/
public class LockSettingsService extends ILockSettings.Stub {
- private static final String PERMISSION = "android.permission.ACCESS_KEYGUARD_SECURE_STORAGE";
+ private static final String PERMISSION = ACCESS_KEYGUARD_SECURE_STORAGE;
private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
- private final DatabaseHelper mOpenHelper;
+
private static final String TAG = "LockSettingsService";
- private static final String TABLE = "locksettings";
- private static final String COLUMN_KEY = "name";
- private static final String COLUMN_USERID = "user";
- private static final String COLUMN_VALUE = "value";
-
- private static final String[] COLUMNS_FOR_QUERY = {
- COLUMN_VALUE
- };
-
- private static final String SYSTEM_DIRECTORY = "/system/";
- private static final String LOCK_PATTERN_FILE = "gesture.key";
- private static final String LOCK_PASSWORD_FILE = "password.key";
-
private final Context mContext;
+
+ private final LockSettingsStorage mStorage;
+
private LockPatternUtils mLockPatternUtils;
private boolean mFirstCallToVold;
@@ -102,7 +81,6 @@
public LockSettingsService(Context context) {
mContext = context;
// Open the database
- mOpenHelper = new DatabaseHelper(mContext);
mLockPatternUtils = new LockPatternUtils(context);
mFirstCallToVold = true;
@@ -110,6 +88,18 @@
IntentFilter filter = new IntentFilter();
filter.addAction(Intent.ACTION_USER_ADDED);
mContext.registerReceiverAsUser(mBroadcastReceiver, UserHandle.ALL, filter, null, null);
+
+ mStorage = new LockSettingsStorage(context, new LockSettingsStorage.Callback() {
+ @Override
+ public void initialize(SQLiteDatabase db) {
+ // Get the lockscreen default from a system property, if available
+ boolean lockScreenDisable = SystemProperties.getBoolean(
+ "ro.lockscreen.disable.default", false);
+ if (lockScreenDisable) {
+ mStorage.writeKeyValue(db, LockPatternUtils.DISABLE_LOCKSCREEN_KEY, "1", 0);
+ }
+ }
+ });
}
private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
@@ -220,29 +210,31 @@
@Override
public void setBoolean(String key, boolean value, int userId) throws RemoteException {
checkWritePermission(userId);
-
- writeToDb(key, value ? "1" : "0", userId);
+ setStringUnchecked(key, userId, value ? "1" : "0");
}
@Override
public void setLong(String key, long value, int userId) throws RemoteException {
checkWritePermission(userId);
-
- writeToDb(key, Long.toString(value), userId);
+ setStringUnchecked(key, userId, Long.toString(value));
}
@Override
public void setString(String key, String value, int userId) throws RemoteException {
checkWritePermission(userId);
+ setStringUnchecked(key, userId, value);
+ }
- writeToDb(key, value, userId);
+ private void setStringUnchecked(String key, int userId, String value) {
+ mStorage.writeKeyValue(key, value, userId);
+ notifyObservers(key, userId);
}
@Override
public boolean getBoolean(String key, boolean defaultValue, int userId) throws RemoteException {
checkReadPermission(key, userId);
- String value = readFromDb(key, null, userId);
+ String value = mStorage.readKeyValue(key, null, userId);
return TextUtils.isEmpty(value) ?
defaultValue : (value.equals("1") || value.equals("true"));
}
@@ -251,7 +243,7 @@
public long getLong(String key, long defaultValue, int userId) throws RemoteException {
checkReadPermission(key, userId);
- String value = readFromDb(key, null, userId);
+ String value = mStorage.readKeyValue(key, null, userId);
return TextUtils.isEmpty(value) ? defaultValue : Long.parseLong(value);
}
@@ -259,7 +251,7 @@
public String getString(String key, String defaultValue, int userId) throws RemoteException {
checkReadPermission(key, userId);
- return readFromDb(key, defaultValue, userId);
+ return mStorage.readKeyValue(key, defaultValue, userId);
}
@Override
@@ -308,57 +300,18 @@
}
}
- private int getUserParentOrSelfId(int userId) {
- if (userId != 0) {
- final UserManager um = (UserManager) mContext.getSystemService(USER_SERVICE);
- final UserInfo pi = um.getProfileParent(userId);
- if (pi != null) {
- return pi.id;
- }
- }
- return userId;
- }
-
- private String getLockPatternFilename(int userId) {
- String dataSystemDirectory =
- android.os.Environment.getDataDirectory().getAbsolutePath() +
- SYSTEM_DIRECTORY;
- userId = getUserParentOrSelfId(userId);
- if (userId == 0) {
- // Leave it in the same place for user 0
- return dataSystemDirectory + LOCK_PATTERN_FILE;
- } else {
- return new File(Environment.getUserSystemDirectory(userId), LOCK_PATTERN_FILE)
- .getAbsolutePath();
- }
- }
-
- private String getLockPasswordFilename(int userId) {
- userId = getUserParentOrSelfId(userId);
- String dataSystemDirectory =
- android.os.Environment.getDataDirectory().getAbsolutePath() +
- SYSTEM_DIRECTORY;
- if (userId == 0) {
- // Leave it in the same place for user 0
- return dataSystemDirectory + LOCK_PASSWORD_FILE;
- } else {
- return new File(Environment.getUserSystemDirectory(userId), LOCK_PASSWORD_FILE)
- .getAbsolutePath();
- }
- }
-
@Override
public boolean havePassword(int userId) throws RemoteException {
// Do we need a permissions check here?
- return new File(getLockPasswordFilename(userId)).length() > 0;
+ return mStorage.hasPassword(userId);
}
@Override
public boolean havePattern(int userId) throws RemoteException {
// Do we need a permissions check here?
- return new File(getLockPatternFilename(userId)).length() > 0;
+ return mStorage.hasPattern(userId);
}
private void maybeUpdateKeystore(String password, int userHandle) {
@@ -394,7 +347,7 @@
final byte[] hash = LockPatternUtils.patternToHash(
LockPatternUtils.stringToPattern(pattern));
- writeFile(getLockPatternFilename(userId), hash);
+ mStorage.writePatternHash(hash, userId);
}
@Override
@@ -403,68 +356,46 @@
maybeUpdateKeystore(password, userId);
- writeFile(getLockPasswordFilename(userId),
- mLockPatternUtils.passwordToHash(password, userId));
+ mStorage.writePasswordHash(mLockPatternUtils.passwordToHash(password, userId), userId);
}
@Override
public boolean checkPattern(String pattern, int userId) throws RemoteException {
checkPasswordReadPermission(userId);
- try {
- // Read all the bytes from the file
- RandomAccessFile raf = new RandomAccessFile(getLockPatternFilename(userId), "r");
- final byte[] stored = new byte[(int) raf.length()];
- int got = raf.read(stored, 0, stored.length);
- raf.close();
- if (got <= 0) {
- return true;
- }
- // Compare the hash from the file with the entered pattern's hash
- final byte[] hash = LockPatternUtils.patternToHash(
- LockPatternUtils.stringToPattern(pattern));
- final boolean matched = Arrays.equals(stored, hash);
- if (matched && !TextUtils.isEmpty(pattern)) {
- maybeUpdateKeystore(pattern, userId);
- }
- return matched;
- } catch (FileNotFoundException fnfe) {
- Slog.e(TAG, "Cannot read file " + fnfe);
- } catch (IOException ioe) {
- Slog.e(TAG, "Cannot read file " + ioe);
+ byte[] hash = LockPatternUtils.patternToHash(LockPatternUtils.stringToPattern(pattern));
+ byte[] storedHash = mStorage.readPatternHash(userId);
+
+ if (storedHash == null) {
+ return true;
}
- return true;
+
+ boolean matched = Arrays.equals(hash, storedHash);
+ if (matched && !TextUtils.isEmpty(pattern)) {
+ maybeUpdateKeystore(pattern, userId);
+ }
+ return matched;
}
@Override
public boolean checkPassword(String password, int userId) throws RemoteException {
checkPasswordReadPermission(userId);
- try {
- // Read all the bytes from the file
- RandomAccessFile raf = new RandomAccessFile(getLockPasswordFilename(userId), "r");
- final byte[] stored = new byte[(int) raf.length()];
- int got = raf.read(stored, 0, stored.length);
- raf.close();
- if (got <= 0) {
- return true;
- }
- // Compare the hash from the file with the entered password's hash
- final byte[] hash = mLockPatternUtils.passwordToHash(password, userId);
- final boolean matched = Arrays.equals(stored, hash);
- if (matched && !TextUtils.isEmpty(password)) {
- maybeUpdateKeystore(password, userId);
- }
- return matched;
- } catch (FileNotFoundException fnfe) {
- Slog.e(TAG, "Cannot read file " + fnfe);
- } catch (IOException ioe) {
- Slog.e(TAG, "Cannot read file " + ioe);
+ byte[] hash = mLockPatternUtils.passwordToHash(password, userId);
+ byte[] storedHash = mStorage.readPasswordHash(userId);
+
+ if (storedHash == null) {
+ return true;
}
- return true;
+
+ boolean matched = Arrays.equals(hash, storedHash);
+ if (matched && !TextUtils.isEmpty(password)) {
+ maybeUpdateKeystore(password, userId);
+ }
+ return matched;
}
@Override
- public boolean checkVoldPassword(int userId) throws RemoteException {
+ public boolean checkVoldPassword(int userId) throws RemoteException {
if (!mFirstCallToVold) {
return false;
}
@@ -512,166 +443,14 @@
public void removeUser(int userId) {
checkWritePermission(userId);
- SQLiteDatabase db = mOpenHelper.getWritableDatabase();
- try {
- final UserManager um = (UserManager) mContext.getSystemService(USER_SERVICE);
- final UserInfo parentInfo = um.getProfileParent(userId);
- if (parentInfo == null) {
- // This user owns its lock settings files - safe to delete them
- File file = new File(getLockPasswordFilename(userId));
- if (file.exists()) {
- file.delete();
- }
- file = new File(getLockPatternFilename(userId));
- if (file.exists()) {
- file.delete();
- }
- }
-
- db.beginTransaction();
- db.delete(TABLE, COLUMN_USERID + "='" + userId + "'", null);
- db.setTransactionSuccessful();
- } finally {
- db.endTransaction();
- }
+ mStorage.removeUser(userId);
+ notifyObservers(null /* key */, userId);
final KeyStore ks = KeyStore.getInstance();
final int userUid = UserHandle.getUid(userId, Process.SYSTEM_UID);
ks.resetUid(userUid);
}
- private void writeFile(String name, byte[] hash) {
- try {
- // Write the hash to file
- RandomAccessFile raf = new RandomAccessFile(name, "rw");
- // Truncate the file if pattern is null, to clear the lock
- if (hash == null || hash.length == 0) {
- raf.setLength(0);
- } else {
- raf.write(hash, 0, hash.length);
- }
- raf.close();
- } catch (IOException ioe) {
- Slog.e(TAG, "Error writing to file " + ioe);
- }
- }
-
- private void writeToDb(String key, String value, int userId) {
- writeToDb(mOpenHelper.getWritableDatabase(), key, value, userId);
- notifyObservers(key, userId);
- }
-
- private void writeToDb(SQLiteDatabase db, String key, String value, int userId) {
- ContentValues cv = new ContentValues();
- cv.put(COLUMN_KEY, key);
- cv.put(COLUMN_USERID, userId);
- cv.put(COLUMN_VALUE, value);
-
- db.beginTransaction();
- try {
- db.delete(TABLE, COLUMN_KEY + "=? AND " + COLUMN_USERID + "=?",
- new String[] {key, Integer.toString(userId)});
- db.insert(TABLE, null, cv);
- db.setTransactionSuccessful();
- } finally {
- db.endTransaction();
- }
- }
-
- private String readFromDb(String key, String defaultValue, int userId) {
- Cursor cursor;
- String result = defaultValue;
- SQLiteDatabase db = mOpenHelper.getReadableDatabase();
- if ((cursor = db.query(TABLE, COLUMNS_FOR_QUERY,
- COLUMN_USERID + "=? AND " + COLUMN_KEY + "=?",
- new String[] { Integer.toString(userId), key },
- null, null, null)) != null) {
- if (cursor.moveToFirst()) {
- result = cursor.getString(0);
- }
- cursor.close();
- }
- return result;
- }
-
- class DatabaseHelper extends SQLiteOpenHelper {
- private static final String TAG = "LockSettingsDB";
- private static final String DATABASE_NAME = "locksettings.db";
-
- private static final int DATABASE_VERSION = 2;
-
- public DatabaseHelper(Context context) {
- super(context, DATABASE_NAME, null, DATABASE_VERSION);
- setWriteAheadLoggingEnabled(true);
- }
-
- private void createTable(SQLiteDatabase db) {
- db.execSQL("CREATE TABLE " + TABLE + " (" +
- "_id INTEGER PRIMARY KEY AUTOINCREMENT," +
- COLUMN_KEY + " TEXT," +
- COLUMN_USERID + " INTEGER," +
- COLUMN_VALUE + " TEXT" +
- ");");
- }
-
- @Override
- public void onCreate(SQLiteDatabase db) {
- createTable(db);
- initializeDefaults(db);
- }
-
- private void initializeDefaults(SQLiteDatabase db) {
- // Get the lockscreen default from a system property, if available
- boolean lockScreenDisable = SystemProperties.getBoolean("ro.lockscreen.disable.default",
- false);
- if (lockScreenDisable) {
- writeToDb(db, LockPatternUtils.DISABLE_LOCKSCREEN_KEY, "1", 0);
- }
- }
-
- @Override
- public void onUpgrade(SQLiteDatabase db, int oldVersion, int currentVersion) {
- int upgradeVersion = oldVersion;
- if (upgradeVersion == 1) {
- // Set the initial value for {@link LockPatternUtils#LOCKSCREEN_WIDGETS_ENABLED}
- // during upgrade based on whether each user previously had widgets in keyguard.
- maybeEnableWidgetSettingForUsers(db);
- upgradeVersion = 2;
- }
-
- if (upgradeVersion != DATABASE_VERSION) {
- Log.w(TAG, "Failed to upgrade database!");
- }
- }
-
- private void maybeEnableWidgetSettingForUsers(SQLiteDatabase db) {
- final UserManager um = (UserManager) mContext.getSystemService(USER_SERVICE);
- final ContentResolver cr = mContext.getContentResolver();
- final List<UserInfo> users = um.getUsers();
- for (int i = 0; i < users.size(); i++) {
- final int userId = users.get(i).id;
- final boolean enabled = mLockPatternUtils.hasWidgetsEnabledInKeyguard(userId);
- Log.v(TAG, "Widget upgrade uid=" + userId + ", enabled="
- + enabled + ", w[]=" + mLockPatternUtils.getAppWidgets());
- loadSetting(db, LockPatternUtils.LOCKSCREEN_WIDGETS_ENABLED, userId, enabled);
- }
- }
-
- private void loadSetting(SQLiteDatabase db, String key, int userId, boolean value) {
- SQLiteStatement stmt = null;
- try {
- stmt = db.compileStatement(
- "INSERT OR REPLACE INTO locksettings(name,user,value) VALUES(?,?,?);");
- stmt.bindString(1, key);
- stmt.bindLong(2, userId);
- stmt.bindLong(3, value ? 1 : 0);
- stmt.execute();
- } finally {
- if (stmt != null) stmt.close();
- }
- }
- }
-
private static final String[] VALID_SETTINGS = new String[] {
LockPatternUtils.LOCKOUT_PERMANENT_KEY,
LockPatternUtils.LOCKOUT_ATTEMPT_DEADLINE,
diff --git a/services/core/java/com/android/server/LockSettingsStorage.java b/services/core/java/com/android/server/LockSettingsStorage.java
new file mode 100644
index 0000000..acbf8ef
--- /dev/null
+++ b/services/core/java/com/android/server/LockSettingsStorage.java
@@ -0,0 +1,307 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server;
+
+import android.content.ContentValues;
+import android.content.Context;
+import android.content.pm.UserInfo;
+import android.database.Cursor;
+import android.database.sqlite.SQLiteDatabase;
+import android.database.sqlite.SQLiteOpenHelper;
+import android.os.Environment;
+import android.os.UserManager;
+import android.util.ArrayMap;
+import android.util.Log;
+import android.util.Slog;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.RandomAccessFile;
+
+import static android.content.Context.USER_SERVICE;
+
+/**
+ * Storage for the lock settings service.
+ */
+class LockSettingsStorage {
+
+ private static final String TAG = "LockSettingsStorage";
+ private static final String TABLE = "locksettings";
+
+ private static final String COLUMN_KEY = "name";
+ private static final String COLUMN_USERID = "user";
+ private static final String COLUMN_VALUE = "value";
+
+ private static final String[] COLUMNS_FOR_QUERY = {
+ COLUMN_VALUE
+ };
+
+ private static final String SYSTEM_DIRECTORY = "/system/";
+ private static final String LOCK_PATTERN_FILE = "gesture.key";
+ private static final String LOCK_PASSWORD_FILE = "password.key";
+
+ private final DatabaseHelper mOpenHelper;
+ private final Context mContext;
+ private final Object mFileWriteLock = new Object();
+
+ LockSettingsStorage(Context context, Callback callback) {
+ mContext = context;
+ mOpenHelper = new DatabaseHelper(context, callback);
+ }
+
+ void writeKeyValue(String key, String value, int userId) {
+ writeKeyValue(mOpenHelper.getWritableDatabase(), key, value, userId);
+ }
+
+ void writeKeyValue(SQLiteDatabase db, String key, String value, int userId) {
+ ContentValues cv = new ContentValues();
+ cv.put(COLUMN_KEY, key);
+ cv.put(COLUMN_USERID, userId);
+ cv.put(COLUMN_VALUE, value);
+
+ db.beginTransaction();
+ try {
+ db.delete(TABLE, COLUMN_KEY + "=? AND " + COLUMN_USERID + "=?",
+ new String[] {key, Integer.toString(userId)});
+ db.insert(TABLE, null, cv);
+ db.setTransactionSuccessful();
+ } finally {
+ db.endTransaction();
+ }
+
+ }
+
+ String readKeyValue(String key, String defaultValue, int userId) {
+ Cursor cursor;
+ String result = defaultValue;
+ SQLiteDatabase db = mOpenHelper.getReadableDatabase();
+ if ((cursor = db.query(TABLE, COLUMNS_FOR_QUERY,
+ COLUMN_USERID + "=? AND " + COLUMN_KEY + "=?",
+ new String[] { Integer.toString(userId), key },
+ null, null, null)) != null) {
+ if (cursor.moveToFirst()) {
+ result = cursor.getString(0);
+ }
+ cursor.close();
+ }
+ return result;
+ }
+
+ byte[] readPasswordHash(int userId) {
+ final byte[] stored = readFile(getLockPasswordFilename(userId), userId);
+ if (stored != null && stored.length > 0) {
+ return stored;
+ }
+ return null;
+ }
+
+ byte[] readPatternHash(int userId) {
+ final byte[] stored = readFile(getLockPatternFilename(userId), userId);
+ if (stored != null && stored.length > 0) {
+ return stored;
+ }
+ return null;
+ }
+
+ boolean hasPassword(int userId) {
+ return hasFile(getLockPasswordFilename(userId), userId);
+ }
+
+ boolean hasPattern(int userId) {
+ return hasFile(getLockPatternFilename(userId), userId);
+ }
+
+ private boolean hasFile(String name, int userId) {
+ byte[] contents = readFile(name, userId);
+ return contents != null && contents.length > 0;
+ }
+
+ private byte[] readFile(String name, int userId) {
+ RandomAccessFile raf = null;
+ byte[] stored = null;
+ try {
+ raf = new RandomAccessFile(name, "r");
+ stored = new byte[(int) raf.length()];
+ raf.readFully(stored, 0, stored.length);
+ raf.close();
+ } catch (IOException e) {
+ Slog.e(TAG, "Cannot read file " + e);
+ } finally {
+ if (raf != null) {
+ try {
+ raf.close();
+ } catch (IOException e) {
+ Slog.e(TAG, "Error closing file " + e);
+ }
+ }
+ }
+ return stored;
+ }
+
+ private void writeFile(String name, byte[] hash, int userId) {
+ synchronized (mFileWriteLock) {
+ RandomAccessFile raf = null;
+ try {
+ // Write the hash to file
+ raf = new RandomAccessFile(name, "rw");
+ // Truncate the file if pattern is null, to clear the lock
+ if (hash == null || hash.length == 0) {
+ raf.setLength(0);
+ } else {
+ raf.write(hash, 0, hash.length);
+ }
+ raf.close();
+ } catch (IOException e) {
+ Slog.e(TAG, "Error writing to file " + e);
+ } finally {
+ if (raf != null) {
+ try {
+ raf.close();
+ } catch (IOException e) {
+ Slog.e(TAG, "Error closing file " + e);
+ }
+ }
+ }
+ }
+ }
+
+ public void writePatternHash(byte[] hash, int userId) {
+ writeFile(getLockPatternFilename(userId), hash, userId);
+ }
+
+ public void writePasswordHash(byte[] hash, int userId) {
+ writeFile(getLockPasswordFilename(userId), hash, userId);
+ }
+
+
+ private String getLockPatternFilename(int userId) {
+ String dataSystemDirectory =
+ android.os.Environment.getDataDirectory().getAbsolutePath() +
+ SYSTEM_DIRECTORY;
+ userId = getUserParentOrSelfId(userId);
+ if (userId == 0) {
+ // Leave it in the same place for user 0
+ return dataSystemDirectory + LOCK_PATTERN_FILE;
+ } else {
+ return new File(Environment.getUserSystemDirectory(userId), LOCK_PATTERN_FILE)
+ .getAbsolutePath();
+ }
+ }
+
+ private String getLockPasswordFilename(int userId) {
+ userId = getUserParentOrSelfId(userId);
+ String dataSystemDirectory =
+ android.os.Environment.getDataDirectory().getAbsolutePath() +
+ SYSTEM_DIRECTORY;
+ if (userId == 0) {
+ // Leave it in the same place for user 0
+ return dataSystemDirectory + LOCK_PASSWORD_FILE;
+ } else {
+ return new File(Environment.getUserSystemDirectory(userId), LOCK_PASSWORD_FILE)
+ .getAbsolutePath();
+ }
+ }
+
+ private int getUserParentOrSelfId(int userId) {
+ if (userId != 0) {
+ final UserManager um = (UserManager) mContext.getSystemService(USER_SERVICE);
+ final UserInfo pi = um.getProfileParent(userId);
+ if (pi != null) {
+ return pi.id;
+ }
+ }
+ return userId;
+ }
+
+
+ public void removeUser(int userId) {
+ SQLiteDatabase db = mOpenHelper.getWritableDatabase();
+
+ final UserManager um = (UserManager) mContext.getSystemService(USER_SERVICE);
+ final UserInfo parentInfo = um.getProfileParent(userId);
+
+ synchronized (mFileWriteLock) {
+ if (parentInfo == null) {
+ // This user owns its lock settings files - safe to delete them
+ File file = new File(getLockPasswordFilename(userId));
+ if (file.exists()) {
+ file.delete();
+ }
+ file = new File(getLockPatternFilename(userId));
+ if (file.exists()) {
+ file.delete();
+ }
+ }
+ }
+
+ try {
+ db.beginTransaction();
+ db.delete(TABLE, COLUMN_USERID + "='" + userId + "'", null);
+ db.setTransactionSuccessful();
+ } finally {
+ db.endTransaction();
+ }
+ }
+
+
+ interface Callback {
+ void initialize(SQLiteDatabase db);
+ }
+
+ class DatabaseHelper extends SQLiteOpenHelper {
+ private static final String TAG = "LockSettingsDB";
+ private static final String DATABASE_NAME = "locksettings.db";
+
+ private static final int DATABASE_VERSION = 2;
+
+ private final Callback mCallback;
+
+ public DatabaseHelper(Context context, Callback callback) {
+ super(context, DATABASE_NAME, null, DATABASE_VERSION);
+ setWriteAheadLoggingEnabled(true);
+ mCallback = callback;
+ }
+
+ private void createTable(SQLiteDatabase db) {
+ db.execSQL("CREATE TABLE " + TABLE + " (" +
+ "_id INTEGER PRIMARY KEY AUTOINCREMENT," +
+ COLUMN_KEY + " TEXT," +
+ COLUMN_USERID + " INTEGER," +
+ COLUMN_VALUE + " TEXT" +
+ ");");
+ }
+
+ @Override
+ public void onCreate(SQLiteDatabase db) {
+ createTable(db);
+ mCallback.initialize(db);
+ }
+
+ @Override
+ public void onUpgrade(SQLiteDatabase db, int oldVersion, int currentVersion) {
+ int upgradeVersion = oldVersion;
+ if (upgradeVersion == 1) {
+ // Previously migrated lock screen widget settings. Now defunct.
+ upgradeVersion = 2;
+ }
+
+ if (upgradeVersion != DATABASE_VERSION) {
+ Log.w(TAG, "Failed to upgrade database!");
+ }
+ }
+ }
+}
diff --git a/services/core/java/com/android/server/NetworkManagementService.java b/services/core/java/com/android/server/NetworkManagementService.java
index d03a154..0f033d71 100644
--- a/services/core/java/com/android/server/NetworkManagementService.java
+++ b/services/core/java/com/android/server/NetworkManagementService.java
@@ -940,6 +940,17 @@
}
@Override
+ public void setInterfaceIpv6NdOffload(String iface, boolean enable) {
+ mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
+ try {
+ mConnector.execute(
+ "interface", "ipv6ndoffload", iface, (enable ? "enable" : "disable"));
+ } catch (NativeDaemonConnectorException e) {
+ throw e.rethrowAsParcelableException();
+ }
+ }
+
+ @Override
public void addRoute(int netId, RouteInfo route) {
modifyRoute("add", "" + netId, route);
}
diff --git a/services/core/java/com/android/server/NetworkScoreService.java b/services/core/java/com/android/server/NetworkScoreService.java
index 395e365..738917f 100644
--- a/services/core/java/com/android/server/NetworkScoreService.java
+++ b/services/core/java/com/android/server/NetworkScoreService.java
@@ -115,10 +115,10 @@
@Override
public boolean clearScores() {
- // Only the active scorer or the system (who can broadcast BROADCAST_SCORE_NETWORKS) should
- // be allowed to flush all scores.
+ // Only the active scorer or the system (who can broadcast BROADCAST_NETWORK_PRIVILEGED)
+ // should be allowed to flush all scores.
if (NetworkScorerAppManager.isCallerActiveScorer(mContext, getCallingUid()) ||
- mContext.checkCallingOrSelfPermission(permission.BROADCAST_SCORE_NETWORKS) ==
+ mContext.checkCallingOrSelfPermission(permission.BROADCAST_NETWORK_PRIVILEGED) ==
PackageManager.PERMISSION_GRANTED) {
clearInternal();
return true;
@@ -130,16 +130,25 @@
@Override
public boolean setActiveScorer(String packageName) {
- mContext.enforceCallingOrSelfPermission(permission.BROADCAST_SCORE_NETWORKS, TAG);
+ // TODO: For now, since SCORE_NETWORKS requires an app to be privileged, we allow such apps
+ // to directly set the scorer app rather than having to use the consent dialog. The
+ // assumption is that anyone bundling a scorer app with the system is trusted by the OEM to
+ // do the right thing and not enable this feature without explaining it to the user.
+ // In the future, should this API be opened to 3p apps, we will need to lock this down and
+ // figure out another way to streamline the UX.
+
+ // mContext.enforceCallingOrSelfPermission(permission.BROADCAST_NETWORK_PRIVILEGED, TAG);
+ mContext.enforceCallingOrSelfPermission(permission.SCORE_NETWORKS, TAG);
+
return setScorerInternal(packageName);
}
@Override
public void disableScoring() {
- // Only the active scorer or the system (who can broadcast BROADCAST_SCORE_NETOWRKS) should
- // be allowed to disable scoring.
+ // Only the active scorer or the system (who can broadcast BROADCAST_NETWORK_PRIVILEGED)
+ // should be allowed to disable scoring.
if (NetworkScorerAppManager.isCallerActiveScorer(mContext, getCallingUid()) ||
- mContext.checkCallingOrSelfPermission(permission.BROADCAST_SCORE_NETWORKS) ==
+ mContext.checkCallingOrSelfPermission(permission.BROADCAST_NETWORK_PRIVILEGED) ==
PackageManager.PERMISSION_GRANTED) {
// The return value is discarded here because at this point, the call should always
// succeed. The only reason for failure is if the new package is not a valid scorer, but
@@ -188,7 +197,7 @@
@Override
public void registerNetworkScoreCache(int networkType, INetworkScoreCache scoreCache) {
- mContext.enforceCallingOrSelfPermission(permission.BROADCAST_SCORE_NETWORKS, TAG);
+ mContext.enforceCallingOrSelfPermission(permission.BROADCAST_NETWORK_PRIVILEGED, TAG);
synchronized (mScoreCaches) {
if (mScoreCaches.containsKey(networkType)) {
throw new IllegalArgumentException(
diff --git a/services/core/java/com/android/server/PersistentDataBlockService.java b/services/core/java/com/android/server/PersistentDataBlockService.java
index 6f378fd..de90aa2 100644
--- a/services/core/java/com/android/server/PersistentDataBlockService.java
+++ b/services/core/java/com/android/server/PersistentDataBlockService.java
@@ -72,7 +72,7 @@
private final String mDataBlockFile;
private final Object mLock = new Object();
- private int mAllowedAppId = -1;
+ private int mAllowedUid = -1;
/*
* Separate lock for OEM unlock related operations as they can happen in parallel with regular
* block operations.
@@ -86,11 +86,11 @@
mContext = context;
mDataBlockFile = SystemProperties.get(PERSISTENT_DATA_BLOCK_PROP);
mBlockDeviceSize = -1; // Load lazily
- mAllowedAppId = getAllowedAppId(UserHandle.USER_OWNER);
+ mAllowedUid = getAllowedUid(UserHandle.USER_OWNER);
}
- private int getAllowedAppId(int userHandle) {
+ private int getAllowedUid(int userHandle) {
String allowedPackage = mContext.getResources()
.getString(R.string.config_persistentDataPackageName);
PackageManager pm = mContext.getPackageManager();
@@ -101,7 +101,7 @@
// not expected
Slog.e(TAG, "not able to find package " + allowedPackage, e);
}
- return UserHandle.getAppId(allowedUid);
+ return allowedUid;
}
@Override
@@ -116,11 +116,17 @@
}
private void enforceUid(int callingUid) {
- if (UserHandle.getAppId(callingUid) != mAllowedAppId) {
+ if (callingUid != mAllowedUid) {
throw new SecurityException("uid " + callingUid + " not allowed to access PST");
}
}
+ private void enforceIsOwner() {
+ if (!Binder.getCallingUserHandle().isOwner()) {
+ throw new SecurityException("Only the Owner is allowed to change OEM unlock state");
+ }
+ }
+
private int getTotalDataSizeLocked(DataInputStream inputStream) throws IOException {
int totalDataSize;
int blockId = inputStream.readInt();
@@ -249,6 +255,7 @@
return;
}
enforceOemUnlockPermission();
+ enforceIsOwner();
FileOutputStream outputStream;
try {
outputStream = new FileOutputStream(new File(mDataBlockFile));
diff --git a/services/core/java/com/android/server/TextServicesManagerService.java b/services/core/java/com/android/server/TextServicesManagerService.java
index d4c436f..5add88e 100644
--- a/services/core/java/com/android/server/TextServicesManagerService.java
+++ b/services/core/java/com/android/server/TextServicesManagerService.java
@@ -16,6 +16,7 @@
package com.android.server;
+import com.android.internal.annotations.GuardedBy;
import com.android.internal.content.PackageMonitor;
import com.android.internal.textservice.ISpellCheckerService;
import com.android.internal.textservice.ISpellCheckerSession;
@@ -28,14 +29,18 @@
import android.app.ActivityManagerNative;
import android.app.AppGlobals;
import android.app.IUserSwitchObserver;
+import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
+import android.content.IntentFilter;
import android.content.ServiceConnection;
+import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.content.pm.ServiceInfo;
+import android.content.pm.UserInfo;
import android.os.Binder;
import android.os.Bundle;
import android.os.IBinder;
@@ -43,6 +48,7 @@
import android.os.Process;
import android.os.RemoteException;
import android.os.UserHandle;
+import android.os.UserManager;
import android.provider.Settings;
import android.service.textservice.SpellCheckerService;
import android.text.TextUtils;
@@ -84,6 +90,12 @@
public TextServicesManagerService(Context context) {
mSystemReady = false;
mContext = context;
+
+ final IntentFilter broadcastFilter = new IntentFilter();
+ broadcastFilter.addAction(Intent.ACTION_USER_ADDED);
+ broadcastFilter.addAction(Intent.ACTION_USER_REMOVED);
+ mContext.registerReceiver(new TextServicesBroadcastReceiver(), broadcastFilter);
+
int userId = UserHandle.USER_OWNER;
try {
ActivityManagerNative.getDefault().registerUserSwitchObserver(
@@ -119,6 +131,7 @@
private void switchUserLocked(int userId) {
mSettings.setCurrentUserId(userId);
+ updateCurrentProfileIds();
unbindServiceLocked();
buildSpellCheckerMapLocked(mContext, mSpellCheckerList, mSpellCheckerMap, mSettings);
SpellCheckerInfo sci = getCurrentSpellChecker(null);
@@ -133,6 +146,16 @@
}
}
+ void updateCurrentProfileIds() {
+ List<UserInfo> profiles =
+ UserManager.get(mContext).getProfiles(mSettings.getCurrentUserId());
+ int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
+ for (int i = 0; i < currentProfileIds.length; i++) {
+ currentProfileIds[i] = profiles.get(i).id;
+ }
+ mSettings.setCurrentProfileIds(currentProfileIds);
+ }
+
private class TextServicesMonitor extends PackageMonitor {
private boolean isChangingPackagesOfCurrentUser() {
final int userId = getChangingUserId();
@@ -171,6 +194,19 @@
}
}
+ class TextServicesBroadcastReceiver extends BroadcastReceiver {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ final String action = intent.getAction();
+ if (Intent.ACTION_USER_ADDED.equals(action)
+ || Intent.ACTION_USER_REMOVED.equals(action)) {
+ updateCurrentProfileIds();
+ return;
+ }
+ Slog.w(TAG, "Unexpected intent " + intent);
+ }
+ }
+
private static void buildSpellCheckerMapLocked(Context context,
ArrayList<SpellCheckerInfo> list, HashMap<String, SpellCheckerInfo> map,
TextServicesSettings settings) {
@@ -223,7 +259,7 @@
Slog.d(TAG, "--- calledFromForegroundUserOrSystemProcess ? "
+ "calling uid = " + uid + " system uid = " + Process.SYSTEM_UID
+ " calling userId = " + userId + ", foreground user id = "
- + mSettings.getCurrentUserId());
+ + mSettings.getCurrentUserId() + ", calling pid = " + Binder.getCallingPid());
try {
final String[] packageNames = AppGlobals.getPackageManager().getPackagesForUid(uid);
for (int i = 0; i < packageNames.length; ++i) {
@@ -237,10 +273,40 @@
if (uid == Process.SYSTEM_UID || userId == mSettings.getCurrentUserId()) {
return true;
- } else {
- Slog.w(TAG, "--- IPC called from background users. Ignore. \n" + getStackTrace());
- return false;
}
+
+ // Permits current profile to use TSFM as long as the current text service is the system's
+ // one. This is a tentative solution and should be replaced with fully functional multiuser
+ // support.
+ // TODO: Implement multiuser support in TSMS.
+ final boolean isCurrentProfile = mSettings.isCurrentProfile(userId);
+ if (DBG) {
+ Slog.d(TAG, "--- userId = "+ userId + " isCurrentProfile = " + isCurrentProfile);
+ }
+ if (mSettings.isCurrentProfile(userId)) {
+ final SpellCheckerInfo spellCheckerInfo = getCurrentSpellCheckerWithoutVerification();
+ if (spellCheckerInfo != null) {
+ final ServiceInfo serviceInfo = spellCheckerInfo.getServiceInfo();
+ final boolean isSystemSpellChecker =
+ (serviceInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
+ if (DBG) {
+ Slog.d(TAG, "--- current spell checker = "+ spellCheckerInfo.getPackageName()
+ + " isSystem = " + isSystemSpellChecker);
+ }
+ if (isSystemSpellChecker) {
+ return true;
+ }
+ }
+ }
+
+ // Unlike InputMethodManagerService#calledFromValidUser, INTERACT_ACROSS_USERS_FULL isn't
+ // taken into account here. Anyway this method is supposed to be removed once multiuser
+ // support is implemented.
+ if (DBG) {
+ Slog.d(TAG, "--- IPC from userId:" + userId + " is being ignored. \n"
+ + getStackTrace());
+ }
+ return false;
}
private boolean bindCurrentSpellCheckerService(
@@ -292,6 +358,10 @@
if (!calledFromValidUser()) {
return null;
}
+ return getCurrentSpellCheckerWithoutVerification();
+ }
+
+ private SpellCheckerInfo getCurrentSpellCheckerWithoutVerification() {
synchronized (mSpellCheckerMap) {
final String curSpellCheckerId = mSettings.getSelectedSpellChecker();
if (DBG) {
@@ -914,6 +984,10 @@
private static class TextServicesSettings {
private final ContentResolver mResolver;
private int mCurrentUserId;
+ @GuardedBy("mLock")
+ private int[] mCurrentProfileIds = new int[0];
+ private Object mLock = new Object();
+
public TextServicesSettings(ContentResolver resolver, int userId) {
mResolver = resolver;
mCurrentUserId = userId;
@@ -928,6 +1002,22 @@
mCurrentUserId = userId;
}
+ public void setCurrentProfileIds(int[] currentProfileIds) {
+ synchronized (mLock) {
+ mCurrentProfileIds = currentProfileIds;
+ }
+ }
+
+ public boolean isCurrentProfile(int userId) {
+ synchronized (mLock) {
+ if (userId == mCurrentUserId) return true;
+ for (int i = 0; i < mCurrentProfileIds.length; i++) {
+ if (userId == mCurrentProfileIds[i]) return true;
+ }
+ return false;
+ }
+ }
+
public int getCurrentUserId() {
return mCurrentUserId;
}
diff --git a/services/core/java/com/android/server/Watchdog.java b/services/core/java/com/android/server/Watchdog.java
index 89e3f49..8e46c4d 100644
--- a/services/core/java/com/android/server/Watchdog.java
+++ b/services/core/java/com/android/server/Watchdog.java
@@ -415,15 +415,9 @@
dumpKernelStackTraces();
}
- // Trigger the kernel to dump all blocked threads to the kernel log
- try {
- FileWriter sysrq_trigger = new FileWriter("/proc/sysrq-trigger");
- sysrq_trigger.write("w");
- sysrq_trigger.close();
- } catch (IOException e) {
- Slog.e(TAG, "Failed to write to /proc/sysrq-trigger");
- Slog.e(TAG, e.getMessage());
- }
+ // Trigger the kernel to dump all blocked threads, and backtraces on all CPUs to the kernel log
+ doSysRq('w');
+ doSysRq('l');
// Try to add the error to the dropbox, but assuming that the ActivityManager
// itself may be deadlocked. (which has happened, causing this statement to
@@ -488,6 +482,16 @@
}
}
+ private void doSysRq(char c) {
+ try {
+ FileWriter sysrq_trigger = new FileWriter("/proc/sysrq-trigger");
+ sysrq_trigger.write(c);
+ sysrq_trigger.close();
+ } catch (IOException e) {
+ Slog.w(TAG, "Failed to write to /proc/sysrq-trigger", e);
+ }
+ }
+
private File dumpKernelStackTraces() {
String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
if (tracesPath == null || tracesPath.length() == 0) {
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 9f1ce0b..91e2df0 100755
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -1606,197 +1606,7 @@
final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
Thread thread = new Thread() {
@Override public void run() {
- final SparseArray<ProcessMemInfo> infoMap
- = new SparseArray<ProcessMemInfo>(memInfos.size());
- for (int i=0, N=memInfos.size(); i<N; i++) {
- ProcessMemInfo mi = memInfos.get(i);
- infoMap.put(mi.pid, mi);
- }
- updateCpuStatsNow();
- synchronized (mProcessCpuTracker) {
- final int N = mProcessCpuTracker.countStats();
- for (int i=0; i<N; i++) {
- ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
- if (st.vsize > 0) {
- long pss = Debug.getPss(st.pid, null);
- if (pss > 0) {
- if (infoMap.indexOfKey(st.pid) < 0) {
- ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
- ProcessList.NATIVE_ADJ, -1, "native", null);
- mi.pss = pss;
- memInfos.add(mi);
- }
- }
- }
- }
- }
-
- long totalPss = 0;
- for (int i=0, N=memInfos.size(); i<N; i++) {
- ProcessMemInfo mi = memInfos.get(i);
- if (mi.pss == 0) {
- mi.pss = Debug.getPss(mi.pid, null);
- }
- totalPss += mi.pss;
- }
- Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
- @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
- if (lhs.oomAdj != rhs.oomAdj) {
- return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
- }
- if (lhs.pss != rhs.pss) {
- return lhs.pss < rhs.pss ? 1 : -1;
- }
- return 0;
- }
- });
-
- StringBuilder tag = new StringBuilder(128);
- StringBuilder stack = new StringBuilder(128);
- tag.append("Low on memory -- ");
- appendMemBucket(tag, totalPss, "total", false);
- appendMemBucket(stack, totalPss, "total", true);
-
- StringBuilder logBuilder = new StringBuilder(1024);
- logBuilder.append("Low on memory:\n");
-
- boolean firstLine = true;
- int lastOomAdj = Integer.MIN_VALUE;
- for (int i=0, N=memInfos.size(); i<N; i++) {
- ProcessMemInfo mi = memInfos.get(i);
-
- if (mi.oomAdj != ProcessList.NATIVE_ADJ
- && (mi.oomAdj < ProcessList.SERVICE_ADJ
- || mi.oomAdj == ProcessList.HOME_APP_ADJ
- || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
- if (lastOomAdj != mi.oomAdj) {
- lastOomAdj = mi.oomAdj;
- if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
- tag.append(" / ");
- }
- if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
- if (firstLine) {
- stack.append(":");
- firstLine = false;
- }
- stack.append("\n\t at ");
- } else {
- stack.append("$");
- }
- } else {
- tag.append(" ");
- stack.append("$");
- }
- if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
- appendMemBucket(tag, mi.pss, mi.name, false);
- }
- appendMemBucket(stack, mi.pss, mi.name, true);
- if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
- && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
- stack.append("(");
- for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
- if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
- stack.append(DUMP_MEM_OOM_LABEL[k]);
- stack.append(":");
- stack.append(DUMP_MEM_OOM_ADJ[k]);
- }
- }
- stack.append(")");
- }
- }
-
- logBuilder.append(" ");
- logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj));
- logBuilder.append(' ');
- logBuilder.append(ProcessList.makeProcStateString(mi.procState));
- logBuilder.append(' ');
- ProcessList.appendRamKb(logBuilder, mi.pss);
- logBuilder.append(" kB: ");
- logBuilder.append(mi.name);
- logBuilder.append(" (");
- logBuilder.append(mi.pid);
- logBuilder.append(") ");
- logBuilder.append(mi.adjType);
- logBuilder.append('\n');
- if (mi.adjReason != null) {
- logBuilder.append(" ");
- logBuilder.append(mi.adjReason);
- logBuilder.append('\n');
- }
- }
-
- logBuilder.append(" ");
- ProcessList.appendRamKb(logBuilder, totalPss);
- logBuilder.append(" kB: TOTAL\n");
-
- long[] infos = new long[Debug.MEMINFO_COUNT];
- Debug.getMemInfo(infos);
- logBuilder.append(" MemInfo: ");
- logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
- logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
- logBuilder.append(infos[Debug.MEMINFO_VM_ALLOC_USED]).append(" kB vm alloc, ");
- logBuilder.append(infos[Debug.MEMINFO_PAGE_TABLES]).append(" kB page tables ");
- logBuilder.append(infos[Debug.MEMINFO_KERNEL_STACK]).append(" kB kernel stack\n");
- logBuilder.append(" ");
- logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
- logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
- logBuilder.append(infos[Debug.MEMINFO_MAPPED]).append(" kB mapped, ");
- logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
- if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
- logBuilder.append(" ZRAM: ");
- logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
- logBuilder.append(" kB RAM, ");
- logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
- logBuilder.append(" kB swap total, ");
- logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
- logBuilder.append(" kB swap free\n");
- }
- Slog.i(TAG, logBuilder.toString());
-
- StringBuilder dropBuilder = new StringBuilder(1024);
- /*
- StringWriter oomSw = new StringWriter();
- PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
- StringWriter catSw = new StringWriter();
- PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
- String[] emptyArgs = new String[] { };
- dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw);
- oomPw.flush();
- String oomString = oomSw.toString();
- */
- dropBuilder.append(stack);
- dropBuilder.append('\n');
- dropBuilder.append('\n');
- dropBuilder.append(logBuilder);
- dropBuilder.append('\n');
- /*
- dropBuilder.append(oomString);
- dropBuilder.append('\n');
- */
- StringWriter catSw = new StringWriter();
- synchronized (ActivityManagerService.this) {
- PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
- String[] emptyArgs = new String[] { };
- catPw.println();
- dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
- catPw.println();
- mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
- false, false, null);
- catPw.println();
- dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
- catPw.flush();
- }
- dropBuilder.append(catSw.toString());
- addErrorToDropBox("lowmem", null, "system_server", null,
- null, tag.toString(), dropBuilder.toString(), null, null);
- //Slog.i(TAG, "Sent to dropbox:");
- //Slog.i(TAG, dropBuilder.toString());
- synchronized (ActivityManagerService.this) {
- long now = SystemClock.uptimeMillis();
- if (mLastMemUsageReportTime < now) {
- mLastMemUsageReportTime = now;
- }
- }
+ reportMemUsage(memInfos);
}
};
thread.start();
@@ -2026,8 +1836,8 @@
ComponentName cn = tr.intent.getComponent();
if (cn != null && cn.getPackageName().equals(packageName)) {
- // If the package name matches, remove the task and kill the process
- removeTaskByIdLocked(tr.taskId, ActivityManager.REMOVE_TASK_KILL_PROCESS);
+ // If the package name matches, remove the task
+ removeTaskByIdLocked(tr.taskId, true);
}
}
}
@@ -2081,9 +1891,7 @@
// Prune all the tasks with removed components from the list of recent tasks
synchronized (ActivityManagerService.this) {
for (int i = tasksToRemove.size() - 1; i >= 0; i--) {
- // Remove the task but don't kill the process (since other components in that
- // package may still be running and in the background)
- removeTaskByIdLocked(tasksToRemove.get(i), 0);
+ removeTaskByIdLocked(tasksToRemove.get(i), false);
}
}
}
@@ -4503,9 +4311,9 @@
boolean res;
if (finishTask && 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.
- res = removeTaskByIdLocked(tr.taskId, 0);
+ // was the root activity in the task. The result code and data is ignored
+ // because we don't support returning them across task boundaries.
+ res = removeTaskByIdLocked(tr.taskId, false);
} else {
res = tr.stack.requestFinishActivityLocked(token, resultCode,
resultData, "app-request", true);
@@ -5332,7 +5140,7 @@
tr.getBaseIntent().getComponent().getPackageName();
if (tr.userId != userId) continue;
if (!taskPackageName.equals(packageName)) continue;
- removeTaskByIdLocked(tr.taskId, 0);
+ removeTaskByIdLocked(tr.taskId, false);
}
}
@@ -8477,52 +8285,65 @@
return mTaskPersister.getTaskDescriptionIcon(filename);
}
- private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
+ private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess) {
mRecentTasks.remove(tr);
tr.removedFromRecents(mTaskPersister);
- final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
- Intent baseIntent = new Intent(
- tr.intent != null ? tr.intent : tr.affinityIntent);
- ComponentName component = baseIntent.getComponent();
+ ComponentName component = tr.getBaseIntent().getComponent();
if (component == null) {
- Slog.w(TAG, "Now component for base intent of task: " + tr);
+ Slog.w(TAG, "No component for base intent of task: " + tr);
return;
}
- // Find any running services associated with this app.
- mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
+ if (!killProcess) {
+ return;
+ }
- if (killProcesses) {
- // Find any running processes associated with this app.
- final String pkg = component.getPackageName();
- ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
- ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
- for (int i=0; i<pmap.size(); i++) {
- SparseArray<ProcessRecord> uids = pmap.valueAt(i);
- for (int j=0; j<uids.size(); j++) {
- ProcessRecord proc = uids.valueAt(j);
- if (proc.userId != tr.userId) {
- continue;
- }
- if (!proc.pkgList.containsKey(pkg)) {
- continue;
- }
- procs.add(proc);
+ // Determine if the process(es) for this task should be killed.
+ final String pkg = component.getPackageName();
+ ArrayList<ProcessRecord> procsToKill = new ArrayList<ProcessRecord>();
+ ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
+ for (int i = 0; i < pmap.size(); i++) {
+
+ SparseArray<ProcessRecord> uids = pmap.valueAt(i);
+ for (int j = 0; j < uids.size(); j++) {
+ ProcessRecord proc = uids.valueAt(j);
+ if (proc.userId != tr.userId) {
+ // Don't kill process for a different user.
+ continue;
}
- }
-
- // Kill the running processes.
- for (int i=0; i<procs.size(); i++) {
- ProcessRecord pr = procs.get(i);
- if (pr == mHomeProcess) {
+ if (proc == mHomeProcess) {
// Don't kill the home process along with tasks from the same package.
continue;
}
- if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
- pr.kill("remove task", true);
- } else {
- pr.waitingToKill = "remove task";
+ if (!proc.pkgList.containsKey(pkg)) {
+ // Don't kill process that is not associated with this task.
+ continue;
}
+
+ for (int k = 0; k < proc.activities.size(); k++) {
+ TaskRecord otherTask = proc.activities.get(k).task;
+ if (tr.taskId != otherTask.taskId && otherTask.inRecents) {
+ // Don't kill process(es) that has an activity in a different task that is
+ // also in recents.
+ return;
+ }
+ }
+
+ // Add process to kill list.
+ procsToKill.add(proc);
+ }
+ }
+
+ // Find any running services associated with this app and stop if needed.
+ mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent()));
+
+ // Kill the running processes.
+ for (int i = 0; i < procsToKill.size(); i++) {
+ ProcessRecord pr = procsToKill.get(i);
+ if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
+ pr.kill("remove task", true);
+ } else {
+ pr.waitingToKill = "remove task";
}
}
}
@@ -8531,15 +8352,14 @@
* Removes the task with the specified task id.
*
* @param taskId Identifier of the task to be removed.
- * @param flags Additional operational flags. May be 0 or
- * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}.
+ * @param killProcess Kill any process associated with the task if possible.
* @return Returns true if the given task was found and removed.
*/
- private boolean removeTaskByIdLocked(int taskId, int flags) {
+ private boolean removeTaskByIdLocked(int taskId, boolean killProcess) {
TaskRecord tr = recentTaskForIdLocked(taskId);
if (tr != null) {
tr.removeTaskActivitiesLocked();
- cleanUpRemovedTaskLocked(tr, flags);
+ cleanUpRemovedTaskLocked(tr, killProcess);
if (tr.isPersistable) {
notifyTaskPersisterLocked(null, true);
}
@@ -8549,19 +8369,19 @@
}
@Override
- public boolean removeTask(int taskId, int flags) {
+ public boolean removeTask(int taskId) {
synchronized (this) {
enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
"removeTask()");
long ident = Binder.clearCallingIdentity();
try {
- return removeTaskByIdLocked(taskId, flags);
+ return removeTaskByIdLocked(taskId, true);
} finally {
Binder.restoreCallingIdentity(ident);
}
}
}
-
+
/**
* TODO: Add mController hook
*/
@@ -13927,6 +13747,35 @@
}
}
+ private static final int KSM_SHARED = 0;
+ private static final int KSM_SHARING = 1;
+ private static final int KSM_UNSHARED = 2;
+ private static final int KSM_VOLATILE = 3;
+
+ private final long[] getKsmInfo() {
+ long[] longOut = new long[4];
+ final int[] SINGLE_LONG_FORMAT = new int[] {
+ Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
+ };
+ long[] longTmp = new long[1];
+ Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
+ SINGLE_LONG_FORMAT, null, longTmp, null);
+ longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
+ longTmp[0] = 0;
+ Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
+ SINGLE_LONG_FORMAT, null, longTmp, null);
+ longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
+ longTmp[0] = 0;
+ Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
+ SINGLE_LONG_FORMAT, null, longTmp, null);
+ longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
+ longTmp[0] = 0;
+ Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
+ SINGLE_LONG_FORMAT, null, longTmp, null);
+ longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
+ return longOut;
+ }
+
final void dumpApplicationMemoryUsage(FileDescriptor fd,
PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
boolean dumpDetails = false;
@@ -14272,7 +14121,7 @@
pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
+ memInfo.getFreeSizeKb()); pw.print(" kB (");
pw.print(cachedPss); pw.print(" cached pss + ");
- pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + ");
+ pw.print(memInfo.getCachedSizeKb()); pw.print(" cached kernel + ");
pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
} else {
pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
@@ -14306,32 +14155,16 @@
pw.println(memInfo.getSwapFreeSizeKb());
}
}
- final int[] SINGLE_LONG_FORMAT = new int[] {
- Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
- };
- long[] longOut = new long[1];
- Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
- SINGLE_LONG_FORMAT, null, longOut, null);
- long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
- longOut[0] = 0;
- Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
- SINGLE_LONG_FORMAT, null, longOut, null);
- long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
- longOut[0] = 0;
- Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
- SINGLE_LONG_FORMAT, null, longOut, null);
- long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
- longOut[0] = 0;
- Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
- SINGLE_LONG_FORMAT, null, longOut, null);
- long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
+ final long[] ksm = getKsmInfo();
if (!isCompact) {
- if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) {
- pw.print(" KSM: "); pw.print(sharing);
+ if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
+ || ksm[KSM_VOLATILE] != 0) {
+ pw.print(" KSM: "); pw.print(ksm[KSM_SHARING]);
pw.print(" kB saved from shared ");
- pw.print(shared); pw.println(" kB");
- pw.print(" "); pw.print(unshared); pw.print(" kB unshared; ");
- pw.print(voltile); pw.println(" kB volatile");
+ pw.print(ksm[KSM_SHARED]); pw.println(" kB");
+ pw.print(" "); pw.print(ksm[KSM_UNSHARED]);
+ pw.print(" kB unshared; ");
+ pw.print(ksm[KSM_VOLATILE]); pw.println(" kB volatile");
}
pw.print(" Tuning: ");
pw.print(ActivityManager.staticGetMemoryClass());
@@ -14351,9 +14184,9 @@
}
pw.println();
} else {
- pw.print("ksm,"); pw.print(sharing); pw.print(",");
- pw.print(shared); pw.print(","); pw.print(unshared); pw.print(",");
- pw.println(voltile);
+ pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
+ pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
+ pw.print(","); pw.println(ksm[KSM_VOLATILE]);
pw.print("tuning,");
pw.print(ActivityManager.staticGetMemoryClass());
pw.print(',');
@@ -14372,6 +14205,265 @@
}
}
+ private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
+ String name) {
+ sb.append(" ");
+ sb.append(ProcessList.makeOomAdjString(oomAdj));
+ sb.append(' ');
+ sb.append(ProcessList.makeProcStateString(procState));
+ sb.append(' ');
+ ProcessList.appendRamKb(sb, pss);
+ sb.append(" kB: ");
+ sb.append(name);
+ }
+
+ private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
+ appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.name);
+ sb.append(" (");
+ sb.append(mi.pid);
+ sb.append(") ");
+ sb.append(mi.adjType);
+ sb.append('\n');
+ if (mi.adjReason != null) {
+ sb.append(" ");
+ sb.append(mi.adjReason);
+ sb.append('\n');
+ }
+ }
+
+ void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
+ final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
+ for (int i=0, N=memInfos.size(); i<N; i++) {
+ ProcessMemInfo mi = memInfos.get(i);
+ infoMap.put(mi.pid, mi);
+ }
+ updateCpuStatsNow();
+ synchronized (mProcessCpuTracker) {
+ final int N = mProcessCpuTracker.countStats();
+ for (int i=0; i<N; i++) {
+ ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
+ if (st.vsize > 0) {
+ long pss = Debug.getPss(st.pid, null);
+ if (pss > 0) {
+ if (infoMap.indexOfKey(st.pid) < 0) {
+ ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
+ ProcessList.NATIVE_ADJ, -1, "native", null);
+ mi.pss = pss;
+ memInfos.add(mi);
+ }
+ }
+ }
+ }
+ }
+
+ long totalPss = 0;
+ for (int i=0, N=memInfos.size(); i<N; i++) {
+ ProcessMemInfo mi = memInfos.get(i);
+ if (mi.pss == 0) {
+ mi.pss = Debug.getPss(mi.pid, null);
+ }
+ totalPss += mi.pss;
+ }
+ Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
+ @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
+ if (lhs.oomAdj != rhs.oomAdj) {
+ return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
+ }
+ if (lhs.pss != rhs.pss) {
+ return lhs.pss < rhs.pss ? 1 : -1;
+ }
+ return 0;
+ }
+ });
+
+ StringBuilder tag = new StringBuilder(128);
+ StringBuilder stack = new StringBuilder(128);
+ tag.append("Low on memory -- ");
+ appendMemBucket(tag, totalPss, "total", false);
+ appendMemBucket(stack, totalPss, "total", true);
+
+ StringBuilder fullNativeBuilder = new StringBuilder(1024);
+ StringBuilder shortNativeBuilder = new StringBuilder(1024);
+ StringBuilder fullJavaBuilder = new StringBuilder(1024);
+
+ boolean firstLine = true;
+ int lastOomAdj = Integer.MIN_VALUE;
+ long extraNativeRam = 0;
+ long cachedPss = 0;
+ for (int i=0, N=memInfos.size(); i<N; i++) {
+ ProcessMemInfo mi = memInfos.get(i);
+
+ if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
+ cachedPss += mi.pss;
+ }
+
+ if (mi.oomAdj != ProcessList.NATIVE_ADJ
+ && (mi.oomAdj < ProcessList.SERVICE_ADJ
+ || mi.oomAdj == ProcessList.HOME_APP_ADJ
+ || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
+ if (lastOomAdj != mi.oomAdj) {
+ lastOomAdj = mi.oomAdj;
+ if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
+ tag.append(" / ");
+ }
+ if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
+ if (firstLine) {
+ stack.append(":");
+ firstLine = false;
+ }
+ stack.append("\n\t at ");
+ } else {
+ stack.append("$");
+ }
+ } else {
+ tag.append(" ");
+ stack.append("$");
+ }
+ if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
+ appendMemBucket(tag, mi.pss, mi.name, false);
+ }
+ appendMemBucket(stack, mi.pss, mi.name, true);
+ if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
+ && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
+ stack.append("(");
+ for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
+ if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
+ stack.append(DUMP_MEM_OOM_LABEL[k]);
+ stack.append(":");
+ stack.append(DUMP_MEM_OOM_ADJ[k]);
+ }
+ }
+ stack.append(")");
+ }
+ }
+
+ appendMemInfo(fullNativeBuilder, mi);
+ if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
+ // The short form only has native processes that are >= 1MB.
+ if (mi.pss >= 1000) {
+ appendMemInfo(shortNativeBuilder, mi);
+ } else {
+ extraNativeRam += mi.pss;
+ }
+ } else {
+ // Short form has all other details, but if we have collected RAM
+ // from smaller native processes let's dump a summary of that.
+ if (extraNativeRam > 0) {
+ appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
+ -1, extraNativeRam, "(Other native)");
+ shortNativeBuilder.append('\n');
+ extraNativeRam = 0;
+ }
+ appendMemInfo(fullJavaBuilder, mi);
+ }
+ }
+
+ fullJavaBuilder.append(" ");
+ ProcessList.appendRamKb(fullJavaBuilder, totalPss);
+ fullJavaBuilder.append(" kB: TOTAL\n");
+
+ MemInfoReader memInfo = new MemInfoReader();
+ memInfo.readMemInfo();
+ final long[] infos = memInfo.getRawInfo();
+
+ StringBuilder memInfoBuilder = new StringBuilder(1024);
+ Debug.getMemInfo(infos);
+ memInfoBuilder.append(" MemInfo: ");
+ memInfoBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
+ memInfoBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
+ memInfoBuilder.append(infos[Debug.MEMINFO_VM_ALLOC_USED]).append(" kB vm alloc, ");
+ memInfoBuilder.append(infos[Debug.MEMINFO_PAGE_TABLES]).append(" kB page tables ");
+ memInfoBuilder.append(infos[Debug.MEMINFO_KERNEL_STACK]).append(" kB kernel stack\n");
+ memInfoBuilder.append(" ");
+ memInfoBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
+ memInfoBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
+ memInfoBuilder.append(infos[Debug.MEMINFO_MAPPED]).append(" kB mapped, ");
+ memInfoBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
+ if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
+ memInfoBuilder.append(" ZRAM: ");
+ memInfoBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
+ memInfoBuilder.append(" kB RAM, ");
+ memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
+ memInfoBuilder.append(" kB swap total, ");
+ memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
+ memInfoBuilder.append(" kB swap free\n");
+ }
+ final long[] ksm = getKsmInfo();
+ if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
+ || ksm[KSM_VOLATILE] != 0) {
+ memInfoBuilder.append(" KSM: "); memInfoBuilder.append(ksm[KSM_SHARING]);
+ memInfoBuilder.append(" kB saved from shared ");
+ memInfoBuilder.append(ksm[KSM_SHARED]); memInfoBuilder.append(" kB\n");
+ memInfoBuilder.append(" "); memInfoBuilder.append(ksm[KSM_UNSHARED]);
+ memInfoBuilder.append(" kB unshared; ");
+ memInfoBuilder.append(ksm[KSM_VOLATILE]); memInfoBuilder.append(" kB volatile\n");
+ }
+ memInfoBuilder.append(" Free RAM: ");
+ memInfoBuilder.append(cachedPss + memInfo.getCachedSizeKb()
+ + memInfo.getFreeSizeKb());
+ memInfoBuilder.append(" kB\n");
+ memInfoBuilder.append(" Used RAM: ");
+ memInfoBuilder.append(totalPss - cachedPss + memInfo.getKernelUsedSizeKb());
+ memInfoBuilder.append(" kB\n");
+ memInfoBuilder.append(" Lost RAM: ");
+ memInfoBuilder.append(memInfo.getTotalSizeKb()
+ - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
+ - memInfo.getKernelUsedSizeKb());
+ memInfoBuilder.append(" kB\n");
+ Slog.i(TAG, "Low on memory:");
+ Slog.i(TAG, shortNativeBuilder.toString());
+ Slog.i(TAG, fullJavaBuilder.toString());
+ Slog.i(TAG, memInfoBuilder.toString());
+
+ StringBuilder dropBuilder = new StringBuilder(1024);
+ /*
+ StringWriter oomSw = new StringWriter();
+ PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
+ StringWriter catSw = new StringWriter();
+ PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
+ String[] emptyArgs = new String[] { };
+ dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw);
+ oomPw.flush();
+ String oomString = oomSw.toString();
+ */
+ dropBuilder.append("Low on memory:");
+ dropBuilder.append(stack);
+ dropBuilder.append('\n');
+ dropBuilder.append(fullNativeBuilder);
+ dropBuilder.append(fullJavaBuilder);
+ dropBuilder.append('\n');
+ dropBuilder.append(memInfoBuilder);
+ dropBuilder.append('\n');
+ /*
+ dropBuilder.append(oomString);
+ dropBuilder.append('\n');
+ */
+ StringWriter catSw = new StringWriter();
+ synchronized (ActivityManagerService.this) {
+ PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
+ String[] emptyArgs = new String[] { };
+ catPw.println();
+ dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
+ catPw.println();
+ mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
+ false, false, null);
+ catPw.println();
+ dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
+ catPw.flush();
+ }
+ dropBuilder.append(catSw.toString());
+ addErrorToDropBox("lowmem", null, "system_server", null,
+ null, tag.toString(), dropBuilder.toString(), null, null);
+ //Slog.i(TAG, "Sent to dropbox:");
+ //Slog.i(TAG, dropBuilder.toString());
+ synchronized (ActivityManagerService.this) {
+ long now = SystemClock.uptimeMillis();
+ if (mLastMemUsageReportTime < now) {
+ mLastMemUsageReportTime = now;
+ }
+ }
+ }
+
/**
* Searches array of arguments for the specified string
* @param args array of argument strings
@@ -19085,16 +19177,9 @@
synchronized (ActivityManagerService.this) {
long origId = Binder.clearCallingIdentity();
try {
- TaskRecord tr = recentTaskForIdLocked(mTaskId);
- if (tr == null) {
+ if (!removeTaskByIdLocked(mTaskId, false)) {
throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
}
- // Only kill the process if we are not a new document
- int flags = tr.getBaseIntent().getFlags();
- boolean isDocument = (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) ==
- Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
- removeTaskByIdLocked(mTaskId,
- !isDocument ? ActivityManager.REMOVE_TASK_KILL_PROCESS : 0);
} finally {
Binder.restoreCallingIdentity(origId);
}
diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java
index e1b8278..b61bd8a 100755
--- a/services/core/java/com/android/server/am/ActivityStack.java
+++ b/services/core/java/com/android/server/am/ActivityStack.java
@@ -835,7 +835,7 @@
prev.task.touchActiveTime();
clearLaunchTime(prev);
final ActivityRecord next = mStackSupervisor.topRunningActivityLocked();
- if (mService.mHasRecents && (next == null || next.noDisplay || next.task != prev.task)) {
+ if (mService.mHasRecents && (next == null || next.noDisplay || next.task != prev.task || uiSleeping)) {
prev.updateThumbnail(screenshotActivities(prev), null);
}
stopFullyDrawnTraceIfNeeded();
diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
index c1bf955..cc7026a 100644
--- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
@@ -444,10 +444,6 @@
return mService.startHomeActivityLocked(mCurrentUser);
}
- void keyguardWaitingForActivityDrawn() {
- mWindowManager.keyguardWaitingForActivityDrawn();
- }
-
TaskRecord anyTaskForIdLocked(int id) {
int numDisplays = mActivityDisplays.size();
for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
@@ -3550,9 +3546,9 @@
}
mLockTaskNotify.show(false);
try {
- boolean shouldLockKeyguard = Settings.System.getInt(
+ boolean shouldLockKeyguard = Settings.Secure.getInt(
mService.mContext.getContentResolver(),
- Settings.System.LOCK_TO_APP_EXIT_LOCKED) != 0;
+ Settings.Secure.LOCK_TO_APP_EXIT_LOCKED) != 0;
if (!mLockTaskIsLocked && shouldLockKeyguard) {
mWindowManager.lockNow(null);
mWindowManager.dismissKeyguard();
diff --git a/services/core/java/com/android/server/am/LockToAppRequestDialog.java b/services/core/java/com/android/server/am/LockToAppRequestDialog.java
index a1eb31e..739fd0a 100644
--- a/services/core/java/com/android/server/am/LockToAppRequestDialog.java
+++ b/services/core/java/com/android/server/am/LockToAppRequestDialog.java
@@ -112,8 +112,8 @@
// Remember state.
try {
- boolean useLock = Settings.System.getInt(mContext.getContentResolver(),
- Settings.System.LOCK_TO_APP_EXIT_LOCKED) != 0;
+ boolean useLock = Settings.Secure.getInt(mContext.getContentResolver(),
+ Settings.Secure.LOCK_TO_APP_EXIT_LOCKED) != 0;
mCheckbox.setChecked(useLock);
} catch (SettingNotFoundException e) {
}
@@ -127,8 +127,8 @@
if (DialogInterface.BUTTON_POSITIVE == which) {
Slog.d(TAG, "accept lock-to-app request");
// Set whether to use the lock screen when exiting.
- Settings.System.putInt(mContext.getContentResolver(),
- Settings.System.LOCK_TO_APP_EXIT_LOCKED,
+ Settings.Secure.putInt(mContext.getContentResolver(),
+ Settings.Secure.LOCK_TO_APP_EXIT_LOCKED,
mCheckbox != null && mCheckbox.isChecked() ? 1 : 0);
// Start lock-to-app.
diff --git a/services/core/java/com/android/server/am/ProcessList.java b/services/core/java/com/android/server/am/ProcessList.java
index 5b22255..843a0cb 100644
--- a/services/core/java/com/android/server/am/ProcessList.java
+++ b/services/core/java/com/android/server/am/ProcessList.java
@@ -235,22 +235,16 @@
Slog.i("XXXXXX", "minfree_adj=" + minfree_adj + " minfree_abs=" + minfree_abs);
}
- // We've now baked in the increase to the basic oom values above, since
- // they seem to be useful more generally for devices that are tight on
- // memory than just for 64 bit. This should probably have some more
- // tuning done, so not deleting it quite yet...
- final boolean is64bit = false; //Build.SUPPORTED_64_BIT_ABIS.length > 0;
+ if (Build.SUPPORTED_64_BIT_ABIS.length > 0) {
+ // Increase the high min-free levels for cached processes for 64-bit
+ mOomMinFreeHigh[4] = 225000;
+ mOomMinFreeHigh[5] = 325000;
+ }
for (int i=0; i<mOomAdj.length; i++) {
int low = mOomMinFreeLow[i];
int high = mOomMinFreeHigh[i];
mOomMinFree[i] = (int)(low + ((high-low)*scale));
- if (is64bit) {
- // On 64 bit devices, we consume more baseline RAM, because 64 bit is cool!
- // To avoid being all pagey and stuff, scale up the memory levels to
- // give us some breathing room.
- mOomMinFree[i] = (3*mOomMinFree[i])/2;
- }
}
if (minfree_abs >= 0) {
diff --git a/services/core/java/com/android/server/am/UserSwitchingDialog.java b/services/core/java/com/android/server/am/UserSwitchingDialog.java
index dfc8df5..36263ec 100644
--- a/services/core/java/com/android/server/am/UserSwitchingDialog.java
+++ b/services/core/java/com/android/server/am/UserSwitchingDialog.java
@@ -17,17 +17,11 @@
package com.android.server.am;
import android.app.AlertDialog;
-import android.app.Service;
-import android.content.ActivityNotFoundException;
import android.content.Context;
-import android.content.DialogInterface;
-import android.content.Intent;
import android.content.res.Resources;
-import android.os.Handler;
-import android.os.Message;
-import android.util.Slog;
import android.view.LayoutInflater;
import android.view.View;
+import android.view.ViewTreeObserver;
import android.view.WindowManager;
import android.widget.TextView;
@@ -39,11 +33,10 @@
* in the background rather than just freeze the screen and not know if the user-switch affordance
* was being handled.
*/
-final class UserSwitchingDialog extends AlertDialog {
+final class UserSwitchingDialog extends AlertDialog
+ implements ViewTreeObserver.OnWindowShownListener {
private static final String TAG = "ActivityManagerUserSwitchingDialog";
- private static final int MSG_START_USER = 1;
-
private final ActivityManagerService mService;
private final int mUserId;
@@ -74,19 +67,21 @@
@Override
public void show() {
+ // Slog.v(TAG, "show called");
super.show();
- // TODO: Instead of just an arbitrary delay, wait for a signal that the window was fully
- // displayed by the window manager
- mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_START_USER), 250);
+ final View decorView = getWindow().getDecorView();
+ if (decorView != null) {
+ decorView.getViewTreeObserver().addOnWindowShownListener(this);
+ }
}
- private final Handler mHandler = new Handler() {
- public void handleMessage(Message msg) {
- switch (msg.what) {
- case MSG_START_USER:
- mService.startUserInForeground(mUserId, UserSwitchingDialog.this);
- break;
- }
+ @Override
+ public void onWindowShown() {
+ // Slog.v(TAG, "onWindowShown called");
+ mService.startUserInForeground(mUserId, this);
+ final View decorView = getWindow().getDecorView();
+ if (decorView != null) {
+ decorView.getViewTreeObserver().removeOnWindowShownListener(this);
}
- };
+ }
}
diff --git a/services/core/java/com/android/server/connectivity/Nat464Xlat.java b/services/core/java/com/android/server/connectivity/Nat464Xlat.java
index c7a2ce1..576556b 100644
--- a/services/core/java/com/android/server/connectivity/Nat464Xlat.java
+++ b/services/core/java/com/android/server/connectivity/Nat464Xlat.java
@@ -17,6 +17,7 @@
package com.android.server.connectivity;
import static android.net.ConnectivityManager.TYPE_MOBILE;
+import static android.net.ConnectivityManager.TYPE_WIFI;
import java.net.Inet4Address;
@@ -53,7 +54,7 @@
// ConnectivityService Handler for LinkProperties updates.
private final Handler mHandler;
- // The network we're running on.
+ // The network we're running on, and its type.
private final NetworkAgentInfo mNetwork;
// Internal state variables.
@@ -90,8 +91,9 @@
final boolean connected = nai.networkInfo.isConnected();
final boolean hasIPv4Address =
(nai.linkProperties != null) ? nai.linkProperties.hasIPv4Address() : false;
- // Only support clat on mobile for now.
- return netType == TYPE_MOBILE && connected && !hasIPv4Address;
+ // Only support clat on mobile and wifi for now, because these are the only IPv6-only
+ // networks we can connect to.
+ return connected && !hasIPv4Address && (netType == TYPE_MOBILE || netType == TYPE_WIFI);
}
/**
@@ -211,23 +213,41 @@
return stacked;
}
+ private LinkAddress getLinkAddress(String iface) {
+ try {
+ InterfaceConfiguration config = mNMService.getInterfaceConfig(iface);
+ return config.getLinkAddress();
+ } catch(RemoteException|IllegalStateException e) {
+ Slog.e(TAG, "Error getting link properties: " + e);
+ return null;
+ }
+ }
+
+ private void maybeSetIpv6NdOffload(String iface, boolean on) {
+ if (mNetwork.networkInfo.getType() != TYPE_WIFI) {
+ return;
+ }
+ try {
+ Slog.d(TAG, (on ? "En" : "Dis") + "abling ND offload on " + iface);
+ mNMService.setInterfaceIpv6NdOffload(iface, on);
+ } catch(RemoteException|IllegalStateException e) {
+ Slog.w(TAG, "Changing IPv6 ND offload on " + iface + "failed: " + e);
+ }
+ }
+
@Override
public void interfaceAdded(String iface) {
// Called by the InterfaceObserver on its own thread, so can race with stop().
if (isStarted() && mIface.equals(iface)) {
Slog.i(TAG, "interface " + iface + " added, mIsRunning " + mIsRunning + "->true");
- LinkAddress clatAddress;
- try {
- InterfaceConfiguration config = mNMService.getInterfaceConfig(iface);
- clatAddress = config.getLinkAddress();
- } catch(RemoteException e) {
- Slog.e(TAG, "Error getting link properties: " + e);
- return;
- }
-
if (!mIsRunning) {
+ LinkAddress clatAddress = getLinkAddress(iface);
+ if (clatAddress == null) {
+ return;
+ }
mIsRunning = true;
+ maybeSetIpv6NdOffload(mBaseIface, false);
LinkProperties lp = new LinkProperties(mNetwork.linkProperties);
lp.addStackedLink(makeLinkProperties(clatAddress));
Slog.i(TAG, "Adding stacked link " + mIface + " on top of " + mBaseIface);
@@ -255,6 +275,7 @@
} catch (RemoteException|IllegalStateException e) {
// Well, we tried.
}
+ maybeSetIpv6NdOffload(mBaseIface, true);
LinkProperties lp = new LinkProperties(mNetwork.linkProperties);
lp.removeStackedLink(mIface);
clear();
diff --git a/services/core/java/com/android/server/connectivity/PacManager.java b/services/core/java/com/android/server/connectivity/PacManager.java
index 07fe7ba..7d1da01 100644
--- a/services/core/java/com/android/server/connectivity/PacManager.java
+++ b/services/core/java/com/android/server/connectivity/PacManager.java
@@ -265,14 +265,9 @@
}
Intent intent = new Intent();
intent.setClassName(PAC_PACKAGE, PAC_SERVICE);
- // Already bound no need to bind again.
if ((mProxyConnection != null) && (mConnection != null)) {
- if (mLastPort != -1) {
- sendPacBroadcast(new ProxyInfo(mPacUrl, mLastPort));
- } else {
- Log.e(TAG, "Received invalid port from Local Proxy,"
- + " PAC will not be operational");
- }
+ // Already bound no need to bind again, just download the new file.
+ IoThread.getHandler().post(mPacDownloader);
return;
}
mConnection = new ServiceConnection() {
diff --git a/services/core/java/com/android/server/connectivity/PermissionMonitor.java b/services/core/java/com/android/server/connectivity/PermissionMonitor.java
index 238402f..debda14 100644
--- a/services/core/java/com/android/server/connectivity/PermissionMonitor.java
+++ b/services/core/java/com/android/server/connectivity/PermissionMonitor.java
@@ -191,8 +191,8 @@
}
try {
if (add) {
- mNetd.setPermission(CHANGE_NETWORK_STATE, toIntArray(network));
- mNetd.setPermission(CONNECTIVITY_INTERNAL, toIntArray(system));
+ mNetd.setPermission("NETWORK", toIntArray(network));
+ mNetd.setPermission("SYSTEM", toIntArray(system));
} else {
mNetd.clearPermission(toIntArray(network));
mNetd.clearPermission(toIntArray(system));
diff --git a/services/core/java/com/android/server/display/AutomaticBrightnessController.java b/services/core/java/com/android/server/display/AutomaticBrightnessController.java
index 45d3771..d919bf6 100644
--- a/services/core/java/com/android/server/display/AutomaticBrightnessController.java
+++ b/services/core/java/com/android/server/display/AutomaticBrightnessController.java
@@ -21,7 +21,6 @@
import com.android.server.twilight.TwilightManager;
import com.android.server.twilight.TwilightState;
-import android.content.res.Resources;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
@@ -120,6 +119,7 @@
// The minimum and maximum screen brightnesses.
private final int mScreenBrightnessRangeMinimum;
private final int mScreenBrightnessRangeMaximum;
+ private final float mDozeScaleFactor;
// Amount of time to delay auto-brightness after screen on while waiting for
// the light sensor to warm-up in milliseconds.
@@ -171,9 +171,12 @@
// The last screen auto-brightness gamma. (For printing in dump() only.)
private float mLastScreenAutoBrightnessGamma = 1.0f;
+ // Are we going to adjust brightness while dozing.
+ private boolean mDozing;
+
public AutomaticBrightnessController(Callbacks callbacks, Looper looper,
- SensorManager sensorManager, Spline autoBrightnessSpline,
- int lightSensorWarmUpTime, int brightnessMin, int brightnessMax) {
+ SensorManager sensorManager, Spline autoBrightnessSpline, int lightSensorWarmUpTime,
+ int brightnessMin, int brightnessMax, float dozeScaleFactor) {
mCallbacks = callbacks;
mTwilight = LocalServices.getService(TwilightManager.class);
mSensorManager = sensorManager;
@@ -181,6 +184,7 @@
mScreenBrightnessRangeMinimum = brightnessMin;
mScreenBrightnessRangeMaximum = brightnessMax;
mLightSensorWarmUpTimeConfig = lightSensorWarmUpTime;
+ mDozeScaleFactor = dozeScaleFactor;
mHandler = new AutomaticBrightnessHandler(looper);
mAmbientLightRingBuffer = new AmbientLightRingBuffer();
@@ -195,11 +199,20 @@
}
public int getAutomaticScreenBrightness() {
+ if (mDozing) {
+ return (int) (mScreenAutoBrightness * mDozeScaleFactor);
+ }
return mScreenAutoBrightness;
}
- public void configure(boolean enable, float adjustment) {
- boolean changed = setLightSensorEnabled(enable);
+ public void configure(boolean enable, float adjustment, boolean dozing) {
+ // While dozing, the application processor may be suspended which will prevent us from
+ // receiving new information from the light sensor. On some devices, we may be able to
+ // switch to a wake-up light sensor instead but for now we will simply disable the sensor
+ // and hold onto the last computed screen auto brightness. We save the dozing flag for
+ // debugging purposes.
+ mDozing = dozing;
+ boolean changed = setLightSensorEnabled(enable && !dozing);
changed |= setScreenAutoBrightnessAdjustment(adjustment);
if (changed) {
updateAutoBrightness(false /*sendUpdate*/);
@@ -230,6 +243,7 @@
pw.println(" mScreenAutoBrightness=" + mScreenAutoBrightness);
pw.println(" mScreenAutoBrightnessAdjustment=" + mScreenAutoBrightnessAdjustment);
pw.println(" mLastScreenAutoBrightnessGamma=" + mLastScreenAutoBrightnessGamma);
+ pw.println(" mDozing=" + mDozing);
}
private boolean setLightSensorEnabled(boolean enable) {
diff --git a/services/core/java/com/android/server/display/DisplayPowerController.java b/services/core/java/com/android/server/display/DisplayPowerController.java
index 2d5b99e..81cd94b 100644
--- a/services/core/java/com/android/server/display/DisplayPowerController.java
+++ b/services/core/java/com/android/server/display/DisplayPowerController.java
@@ -155,6 +155,9 @@
// True if auto-brightness should be used.
private boolean mUseSoftwareAutoBrightnessConfig;
+ // True if should use light sensor to automatically determine doze screen brightness.
+ private final boolean mAllowAutoBrightnessWhileDozingConfig;
+
// True if we should fade the screen while turning it off, false if we should play
// a stylish color fade animation instead.
private boolean mColorFadeFadesConfig;
@@ -295,6 +298,10 @@
mUseSoftwareAutoBrightnessConfig = resources.getBoolean(
com.android.internal.R.bool.config_automatic_brightness_available);
+
+ mAllowAutoBrightnessWhileDozingConfig = resources.getBoolean(
+ com.android.internal.R.bool.config_allowAutoBrightnessWhileDozing);
+
if (mUseSoftwareAutoBrightnessConfig) {
int[] lux = resources.getIntArray(
com.android.internal.R.array.config_autoBrightnessLevels);
@@ -302,6 +309,9 @@
com.android.internal.R.array.config_autoBrightnessLcdBacklightValues);
int lightSensorWarmUpTimeConfig = resources.getInteger(
com.android.internal.R.integer.config_lightSensorWarmupTime);
+ final float dozeScaleFactor = resources.getFraction(
+ com.android.internal.R.fraction.config_screenAutoBrightnessDozeScaleFactor,
+ 1, 1);
Spline screenAutoBrightnessSpline = createAutoBrightnessSpline(lux, screenBrightness);
if (screenAutoBrightnessSpline == null) {
@@ -326,7 +336,7 @@
mAutomaticBrightnessController = new AutomaticBrightnessController(this,
handler.getLooper(), sensorManager, screenAutoBrightnessSpline,
lightSensorWarmUpTimeConfig, screenBrightnessRangeMinimum,
- mScreenBrightnessRangeMaximum);
+ mScreenBrightnessRangeMaximum, dozeScaleFactor);
}
}
@@ -523,7 +533,9 @@
} else {
state = Display.STATE_DOZE;
}
- brightness = mPowerRequest.dozeScreenBrightness;
+ if (!mAllowAutoBrightnessWhileDozingConfig) {
+ brightness = mPowerRequest.dozeScreenBrightness;
+ }
break;
case DisplayPowerRequest.POLICY_DIM:
case DisplayPowerRequest.POLICY_BRIGHT:
@@ -570,23 +582,23 @@
state = mPowerState.getScreenState();
// Use zero brightness when screen is off.
+ // Use full brightness when screen brightness is boosted.
if (state == Display.STATE_OFF) {
brightness = PowerManager.BRIGHTNESS_OFF;
- }
-
- // Use default brightness when dozing unless overridden.
- if (brightness < 0 && (state == Display.STATE_DOZE
- || state == Display.STATE_DOZE_SUSPEND)) {
- brightness = mScreenBrightnessDozeConfig;
+ } else if (mPowerRequest.boostScreenBrightness) {
+ brightness = PowerManager.BRIGHTNESS_ON;
}
// Configure auto-brightness.
boolean autoBrightnessEnabled = false;
if (mAutomaticBrightnessController != null) {
+ final boolean autoBrightnessEnabledInDoze = mAllowAutoBrightnessWhileDozingConfig
+ && (state == Display.STATE_DOZE || state == Display.STATE_DOZE_SUSPEND);
autoBrightnessEnabled = mPowerRequest.useAutoBrightness
- && state == Display.STATE_ON && brightness < 0;
+ && (state == Display.STATE_ON || autoBrightnessEnabledInDoze)
+ && brightness < 0;
mAutomaticBrightnessController.configure(autoBrightnessEnabled,
- mPowerRequest.screenAutoBrightnessAdjustment);
+ mPowerRequest.screenAutoBrightnessAdjustment, state != Display.STATE_ON);
}
// Apply auto-brightness.
@@ -609,6 +621,12 @@
mAppliedAutoBrightness = false;
}
+ // Use default brightness when dozing unless overridden.
+ if (brightness < 0 && (state == Display.STATE_DOZE
+ || state == Display.STATE_DOZE_SUSPEND)) {
+ brightness = mScreenBrightnessDozeConfig;
+ }
+
// Apply manual brightness.
// Use the current brightness setting from the request, which is expected
// provide a nominal default value for the case where auto-brightness
@@ -1021,6 +1039,8 @@
pw.println(" mScreenBrightnessRangeMinimum=" + mScreenBrightnessRangeMinimum);
pw.println(" mScreenBrightnessRangeMaximum=" + mScreenBrightnessRangeMaximum);
pw.println(" mUseSoftwareAutoBrightnessConfig=" + mUseSoftwareAutoBrightnessConfig);
+ pw.println(" mAllowAutoBrightnessWhileDozingConfig=" +
+ mAllowAutoBrightnessWhileDozingConfig);
pw.println(" mColorFadeFadesConfig=" + mColorFadeFadesConfig);
mHandler.runWithScissors(new Runnable() {
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java
index 6bae761..f0f7973 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java
@@ -1029,6 +1029,7 @@
OneTouchRecordAction action = actions.get(0);
if (action.getRecorderAddress() != message.getSource()) {
announceOneTouchRecordResult(
+ message.getSource(),
HdmiControlManager.ONE_TOUCH_RECORD_PREVIOUS_RECORDING_IN_PROGRESS);
}
return super.handleRecordTvScreen(message);
@@ -1047,20 +1048,20 @@
protected boolean handleTimerClearedStatus(HdmiCecMessage message) {
byte[] params = message.getParams();
int timerClearedStatusData = params[0] & 0xFF;
- announceTimerRecordingResult(timerClearedStatusData);
+ announceTimerRecordingResult(message.getSource(), timerClearedStatusData);
return true;
}
- void announceOneTouchRecordResult(int result) {
- mService.invokeOneTouchRecordResult(result);
+ void announceOneTouchRecordResult(int recorderAddress, int result) {
+ mService.invokeOneTouchRecordResult(recorderAddress, result);
}
- void announceTimerRecordingResult(int result) {
- mService.invokeTimerRecordingResult(result);
+ void announceTimerRecordingResult(int recorderAddress, int result) {
+ mService.invokeTimerRecordingResult(recorderAddress, result);
}
- void announceClearTimerRecordingResult(int result) {
- mService.invokeClearTimerRecordingResult(result);
+ void announceClearTimerRecordingResult(int recorderAddress, int result) {
+ mService.invokeClearTimerRecordingResult(recorderAddress, result);
}
private boolean isMessageForSystemAudio(HdmiCecMessage message) {
@@ -1528,19 +1529,21 @@
assertRunOnServiceThread();
if (!mService.isControlEnabled()) {
Slog.w(TAG, "Can not start one touch record. CEC control is disabled.");
- announceOneTouchRecordResult(ONE_TOUCH_RECORD_CEC_DISABLED);
+ announceOneTouchRecordResult(recorderAddress, ONE_TOUCH_RECORD_CEC_DISABLED);
return Constants.ABORT_NOT_IN_CORRECT_MODE;
}
if (!checkRecorder(recorderAddress)) {
Slog.w(TAG, "Invalid recorder address:" + recorderAddress);
- announceOneTouchRecordResult(ONE_TOUCH_RECORD_CHECK_RECORDER_CONNECTION);
+ announceOneTouchRecordResult(recorderAddress,
+ ONE_TOUCH_RECORD_CHECK_RECORDER_CONNECTION);
return Constants.ABORT_NOT_IN_CORRECT_MODE;
}
if (!checkRecordSource(recordSource)) {
Slog.w(TAG, "Invalid record source." + Arrays.toString(recordSource));
- announceOneTouchRecordResult(ONE_TOUCH_RECORD_FAIL_TO_RECORD_DISPLAYED_SCREEN);
+ announceOneTouchRecordResult(recorderAddress,
+ ONE_TOUCH_RECORD_FAIL_TO_RECORD_DISPLAYED_SCREEN);
return Constants.ABORT_UNABLE_TO_DETERMINE;
}
@@ -1555,13 +1558,14 @@
assertRunOnServiceThread();
if (!mService.isControlEnabled()) {
Slog.w(TAG, "Can not stop one touch record. CEC control is disabled.");
- announceOneTouchRecordResult(ONE_TOUCH_RECORD_CEC_DISABLED);
+ announceOneTouchRecordResult(recorderAddress, ONE_TOUCH_RECORD_CEC_DISABLED);
return;
}
if (!checkRecorder(recorderAddress)) {
Slog.w(TAG, "Invalid recorder address:" + recorderAddress);
- announceOneTouchRecordResult(ONE_TOUCH_RECORD_CHECK_RECORDER_CONNECTION);
+ announceOneTouchRecordResult(recorderAddress,
+ ONE_TOUCH_RECORD_CHECK_RECORDER_CONNECTION);
return;
}
@@ -1587,13 +1591,14 @@
assertRunOnServiceThread();
if (!mService.isControlEnabled()) {
Slog.w(TAG, "Can not start one touch record. CEC control is disabled.");
- announceTimerRecordingResult(TIMER_RECORDING_RESULT_EXTRA_CEC_DISABLED);
+ announceTimerRecordingResult(recorderAddress,
+ TIMER_RECORDING_RESULT_EXTRA_CEC_DISABLED);
return;
}
if (!checkRecorder(recorderAddress)) {
Slog.w(TAG, "Invalid recorder address:" + recorderAddress);
- announceTimerRecordingResult(
+ announceTimerRecordingResult(recorderAddress,
TIMER_RECORDING_RESULT_EXTRA_CHECK_RECORDER_CONNECTION);
return;
}
@@ -1601,6 +1606,7 @@
if (!checkTimerRecordingSource(sourceType, recordSource)) {
Slog.w(TAG, "Invalid record source." + Arrays.toString(recordSource));
announceTimerRecordingResult(
+ recorderAddress,
TIMER_RECORDING_RESULT_EXTRA_FAIL_TO_RECORD_SELECTED_SOURCE);
return;
}
@@ -1621,26 +1627,29 @@
assertRunOnServiceThread();
if (!mService.isControlEnabled()) {
Slog.w(TAG, "Can not start one touch record. CEC control is disabled.");
- announceClearTimerRecordingResult(CLEAR_TIMER_STATUS_CEC_DISABLE);
+ announceClearTimerRecordingResult(recorderAddress, CLEAR_TIMER_STATUS_CEC_DISABLE);
return;
}
if (!checkRecorder(recorderAddress)) {
Slog.w(TAG, "Invalid recorder address:" + recorderAddress);
- announceClearTimerRecordingResult(CLEAR_TIMER_STATUS_CHECK_RECORDER_CONNECTION);
+ announceClearTimerRecordingResult(recorderAddress,
+ CLEAR_TIMER_STATUS_CHECK_RECORDER_CONNECTION);
return;
}
if (!checkTimerRecordingSource(sourceType, recordSource)) {
Slog.w(TAG, "Invalid record source." + Arrays.toString(recordSource));
- announceClearTimerRecordingResult(CLEAR_TIMER_STATUS_FAIL_TO_CLEAR_SELECTED_SOURCE);
+ announceClearTimerRecordingResult(recorderAddress,
+ CLEAR_TIMER_STATUS_FAIL_TO_CLEAR_SELECTED_SOURCE);
return;
}
sendClearTimerMessage(recorderAddress, sourceType, recordSource);
}
- private void sendClearTimerMessage(int recorderAddress, int sourceType, byte[] recordSource) {
+ private void sendClearTimerMessage(final int recorderAddress, int sourceType,
+ byte[] recordSource) {
HdmiCecMessage message = null;
switch (sourceType) {
case TIMER_RECORDING_TYPE_DIGITAL:
@@ -1657,7 +1666,8 @@
break;
default:
Slog.w(TAG, "Invalid source type:" + recorderAddress);
- announceClearTimerRecordingResult(CLEAR_TIMER_STATUS_FAIL_TO_CLEAR_SELECTED_SOURCE);
+ announceClearTimerRecordingResult(recorderAddress,
+ CLEAR_TIMER_STATUS_FAIL_TO_CLEAR_SELECTED_SOURCE);
return;
}
@@ -1665,7 +1675,7 @@
@Override
public void onSendCompleted(int error) {
if (error != Constants.SEND_RESULT_SUCCESS) {
- announceClearTimerRecordingResult(
+ announceClearTimerRecordingResult(recorderAddress,
CLEAR_TIMER_STATUS_FAIL_TO_CLEAR_SELECTED_SOURCE);
}
}
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecMessageValidator.java b/services/core/java/com/android/server/hdmi/HdmiCecMessageValidator.java
index d703989..53740fe 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecMessageValidator.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecMessageValidator.java
@@ -29,11 +29,16 @@
static final int ERROR_SOURCE = 1;
static final int ERROR_DESTINATION = 2;
static final int ERROR_PARAMETER = 3;
+ static final int ERROR_PARAMETER_SHORT = 4;
private final HdmiControlService mService;
interface ParameterValidator {
- boolean isValid(byte[] params);
+ /**
+ * @return errorCode errorCode can be {@link #OK}, {@link #ERROR_PARAMETER} or
+ * {@link #ERROR_PARAMETER_SHORT}.
+ */
+ int isValid(byte[] params);
}
// Only the direct addressing is allowed.
@@ -74,7 +79,7 @@
addValidationInfo(Constants.MESSAGE_SET_STREAM_PATH,
physicalAddressValidator, DEST_BROADCAST);
addValidationInfo(Constants.MESSAGE_SYSTEM_AUDIO_MODE_REQUEST,
- physicalAddressValidator, DEST_DIRECT);
+ new SystemAudioModeRequestValidator(), DEST_DIRECT);
// Messages have no parameter.
FixedLengthValidator noneValidator = new FixedLengthValidator(0);
@@ -213,9 +218,10 @@
}
// Check the parameter type.
- if (!info.parameterValidator.isValid(message.getParams())) {
+ int errorCode = info.parameterValidator.isValid(message.getParams());
+ if (errorCode != OK) {
HdmiLogger.warning("Unexpected parameters: " + message);
- return ERROR_PARAMETER;
+ return errorCode;
}
return OK;
}
@@ -228,8 +234,10 @@
}
@Override
- public boolean isValid(byte[] params) {
- return params.length == mLength;
+ public int isValid(byte[] params) {
+ // If the length is longer than expected, we assume it's OK since the parameter can be
+ // extended in the future version.
+ return params.length < mLength ? ERROR_PARAMETER_SHORT : OK;
}
}
@@ -243,8 +251,8 @@
}
@Override
- public boolean isValid(byte[] params) {
- return params.length >= mMinLength && params.length <= mMaxLength;
+ public int isValid(byte[] params) {
+ return params.length < mMinLength ? ERROR_PARAMETER_SHORT : OK;
}
}
@@ -270,8 +278,7 @@
* Check if the given type is valid. A valid type is one of the actual logical device types
* defined in the standard ({@link HdmiDeviceInfo#DEVICE_TV},
* {@link HdmiDeviceInfo#DEVICE_PLAYBACK}, {@link HdmiDeviceInfo#DEVICE_TUNER},
- * {@link HdmiDeviceInfo#DEVICE_RECORDER}, and
- * {@link HdmiDeviceInfo#DEVICE_AUDIO_SYSTEM}).
+ * {@link HdmiDeviceInfo#DEVICE_RECORDER}, and {@link HdmiDeviceInfo#DEVICE_AUDIO_SYSTEM}).
*
* @param type device type
* @return true if the given type is valid
@@ -282,33 +289,49 @@
&& type != HdmiDeviceInfo.DEVICE_RESERVED;
}
+ private static int toErrorCode(boolean success) {
+ return success ? OK : ERROR_PARAMETER;
+ }
+
private class PhysicalAddressValidator implements ParameterValidator {
@Override
- public boolean isValid(byte[] params) {
- if (params.length != 2) {
- return false;
+ public int isValid(byte[] params) {
+ if (params.length < 2) {
+ return ERROR_PARAMETER_SHORT;
}
- return isValidPhysicalAddress(params, 0);
+ return toErrorCode(isValidPhysicalAddress(params, 0));
+ }
+ }
+
+ private class SystemAudioModeRequestValidator extends PhysicalAddressValidator {
+ @Override
+ public int isValid(byte[] params) {
+ // TV can send <System Audio Mode Request> with no parameters to terminate system audio.
+ if (params.length == 0) {
+ return OK;
+ }
+ return super.isValid(params);
}
}
private class ReportPhysicalAddressValidator implements ParameterValidator {
@Override
- public boolean isValid(byte[] params) {
- if (params.length != 3) {
- return false;
+ public int isValid(byte[] params) {
+ if (params.length < 3) {
+ return ERROR_PARAMETER_SHORT;
}
- return isValidPhysicalAddress(params, 0) && isValidType(params[2]);
+ return toErrorCode(isValidPhysicalAddress(params, 0) && isValidType(params[2]));
}
}
private class RoutingChangeValidator implements ParameterValidator {
@Override
- public boolean isValid(byte[] params) {
- if (params.length != 4) {
- return false;
+ public int isValid(byte[] params) {
+ if (params.length < 4) {
+ return ERROR_PARAMETER_SHORT;
}
- return isValidPhysicalAddress(params, 0) && isValidPhysicalAddress(params, 2);
+ return toErrorCode(
+ isValidPhysicalAddress(params, 0) && isValidPhysicalAddress(params, 2));
}
}
}
diff --git a/services/core/java/com/android/server/hdmi/HdmiControlService.java b/services/core/java/com/android/server/hdmi/HdmiControlService.java
index aeb21db..907a49a 100644
--- a/services/core/java/com/android/server/hdmi/HdmiControlService.java
+++ b/services/core/java/com/android/server/hdmi/HdmiControlService.java
@@ -719,7 +719,8 @@
assertRunOnServiceThread();
int errorCode = mMessageValidator.isValid(message);
if (errorCode != HdmiCecMessageValidator.OK) {
- // We'll not response on the messages with the invalid source or destination.
+ // We'll not response on the messages with the invalid source or destination
+ // or with parameter length shorter than specified in the standard.
if (errorCode == HdmiCecMessageValidator.ERROR_PARAMETER) {
maySendFeatureAbortCommand(message, Constants.ABORT_INVALID_OPERAND);
}
@@ -1661,11 +1662,11 @@
}
}
- void invokeOneTouchRecordResult(int result) {
+ void invokeOneTouchRecordResult(int recorderAddress, int result) {
synchronized (mLock) {
if (mRecordListenerRecord != null) {
try {
- mRecordListenerRecord.mListener.onOneTouchRecordResult(result);
+ mRecordListenerRecord.mListener.onOneTouchRecordResult(recorderAddress, result);
} catch (RemoteException e) {
Slog.w(TAG, "Failed to call onOneTouchRecordResult.", e);
}
@@ -1673,11 +1674,11 @@
}
}
- void invokeTimerRecordingResult(int result) {
+ void invokeTimerRecordingResult(int recorderAddress, int result) {
synchronized (mLock) {
if (mRecordListenerRecord != null) {
try {
- mRecordListenerRecord.mListener.onTimerRecordingResult(result);
+ mRecordListenerRecord.mListener.onTimerRecordingResult(recorderAddress, result);
} catch (RemoteException e) {
Slog.w(TAG, "Failed to call onTimerRecordingResult.", e);
}
@@ -1685,11 +1686,12 @@
}
}
- void invokeClearTimerRecordingResult(int result) {
+ void invokeClearTimerRecordingResult(int recorderAddress, int result) {
synchronized (mLock) {
if (mRecordListenerRecord != null) {
try {
- mRecordListenerRecord.mListener.onClearTimerRecordingResult(result);
+ mRecordListenerRecord.mListener.onClearTimerRecordingResult(recorderAddress,
+ result);
} catch (RemoteException e) {
Slog.w(TAG, "Failed to call onClearTimerRecordingResult.", e);
}
diff --git a/services/core/java/com/android/server/hdmi/OneTouchRecordAction.java b/services/core/java/com/android/server/hdmi/OneTouchRecordAction.java
index 906944b..d80b81f6 100644
--- a/services/core/java/com/android/server/hdmi/OneTouchRecordAction.java
+++ b/services/core/java/com/android/server/hdmi/OneTouchRecordAction.java
@@ -64,6 +64,7 @@
// if failed to send <Record On>, display error message and finish action.
if (error != Constants.SEND_RESULT_SUCCESS) {
tv().announceOneTouchRecordResult(
+ mRecorderAddress,
ONE_TOUCH_RECORD_CHECK_RECORDER_CONNECTION);
finish();
return;
@@ -94,7 +95,7 @@
}
int recordStatus = cmd.getParams()[0];
- tv().announceOneTouchRecordResult(recordStatus);
+ tv().announceOneTouchRecordResult(mRecorderAddress, recordStatus);
Slog.i(TAG, "Got record status:" + recordStatus + " from " + cmd.getSource());
// If recording started successfully, change state and keep this action until <Record Off>
@@ -121,7 +122,8 @@
return;
}
- tv().announceOneTouchRecordResult(ONE_TOUCH_RECORD_CHECK_RECORDER_CONNECTION);
+ tv().announceOneTouchRecordResult(mRecorderAddress,
+ ONE_TOUCH_RECORD_CHECK_RECORDER_CONNECTION);
finish();
}
diff --git a/services/core/java/com/android/server/hdmi/TimerRecordingAction.java b/services/core/java/com/android/server/hdmi/TimerRecordingAction.java
index 5fcbc91..16fc25f 100644
--- a/services/core/java/com/android/server/hdmi/TimerRecordingAction.java
+++ b/services/core/java/com/android/server/hdmi/TimerRecordingAction.java
@@ -74,7 +74,7 @@
mRecorderAddress, mRecordSource);
break;
default:
- tv().announceTimerRecordingResult(
+ tv().announceTimerRecordingResult(mRecorderAddress,
TIMER_RECORDING_RESULT_EXTRA_FAIL_TO_RECORD_SELECTED_SOURCE);
finish();
return;
@@ -83,7 +83,7 @@
@Override
public void onSendCompleted(int error) {
if (error != Constants.SEND_RESULT_SUCCESS) {
- tv().announceTimerRecordingResult(
+ tv().announceTimerRecordingResult(mRecorderAddress,
TIMER_RECORDING_RESULT_EXTRA_CHECK_RECORDER_CONNECTION);
finish();
return;
@@ -114,7 +114,7 @@
byte[] timerStatusData = cmd.getParams();
// [Timer Status Data] should be one or three bytes.
if (timerStatusData.length == 1 || timerStatusData.length == 3) {
- tv().announceTimerRecordingResult(bytesToInt(timerStatusData));
+ tv().announceTimerRecordingResult(mRecorderAddress, bytesToInt(timerStatusData));
Slog.i(TAG, "Received [Timer Status Data]:" + Arrays.toString(timerStatusData));
} else {
Slog.w(TAG, "Invalid [Timer Status Data]:" + Arrays.toString(timerStatusData));
@@ -138,7 +138,8 @@
}
int reason = params[1] & 0xFF;
Slog.i(TAG, "[Feature Abort] for " + messageType + " reason:" + reason);
- tv().announceTimerRecordingResult(TIMER_RECORDING_RESULT_EXTRA_CHECK_RECORDER_CONNECTION);
+ tv().announceTimerRecordingResult(mRecorderAddress,
+ TIMER_RECORDING_RESULT_EXTRA_CHECK_RECORDER_CONNECTION);
finish();
return true;
}
@@ -163,7 +164,8 @@
return;
}
- tv().announceTimerRecordingResult(TIMER_RECORDING_RESULT_EXTRA_CHECK_RECORDER_CONNECTION);
+ tv().announceTimerRecordingResult(mRecorderAddress,
+ TIMER_RECORDING_RESULT_EXTRA_CHECK_RECORDER_CONNECTION);
finish();
}
}
diff --git a/services/core/java/com/android/server/location/GpsLocationProvider.java b/services/core/java/com/android/server/location/GpsLocationProvider.java
index 0198e46..c2cb4b1 100644
--- a/services/core/java/com/android/server/location/GpsLocationProvider.java
+++ b/services/core/java/com/android/server/location/GpsLocationProvider.java
@@ -473,14 +473,7 @@
checkSmsSuplInit(intent);
} else if (action.equals(Intents.WAP_PUSH_RECEIVED_ACTION)) {
checkWapSuplInit(intent);
- } else if (action.equals(ConnectivityManager.CONNECTIVITY_ACTION)) {
- int networkState;
- if (intent.getBooleanExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY, false)) {
- networkState = LocationProvider.TEMPORARILY_UNAVAILABLE;
- } else {
- networkState = LocationProvider.AVAILABLE;
- }
-
+ } else if (action.equals(ConnectivityManager.CONNECTIVITY_ACTION_IMMEDIATE)) {
// retrieve NetworkInfo result for this UID
NetworkInfo info =
intent.getParcelableExtra(ConnectivityManager.EXTRA_NETWORK_INFO);
@@ -488,6 +481,15 @@
mContext.getSystemService(Context.CONNECTIVITY_SERVICE);
info = connManager.getNetworkInfo(info.getType());
+ int networkState;
+ if (intent.getBooleanExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY, false) ||
+ !info.isConnected()) {
+ networkState = LocationProvider.TEMPORARILY_UNAVAILABLE;
+ } else {
+ networkState = LocationProvider.AVAILABLE;
+ }
+
+
updateNetworkState(networkState, info);
} else if (PowerManager.ACTION_POWER_SAVE_MODE_CHANGED.equals(action)
|| Intent.ACTION_SCREEN_OFF.equals(action)
@@ -715,7 +717,7 @@
intentFilter = new IntentFilter();
intentFilter.addAction(ALARM_WAKEUP);
intentFilter.addAction(ALARM_TIMEOUT);
- intentFilter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
+ intentFilter.addAction(ConnectivityManager.CONNECTIVITY_ACTION_IMMEDIATE);
intentFilter.addAction(PowerManager.ACTION_POWER_SAVE_MODE_CHANGED);
intentFilter.addAction(Intent.ACTION_SCREEN_OFF);
intentFilter.addAction(Intent.ACTION_SCREEN_ON);
diff --git a/services/core/java/com/android/server/notification/ConditionProviders.java b/services/core/java/com/android/server/notification/ConditionProviders.java
index 05ad1fe..3ff9ff4 100644
--- a/services/core/java/com/android/server/notification/ConditionProviders.java
+++ b/services/core/java/com/android/server/notification/ConditionProviders.java
@@ -52,6 +52,7 @@
private final ArrayList<ConditionRecord> mRecords = new ArrayList<ConditionRecord>();
private final CountdownConditionProvider mCountdown = new CountdownConditionProvider();
private final DowntimeConditionProvider mDowntime = new DowntimeConditionProvider();
+ private final NextAlarmConditionProvider mNextAlarm = new NextAlarmConditionProvider();
private Condition mExitCondition;
private ComponentName mExitConditionComponent;
@@ -99,6 +100,7 @@
}
mCountdown.dump(pw, filter);
mDowntime.dump(pw, filter);
+ mNextAlarm.dump(pw, filter);
}
@Override
@@ -116,6 +118,23 @@
registerService(mDowntime.asInterface(), DowntimeConditionProvider.COMPONENT,
UserHandle.USER_OWNER);
mDowntime.setCallback(new DowntimeCallback());
+ mNextAlarm.attachBase(mContext);
+ registerService(mNextAlarm.asInterface(), NextAlarmConditionProvider.COMPONENT,
+ UserHandle.USER_OWNER);
+ mNextAlarm.setCallback(new NextAlarmConditionProvider.Callback() {
+ @Override
+ public boolean isInDowntime() {
+ return mDowntime.isInDowntime();
+ }
+ });
+ }
+
+ @Override
+ public void onUserSwitched() {
+ super.onUserSwitched();
+ if (mNextAlarm != null) {
+ mNextAlarm.onUserSwitched();
+ }
}
@Override
@@ -534,20 +553,22 @@
private class DowntimeCallback implements DowntimeConditionProvider.Callback {
@Override
- public void onDowntimeChanged(boolean inDowntime) {
+ public void onDowntimeChanged(int downtimeMode) {
final int mode = mZenModeHelper.getZenMode();
final ZenModeConfig config = mZenModeHelper.getConfig();
- // enter downtime
- if (inDowntime && mode == Global.ZEN_MODE_OFF && config != null) {
+ final boolean inDowntime = downtimeMode == Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS
+ || downtimeMode == Global.ZEN_MODE_NO_INTERRUPTIONS;
+ final boolean downtimeCurrent = mDowntime.isDowntimeCondition(mExitCondition);
+ // enter downtime, or update mode if reconfigured during an active downtime
+ if (inDowntime && (mode == Global.ZEN_MODE_OFF || downtimeCurrent) && config != null) {
final Condition condition = mDowntime.createCondition(config.toDowntimeInfo(),
Condition.STATE_TRUE);
- mZenModeHelper.setZenMode(Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS, "downtimeEnter");
+ mZenModeHelper.setZenMode(downtimeMode, "downtimeEnter");
setZenModeCondition(condition, "downtime");
}
// exit downtime
- if (!inDowntime && mDowntime.isDowntimeCondition(mExitCondition)
- && (mode == Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS
- || mode == Global.ZEN_MODE_NO_INTERRUPTIONS)) {
+ if (!inDowntime && downtimeCurrent && (mode == Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS
+ || mode == Global.ZEN_MODE_NO_INTERRUPTIONS)) {
mZenModeHelper.setZenMode(Global.ZEN_MODE_OFF, "downtimeExit");
}
}
diff --git a/services/core/java/com/android/server/notification/DowntimeConditionProvider.java b/services/core/java/com/android/server/notification/DowntimeConditionProvider.java
index efe47c3..881c9ad 100644
--- a/services/core/java/com/android/server/notification/DowntimeConditionProvider.java
+++ b/services/core/java/com/android/server/notification/DowntimeConditionProvider.java
@@ -24,6 +24,7 @@
import android.content.Intent;
import android.content.IntentFilter;
import android.net.Uri;
+import android.provider.Settings.Global;
import android.service.notification.Condition;
import android.service.notification.ConditionProviderService;
import android.service.notification.IConditionProvider;
@@ -64,7 +65,7 @@
private final ArraySet<Integer> mDays = new ArraySet<Integer>();
private boolean mConnected;
- private boolean mInDowntime;
+ private int mDowntimeMode;
private ZenModeConfig mConfig;
private Callback mCallback;
@@ -75,7 +76,7 @@
public void dump(PrintWriter pw, DumpFilter filter) {
pw.println(" DowntimeConditionProvider:");
pw.print(" mConnected="); pw.println(mConnected);
- pw.print(" mInDowntime="); pw.println(mInDowntime);
+ pw.print(" mDowntimeMode="); pw.println(Global.zenModeToString(mDowntimeMode));
}
public void attachBase(Context base) {
@@ -113,7 +114,7 @@
public void onRequestConditions(int relevance) {
if (DEBUG) Slog.d(TAG, "onRequestConditions relevance=" + relevance);
if ((relevance & Condition.FLAG_RELEVANT_NOW) != 0) {
- if (mInDowntime && mConfig != null) {
+ if (isInDowntime() && mConfig != null) {
notifyCondition(createCondition(mConfig.toDowntimeInfo(), Condition.STATE_TRUE));
}
}
@@ -124,7 +125,7 @@
if (DEBUG) Slog.d(TAG, "onSubscribe conditionId=" + conditionId);
final DowntimeInfo downtime = ZenModeConfig.tryParseDowntimeConditionId(conditionId);
if (downtime != null && mConfig != null) {
- final int state = mConfig.toDowntimeInfo().equals(downtime) && mInDowntime
+ final int state = mConfig.toDowntimeInfo().equals(downtime) && isInDowntime()
? Condition.STATE_TRUE : Condition.STATE_FALSE;
if (DEBUG) Slog.d(TAG, "notify condition state: " + Condition.stateToString(state));
notifyCondition(createCondition(downtime, state));
@@ -146,7 +147,7 @@
}
public boolean isInDowntime() {
- return mInDowntime;
+ return mDowntimeMode != Global.ZEN_MODE_OFF;
}
public Condition createCondition(DowntimeInfo downtime, int state) {
@@ -158,7 +159,8 @@
final long time = getTime(System.currentTimeMillis(), downtime.endHour, downtime.endMinute);
final String formatted = new SimpleDateFormat(pattern, locale).format(new Date(time));
final String summary = mContext.getString(R.string.downtime_condition_summary, formatted);
- return new Condition(id, summary, "", "", 0, state, Condition.FLAG_RELEVANT_NOW);
+ final String line1 = mContext.getString(R.string.downtime_condition_line_one);
+ return new Condition(id, summary, line1, formatted, 0, state, Condition.FLAG_RELEVANT_NOW);
}
public boolean isDowntimeCondition(Condition condition) {
@@ -181,15 +183,18 @@
}
}
- private boolean isInDowntime(long time) {
- if (mConfig == null || mDays.size() == 0) return false;
+ private int computeDowntimeMode(long time) {
+ if (mConfig == null || mDays.size() == 0) return Global.ZEN_MODE_OFF;
final long start = getTime(time, mConfig.sleepStartHour, mConfig.sleepStartMinute);
long end = getTime(time, mConfig.sleepEndHour, mConfig.sleepEndMinute);
- if (start == end) return false;
+ if (start == end) return Global.ZEN_MODE_OFF;
if (end < start) {
end = addDays(end, 1);
}
- return isInDowntime(-1, time, start, end) || isInDowntime(0, time, start, end);
+ final boolean inDowntime = isInDowntime(-1, time, start, end)
+ || isInDowntime(0, time, start, end);
+ return inDowntime ? (mConfig.sleepNone ? Global.ZEN_MODE_NO_INTERRUPTIONS
+ : Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS) : Global.ZEN_MODE_OFF;
}
private boolean isInDowntime(int daysOffset, long time, long start, long end) {
@@ -201,18 +206,18 @@
}
private void reevaluateDowntime() {
- final boolean inDowntime = isInDowntime(System.currentTimeMillis());
- if (DEBUG) Slog.d(TAG, "inDowntime=" + inDowntime);
- if (inDowntime == mInDowntime) return;
- Slog.i(TAG, (inDowntime ? "Entering" : "Exiting" ) + " downtime");
- mInDowntime = inDowntime;
- ZenLog.traceDowntime(mInDowntime, getDayOfWeek(System.currentTimeMillis()), mDays);
+ final int downtimeMode = computeDowntimeMode(System.currentTimeMillis());
+ if (DEBUG) Slog.d(TAG, "downtimeMode=" + downtimeMode);
+ if (downtimeMode == mDowntimeMode) return;
+ mDowntimeMode = downtimeMode;
+ Slog.i(TAG, (isInDowntime() ? "Entering" : "Exiting" ) + " downtime");
+ ZenLog.traceDowntime(mDowntimeMode, getDayOfWeek(System.currentTimeMillis()), mDays);
fireDowntimeChanged();
}
private void fireDowntimeChanged() {
if (mCallback != null) {
- mCallback.onDowntimeChanged(mInDowntime);
+ mCallback.onDowntimeChanged(mDowntimeMode);
}
}
@@ -255,7 +260,10 @@
time = addDays(time, 1);
}
final PendingIntent pendingIntent = PendingIntent.getBroadcast(mContext, requestCode,
- new Intent(action).putExtra(EXTRA_TIME, time), PendingIntent.FLAG_UPDATE_CURRENT);
+ new Intent(action)
+ .addFlags(Intent.FLAG_RECEIVER_FOREGROUND)
+ .putExtra(EXTRA_TIME, time),
+ PendingIntent.FLAG_UPDATE_CURRENT);
alarms.cancel(pendingIntent);
if (mConfig.sleepMode != null) {
if (DEBUG) Slog.d(TAG, String.format("Scheduling %s for %s, %s in the future, now=%s",
@@ -289,6 +297,6 @@
};
public interface Callback {
- void onDowntimeChanged(boolean inDowntime);
+ void onDowntimeChanged(int downtimeMode);
}
}
diff --git a/services/core/java/com/android/server/notification/NextAlarmConditionProvider.java b/services/core/java/com/android/server/notification/NextAlarmConditionProvider.java
new file mode 100644
index 0000000..dba203b
--- /dev/null
+++ b/services/core/java/com/android/server/notification/NextAlarmConditionProvider.java
@@ -0,0 +1,318 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.notification;
+
+import android.app.ActivityManager;
+import android.app.AlarmManager;
+import android.app.PendingIntent;
+import android.app.AlarmManager.AlarmClockInfo;
+import android.content.BroadcastReceiver;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.net.Uri;
+import android.os.Handler;
+import android.os.Message;
+import android.os.PowerManager;
+import android.os.UserHandle;
+import android.service.notification.Condition;
+import android.service.notification.ConditionProviderService;
+import android.service.notification.IConditionProvider;
+import android.service.notification.ZenModeConfig;
+import android.util.TimeUtils;
+import android.text.format.DateFormat;
+import android.util.Log;
+import android.util.Slog;
+
+import com.android.internal.R;
+import com.android.server.notification.NotificationManagerService.DumpFilter;
+
+import java.io.PrintWriter;
+import java.util.Locale;
+
+/** Built-in zen condition provider for alarm clock conditions */
+public class NextAlarmConditionProvider extends ConditionProviderService {
+ private static final String TAG = "NextAlarmConditions";
+ private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
+
+ private static final String ACTION_TRIGGER = TAG + ".trigger";
+ private static final String EXTRA_TRIGGER = "trigger";
+ private static final int REQUEST_CODE = 100;
+ private static final long SECONDS = 1000;
+ private static final long HOURS = 60 * 60 * SECONDS;
+ private static final long NEXT_ALARM_UPDATE_DELAY = 1 * SECONDS; // treat clear+set as update
+ private static final long EARLY = 5 * SECONDS; // fire early, ensure alarm stream is unmuted
+ private static final String NEXT_ALARM_PATH = "next_alarm";
+ public static final ComponentName COMPONENT =
+ new ComponentName("android", NextAlarmConditionProvider.class.getName());
+
+ private final Context mContext = this;
+ private final H mHandler = new H();
+
+ private boolean mConnected;
+ private boolean mRegistered;
+ private AlarmManager mAlarmManager;
+ private int mCurrentUserId;
+ private long mLookaheadThreshold;
+ private long mScheduledAlarmTime;
+ private Callback mCallback;
+ private Uri mCurrentSubscription;
+ private PowerManager.WakeLock mWakeLock;
+
+ public NextAlarmConditionProvider() {
+ if (DEBUG) Slog.d(TAG, "new NextAlarmConditionProvider()");
+ }
+
+ public void dump(PrintWriter pw, DumpFilter filter) {
+ pw.println(" NextAlarmConditionProvider:");
+ pw.print(" mConnected="); pw.println(mConnected);
+ pw.print(" mRegistered="); pw.println(mRegistered);
+ pw.print(" mCurrentUserId="); pw.println(mCurrentUserId);
+ pw.print(" mScheduledAlarmTime="); pw.println(formatAlarmDebug(mScheduledAlarmTime));
+ pw.print(" mLookaheadThreshold="); pw.print(mLookaheadThreshold);
+ pw.print(" ("); TimeUtils.formatDuration(mLookaheadThreshold, pw); pw.println(")");
+ pw.print(" mCurrentSubscription="); pw.println(mCurrentSubscription);
+ pw.print(" mWakeLock="); pw.println(mWakeLock);
+ }
+
+ public void setCallback(Callback callback) {
+ mCallback = callback;
+ }
+
+ @Override
+ public void onConnected() {
+ if (DEBUG) Slog.d(TAG, "onConnected");
+ mAlarmManager = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE);
+ final PowerManager p = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
+ mWakeLock = p.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG);
+ mLookaheadThreshold = mContext.getResources()
+ .getInteger(R.integer.config_next_alarm_condition_lookahead_threshold_hrs) * HOURS;
+ init();
+ mConnected = true;
+ }
+
+ public void onUserSwitched() {
+ if (DEBUG) Slog.d(TAG, "onUserSwitched");
+ if (mConnected) {
+ init();
+ }
+ }
+
+ @Override
+ public void onDestroy() {
+ super.onDestroy();
+ if (DEBUG) Slog.d(TAG, "onDestroy");
+ if (mConnected) {
+ mContext.unregisterReceiver(mReceiver);
+ }
+ mConnected = false;
+ }
+
+ @Override
+ public void onRequestConditions(int relevance) {
+ if (!mConnected || (relevance & Condition.FLAG_RELEVANT_NOW) == 0) return;
+
+ final AlarmClockInfo nextAlarm = mAlarmManager.getNextAlarmClock(mCurrentUserId);
+ if (nextAlarm == null) return; // no next alarm
+ if (mCallback != null && mCallback.isInDowntime()) return; // prefer downtime condition
+ if (!isWithinLookaheadThreshold(nextAlarm)) return; // alarm not within window
+
+ // next alarm exists, and is within the configured lookahead threshold
+ notifyCondition(newConditionId(), nextAlarm, true, "request");
+ }
+
+ private boolean isWithinLookaheadThreshold(AlarmClockInfo alarm) {
+ if (alarm == null) return false;
+ final long delta = getEarlyTriggerTime(alarm) - System.currentTimeMillis();
+ return delta > 0 && (mLookaheadThreshold <= 0 || delta < mLookaheadThreshold);
+ }
+
+ @Override
+ public void onSubscribe(Uri conditionId) {
+ if (DEBUG) Slog.d(TAG, "onSubscribe " + conditionId);
+ if (!isNextAlarmCondition(conditionId)) {
+ notifyCondition(conditionId, null, false, "badCondition");
+ return;
+ }
+ mCurrentSubscription = conditionId;
+ mHandler.postEvaluate(0);
+ }
+
+ private static long getEarlyTriggerTime(AlarmClockInfo alarm) {
+ return alarm != null ? (alarm.getTriggerTime() - EARLY) : 0;
+ }
+
+ private void handleEvaluate() {
+ final AlarmClockInfo nextAlarm = mAlarmManager.getNextAlarmClock(mCurrentUserId);
+ final long triggerTime = getEarlyTriggerTime(nextAlarm);
+ final boolean withinThreshold = isWithinLookaheadThreshold(nextAlarm);
+ if (DEBUG) Slog.d(TAG, "handleEvaluate mCurrentSubscription=" + mCurrentSubscription
+ + " nextAlarm=" + formatAlarmDebug(triggerTime)
+ + " withinThreshold=" + withinThreshold);
+ if (mCurrentSubscription == null) return; // no one cares
+ if (!withinThreshold) {
+ // triggertime invalid or in the past, condition = false
+ notifyCondition(mCurrentSubscription, nextAlarm, false, "!withinThreshold");
+ mCurrentSubscription = null;
+ return;
+ }
+ // triggertime in the future, condition = true, schedule alarm
+ notifyCondition(mCurrentSubscription, nextAlarm, true, "withinThreshold");
+ rescheduleAlarm(triggerTime);
+ }
+
+ private static String formatDuration(long millis) {
+ final StringBuilder sb = new StringBuilder();
+ TimeUtils.formatDuration(millis, sb);
+ return sb.toString();
+ }
+
+ private void rescheduleAlarm(long time) {
+ if (DEBUG) Slog.d(TAG, "rescheduleAlarm " + time);
+ final AlarmManager alarms = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE);
+ final PendingIntent pendingIntent = PendingIntent.getBroadcast(mContext, REQUEST_CODE,
+ new Intent(ACTION_TRIGGER)
+ .addFlags(Intent.FLAG_RECEIVER_FOREGROUND)
+ .putExtra(EXTRA_TRIGGER, time),
+ PendingIntent.FLAG_UPDATE_CURRENT);
+ alarms.cancel(pendingIntent);
+ mScheduledAlarmTime = time;
+ if (time > 0) {
+ if (DEBUG) Slog.d(TAG, String.format("Scheduling alarm for %s (in %s)",
+ formatAlarmDebug(time), formatDuration(time - System.currentTimeMillis())));
+ alarms.setExact(AlarmManager.RTC_WAKEUP, time, pendingIntent);
+ }
+ }
+
+ private void notifyCondition(Uri id, AlarmClockInfo alarm, boolean state, String reason) {
+ final String formattedAlarm = alarm == null ? "" : formatAlarm(alarm.getTriggerTime());
+ if (DEBUG) Slog.d(TAG, "notifyCondition " + state + " alarm=" + formattedAlarm + " reason="
+ + reason);
+ notifyCondition(new Condition(id,
+ mContext.getString(R.string.zen_mode_next_alarm_summary, formattedAlarm),
+ mContext.getString(R.string.zen_mode_next_alarm_line_one),
+ formattedAlarm, 0,
+ state ? Condition.STATE_TRUE : Condition.STATE_FALSE,
+ Condition.FLAG_RELEVANT_NOW));
+ }
+
+ @Override
+ public void onUnsubscribe(Uri conditionId) {
+ if (DEBUG) Slog.d(TAG, "onUnsubscribe " + conditionId);
+ if (conditionId != null && conditionId.equals(mCurrentSubscription)) {
+ mCurrentSubscription = null;
+ rescheduleAlarm(0);
+ }
+ }
+
+ public void attachBase(Context base) {
+ attachBaseContext(base);
+ }
+
+ public IConditionProvider asInterface() {
+ return (IConditionProvider) onBind(null);
+ }
+
+ private Uri newConditionId() {
+ return new Uri.Builder().scheme(Condition.SCHEME)
+ .authority(ZenModeConfig.SYSTEM_AUTHORITY)
+ .appendPath(NEXT_ALARM_PATH)
+ .appendPath(Integer.toString(mCurrentUserId))
+ .build();
+ }
+
+ private boolean isNextAlarmCondition(Uri conditionId) {
+ return conditionId != null && conditionId.getScheme().equals(Condition.SCHEME)
+ && conditionId.getAuthority().equals(ZenModeConfig.SYSTEM_AUTHORITY)
+ && conditionId.getPathSegments().size() == 2
+ && conditionId.getPathSegments().get(0).equals(NEXT_ALARM_PATH)
+ && conditionId.getPathSegments().get(1).equals(Integer.toString(mCurrentUserId));
+ }
+
+ private void init() {
+ if (mRegistered) {
+ mContext.unregisterReceiver(mReceiver);
+ }
+ mCurrentUserId = ActivityManager.getCurrentUser();
+ final IntentFilter filter = new IntentFilter();
+ filter.addAction(AlarmManager.ACTION_NEXT_ALARM_CLOCK_CHANGED);
+ filter.addAction(ACTION_TRIGGER);
+ filter.addAction(Intent.ACTION_TIME_CHANGED);
+ filter.addAction(Intent.ACTION_TIMEZONE_CHANGED);
+ mContext.registerReceiverAsUser(mReceiver, new UserHandle(mCurrentUserId), filter, null,
+ null);
+ mRegistered = true;
+ mHandler.postEvaluate(0);
+ }
+
+ private String formatAlarm(long time) {
+ return formatAlarm(time, "Hm", "hma");
+ }
+
+ private String formatAlarm(long time, String skeleton24, String skeleton12) {
+ final String skeleton = DateFormat.is24HourFormat(mContext) ? skeleton24 : skeleton12;
+ final String pattern = DateFormat.getBestDateTimePattern(Locale.getDefault(), skeleton);
+ return DateFormat.format(pattern, time).toString();
+ }
+
+ private String formatAlarmDebug(AlarmClockInfo alarm) {
+ return formatAlarmDebug(alarm != null ? alarm.getTriggerTime() : 0);
+ }
+
+ private String formatAlarmDebug(long time) {
+ if (time <= 0) return Long.toString(time);
+ return String.format("%s (%s)", time, formatAlarm(time, "Hms", "hmsa"));
+ }
+
+ private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ final String action = intent.getAction();
+ if (DEBUG) Slog.d(TAG, "onReceive " + action);
+ long delay = 0;
+ if (action.equals(AlarmManager.ACTION_NEXT_ALARM_CLOCK_CHANGED)) {
+ delay = NEXT_ALARM_UPDATE_DELAY;
+ if (DEBUG) Slog.d(TAG, String.format(" next alarm for user %s: %s",
+ mCurrentUserId,
+ formatAlarmDebug(mAlarmManager.getNextAlarmClock(mCurrentUserId))));
+ }
+ mHandler.postEvaluate(delay);
+ mWakeLock.acquire(delay + 5000); // stay awake during evaluate
+ }
+ };
+
+ public interface Callback {
+ boolean isInDowntime();
+ }
+
+ private class H extends Handler {
+ private static final int MSG_EVALUATE = 1;
+
+ public void postEvaluate(long delay) {
+ removeMessages(MSG_EVALUATE);
+ sendEmptyMessageDelayed(MSG_EVALUATE, delay);
+ }
+
+ @Override
+ public void handleMessage(Message msg) {
+ if (msg.what == MSG_EVALUATE) {
+ handleEvaluate();
+ }
+ }
+ }
+}
diff --git a/services/core/java/com/android/server/notification/ZenLog.java b/services/core/java/com/android/server/notification/ZenLog.java
index e0b83de..1a3da79 100644
--- a/services/core/java/com/android/server/notification/ZenLog.java
+++ b/services/core/java/com/android/server/notification/ZenLog.java
@@ -75,8 +75,8 @@
append(TYPE_SET_RINGER_MODE, ringerModeToString(ringerMode));
}
- public static void traceDowntime(boolean inDowntime, int day, ArraySet<Integer> days) {
- append(TYPE_DOWNTIME, inDowntime + ",day=" + day + ",days=" + days);
+ public static void traceDowntime(int downtimeMode, int day, ArraySet<Integer> days) {
+ append(TYPE_DOWNTIME, zenModeToString(downtimeMode) + ",day=" + day + ",days=" + days);
}
public static void traceSetZenMode(int mode, String reason) {
diff --git a/services/core/java/com/android/server/power/PowerManagerService.java b/services/core/java/com/android/server/power/PowerManagerService.java
index 5e95dfe..8682f5c 100644
--- a/services/core/java/com/android/server/power/PowerManagerService.java
+++ b/services/core/java/com/android/server/power/PowerManagerService.java
@@ -88,6 +88,8 @@
private static final int MSG_USER_ACTIVITY_TIMEOUT = 1;
// Message: Sent when the device enters or exits a dreaming or dozing state.
private static final int MSG_SANDMAN = 2;
+ // Message: Sent when the screen brightness boost expires.
+ private static final int MSG_SCREEN_BRIGHTNESS_BOOST_TIMEOUT = 3;
// Dirty bit: mWakeLocks changed
private static final int DIRTY_WAKE_LOCKS = 1 << 0;
@@ -111,6 +113,8 @@
private static final int DIRTY_PROXIMITY_POSITIVE = 1 << 9;
// Dirty bit: dock state changed
private static final int DIRTY_DOCK_STATE = 1 << 10;
+ // Dirty bit: brightness boost changed
+ private static final int DIRTY_SCREEN_BRIGHTNESS_BOOST = 1 << 11;
// Wakefulness: The device is asleep and can only be awoken by a call to wakeUp().
// The screen should be off or in the process of being turned off by the display controller.
@@ -149,6 +153,11 @@
private static final int DEFAULT_SCREEN_OFF_TIMEOUT = 15 * 1000;
private static final int DEFAULT_SLEEP_TIMEOUT = -1;
+ // Screen brightness boost timeout.
+ // Hardcoded for now until we decide what the right policy should be.
+ // This should perhaps be a setting.
+ private static final int SCREEN_BRIGHTNESS_BOOST_TIMEOUT = 5 * 1000;
+
// Power hints defined in hardware/libhardware/include/hardware/power.h.
private static final int POWER_HINT_INTERACTION = 2;
private static final int POWER_HINT_LOW_POWER = 5;
@@ -215,6 +224,10 @@
// Timestamp of last interactive power hint.
private long mLastInteractivePowerHintTime;
+ // Timestamp of the last screen brightness boost.
+ private long mLastScreenBrightnessBoostTime;
+ private boolean mScreenBrightnessBoostInProgress;
+
// A bitfield that summarizes the effect of the user activity timer.
private int mUserActivitySummary;
@@ -1812,9 +1825,13 @@
final boolean oldDisplayReady = mDisplayReady;
if ((dirty & (DIRTY_WAKE_LOCKS | DIRTY_USER_ACTIVITY | DIRTY_WAKEFULNESS
| DIRTY_ACTUAL_DISPLAY_POWER_STATE_UPDATED | DIRTY_BOOT_COMPLETED
- | DIRTY_SETTINGS)) != 0) {
+ | DIRTY_SETTINGS | DIRTY_SCREEN_BRIGHTNESS_BOOST)) != 0) {
mDisplayPowerRequest.policy = getDesiredScreenPolicyLocked();
+ // Handle screen brightness boost timeout.
+ updateScreenBrightnessBoostLocked();
+
+ // Determine appropriate screen brightness and auto-brightness adjustments.
int screenBrightness = mScreenBrightnessSettingDefault;
float screenAutoBrightnessAdjustment = 0.0f;
boolean autoBrightness = (mScreenBrightnessModeSetting ==
@@ -1842,14 +1859,15 @@
mScreenBrightnessSettingMaximum), mScreenBrightnessSettingMinimum);
screenAutoBrightnessAdjustment = Math.max(Math.min(
screenAutoBrightnessAdjustment, 1.0f), -1.0f);
+
+ // Update display power request.
mDisplayPowerRequest.screenBrightness = screenBrightness;
mDisplayPowerRequest.screenAutoBrightnessAdjustment =
screenAutoBrightnessAdjustment;
mDisplayPowerRequest.useAutoBrightness = autoBrightness;
-
mDisplayPowerRequest.useProximitySensor = shouldUseProximitySensorLocked();
-
mDisplayPowerRequest.lowPowerMode = mLowPowerModeEnabled;
+ mDisplayPowerRequest.boostScreenBrightness = mScreenBrightnessBoostInProgress;
if (mDisplayPowerRequest.policy == DisplayPowerRequest.POLICY_DOZE) {
mDisplayPowerRequest.dozeScreenState = mDozeScreenStateOverrideFromDreamManager;
@@ -1861,21 +1879,40 @@
}
mDisplayReady = mDisplayManagerInternal.requestPowerState(mDisplayPowerRequest,
- mRequestWaitForNegativeProximity);
+ mRequestWaitForNegativeProximity) && !mScreenBrightnessBoostInProgress;
mRequestWaitForNegativeProximity = false;
if (DEBUG_SPEW) {
- Slog.d(TAG, "updateScreenStateLocked: mDisplayReady=" + mDisplayReady
+ Slog.d(TAG, "updateDisplayPowerStateLocked: mDisplayReady=" + mDisplayReady
+ ", policy=" + mDisplayPowerRequest.policy
+ ", mWakefulness=" + mWakefulness
+ ", mWakeLockSummary=0x" + Integer.toHexString(mWakeLockSummary)
+ ", mUserActivitySummary=0x" + Integer.toHexString(mUserActivitySummary)
- + ", mBootCompleted=" + mBootCompleted);
+ + ", mBootCompleted=" + mBootCompleted
+ + ", mScreenBrightnessBoostInProgress="
+ + mScreenBrightnessBoostInProgress);
}
}
return mDisplayReady && !oldDisplayReady;
}
+ private void updateScreenBrightnessBoostLocked() {
+ if (mScreenBrightnessBoostInProgress) {
+ mHandler.removeMessages(MSG_SCREEN_BRIGHTNESS_BOOST_TIMEOUT);
+ if (mLastScreenBrightnessBoostTime > mLastSleepTime) {
+ final long boostTimeout = mLastScreenBrightnessBoostTime +
+ SCREEN_BRIGHTNESS_BOOST_TIMEOUT;
+ if (boostTimeout > SystemClock.uptimeMillis()) {
+ Message msg = mHandler.obtainMessage(MSG_SCREEN_BRIGHTNESS_BOOST_TIMEOUT);
+ msg.setAsynchronous(true);
+ mHandler.sendMessageAtTime(msg, boostTimeout);
+ return;
+ }
+ }
+ mScreenBrightnessBoostInProgress = false;
+ }
+ }
+
private static boolean isValidBrightness(int value) {
return value >= 0 && value <= 255;
}
@@ -2223,6 +2260,41 @@
light.setFlashing(color, Light.LIGHT_FLASH_HARDWARE, (on ? 3 : 0), 0);
}
+ private void boostScreenBrightnessInternal(long eventTime, int uid) {
+ synchronized (mLock) {
+ if (!mSystemReady || mWakefulness == WAKEFULNESS_ASLEEP
+ || eventTime < mLastScreenBrightnessBoostTime) {
+ return;
+ }
+
+ Slog.i(TAG, "Brightness boost activated (uid " + uid +")...");
+ mLastScreenBrightnessBoostTime = eventTime;
+ mScreenBrightnessBoostInProgress = true;
+ mDirty |= DIRTY_SCREEN_BRIGHTNESS_BOOST;
+
+ userActivityNoUpdateLocked(eventTime,
+ PowerManager.USER_ACTIVITY_EVENT_OTHER, 0, uid);
+ updatePowerStateLocked();
+ }
+ }
+
+ /**
+ * Called when a screen brightness boost timeout has occurred.
+ *
+ * This function must have no other side-effects besides setting the dirty
+ * bit and calling update power state.
+ */
+ private void handleScreenBrightnessBoostTimeout() { // runs on handler thread
+ synchronized (mLock) {
+ if (DEBUG_SPEW) {
+ Slog.d(TAG, "handleScreenBrightnessBoostTimeout");
+ }
+
+ mDirty |= DIRTY_SCREEN_BRIGHTNESS_BOOST;
+ updatePowerStateLocked();
+ }
+ }
+
private void setScreenBrightnessOverrideFromWindowManagerInternal(int brightness) {
synchronized (mLock) {
if (mScreenBrightnessOverrideFromWindowManager != brightness) {
@@ -2366,6 +2438,10 @@
+ TimeUtils.formatUptime(mLastUserActivityTimeNoChangeLights));
pw.println(" mLastInteractivePowerHintTime="
+ TimeUtils.formatUptime(mLastInteractivePowerHintTime));
+ pw.println(" mLastScreenBrightnessBoostTime="
+ + TimeUtils.formatUptime(mLastScreenBrightnessBoostTime));
+ pw.println(" mScreenBrightnessBoostInProgress="
+ + mScreenBrightnessBoostInProgress);
pw.println(" mDisplayReady=" + mDisplayReady);
pw.println(" mHoldingWakeLockSuspendBlocker=" + mHoldingWakeLockSuspendBlocker);
pw.println(" mHoldingDisplaySuspendBlocker=" + mHoldingDisplaySuspendBlocker);
@@ -2562,6 +2638,9 @@
case MSG_SANDMAN:
handleSandman();
break;
+ case MSG_SCREEN_BRIGHTNESS_BOOST_TIMEOUT:
+ handleScreenBrightnessBoostTimeout();
+ break;
}
}
}
@@ -3143,6 +3222,24 @@
}
@Override // Binder call
+ public void boostScreenBrightness(long eventTime) {
+ if (eventTime > SystemClock.uptimeMillis()) {
+ throw new IllegalArgumentException("event time must not be in the future");
+ }
+
+ mContext.enforceCallingOrSelfPermission(
+ android.Manifest.permission.DEVICE_POWER, null);
+
+ final int uid = Binder.getCallingUid();
+ final long ident = Binder.clearCallingIdentity();
+ try {
+ boostScreenBrightnessInternal(eventTime, uid);
+ } finally {
+ Binder.restoreCallingIdentity(ident);
+ }
+ }
+
+ @Override // Binder call
protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
if (mContext.checkCallingOrSelfPermission(Manifest.permission.DUMP)
!= PackageManager.PERMISSION_GRANTED) {
diff --git a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
index 15e0bf0..1919281 100644
--- a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
+++ b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
@@ -353,7 +353,7 @@
}
@Override
- public void setSystemUiVisibility(int vis, int mask) {
+ public void setSystemUiVisibility(int vis, int mask, String cause) {
// also allows calls from window manager which is in this process.
enforceStatusBarService();
@@ -365,7 +365,7 @@
mCurrentUserId,
vis & StatusBarManager.DISABLE_MASK,
mSysUiVisToken,
- "WindowManager.LayoutParams");
+ cause);
}
}
diff --git a/services/core/java/com/android/server/trust/TrustAgentWrapper.java b/services/core/java/com/android/server/trust/TrustAgentWrapper.java
index b1c918d..b2bcf75 100644
--- a/services/core/java/com/android/server/trust/TrustAgentWrapper.java
+++ b/services/core/java/com/android/server/trust/TrustAgentWrapper.java
@@ -27,11 +27,11 @@
import android.content.ServiceConnection;
import android.net.Uri;
import android.os.Binder;
-import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.PatternMatcher;
+import android.os.PersistableBundle;
import android.os.RemoteException;
import android.os.SystemClock;
import android.os.UserHandle;
@@ -218,7 +218,7 @@
}
@Override
- public void onSetTrustAgentFeaturesEnabledCompleted(boolean result, IBinder token) {
+ public void onConfigureCompleted(boolean result, IBinder token) {
if (DEBUG) Slog.v(TAG, "onSetTrustAgentFeaturesEnabledCompleted(result=" + result);
mHandler.obtainMessage(MSG_SET_TRUST_AGENT_FEATURES_COMPLETED,
result ? 1 : 0, 0, token).sendToTarget();
@@ -318,23 +318,19 @@
DevicePolicyManager dpm =
(DevicePolicyManager) mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
- if ((dpm.getKeyguardDisabledFeatures(null)
+ if ((dpm.getKeyguardDisabledFeatures(null, mUserId)
& DevicePolicyManager.KEYGUARD_DISABLE_TRUST_AGENTS) != 0) {
- List<String> features = dpm.getTrustAgentFeaturesEnabled(null, mName);
+ List<PersistableBundle> config = dpm.getTrustAgentConfiguration(
+ null, mName, mUserId);
trustDisabled = true;
- if (DEBUG) Slog.v(TAG, "Detected trust agents disabled. Features = "
- + features);
- if (features != null && features.size() > 0) {
- Bundle bundle = new Bundle();
- bundle.putStringArrayList(TrustAgentService.KEY_FEATURES,
- (ArrayList<String>)features);
+ if (DEBUG) Slog.v(TAG, "Detected trust agents disabled. Config = " + config);
+ if (config != null && config.size() > 0) {
if (DEBUG) {
Slog.v(TAG, "TrustAgent " + mName.flattenToShortString()
- + " disabled until it acknowledges "+ features);
+ + " disabled until it acknowledges "+ config);
}
mSetTrustAgentFeaturesToken = new Binder();
- mTrustAgentService.setTrustAgentFeaturesEnabled(bundle,
- mSetTrustAgentFeaturesToken);
+ mTrustAgentService.onConfigure(config, mSetTrustAgentFeaturesToken);
}
}
final long maxTimeToLock = dpm.getMaximumTimeToLock(null);
diff --git a/services/core/java/com/android/server/trust/TrustManagerService.java b/services/core/java/com/android/server/trust/TrustManagerService.java
index 65cb35b..fe5cb33 100644
--- a/services/core/java/com/android/server/trust/TrustManagerService.java
+++ b/services/core/java/com/android/server/trust/TrustManagerService.java
@@ -48,6 +48,7 @@
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
+import android.os.PersistableBundle;
import android.os.RemoteException;
import android.os.SystemClock;
import android.os.UserHandle;
@@ -104,14 +105,18 @@
private final Context mContext;
private final LockPatternUtils mLockPatternUtils;
private final UserManager mUserManager;
+ private final ActivityManager mActivityManager;
@GuardedBy("mUserIsTrusted")
private final SparseBooleanArray mUserIsTrusted = new SparseBooleanArray();
+ private boolean mTrustAgentsCanRun = false;
+
public TrustManagerService(Context context) {
super(context);
mContext = context;
mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
+ mActivityManager = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE);
mLockPatternUtils = new LockPatternUtils(context);
}
@@ -129,6 +134,8 @@
if (phase == SystemService.PHASE_SYSTEM_SERVICES_READY) {
mPackageMonitor.register(mContext, mHandler.getLooper(), UserHandle.ALL, true);
mReceiver.register(mContext);
+ } else if (phase == SystemService.PHASE_THIRD_PARTY_APPS_CAN_START) {
+ mTrustAgentsCanRun = true;
refreshAgentList(UserHandle.USER_ALL);
} else if (phase == SystemService.PHASE_BOOT_COMPLETED) {
maybeEnableFactoryTrustAgents(mLockPatternUtils, UserHandle.USER_OWNER);
@@ -178,8 +185,7 @@
void refreshAgentList(int userId) {
if (DEBUG) Slog.d(TAG, "refreshAgentList()");
- if (isSafeMode()) {
- // Don't ever bind to trust agents in safe mode.
+ if (!mTrustAgentsCanRun) {
return;
}
if (userId != UserHandle.USER_ALL && userId < UserHandle.USER_OWNER) {
@@ -202,7 +208,9 @@
obsoleteAgents.addAll(mActiveAgents);
for (UserInfo userInfo : userInfos) {
+ if (userInfo.partial || !userInfo.isEnabled() || userInfo.guestToRemove) continue;
if (!userInfo.supportsSwitchTo()) continue;
+ if (!mActivityManager.isUserRunning(userInfo.id)) continue;
if (lockPatternUtils.getKeyguardStoredPasswordQuality(userInfo.id)
== DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED) continue;
if (!mUserHasAuthenticatedSinceBoot.get(userInfo.id)) continue;
@@ -221,10 +229,10 @@
if (!enabledAgents.contains(name)) continue;
if (disableTrustAgents) {
- List<String> features =
- dpm.getTrustAgentFeaturesEnabled(null /* admin */, name);
+ List<PersistableBundle> config =
+ dpm.getTrustAgentConfiguration(null /* admin */, name, userInfo.id);
// Disable agent if no features are enabled.
- if (features == null || features.isEmpty()) continue;
+ if (config == null || config.isEmpty()) continue;
}
AgentInfo agentInfo = new AgentInfo();
@@ -256,7 +264,11 @@
}
if (trustMayHaveChanged) {
- updateTrustAll();
+ if (userId == UserHandle.USER_ALL) {
+ updateTrustAll();
+ } else {
+ updateTrust(userId, false /* initiatedByUser */);
+ }
}
}
@@ -523,6 +535,18 @@
}
}
+ // User lifecycle
+
+ @Override
+ public void onStartUser(int userId) {
+ refreshAgentList(userId);
+ }
+
+ @Override
+ public void onCleanupUser(int userId) {
+ refreshAgentList(userId);
+ }
+
// Plumbing
private final IBinder mService = new ITrustManager.Stub() {
@@ -592,6 +616,10 @@
fout.println("disabled because the system is in safe mode.");
return;
}
+ if (!mTrustAgentsCanRun) {
+ fout.println("disabled because the third-party apps can't run yet.");
+ return;
+ }
final UserInfo currentUser;
final List<UserInfo> userInfos = mUserManager.getUsers(true /* excludeDying */);
try {
@@ -719,12 +747,27 @@
} else if (Intent.ACTION_USER_PRESENT.equals(action)) {
updateUserHasAuthenticated(getSendingUserId());
} else if (Intent.ACTION_USER_ADDED.equals(action)) {
- int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -100);
+ int userId = getUserId(intent);
if (userId > 0) {
maybeEnableFactoryTrustAgents(mLockPatternUtils, userId);
- } else {
- Log.wtf(TAG, "EXTRA_USER_HANDLE missing or invalid, value=" + userId);
}
+ } else if (Intent.ACTION_USER_REMOVED.equals(action)) {
+ int userId = getUserId(intent);
+ if (userId > 0) {
+ mUserHasAuthenticatedSinceBoot.delete(userId);
+ mUserIsTrusted.delete(userId);
+ refreshAgentList(userId);
+ }
+ }
+ }
+
+ private int getUserId(Intent intent) {
+ int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -100);
+ if (userId > 0) {
+ return userId;
+ } else {
+ Slog.wtf(TAG, "EXTRA_USER_HANDLE missing or invalid, value=" + userId);
+ return -100;
}
}
@@ -733,6 +776,7 @@
filter.addAction(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED);
filter.addAction(Intent.ACTION_USER_PRESENT);
filter.addAction(Intent.ACTION_USER_ADDED);
+ filter.addAction(Intent.ACTION_USER_REMOVED);
context.registerReceiverAsUser(this,
UserHandle.ALL,
filter,
diff --git a/services/core/java/com/android/server/wm/AppTransition.java b/services/core/java/com/android/server/wm/AppTransition.java
index bfc7659..eeb007c 100644
--- a/services/core/java/com/android/server/wm/AppTransition.java
+++ b/services/core/java/com/android/server/wm/AppTransition.java
@@ -691,8 +691,10 @@
throw new RuntimeException("Invalid thumbnail transition state");
}
- return prepareThumbnailAnimationWithDuration(a, appWidth, appHeight,
- THUMBNAIL_APP_TRANSITION_DURATION, mThumbnailFastOutSlowInInterpolator);
+ int duration = Math.max(THUMBNAIL_APP_TRANSITION_ALPHA_DURATION,
+ THUMBNAIL_APP_TRANSITION_DURATION);
+ return prepareThumbnailAnimationWithDuration(a, appWidth, appHeight, duration,
+ mThumbnailFastOutSlowInInterpolator);
}
/**
diff --git a/services/core/java/com/android/server/wm/AppWindowAnimator.java b/services/core/java/com/android/server/wm/AppWindowAnimator.java
index 69c9144..bf96ea5 100644
--- a/services/core/java/com/android/server/wm/AppWindowAnimator.java
+++ b/services/core/java/com/android/server/wm/AppWindowAnimator.java
@@ -58,7 +58,9 @@
// the state changes.
boolean allDrawn;
- // Special surface for thumbnail animation.
+ // Special surface for thumbnail animation. If deferThumbnailDestruction is enabled, then we
+ // will make sure that the thumbnail is destroyed after the other surface is completed. This
+ // requires that the duration of the two animations are the same.
SurfaceControl thumbnail;
int thumbnailTransactionSeq;
int thumbnailX;
@@ -68,13 +70,12 @@
Animation thumbnailAnimation;
final Transformation thumbnailTransformation = new Transformation();
// This flag indicates that the destruction of the thumbnail surface is synchronized with
- // another animation, so do not pre-emptively destroy the thumbnail surface when the animation
- // completes
+ // another animation, so defer the destruction of this thumbnail surface for a single frame
+ // after the secondary animation completes.
boolean deferThumbnailDestruction;
- // This is the thumbnail surface that has been bestowed upon this animator, and when the
- // surface for this animator's animation is complete, we will destroy the thumbnail surface
- // as well. Do not animate or do anything with this surface.
- SurfaceControl deferredThumbnail;
+ // This flag is set if the animator has deferThumbnailDestruction set and has reached the final
+ // frame of animation. It will extend the animation by one frame and then clean up afterwards.
+ boolean deferFinalFrameCleanup;
/** WindowStateAnimator from mAppAnimator.allAppWindows as of last performLayout */
ArrayList<WindowStateAnimator> mAllAppWinAnimators = new ArrayList<WindowStateAnimator>();
@@ -134,9 +135,7 @@
animation = null;
animating = true;
}
- if (!deferThumbnailDestruction) {
- clearThumbnail();
- }
+ clearThumbnail();
if (mAppToken.deferClearAllDrawn) {
mAppToken.allDrawn = false;
mAppToken.deferClearAllDrawn = false;
@@ -148,13 +147,7 @@
thumbnail.destroy();
thumbnail = null;
}
- }
-
- public void clearDeferredThumbnail() {
- if (deferredThumbnail != null) {
- deferredThumbnail.destroy();
- deferredThumbnail = null;
- }
+ deferThumbnailDestruction = false;
}
void updateLayers() {
@@ -223,19 +216,26 @@
return false;
}
transformation.clear();
- final boolean more = animation.getTransformation(currentTime, transformation);
- if (false && WindowManagerService.DEBUG_ANIM) Slog.v(
- TAG, "Stepped animation in " + mAppToken + ": more=" + more + ", xform=" + transformation);
- if (!more) {
- animation = null;
- if (!deferThumbnailDestruction) {
+ boolean hasMoreFrames = animation.getTransformation(currentTime, transformation);
+ if (!hasMoreFrames) {
+ if (deferThumbnailDestruction && !deferFinalFrameCleanup) {
+ // We are deferring the thumbnail destruction, so extend the animation for one more
+ // (dummy) frame before we clean up
+ deferFinalFrameCleanup = true;
+ hasMoreFrames = true;
+ } else {
+ if (false && WindowManagerService.DEBUG_ANIM) Slog.v(
+ TAG, "Stepped animation in " + mAppToken + ": more=" + hasMoreFrames +
+ ", xform=" + transformation);
+ deferFinalFrameCleanup = false;
+ animation = null;
clearThumbnail();
+ if (WindowManagerService.DEBUG_ANIM) Slog.v(
+ TAG, "Finished animation in " + mAppToken + " @ " + currentTime);
}
- if (WindowManagerService.DEBUG_ANIM) Slog.v(
- TAG, "Finished animation in " + mAppToken + " @ " + currentTime);
}
- hasTransformation = more;
- return more;
+ hasTransformation = hasMoreFrames;
+ return hasMoreFrames;
}
// This must be called while inside a transaction.
diff --git a/services/core/java/com/android/server/wm/WindowAnimator.java b/services/core/java/com/android/server/wm/WindowAnimator.java
index 69d3191..8d931418 100644
--- a/services/core/java/com/android/server/wm/WindowAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowAnimator.java
@@ -20,6 +20,7 @@
import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_KEYGUARD;
+import static com.android.server.wm.WindowManagerService.DEBUG_KEYGUARD;
import static com.android.server.wm.WindowManagerService.LayoutFields.SET_UPDATE_ROTATION;
import static com.android.server.wm.WindowManagerService.LayoutFields.SET_WALLPAPER_MAY_CHANGE;
import static com.android.server.wm.WindowManagerService.LayoutFields.SET_FORCE_HIDING_CHANGED;
@@ -29,7 +30,6 @@
import android.content.Context;
import android.os.Debug;
import android.os.SystemClock;
-import android.util.Log;
import android.util.Slog;
import android.util.SparseArray;
import android.util.SparseIntArray;
@@ -91,6 +91,9 @@
boolean mKeyguardGoingAwayToNotificationShade;
boolean mKeyguardGoingAwayDisableWindowAnimations;
+ /** Use one animation for all entering activities after keyguard is dismissed. */
+ Animation mPostKeyguardExitAnimation;
+
// forceHiding states.
static final int KEYGUARD_NOT_SHOWN = 0;
static final int KEYGUARD_ANIMATING_IN = 1;
@@ -220,9 +223,6 @@
++mAnimTransactionSequence;
final WindowList windows = mService.getWindowListLocked(displayId);
- ArrayList<WindowStateAnimator> unForceHiding = null;
- boolean wallpaperInUnForceHiding = false;
- WindowState wallpaper = null;
if (mKeyguardGoingAway) {
for (int i = windows.size() - 1; i >= 0; i--) {
@@ -233,12 +233,17 @@
final WindowStateAnimator winAnimator = win.mWinAnimator;
if ((win.mAttrs.privateFlags & PRIVATE_FLAG_KEYGUARD) != 0) {
if (!winAnimator.mAnimating) {
+ if (DEBUG_KEYGUARD) Slog.d(TAG,
+ "updateWindowsLocked: creating delay animation");
+
// Create a new animation to delay until keyguard is gone on its own.
winAnimator.mAnimation = new AlphaAnimation(1.0f, 1.0f);
winAnimator.mAnimation.setDuration(KEYGUARD_ANIM_TIMEOUT_MS);
winAnimator.mAnimationIsEntrance = false;
}
} else {
+ if (DEBUG_KEYGUARD) Slog.d(TAG,
+ "updateWindowsLocked: StatusBar is no longer keyguard");
mKeyguardGoingAway = false;
winAnimator.clearAnimation();
}
@@ -256,6 +261,9 @@
final AppWindowToken appShowWhenLocked = winShowWhenLocked == null ?
null : winShowWhenLocked.mAppToken;
+ boolean wallpaperInUnForceHiding = false;
+ ArrayList<WindowStateAnimator> unForceHiding = null;
+ WindowState wallpaper = null;
for (int i = windows.size() - 1; i >= 0; i--) {
WindowState win = windows.get(i);
WindowStateAnimator winAnimator = win.mWinAnimator;
@@ -282,7 +290,7 @@
if (mPolicy.isForceHiding(win.mAttrs)) {
if (!wasAnimating && nowAnimating) {
- if (WindowManagerService.DEBUG_ANIM ||
+ if (DEBUG_KEYGUARD || WindowManagerService.DEBUG_ANIM ||
WindowManagerService.DEBUG_VISIBILITY) Slog.v(TAG,
"Animation started that could impact force hide: " + win);
mBulkUpdateParams |= SET_FORCE_HIDING_CHANGED;
@@ -310,7 +318,7 @@
mForceHiding = win.isDrawnLw() ? KEYGUARD_SHOWN : KEYGUARD_NOT_SHOWN;
}
}
- if (WindowManagerService.DEBUG_VISIBILITY) Slog.v(TAG,
+ if (DEBUG_KEYGUARD || WindowManagerService.DEBUG_VISIBILITY) Slog.v(TAG,
"Force hide " + forceHidingToString()
+ " hasSurface=" + win.mHasSurface
+ " policyVis=" + win.mPolicyVisibility
@@ -322,40 +330,53 @@
} else if (mPolicy.canBeForceHidden(win, win.mAttrs)) {
final boolean hideWhenLocked = !((win.mIsImWindow && showImeOverKeyguard) ||
(appShowWhenLocked != null && appShowWhenLocked == win.mAppToken));
- final boolean changed;
if (((mForceHiding == KEYGUARD_ANIMATING_IN)
&& (!winAnimator.isAnimating() || hideWhenLocked))
|| ((mForceHiding == KEYGUARD_SHOWN) && hideWhenLocked)) {
- changed = win.hideLw(false, false);
- if (WindowManagerService.DEBUG_VISIBILITY && changed) Slog.v(TAG,
+ if (!win.hideLw(false, false)) {
+ // Was already hidden
+ continue;
+ }
+ if (DEBUG_KEYGUARD || WindowManagerService.DEBUG_VISIBILITY) Slog.v(TAG,
"Now policy hidden: " + win);
} else {
- changed = win.showLw(false, false);
- if (WindowManagerService.DEBUG_VISIBILITY && changed) Slog.v(TAG,
+ if (!win.showLw(false, false)) {
+ // Was already showing.
+ continue;
+ }
+ final boolean visibleNow = win.isVisibleNow();
+ if (!visibleNow) {
+ // Couldn't really show, must showLw() again when win becomes visible.
+ win.hideLw(false, false);
+ continue;
+ }
+ if (DEBUG_KEYGUARD || WindowManagerService.DEBUG_VISIBILITY) Slog.v(TAG,
"Now policy shown: " + win);
- if (changed) {
- if ((mBulkUpdateParams & SET_FORCE_HIDING_CHANGED) != 0
- && win.isVisibleNow() /*w.isReadyForDisplay()*/) {
- if (unForceHiding == null) {
- unForceHiding = new ArrayList<WindowStateAnimator>();
- }
- unForceHiding.add(winAnimator);
- if ((flags & FLAG_SHOW_WALLPAPER) != 0) {
- wallpaperInUnForceHiding = true;
- }
+ if ((mBulkUpdateParams & SET_FORCE_HIDING_CHANGED) != 0) {
+ if (unForceHiding == null) {
+ unForceHiding = new ArrayList<>();
}
- final WindowState currentFocus = mService.mCurrentFocus;
- if (currentFocus == null || currentFocus.mLayer < win.mLayer) {
- // We are showing on to of the current
- // focus, so re-evaluate focus to make
- // sure it is correct.
- if (WindowManagerService.DEBUG_FOCUS_LIGHT) Slog.v(TAG,
- "updateWindowsLocked: setting mFocusMayChange true");
- mService.mFocusMayChange = true;
+ unForceHiding.add(winAnimator);
+ if ((flags & FLAG_SHOW_WALLPAPER) != 0) {
+ wallpaperInUnForceHiding = true;
}
+ } else if (mPostKeyguardExitAnimation != null) {
+ // We're already in the middle of an animation. Use the existing
+ // animation to bring in this window.
+ winAnimator.setAnimation(mPostKeyguardExitAnimation);
+ winAnimator.keyguardGoingAwayAnimation = true;
+ }
+ final WindowState currentFocus = mService.mCurrentFocus;
+ if (currentFocus == null || currentFocus.mLayer < win.mLayer) {
+ // We are showing on top of the current
+ // focus, so re-evaluate focus to make
+ // sure it is correct.
+ if (WindowManagerService.DEBUG_FOCUS_LIGHT) Slog.v(TAG,
+ "updateWindowsLocked: setting mFocusMayChange true");
+ mService.mFocusMayChange = true;
}
}
- if (changed && (flags & FLAG_SHOW_WALLPAPER) != 0) {
+ if ((flags & FLAG_SHOW_WALLPAPER) != 0) {
mBulkUpdateParams |= SET_WALLPAPER_MAY_CHANGE;
setPendingLayoutChanges(Display.DEFAULT_DISPLAY,
WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER);
@@ -398,36 +419,44 @@
// If we have windows that are being show due to them no longer
// being force-hidden, apply the appropriate animation to them.
if (unForceHiding != null) {
- boolean startKeyguardExit = true;
- for (int i=unForceHiding.size()-1; i>=0; i--) {
- Animation a = null;
- if (!mKeyguardGoingAwayDisableWindowAnimations) {
- a = mPolicy.createForceHideEnterAnimation(wallpaperInUnForceHiding,
- mKeyguardGoingAwayToNotificationShade);
- }
- if (a != null) {
+ // This only happens the first time that we detect the keyguard is animating out.
+ if (mKeyguardGoingAwayDisableWindowAnimations) {
+ if (DEBUG_KEYGUARD) Slog.d(TAG, "updateWindowsLocked: skipping anim for windows");
+ } else {
+ if (DEBUG_KEYGUARD) Slog.d(TAG, "updateWindowsLocked: created anim for windows");
+ mPostKeyguardExitAnimation = mPolicy.createForceHideEnterAnimation(
+ wallpaperInUnForceHiding, mKeyguardGoingAwayToNotificationShade);
+ }
+ if (mPostKeyguardExitAnimation != null) {
+ for (int i=unForceHiding.size()-1; i>=0; i--) {
final WindowStateAnimator winAnimator = unForceHiding.get(i);
- winAnimator.setAnimation(a);
+ winAnimator.setAnimation(mPostKeyguardExitAnimation);
winAnimator.keyguardGoingAwayAnimation = true;
- if (startKeyguardExit && mKeyguardGoingAway) {
- // Do one time only.
- mPolicy.startKeyguardExitAnimation(mCurrentTime + a.getStartOffset(),
- a.getDuration());
- mKeyguardGoingAway = false;
- startKeyguardExit = false;
- }
}
}
+ }
- // Wallpaper is going away in un-force-hide motion, animate it as well.
- if (!wallpaperInUnForceHiding && wallpaper != null
- && !mKeyguardGoingAwayDisableWindowAnimations) {
- Animation a = mPolicy.createForceHideWallpaperExitAnimation(
- mKeyguardGoingAwayToNotificationShade);
- if (a != null) {
- WindowStateAnimator animator = wallpaper.mWinAnimator;
- animator.setAnimation(a);
- }
+ if (mPostKeyguardExitAnimation != null) {
+ // We're in the midst of a keyguard exit animation.
+ if (mKeyguardGoingAway) {
+ mPolicy.startKeyguardExitAnimation(mCurrentTime +
+ mPostKeyguardExitAnimation.getStartOffset(),
+ mPostKeyguardExitAnimation.getDuration());
+ mKeyguardGoingAway = false;
+ } else if (mPostKeyguardExitAnimation.hasEnded()) {
+ // Done with the animation, reset.
+ mPostKeyguardExitAnimation = null;
+ }
+ }
+
+ // Wallpaper is going away in un-force-hide motion, animate it as well.
+ if (!wallpaperInUnForceHiding && wallpaper != null
+ && !mKeyguardGoingAwayDisableWindowAnimations) {
+ if (DEBUG_KEYGUARD) Slog.d(TAG, "updateWindowsLocked: wallpaper animating away");
+ Animation a = mPolicy.createForceHideWallpaperExitAnimation(
+ mKeyguardGoingAwayToNotificationShade);
+ if (a != null) {
+ wallpaper.mWinAnimator.setAnimation(a);
}
}
}
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 13fb96f..968b35c 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -73,6 +73,7 @@
import android.graphics.Region;
import android.hardware.display.DisplayManager;
import android.hardware.display.DisplayManagerInternal;
+import android.net.Uri;
import android.os.Binder;
import android.os.Bundle;
import android.os.Debug;
@@ -166,6 +167,7 @@
static final boolean DEBUG_FOCUS = false;
static final boolean DEBUG_FOCUS_LIGHT = DEBUG_FOCUS || false;
static final boolean DEBUG_ANIM = false;
+ static final boolean DEBUG_KEYGUARD = false;
static final boolean DEBUG_LAYOUT = false;
static final boolean DEBUG_RESIZE = false;
static final boolean DEBUG_LAYERS = false;
@@ -557,16 +559,26 @@
SettingsObserver mSettingsObserver;
private final class SettingsObserver extends ContentObserver {
+ private final Uri mShowImeWithHardKeyboardUri =
+ Settings.Secure.getUriFor(Settings.Secure.SHOW_IME_WITH_HARD_KEYBOARD);
+
+ private final Uri mDisplayInversionEnabledUri =
+ Settings.Secure.getUriFor(Settings.Secure.ACCESSIBILITY_DISPLAY_INVERSION_ENABLED);
+
public SettingsObserver() {
super(new Handler());
ContentResolver resolver = mContext.getContentResolver();
- resolver.registerContentObserver(Settings.Secure.getUriFor(
- Settings.Secure.SHOW_IME_WITH_HARD_KEYBOARD), false, this);
+ resolver.registerContentObserver(mShowImeWithHardKeyboardUri, false, this);
+ resolver.registerContentObserver(mDisplayInversionEnabledUri, false, this);
}
@Override
- public void onChange(boolean selfChange) {
- updateShowImeWithHardKeyboard();
+ public void onChange(boolean selfChange, Uri uri) {
+ if (mShowImeWithHardKeyboardUri.equals(uri)) {
+ updateShowImeWithHardKeyboard();
+ } else if (mDisplayInversionEnabledUri.equals(uri)) {
+ updateCircularDisplayMaskIfNeeded();
+ }
}
}
@@ -902,7 +914,7 @@
SurfaceControl.closeTransaction();
}
- showCircularDisplayMaskIfNeeded();
+ updateCircularDisplayMaskIfNeeded();
showEmulatorDisplayOverlayIfNeeded();
}
@@ -2487,7 +2499,9 @@
}
}
- win.mWinAnimator.mEnterAnimationPending = true;
+ final WindowStateAnimator winAnimator = win.mWinAnimator;
+ winAnimator.mEnterAnimationPending = true;
+ winAnimator.mEnteringAnimation = true;
if (displayContent.isDefaultDisplay) {
mPolicy.getContentInsetHintLw(attrs, outContentInsets);
@@ -3099,6 +3113,7 @@
if (oldVisibility == View.GONE) {
winAnimator.mEnterAnimationPending = true;
}
+ winAnimator.mEnteringAnimation = true;
if (toBeDisplayed) {
if (win.isDrawnLw() && okToDisplay()) {
winAnimator.applyEnterAnimationLocked();
@@ -3167,6 +3182,7 @@
}
} else {
winAnimator.mEnterAnimationPending = false;
+ winAnimator.mEnteringAnimation = false;
if (winAnimator.mSurfaceControl != null) {
if (DEBUG_VISIBILITY) Slog.i(TAG, "Relayout invis " + win
+ ": mExiting=" + win.mExiting);
@@ -5359,6 +5375,8 @@
!= PackageManager.PERMISSION_GRANTED) {
throw new SecurityException("Requires DISABLE_KEYGUARD permission");
}
+ if (DEBUG_KEYGUARD) Slog.d(TAG, "keyguardGoingAway: disableWinAnim="
+ + disableWindowAnimations + " kgToNotifShade=" + keyguardGoingToNotificationShade);
synchronized (mWindowMap) {
mAnimator.mKeyguardGoingAway = true;
mAnimator.mKeyguardGoingAwayToNotificationShade = keyguardGoingToNotificationShade;
@@ -5368,12 +5386,15 @@
}
public void keyguardWaitingForActivityDrawn() {
+ if (DEBUG_KEYGUARD) Slog.d(TAG, "keyguardWaitingForActivityDrawn");
synchronized (mWindowMap) {
mKeyguardWaitingForActivityDrawn = true;
}
}
public void notifyActivityDrawnForKeyguard() {
+ if (DEBUG_KEYGUARD) Slog.d(TAG, "notifyActivityDrawnForKeyguard: waiting="
+ + mKeyguardWaitingForActivityDrawn);
synchronized (mWindowMap) {
if (mKeyguardWaitingForActivityDrawn) {
mPolicy.notifyActivityDrawnForKeyguardLw();
@@ -5832,13 +5853,21 @@
}
}
- public void showCircularDisplayMaskIfNeeded() {
+ public void updateCircularDisplayMaskIfNeeded() {
// we're fullscreen and not hosted in an ActivityView
if (mContext.getResources().getBoolean(
com.android.internal.R.bool.config_windowIsRound)
&& mContext.getResources().getBoolean(
com.android.internal.R.bool.config_windowShowCircularMask)) {
- mH.sendMessage(mH.obtainMessage(H.SHOW_CIRCULAR_DISPLAY_MASK));
+ // Device configuration calls for a circular display mask, but we only enable the mask
+ // if the accessibility color inversion feature is disabled, as the inverted mask
+ // causes artifacts.
+ int inversionState = Settings.Secure.getIntForUser(mContext.getContentResolver(),
+ Settings.Secure.ACCESSIBILITY_DISPLAY_INVERSION_ENABLED, 0, mCurrentUserId);
+ int showMask = (inversionState == 1) ? 0 : 1;
+ Message m = mH.obtainMessage(H.SHOW_CIRCULAR_DISPLAY_MASK);
+ m.arg1 = showMask;
+ mH.sendMessage(m);
}
}
@@ -5851,30 +5880,35 @@
}
}
- public void showCircularMask() {
+ public void showCircularMask(boolean visible) {
synchronized(mWindowMap) {
if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
- ">>> OPEN TRANSACTION showCircularMask");
+ ">>> OPEN TRANSACTION showCircularMask(visible=" + visible + ")");
SurfaceControl.openTransaction();
try {
- // TODO(multi-display): support multiple displays
- if (mCircularDisplayMask == null) {
- int screenOffset = mContext.getResources().getDimensionPixelSize(
- com.android.internal.R.dimen.circular_display_mask_offset);
+ if (visible) {
+ // TODO(multi-display): support multiple displays
+ if (mCircularDisplayMask == null) {
+ int screenOffset = mContext.getResources().getDimensionPixelSize(
+ com.android.internal.R.dimen.circular_display_mask_offset);
- mCircularDisplayMask = new CircularDisplayMask(
- getDefaultDisplayContentLocked().getDisplay(),
- mFxSession,
- mPolicy.windowTypeToLayerLw(
- WindowManager.LayoutParams.TYPE_POINTER)
- * TYPE_LAYER_MULTIPLIER + 10, screenOffset);
+ mCircularDisplayMask = new CircularDisplayMask(
+ getDefaultDisplayContentLocked().getDisplay(),
+ mFxSession,
+ mPolicy.windowTypeToLayerLw(
+ WindowManager.LayoutParams.TYPE_POINTER)
+ * TYPE_LAYER_MULTIPLIER + 10, screenOffset);
+ }
+ mCircularDisplayMask.setVisibility(true);
+ } else if (mCircularDisplayMask != null) {
+ mCircularDisplayMask.setVisibility(false);
+ mCircularDisplayMask = null;
}
- mCircularDisplayMask.setVisibility(true);
} finally {
SurfaceControl.closeTransaction();
if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
- "<<< CLOSE TRANSACTION showCircularMask");
+ "<<< CLOSE TRANSACTION showCircularMask(visible=" + visible + ")");
}
}
}
@@ -7945,7 +7979,7 @@
}
case SHOW_CIRCULAR_DISPLAY_MASK: {
- showCircularMask();
+ showCircularMask(msg.arg1 == 1);
break;
}
@@ -9210,12 +9244,6 @@
topClosingLayer);
openingAppAnimator.deferThumbnailDestruction =
!mAppTransition.isNextThumbnailTransitionScaleUp();
- if (openingAppAnimator.deferThumbnailDestruction) {
- if (closingAppAnimator != null &&
- closingAppAnimator.animation != null) {
- closingAppAnimator.deferredThumbnail = surfaceControl;
- }
- }
} else {
anim = mAppTransition.createThumbnailScaleAnimationLocked(
displayInfo.appWidth, displayInfo.appHeight, transit);
@@ -9749,7 +9777,7 @@
if (!w.isDrawnLw()) {
Slog.v(TAG, "Not displayed: s=" + winAnimator.mSurfaceControl
+ " pv=" + w.mPolicyVisibility
- + " mDrawState=" + winAnimator.mDrawState
+ + " mDrawState=" + winAnimator.drawStateToString()
+ " ah=" + w.mAttachedHidden
+ " th=" + atoken.hiddenRequested
+ " a=" + winAnimator.mAnimating);
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index e5cf764..f9efc80 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -29,6 +29,7 @@
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_NO_MOVE_ANIMATION;
import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD;
import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD_DIALOG;
+import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
import android.app.AppOpsManager;
@@ -902,7 +903,8 @@
*/
boolean isVisibleNow() {
return mHasSurface && mPolicyVisibility && !mAttachedHidden
- && !mRootToken.hidden && !mExiting && !mDestroying;
+ && (!mRootToken.hidden || mAttrs.type == TYPE_APPLICATION_STARTING)
+ && !mExiting && !mDestroying;
}
/**
diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java
index 0c727f3..1dadb17 100644
--- a/services/core/java/com/android/server/wm/WindowStateAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java
@@ -40,6 +40,7 @@
import android.graphics.RectF;
import android.graphics.Region;
import android.os.Debug;
+import android.os.RemoteException;
import android.os.UserHandle;
import android.util.Slog;
import android.view.Display;
@@ -141,6 +142,11 @@
// an enter animation.
boolean mEnterAnimationPending;
+ /** Used to indicate that this window is undergoing an enter animation. Used for system
+ * windows to make the callback to View.dispatchOnWindowShownCallback(). Set when the
+ * window is first added or shown, cleared when the callback has been made. */
+ boolean mEnteringAnimation;
+
boolean keyguardGoingAwayAnimation;
/** This is set when there is no Surface */
@@ -161,14 +167,14 @@
private static final int SYSTEM_UI_FLAGS_LAYOUT_STABLE_FULLSCREEN =
View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN;
- static String drawStateToString(int state) {
- switch (state) {
+ String drawStateToString() {
+ switch (mDrawState) {
case NO_SURFACE: return "NO_SURFACE";
case DRAW_PENDING: return "DRAW_PENDING";
case COMMIT_DRAW_PENDING: return "COMMIT_DRAW_PENDING";
case READY_TO_SHOW: return "READY_TO_SHOW";
case HAS_DRAWN: return "HAS_DRAWN";
- default: return Integer.toString(state);
+ default: return Integer.toString(mDrawState);
}
}
int mDrawState;
@@ -428,6 +434,14 @@
mWin.mChildWindows.get(i).mWinAnimator.finishExit();
}
+ if (mEnteringAnimation && mWin.mAppToken == null) {
+ try {
+ mEnteringAnimation = false;
+ mWin.mClient.dispatchWindowShown();
+ } catch (RemoteException e) {
+ }
+ }
+
if (!mWin.mExiting) {
return;
}
@@ -475,7 +489,7 @@
if (DEBUG_STARTING_WINDOW &&
mWin.mAttrs.type == WindowManager.LayoutParams.TYPE_APPLICATION_STARTING) {
Slog.v(TAG, "Finishing drawing window " + mWin + ": mDrawState="
- + drawStateToString(mDrawState));
+ + drawStateToString());
}
if (mDrawState == DRAW_PENDING) {
if (DEBUG_SURFACE_TRACE || DEBUG_ANIM || SHOW_TRANSACTIONS || DEBUG_ORIENTATION)
@@ -496,18 +510,17 @@
if (DEBUG_STARTING_WINDOW &&
mWin.mAttrs.type == WindowManager.LayoutParams.TYPE_APPLICATION_STARTING) {
Slog.i(TAG, "commitFinishDrawingLocked: " + mWin + " cur mDrawState="
- + drawStateToString(mDrawState));
+ + drawStateToString());
}
- if (mDrawState != COMMIT_DRAW_PENDING) {
+ if (mDrawState != COMMIT_DRAW_PENDING && mDrawState != READY_TO_SHOW) {
return false;
}
if (DEBUG_SURFACE_TRACE || DEBUG_ANIM) {
Slog.i(TAG, "commitFinishDrawingLocked: mDrawState=READY_TO_SHOW " + mSurfaceControl);
}
mDrawState = READY_TO_SHOW;
- final boolean starting = mWin.mAttrs.type == TYPE_APPLICATION_STARTING;
final AppWindowToken atoken = mWin.mAppToken;
- if (atoken == null || atoken.allDrawn || starting) {
+ if (atoken == null || atoken.allDrawn || mWin.mAttrs.type == TYPE_APPLICATION_STARTING) {
performShowLocked();
}
return true;
@@ -962,11 +975,6 @@
mWin.mHasSurface = false;
mDrawState = NO_SURFACE;
}
-
- // Destroy any deferred thumbnail surfaces
- if (mAppAnimator != null) {
- mAppAnimator.clearDeferredThumbnail();
- }
}
void destroyDeferredSurfaceLocked() {
@@ -1854,7 +1862,7 @@
if (dumpAll) {
pw.print(prefix); pw.print("mSurface="); pw.println(mSurfaceControl);
pw.print(prefix); pw.print("mDrawState=");
- pw.print(drawStateToString(mDrawState));
+ pw.print(drawStateToString());
pw.print(" mLastHidden="); pw.println(mLastHidden);
}
pw.print(prefix); pw.print("Surface: shown="); pw.print(mSurfaceShown);
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index 308fcd8..2c6a222 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -60,6 +60,7 @@
import android.os.Handler;
import android.os.IBinder;
import android.os.IPowerManager;
+import android.os.PersistableBundle;
import android.os.PowerManager;
import android.os.Process;
import android.os.RecoverySystem;
@@ -96,6 +97,7 @@
import com.android.org.conscrypt.TrustedCertificateStore;
import com.android.server.LocalServices;
import com.android.server.SystemService;
+import com.android.server.devicepolicy.DevicePolicyManagerService.ActiveAdmin.TrustAgentInfo;
import org.xmlpull.v1.XmlPullParser;
@@ -322,7 +324,7 @@
= "permitted-accessiblity-services";
private static final String TAG_ENCRYPTION_REQUESTED = "encryption-requested";
private static final String TAG_MANAGE_TRUST_AGENT_FEATURES = "manage-trust-agent-features";
- private static final String TAG_TRUST_AGENT_FEATURE = "feature";
+ private static final String TAG_TRUST_AGENT_COMPONENT_OPTIONS = "trust-agent-component-options";
private static final String TAG_TRUST_AGENT_COMPONENT = "component";
private static final String TAG_PASSWORD_EXPIRATION_DATE = "password-expiration-date";
private static final String TAG_PASSWORD_EXPIRATION_TIMEOUT = "password-expiration-timeout";
@@ -389,6 +391,7 @@
long passwordExpirationDate = DEF_PASSWORD_EXPIRATION_DATE;
static final int DEF_KEYGUARD_FEATURES_DISABLED = 0; // none
+
int disabledKeyguardFeatures = DEF_KEYGUARD_FEATURES_DISABLED;
boolean encryptionRequested = false;
@@ -397,6 +400,13 @@
boolean disableScreenCapture = false; // Can only be set by a device/profile owner.
boolean requireAutoTime = false; // Can only be set by a device owner.
+ static class TrustAgentInfo {
+ public PersistableBundle options;
+ TrustAgentInfo(PersistableBundle bundle) {
+ options = bundle;
+ }
+ }
+
Set<String> accountTypesWithManagementDisabled = new HashSet<String>();
// The list of permitted accessibility services package namesas set by a profile
@@ -413,7 +423,8 @@
boolean specifiesGlobalProxy = false;
String globalProxySpec = null;
String globalProxyExclusionList = null;
- HashMap<String, List<String>> trustAgentFeatures = new HashMap<String, List<String>>();
+
+ HashMap<String, TrustAgentInfo> trustAgentInfos = new HashMap<String, TrustAgentInfo>();
List<String> crossProfileWidgetProviders;
@@ -551,16 +562,21 @@
}
out.endTag(null, TAG_DISABLE_ACCOUNT_MANAGEMENT);
}
- if (!trustAgentFeatures.isEmpty()) {
- Set<Entry<String, List<String>>> set = trustAgentFeatures.entrySet();
+ if (!trustAgentInfos.isEmpty()) {
+ Set<Entry<String, TrustAgentInfo>> set = trustAgentInfos.entrySet();
out.startTag(null, TAG_MANAGE_TRUST_AGENT_FEATURES);
- for (Entry<String, List<String>> component : set) {
+ for (Entry<String, TrustAgentInfo> entry : set) {
+ TrustAgentInfo trustAgentInfo = entry.getValue();
out.startTag(null, TAG_TRUST_AGENT_COMPONENT);
- out.attribute(null, ATTR_VALUE, component.getKey());
- for (String feature : component.getValue()) {
- out.startTag(null, TAG_TRUST_AGENT_FEATURE);
- out.attribute(null, ATTR_VALUE, feature);
- out.endTag(null, TAG_TRUST_AGENT_FEATURE);
+ out.attribute(null, ATTR_VALUE, entry.getKey());
+ if (trustAgentInfo.options != null) {
+ out.startTag(null, TAG_TRUST_AGENT_COMPONENT_OPTIONS);
+ try {
+ trustAgentInfo.options.saveToXml(out);
+ } catch (XmlPullParserException e) {
+ Log.e(LOG_TAG, "Failed to save TrustAgent options", e);
+ }
+ out.endTag(null, TAG_TRUST_AGENT_COMPONENT_OPTIONS);
}
out.endTag(null, TAG_TRUST_AGENT_COMPONENT);
}
@@ -679,7 +695,7 @@
} else if (TAG_DISABLE_ACCOUNT_MANAGEMENT.equals(tag)) {
accountTypesWithManagementDisabled = readDisableAccountInfo(parser, tag);
} else if (TAG_MANAGE_TRUST_AGENT_FEATURES.equals(tag)) {
- trustAgentFeatures = getAllTrustAgentFeatures(parser, tag);
+ trustAgentInfos = getAllTrustAgentInfos(parser, tag);
} else if (TAG_CROSS_PROFILE_WIDGET_PROVIDERS.equals(tag)) {
crossProfileWidgetProviders = getCrossProfileWidgetProviders(parser, tag);
} else if (TAG_PERMITTED_ACCESSIBILITY_SERVICES.equals(tag)) {
@@ -738,11 +754,11 @@
return result;
}
- private HashMap<String, List<String>> getAllTrustAgentFeatures(XmlPullParser parser,
- String tag) throws XmlPullParserException, IOException {
+ private HashMap<String, TrustAgentInfo> getAllTrustAgentInfos(
+ XmlPullParser parser, String tag) throws XmlPullParserException, IOException {
int outerDepthDAM = parser.getDepth();
int typeDAM;
- HashMap<String, List<String>> result = new HashMap<String, List<String>>();
+ HashMap<String, TrustAgentInfo> result = new HashMap<String, TrustAgentInfo>();
while ((typeDAM=parser.next()) != END_DOCUMENT
&& (typeDAM != END_TAG || parser.getDepth() > outerDepthDAM)) {
if (typeDAM == END_TAG || typeDAM == TEXT) {
@@ -751,7 +767,8 @@
String tagDAM = parser.getName();
if (TAG_TRUST_AGENT_COMPONENT.equals(tagDAM)) {
final String component = parser.getAttributeValue(null, ATTR_VALUE);
- result.put(component, getTrustAgentFeatures(parser, tag));
+ final TrustAgentInfo trustAgentInfo = getTrustAgentInfo(parser, tag);
+ result.put(component, trustAgentInfo);
} else {
Slog.w(LOG_TAG, "Unknown tag under " + tag + ": " + tagDAM);
}
@@ -759,20 +776,21 @@
return result;
}
- private List<String> getTrustAgentFeatures(XmlPullParser parser, String tag)
+ private TrustAgentInfo getTrustAgentInfo(XmlPullParser parser, String tag)
throws XmlPullParserException, IOException {
int outerDepthDAM = parser.getDepth();
int typeDAM;
- ArrayList<String> result = new ArrayList<String>();
+ TrustAgentInfo result = new TrustAgentInfo(null);
while ((typeDAM=parser.next()) != END_DOCUMENT
&& (typeDAM != END_TAG || parser.getDepth() > outerDepthDAM)) {
if (typeDAM == END_TAG || typeDAM == TEXT) {
continue;
}
String tagDAM = parser.getName();
- if (TAG_TRUST_AGENT_FEATURE.equals(tagDAM)) {
- final String feature = parser.getAttributeValue(null, ATTR_VALUE);
- result.add(feature);
+ if (TAG_TRUST_AGENT_COMPONENT_OPTIONS.equals(tagDAM)) {
+ PersistableBundle bundle = new PersistableBundle();
+ bundle.restoreFromXml(parser);
+ result.options = bundle;
} else {
Slog.w(LOG_TAG, "Unknown tag under " + tag + ": " + tagDAM);
}
@@ -1174,7 +1192,7 @@
int userHandle) {
List<UserInfo> profiles = mUserManager.getProfiles(userHandle);
for (UserInfo ui : profiles) {
- int id = ui.getUserHandle().getIdentifier();
+ int id = ui.id;
sendAdminCommandLocked(action, reqPolicy, id);
}
}
@@ -1591,7 +1609,7 @@
List<UserInfo> profiles = mUserManager.getProfiles(userHandle);
for (UserInfo ui : profiles) {
- int profileUserHandle = ui.getUserHandle().getIdentifier();
+ int profileUserHandle = ui.id;
final DevicePolicyData policy = getUserData(profileUserHandle);
final int count = policy.mAdminList.size();
if (count > 0) {
@@ -1878,7 +1896,7 @@
// Return strictest policy for this user and profiles that are visible from this user.
List<UserInfo> profiles = mUserManager.getProfiles(userHandle);
for (UserInfo userInfo : profiles) {
- DevicePolicyData policy = getUserData(userInfo.getUserHandle().getIdentifier());
+ DevicePolicyData policy = getUserData(userInfo.id);
final int N = policy.mAdminList.size();
for (int i=0; i<N; i++) {
ActiveAdmin admin = policy.mAdminList.get(i);
@@ -1925,7 +1943,7 @@
// Return strictest policy for this user and profiles that are visible from this user.
List<UserInfo> profiles = mUserManager.getProfiles(userHandle);
for (UserInfo userInfo : profiles) {
- DevicePolicyData policy = getUserData(userInfo.getUserHandle().getIdentifier());
+ DevicePolicyData policy = getUserData(userInfo.id);
final int N = policy.mAdminList.size();
for (int i=0; i<N; i++) {
ActiveAdmin admin = policy.mAdminList.get(i);
@@ -1972,7 +1990,7 @@
// Return strictest policy for this user and profiles that are visible from this user.
List<UserInfo> profiles = mUserManager.getProfiles(userHandle);
for (UserInfo userInfo : profiles) {
- DevicePolicyData policy = getUserData(userInfo.getUserHandle().getIdentifier());
+ DevicePolicyData policy = getUserData(userInfo.id);
final int N = policy.mAdminList.size();
for (int i = 0; i < N; i++) {
ActiveAdmin admin = policy.mAdminList.get(i);
@@ -2033,7 +2051,7 @@
List<UserInfo> profiles = mUserManager.getProfiles(userHandle);
for (UserInfo userInfo : profiles) {
- DevicePolicyData policy = getUserData(userInfo.getUserHandle().getIdentifier());
+ DevicePolicyData policy = getUserData(userInfo.id);
final int N = policy.mAdminList.size();
for (int i = 0; i < N; i++) {
ActiveAdmin admin = policy.mAdminList.get(i);
@@ -2131,7 +2149,7 @@
List<UserInfo> profiles = mUserManager.getProfiles(userHandle);
for (UserInfo userInfo : profiles) {
- DevicePolicyData policy = getUserData(userInfo.getUserHandle().getIdentifier());
+ DevicePolicyData policy = getUserData(userInfo.id);
final int N = policy.mAdminList.size();
for (int i = 0; i < N; i++) {
ActiveAdmin admin = policy.mAdminList.get(i);
@@ -2188,7 +2206,7 @@
// Return strictest policy for this user and profiles that are visible from this user.
List<UserInfo> profiles = mUserManager.getProfiles(userHandle);
for (UserInfo userInfo : profiles) {
- DevicePolicyData policy = getUserData(userInfo.getUserHandle().getIdentifier());
+ DevicePolicyData policy = getUserData(userInfo.id);
final int N = policy.mAdminList.size();
for (int i=0; i<N; i++) {
ActiveAdmin admin = policy.mAdminList.get(i);
@@ -2232,7 +2250,7 @@
// Return strictest policy for this user and profiles that are visible from this user.
List<UserInfo> profiles = mUserManager.getProfiles(userHandle);
for (UserInfo userInfo : profiles) {
- DevicePolicyData policy = getUserData(userInfo.getUserHandle().getIdentifier());
+ DevicePolicyData policy = getUserData(userInfo.id);
final int N = policy.mAdminList.size();
for (int i=0; i<N; i++) {
ActiveAdmin admin = policy.mAdminList.get(i);
@@ -2279,7 +2297,7 @@
// Return strictest policy for this user and profiles that are visible from this user.
List<UserInfo> profiles = mUserManager.getProfiles(userHandle);
for (UserInfo userInfo : profiles) {
- DevicePolicyData policy = getUserData(userInfo.getUserHandle().getIdentifier());
+ DevicePolicyData policy = getUserData(userInfo.id);
final int N = policy.mAdminList.size();
for (int i=0; i<N; i++) {
ActiveAdmin admin = policy.mAdminList.get(i);
@@ -2326,7 +2344,7 @@
// Return strictest policy for this user and profiles that are visible from this user.
List<UserInfo> profiles = mUserManager.getProfiles(userHandle);
for (UserInfo userInfo : profiles) {
- DevicePolicyData policy = getUserData(userInfo.getUserHandle().getIdentifier());
+ DevicePolicyData policy = getUserData(userInfo.id);
final int N = policy.mAdminList.size();
for (int i = 0; i < N; i++) {
ActiveAdmin admin = policy.mAdminList.get(i);
@@ -2373,7 +2391,7 @@
// Return strictest policy for this user and profiles that are visible from this user.
List<UserInfo> profiles = mUserManager.getProfiles(userHandle);
for (UserInfo userInfo : profiles) {
- DevicePolicyData policy = getUserData(userInfo.getUserHandle().getIdentifier());
+ DevicePolicyData policy = getUserData(userInfo.id);
final int N = policy.mAdminList.size();
for (int i=0; i<N; i++) {
ActiveAdmin admin = policy.mAdminList.get(i);
@@ -2420,7 +2438,7 @@
// Return strictest policy for this user and profiles that are visible from this user.
List<UserInfo> profiles = mUserManager.getProfiles(userHandle);
for (UserInfo userInfo : profiles) {
- DevicePolicyData policy = getUserData(userInfo.getUserHandle().getIdentifier());
+ DevicePolicyData policy = getUserData(userInfo.id);
final int N = policy.mAdminList.size();
for (int i=0; i<N; i++) {
ActiveAdmin admin = policy.mAdminList.get(i);
@@ -2526,7 +2544,7 @@
int count = 0;
ActiveAdmin strictestAdmin = null;
for (UserInfo userInfo : mUserManager.getProfiles(userHandle)) {
- DevicePolicyData policy = getUserData(userInfo.getUserHandle().getIdentifier());
+ DevicePolicyData policy = getUserData(userInfo.id);
for (ActiveAdmin admin : policy.mAdminList) {
if (admin.maximumFailedPasswordsForWipe ==
ActiveAdmin.DEF_MAXIMUM_FAILED_PASSWORDS_FOR_WIPE) {
@@ -2738,7 +2756,7 @@
// Return strictest policy for this user and profiles that are visible from this user.
List<UserInfo> profiles = mUserManager.getProfiles(userHandle);
for (UserInfo userInfo : profiles) {
- DevicePolicyData policy = getUserData(userInfo.getUserHandle().getIdentifier());
+ DevicePolicyData policy = getUserData(userInfo.id);
final int N = policy.mAdminList.size();
for (int i=0; i<N; i++) {
ActiveAdmin admin = policy.mAdminList.get(i);
@@ -3055,7 +3073,7 @@
private void updatePasswordExpirationsLocked(int userHandle) {
List<UserInfo> profiles = mUserManager.getProfiles(userHandle);
for (UserInfo userInfo : profiles) {
- int profileId = userInfo.getUserHandle().getIdentifier();
+ int profileId = userInfo.id;
DevicePolicyData policy = getUserData(profileId);
final int N = policy.mAdminList.size();
if (N > 0) {
@@ -4106,13 +4124,13 @@
}
}
- public void setTrustAgentFeaturesEnabled(ComponentName admin, ComponentName agent,
- List<String>features, int userHandle) {
+ public void setTrustAgentConfiguration(ComponentName admin, ComponentName agent,
+ PersistableBundle args, int userHandle) {
if (!mHasFeature) {
return;
}
enforceCrossUserPermission(userHandle);
- enforceNotManagedProfile(userHandle, "manage trust agent features");
+ enforceNotManagedProfile(userHandle, "set trust agent configuration");
synchronized (this) {
if (admin == null) {
throw new NullPointerException("admin is null");
@@ -4122,57 +4140,68 @@
}
ActiveAdmin ap = getActiveAdminForCallerLocked(admin,
DeviceAdminInfo.USES_POLICY_DISABLE_KEYGUARD_FEATURES);
- ap.trustAgentFeatures.put(agent.flattenToString(), features);
+ ap.trustAgentInfos.put(agent.flattenToString(), new TrustAgentInfo(args));
saveSettingsLocked(userHandle);
syncDeviceCapabilitiesLocked(getUserData(userHandle));
}
}
- public List<String> getTrustAgentFeaturesEnabled(ComponentName admin, ComponentName agent,
- int userHandle) {
+ public List<PersistableBundle> getTrustAgentConfiguration(ComponentName admin,
+ ComponentName agent, int userHandle) {
if (!mHasFeature) {
return null;
}
enforceCrossUserPermission(userHandle);
+ if (agent == null) {
+ throw new NullPointerException("agent is null");
+ }
+
synchronized (this) {
- if (agent == null) {
- throw new NullPointerException("agent is null");
- }
final String componentName = agent.flattenToString();
if (admin != null) {
final ActiveAdmin ap = getActiveAdminUncheckedLocked(admin, userHandle);
- return (ap != null) ? ap.trustAgentFeatures.get(componentName) : null;
+ if (ap == null) return null;
+ TrustAgentInfo trustAgentInfo = ap.trustAgentInfos.get(componentName);
+ if (trustAgentInfo == null || trustAgentInfo.options == null) return null;
+ List<PersistableBundle> result = new ArrayList<PersistableBundle>();
+ result.add(trustAgentInfo.options);
+ return result;
}
// Return strictest policy for this user and profiles that are visible from this user.
- List<UserInfo> profiles = mUserManager.getProfiles(userHandle);
- List<String> result = null;
+ final List<UserInfo> profiles = mUserManager.getProfiles(userHandle);
+ List<PersistableBundle> result = null;
+
+ // Search through all admins that use KEYGUARD_DISABLE_TRUST_AGENTS and keep track
+ // of the options. If any admin doesn't have options, discard options for the rest
+ // and return null.
+ boolean allAdminsHaveOptions = true;
for (UserInfo userInfo : profiles) {
- DevicePolicyData policy = getUserData(userInfo.getUserHandle().getIdentifier());
+ DevicePolicyData policy = getUserData(userInfo.id);
final int N = policy.mAdminList.size();
- for (int i=0; i<N; i++) {
- ActiveAdmin ap = policy.mAdminList.get(i);
- // Compute the intersection of all features for active admins that disable
- // trust agents:
- if ((ap.disabledKeyguardFeatures
- & DevicePolicyManager.KEYGUARD_DISABLE_TRUST_AGENTS) != 0) {
- final List<String> features = ap.trustAgentFeatures.get(componentName);
- if (result == null) {
- if (features == null || features.size() == 0) {
- result = new ArrayList<String>();
- Slog.w(LOG_TAG, "admin " + ap.info.getPackageName()
- + " has null trust agent feature set; all will be disabled");
- } else {
- result = new ArrayList<String>(features.size());
- result.addAll(features);
+ for (int i=0; i < N; i++) {
+ final ActiveAdmin active = policy.mAdminList.get(i);
+ final boolean disablesTrust = (active.disabledKeyguardFeatures
+ & DevicePolicyManager.KEYGUARD_DISABLE_TRUST_AGENTS) != 0;
+ final TrustAgentInfo info = active.trustAgentInfos.get(componentName);
+ if (info != null && info.options != null && !info.options.isEmpty()) {
+ if (disablesTrust) {
+ if (result == null) {
+ result = new ArrayList<PersistableBundle>();
}
+ result.add(info.options);
} else {
- result.retainAll(features);
+ Log.w(LOG_TAG, "Ignoring admin " + active.info
+ + " because it has trust options but doesn't declare "
+ + "KEYGUARD_DISABLE_TRUST_AGENTS");
}
+ } else if (disablesTrust) {
+ allAdminsHaveOptions = false;
+ break;
}
}
}
- return result;
+ return allAdminsHaveOptions ? result : null;
}
}
diff --git a/services/usage/java/com/android/server/usage/UsageStatsDatabase.java b/services/usage/java/com/android/server/usage/UsageStatsDatabase.java
index 11da380..098b3ef 100644
--- a/services/usage/java/com/android/server/usage/UsageStatsDatabase.java
+++ b/services/usage/java/com/android/server/usage/UsageStatsDatabase.java
@@ -119,6 +119,7 @@
if (!files.valueAt(start).getBaseFile().getName().endsWith("-c")) {
break;
}
+ start++;
}
if (start == fileCount - 1) {
diff --git a/services/usb/java/com/android/server/usb/UsbAudioManager.java b/services/usb/java/com/android/server/usb/UsbAudioManager.java
new file mode 100644
index 0000000..bb45ee8
--- /dev/null
+++ b/services/usb/java/com/android/server/usb/UsbAudioManager.java
@@ -0,0 +1,197 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions an
+ * limitations under the License.
+ */
+
+package com.android.server.usb;
+
+import android.alsa.AlsaCardsParser;
+import android.alsa.AlsaDevicesParser;
+import android.content.Context;
+import android.content.Intent;
+import android.hardware.usb.UsbConstants;
+import android.hardware.usb.UsbDevice;
+import android.hardware.usb.UsbInterface;
+import android.media.AudioManager;
+import android.os.UserHandle;
+import android.util.Slog;
+
+import java.io.File;
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
+import java.util.HashMap;
+
+/**
+ * UsbAudioManager manages USB audio devices.
+ */
+public class UsbAudioManager {
+ private static final String TAG = UsbAudioManager.class.getSimpleName();
+ private static final boolean DEBUG = false;
+
+ private final Context mContext;
+
+ private final class AudioDevice {
+ public int mCard;
+ public int mDevice;
+ public boolean mHasPlayback;
+ public boolean mHasCapture;
+ public boolean mHasMIDI;
+
+ public AudioDevice(int card, int device,
+ boolean hasPlayback, boolean hasCapture, boolean hasMidi) {
+ mCard = card;
+ mDevice = device;
+ mHasPlayback = hasPlayback;
+ mHasCapture = hasCapture;
+ mHasMIDI = hasMidi;
+ }
+
+ public String toString() {
+ StringBuilder sb = new StringBuilder();
+ sb.append("AudioDevice: [card: " + mCard);
+ sb.append(", device: " + mDevice);
+ sb.append(", hasPlayback: " + mHasPlayback);
+ sb.append(", hasCapture: " + mHasCapture);
+ sb.append(", hasMidi: " + mHasMIDI);
+ sb.append("]");
+ return sb.toString();
+ }
+ }
+
+ private final HashMap<UsbDevice,AudioDevice> mAudioDevices
+ = new HashMap<UsbDevice,AudioDevice>();
+
+ /* package */ UsbAudioManager(Context context) {
+ mContext = context;
+ }
+
+ // Broadcasts the arrival/departure of a USB audio interface
+ // audioDevice - the AudioDevice that was added or removed
+ // enabled - if true, we're connecting a device (it's arrived), else disconnecting
+ private void sendDeviceNotification(AudioDevice audioDevice, boolean enabled) {
+ // send a sticky broadcast containing current USB state
+ Intent intent = new Intent(AudioManager.ACTION_USB_AUDIO_DEVICE_PLUG);
+ intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING);
+ intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
+ intent.putExtra("state", enabled ? 1 : 0);
+ intent.putExtra("card", audioDevice.mCard);
+ intent.putExtra("device", audioDevice.mDevice);
+ intent.putExtra("hasPlayback", audioDevice.mHasPlayback);
+ intent.putExtra("hasCapture", audioDevice.mHasCapture);
+ intent.putExtra("hasMIDI", audioDevice.mHasMIDI);
+ mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
+ }
+
+ private boolean waitForAlsaFile(int card, int device, boolean capture) {
+ // These values were empirically determined.
+ final int kNumRetries = 5;
+ final int kSleepTime = 500; // ms
+ String alsaDevPath = "/dev/snd/pcmC" + card + "D" + device + (capture ? "c" : "p");
+ File alsaDevFile = new File(alsaDevPath);
+ boolean exists = false;
+ for (int retry = 0; !exists && retry < kNumRetries; retry++) {
+ exists = alsaDevFile.exists();
+ if (!exists) {
+ try {
+ Thread.sleep(kSleepTime);
+ } catch (IllegalThreadStateException ex) {
+ Slog.d(TAG, "usb: IllegalThreadStateException while waiting for ALSA file.");
+ } catch (java.lang.InterruptedException ex) {
+ Slog.d(TAG, "usb: InterruptedException while waiting for ALSA file.");
+ }
+ }
+ }
+
+ return exists;
+ }
+
+ /* package */ void deviceAdded(UsbDevice usbDevice) {
+ // Is there an audio interface in there?
+ boolean isAudioDevice = false;
+
+ // FIXME - handle multiple configurations?
+ int interfaceCount = usbDevice.getInterfaceCount();
+ for (int ntrfaceIndex = 0; !isAudioDevice && ntrfaceIndex < interfaceCount;
+ ntrfaceIndex++) {
+ UsbInterface ntrface = usbDevice.getInterface(ntrfaceIndex);
+ if (ntrface.getInterfaceClass() == UsbConstants.USB_CLASS_AUDIO) {
+ isAudioDevice = true;
+ }
+ }
+ if (!isAudioDevice) {
+ return;
+ }
+
+ //TODO(pmclean) The "Parser" objects inspect files in "/proc/asound" which we presume is
+ // present, unlike the waitForAlsaFile() which waits on a file in /dev/snd. It is not
+ // clear why this works, or that it can be relied on going forward. Needs further
+ // research.
+ AlsaCardsParser cardsParser = new AlsaCardsParser();
+ cardsParser.scan();
+ // cardsParser.Log();
+
+ // But we need to parse the device to determine its capabilities.
+ AlsaDevicesParser devicesParser = new AlsaDevicesParser();
+ devicesParser.scan();
+ // devicesParser.Log();
+
+ // The protocol for now will be to select the last-connected (highest-numbered)
+ // Alsa Card.
+ int card = cardsParser.getNumCardRecords() - 1;
+ int device = 0;
+
+ boolean hasPlayback = devicesParser.hasPlaybackDevices(card);
+ boolean hasCapture = devicesParser.hasCaptureDevices(card);
+ boolean hasMidi = devicesParser.hasMIDIDevices(card);
+
+ // Playback device file needed/present?
+ if (hasPlayback &&
+ !waitForAlsaFile(card, device, false)) {
+ return;
+ }
+
+ // Capture device file needed/present?
+ if (hasCapture &&
+ !waitForAlsaFile(card, device, true)) {
+ return;
+ }
+
+ if (DEBUG) {
+ Slog.d(TAG,
+ "usb: hasPlayback:" + hasPlayback + " hasCapture:" + hasCapture);
+ }
+
+ AudioDevice audioDevice = new AudioDevice(card, device, hasPlayback, hasCapture, hasMidi);
+ mAudioDevices.put(usbDevice, audioDevice);
+ sendDeviceNotification(audioDevice, true);
+ }
+
+ /* package */ void deviceRemoved(UsbDevice device) {
+ if (DEBUG) {
+ Slog.d(TAG, "deviceRemoved(): " + device);
+ }
+
+ AudioDevice audioDevice = mAudioDevices.remove(device);
+ if (audioDevice != null) {
+ sendDeviceNotification(audioDevice, false);
+ }
+ }
+
+ public void dump(FileDescriptor fd, PrintWriter pw) {
+ pw.println(" USB AudioDevices:");
+ for (UsbDevice device : mAudioDevices.keySet()) {
+ pw.println(" " + device.getDeviceName() + ": " + mAudioDevices.get(device));
+ }
+ }
+}
diff --git a/services/usb/java/com/android/server/usb/UsbHostManager.java b/services/usb/java/com/android/server/usb/UsbHostManager.java
index 06febb3..e769bda 100644
--- a/services/usb/java/com/android/server/usb/UsbHostManager.java
+++ b/services/usb/java/com/android/server/usb/UsbHostManager.java
@@ -16,8 +16,6 @@
package com.android.server.usb;
-import android.alsa.AlsaCardsParser;
-import android.alsa.AlsaDevicesParser;
import android.content.Context;
import android.content.Intent;
import android.hardware.usb.UsbConfiguration;
@@ -25,16 +23,13 @@
import android.hardware.usb.UsbDevice;
import android.hardware.usb.UsbEndpoint;
import android.hardware.usb.UsbInterface;
-import android.media.AudioManager;
import android.os.Bundle;
import android.os.ParcelFileDescriptor;
import android.os.Parcelable;
-import android.os.UserHandle;
import android.util.Slog;
import com.android.internal.annotations.GuardedBy;
-import java.io.File;
import java.io.FileDescriptor;
import java.io.FileNotFoundException;
import java.io.PrintWriter;
@@ -46,11 +41,12 @@
*/
public class UsbHostManager {
private static final String TAG = UsbHostManager.class.getSimpleName();
- private static final boolean DEBUG_AUDIO = false;
+ private static final boolean DEBUG = false;
// contains all connected USB devices
private final HashMap<String, UsbDevice> mDevices = new HashMap<String, UsbDevice>();
+
// USB busses to exclude from USB host support
private final String[] mHostBlacklist;
@@ -64,14 +60,7 @@
private ArrayList<UsbInterface> mNewInterfaces;
private ArrayList<UsbEndpoint> mNewEndpoints;
- // Attributes of any connected USB audio device.
- //TODO(pmclean) When we extend to multiple, USB Audio devices, we will need to get
- // more clever about this.
- private int mConnectedUsbCard = -1;
- private int mConnectedUsbDeviceNum = -1;
- private boolean mConnectedHasPlayback = false;
- private boolean mConnectedHasCapture = false;
- private boolean mConnectedHasMIDI = false;
+ private UsbAudioManager mUsbAudioManager;
@GuardedBy("mLock")
private UsbSettingsManager mCurrentSettings;
@@ -80,6 +69,7 @@
mContext = context;
mHostBlacklist = context.getResources().getStringArray(
com.android.internal.R.array.config_usbHostBlacklist);
+ mUsbAudioManager = new UsbAudioManager(context);
}
public void setCurrentSettings(UsbSettingsManager settings) {
@@ -118,48 +108,6 @@
return false;
}
- // Broadcasts the arrival/departure of a USB audio interface
- // card - the ALSA card number of the physical interface
- // device - the ALSA device number of the physical interface
- // enabled - if true, we're connecting a device (it's arrived), else disconnecting
- private void sendDeviceNotification(int card, int device, boolean enabled,
- boolean hasPlayback, boolean hasCapture, boolean hasMIDI) {
- // send a sticky broadcast containing current USB state
- Intent intent = new Intent(AudioManager.ACTION_USB_AUDIO_DEVICE_PLUG);
- intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING);
- intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
- intent.putExtra("state", enabled ? 1 : 0);
- intent.putExtra("card", card);
- intent.putExtra("device", device);
- intent.putExtra("hasPlayback", hasPlayback);
- intent.putExtra("hasCapture", hasCapture);
- intent.putExtra("hasMIDI", hasMIDI);
- mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
- }
-
- private boolean waitForAlsaFile(int card, int device, boolean capture) {
- // These values were empirically determined.
- final int kNumRetries = 5;
- final int kSleepTime = 500; // ms
- String alsaDevPath = "/dev/snd/pcmC" + card + "D" + device + (capture ? "c" : "p");
- File alsaDevFile = new File(alsaDevPath);
- boolean exists = false;
- for (int retry = 0; !exists && retry < kNumRetries; retry++) {
- exists = alsaDevFile.exists();
- if (!exists) {
- try {
- Thread.sleep(kSleepTime);
- } catch (IllegalThreadStateException ex) {
- Slog.d(TAG, "usb: IllegalThreadStateException while waiting for ALSA file.");
- } catch (java.lang.InterruptedException ex) {
- Slog.d(TAG, "usb: InterruptedException while waiting for ALSA file.");
- }
- }
- }
-
- return exists;
- }
-
/* Called from JNI in monitorUsbHostBus() to report new USB devices
Returns true if successful, in which case the JNI code will continue adding configurations,
interfaces and endpoints, and finally call endUsbDeviceAdded after all descriptors
@@ -169,7 +117,7 @@
int deviceClass, int deviceSubclass, int deviceProtocol,
String manufacturerName, String productName, String serialNumber) {
- if (DEBUG_AUDIO) {
+ if (DEBUG) {
Slog.d(TAG, "usb:UsbHostManager.beginUsbDeviceAdded(" + deviceName + ")");
// Audio Class Codes:
// Audio: 0x01
@@ -254,7 +202,7 @@
/* Called from JNI in monitorUsbHostBus() to finish adding a new device */
private void endUsbDeviceAdded() {
- if (DEBUG_AUDIO) {
+ if (DEBUG) {
Slog.d(TAG, "usb:UsbHostManager.endUsbDeviceAdded()");
}
if (mNewInterface != null) {
@@ -266,16 +214,6 @@
mNewInterfaces.toArray(new UsbInterface[mNewInterfaces.size()]));
}
- // Is there an audio interface in there?
- final int kUsbClassId_Audio = 0x01;
- boolean isAudioDevice = false;
- for (int ntrfaceIndex = 0; !isAudioDevice && ntrfaceIndex < mNewInterfaces.size();
- ntrfaceIndex++) {
- UsbInterface ntrface = mNewInterfaces.get(ntrfaceIndex);
- if (ntrface.getInterfaceClass() == kUsbClassId_Audio) {
- isAudioDevice = true;
- }
- }
synchronized (mLock) {
if (mNewDevice != null) {
@@ -284,6 +222,7 @@
mDevices.put(mNewDevice.getDeviceName(), mNewDevice);
Slog.d(TAG, "Added device " + mNewDevice);
getCurrentSettings().deviceAttached(mNewDevice);
+ mUsbAudioManager.deviceAdded(mNewDevice);
} else {
Slog.e(TAG, "mNewDevice is null in endUsbDeviceAdded");
}
@@ -292,81 +231,14 @@
mNewInterfaces = null;
mNewEndpoints = null;
}
-
- if (!isAudioDevice) {
- return; // bail
- }
-
- //TODO(pmclean) The "Parser" objects inspect files in "/proc/asound" which we presume is
- // present, unlike the waitForAlsaFile() which waits on a file in /dev/snd. It is not
- // clear why this works, or that it can be relied on going forward. Needs further
- // research.
- AlsaCardsParser cardsParser = new AlsaCardsParser();
- cardsParser.scan();
- // cardsParser.Log();
-
- // But we need to parse the device to determine its capabilities.
- AlsaDevicesParser devicesParser = new AlsaDevicesParser();
- devicesParser.scan();
- // devicesParser.Log();
-
- // The protocol for now will be to select the last-connected (highest-numbered)
- // Alsa Card.
- mConnectedUsbCard = cardsParser.getNumCardRecords() - 1;
- mConnectedUsbDeviceNum = 0;
-
- mConnectedHasPlayback = devicesParser.hasPlaybackDevices(mConnectedUsbCard);
- mConnectedHasCapture = devicesParser.hasCaptureDevices(mConnectedUsbCard);
- mConnectedHasMIDI = devicesParser.hasMIDIDevices(mConnectedUsbCard);
-
- // Playback device file needed/present?
- if (mConnectedHasPlayback &&
- !waitForAlsaFile(mConnectedUsbCard, mConnectedUsbDeviceNum, false)) {
- return;
- }
-
- // Capture device file needed/present?
- if (mConnectedHasCapture &&
- !waitForAlsaFile(mConnectedUsbCard, mConnectedUsbDeviceNum, true)) {
- return;
- }
-
- if (DEBUG_AUDIO) {
- Slog.d(TAG,
- "usb: hasPlayback:" + mConnectedHasPlayback + " hasCapture:" + mConnectedHasCapture);
- }
-
- sendDeviceNotification(mConnectedUsbCard,
- mConnectedUsbDeviceNum,
- true,
- mConnectedHasPlayback,
- mConnectedHasCapture,
- mConnectedHasMIDI);
}
/* Called from JNI in monitorUsbHostBus to report USB device removal */
private void usbDeviceRemoved(String deviceName) {
- if (DEBUG_AUDIO) {
- Slog.d(TAG, "usb:UsbHostManager.usbDeviceRemoved() nm:" + deviceName);
- }
-
- if (mConnectedUsbCard != -1 && mConnectedUsbDeviceNum != -1) {
- sendDeviceNotification(mConnectedUsbCard,
- mConnectedUsbDeviceNum,
- false,
- mConnectedHasPlayback,
- mConnectedHasCapture,
- mConnectedHasMIDI);
- mConnectedUsbCard = -1;
- mConnectedUsbDeviceNum = -1;
- mConnectedHasPlayback = false;
- mConnectedHasCapture = false;
- mConnectedHasMIDI = false;
- }
-
synchronized (mLock) {
UsbDevice device = mDevices.remove(deviceName);
if (device != null) {
+ mUsbAudioManager.deviceRemoved(device);
getCurrentSettings().deviceDetached(device);
}
}
@@ -418,6 +290,7 @@
pw.println(" " + name + ": " + mDevices.get(name));
}
}
+ mUsbAudioManager.dump(fd, pw);
}
private native void monitorUsbHostBus();
diff --git a/telecomm/java/android/telecom/AudioState.java b/telecomm/java/android/telecom/AudioState.java
index d0e2860..43da38f 100644
--- a/telecomm/java/android/telecom/AudioState.java
+++ b/telecomm/java/android/telecom/AudioState.java
@@ -22,7 +22,8 @@
import java.util.Locale;
/**
- * Encapsulates all audio states during a call.
+ * Encapsulates the telecom audio state, including the current audio routing, supported audio
+ * routing and mute.
*/
public final class AudioState implements Parcelable {
/** Direct the audio stream through the device's earpiece. */
@@ -53,10 +54,10 @@
/** True if the call is muted, false otherwise. */
public final boolean isMuted;
- /** The route to use for the audio stream. */
+ /** The current audio route being used. */
public final int route;
- /** Bit vector of all routes supported by this call. */
+ /** Bit mask of all routes supported by this call. */
public final int supportedRouteMask;
public AudioState(boolean isMuted, int route, int supportedRouteMask) {
diff --git a/telecomm/java/android/telecom/Conference.java b/telecomm/java/android/telecom/Conference.java
index 15cb786..6480a8a 100644
--- a/telecomm/java/android/telecom/Conference.java
+++ b/telecomm/java/android/telecom/Conference.java
@@ -207,6 +207,13 @@
}
/**
+ * @return The {@link DisconnectCause} for this connection.
+ */
+ public final DisconnectCause getDisconnectCause() {
+ return mDisconnectCause;
+ }
+
+ /**
* Sets the capabilities of a conference. See {@link PhoneCapabilities} for valid values.
*
* @param capabilities A bitmask of the {@code PhoneCapabilities} of the conference call.
@@ -334,6 +341,19 @@
}
/**
+ * Retrieves the primary connection associated with the conference. The primary connection is
+ * the connection from which the conference will retrieve its current state.
+ *
+ * @return The primary connection.
+ */
+ public Connection getPrimaryConnection() {
+ if (mUnmodifiableChildConnections == null || mUnmodifiableChildConnections.isEmpty()) {
+ return null;
+ }
+ return mUnmodifiableChildConnections.get(0);
+ }
+
+ /**
* Inform this Conference that the state of its audio output has been changed externally.
*
* @param state The new audio state.
diff --git a/telecomm/java/android/telecom/Connection.java b/telecomm/java/android/telecom/Connection.java
index 9bdbba8..34d0660 100644
--- a/telecomm/java/android/telecom/Connection.java
+++ b/telecomm/java/android/telecom/Connection.java
@@ -974,6 +974,15 @@
public void onDisconnect() {}
/**
+ * Notifies this Connection of a request to disconnect a participant of the conference managed
+ * by the connection.
+ *
+ * @param endpoint the {@link Uri} of the participant to disconnect.
+ * @hide
+ */
+ public void onDisconnectConferenceParticipant(Uri endpoint) {}
+
+ /**
* Notifies this Connection of a request to separate from its parent conference.
*/
public void onSeparate() {}
diff --git a/telecomm/java/android/telecom/ConnectionService.java b/telecomm/java/android/telecom/ConnectionService.java
index 649533e..4648d78 100644
--- a/telecomm/java/android/telecom/ConnectionService.java
+++ b/telecomm/java/android/telecom/ConnectionService.java
@@ -40,8 +40,37 @@
import java.util.concurrent.ConcurrentHashMap;
/**
- * A {@link android.app.Service} that provides telephone connections to processes running on an
- * Android device.
+ * {@code ConnectionService} is an abstract service that should be implemented by any app which can
+ * make phone calls and want those calls to be integrated into the built-in phone app.
+ * Once implemented, the {@code ConnectionService} needs two additional steps before it will be
+ * integrated into the phone app:
+ * <p>
+ * 1. <i>Registration in AndroidManifest.xml</i>
+ * <br/>
+ * <pre>
+ * <service android:name="com.example.package.MyConnectionService"
+ * android:label="@string/some_label_for_my_connection_service"
+ * android:permission="android.permission.BIND_CONNECTION_SERVICE">
+ * <intent-filter>
+ * <action android:name="android.telecom.ConnectionService" />
+ * </intent-filter>
+ * </service>
+ * </pre>
+ * <p>
+ * 2. <i> Registration of {@link PhoneAccount} with {@link TelecomManager}.</i>
+ * <br/>
+ * See {@link PhoneAccount} and {@link TelecomManager#registerPhoneAccount} for more information.
+ * <p>
+ * Once registered and enabled by the user in the dialer settings, telecom will bind to a
+ * {@code ConnectionService} implementation when it wants that {@code ConnectionService} to place
+ * a call or the service has indicated that is has an incoming call through
+ * {@link TelecomManager#addNewIncomingCall}. The {@code ConnectionService} can then expect a call
+ * to {@link #onCreateIncomingConnection} or {@link #onCreateOutgoingConnection} wherein it
+ * should provide a new instance of a {@link Connection} object. It is through this
+ * {@link Connection} object that telecom receives state updates and the {@code ConnectionService}
+ * receives call-commands such as answer, reject, hold and disconnect.
+ * <p>
+ * When there are no more live calls, telecom will unbind from the {@code ConnectionService}.
*/
public abstract class ConnectionService extends Service {
/**
@@ -746,7 +775,9 @@
/**
* Ask some other {@code ConnectionService} to create a {@code RemoteConnection} given an
- * incoming request. This is used to attach to existing incoming calls.
+ * incoming request. This is used by {@code ConnectionService}s that are registered with
+ * {@link PhoneAccount#CAPABILITY_CONNECTION_MANAGER} and want to be able to manage
+ * SIM-based incoming calls.
*
* @param connectionManagerPhoneAccount See description at
* {@link #onCreateOutgoingConnection(PhoneAccountHandle, ConnectionRequest)}.
@@ -763,7 +794,9 @@
/**
* Ask some other {@code ConnectionService} to create a {@code RemoteConnection} given an
- * outgoing request. This is used to initiate new outgoing calls.
+ * outgoing request. This is used by {@code ConnectionService}s that are registered with
+ * {@link PhoneAccount#CAPABILITY_CONNECTION_MANAGER} and want to be able to use the
+ * SIM-based {@code ConnectionService} to place its outgoing calls.
*
* @param connectionManagerPhoneAccount See description at
* {@link #onCreateOutgoingConnection(PhoneAccountHandle, ConnectionRequest)}.
@@ -779,12 +812,19 @@
}
/**
- * Adds two {@code RemoteConnection}s to some {@code RemoteConference}.
+ * Indicates to the relevant {@code RemoteConnectionService} that the specified
+ * {@link RemoteConnection}s should be merged into a conference call.
+ * <p>
+ * If the conference request is successful, the method {@link #onRemoteConferenceAdded} will
+ * be invoked.
+ *
+ * @param remoteConnection1 The first of the remote connections to conference.
+ * @param remoteConnection2 The second of the remote connections to conference.
*/
public final void conferenceRemoteConnections(
- RemoteConnection a,
- RemoteConnection b) {
- mRemoteConnectionManager.conferenceRemoteConnections(a, b);
+ RemoteConnection remoteConnection1,
+ RemoteConnection remoteConnection2) {
+ mRemoteConnectionManager.conferenceRemoteConnections(remoteConnection1, remoteConnection2);
}
/**
@@ -822,6 +862,40 @@
}
/**
+ * Adds a connection created by the {@link ConnectionService} and informs telecom of the new
+ * connection.
+ *
+ * @param phoneAccountHandle The phone account handle for the connection.
+ * @param connection The connection to add.
+ */
+ public final void addExistingConnection(PhoneAccountHandle phoneAccountHandle,
+ Connection connection) {
+
+ String id = addExistingConnectionInternal(connection);
+ if (id != null) {
+ List<String> emptyList = new ArrayList<>(0);
+
+ ParcelableConnection parcelableConnection = new ParcelableConnection(
+ phoneAccountHandle,
+ connection.getState(),
+ connection.getCallCapabilities(),
+ connection.getAddress(),
+ connection.getAddressPresentation(),
+ connection.getCallerDisplayName(),
+ connection.getCallerDisplayNamePresentation(),
+ connection.getVideoProvider() == null ?
+ null : connection.getVideoProvider().getInterface(),
+ connection.getVideoState(),
+ connection.isRingbackRequested(),
+ connection.getAudioModeIsVoip(),
+ connection.getStatusHints(),
+ connection.getDisconnectCause(),
+ emptyList);
+ mAdapter.addExistingConnection(id, parcelableConnection);
+ }
+ }
+
+ /**
* Returns all the active {@code Connection}s for which this {@code ConnectionService}
* has taken responsibility.
*
@@ -903,9 +977,25 @@
*/
public void onConference(Connection connection1, Connection connection2) {}
+ /**
+ * Indicates that a remote conference has been created for existing {@link RemoteConnection}s.
+ * When this method is invoked, this {@link ConnectionService} should create its own
+ * representation of the conference call and send it to telecom using {@link #addConference}.
+ * <p>
+ * This is only relevant to {@link ConnectionService}s which are registered with
+ * {@link PhoneAccount#CAPABILITY_CONNECTION_MANAGER}.
+ *
+ * @param conference The remote conference call.
+ */
public void onRemoteConferenceAdded(RemoteConference conference) {}
/**
+ * Called when an existing connection is added remotely.
+ * @param connection The existing connection which was added.
+ */
+ public void onRemoteExistingConnectionAdded(RemoteConnection connection) {}
+
+ /**
* @hide
*/
public boolean containsConference(Conference conference) {
@@ -917,6 +1007,11 @@
onRemoteConferenceAdded(remoteConference);
}
+ /** {@hide} */
+ void addRemoteExistingConnection(RemoteConnection remoteConnection) {
+ onRemoteExistingConnectionAdded(remoteConnection);
+ }
+
private void onAccountsInitialized() {
mAreAccountsInitialized = true;
for (Runnable r : mPreInitializationConnectionRequests) {
@@ -925,6 +1020,18 @@
mPreInitializationConnectionRequests.clear();
}
+ /**
+ * Adds an existing connection to the list of connections, identified by a new UUID.
+ *
+ * @param connection The connection.
+ * @return The UUID of the connection (e.g. the call-id).
+ */
+ private String addExistingConnectionInternal(Connection connection) {
+ String id = UUID.randomUUID().toString();
+ addConnection(id, connection);
+ return id;
+ }
+
private void addConnection(String callId, Connection connection) {
mConnectionById.put(callId, connection);
mIdByConnection.put(connection, callId);
diff --git a/telecomm/java/android/telecom/ConnectionServiceAdapter.java b/telecomm/java/android/telecom/ConnectionServiceAdapter.java
index c676172..e67af8c 100644
--- a/telecomm/java/android/telecom/ConnectionServiceAdapter.java
+++ b/telecomm/java/android/telecom/ConnectionServiceAdapter.java
@@ -344,4 +344,20 @@
}
}
}
+
+ /**
+ * Informs telecom of an existing connection which was added by the {@link ConnectionService}.
+ *
+ * @param callId The unique ID of the call being added.
+ * @param connection The connection.
+ */
+ void addExistingConnection(String callId, ParcelableConnection connection) {
+ Log.v(this, "addExistingConnection: %s", callId);
+ for (IConnectionServiceAdapter adapter : mAdapters) {
+ try {
+ adapter.addExistingConnection(callId, connection);
+ } catch (RemoteException ignored) {
+ }
+ }
+ }
}
diff --git a/telecomm/java/android/telecom/ConnectionServiceAdapterServant.java b/telecomm/java/android/telecom/ConnectionServiceAdapterServant.java
index 217dbc3..519a400 100644
--- a/telecomm/java/android/telecom/ConnectionServiceAdapterServant.java
+++ b/telecomm/java/android/telecom/ConnectionServiceAdapterServant.java
@@ -57,6 +57,7 @@
private static final int MSG_SET_ADDRESS = 18;
private static final int MSG_SET_CALLER_DISPLAY_NAME = 19;
private static final int MSG_SET_CONFERENCEABLE_CONNECTIONS = 20;
+ private static final int MSG_ADD_EXISTING_CONNECTION = 21;
private final IConnectionServiceAdapter mDelegate;
@@ -199,6 +200,16 @@
}
break;
}
+ case MSG_ADD_EXISTING_CONNECTION: {
+ SomeArgs args = (SomeArgs) msg.obj;
+ try {
+ mDelegate.addExistingConnection(
+ (String) args.arg1, (ParcelableConnection) args.arg2);
+ } finally {
+ args.recycle();
+ }
+ break;
+ }
}
}
};
@@ -345,6 +356,15 @@
args.arg2 = conferenceableConnectionIds;
mHandler.obtainMessage(MSG_SET_CONFERENCEABLE_CONNECTIONS, args).sendToTarget();
}
+
+ @Override
+ public final void addExistingConnection(
+ String connectionId, ParcelableConnection connection) {
+ SomeArgs args = SomeArgs.obtain();
+ args.arg1 = connectionId;
+ args.arg2 = connection;
+ mHandler.obtainMessage(MSG_ADD_EXISTING_CONNECTION, args).sendToTarget();
+ }
};
public ConnectionServiceAdapterServant(IConnectionServiceAdapter delegate) {
diff --git a/telecomm/java/android/telecom/DisconnectCause.java b/telecomm/java/android/telecom/DisconnectCause.java
index 9be0138..73bcd0c 100644
--- a/telecomm/java/android/telecom/DisconnectCause.java
+++ b/telecomm/java/android/telecom/DisconnectCause.java
@@ -25,9 +25,10 @@
/**
* Describes the cause of a disconnected call. This always includes a code describing the generic
- * cause of the disconnect. Optionally, it may include a localized label and/or localized description
- * to display to the user which is provided by the {@link ConnectionService}. It also may contain a
- * reason for the the disconnect, which is intended for logging and not for display to the user.
+ * cause of the disconnect. Optionally, it may include a label and/or description to display to the
+ * user. It is the responsibility of the {@link ConnectionService} to provide localized versions of
+ * the label and description. It also may contain a reason for the disconnect, which is intended for
+ * logging and not for display to the user.
*/
public final class DisconnectCause implements Parcelable {
@@ -57,6 +58,11 @@
public static final int RESTRICTED = 8;
/** Disconnected for reason not described by other disconnect codes. */
public static final int OTHER = 9;
+ /**
+ * Disconnected because the connection manager did not support the call. The call will be tried
+ * again without a connection manager. See {@link PhoneAccount#CAPABILITY_CONNECTION_MANAGER}.
+ */
+ public static final int CONNECTION_MANAGER_NOT_SUPPORTED = 10;
private int mDisconnectCode;
private CharSequence mDisconnectLabel;
@@ -85,6 +91,7 @@
/**
* Creates a new DisconnectCause.
+ *
* @param label The localized label to show to the user to explain the disconnect.
* @param code The code for the disconnect cause.
* @param description The localized description to show to the user to explain the disconnect.
@@ -218,7 +225,10 @@
@Override
public String toString() {
String code = "";
- switch (getCode()) {
+ switch (mDisconnectCode) {
+ case UNKNOWN:
+ code = "UNKNOWN";
+ break;
case ERROR:
code = "ERROR";
break;
@@ -228,6 +238,9 @@
case REMOTE:
code = "REMOTE";
break;
+ case CANCELED:
+ code = "CANCELED";
+ break;
case MISSED:
code = "MISSED";
break;
@@ -243,9 +256,12 @@
case OTHER:
code = "OTHER";
break;
- case UNKNOWN:
+ case CONNECTION_MANAGER_NOT_SUPPORTED:
+ code = "CONNECTION_MANAGER_NOT_SUPPORTED";
+ break;
default:
- code = "UNKNOWN";
+ code = "invalid code: " + mDisconnectCode;
+ break;
}
String label = mDisconnectLabel == null ? "" : mDisconnectLabel.toString();
String description = mDisconnectDescription == null
diff --git a/telecomm/java/android/telecom/GatewayInfo.java b/telecomm/java/android/telecom/GatewayInfo.java
index 583c3e2..7105602 100644
--- a/telecomm/java/android/telecom/GatewayInfo.java
+++ b/telecomm/java/android/telecom/GatewayInfo.java
@@ -23,12 +23,16 @@
import android.text.TextUtils;
/**
- * When calls are made, they may contain gateway information for services which route phone calls
- * through their own service/numbers. The data consists of a number to call and the package name of
- * the service. This data is used in two ways:
+ * Encapsulated gateway address information for outgoing call. When calls are made, the system
+ * provides a facility to specify two addresses for the call: one to display as the address being
+ * dialed and a separate (gateway) address to actually dial. Telecom provides this information to
+ * {@link ConnectionService}s when placing the call as an instance of {@code GatewayInfo}.
+ * <p>
+ * The data consists of an address to call, an address to display and the package name of the
+ * service. This data is used in two ways:
* <ol>
- * <li> Call the appropriate routing number
- * <li> Display information about how the call is being routed to the user
+ * <li> Call the appropriate gateway address.
+ * <li> Display information about how the call is being routed to the user.
* </ol>
*/
public class GatewayInfo implements Parcelable {
@@ -46,31 +50,39 @@
}
/**
- * Package name of the gateway provider service. used to place the call with.
+ * Package name of the gateway provider service that provided the gateway information.
+ * This can be used to identify the gateway address source and to load an appropriate icon when
+ * displaying gateway information in the in-call UI.
*/
public String getGatewayProviderPackageName() {
return mGatewayProviderPackageName;
}
/**
- * Gateway provider address to use when actually placing the call.
+ * Returns the gateway address to dial when placing the call.
*/
public Uri getGatewayAddress() {
return mGatewayAddress;
}
/**
- * The actual call address that the user is trying to connect to via the gateway.
+ * Returns the address that the user is trying to connect to via the gateway.
*/
public Uri getOriginalAddress() {
return mOriginalAddress;
}
+ /**
+ * Indicates whether this {@code GatewayInfo} instance contains any data. A returned value of
+ * false indicates that no gateway number is being used for the call.
+ */
public boolean isEmpty() {
return TextUtils.isEmpty(mGatewayProviderPackageName) || mGatewayAddress == null;
}
- /** Implement the Parcelable interface */
+ /**
+ * The Parcelable interface.
+ * */
public static final Parcelable.Creator<GatewayInfo> CREATOR =
new Parcelable.Creator<GatewayInfo> () {
diff --git a/telecomm/java/android/telecom/PhoneAccountHandle.java b/telecomm/java/android/telecom/PhoneAccountHandle.java
index 768188b..bc4cc8c 100644
--- a/telecomm/java/android/telecom/PhoneAccountHandle.java
+++ b/telecomm/java/android/telecom/PhoneAccountHandle.java
@@ -23,7 +23,16 @@
import java.util.Objects;
/**
- * The unique identifier for a {@link PhoneAccount}.
+ * The unique identifier for a {@link PhoneAccount}. A {@code PhoneAccountHandle} is made of two
+ * parts:
+ * <ul>
+ * <li>The component name of the associated {@link ConnectionService}.</li>
+ * <li>A string identifier that is unique across {@code PhoneAccountHandle}s with the same
+ * component name.</li>
+ * </ul>
+ *
+ * See {@link PhoneAccount},
+ * {@link TelecomManager#registerPhoneAccount TelecomManager.registerPhoneAccount}.
*/
public class PhoneAccountHandle implements Parcelable {
private ComponentName mComponentName;
diff --git a/telecomm/java/android/telecom/PhoneCapabilities.java b/telecomm/java/android/telecom/PhoneCapabilities.java
index 9c67503..3d3c6bd 100644
--- a/telecomm/java/android/telecom/PhoneCapabilities.java
+++ b/telecomm/java/android/telecom/PhoneCapabilities.java
@@ -17,8 +17,8 @@
package android.telecom;
/**
- * Defines capabilities a phone call can support, such as conference calling and video telephony.
- * Also defines properties of a phone call, such as whether it is using VoLTE technology.
+ * Defines capabilities for {@link Connection}s and {@link Conference}s such as hold, swap, and
+ * merge.
*/
public final class PhoneCapabilities {
/** Call can currently be put on hold or unheld. */
@@ -28,15 +28,22 @@
public static final int SUPPORT_HOLD = 0x00000002;
/**
- * Calls within a conference can be merged. Some connection services create a conference call
- * only after two calls have been merged. However, a conference call can also be added the
- * moment there are more than one call. CDMA calls are implemented in this way because the call
- * actions are more limited when more than one call exists. This flag allows merge to be exposed
- * as a capability on the conference call instead of individual calls.
+ * Calls within a conference can be merged. A {@link ConnectionService} has the option to
+ * add a {@link Conference} call before the child {@link Connection}s are merged. This is how
+ * CDMA-based {@link Connection}s are implemented. For these unmerged {@link Conference}s, this
+ * capability allows a merge button to be shown while the conference call is in the foreground
+ * of the in-call UI.
+ * <p>
+ * This is only intended for use by a {@link Conference}.
*/
public static final int MERGE_CONFERENCE = 0x00000004;
- /** Calls withing a conference can be swapped between foreground and background. */
+ /**
+ * Calls within a conference can be swapped between foreground and background.
+ * See {@link #MERGE_CONFERENCE} for additional information.
+ * <p>
+ * This is only intended for use by a {@link Conference}.
+ */
public static final int SWAP_CONFERENCE = 0x00000008;
/** Call currently supports adding another call to this one. */
@@ -49,8 +56,8 @@
public static final int MUTE = 0x00000040;
/**
- * Call supports conference call management. This capability only applies to conference calls
- * which can have other calls as children.
+ * Call supports conference call management. This capability only applies to {@link Conference}
+ * calls which can have {@link Connection}s as children.
*/
public static final int MANAGE_CONFERENCE = 0x00000080;
diff --git a/telecomm/java/android/telecom/RemoteConnection.java b/telecomm/java/android/telecom/RemoteConnection.java
index 9a094df..816e2bf 100644
--- a/telecomm/java/android/telecom/RemoteConnection.java
+++ b/telecomm/java/android/telecom/RemoteConnection.java
@@ -407,6 +407,29 @@
}
/**
+ * @hide
+ */
+ RemoteConnection(String callId, IConnectionService connectionService,
+ ParcelableConnection connection) {
+ mConnectionId = callId;
+ mConnectionService = connectionService;
+ mConnected = true;
+ mState = connection.getState();
+ mDisconnectCause = connection.getDisconnectCause();
+ mRingbackRequested = connection.isRingbackRequested();
+ mCallCapabilities = connection.getCapabilities();
+ mVideoState = connection.getVideoState();
+ mVideoProvider = new RemoteConnection.VideoProvider(connection.getVideoProvider());
+ mIsVoipAudioMode = connection.getIsVoipAudioMode();
+ mStatusHints = connection.getStatusHints();
+ mAddress = connection.getHandle();
+ mAddressPresentation = connection.getHandlePresentation();
+ mCallerDisplayName = connection.getCallerDisplayName();
+ mCallerDisplayNamePresentation = connection.getCallerDisplayNamePresentation();
+ mConference = null;
+ }
+
+ /**
* Create a RemoteConnection which is used for failed connections. Note that using it for any
* "real" purpose will almost certainly fail. Callers should note the failure and act
* accordingly (moving on to another RemoteConnection, for example)
@@ -415,7 +438,7 @@
* @hide
*/
RemoteConnection(DisconnectCause disconnectCause) {
- this("NULL", null, null);
+ mConnectionId = "NULL";
mConnected = false;
mState = Connection.STATE_DISCONNECTED;
mDisconnectCause = disconnectCause;
diff --git a/telecomm/java/android/telecom/RemoteConnectionService.java b/telecomm/java/android/telecom/RemoteConnectionService.java
index af4ee22..4bb78c0 100644
--- a/telecomm/java/android/telecom/RemoteConnectionService.java
+++ b/telecomm/java/android/telecom/RemoteConnectionService.java
@@ -41,8 +41,9 @@
*/
final class RemoteConnectionService {
+ // Note: Casting null to avoid ambiguous constructor reference.
private static final RemoteConnection NULL_CONNECTION =
- new RemoteConnection("NULL", null, null);
+ new RemoteConnection("NULL", null, (ConnectionRequest) null);
private static final RemoteConference NULL_CONFERENCE =
new RemoteConference("NULL", null);
@@ -286,6 +287,15 @@
.setConferenceableConnections(conferenceable);
}
}
+
+ @Override
+ public void addExistingConnection(String callId, ParcelableConnection connection) {
+ // TODO: add contents of this method
+ RemoteConnection remoteConnction = new RemoteConnection(callId,
+ mOutgoingConnectionServiceRpc, connection);
+
+ mOurConnectionServiceImpl.addRemoteExistingConnection(remoteConnction);
+ }
};
private final ConnectionServiceAdapterServant mServant =
diff --git a/telecomm/java/android/telecom/TelecomManager.java b/telecomm/java/android/telecom/TelecomManager.java
index bc51a70..d98a255 100644
--- a/telecomm/java/android/telecom/TelecomManager.java
+++ b/telecomm/java/android/telecom/TelecomManager.java
@@ -17,6 +17,7 @@
import android.annotation.SystemApi;
import android.content.ComponentName;
import android.content.Context;
+import android.net.Uri;
import android.os.Bundle;
import android.os.RemoteException;
import android.os.ServiceManager;
@@ -31,7 +32,17 @@
import java.util.List;
/**
- * Provides access to Telecom-related functionality.
+ * Provides access to information about active calls and registration/call-management functionality.
+ * Apps can use methods in this class to determine the current call state. Apps can also register new
+ * {@link PhoneAccount}s and get a listing of existing {@link PhoneAccount}s.
+ * <p>
+ * Apps do not instantiate this class directly; instead, they retrieve a reference to an instance
+ * through {@link Context#getSystemService Context.getSystemService(Context.TELECOM_SERVICE)}.
+ * <p>
+ * Note that access to some telecom information is permission-protected. Your app cannot access the
+ * protected information or gain access to protected functionality unless it has the appropriate
+ * permissions declared in its manifest file. Where permissions apply, they are noted in the method
+ * descriptions.
*/
public class TelecomManager {
@@ -583,7 +594,16 @@
}
/**
- * Register a {@link PhoneAccount} for use by the system.
+ * Register a {@link PhoneAccount} for use by the system. When registering
+ * {@link PhoneAccount}s, existing registrations will be overwritten if the
+ * {@link PhoneAccountHandle} matches that of a {@link PhoneAccount} which is already
+ * registered. Once registered, the {@link PhoneAccount} is listed to the user as an option
+ * when placing calls. The user may still need to enable the {@link PhoneAccount} within
+ * the phone app settings before the account is usable.
+ * <p>
+ * A {@link SecurityException} will be thrown if an app tries to register a
+ * {@link PhoneAccountHandle} where the package name specified within
+ * {@link PhoneAccountHandle#getComponentName()} does not match the package name of the app.
*
* @param account The complete {@link PhoneAccount}.
*/
@@ -876,6 +896,7 @@
* Processes the specified dial string as an MMI code.
* MMI codes are any sequence of characters entered into the dialpad that contain a "*" or "#".
* Some of these sequences launch special behavior through handled by Telephony.
+ * This method uses the default subscription.
* <p>
* Requires that the method-caller be set as the system dialer app.
* </p>
@@ -896,6 +917,48 @@
}
/**
+ * Processes the specified dial string as an MMI code.
+ * MMI codes are any sequence of characters entered into the dialpad that contain a "*" or "#".
+ * Some of these sequences launch special behavior through handled by Telephony.
+ * <p>
+ * Requires that the method-caller be set as the system dialer app.
+ * </p>
+ *
+ * @param accountHandle The handle for the account the MMI code should apply to.
+ * @param dialString The digits to dial.
+ * @return True if the digits were processed as an MMI code, false otherwise.
+ */
+ public boolean handleMmi(PhoneAccountHandle accountHandle, String dialString) {
+ ITelecomService service = getTelecomService();
+ if (service != null) {
+ try {
+ return service.handlePinMmiForPhoneAccount(accountHandle, dialString);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Error calling ITelecomService#handlePinMmi", e);
+ }
+ }
+ return false;
+ }
+
+ /**
+ * @param accountHandle The handle for the account to derive an adn query URI for or
+ * {@code null} to return a URI which will use the default account.
+ * @return The URI (with the content:// scheme) specific to the specified {@link PhoneAccount}
+ * for the the content retrieve.
+ */
+ public Uri getAdnUriForPhoneAccount(PhoneAccountHandle accountHandle) {
+ ITelecomService service = getTelecomService();
+ if (service != null && accountHandle != null) {
+ try {
+ return service.getAdnUriForPhoneAccount(accountHandle);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Error calling ITelecomService#getAdnUriForPhoneAccount", e);
+ }
+ }
+ return Uri.parse("content://icc/adn");
+ }
+
+ /**
* Removes the missed-call notification if one is present.
* <p>
* Requires that the method-caller be set as the system dialer app.
diff --git a/telecomm/java/com/android/internal/telecom/IConnectionServiceAdapter.aidl b/telecomm/java/com/android/internal/telecom/IConnectionServiceAdapter.aidl
index 5daa568..0d6b3d9 100644
--- a/telecomm/java/com/android/internal/telecom/IConnectionServiceAdapter.aidl
+++ b/telecomm/java/com/android/internal/telecom/IConnectionServiceAdapter.aidl
@@ -77,4 +77,6 @@
void setCallerDisplayName(String callId, String callerDisplayName, int presentation);
void setConferenceableConnections(String callId, in List<String> conferenceableCallIds);
+
+ void addExistingConnection(String callId, in ParcelableConnection connection);
}
diff --git a/telecomm/java/com/android/internal/telecom/ITelecomService.aidl b/telecomm/java/com/android/internal/telecom/ITelecomService.aidl
index 91f44b9..cbd9d69 100644
--- a/telecomm/java/com/android/internal/telecom/ITelecomService.aidl
+++ b/telecomm/java/com/android/internal/telecom/ITelecomService.aidl
@@ -18,6 +18,7 @@
import android.content.ComponentName;
import android.telecom.PhoneAccountHandle;
+import android.net.Uri;
import android.os.Bundle;
import android.telecom.PhoneAccount;
@@ -169,6 +170,16 @@
boolean handlePinMmi(String dialString);
/**
+ * @see TelecomServiceImpl#handleMmi
+ */
+ boolean handlePinMmiForPhoneAccount(in PhoneAccountHandle accountHandle, String dialString);
+
+ /**
+ * @see TelecomServiceImpl#getAdnUriForPhoneAccount
+ */
+ Uri getAdnUriForPhoneAccount(in PhoneAccountHandle accountHandle);
+
+ /**
* @see TelecomServiceImpl#isTtySupported
*/
boolean isTtySupported();
diff --git a/telephony/java/android/telephony/SignalStrength.java b/telephony/java/android/telephony/SignalStrength.java
index 3363ca6..17db3fb 100644
--- a/telephony/java/android/telephony/SignalStrength.java
+++ b/telephony/java/android/telephony/SignalStrength.java
@@ -20,6 +20,7 @@
import android.os.Parcel;
import android.os.Parcelable;
import android.telephony.Rlog;
+import android.content.res.Resources;
/**
* Contains phone signal strength related information.
@@ -50,6 +51,11 @@
//Use int max, as -1 is a valid value in signal strength
public static final int INVALID = 0x7FFFFFFF;
+ private static final int RSRP_THRESH_TYPE_STRICT = 0;
+ private static final int[] RSRP_THRESH_STRICT = new int[] {-140, -115, -105, -95, -85, -44};
+ private static final int[] RSRP_THRESH_LENIENT = new int[] {-140, -128, -118, -108, -98, -44};
+
+
private int mGsmSignalStrength; // Valid values are (0-31, 99) as defined in TS 27.007 8.5
private int mGsmBitErrorRate; // bit error rate (0-7, 99) as defined in TS 27.007 8.5
private int mCdmaDbm; // This value is the RSSI value
@@ -745,12 +751,21 @@
*/
int rssiIconLevel = SIGNAL_STRENGTH_NONE_OR_UNKNOWN, rsrpIconLevel = -1, snrIconLevel = -1;
- if (mLteRsrp > -44) rsrpIconLevel = -1;
- else if (mLteRsrp >= -85) rsrpIconLevel = SIGNAL_STRENGTH_GREAT;
- else if (mLteRsrp >= -95) rsrpIconLevel = SIGNAL_STRENGTH_GOOD;
- else if (mLteRsrp >= -105) rsrpIconLevel = SIGNAL_STRENGTH_MODERATE;
- else if (mLteRsrp >= -115) rsrpIconLevel = SIGNAL_STRENGTH_POOR;
- else if (mLteRsrp >= -140) rsrpIconLevel = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
+ int rsrpThreshType = Resources.getSystem().getInteger(com.android.internal.R.integer.
+ config_LTE_RSRP_threshold_type);
+ int[] threshRsrp;
+ if (rsrpThreshType == RSRP_THRESH_TYPE_STRICT) {
+ threshRsrp = RSRP_THRESH_STRICT;
+ } else {
+ threshRsrp = RSRP_THRESH_LENIENT;
+ }
+
+ if (mLteRsrp > threshRsrp[5]) rsrpIconLevel = -1;
+ else if (mLteRsrp >= threshRsrp[4]) rsrpIconLevel = SIGNAL_STRENGTH_GREAT;
+ else if (mLteRsrp >= threshRsrp[3]) rsrpIconLevel = SIGNAL_STRENGTH_GOOD;
+ else if (mLteRsrp >= threshRsrp[2]) rsrpIconLevel = SIGNAL_STRENGTH_MODERATE;
+ else if (mLteRsrp >= threshRsrp[1]) rsrpIconLevel = SIGNAL_STRENGTH_POOR;
+ else if (mLteRsrp >= threshRsrp[0]) rsrpIconLevel = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
/*
* Values are -200 dB to +300 (SNR*10dB) RS_SNR >= 13.0 dB =>4 bars 4.5
@@ -789,6 +804,7 @@
else if (mLteSignalStrength >= 8) rssiIconLevel = SIGNAL_STRENGTH_GOOD;
else if (mLteSignalStrength >= 5) rssiIconLevel = SIGNAL_STRENGTH_MODERATE;
else if (mLteSignalStrength >= 0) rssiIconLevel = SIGNAL_STRENGTH_POOR;
+
if (DBG) log("getLTELevel - rssi:" + mLteSignalStrength + " rssiIconLevel:"
+ rssiIconLevel);
return rssiIconLevel;
diff --git a/telephony/java/android/telephony/SubInfoRecord.java b/telephony/java/android/telephony/SubInfoRecord.java
index 4a3d67e..e08f255 100644
--- a/telephony/java/android/telephony/SubInfoRecord.java
+++ b/telephony/java/android/telephony/SubInfoRecord.java
@@ -29,98 +29,138 @@
* Subscription Identifier, this is a device unique number
* and not an index into an array
*/
- public int subId;
- /** The GID for a SIM that maybe associated with this subscription, empty if unknown */
- public String iccId;
+ private int mId;
+
/**
- * The slot identifier for that currently contains the subscription
+ * The GID for a SIM that maybe associated with this subscription, empty if unknown
+ */
+ private String mIccId;
+
+ /**
+ * The index of the slot that currently contains the subscription
* and not necessarily unique and maybe INVALID_SLOT_ID if unknown
*/
- public int slotId;
+ private int mSimSlotIndex;
+
/**
- * The string displayed to the user that identifies this subscription
+ * The name displayed to the user that identifies this subscription
*/
- public String displayName;
+ private CharSequence mDisplayName;
+
/**
* The source of the name, NAME_SOURCE_UNDEFINED, NAME_SOURCE_DEFAULT_SOURCE,
* NAME_SOURCE_SIM_SOURCE or NAME_SOURCE_USER_INPUT.
*/
- public int nameSource;
+ private int mNameSource;
+
/**
* The color to be used for when displaying to the user
*/
- public int color;
+ private int mColor;
+
/**
* A number presented to the user identify this subscription
*/
- public String number;
- /**
- * How to display the phone number, DISPLAY_NUMBER_NONE, DISPLAY_NUMBER_FIRST,
- * DISPLAY_NUMBER_LAST
- */
- public int displayNumberFormat;
+ private String mNumber;
+
/**
* Data roaming state, DATA_RAOMING_ENABLE, DATA_RAOMING_DISABLE
*/
- public int dataRoaming;
+ private int mDataRoaming;
+
/**
* SIM Icon resource identifiers. FIXME: Check with MTK what it really is
*/
- public int[] simIconRes;
+ private int[] mSimIconRes;
+
/**
* Mobile Country Code
*/
- public int mcc;
+ private int mMcc;
+
/**
* Mobile Network Code
*/
- public int mnc;
+ private int mMnc;
+ /**
+ * @hide
public SubInfoRecord() {
- this.subId = SubscriptionManager.INVALID_SUB_ID;
- this.iccId = "";
- this.slotId = SubscriptionManager.INVALID_SLOT_ID;
- this.displayName = "";
- this.nameSource = 0;
- this.color = 0;
- this.number = "";
- this.displayNumberFormat = 0;
- this.dataRoaming = 0;
- this.simIconRes = new int[2];
- this.mcc = 0;
- this.mnc = 0;
+ this.mId = SubscriptionManager.INVALID_SUB_ID;
+ this.mIccId = "";
+ this.mSimSlotIndex = SubscriptionManager.INVALID_SLOT_ID;
+ this.mDisplayName = "";
+ this.mNameSource = 0;
+ this.mColor = 0;
+ this.mNumber = "";
+ this.mDataRoaming = 0;
+ this.mSimIconRes = new int[2];
+ this.mMcc = 0;
+ this.mMnc = 0;
}
+ */
- public SubInfoRecord(int subId, String iccId, int slotId, String displayName, int nameSource,
- int color, String number, int displayFormat, int roaming, int[] iconRes,
- int mcc, int mnc) {
- this.subId = subId;
- this.iccId = iccId;
- this.slotId = slotId;
- this.displayName = displayName;
- this.nameSource = nameSource;
- this.color = color;
- this.number = number;
- this.displayNumberFormat = displayFormat;
- this.dataRoaming = roaming;
- this.simIconRes = iconRes;
- this.mcc = mcc;
- this.mnc = mnc;
+ /**
+ * @hide
+ */
+ public SubInfoRecord(int id, String iccId, int simSlotIndex, CharSequence displayName,
+ int nameSource, int color, String number, int roaming, int[] iconRes, int mcc,
+ int mnc) {
+ this.mId = id;
+ this.mIccId = iccId;
+ this.mSimSlotIndex = simSlotIndex;
+ this.mDisplayName = displayName;
+ this.mNameSource = nameSource;
+ this.mColor = color;
+ this.mNumber = number;
+ this.mDataRoaming = roaming;
+ this.mSimIconRes = iconRes;
+ this.mMcc = mcc;
+ this.mMnc = mnc;
}
/**
- * Returns the string displayed to the user that identifies this subscription
+ * Returns the subscription ID.
*/
- public String getLabel() {
- return this.displayName;
+ public int getSubscriptionId() {
+ return this.mId;
}
/**
- * Return the icon used to identify this SIM.
- * TODO: return the correct drawable.
+ * Returns the ICC ID.
*/
- public BitmapDrawable getIconDrawable() {
- return new BitmapDrawable();
+ public String getIccId() {
+ return this.mIccId;
+ }
+
+ /**
+ * Returns the slot index of this Subscription's SIM card.
+ */
+ public int getSimSlotIndex() {
+ return this.mSimSlotIndex;
+ }
+
+ /**
+ * Returns the name displayed to the user that identifies this subscription
+ */
+ public CharSequence getDisplayName() {
+ return this.mDisplayName;
+ }
+
+ /**
+ * Sets the name displayed to the user that identifies this subscription
+ * @hide
+ */
+ public void setDisplayName(CharSequence name) {
+ this.mDisplayName = name;
+ }
+
+ /**
+ * Return the source of the name, eg NAME_SOURCE_UNDEFINED, NAME_SOURCE_DEFAULT_SOURCE,
+ * NAME_SOURCE_SIM_SOURCE or NAME_SOURCE_USER_INPUT.
+ */
+ public int getNameSource() {
+ return this.mNameSource;
}
/**
@@ -130,28 +170,70 @@
public int getColor() {
// Note: This color is currently an index into a list of drawables, but this is soon to
// change.
- return this.color;
+ return this.mColor;
+ }
+
+ /**
+ * Sets the color displayed to the user that identifies this subscription
+ * @hide
+ */
+ public void setColor(int color) {
+ this.mColor = color;
+ }
+
+ /**
+ * Returns the number of this subscription.
+ */
+ public String getNumber() {
+ return mNumber;
+ }
+
+ /**
+ * Return the data roaming value.
+ */
+ public int getDataRoaming() {
+ return this.mDataRoaming;
+ }
+
+ /**
+ * Return the icon used to identify this subscription.
+ */
+ public BitmapDrawable getIcon() {
+ return new BitmapDrawable();
+ }
+
+ /**
+ * Returns the MCC.
+ */
+ public int getMcc() {
+ return this.mMcc;
+ }
+
+ /**
+ * Returns the MNC.
+ */
+ public int getMnc() {
+ return this.mMnc;
}
public static final Parcelable.Creator<SubInfoRecord> CREATOR = new Parcelable.Creator<SubInfoRecord>() {
@Override
public SubInfoRecord createFromParcel(Parcel source) {
- int subId = source.readInt();
+ int id = source.readInt();
String iccId = source.readString();
- int slotId = source.readInt();
- String displayName = source.readString();
+ int simSlotIndex = source.readInt();
+ CharSequence displayName = source.readCharSequence();
int nameSource = source.readInt();
int color = source.readInt();
String number = source.readString();
- int displayNumberFormat = source.readInt();
int dataRoaming = source.readInt();
int[] iconRes = new int[2];
source.readIntArray(iconRes);
int mcc = source.readInt();
int mnc = source.readInt();
- return new SubInfoRecord(subId, iccId, slotId, displayName, nameSource, color, number,
- displayNumberFormat, dataRoaming, iconRes, mcc, mnc);
+ return new SubInfoRecord(id, iccId, simSlotIndex, displayName, nameSource, color, number,
+ dataRoaming, iconRes, mcc, mnc);
}
@Override
@@ -162,18 +244,17 @@
@Override
public void writeToParcel(Parcel dest, int flags) {
- dest.writeInt(subId);
- dest.writeString(iccId);
- dest.writeInt(slotId);
- dest.writeString(displayName);
- dest.writeInt(nameSource);
- dest.writeInt(color);
- dest.writeString(number);
- dest.writeInt(displayNumberFormat);
- dest.writeInt(dataRoaming);
- dest.writeIntArray(simIconRes);
- dest.writeInt(mcc);
- dest.writeInt(mnc);
+ dest.writeInt(mId);
+ dest.writeString(mIccId);
+ dest.writeInt(mSimSlotIndex);
+ dest.writeCharSequence(mDisplayName);
+ dest.writeInt(mNameSource);
+ dest.writeInt(mColor);
+ dest.writeString(mNumber.toString());
+ dest.writeInt(mDataRoaming);
+ dest.writeIntArray(mSimIconRes);
+ dest.writeInt(mMcc);
+ dest.writeInt(mMnc);
}
@Override
@@ -183,10 +264,9 @@
@Override
public String toString() {
- return "{mSubId=" + subId + ", mIccId=" + iccId + " mSlotId=" + slotId
- + " mDisplayName=" + displayName + " mNameSource=" + nameSource
- + " mColor=" + color + " mNumber=" + number
- + " mDisplayNumberFormat=" + displayNumberFormat + " mDataRoaming=" + dataRoaming
- + " mSimIconRes=" + simIconRes + " mMcc " + mcc + " mMnc " + mnc + "}";
+ return "{id=" + mId + ", iccId=" + mIccId + " simSlotIndex=" + mSimSlotIndex
+ + " displayName=" + mDisplayName + " nameSource=" + mNameSource + " color=" + mColor
+ + " number=" + mNumber + " dataRoaming=" + mDataRoaming + " simIconRes=" + mSimIconRes
+ + " mcc " + mMcc + " mnc " + mMnc + "}";
}
}
diff --git a/telephony/java/android/telephony/SubscriptionManager.java b/telephony/java/android/telephony/SubscriptionManager.java
index edfddc7..9cd533d 100644
--- a/telephony/java/android/telephony/SubscriptionManager.java
+++ b/telephony/java/android/telephony/SubscriptionManager.java
@@ -209,7 +209,7 @@
public static final int DISPLAY_NUMBER_LAST = 2;
/** @hide */
- public static final int DISLPAY_NUMBER_DEFAULT = DISPLAY_NUMBER_FIRST;
+ public static final int DISPLAY_NUMBER_DEFAULT = DISPLAY_NUMBER_FIRST;
/**
* TelephonyProvider column name for permission for data roaming of a SIM.
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index a3546ed..0246a2d 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -3336,6 +3336,17 @@
/** @hide */
@SystemApi
+ public boolean handlePinMmiForSubscriber(int subId, String dialString) {
+ try {
+ return getITelephony().handlePinMmiForSubscriber(subId, dialString);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Error calling ITelephony#handlePinMmi", e);
+ }
+ return false;
+ }
+
+ /** @hide */
+ @SystemApi
public void toggleRadioOnOff() {
try {
getITelephony().toggleRadioOnOff();
diff --git a/tests/ActivityTests/src/com/google/android/test/activity/ActivityTestMain.java b/tests/ActivityTests/src/com/google/android/test/activity/ActivityTestMain.java
index 6837d22..94874c8 100644
--- a/tests/ActivityTests/src/com/google/android/test/activity/ActivityTestMain.java
+++ b/tests/ActivityTests/src/com/google/android/test/activity/ActivityTestMain.java
@@ -127,7 +127,7 @@
@Override
public boolean onLongClick(View v) {
if (task.id >= 0 && thumbs != null) {
- mAm.removeTask(task.id, ActivityManager.REMOVE_TASK_KILL_PROCESS);
+ mAm.removeTask(task.id);
buildUi();
return true;
}
diff --git a/tools/aapt/AaptConfig.cpp b/tools/aapt/AaptConfig.cpp
index f447462..848d9a1 100644
--- a/tools/aapt/AaptConfig.cpp
+++ b/tools/aapt/AaptConfig.cpp
@@ -794,4 +794,23 @@
return a.diff(b) == axisMask;
}
+bool isDensityOnly(const ResTable_config& config) {
+ if (config.density == ResTable_config::DENSITY_NONE) {
+ return false;
+ }
+
+ if (config.density == ResTable_config::DENSITY_ANY) {
+ if (config.sdkVersion != SDK_L) {
+ // Someone modified the sdkVersion from the default, this is not safe to assume.
+ return false;
+ }
+ } else if (config.sdkVersion != SDK_DONUT) {
+ return false;
+ }
+
+ const uint32_t mask = ResTable_config::CONFIG_DENSITY | ResTable_config::CONFIG_VERSION;
+ const ConfigDescription nullConfig;
+ return (nullConfig.diff(config) & ~mask) == 0;
+}
+
} // namespace AaptConfig
diff --git a/tools/aapt/AaptConfig.h b/tools/aapt/AaptConfig.h
index 2963539..f73a5081 100644
--- a/tools/aapt/AaptConfig.h
+++ b/tools/aapt/AaptConfig.h
@@ -80,6 +80,12 @@
*/
bool isSameExcept(const android::ResTable_config& a, const android::ResTable_config& b, int configMask);
+/**
+ * Returns true if the configuration only has the density specified. In the case
+ * of 'anydpi', the version is ignored.
+ */
+bool isDensityOnly(const android::ResTable_config& config);
+
} // namespace AaptConfig
#endif // __AAPT_CONFIG_H
diff --git a/tools/aapt/AaptUtil.h b/tools/aapt/AaptUtil.h
index 47a704a..89e1ee8 100644
--- a/tools/aapt/AaptUtil.h
+++ b/tools/aapt/AaptUtil.h
@@ -14,9 +14,11 @@
* limitations under the License.
*/
-#ifndef __AAPT_UTIL_H
-#define __AAPT_UTIL_H
+#ifndef H_AAPT_UTIL
+#define H_AAPT_UTIL
+#include <utils/KeyedVector.h>
+#include <utils/SortedVector.h>
#include <utils/String8.h>
#include <utils/Vector.h>
@@ -25,6 +27,38 @@
android::Vector<android::String8> split(const android::String8& str, const char sep);
android::Vector<android::String8> splitAndLowerCase(const android::String8& str, const char sep);
+template <typename KEY, typename VALUE>
+void appendValue(android::KeyedVector<KEY, android::Vector<VALUE> >& keyedVector,
+ const KEY& key, const VALUE& value);
+
+template <typename KEY, typename VALUE>
+void appendValue(android::KeyedVector<KEY, android::SortedVector<VALUE> >& keyedVector,
+ const KEY& key, const VALUE& value);
+
+//
+// Implementations
+//
+
+template <typename KEY, typename VALUE>
+void appendValue(android::KeyedVector<KEY, android::Vector<VALUE> >& keyedVector,
+ const KEY& key, const VALUE& value) {
+ ssize_t idx = keyedVector.indexOfKey(key);
+ if (idx < 0) {
+ idx = keyedVector.add(key, android::Vector<VALUE>());
+ }
+ keyedVector.editValueAt(idx).add(value);
+}
+
+template <typename KEY, typename VALUE>
+void appendValue(android::KeyedVector<KEY, android::SortedVector<VALUE> >& keyedVector,
+ const KEY& key, const VALUE& value) {
+ ssize_t idx = keyedVector.indexOfKey(key);
+ if (idx < 0) {
+ idx = keyedVector.add(key, android::SortedVector<VALUE>());
+ }
+ keyedVector.editValueAt(idx).add(value);
+}
+
} // namespace AaptUtil
-#endif // __AAPT_UTIL_H
+#endif // H_AAPT_UTIL
diff --git a/tools/aapt/AaptXml.cpp b/tools/aapt/AaptXml.cpp
index 708e405..b04a55d 100644
--- a/tools/aapt/AaptXml.cpp
+++ b/tools/aapt/AaptXml.cpp
@@ -41,7 +41,7 @@
}
size_t len;
- const uint16_t* str = tree.getAttributeStringValue(attrIndex, &len);
+ const char16_t* str = tree.getAttributeStringValue(attrIndex, &len);
return str ? String8(str, len) : String8();
}
@@ -103,7 +103,7 @@
if (tree.getAttributeValue(idx, &value) != NO_ERROR) {
if (value.dataType == Res_value::TYPE_STRING) {
size_t len;
- const uint16_t* str = tree.getAttributeStringValue(idx, &len);
+ const char16_t* str = tree.getAttributeStringValue(idx, &len);
return str ? String8(str, len) : String8();
}
resTable.resolveReference(&value, 0);
diff --git a/tools/aapt/Android.mk b/tools/aapt/Android.mk
index 2cbabe1..bc9c1f7 100644
--- a/tools/aapt/Android.mk
+++ b/tools/aapt/Android.mk
@@ -33,20 +33,20 @@
Command.cpp \
CrunchCache.cpp \
FileFinder.cpp \
+ Images.cpp \
Package.cpp \
- StringPool.cpp \
- XMLNode.cpp \
+ pseudolocalize.cpp \
+ qsort_r_compat.c \
+ Resource.cpp \
ResourceFilter.cpp \
ResourceIdCache.cpp \
ResourceTable.cpp \
- Images.cpp \
- Resource.cpp \
- pseudolocalize.cpp \
SourcePos.cpp \
+ StringPool.cpp \
WorkQueue.cpp \
+ XMLNode.cpp \
ZipEntry.cpp \
- ZipFile.cpp \
- qsort_r_compat.c
+ ZipFile.cpp
aaptTests := \
tests/AaptConfig_test.cpp \
@@ -88,16 +88,13 @@
include $(CLEAR_VARS)
LOCAL_MODULE := libaapt
-
-LOCAL_SRC_FILES := $(aaptSources)
-LOCAL_C_INCLUDES += $(aaptCIncludes)
-
-LOCAL_CFLAGS += -Wno-format-y2k
-LOCAL_CFLAGS += -DSTATIC_ANDROIDFW_FOR_TOOLS
-LOCAL_CFLAGS += $(aaptCFlags)
+LOCAL_CFLAGS += -Wno-format-y2k -DSTATIC_ANDROIDFW_FOR_TOOLS $(aaptCFlags)
+LOCAL_CPPFLAGS += $(aaptCppFlags)
ifeq (darwin,$(HOST_OS))
LOCAL_CFLAGS += -D_DARWIN_UNLIMITED_STREAMS
endif
+LOCAL_C_INCLUDES += $(aaptCIncludes)
+LOCAL_SRC_FILES := $(aaptSources)
include $(BUILD_HOST_STATIC_LIBRARY)
@@ -108,15 +105,11 @@
include $(CLEAR_VARS)
LOCAL_MODULE := aapt
-
-LOCAL_SRC_FILES := $(aaptMain)
-
-LOCAL_STATIC_LIBRARIES += \
- libaapt \
- $(aaptHostStaticLibs)
-
-LOCAL_LDLIBS += $(aaptHostLdLibs)
LOCAL_CFLAGS += $(aaptCFlags)
+LOCAL_CPPFLAGS += $(aaptCppFlags)
+LOCAL_LDLIBS += $(aaptHostLdLibs)
+LOCAL_SRC_FILES := $(aaptMain)
+LOCAL_STATIC_LIBRARIES += libaapt $(aaptHostStaticLibs)
include $(BUILD_HOST_EXECUTABLE)
@@ -127,16 +120,12 @@
include $(CLEAR_VARS)
LOCAL_MODULE := libaapt_tests
-
+LOCAL_CFLAGS += $(aaptCFlags)
+LOCAL_CPPFLAGS += $(aaptCppFlags)
+LOCAL_LDLIBS += $(aaptHostLdLibs)
LOCAL_SRC_FILES += $(aaptTests)
LOCAL_C_INCLUDES += $(LOCAL_PATH)
-
-LOCAL_STATIC_LIBRARIES += \
- libaapt \
- $(aaptHostStaticLibs)
-
-LOCAL_LDLIBS += $(aaptHostLdLibs)
-LOCAL_CFLAGS += $(aaptCFlags)
+LOCAL_STATIC_LIBRARIES += libaapt $(aaptHostStaticLibs)
include $(BUILD_HOST_NATIVE_TEST)
@@ -148,13 +137,12 @@
include $(CLEAR_VARS)
LOCAL_MODULE := aapt
-
+LOCAL_CFLAGS += $(aaptCFlags)
LOCAL_SRC_FILES := $(aaptSources) $(aaptMain)
LOCAL_C_INCLUDES += \
$(aaptCIncludes) \
bionic \
external/stlport/stlport
-
LOCAL_SHARED_LIBRARIES := \
libandroidfw \
libutils \
@@ -162,14 +150,10 @@
libpng \
liblog \
libz
-
LOCAL_STATIC_LIBRARIES := \
libstlport_static \
libexpat_static
-LOCAL_CFLAGS += $(aaptCFlags)
-LOCAL_CPPFLAGS += -Wno-non-virtual-dtor
-
include $(BUILD_EXECUTABLE)
endif # Not SDK_ONLY
diff --git a/tools/aapt/CacheUpdater.h b/tools/aapt/CacheUpdater.h
index efb2453..fade53a 100644
--- a/tools/aapt/CacheUpdater.h
+++ b/tools/aapt/CacheUpdater.h
@@ -30,6 +30,8 @@
*/
class CacheUpdater {
public:
+ virtual ~CacheUpdater() {}
+
// Make sure all the directories along this path exist
virtual void ensureDirectoriesExist(String8 path) = 0;
@@ -107,4 +109,4 @@
Bundle* bundle;
};
-#endif // CACHE_UPDATER_H
\ No newline at end of file
+#endif // CACHE_UPDATER_H
diff --git a/tools/aapt/Main.cpp b/tools/aapt/Main.cpp
index 2857b59..18b8e1e 100644
--- a/tools/aapt/Main.cpp
+++ b/tools/aapt/Main.cpp
@@ -11,9 +11,9 @@
#include <utils/List.h>
#include <utils/Errors.h>
-#include <stdlib.h>
+#include <cstdlib>
#include <getopt.h>
-#include <assert.h>
+#include <cassert>
using namespace android;
diff --git a/tools/aapt/Resource.cpp b/tools/aapt/Resource.cpp
index a4c9dab..0d8db13 100644
--- a/tools/aapt/Resource.cpp
+++ b/tools/aapt/Resource.cpp
@@ -4,6 +4,7 @@
// Build resource files from raw assets.
//
#include "AaptAssets.h"
+#include "AaptUtil.h"
#include "AaptXml.h"
#include "CacheUpdater.h"
#include "CrunchCache.h"
@@ -13,9 +14,12 @@
#include "Main.h"
#include "ResourceTable.h"
#include "StringPool.h"
+#include "Symbol.h"
#include "WorkQueue.h"
#include "XMLNode.h"
+#include <algorithm>
+
#if HAVE_PRINTF_ZD
# define ZD "%zd"
# define ZD_TYPE ssize_t
@@ -261,7 +265,7 @@
ssize_t minSdkIndex = block.indexOfAttribute(RESOURCES_ANDROID_NAMESPACE,
"minSdkVersion");
if (minSdkIndex >= 0) {
- const uint16_t* minSdk16 = block.getAttributeStringValue(minSdkIndex, &len);
+ const char16_t* minSdk16 = block.getAttributeStringValue(minSdkIndex, &len);
const char* minSdk8 = strdup(String8(minSdk16).string());
bundle->setManifestMinSdkVersion(minSdk8);
}
@@ -450,7 +454,7 @@
size_t len;
ssize_t index = parser.indexOfAttribute(ns, attr);
- const uint16_t* str;
+ const char16_t* str;
Res_value value;
if (index >= 0 && parser.getAttributeValue(index, &value) >= 0) {
const ResStringPool* pool = &parser.getStrings();
@@ -503,7 +507,7 @@
}
if (validChars) {
for (size_t i=0; i<len; i++) {
- uint16_t c = str[i];
+ char16_t c = str[i];
const char* p = validChars;
bool okay = false;
while (*p) {
@@ -1550,6 +1554,7 @@
// Re-flatten because we may have added new resource IDs
// --------------------------------------------------------------
+
ResTable finalResTable;
sp<AaptFile> resFile;
@@ -1560,6 +1565,13 @@
return err;
}
+ KeyedVector<Symbol, Vector<SymbolDefinition> > densityVaryingResources;
+ if (builder->getSplits().size() > 1) {
+ // Only look for density varying resources if we're generating
+ // splits.
+ table.getDensityVaryingResources(densityVaryingResources);
+ }
+
Vector<sp<ApkSplit> >& splits = builder->getSplits();
const size_t numSplits = splits.size();
for (size_t i = 0; i < numSplits; i++) {
@@ -1583,6 +1595,63 @@
return err;
}
} else {
+ ResTable resTable;
+ err = resTable.add(flattenedTable->getData(), flattenedTable->getSize());
+ if (err != NO_ERROR) {
+ fprintf(stderr, "Generated resource table for split '%s' is corrupt.\n",
+ split->getPrintableName().string());
+ return err;
+ }
+
+ bool hasError = false;
+ const std::set<ConfigDescription>& splitConfigs = split->getConfigs();
+ for (std::set<ConfigDescription>::const_iterator iter = splitConfigs.begin();
+ iter != splitConfigs.end();
+ ++iter) {
+ const ConfigDescription& config = *iter;
+ if (AaptConfig::isDensityOnly(config)) {
+ // Each density only split must contain all
+ // density only resources.
+ Res_value val;
+ resTable.setParameters(&config);
+ const size_t densityVaryingResourceCount = densityVaryingResources.size();
+ for (size_t k = 0; k < densityVaryingResourceCount; k++) {
+ const Symbol& symbol = densityVaryingResources.keyAt(k);
+ ssize_t block = resTable.getResource(symbol.id, &val, true);
+ if (block < 0) {
+ // Maybe it's in the base?
+ finalResTable.setParameters(&config);
+ block = finalResTable.getResource(symbol.id, &val, true);
+ }
+
+ if (block < 0) {
+ hasError = true;
+ SourcePos().error("%s has no definition for density split '%s'",
+ symbol.toString().string(), config.toString().string());
+
+ if (bundle->getVerbose()) {
+ const Vector<SymbolDefinition>& defs = densityVaryingResources[k];
+ const size_t defCount = std::min(size_t(5), defs.size());
+ for (size_t d = 0; d < defCount; d++) {
+ const SymbolDefinition& def = defs[d];
+ def.source.error("%s has definition for %s",
+ symbol.toString().string(), def.config.toString().string());
+ }
+
+ if (defCount < defs.size()) {
+ SourcePos().error("and %d more ...", (int) (defs.size() - defCount));
+ }
+ }
+ }
+ }
+ }
+ }
+
+ if (hasError) {
+ return UNKNOWN_ERROR;
+ }
+
+ // Generate the AndroidManifest for this split.
sp<AaptFile> generatedManifest = new AaptFile(String8("AndroidManifest.xml"),
AaptGroupEntry(), String8());
err = generateAndroidManifestForSplit(bundle, assets, split,
@@ -1710,7 +1779,7 @@
}
size_t len;
ssize_t index = block.indexOfAttribute(RESOURCES_ANDROID_NAMESPACE, "name");
- const uint16_t* id = block.getAttributeStringValue(index, &len);
+ const char16_t* id = block.getAttributeStringValue(index, &len);
if (id == NULL) {
fprintf(stderr, "%s:%d: missing name attribute in element <%s>.\n",
manifestPath.string(), block.getLineNumber(),
@@ -1753,7 +1822,7 @@
hasErrors = true;
}
syms->addStringSymbol(String8(e), idStr, srcPos);
- const uint16_t* cmt = block.getComment(&len);
+ const char16_t* cmt = block.getComment(&len);
if (cmt != NULL && *cmt != 0) {
//printf("Comment of %s: %s\n", String8(e).string(),
// String8(cmt).string());
diff --git a/tools/aapt/ResourceTable.cpp b/tools/aapt/ResourceTable.cpp
index 4587a4b..beff604 100644
--- a/tools/aapt/ResourceTable.cpp
+++ b/tools/aapt/ResourceTable.cpp
@@ -6,6 +6,7 @@
#include "ResourceTable.h"
+#include "AaptUtil.h"
#include "XMLNode.h"
#include "ResourceFilter.h"
#include "ResourceIdCache.h"
@@ -399,7 +400,7 @@
ssize_t l10nIdx = block.indexOfAttribute(NULL, "localization");
if (l10nIdx >= 0) {
- const uint16_t* str = block.getAttributeStringValue(l10nIdx, &len);
+ const char16_t* str = block.getAttributeStringValue(l10nIdx, &len);
bool error;
uint32_t l10n_required = parse_flags(str, len, l10nRequiredFlags, &error);
if (error) {
@@ -1325,7 +1326,7 @@
size_t n = block.getAttributeCount();
for (size_t i = 0; i < n; i++) {
size_t length;
- const uint16_t* attr = block.getAttributeName(i, &length);
+ const char16_t* attr = block.getAttributeName(i, &length);
if (strcmp16(attr, name16.string()) == 0) {
name.setTo(block.getAttributeStringValue(i, &length));
} else if (strcmp16(attr, translatable16.string()) == 0) {
@@ -1441,14 +1442,14 @@
// translatable.
for (size_t i = 0; i < n; i++) {
size_t length;
- const uint16_t* attr = block.getAttributeName(i, &length);
+ const char16_t* attr = block.getAttributeName(i, &length);
if (strcmp16(attr, formatted16.string()) == 0) {
- const uint16_t* value = block.getAttributeStringValue(i, &length);
+ const char16_t* value = block.getAttributeStringValue(i, &length);
if (strcmp16(value, false16.string()) == 0) {
curIsFormatted = false;
}
} else if (strcmp16(attr, translatable16.string()) == 0) {
- const uint16_t* value = block.getAttributeStringValue(i, &length);
+ const char16_t* value = block.getAttributeStringValue(i, &length);
if (strcmp16(value, false16.string()) == 0) {
isTranslatable = false;
}
@@ -4486,3 +4487,34 @@
return NO_ERROR;
}
+
+void ResourceTable::getDensityVaryingResources(KeyedVector<Symbol, Vector<SymbolDefinition> >& resources) {
+ const ConfigDescription nullConfig;
+
+ const size_t packageCount = mOrderedPackages.size();
+ for (size_t p = 0; p < packageCount; p++) {
+ const Vector<sp<Type> >& types = mOrderedPackages[p]->getOrderedTypes();
+ const size_t typeCount = types.size();
+ for (size_t t = 0; t < typeCount; t++) {
+ 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 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(),
+ types[t]->getName(),
+ configs[c]->getName(),
+ getResId(mOrderedPackages[p], types[t], configs[c]->getEntryIndex()));
+
+ const sp<Entry>& entry = configEntries.valueAt(ce);
+ AaptUtil::appendValue(resources, symbol, SymbolDefinition(symbol, config, entry->getPos()));
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/tools/aapt/ResourceTable.h b/tools/aapt/ResourceTable.h
index eac5dd3..db392c89 100644
--- a/tools/aapt/ResourceTable.h
+++ b/tools/aapt/ResourceTable.h
@@ -7,15 +7,16 @@
#ifndef RESOURCE_TABLE_H
#define RESOURCE_TABLE_H
-#include "ConfigDescription.h"
-#include "StringPool.h"
-#include "SourcePos.h"
-#include "ResourceFilter.h"
-
#include <map>
#include <queue>
#include <set>
+#include "ConfigDescription.h"
+#include "ResourceFilter.h"
+#include "SourcePos.h"
+#include "StringPool.h"
+#include "Symbol.h"
+
using namespace std;
class XMLNode;
@@ -543,6 +544,8 @@
DefaultKeyedVector<String16, uint32_t> mKeyStringsMapping;
};
+ void getDensityVaryingResources(KeyedVector<Symbol, Vector<SymbolDefinition> >& resources);
+
private:
void writePublicDefinitions(const String16& package, FILE* fp, bool pub);
sp<Package> getPackage(const String16& package);
diff --git a/tools/aapt/SourcePos.cpp b/tools/aapt/SourcePos.cpp
index ae25047..3864320 100644
--- a/tools/aapt/SourcePos.cpp
+++ b/tools/aapt/SourcePos.cpp
@@ -141,6 +141,12 @@
}
bool
+SourcePos::operator<(const SourcePos& rhs) const
+{
+ return (file < rhs.file) || (line < rhs.line);
+}
+
+bool
SourcePos::hasErrors()
{
return g_errors.size() > 0;
diff --git a/tools/aapt/SourcePos.h b/tools/aapt/SourcePos.h
index 4ce817f..13cfb9d 100644
--- a/tools/aapt/SourcePos.h
+++ b/tools/aapt/SourcePos.h
@@ -21,6 +21,8 @@
void warning(const char* fmt, ...) const;
void printf(const char* fmt, ...) const;
+ bool operator<(const SourcePos& rhs) const;
+
static bool hasErrors();
static void printErrors(FILE* to);
};
diff --git a/tools/aapt/StringPool.cpp b/tools/aapt/StringPool.cpp
index 06769e4..2727b3d 100644
--- a/tools/aapt/StringPool.cpp
+++ b/tools/aapt/StringPool.cpp
@@ -21,7 +21,8 @@
#define NOISY(x) //x
-void strcpy16_htod(uint16_t* dst, const uint16_t* src)
+#if __cplusplus >= 201103L
+void strcpy16_htod(char16_t* dst, const char16_t* src)
{
while (*src) {
char16_t s = htods(*src);
@@ -30,6 +31,17 @@
}
*dst = 0;
}
+#endif
+
+void strcpy16_htod(uint16_t* dst, const char16_t* src)
+{
+ while (*src) {
+ uint16_t s = htods(static_cast<uint16_t>(*src));
+ *dst++ = s;
+ src++;
+ }
+ *dst = 0;
+}
void printStringPool(const ResStringPool* pool)
{
@@ -416,7 +428,7 @@
return NO_MEMORY;
}
- const size_t charSize = mUTF8 ? sizeof(uint8_t) : sizeof(char16_t);
+ const size_t charSize = mUTF8 ? sizeof(uint8_t) : sizeof(uint16_t);
size_t strPos = 0;
for (i=0; i<STRINGS; i++) {
diff --git a/tools/aapt/StringPool.h b/tools/aapt/StringPool.h
index 1b3abfd..a9c7bec 100644
--- a/tools/aapt/StringPool.h
+++ b/tools/aapt/StringPool.h
@@ -26,7 +26,10 @@
#define PRINT_STRING_METRICS 0
-void strcpy16_htod(uint16_t* dst, const uint16_t* src);
+#if __cplusplus >= 201103L
+void strcpy16_htod(char16_t* dst, const char16_t* src);
+#endif
+void strcpy16_htod(uint16_t* dst, const char16_t* src);
void printStringPool(const ResStringPool* pool);
diff --git a/tools/aapt/Symbol.h b/tools/aapt/Symbol.h
new file mode 100644
index 0000000..e157541
--- /dev/null
+++ b/tools/aapt/Symbol.h
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef AAPT_SYMBOL_H
+#define AAPT_SYMBOL_H
+
+#include <utils/String8.h>
+#include <utils/String16.h>
+
+#include "ConfigDescription.h"
+#include "SourcePos.h"
+
+/**
+ * A resource symbol, not attached to any configuration or context.
+ */
+struct Symbol {
+ inline Symbol();
+ inline Symbol(const android::String16& p, const android::String16& t, const android::String16& n, uint32_t i);
+ inline android::String8 toString() const;
+ inline bool operator<(const Symbol& rhs) const;
+
+ android::String16 package;
+ android::String16 type;
+ android::String16 name;
+ uint32_t id;
+
+};
+
+/**
+ * A specific defintion of a symbol, defined with a configuration and a definition site.
+ */
+struct SymbolDefinition {
+ inline SymbolDefinition();
+ inline SymbolDefinition(const Symbol& s, const ConfigDescription& c, const SourcePos& src);
+ inline bool operator<(const SymbolDefinition& rhs) const;
+
+ Symbol symbol;
+ ConfigDescription config;
+ SourcePos source;
+};
+
+//
+// Implementations
+//
+
+Symbol::Symbol() {
+}
+
+Symbol::Symbol(const android::String16& p, const android::String16& t, const android::String16& n, uint32_t i)
+ : package(p)
+ , type(t)
+ , name(n)
+ , id(i) {
+}
+
+android::String8 Symbol::toString() const {
+ return android::String8::format("%s:%s/%s (0x%08x)",
+ android::String8(package).string(),
+ android::String8(type).string(),
+ android::String8(name).string(),
+ (int) id);
+}
+
+bool Symbol::operator<(const Symbol& rhs) const {
+ return (package < rhs.package) || (type < rhs.type) || (name < rhs.name) || (id < rhs.id);
+}
+
+SymbolDefinition::SymbolDefinition() {
+}
+
+SymbolDefinition::SymbolDefinition(const Symbol& s, const ConfigDescription& c, const SourcePos& src)
+ : symbol(s)
+ , config(c)
+ , source(src) {
+}
+
+bool SymbolDefinition::operator<(const SymbolDefinition& rhs) const {
+ return (symbol < rhs.symbol) || (config < rhs.config) || (source < rhs.source);
+}
+
+#endif // AAPT_SYMBOL_H
+
diff --git a/tools/aapt/XMLNode.cpp b/tools/aapt/XMLNode.cpp
index 51a4154..899fb63 100644
--- a/tools/aapt/XMLNode.cpp
+++ b/tools/aapt/XMLNode.cpp
@@ -234,9 +234,9 @@
const String8 element8(element16);
size_t nslen;
- const uint16_t* ns = inXml->getElementNamespace(&nslen);
+ const char16_t* ns = inXml->getElementNamespace(&nslen);
if (ns == NULL) {
- ns = (const uint16_t*)"\0\0";
+ ns = (const char16_t*)"\0\0";
nslen = 0;
}
const String8 nspace(String16(ns, nslen));
@@ -291,9 +291,9 @@
} else if (code == ResXMLTree::END_TAG) {
size_t nslen;
- const uint16_t* ns = inXml->getElementNamespace(&nslen);
+ const char16_t* ns = inXml->getElementNamespace(&nslen);
if (ns == NULL) {
- ns = (const uint16_t*)"\0\0";
+ ns = (const char16_t*)"\0\0";
nslen = 0;
}
const String8 nspace(String16(ns, nslen));
@@ -422,7 +422,7 @@
}
static String8 build_namespace(const Vector<namespace_entry>& namespaces,
- const uint16_t* ns)
+ const char16_t* ns)
{
String8 str;
if (ns != NULL) {
@@ -453,9 +453,9 @@
int i;
if (code == ResXMLTree::START_TAG) {
size_t len;
- const uint16_t* ns16 = block->getElementNamespace(&len);
+ const char16_t* ns16 = block->getElementNamespace(&len);
String8 elemNs = build_namespace(namespaces, ns16);
- const uint16_t* com16 = block->getComment(&len);
+ const char16_t* com16 = block->getComment(&len);
if (com16) {
printf("%s <!-- %s -->\n", prefix.string(), String8(com16).string());
}
@@ -503,7 +503,7 @@
} else if (code == ResXMLTree::START_NAMESPACE) {
namespace_entry ns;
size_t len;
- const uint16_t* prefix16 = block->getNamespacePrefix(&len);
+ const char16_t* prefix16 = block->getNamespacePrefix(&len);
if (prefix16) {
ns.prefix = String8(prefix16);
} else {
@@ -518,7 +518,7 @@
depth--;
const namespace_entry& ns = namespaces.top();
size_t len;
- const uint16_t* prefix16 = block->getNamespacePrefix(&len);
+ const char16_t* prefix16 = block->getNamespacePrefix(&len);
String8 pr;
if (prefix16) {
pr = String8(prefix16);
diff --git a/tools/layoutlib/bridge/src/android/view/WindowCallback.java b/tools/layoutlib/bridge/src/android/view/WindowCallback.java
new file mode 100644
index 0000000..78242a8
--- /dev/null
+++ b/tools/layoutlib/bridge/src/android/view/WindowCallback.java
@@ -0,0 +1,131 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.view;
+
+import android.view.ActionMode.Callback;
+import android.view.WindowManager.LayoutParams;
+import android.view.accessibility.AccessibilityEvent;
+
+/**
+ * An empty implementation of {@link Window.Callback} that always returns null/false.
+ */
+public class WindowCallback implements Window.Callback {
+ @Override
+ public boolean dispatchKeyEvent(KeyEvent event) {
+ return false;
+ }
+
+ @Override
+ public boolean dispatchKeyShortcutEvent(KeyEvent event) {
+ return false;
+ }
+
+ @Override
+ public boolean dispatchTouchEvent(MotionEvent event) {
+ return false;
+ }
+
+ @Override
+ public boolean dispatchTrackballEvent(MotionEvent event) {
+ return false;
+ }
+
+ @Override
+ public boolean dispatchGenericMotionEvent(MotionEvent event) {
+ return false;
+ }
+
+ @Override
+ public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) {
+ return false;
+ }
+
+ @Override
+ public View onCreatePanelView(int featureId) {
+ return null;
+ }
+
+ @Override
+ public boolean onCreatePanelMenu(int featureId, Menu menu) {
+ return false;
+ }
+
+ @Override
+ public boolean onPreparePanel(int featureId, View view, Menu menu) {
+ return false;
+ }
+
+ @Override
+ public boolean onMenuOpened(int featureId, Menu menu) {
+ return false;
+ }
+
+ @Override
+ public boolean onMenuItemSelected(int featureId, MenuItem item) {
+ return false;
+ }
+
+ @Override
+ public void onWindowAttributesChanged(LayoutParams attrs) {
+
+ }
+
+ @Override
+ public void onContentChanged() {
+
+ }
+
+ @Override
+ public void onWindowFocusChanged(boolean hasFocus) {
+
+ }
+
+ @Override
+ public void onAttachedToWindow() {
+
+ }
+
+ @Override
+ public void onDetachedFromWindow() {
+
+ }
+
+ @Override
+ public void onPanelClosed(int featureId, Menu menu) {
+
+ }
+
+ @Override
+ public boolean onSearchRequested() {
+ return false;
+ }
+
+ @Override
+ public ActionMode onWindowStartingActionMode(Callback callback) {
+ return null;
+ }
+
+ @Override
+ public void onActionModeStarted(ActionMode mode) {
+
+ }
+
+ @Override
+ public void onActionModeFinished(ActionMode mode) {
+
+ }
+}
diff --git a/tools/layoutlib/bridge/src/android/widget/Toolbar_Accessor.java b/tools/layoutlib/bridge/src/android/widget/Toolbar_Accessor.java
new file mode 100644
index 0000000..fdd1779
--- /dev/null
+++ b/tools/layoutlib/bridge/src/android/widget/Toolbar_Accessor.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.widget;
+
+import android.content.Context;
+
+/**
+ * To access non public members of classes in {@link Toolbar}
+ */
+public class Toolbar_Accessor {
+ public static ActionMenuPresenter getActionMenuPresenter(Toolbar toolbar) {
+ return toolbar.getOuterActionMenuPresenter();
+ }
+
+ public static Context getPopupContext(Toolbar toolbar) {
+ return toolbar.getPopupContext();
+ }
+}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java
index 825731b..ec78712 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java
@@ -19,6 +19,7 @@
import static com.android.ide.common.rendering.api.Result.Status.ERROR_UNKNOWN;
import static com.android.ide.common.rendering.api.Result.Status.SUCCESS;
+import com.android.annotations.NonNull;
import com.android.ide.common.rendering.api.Capability;
import com.android.ide.common.rendering.api.DrawableParams;
import com.android.ide.common.rendering.api.LayoutLog;
@@ -459,7 +460,7 @@
public static void setLog(LayoutLog log) {
// check only the thread currently owning the lock can do this.
- if (sLock.isHeldByCurrentThread() == false) {
+ if (!sLock.isHeldByCurrentThread()) {
throw new IllegalStateException("scene must be acquired first. see #acquire(long)");
}
@@ -489,7 +490,6 @@
/**
* Returns the name of a framework resource whose value is an int array.
- * @param array
*/
public static String resolveResourceId(int[] array) {
sIntArrayWrapper.set(array);
@@ -502,6 +502,7 @@
* @param name the name of the resource.
* @return an {@link Integer} containing the resource id, or null if no resource were found.
*/
+ @NonNull
public static Integer getResourceId(ResourceType type, String name) {
Map<String, Integer> map = sRevRMap.get(type);
Integer value = null;
@@ -509,11 +510,8 @@
value = map.get(name);
}
- if (value == null) {
- value = sDynamicIds.getId(type, name);
- }
+ return value == null ? sDynamicIds.getId(type, name) : value;
- return value;
}
/**
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java
index d804230..3d3afa4 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java
@@ -52,7 +52,6 @@
import android.content.res.Configuration;
import android.content.res.Resources;
import android.content.res.Resources.Theme;
-import android.content.res.TypedArray;
import android.database.DatabaseErrorHandler;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteDatabase.CursorFactory;
@@ -127,7 +126,6 @@
* @param metrics the {@link DisplayMetrics}.
* @param renderResources the configured resources (both framework and projects) for this
* render.
- * @param projectCallback
* @param config the Configuration object for this render.
* @param targetSdkVersion the targetSdkVersion of the application.
*/
@@ -331,7 +329,7 @@
boolean attachToRoot, boolean skipCallbackParser) {
boolean isPlatformLayout = resource.isFramework();
- if (isPlatformLayout == false && skipCallbackParser == false) {
+ if (!isPlatformLayout && !skipCallbackParser) {
// check if the project callback can provide us with a custom parser.
ILayoutPullParser parser = getParser(resource);
@@ -663,7 +661,7 @@
}
String attrName = attribute.getFirst();
- boolean frameworkAttr = attribute.getSecond().booleanValue();
+ boolean frameworkAttr = attribute.getSecond();
String value = null;
if (set != null) {
value = set.getAttributeValue(
@@ -672,7 +670,7 @@
// if this is an app attribute, and the first get fails, try with the
// new res-auto namespace as well
- if (frameworkAttr == false && value == null) {
+ if (!frameworkAttr && value == null) {
value = set.getAttributeValue(BridgeConstants.NS_APP_RES_AUTO, attrName);
}
}
@@ -789,13 +787,13 @@
List<Pair<String, Boolean>> results = new ArrayList<Pair<String, Boolean>>(attrs.length);
// for each attribute, get its name so that we can search it in the style
- for (int i = 0 ; i < attrs.length ; i++) {
- Pair<ResourceType, String> resolvedResource = Bridge.resolveResourceId(attrs[i]);
+ for (int attr : attrs) {
+ Pair<ResourceType, String> resolvedResource = Bridge.resolveResourceId(attr);
boolean isFramework = false;
if (resolvedResource != null) {
isFramework = true;
} else {
- resolvedResource = mProjectCallback.resolveResourceId(attrs[i]);
+ resolvedResource = mProjectCallback.resolveResourceId(attr);
}
if (resolvedResource != null) {
@@ -841,7 +839,7 @@
if (id == null) {
// generate a new id
- id = Integer.valueOf(++mDynamicIdGenerator);
+ id = ++mDynamicIdGenerator;
// and add it to the maps.
mDynamicIdToStyleMap.put(id, resValue);
@@ -860,19 +858,24 @@
}
public int getFrameworkResourceValue(ResourceType resType, String resName, int defValue) {
- Integer value = Bridge.getResourceId(resType, resName);
- if (value != null) {
- return value.intValue();
+ if (getRenderResources().getFrameworkResource(resType, resName) != null) {
+ // Bridge.getResourceId creates a new resource id if an existing one isn't found. So,
+ // we check for the existence of the resource before calling it.
+ return Bridge.getResourceId(resType, resName);
}
return defValue;
}
public int getProjectResourceValue(ResourceType resType, String resName, int defValue) {
- if (mProjectCallback != null) {
- Integer value = mProjectCallback.getResourceId(resType, resName);
- if (value != null) {
- return value.intValue();
+ // getResourceId creates a new resource id if an existing resource id isn't found. So, we
+ // check for the existence of the resource before calling it.
+ if (getRenderResources().getProjectResource(resType, resName) != null) {
+ if (mProjectCallback != null) {
+ Integer value = mProjectCallback.getResourceId(resType, resName);
+ if (value != null) {
+ return value;
+ }
}
}
@@ -1455,9 +1458,6 @@
return null;
}
- /**
- * @hide
- */
@Override
public int getUserId() {
return 0; // not used
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 22265a3..05a6fd6 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
@@ -145,4 +145,9 @@
public void wakeUp(long time) throws RemoteException {
// pass for now.
}
+
+ @Override
+ public void boostScreenBrightness(long time) throws RemoteException {
+ // pass for now.
+ }
}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindow.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindow.java
index 997b199..4c4454d 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindow.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindow.java
@@ -95,6 +95,10 @@
}
@Override
+ public void dispatchWindowShown() {
+ }
+
+ @Override
public IBinder asBinder() {
// pass for now.
return null;
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/ActionBarLayout.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/ActionBarLayout.java
index d95c815..57fd68e 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/ActionBarLayout.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/ActionBarLayout.java
@@ -18,36 +18,24 @@
import com.android.annotations.NonNull;
import com.android.annotations.Nullable;
-import com.android.ide.common.rendering.api.ActionBarCallback;
-import com.android.ide.common.rendering.api.ActionBarCallback.HomeButtonStyle;
-import com.android.ide.common.rendering.api.RenderResources;
import com.android.ide.common.rendering.api.ResourceValue;
import com.android.ide.common.rendering.api.SessionParams;
import com.android.internal.R;
-import com.android.internal.app.WindowDecorActionBar;
import com.android.internal.view.menu.MenuBuilder;
import com.android.internal.view.menu.MenuItemImpl;
-import com.android.internal.widget.ActionBarAccessor;
-import com.android.internal.widget.ActionBarContainer;
-import com.android.internal.widget.ActionBarView;
import com.android.layoutlib.bridge.android.BridgeContext;
import com.android.layoutlib.bridge.impl.ResourceHelper;
-import com.android.resources.ResourceType;
-import android.app.ActionBar;
-import android.app.ActionBar.Tab;
-import android.app.ActionBar.TabListener;
-import android.app.FragmentTransaction;
import android.content.Context;
import android.content.res.TypedArray;
-import android.graphics.drawable.Drawable;
import android.util.DisplayMetrics;
import android.util.TypedValue;
-import android.view.Gravity;
import android.view.LayoutInflater;
-import android.view.MenuInflater;
import android.view.View;
+import android.view.View.MeasureSpec;
import android.view.ViewGroup;
+import android.view.ViewGroup.LayoutParams;
+import android.widget.ActionMenuPresenter;
import android.widget.FrameLayout;
import android.widget.LinearLayout;
import android.widget.ListAdapter;
@@ -56,172 +44,72 @@
import java.util.ArrayList;
-/**
- * A layout representing the action bar.
- */
-public class ActionBarLayout extends LinearLayout {
+public class ActionBarLayout {
+
+ private static final String LAYOUT_ATTR_NAME = "windowActionBarFullscreenDecorLayout";
+
+ // The Action Bar
+ @NonNull private CustomActionBarWrapper mActionBar;
// Store another reference to the context so that we don't have to cast it repeatedly.
@NonNull private final BridgeContext mBridgeContext;
- @NonNull private final Context mThemedContext;
- @NonNull private final ActionBar mActionBar;
-
- // Data for Action Bar.
- @Nullable private final String mIcon;
- @Nullable private final String mTitle;
- @Nullable private final String mSubTitle;
- private final boolean mSplit;
- private final boolean mShowHomeAsUp;
- private final int mNavMode;
-
- // Helper fields.
- @NonNull private final MenuBuilder mMenuBuilder;
- private final int mPopupMaxWidth;
- @NonNull private final RenderResources res;
- @Nullable private final ActionBarView mActionBarView;
- @Nullable private FrameLayout mContentRoot;
- @NonNull private final ActionBarCallback mCallback;
+ @NonNull private FrameLayout mContentRoot;
// A fake parent for measuring views.
@Nullable private ViewGroup mMeasureParent;
- public ActionBarLayout(@NonNull BridgeContext context, @NonNull SessionParams params) {
+ /**
+ * Inflate the action bar and attach it to {@code parentView}
+ */
+ public ActionBarLayout(@NonNull BridgeContext context, @NonNull SessionParams params,
+ @NonNull ViewGroup parentView) {
- super(context);
- setOrientation(LinearLayout.HORIZONTAL);
- setGravity(Gravity.CENTER_VERTICAL);
-
- // Inflate action bar layout.
- LayoutInflater.from(context).inflate(R.layout.screen_action_bar, this,
- true /*attachToRoot*/);
- mActionBar = new WindowDecorActionBar(this);
-
- // Set contexts.
mBridgeContext = context;
- mThemedContext = mActionBar.getThemedContext();
- // Set data for action bar.
- mCallback = params.getProjectCallback().getActionBarCallback();
- mIcon = params.getAppIcon();
- mTitle = params.getAppLabel();
- // Split Action Bar when the screen size is narrow and the application requests split action
- // bar when narrow.
- mSplit = context.getResources().getBoolean(R.bool.split_action_bar_is_narrow) &&
- mCallback.getSplitActionBarWhenNarrow();
- mNavMode = mCallback.getNavigationMode();
- // TODO: Support Navigation Drawer Indicator.
- mShowHomeAsUp = mCallback.getHomeButtonStyle() == HomeButtonStyle.SHOW_HOME_AS_UP;
- mSubTitle = mCallback.getSubTitle();
-
-
- // Set helper fields.
- mMenuBuilder = new MenuBuilder(mThemedContext);
- res = mBridgeContext.getRenderResources();
- mPopupMaxWidth = Math.max(mBridgeContext.getMetrics().widthPixels / 2,
- mThemedContext.getResources().getDimensionPixelSize(
- R.dimen.config_prefDialogWidth));
- mActionBarView = (ActionBarView) findViewById(R.id.action_bar);
- mContentRoot = (FrameLayout) findViewById(android.R.id.content);
-
- setupActionBar();
- }
-
- /**
- * Sets up the action bar by filling the appropriate data.
- */
- private void setupActionBar() {
- // Add title and sub title.
- ResourceValue titleValue = res.findResValue(mTitle, false /*isFramework*/);
- if (titleValue != null && titleValue.getValue() != null) {
- mActionBar.setTitle(titleValue.getValue());
+ ResourceValue layoutName = context.getRenderResources()
+ .findItemInTheme(LAYOUT_ATTR_NAME, true);
+ if (layoutName != null) {
+ // We may need to resolve the reference obtained.
+ layoutName = context.getRenderResources().findResValue(layoutName.getValue(),
+ layoutName.isFramework());
+ }
+ int layoutId = 0;
+ String error = null;
+ if (layoutName == null) {
+ error = "Unable to find action bar layout (" + LAYOUT_ATTR_NAME
+ + ") in the current theme.";
} else {
- mActionBar.setTitle(mTitle);
- }
- if (mSubTitle != null) {
- mActionBar.setSubtitle(mSubTitle);
- }
-
- // Add show home as up icon.
- if (mShowHomeAsUp) {
- mActionBar.setDisplayOptions(0xFF, ActionBar.DISPLAY_HOME_AS_UP);
- }
-
- // Set the navigation mode.
- mActionBar.setNavigationMode(mNavMode);
- if (mNavMode == ActionBar.NAVIGATION_MODE_TABS) {
- setupTabs(3);
- }
-
- if (mActionBarView != null) {
- // If the action bar style doesn't specify an icon, set the icon obtained from the session
- // params.
- if (!mActionBarView.hasIcon() && mIcon != null) {
- Drawable iconDrawable = getDrawable(mIcon, false /*isFramework*/);
- if (iconDrawable != null) {
- mActionBar.setIcon(iconDrawable);
- }
- }
-
- // Set action bar to be split, if needed.
- ActionBarContainer splitView = (ActionBarContainer) findViewById(R.id.split_action_bar);
- mActionBarView.setSplitView(splitView);
- mActionBarView.setSplitToolbar(mSplit);
-
- inflateMenus();
- }
- }
-
- /**
- * Gets the menus to add to the action bar from the callback, resolves them, inflates them and
- * adds them to the action bar.
- */
- private void inflateMenus() {
- if (mActionBarView == null) {
- return;
- }
- final MenuInflater inflater = new MenuInflater(mThemedContext);
- for (String name : mCallback.getMenuIdNames()) {
- if (mBridgeContext.getRenderResources().getProjectResource(ResourceType.MENU, name)
- != null) {
- int id = mBridgeContext.getProjectResourceValue(ResourceType.MENU, name, -1);
- if (id > -1) {
- inflater.inflate(id, mMenuBuilder);
- }
+ layoutId = context.getFrameworkResourceValue(layoutName.getResourceType(),
+ layoutName.getName(), 0);
+ if (layoutId == 0) {
+ error = String.format("Unable to resolve attribute \"%s\" of type \"%s\"",
+ layoutName.getName(), layoutName.getResourceType());
}
}
- mActionBarView.setMenu(mMenuBuilder, null /*callback*/);
- }
-
- // TODO: Use an adapter, like List View to set up tabs.
- private void setupTabs(int num) {
- for (int i = 1; i <= num; i++) {
- Tab tab = mActionBar.newTab().setText("Tab" + i).setTabListener(new TabListener() {
- @Override
- public void onTabUnselected(Tab t, FragmentTransaction ft) {
- // pass
- }
- @Override
- public void onTabSelected(Tab t, FragmentTransaction ft) {
- // pass
- }
- @Override
- public void onTabReselected(Tab t, FragmentTransaction ft) {
- // pass
- }
- });
- mActionBar.addTab(tab);
+ if (layoutId == 0) {
+ throw new RuntimeException(error);
}
- }
+ // Inflate action bar layout.
+ View decorContent = LayoutInflater.from(context).inflate(layoutId, parentView, true);
- @Nullable
- private Drawable getDrawable(@NonNull String name, boolean isFramework) {
- ResourceValue value = res.findResValue(name, isFramework);
- value = res.resolveResValue(value);
- if (value != null) {
- return ResourceHelper.getDrawable(value, mBridgeContext);
+ mActionBar = CustomActionBarWrapper.getActionBarWrapper(context, params, decorContent);
+
+ FrameLayout contentRoot = (FrameLayout) parentView.findViewById(android.R.id.content);
+
+ // If something went wrong and we were not able to initialize the content root,
+ // just add a frame layout inside this and return.
+ if (contentRoot == null) {
+ contentRoot = new FrameLayout(context);
+ contentRoot.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT,
+ LayoutParams.MATCH_PARENT));
+ parentView.addView(contentRoot);
+ mContentRoot = contentRoot;
+ } else {
+ mContentRoot = contentRoot;
+ mActionBar.setupActionBar();
+ mActionBar.inflateMenus();
}
- return null;
}
/**
@@ -229,7 +117,7 @@
* the content frame which shall serve as the new content root.
*/
public void createMenuPopup() {
- assert mContentRoot != null && findViewById(android.R.id.content) == mContentRoot
+ assert mContentRoot.getId() == android.R.id.content
: "Action Bar Menus have already been created.";
if (!isOverflowPopupNeeded()) {
@@ -237,7 +125,7 @@
}
// Create a layout to hold the menus and the user's content.
- RelativeLayout layout = new RelativeLayout(mThemedContext);
+ RelativeLayout layout = new RelativeLayout(mActionBar.getPopupContext());
layout.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT,
LayoutParams.MATCH_PARENT));
mContentRoot.addView(layout);
@@ -259,13 +147,14 @@
@NonNull
private View createMenuView() {
DisplayMetrics metrics = mBridgeContext.getMetrics();
- OverflowMenuAdapter adapter = new OverflowMenuAdapter(mMenuBuilder, mThemedContext);
+ MenuBuilder menu = mActionBar.getMenuBuilder();
+ OverflowMenuAdapter adapter = new OverflowMenuAdapter(menu, mActionBar.getPopupContext());
- LinearLayout layout = new LinearLayout(mThemedContext);
+ LinearLayout layout = new LinearLayout(mActionBar.getPopupContext());
RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(
measureContentWidth(adapter), LayoutParams.WRAP_CONTENT);
layoutParams.addRule(RelativeLayout.ALIGN_PARENT_END);
- if (mSplit) {
+ if (mActionBar.isSplit()) {
layoutParams.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
// TODO: Find correct value instead of hardcoded 10dp.
layoutParams.bottomMargin = getPixelValue("-10dp", metrics);
@@ -273,7 +162,7 @@
layoutParams.topMargin = getPixelValue("-10dp", metrics);
}
layout.setLayoutParams(layoutParams);
- final TypedArray a = mThemedContext.obtainStyledAttributes(null,
+ final TypedArray a = mActionBar.getPopupContext().obtainStyledAttributes(null,
R.styleable.PopupWindow, R.attr.popupMenuStyle, 0);
layout.setBackground(a.getDrawable(R.styleable.PopupWindow_popupBackground));
layout.setDividerDrawable(a.getDrawable(R.attr.actionBarDivider));
@@ -282,20 +171,25 @@
layout.setDividerPadding(getPixelValue("12dp", metrics));
layout.setShowDividers(LinearLayout.SHOW_DIVIDER_MIDDLE);
- ListView listView = new ListView(mThemedContext, null, R.attr.dropDownListViewStyle);
+ ListView listView = new ListView(mActionBar.getPopupContext(), null,
+ R.attr.dropDownListViewStyle);
listView.setAdapter(adapter);
layout.addView(listView);
return layout;
}
private boolean isOverflowPopupNeeded() {
- boolean needed = mCallback.isOverflowPopupNeeded();
+ boolean needed = mActionBar.isOverflowPopupNeeded();
if (!needed) {
return false;
}
// Copied from android.widget.ActionMenuPresenter.updateMenuView()
- ArrayList<MenuItemImpl> menus = mMenuBuilder.getNonActionItems();
- if (ActionBarAccessor.getActionMenuPresenter(mActionBarView).isOverflowReserved() &&
+ ArrayList<MenuItemImpl> menus = mActionBar.getMenuBuilder().getNonActionItems();
+ ActionMenuPresenter presenter = mActionBar.getActionMenuPresenter();
+ if (presenter == null) {
+ throw new RuntimeException("Failed to create a Presenter for Action Bar Menus.");
+ }
+ if (presenter.isOverflowReserved() &&
menus != null) {
final int count = menus.size();
if (count == 1) {
@@ -307,7 +201,7 @@
return needed;
}
- @Nullable
+ @NonNull
public FrameLayout getContentRoot() {
return mContentRoot;
}
@@ -319,6 +213,7 @@
View itemView = null;
int itemType = 0;
+ Context context = mActionBar.getPopupContext();
final int widthMeasureSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
final int heightMeasureSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
final int count = adapter.getCount();
@@ -330,15 +225,17 @@
}
if (mMeasureParent == null) {
- mMeasureParent = new FrameLayout(mThemedContext);
+ mMeasureParent = new FrameLayout(context);
}
itemView = adapter.getView(i, itemView, mMeasureParent);
itemView.measure(widthMeasureSpec, heightMeasureSpec);
final int itemWidth = itemView.getMeasuredWidth();
- if (itemWidth >= mPopupMaxWidth) {
- return mPopupMaxWidth;
+ int popupMaxWidth = Math.max(mBridgeContext.getMetrics().widthPixels / 2,
+ context.getResources().getDimensionPixelSize(R.dimen.config_prefDialogWidth));
+ if (itemWidth >= popupMaxWidth) {
+ return popupMaxWidth;
} else if (itemWidth > maxWidth) {
maxWidth = itemWidth;
}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/CustomActionBarWrapper.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/CustomActionBarWrapper.java
new file mode 100644
index 0000000..70b9cc3
--- /dev/null
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/CustomActionBarWrapper.java
@@ -0,0 +1,351 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.layoutlib.bridge.bars;
+
+import com.android.annotations.NonNull;
+import com.android.annotations.Nullable;
+import com.android.ide.common.rendering.api.ActionBarCallback;
+import com.android.ide.common.rendering.api.ActionBarCallback.HomeButtonStyle;
+import com.android.ide.common.rendering.api.RenderResources;
+import com.android.ide.common.rendering.api.ResourceValue;
+import com.android.ide.common.rendering.api.SessionParams;
+import com.android.internal.R;
+import com.android.internal.app.ToolbarActionBar;
+import com.android.internal.app.WindowDecorActionBar;
+import com.android.internal.view.menu.MenuBuilder;
+import com.android.internal.widget.ActionBarAccessor;
+import com.android.internal.widget.ActionBarView;
+import com.android.internal.widget.DecorToolbar;
+import com.android.layoutlib.bridge.android.BridgeContext;
+import com.android.layoutlib.bridge.impl.ResourceHelper;
+
+import android.app.ActionBar;
+import android.app.ActionBar.Tab;
+import android.app.ActionBar.TabListener;
+import android.app.FragmentTransaction;
+import android.content.Context;
+import android.content.res.Resources;
+import android.graphics.drawable.Drawable;
+import android.view.MenuInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.WindowCallback;
+import android.widget.ActionMenuPresenter;
+import android.widget.Toolbar;
+import android.widget.Toolbar_Accessor;
+
+import static com.android.SdkConstants.ANDROID_NS_NAME_PREFIX;
+import static com.android.resources.ResourceType.MENU;
+
+/**
+ * A common API to access {@link ToolbarActionBar} and {@link WindowDecorActionBar}.
+ */
+public abstract class CustomActionBarWrapper {
+
+ @NonNull protected ActionBar mActionBar;
+ @NonNull protected SessionParams mParams;
+ @NonNull protected ActionBarCallback mCallback;
+ @NonNull protected BridgeContext mContext;
+
+ /**
+ * Returns a wrapper around different implementations of the Action Bar to provide a common API.
+ *
+ * @param decorContent the top level view returned by inflating
+ * ?attr/windowActionBarFullscreenDecorLayout
+ */
+ @NonNull
+ public static CustomActionBarWrapper getActionBarWrapper(@NonNull BridgeContext context,
+ @NonNull SessionParams params, @NonNull View decorContent) {
+ View view = decorContent.findViewById(R.id.action_bar);
+ if (view instanceof Toolbar) {
+ return new ToolbarWrapper(context, params, ((Toolbar) view)
+ );
+ } else if (view instanceof ActionBarView) {
+ return new WindowActionBarWrapper(context, params, decorContent, ((ActionBarView) view)
+ );
+ } else {
+ throw new IllegalStateException("Can't make an action bar out of " +
+ view.getClass().getSimpleName());
+ }
+ }
+
+ CustomActionBarWrapper(@NonNull BridgeContext context, @NonNull SessionParams params,
+ @NonNull ActionBar actionBar) {
+ mActionBar = actionBar;
+ mParams = params;
+ mCallback = params.getProjectCallback().getActionBarCallback();
+ mContext = context;
+ }
+
+ protected void setupActionBar() {
+ // Do the things that are common to all implementations.
+ RenderResources res = mContext.getRenderResources();
+
+ String title = mParams.getAppLabel();
+ ResourceValue titleValue = res.findResValue(title, false);
+ if (titleValue != null && titleValue.getValue() != null) {
+ mActionBar.setTitle(titleValue.getValue());
+ } else {
+ mActionBar.setTitle(title);
+ }
+
+ String subTitle = mCallback.getSubTitle();
+ if (subTitle != null) {
+ mActionBar.setSubtitle(subTitle);
+ }
+
+ // Add show home as up icon.
+ if (mCallback.getHomeButtonStyle() == HomeButtonStyle.SHOW_HOME_AS_UP) {
+ mActionBar.setDisplayOptions(0xFF, ActionBar.DISPLAY_HOME_AS_UP);
+ }
+ }
+
+ protected boolean isSplit() {
+ return getDecorToolbar().isSplit();
+ }
+
+ protected boolean isOverflowPopupNeeded() {
+ return mCallback.isOverflowPopupNeeded();
+ }
+
+ /**
+ * Gets the menus to add to the action bar from the callback, resolves them, inflates them and
+ * adds them to the action bar.
+ */
+ protected void inflateMenus() {
+ MenuInflater inflater = new MenuInflater(getActionMenuContext());
+ MenuBuilder menuBuilder = getMenuBuilder();
+ for (String name : mCallback.getMenuIdNames()) {
+ int id;
+ if (name.startsWith(ANDROID_NS_NAME_PREFIX)) {
+ // Framework menu.
+ name = name.substring(ANDROID_NS_NAME_PREFIX.length());
+ id = mContext.getFrameworkResourceValue(MENU, name, -1);
+ } else {
+ // Project menu.
+ id = mContext.getProjectResourceValue(MENU, name, -1);
+ }
+ if (id > -1) {
+ inflater.inflate(id, menuBuilder);
+ }
+ }
+ }
+
+ /**
+ * The context used for the ActionBar and the menus in the ActionBarView.
+ */
+ @NonNull
+ protected Context getActionMenuContext() {
+ return mActionBar.getThemedContext();
+ }
+
+ /**
+ * The context used to inflate the popup menu.
+ */
+ @NonNull
+ abstract Context getPopupContext();
+
+ /**
+ * The Menu in which to inflate the user's menus.
+ */
+ @NonNull
+ abstract MenuBuilder getMenuBuilder();
+
+ @Nullable
+ abstract ActionMenuPresenter getActionMenuPresenter();
+
+ /**
+ * Framework's wrapper over two ActionBar implementations.
+ */
+ @NonNull
+ abstract DecorToolbar getDecorToolbar();
+
+ // ---- The implementations ----
+
+ /**
+ * Material theme uses {@link Toolbar} as the action bar. This wrapper provides access to
+ * Toolbar using a common API.
+ */
+ private static class ToolbarWrapper extends CustomActionBarWrapper {
+
+ @NonNull
+ private final Toolbar mToolbar; // This is the view.
+
+ ToolbarWrapper(@NonNull BridgeContext context, @NonNull SessionParams params,
+ @NonNull Toolbar toolbar) {
+ super(context, params, new ToolbarActionBar(toolbar, "", new WindowCallback())
+ );
+ mToolbar = toolbar;
+ }
+
+ @Override
+ protected void inflateMenus() {
+ super.inflateMenus();
+ // Inflating the menus doesn't initialize the ActionMenuPresenter. Setting a fake menu
+ // and then setting it back does the trick.
+ MenuBuilder menu = getMenuBuilder();
+ DecorToolbar decorToolbar = getDecorToolbar();
+ decorToolbar.setMenu(new MenuBuilder(getActionMenuContext()), null);
+ decorToolbar.setMenu(menu, null);
+ }
+
+ @NonNull
+ @Override
+ Context getPopupContext() {
+ return Toolbar_Accessor.getPopupContext(mToolbar);
+ }
+
+ @NonNull
+ @Override
+ MenuBuilder getMenuBuilder() {
+ return (MenuBuilder) mToolbar.getMenu();
+ }
+
+ @Nullable
+ @Override
+ ActionMenuPresenter getActionMenuPresenter() {
+ return Toolbar_Accessor.getActionMenuPresenter(mToolbar);
+ }
+
+ @NonNull
+ @Override
+ DecorToolbar getDecorToolbar() {
+ return mToolbar.getWrapper();
+ }
+ }
+
+ /**
+ * Holo theme uses {@link WindowDecorActionBar} as the action bar. This wrapper provides
+ * access to it using a common API.
+ */
+ private static class WindowActionBarWrapper extends CustomActionBarWrapper{
+
+ @NonNull
+ private final WindowDecorActionBar mActionBar;
+ private final ActionBarView mActionBarView;
+ private MenuBuilder mMenuBuilder;
+
+ public WindowActionBarWrapper(@NonNull BridgeContext context, @NonNull SessionParams params,
+ @NonNull View decorContentRoot, @NonNull ActionBarView actionBarView) {
+ super(context, params, new WindowDecorActionBar(decorContentRoot)
+ );
+ mActionBarView = actionBarView;
+ mActionBar = ((WindowDecorActionBar) super.mActionBar);
+ }
+
+ @Override
+ protected void setupActionBar() {
+ super.setupActionBar();
+
+ // Set the navigation mode.
+ int navMode = mCallback.getNavigationMode();
+ mActionBar.setNavigationMode(navMode);
+ //noinspection deprecation
+ if (navMode == ActionBar.NAVIGATION_MODE_TABS) {
+ setupTabs(3);
+ }
+
+ String icon = mParams.getAppIcon();
+ // If the action bar style doesn't specify an icon, set the icon obtained from the
+ // session params.
+ if (!mActionBar.hasIcon() && icon != null) {
+ Drawable iconDrawable = getDrawable(icon, false);
+ if (iconDrawable != null) {
+ mActionBar.setIcon(iconDrawable);
+ }
+ }
+
+ // Set action bar to be split, if needed.
+ ViewGroup splitView = (ViewGroup) mActionBarView.findViewById(R.id.split_action_bar);
+ if (splitView != null) {
+ mActionBarView.setSplitView(splitView);
+ Resources res = mContext.getResources();
+ boolean split = res.getBoolean(R.bool.split_action_bar_is_narrow)
+ && mCallback.getSplitActionBarWhenNarrow();
+ mActionBarView.setSplitToolbar(split);
+ }
+ }
+
+ @Override
+ protected void inflateMenus() {
+ super.inflateMenus();
+ // The super implementation doesn't set the menu on the view. Set it here.
+ mActionBarView.setMenu(getMenuBuilder(), null);
+ }
+
+ @NonNull
+ @Override
+ Context getPopupContext() {
+ return getActionMenuContext();
+ }
+
+ @NonNull
+ @Override
+ MenuBuilder getMenuBuilder() {
+ if (mMenuBuilder == null) {
+ mMenuBuilder = new MenuBuilder(getActionMenuContext());
+ }
+ return mMenuBuilder;
+ }
+
+ @Nullable
+ @Override
+ ActionMenuPresenter getActionMenuPresenter() {
+ return ActionBarAccessor.getActionMenuPresenter(mActionBarView);
+ }
+
+ @NonNull
+ @Override
+ ActionBarView getDecorToolbar() {
+ return mActionBarView;
+ }
+
+ // TODO: Use an adapter, like List View to set up tabs.
+ @SuppressWarnings("deprecation") // For Tab
+ private void setupTabs(int num) {
+ for (int i = 1; i <= num; i++) {
+ Tab tab = mActionBar.newTab().setText("Tab" + i).setTabListener(new TabListener() {
+ @Override
+ public void onTabUnselected(Tab t, FragmentTransaction ft) {
+ // pass
+ }
+ @Override
+ public void onTabSelected(Tab t, FragmentTransaction ft) {
+ // pass
+ }
+ @Override
+ public void onTabReselected(Tab t, FragmentTransaction ft) {
+ // pass
+ }
+ });
+ mActionBar.addTab(tab);
+ }
+ }
+
+ @Nullable
+ private Drawable getDrawable(@NonNull String name, boolean isFramework) {
+ RenderResources res = mContext.getRenderResources();
+ ResourceValue value = res.findResValue(name, isFramework);
+ value = res.resolveResValue(value);
+ if (value != null) {
+ return ResourceHelper.getDrawable(value, mContext);
+ }
+ return null;
+ }
+
+ }
+}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderSessionImpl.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderSessionImpl.java
index b8dce70..a2eed9a 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderSessionImpl.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderSessionImpl.java
@@ -353,8 +353,7 @@
// if the theme says no title/action bar, then the size will be 0
if (mActionBarSize > 0) {
- ActionBarLayout actionBar = createActionBar(context, params);
- backgroundLayout.addView(actionBar);
+ ActionBarLayout actionBar = createActionBar(context, params, backgroundLayout);
actionBar.createMenuPopup();
mContentRoot = actionBar.getContentRoot();
} else if (mTitleBarSize > 0) {
@@ -1624,11 +1623,9 @@
/**
* Creates the action bar. Also queries the project callback for missing information.
*/
- private ActionBarLayout createActionBar(BridgeContext context, SessionParams params) {
- ActionBarLayout actionBar = new ActionBarLayout(context, params);
- actionBar.setLayoutParams(new LinearLayout.LayoutParams(
- LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
- return actionBar;
+ private ActionBarLayout createActionBar(BridgeContext context, SessionParams params,
+ ViewGroup parentView) {
+ return new ActionBarLayout(context, params, parentView);
}
public BufferedImage getImage() {
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/util/DynamicIdMap.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/util/DynamicIdMap.java
index a1fae95..979aa33 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/util/DynamicIdMap.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/util/DynamicIdMap.java
@@ -16,6 +16,7 @@
package com.android.layoutlib.bridge.util;
+import com.android.annotations.NonNull;
import com.android.resources.ResourceType;
import com.android.util.Pair;
@@ -48,6 +49,7 @@
* @param name the name of the resource
* @return an integer.
*/
+ @NonNull
public Integer getId(ResourceType type, String name) {
return getId(Pair.of(type, name));
}
@@ -59,10 +61,11 @@
* @param resource the type/name of the resource
* @return an integer.
*/
+ @NonNull
public Integer getId(Pair<ResourceType, String> resource) {
Integer value = mDynamicIds.get(resource);
if (value == null) {
- value = Integer.valueOf(++mDynamicSeed);
+ value = ++mDynamicSeed;
mDynamicIds.put(resource, value);
mRevDynamicIds.put(value, resource);
}
diff --git a/tools/split-select/Abi.cpp b/tools/split-select/Abi.cpp
index 20654b6..180dd8f 100644
--- a/tools/split-select/Abi.cpp
+++ b/tools/split-select/Abi.cpp
@@ -16,42 +16,58 @@
#include "Abi.h"
+using namespace android;
+
namespace split {
namespace abi {
-static const std::vector<Variant> sNoneVariants = {};
-static const std::vector<Variant> sArmVariants =
- {Variant::armeabi, Variant::armeabi_v7a, Variant::arm64_v8a};
-static const std::vector<Variant> sIntelVariants = {Variant::x86, Variant::x86_64};
-static const std::vector<Variant> sMipsVariants = {Variant::mips, Variant::mips64};
+static Vector<Variant> buildVariants(Variant v1, Variant v2) {
+ Vector<Variant> v;
+ v.add(v1);
+ v.add(v2);
+ return v;
+}
+
+static Vector<Variant> buildVariants(Variant v1, Variant v2, Variant v3) {
+ Vector<Variant> v;
+ v.add(v1);
+ v.add(v2);
+ v.add(v3);
+ return v;
+}
+
+static const Vector<Variant> sNoneVariants;
+static const Vector<Variant> sArmVariants = buildVariants(Variant_armeabi, Variant_armeabi_v7a, Variant_arm64_v8a);
+static const Vector<Variant> sIntelVariants = buildVariants(Variant_x86, Variant_x86_64);
+static const Vector<Variant> sMipsVariants = buildVariants(Variant_mips, Variant_mips64);
Family getFamily(Variant variant) {
switch (variant) {
- case Variant::none:
- return Family::none;
- case Variant::armeabi:
- case Variant::armeabi_v7a:
- case Variant::arm64_v8a:
- return Family::arm;
- case Variant::x86:
- case Variant::x86_64:
- return Family::intel;
- case Variant::mips:
- case Variant::mips64:
- return Family::mips;
+ case Variant_none:
+ return Family_none;
+ case Variant_armeabi:
+ case Variant_armeabi_v7a:
+ case Variant_arm64_v8a:
+ return Family_arm;
+ case Variant_x86:
+ case Variant_x86_64:
+ return Family_intel;
+ case Variant_mips:
+ case Variant_mips64:
+ return Family_mips;
}
- return Family::none;
+ return Family_none;
}
-const std::vector<Variant>& getVariants(Family family) {
+const Vector<Variant>& getVariants(Family family) {
switch (family) {
- case Family::none:
+ case Family_none:
return sNoneVariants;
- case Family::arm:
+ case Family_arm:
return sArmVariants;
- case Family::intel:
+ case Family_intel:
return sIntelVariants;
- case Family::mips:
+ case Family_mips:
return sMipsVariants;
}
return sNoneVariants;
@@ -59,21 +75,21 @@
const char* toString(Variant variant) {
switch (variant) {
- case Variant::none:
+ case Variant_none:
return "";
- case Variant::armeabi:
+ case Variant_armeabi:
return "armeabi";
- case Variant::armeabi_v7a:
+ case Variant_armeabi_v7a:
return "armeabi-v7a";
- case Variant::arm64_v8a:
+ case Variant_arm64_v8a:
return "arm64-v8a";
- case Variant::x86:
+ case Variant_x86:
return "x86";
- case Variant::x86_64:
+ case Variant_x86_64:
return "x86_64";
- case Variant::mips:
+ case Variant_mips:
return "mips";
- case Variant::mips64:
+ case Variant_mips64:
return "mips64";
}
return "";
diff --git a/tools/split-select/Abi.h b/tools/split-select/Abi.h
index 3e00eba..85b4d62 100644
--- a/tools/split-select/Abi.h
+++ b/tools/split-select/Abi.h
@@ -17,31 +17,31 @@
#ifndef H_ANDROID_SPLIT_ABI
#define H_ANDROID_SPLIT_ABI
-#include <vector>
+#include <utils/Vector.h>
namespace split {
namespace abi {
-enum class Variant {
- none = 0,
- armeabi,
- armeabi_v7a,
- arm64_v8a,
- x86,
- x86_64,
- mips,
- mips64,
+enum Variant {
+ Variant_none = 0,
+ Variant_armeabi,
+ Variant_armeabi_v7a,
+ Variant_arm64_v8a,
+ Variant_x86,
+ Variant_x86_64,
+ Variant_mips,
+ Variant_mips64,
};
-enum class Family {
- none,
- arm,
- intel,
- mips,
+enum Family {
+ Family_none,
+ Family_arm,
+ Family_intel,
+ Family_mips,
};
Family getFamily(Variant variant);
-const std::vector<Variant>& getVariants(Family family);
+const android::Vector<Variant>& getVariants(Family family);
const char* toString(Variant variant);
} // namespace abi
diff --git a/tools/split-select/Android.mk b/tools/split-select/Android.mk
index d0b7287..dc48ea8 100644
--- a/tools/split-select/Android.mk
+++ b/tools/split-select/Android.mk
@@ -17,10 +17,6 @@
# This tool is prebuilt if we're doing an app-only build.
ifeq ($(TARGET_BUILD_APPS)$(filter true,$(TARGET_BUILD_PDK)),)
-# TODO(adamlesinski): Enable OS X builds when I figure out how
-# to build with clang and libc++
-ifneq ($(HOST_OS),darwin)
-
# ==========================================================
# Setup some common variables for the different build
# targets here.
@@ -55,7 +51,7 @@
libexpat \
libziparchive-host
-cFlags := -std=c++11 -Wall -Werror
+cFlags := -Wall -Werror
ifeq ($(HOST_OS),linux)
hostLdLibs += -lrt -ldl -lpthread
@@ -115,5 +111,4 @@
include $(BUILD_HOST_EXECUTABLE)
-endif # Not OS X
endif # No TARGET_BUILD_APPS or TARGET_BUILD_PDK
diff --git a/tools/split-select/Grouper.cpp b/tools/split-select/Grouper.cpp
index 15edf89..22685cd 100644
--- a/tools/split-select/Grouper.cpp
+++ b/tools/split-select/Grouper.cpp
@@ -16,25 +16,17 @@
#include "Grouper.h"
+#include "aapt/AaptUtil.h"
#include "SplitDescription.h"
#include <utils/KeyedVector.h>
#include <utils/Vector.h>
using namespace android;
+using AaptUtil::appendValue;
namespace split {
-template <typename Key, typename Value>
-static void addToVector(KeyedVector<Key, SortedVector<Value> >& group,
- const Key& key, const Value& value) {
- ssize_t idx = group.indexOfKey(key);
- if (idx < 0) {
- idx = group.add(key, SortedVector<Value>());
- }
- group.editValueAt(idx).add(value);
-}
-
Vector<SortedVector<SplitDescription> >
groupByMutualExclusivity(const Vector<SplitDescription>& splits) {
Vector<SortedVector<SplitDescription> > groups;
@@ -43,20 +35,22 @@
KeyedVector<SplitDescription, SortedVector<SplitDescription> > densityGroups;
KeyedVector<SplitDescription, SortedVector<SplitDescription> > abiGroups;
KeyedVector<SplitDescription, SortedVector<SplitDescription> > localeGroups;
- for (const SplitDescription& split : splits) {
+ const size_t splitCount = splits.size();
+ for (size_t i = 0; i < splitCount; i++) {
+ const SplitDescription& split = splits[i];
if (split.config.density != 0) {
SplitDescription key(split);
key.config.density = 0;
key.config.sdkVersion = 0; // Ignore density so we can support anydpi.
- addToVector(densityGroups, key, split);
- } else if (split.abi != abi::Variant::none) {
+ appendValue(densityGroups, key, split);
+ } else if (split.abi != abi::Variant_none) {
SplitDescription key(split);
- key.abi = abi::Variant::none;
- addToVector(abiGroups, key, split);
+ key.abi = abi::Variant_none;
+ appendValue(abiGroups, key, split);
} else if (split.config.locale != 0) {
SplitDescription key(split);
key.config.clearLocale();
- addToVector(localeGroups, key, split);
+ appendValue(localeGroups, key, split);
} else {
groups.add();
groups.editTop().add(split);
diff --git a/tools/split-select/Grouper_test.cpp b/tools/split-select/Grouper_test.cpp
index 4d146cd..a5f9c5a 100644
--- a/tools/split-select/Grouper_test.cpp
+++ b/tools/split-select/Grouper_test.cpp
@@ -19,7 +19,6 @@
#include "SplitDescription.h"
#include <gtest/gtest.h>
-#include <initializer_list>
#include <utils/String8.h>
#include <utils/Vector.h>
@@ -55,7 +54,11 @@
}
void addSplit(Vector<SplitDescription>& splits, const char* str);
- void expectHasGroupWithSplits(std::initializer_list<const char*> l);
+ void expectHasGroupWithSplits(const char* a);
+ void expectHasGroupWithSplits(const char* a, const char* b);
+ void expectHasGroupWithSplits(const char* a, const char* b, const char* c);
+ void expectHasGroupWithSplits(const char* a, const char* b, const char* c, const char* d);
+ void expectHasGroupWithSplits(const Vector<const char*>& expectedStrs);
Vector<SortedVector<SplitDescription> > mGroups;
};
@@ -65,39 +68,70 @@
}
TEST_F(GrouperTest, shouldGroupDensities) {
- expectHasGroupWithSplits({"en-rUS-sw300dp-hdpi", "en-rUS-sw300dp-xhdpi"});
- expectHasGroupWithSplits({"en-rUS-sw600dp-hdpi", "en-rUS-sw600dp-xhdpi"});
- expectHasGroupWithSplits({"fr-rFR-sw600dp-hdpi", "fr-rFR-sw600dp-xhdpi"});
- expectHasGroupWithSplits({"hdpi", "xhdpi", "xxhdpi", "anydpi"});
+ expectHasGroupWithSplits("en-rUS-sw300dp-hdpi", "en-rUS-sw300dp-xhdpi");
+ expectHasGroupWithSplits("en-rUS-sw600dp-hdpi", "en-rUS-sw600dp-xhdpi");
+ expectHasGroupWithSplits("fr-rFR-sw600dp-hdpi", "fr-rFR-sw600dp-xhdpi");
+ expectHasGroupWithSplits("hdpi", "xhdpi", "xxhdpi", "anydpi");
}
TEST_F(GrouperTest, shouldGroupAbi) {
- expectHasGroupWithSplits({":armeabi", ":x86"});
+ expectHasGroupWithSplits(":armeabi", ":x86");
}
TEST_F(GrouperTest, shouldGroupLocale) {
- expectHasGroupWithSplits({"pl-rPL", "de-rDE"});
+ expectHasGroupWithSplits("pl-rPL", "de-rDE");
}
TEST_F(GrouperTest, shouldGroupEachSplitIntoItsOwnGroup) {
- expectHasGroupWithSplits({"large"});
- expectHasGroupWithSplits({"xlarge"});
- expectHasGroupWithSplits({"v7"});
- expectHasGroupWithSplits({"v8"});
- expectHasGroupWithSplits({"sw600dp"});
- expectHasGroupWithSplits({"sw300dp"});
+ expectHasGroupWithSplits("large");
+ expectHasGroupWithSplits("xlarge");
+ expectHasGroupWithSplits("v7");
+ expectHasGroupWithSplits("v8");
+ expectHasGroupWithSplits("sw600dp");
+ expectHasGroupWithSplits("sw300dp");
}
//
// Helper methods
//
-void GrouperTest::expectHasGroupWithSplits(std::initializer_list<const char*> l) {
+void GrouperTest::expectHasGroupWithSplits(const char* a) {
+ Vector<const char*> expected;
+ expected.add(a);
+ expectHasGroupWithSplits(expected);
+}
+
+void GrouperTest::expectHasGroupWithSplits(const char* a, const char* b) {
+ Vector<const char*> expected;
+ expected.add(a);
+ expected.add(b);
+ expectHasGroupWithSplits(expected);
+}
+
+void GrouperTest::expectHasGroupWithSplits(const char* a, const char* b, const char* c) {
+ Vector<const char*> expected;
+ expected.add(a);
+ expected.add(b);
+ expected.add(c);
+ expectHasGroupWithSplits(expected);
+}
+
+void GrouperTest::expectHasGroupWithSplits(const char* a, const char* b, const char* c, const char* d) {
+ Vector<const char*> expected;
+ expected.add(a);
+ expected.add(b);
+ expected.add(c);
+ expected.add(d);
+ expectHasGroupWithSplits(expected);
+}
+
+void GrouperTest::expectHasGroupWithSplits(const Vector<const char*>& expectedStrs) {
Vector<SplitDescription> splits;
- for (const char* str : l) {
+ const size_t expectedStrCount = expectedStrs.size();
+ for (size_t i = 0; i < expectedStrCount; i++) {
splits.add();
- if (!SplitDescription::parse(String8(str), &splits.editTop())) {
- ADD_FAILURE() << "Failed to parse SplitDescription " << str;
+ if (!SplitDescription::parse(String8(expectedStrs[i]), &splits.editTop())) {
+ ADD_FAILURE() << "Failed to parse SplitDescription " << expectedStrs[i];
return;
}
}
diff --git a/tools/split-select/Main.cpp b/tools/split-select/Main.cpp
index d6251c3..434494e 100644
--- a/tools/split-select/Main.cpp
+++ b/tools/split-select/Main.cpp
@@ -63,7 +63,7 @@
class SplitSelector {
public:
- SplitSelector() = default;
+ SplitSelector();
SplitSelector(const Vector<SplitDescription>& splits);
Vector<SplitDescription> getBestSplits(const SplitDescription& target) const;
@@ -75,6 +75,9 @@
Vector<SortedVector<SplitDescription> > mGroups;
};
+SplitSelector::SplitSelector() {
+}
+
SplitSelector::SplitSelector(const Vector<SplitDescription>& splits)
: mGroups(groupByMutualExclusivity(splits)) {
}
diff --git a/tools/split-select/RuleGenerator.cpp b/tools/split-select/RuleGenerator.cpp
index 669ae78..b8f3bcb 100644
--- a/tools/split-select/RuleGenerator.cpp
+++ b/tools/split-select/RuleGenerator.cpp
@@ -65,12 +65,12 @@
sp<Rule> RuleGenerator::generateAbi(const Vector<abi::Variant>& splitAbis, size_t index) {
const abi::Variant thisAbi = splitAbis[index];
- const std::vector<abi::Variant>& familyVariants = abi::getVariants(abi::getFamily(thisAbi));
+ const Vector<abi::Variant>& familyVariants = abi::getVariants(abi::getFamily(thisAbi));
- std::vector<abi::Variant>::const_iterator start =
+ Vector<abi::Variant>::const_iterator start =
std::find(familyVariants.begin(), familyVariants.end(), thisAbi);
- std::vector<abi::Variant>::const_iterator end = familyVariants.end();
+ Vector<abi::Variant>::const_iterator end = familyVariants.end();
if (index + 1 < splitAbis.size()) {
end = std::find(start, familyVariants.end(), splitAbis[index + 1]);
}
@@ -127,7 +127,7 @@
rootRule->subrules.add(generateDensity(allDensities, densityIndex));
}
- if (group[index].abi != abi::Variant::none) {
+ if (group[index].abi != abi::Variant_none) {
size_t abiIndex = 0;
Vector<abi::Variant> allVariants;
allVariants.add(group[index].abi);
diff --git a/tools/split-select/RuleGenerator_test.cpp b/tools/split-select/RuleGenerator_test.cpp
index 60baabe..ee387be 100644
--- a/tools/split-select/RuleGenerator_test.cpp
+++ b/tools/split-select/RuleGenerator_test.cpp
@@ -25,19 +25,19 @@
namespace split {
static void expectDensityRule(const Vector<int>& densities, int density, int greaterThan, int lessThan);
-static void expectAbiRule(const Vector<abi::Variant>& abis, abi::Variant variant,
- std::initializer_list<const char*> matches);
+static void expectAbiRule(const Vector<abi::Variant>& abis, abi::Variant variant, const char* a);
+static void expectAbiRule(const Vector<abi::Variant>& abis, abi::Variant variant, const char* a, const char* b);
TEST(RuleGeneratorTest, testAbiRules) {
Vector<abi::Variant> abis;
- abis.add(abi::Variant::armeabi);
- abis.add(abi::Variant::armeabi_v7a);
- abis.add(abi::Variant::x86);
+ abis.add(abi::Variant_armeabi);
+ abis.add(abi::Variant_armeabi_v7a);
+ abis.add(abi::Variant_x86);
std::sort(abis.begin(), abis.end());
- expectAbiRule(abis, abi::Variant::armeabi, {"armeabi"});
- expectAbiRule(abis, abi::Variant::armeabi_v7a, {"armeabi-v7a", "arm64-v8a"});
- expectAbiRule(abis, abi::Variant::x86, {"x86", "x86_64"});
+ expectAbiRule(abis, abi::Variant_armeabi, "armeabi");
+ expectAbiRule(abis, abi::Variant_armeabi_v7a, "armeabi-v7a", "arm64-v8a");
+ expectAbiRule(abis, abi::Variant_x86, "x86", "x86_64");
}
TEST(RuleGeneratorTest, testDensityRules) {
@@ -126,8 +126,7 @@
}
}
-static void expectAbiRule(const Vector<abi::Variant>& abis, abi::Variant variant,
- std::initializer_list<const char*> matches) {
+static void expectAbiRule(const Vector<abi::Variant>& abis, abi::Variant variant, const Vector<const char*>& matches) {
const abi::Variant* iter = std::find(abis.begin(), abis.end(), variant);
if (abis.end() == iter) {
ADD_FAILURE() << abi::toString(variant) << " was not in the abi list.";
@@ -143,7 +142,9 @@
EXPECT_EQ(matches.size(), rule->stringArgs.size())
<< " for " << abi::toString(variant) << " rule";
- for (const char* match : matches) {
+ const size_t matchCount = matches.size();
+ for (size_t i = 0; i < matchCount; i++) {
+ const char* match = matches[i];
if (rule->stringArgs.end() ==
std::find(rule->stringArgs.begin(), rule->stringArgs.end(), String8(match))) {
ADD_FAILURE() << "Rule for abi " << abi::toString(variant)
@@ -152,4 +153,17 @@
}
}
+static void expectAbiRule(const Vector<abi::Variant>& abis, abi::Variant variant, const char* a) {
+ Vector<const char*> matches;
+ matches.add(a);
+ expectAbiRule(abis, variant, matches);
+}
+
+static void expectAbiRule(const Vector<abi::Variant>& abis, abi::Variant variant, const char* a, const char* b) {
+ Vector<const char*> matches;
+ matches.add(a);
+ matches.add(b);
+ expectAbiRule(abis, variant, matches);
+}
+
} // namespace split
diff --git a/tools/split-select/SplitDescription.cpp b/tools/split-select/SplitDescription.cpp
index 8037ef0..99bc23d 100644
--- a/tools/split-select/SplitDescription.cpp
+++ b/tools/split-select/SplitDescription.cpp
@@ -27,7 +27,7 @@
namespace split {
SplitDescription::SplitDescription()
-: abi(abi::Variant::none) {
+: abi(abi::Variant_none) {
}
int SplitDescription::compare(const SplitDescription& rhs) const {
@@ -38,11 +38,11 @@
}
bool SplitDescription::isBetterThan(const SplitDescription& o, const SplitDescription& target) const {
- if (abi != abi::Variant::none || o.abi != abi::Variant::none) {
+ if (abi != abi::Variant_none || o.abi != abi::Variant_none) {
abi::Family family = abi::getFamily(abi);
abi::Family oFamily = abi::getFamily(o.abi);
if (family != oFamily) {
- return family != abi::Family::none;
+ return family != abi::Family_none;
}
if (int(target.abi) - int(abi) < int(target.abi) - int(o.abi)) {
@@ -53,7 +53,7 @@
}
bool SplitDescription::match(const SplitDescription& o) const {
- if (abi != abi::Variant::none) {
+ if (abi != abi::Variant_none) {
abi::Family family = abi::getFamily(abi);
abi::Family oFamily = abi::getFamily(o.abi);
if (family != oFamily) {
@@ -69,7 +69,7 @@
String8 SplitDescription::toString() const {
String8 extension;
- if (abi != abi::Variant::none) {
+ if (abi != abi::Variant_none) {
if (extension.isEmpty()) {
extension.append(":");
} else {
@@ -85,40 +85,40 @@
ssize_t parseAbi(const Vector<String8>& parts, const ssize_t index,
SplitDescription* outSplit) {
const ssize_t N = parts.size();
- abi::Variant abi = abi::Variant::none;
+ abi::Variant abi = abi::Variant_none;
ssize_t endIndex = index;
if (parts[endIndex] == "arm64") {
endIndex++;
if (endIndex < N) {
if (parts[endIndex] == "v8a") {
endIndex++;
- abi = abi::Variant::arm64_v8a;
+ abi = abi::Variant_arm64_v8a;
}
}
} else if (parts[endIndex] == "armeabi") {
endIndex++;
- abi = abi::Variant::armeabi;
+ abi = abi::Variant_armeabi;
if (endIndex < N) {
if (parts[endIndex] == "v7a") {
endIndex++;
- abi = abi::Variant::armeabi_v7a;
+ abi = abi::Variant_armeabi_v7a;
}
}
} else if (parts[endIndex] == "x86") {
endIndex++;
- abi = abi::Variant::x86;
+ abi = abi::Variant_x86;
} else if (parts[endIndex] == "x86_64") {
endIndex++;
- abi = abi::Variant::x86_64;
+ abi = abi::Variant_x86_64;
} else if (parts[endIndex] == "mips") {
endIndex++;
- abi = abi::Variant::mips;
+ abi = abi::Variant_mips;
} else if (parts[endIndex] == "mips64") {
endIndex++;
- abi = abi::Variant::mips64;
+ abi = abi::Variant_mips64;
}
- if (abi == abi::Variant::none && endIndex != index) {
+ if (abi == abi::Variant_none && endIndex != index) {
return -1;
}
diff --git a/tools/split-select/SplitDescription.h b/tools/split-select/SplitDescription.h
index 5fcafc8..b13c9ee 100644
--- a/tools/split-select/SplitDescription.h
+++ b/tools/split-select/SplitDescription.h
@@ -27,7 +27,6 @@
struct SplitDescription {
SplitDescription();
- SplitDescription(const SplitDescription&) = default;
ConfigDescription config;
abi::Variant abi;
diff --git a/wifi/java/android/net/wifi/WifiInfo.java b/wifi/java/android/net/wifi/WifiInfo.java
index 5bf3470..75198e5 100644
--- a/wifi/java/android/net/wifi/WifiInfo.java
+++ b/wifi/java/android/net/wifi/WifiInfo.java
@@ -286,7 +286,7 @@
* Returns the service set identifier (SSID) of the current 802.11 network.
* If the SSID can be decoded as UTF-8, it will be returned surrounded by double
* quotation marks. Otherwise, it is returned as a string of hex digits. The
- * SSID may be {@code null} if there is no network currently connected.
+ * SSID may be <unknown ssid> if there is no network currently connected.
* @return the SSID
*/
public String getSSID() {