Merge "Fix tests in MtpDocumentsProvider."
diff --git a/api/current.txt b/api/current.txt
index b1e80dd..a32f65e 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -240,8 +240,10 @@
field public static final int activatedBackgroundIndicator = 16843517; // 0x10102fd
field public static final int activityCloseEnterAnimation = 16842938; // 0x10100ba
field public static final int activityCloseExitAnimation = 16842939; // 0x10100bb
+ field public static final int activityHeight = 16844019; // 0x10104f3
field public static final int activityOpenEnterAnimation = 16842936; // 0x10100b8
field public static final int activityOpenExitAnimation = 16842937; // 0x10100b9
+ field public static final int activityWidth = 16844018; // 0x10104f2
field public static final int addPrintersActivity = 16843750; // 0x10103e6
field public static final int addStatesFromChildren = 16842992; // 0x10100f0
field public static final int adjustViewBounds = 16843038; // 0x101011e
@@ -30633,6 +30635,7 @@
field public static final java.lang.String KEY_AUTO_RETRY_ENABLED_BOOL = "auto_retry_enabled_bool";
field public static final java.lang.String KEY_CARRIER_ALLOW_TURNOFF_IMS_BOOL = "carrier_allow_turnoff_ims_bool";
field public static final java.lang.String KEY_CARRIER_SETTINGS_ENABLE_BOOL = "carrier_settings_enable_bool";
+ field public static final java.lang.String KEY_CARRIER_USE_IMS_FIRST_FOR_EMERGENCY_BOOL = "carrier_use_ims_first_for_emergency_bool";
field public static final java.lang.String KEY_CARRIER_VOLTE_AVAILABLE_BOOL = "carrier_volte_available_bool";
field public static final java.lang.String KEY_CARRIER_VOLTE_PROVISIONING_REQUIRED_BOOL = "carrier_volte_provisioning_required_bool";
field public static final java.lang.String KEY_CARRIER_VOLTE_TTY_SUPPORTED_BOOL = "carrier_volte_tty_supported_bool";
diff --git a/api/system-current.txt b/api/system-current.txt
index fe7c6da..81f8c8d 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -333,8 +333,10 @@
field public static final int activatedBackgroundIndicator = 16843517; // 0x10102fd
field public static final int activityCloseEnterAnimation = 16842938; // 0x10100ba
field public static final int activityCloseExitAnimation = 16842939; // 0x10100bb
+ field public static final int activityHeight = 16844019; // 0x10104f3
field public static final int activityOpenEnterAnimation = 16842936; // 0x10100b8
field public static final int activityOpenExitAnimation = 16842937; // 0x10100b9
+ field public static final int activityWidth = 16844018; // 0x10104f2
field public static final int addPrintersActivity = 16843750; // 0x10103e6
field public static final int addStatesFromChildren = 16842992; // 0x10100f0
field public static final int adjustViewBounds = 16843038; // 0x101011e
@@ -32903,6 +32905,7 @@
field public static final java.lang.String KEY_AUTO_RETRY_ENABLED_BOOL = "auto_retry_enabled_bool";
field public static final java.lang.String KEY_CARRIER_ALLOW_TURNOFF_IMS_BOOL = "carrier_allow_turnoff_ims_bool";
field public static final java.lang.String KEY_CARRIER_SETTINGS_ENABLE_BOOL = "carrier_settings_enable_bool";
+ field public static final java.lang.String KEY_CARRIER_USE_IMS_FIRST_FOR_EMERGENCY_BOOL = "carrier_use_ims_first_for_emergency_bool";
field public static final java.lang.String KEY_CARRIER_VOLTE_AVAILABLE_BOOL = "carrier_volte_available_bool";
field public static final java.lang.String KEY_CARRIER_VOLTE_PROVISIONING_REQUIRED_BOOL = "carrier_volte_provisioning_required_bool";
field public static final java.lang.String KEY_CARRIER_VOLTE_TTY_SUPPORTED_BOOL = "carrier_volte_tty_supported_bool";
diff --git a/cmds/pm/src/com/android/commands/pm/Pm.java b/cmds/pm/src/com/android/commands/pm/Pm.java
index f66a4c7..3f0a444 100644
--- a/cmds/pm/src/com/android/commands/pm/Pm.java
+++ b/cmds/pm/src/com/android/commands/pm/Pm.java
@@ -51,6 +51,7 @@
import android.content.res.AssetManager;
import android.content.res.Resources;
import android.net.Uri;
+import android.os.Binder;
import android.os.Build;
import android.os.Bundle;
import android.os.IUserManager;
@@ -987,6 +988,7 @@
case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK: return "ask";
case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS: return "always";
case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER: return "never";
+ case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK : return "always ask";
}
return "Unknown link state: " + state;
}
@@ -1094,6 +1096,7 @@
}
}
+ userId = translateUserId(userId, "runInstall");
if (userId == UserHandle.USER_ALL) {
userId = UserHandle.USER_SYSTEM;
installFlags |= PackageManager.INSTALL_ALL_USERS;
@@ -1164,6 +1167,16 @@
}
}
+ /**
+ * @param userId The user id to be translated.
+ * @param logContext Optional human readable text to provide some context in error log.
+ * @return Translated concrete user id. This will include USER_ALL.
+ */
+ private int translateUserId(int userId, String logContext) {
+ return ActivityManager.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
+ userId, true, true, logContext, "pm command");
+ }
+
private int runInstallCreate() throws RemoteException {
int userId = UserHandle.USER_ALL;
String installerPackageName = null;
@@ -1220,6 +1233,7 @@
}
}
+ userId = translateUserId(userId, "runInstallCreate");
if (userId == UserHandle.USER_ALL) {
userId = UserHandle.USER_SYSTEM;
params.installFlags |= PackageManager.INSTALL_ALL_USERS;
@@ -1551,6 +1565,7 @@
return 1;
}
+ userId = translateUserId(userId, "runUninstall");
if (userId == UserHandle.USER_ALL) {
userId = UserHandle.USER_SYSTEM;
flags |= PackageManager.DELETE_ALL_USERS;
diff --git a/cmds/uiautomator/library/testrunner-src/com/android/uiautomator/core/ShellUiAutomatorBridge.java b/cmds/uiautomator/library/testrunner-src/com/android/uiautomator/core/ShellUiAutomatorBridge.java
index c551482..cb39e37 100644
--- a/cmds/uiautomator/library/testrunner-src/com/android/uiautomator/core/ShellUiAutomatorBridge.java
+++ b/cmds/uiautomator/library/testrunner-src/com/android/uiautomator/core/ShellUiAutomatorBridge.java
@@ -61,7 +61,7 @@
IBinder token = new Binder();
try {
ContentProviderHolder holder = activityManager.getContentProviderExternal(
- providerName, UserHandle.USER_OWNER, token);
+ providerName, UserHandle.USER_SYSTEM, token);
if (holder == null) {
throw new IllegalStateException("Could not find provider: " + providerName);
}
diff --git a/core/java/android/app/backup/FullBackup.java b/core/java/android/app/backup/FullBackup.java
index 7718a36..9ea2ba2 100644
--- a/core/java/android/app/backup/FullBackup.java
+++ b/core/java/android/app/backup/FullBackup.java
@@ -401,7 +401,19 @@
activeSet.add(canonicalJournalPath);
if (Log.isLoggable(TAG_XML_PARSER, Log.VERBOSE)) {
Log.v(TAG_XML_PARSER, "...automatically generated "
- + canonicalJournalPath + ". Ignore if nonexistant.");
+ + canonicalJournalPath + ". Ignore if nonexistent.");
+ }
+ }
+
+ // Special case for sharedpref files (not dirs) also add ".xml" suffix file.
+ if ("sharedpref".equals(domainFromXml) && !canonicalFile.isDirectory() &&
+ !canonicalFile.getCanonicalPath().endsWith(".xml")) {
+ final String canonicalXmlPath =
+ canonicalFile.getCanonicalPath() + ".xml";
+ activeSet.add(canonicalXmlPath);
+ if (Log.isLoggable(TAG_XML_PARSER, Log.VERBOSE)) {
+ Log.v(TAG_XML_PARSER, "...automatically generated "
+ + canonicalXmlPath + ". Ignore if nonexistent.");
}
}
}
diff --git a/core/java/android/app/backup/WallpaperBackupHelper.java b/core/java/android/app/backup/WallpaperBackupHelper.java
index 7a80936..30c11ef 100644
--- a/core/java/android/app/backup/WallpaperBackupHelper.java
+++ b/core/java/android/app/backup/WallpaperBackupHelper.java
@@ -56,11 +56,12 @@
// This path must match what the WallpaperManagerService uses
// TODO: Will need to change if backing up non-primary user's wallpaper
+ // http://b/22388012
public static final String WALLPAPER_IMAGE =
- new File(Environment.getUserSystemDirectory(UserHandle.USER_OWNER),
+ new File(Environment.getUserSystemDirectory(UserHandle.USER_SYSTEM),
"wallpaper").getAbsolutePath();
public static final String WALLPAPER_INFO =
- new File(Environment.getUserSystemDirectory(UserHandle.USER_OWNER),
+ new File(Environment.getUserSystemDirectory(UserHandle.USER_SYSTEM),
"wallpaper_info.xml").getAbsolutePath();
// Use old keys to keep legacy data compatibility and avoid writing two wallpapers
public static final String WALLPAPER_IMAGE_KEY =
@@ -71,8 +72,9 @@
// will be saved to this file from the restore stream, then renamed to the proper
// location if it's deemed suitable.
// TODO: Will need to change if backing up non-primary user's wallpaper
+ // http://b/22388012
private static final String STAGE_FILE =
- new File(Environment.getUserSystemDirectory(UserHandle.USER_OWNER),
+ new File(Environment.getUserSystemDirectory(UserHandle.USER_SYSTEM),
"wallpaper-tmp").getAbsolutePath();
Context mContext;
diff --git a/core/java/android/content/pm/ActivityInfo.java b/core/java/android/content/pm/ActivityInfo.java
index 876fbf5..83092a9 100644
--- a/core/java/android/content/pm/ActivityInfo.java
+++ b/core/java/android/content/pm/ActivityInfo.java
@@ -719,6 +719,7 @@
maxRecents = orig.maxRecents;
resizeable = orig.resizeable;
lockTaskLaunchMode = orig.lockTaskLaunchMode;
+ initialLayout = orig.initialLayout;
}
/**
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index 6443667..502f735 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -3307,25 +3307,25 @@
int height = -1;
float heightFraction = -1f;
final int widthType = sw.getType(
- com.android.internal.R.styleable.AndroidManifestInitialLayout_activity_width);
+ com.android.internal.R.styleable.AndroidManifestInitialLayout_activityWidth);
if (widthType == TypedValue.TYPE_FRACTION) {
widthFraction = sw.getFraction(
- com.android.internal.R.styleable.AndroidManifestInitialLayout_activity_width,
+ com.android.internal.R.styleable.AndroidManifestInitialLayout_activityWidth,
1, 1, -1);
} else if (widthType == TypedValue.TYPE_DIMENSION) {
width = sw.getDimensionPixelSize(
- com.android.internal.R.styleable.AndroidManifestInitialLayout_activity_width,
+ com.android.internal.R.styleable.AndroidManifestInitialLayout_activityWidth,
-1);
}
final int heightType = sw.getType(
- com.android.internal.R.styleable.AndroidManifestInitialLayout_activity_height);
+ com.android.internal.R.styleable.AndroidManifestInitialLayout_activityHeight);
if (heightType == TypedValue.TYPE_FRACTION) {
heightFraction = sw.getFraction(
- com.android.internal.R.styleable.AndroidManifestInitialLayout_activity_height,
+ com.android.internal.R.styleable.AndroidManifestInitialLayout_activityHeight,
1, 1, -1);
} else if (heightType == TypedValue.TYPE_DIMENSION) {
height = sw.getDimensionPixelSize(
- com.android.internal.R.styleable.AndroidManifestInitialLayout_activity_height,
+ com.android.internal.R.styleable.AndroidManifestInitialLayout_activityHeight,
-1);
}
int gravity = sw.getInt(
@@ -3415,6 +3415,7 @@
info.uiOptions = target.info.uiOptions;
info.parentActivityName = target.info.parentActivityName;
info.maxRecents = target.info.maxRecents;
+ info.initialLayout = target.info.initialLayout;
Activity a = new Activity(mParseActivityAliasArgs, info);
if (outError[0] != null) {
diff --git a/core/java/android/content/pm/UserInfo.java b/core/java/android/content/pm/UserInfo.java
index dfd0f7d..38f971a 100644
--- a/core/java/android/content/pm/UserInfo.java
+++ b/core/java/android/content/pm/UserInfo.java
@@ -152,8 +152,9 @@
}
if (UserManager.isSplitSystemUser()) {
return id != UserHandle.USER_SYSTEM;
+ } else {
+ return id == UserHandle.USER_SYSTEM;
}
- return id == UserHandle.USER_OWNER;
}
public UserInfo() {
diff --git a/core/java/android/hardware/ICameraServiceProxy.aidl b/core/java/android/hardware/ICameraServiceProxy.aidl
index 0bb24bc..0e654d5 100644
--- a/core/java/android/hardware/ICameraServiceProxy.aidl
+++ b/core/java/android/hardware/ICameraServiceProxy.aidl
@@ -19,6 +19,8 @@
/**
* Binder interface for the camera service proxy running in system_server.
*
+ * Keep in sync with frameworks/av/include/camera/ICameraServiceProxy.h
+ *
* @hide
*/
interface ICameraServiceProxy
@@ -27,4 +29,9 @@
* Ping the service proxy to update the valid users for the camera service.
*/
oneway void pingForUserUpdate();
+
+ /**
+ * Update the status of a camera device
+ */
+ oneway void notifyCameraState(String cameraId, int newCameraState);
}
diff --git a/core/java/android/hardware/camera2/params/StreamConfigurationMap.java b/core/java/android/hardware/camera2/params/StreamConfigurationMap.java
index e71e49f..b8d6960 100644
--- a/core/java/android/hardware/camera2/params/StreamConfigurationMap.java
+++ b/core/java/android/hardware/camera2/params/StreamConfigurationMap.java
@@ -1290,7 +1290,7 @@
for (StreamConfiguration config : configurations) {
int fmt = config.getFormat();
if (fmt == format && config.isOutput() == output) {
- if (output) {
+ if (output && mListHighResolution) {
// Filter slow high-res output formats; include for
// highRes, remove for !highRes
long duration = 0;
diff --git a/core/java/android/view/ContextThemeWrapper.java b/core/java/android/view/ContextThemeWrapper.java
index ce50091..ea0873d 100644
--- a/core/java/android/view/ContextThemeWrapper.java
+++ b/core/java/android/view/ContextThemeWrapper.java
@@ -19,12 +19,13 @@
import android.annotation.StyleRes;
import android.content.Context;
import android.content.ContextWrapper;
+import android.content.res.AssetManager;
import android.content.res.Configuration;
import android.content.res.Resources;
/**
- * A ContextWrapper that allows you to modify the theme from what is in the
- * wrapped context.
+ * A context wrapper that allows you to modify or replace the theme of the
+ * wrapped context.
*/
public class ContextThemeWrapper extends ContextWrapper {
private int mThemeResource;
@@ -33,15 +34,42 @@
private Configuration mOverrideConfiguration;
private Resources mResources;
+ /**
+ * Creates a new context wrapper with no theme and no base context.
+ * <p>
+ * <stong>Note:</strong> A base context <strong>must</strong> be attached
+ * using {@link #attachBaseContext(Context)} before calling any other
+ * method on the newly constructed context wrapper.
+ */
public ContextThemeWrapper() {
super(null);
}
+ /**
+ * Creates a new context wrapper with the specified theme.
+ * <p>
+ * The specified theme will be applied on top of the base context's theme.
+ * Any attributes not explicitly defined in the theme identified by
+ * <var>themeResId</var> will retain their original values.
+ *
+ * @param base the base context
+ * @param themeResId the resource ID of the theme to be applied on top of
+ * the base context's theme
+ */
public ContextThemeWrapper(Context base, @StyleRes int themeResId) {
super(base);
mThemeResource = themeResId;
}
+ /**
+ * Creates a new context wrapper with the specified theme.
+ * <p>
+ * Unlike {@link #ContextThemeWrapper(Context, int)}, the theme passed to
+ * this constructor will completely replace the base context's theme.
+ *
+ * @param base the base context
+ * @param theme the theme against which resources should be inflated
+ */
public ContextThemeWrapper(Context base, Resources.Theme theme) {
super(base);
mTheme = theme;
@@ -60,11 +88,12 @@
* information.
*
* <p>This method can only be called once, and must be called before any
- * calls to {@link #getResources()} are made.
+ * calls to {@link #getResources()} or {@link #getAssets()} are made.
*/
public void applyOverrideConfiguration(Configuration overrideConfiguration) {
if (mResources != null) {
- throw new IllegalStateException("getResources() has already been called");
+ throw new IllegalStateException(
+ "getResources() or getAssets() has already been called");
}
if (mOverrideConfiguration != null) {
throw new IllegalStateException("Override configuration has already been set");
@@ -73,20 +102,25 @@
}
@Override
- public Resources getResources() {
- if (mResources != null) {
- return mResources;
- }
- if (mOverrideConfiguration == null) {
- mResources = super.getResources();
- return mResources;
- } else {
- Context resc = createConfigurationContext(mOverrideConfiguration);
- mResources = resc.getResources();
- return mResources;
- }
+ public AssetManager getAssets() {
+ // Ensure we're returning assets with the correct configuration.
+ return getResources().getAssets();
}
-
+
+ @Override
+ public Resources getResources() {
+ if (mResources == null) {
+ if (mOverrideConfiguration == null) {
+ mResources = super.getResources();
+ } else {
+ final Context resContext = createConfigurationContext(mOverrideConfiguration);
+ mResources = resContext.getResources();
+ }
+ }
+
+ return mResources;
+ }
+
@Override
public void setTheme(int resid) {
if (mThemeResource != resid) {
@@ -94,14 +128,15 @@
initializeTheme();
}
}
-
+
/** @hide */
@Override
public int getThemeResId() {
return mThemeResource;
}
- @Override public Resources.Theme getTheme() {
+ @Override
+ public Resources.Theme getTheme() {
if (mTheme != null) {
return mTheme;
}
@@ -113,7 +148,8 @@
return mTheme;
}
- @Override public Object getSystemService(String name) {
+ @Override
+ public Object getSystemService(String name) {
if (LAYOUT_INFLATER_SERVICE.equals(name)) {
if (mInflater == null) {
mInflater = LayoutInflater.from(getBaseContext()).cloneInContext(this);
@@ -122,27 +158,27 @@
}
return getBaseContext().getSystemService(name);
}
-
+
/**
* Called by {@link #setTheme} and {@link #getTheme} to apply a theme
- * resource to the current Theme object. Can override to change the
- * default (simple) behavior. This method will not be called in multiple
+ * resource to the current Theme object. May be overridden to change the
+ * default (simple) behavior. This method will not be called in multiple
* threads simultaneously.
*
- * @param theme The Theme object being modified.
- * @param resid The theme style resource being applied to <var>theme</var>.
- * @param first Set to true if this is the first time a style is being
- * applied to <var>theme</var>.
+ * @param theme the theme being modified
+ * @param resId the style resource being applied to <var>theme</var>
+ * @param first {@code true} if this is the first time a style is being
+ * applied to <var>theme</var>
*/
- protected void onApplyThemeResource(Resources.Theme theme, int resid, boolean first) {
- theme.applyStyle(resid, true);
+ protected void onApplyThemeResource(Resources.Theme theme, int resId, boolean first) {
+ theme.applyStyle(resId, true);
}
private void initializeTheme() {
final boolean first = mTheme == null;
if (first) {
mTheme = getResources().newTheme();
- Resources.Theme theme = getBaseContext().getTheme();
+ final Resources.Theme theme = getBaseContext().getTheme();
if (theme != null) {
mTheme.setTo(theme);
}
diff --git a/core/java/android/view/WindowManagerInternal.java b/core/java/android/view/WindowManagerInternal.java
index 7b4640b..a6d9932 100644
--- a/core/java/android/view/WindowManagerInternal.java
+++ b/core/java/android/view/WindowManagerInternal.java
@@ -120,6 +120,13 @@
}
/**
+ * An interface to be notified about hardware keyboard status.
+ */
+ public interface OnHardKeyboardStatusChangeListener {
+ public void onHardKeyboardStatusChange(boolean available);
+ }
+
+ /**
* Request that the window manager call
* {@link DisplayManagerInternal#performTraversalInTransactionFromWindowManager}
* within a surface transaction at a later time.
@@ -231,4 +238,29 @@
* @param listener The listener to register.
*/
public abstract void registerAppTransitionListener(AppTransitionListener listener);
+
+ /**
+ * Retrieves a height of input method window.
+ */
+ public abstract int getInputMethodWindowVisibleHeight();
+
+ /**
+ * Saves last input method window for transition.
+ *
+ * Note that it is assumed that this method is called only by InputMethodManagerService.
+ */
+ public abstract void saveLastInputMethodWindowForTransition();
+
+ /**
+ * Returns true when the hardware keyboard is available.
+ */
+ public abstract boolean isHardKeyboardAvailable();
+
+ /**
+ * Sets the callback listener for hardware keyboard status changes.
+ *
+ * @param listener The listener to set.
+ */
+ public abstract void setOnHardKeyboardStatusChangeListener(
+ OnHardKeyboardStatusChangeListener listener);
}
diff --git a/core/java/android/widget/ImageView.java b/core/java/android/widget/ImageView.java
index 20fe61d..b53af0c 100644
--- a/core/java/android/widget/ImageView.java
+++ b/core/java/android/widget/ImageView.java
@@ -72,6 +72,8 @@
*/
@RemoteView
public class ImageView extends View {
+ private static final String LOG_TAG = "ImageView";
+
// settable by the client
private Uri mUri;
private int mResource = 0;
@@ -87,7 +89,7 @@
private boolean mHasColorFilter = false;
private Xfermode mXfermode;
private int mAlpha = 255;
- private int mViewAlphaScale = 256;
+ private final int mViewAlphaScale = 256;
private boolean mColorMod = false;
private Drawable mDrawable = null;
@@ -105,8 +107,8 @@
private Matrix mDrawMatrix = null;
// Avoid allocations...
- private RectF mTempSrc = new RectF();
- private RectF mTempDst = new RectF();
+ private final RectF mTempSrc = new RectF();
+ private final RectF mTempDst = new RectF();
private boolean mCropToPadding;
@@ -116,6 +118,9 @@
// AdjustViewBounds behavior will be in compatibility mode for older apps.
private boolean mAdjustViewBoundsCompat = false;
+ /** Whether to pass Resources when creating the source from a stream. */
+ private boolean mUseCorrectStreamDensity;
+
private static final ScaleType[] sScaleTypeArray = {
ScaleType.MATRIX,
ScaleType.FIT_XY,
@@ -147,30 +152,21 @@
initImageView();
final TypedArray a = context.obtainStyledAttributes(
- attrs, com.android.internal.R.styleable.ImageView, defStyleAttr, defStyleRes);
+ attrs, R.styleable.ImageView, defStyleAttr, defStyleRes);
- Drawable d = a.getDrawable(com.android.internal.R.styleable.ImageView_src);
+ final Drawable d = a.getDrawable(R.styleable.ImageView_src);
if (d != null) {
setImageDrawable(d);
}
- mBaselineAlignBottom = a.getBoolean(
- com.android.internal.R.styleable.ImageView_baselineAlignBottom, false);
+ mBaselineAlignBottom = a.getBoolean(R.styleable.ImageView_baselineAlignBottom, false);
+ mBaseline = a.getDimensionPixelSize(R.styleable.ImageView_baseline, -1);
- mBaseline = a.getDimensionPixelSize(
- com.android.internal.R.styleable.ImageView_baseline, -1);
+ setAdjustViewBounds(a.getBoolean(R.styleable.ImageView_adjustViewBounds, false));
+ setMaxWidth(a.getDimensionPixelSize(R.styleable.ImageView_maxWidth, Integer.MAX_VALUE));
+ setMaxHeight(a.getDimensionPixelSize(R.styleable.ImageView_maxHeight, Integer.MAX_VALUE));
- setAdjustViewBounds(
- a.getBoolean(com.android.internal.R.styleable.ImageView_adjustViewBounds,
- false));
-
- setMaxWidth(a.getDimensionPixelSize(
- com.android.internal.R.styleable.ImageView_maxWidth, Integer.MAX_VALUE));
-
- setMaxHeight(a.getDimensionPixelSize(
- com.android.internal.R.styleable.ImageView_maxHeight, Integer.MAX_VALUE));
-
- final int index = a.getInt(com.android.internal.R.styleable.ImageView_scaleType, -1);
+ final int index = a.getInt(R.styleable.ImageView_scaleType, -1);
if (index >= 0) {
setScaleType(sScaleTypeArray[index]);
}
@@ -193,24 +189,26 @@
applyImageTint();
- final int alpha = a.getInt(com.android.internal.R.styleable.ImageView_drawableAlpha, 255);
+ final int alpha = a.getInt(R.styleable.ImageView_drawableAlpha, 255);
if (alpha != 255) {
- setAlpha(alpha);
+ setImageAlpha(alpha);
}
mCropToPadding = a.getBoolean(
- com.android.internal.R.styleable.ImageView_cropToPadding, false);
-
+ R.styleable.ImageView_cropToPadding, false);
+
a.recycle();
//need inflate syntax/reader for matrix
}
private void initImageView() {
- mMatrix = new Matrix();
- mScaleType = ScaleType.FIT_CENTER;
- mAdjustViewBoundsCompat = mContext.getApplicationInfo().targetSdkVersion <=
- Build.VERSION_CODES.JELLY_BEAN_MR1;
+ mMatrix = new Matrix();
+ mScaleType = ScaleType.FIT_CENTER;
+
+ final int targetSdkVersion = mContext.getApplicationInfo().targetSdkVersion;
+ mAdjustViewBoundsCompat = targetSdkVersion <= Build.VERSION_CODES.JELLY_BEAN_MR1;
+ mUseCorrectStreamDensity = targetSdkVersion > Build.VERSION_CODES.M;
}
@Override
@@ -258,7 +256,8 @@
@Override
public void onPopulateAccessibilityEventInternal(AccessibilityEvent event) {
super.onPopulateAccessibilityEventInternal(event);
- CharSequence contentDescription = getContentDescription();
+
+ final CharSequence contentDescription = getContentDescription();
if (!TextUtils.isEmpty(contentDescription)) {
event.getText().add(contentDescription);
}
@@ -269,7 +268,7 @@
* to preserve the aspect ratio of its drawable
*
* @return whether to adjust the bounds of this view
- * to presrve the original aspect ratio of the drawable
+ * to preserve the original aspect ratio of the drawable
*
* @see #setAdjustViewBounds(boolean)
*
@@ -291,7 +290,7 @@
*
* @param adjustViewBounds Whether to adjust the bounds of this view
* to preserve the original aspect ratio of the drawable.
- *
+ *
* @see #getAdjustViewBounds()
*
* @attr ref android.R.styleable#ImageView_adjustViewBounds
@@ -323,14 +322,14 @@
* of 100 x 100 while preserving the original aspect ratio, do the following: 1) set
* adjustViewBounds to true 2) set maxWidth and maxHeight to 100 3) set the height and width
* layout params to WRAP_CONTENT.
- *
+ *
* <p>
* Note that this view could be still smaller than 100 x 100 using this approach if the original
* image is small. To set an image to a fixed size, specify that size in the layout params and
* then use {@link #setScaleType(android.widget.ImageView.ScaleType)} to determine how to fit
* the image within the bounds.
* </p>
- *
+ *
* @param maxWidth maximum width for this view
*
* @see #getMaxWidth()
@@ -361,14 +360,14 @@
* maximum of 100 x 100 while preserving the original aspect ratio, do the following: 1) set
* adjustViewBounds to true 2) set maxWidth and maxHeight to 100 3) set the height and width
* layout params to WRAP_CONTENT.
- *
+ *
* <p>
* Note that this view could be still smaller than 100 x 100 using this approach if the original
* image is small. To set an image to a fixed size, specify that size in the layout params and
* then use {@link #setScaleType(android.widget.ImageView.ScaleType)} to determine how to fit
* the image within the bounds.
* </p>
- *
+ *
* @param maxHeight maximum height for this view
*
* @see #getMaxHeight()
@@ -436,9 +435,7 @@
*/
@android.view.RemotableViewMethod
public void setImageURI(@Nullable Uri uri) {
- if (mResource != 0 ||
- (mUri != uri &&
- (uri == null || mUri == null || !uri.equals(mUri)))) {
+ if (mResource != 0 || (mUri != uri && (uri == null || mUri == null || !uri.equals(mUri)))) {
updateDrawable(null);
mResource = 0;
mUri = uri;
@@ -457,7 +454,7 @@
/**
* Sets a drawable as the content of this ImageView.
- *
+ *
* @param drawable the Drawable to set, or {@code null} to clear the
* content
*/
@@ -577,7 +574,7 @@
/**
* Sets a Bitmap as the content of this ImageView.
- *
+ *
* @param bm The bitmap to set
*/
@android.view.RemotableViewMethod
@@ -609,7 +606,7 @@
}
/**
- * Sets the image level, when it is constructed from a
+ * Sets the image level, when it is constructed from a
* {@link android.graphics.drawable.LevelListDrawable}.
*
* @param level The new level for the image.
@@ -675,7 +672,7 @@
* From XML, use this syntax: <code>android:scaleType="centerInside"</code>.
*/
CENTER_INSIDE (7);
-
+
ScaleType(int ni) {
nativeInt = ni;
}
@@ -685,9 +682,9 @@
/**
* Controls how the image should be resized or moved to match the size
* of this ImageView.
- *
+ *
* @param scaleType The desired scaling mode.
- *
+ *
* @attr ref android.R.styleable#ImageView_scaleType
*/
public void setScaleType(ScaleType scaleType) {
@@ -698,13 +695,13 @@
if (mScaleType != scaleType) {
mScaleType = scaleType;
- setWillNotCacheDrawing(mScaleType == ScaleType.CENTER);
+ setWillNotCacheDrawing(mScaleType == ScaleType.CENTER);
requestLayout();
invalidate();
}
}
-
+
/**
* Return the current scale type in use by this ImageView.
*
@@ -734,7 +731,7 @@
* Adds a transformation {@link Matrix} that is applied
* to the view's drawable when it is drawn. Allows custom scaling,
* translation, and perspective distortion.
- *
+ *
* @param matrix the transformation parameters in matrix form
*/
public void setImageMatrix(Matrix matrix) {
@@ -787,8 +784,8 @@
return;
}
- Resources rsrc = getResources();
- if (rsrc == null) {
+ final Resources res = getResources();
+ if (res == null) {
return;
}
@@ -798,12 +795,12 @@
try {
d = mContext.getDrawable(mResource);
} catch (Exception e) {
- Log.w("ImageView", "Unable to find resource: " + mResource, e);
+ Log.w(LOG_TAG, "Unable to find resource: " + mResource, e);
// Don't try again.
mUri = null;
}
} else if (mUri != null) {
- String scheme = mUri.getScheme();
+ final String scheme = mUri.getScheme();
if (ContentResolver.SCHEME_ANDROID_RESOURCE.equals(scheme)) {
try {
// Load drawable through Resources, to get the source density information
@@ -811,31 +808,32 @@
mContext.getContentResolver().getResourceId(mUri);
d = r.r.getDrawable(r.id, mContext.getTheme());
} catch (Exception e) {
- Log.w("ImageView", "Unable to open content: " + mUri, e);
+ Log.w(LOG_TAG, "Unable to open content: " + mUri, e);
}
} else if (ContentResolver.SCHEME_CONTENT.equals(scheme)
|| ContentResolver.SCHEME_FILE.equals(scheme)) {
InputStream stream = null;
try {
stream = mContext.getContentResolver().openInputStream(mUri);
- d = Drawable.createFromStream(stream, null);
+ d = Drawable.createFromResourceStream(
+ mUseCorrectStreamDensity ? res : null, null, stream, null);
} catch (Exception e) {
- Log.w("ImageView", "Unable to open content: " + mUri, e);
+ Log.w(LOG_TAG, "Unable to open content: " + mUri, e);
} finally {
if (stream != null) {
try {
stream.close();
} catch (IOException e) {
- Log.w("ImageView", "Unable to close content: " + mUri, e);
+ Log.w(LOG_TAG, "Unable to close content: " + mUri, e);
}
}
}
- } else {
+ } else {
d = Drawable.createFromPath(mUri.toString());
}
-
+
if (d == null) {
- System.out.println("resolveUri failed on bad bitmap uri: " + mUri);
+ Log.w(LOG_TAG, "resolveUri failed on bad bitmap uri: " + mUri);
// Don't try again.
mUri = null;
}
@@ -890,7 +888,7 @@
}
private void resizeFromDrawable() {
- Drawable d = mDrawable;
+ final Drawable d = mDrawable;
if (d != null) {
int w = d.getIntrinsicWidth();
if (w < 0) w = mDrawableWidth;
@@ -923,23 +921,23 @@
private static Matrix.ScaleToFit scaleTypeToScaleToFit(ScaleType st) {
// ScaleToFit enum to their corresponding Matrix.ScaleToFit values
return sS2FArray[st.nativeInt - 1];
- }
+ }
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
resolveUri();
int w;
int h;
-
+
// Desired aspect ratio of the view's contents (not including padding)
float desiredAspect = 0.0f;
-
+
// We are allowed to change the view's width
boolean resizeWidth = false;
-
+
// We are allowed to change the view's height
boolean resizeHeight = false;
-
+
final int widthSpecMode = MeasureSpec.getMode(widthMeasureSpec);
final int heightSpecMode = MeasureSpec.getMode(heightMeasureSpec);
@@ -959,15 +957,15 @@
if (mAdjustViewBounds) {
resizeWidth = widthSpecMode != MeasureSpec.EXACTLY;
resizeHeight = heightSpecMode != MeasureSpec.EXACTLY;
-
+
desiredAspect = (float) w / (float) h;
}
}
-
- int pleft = mPaddingLeft;
- int pright = mPaddingRight;
- int ptop = mPaddingTop;
- int pbottom = mPaddingBottom;
+
+ final int pleft = mPaddingLeft;
+ final int pright = mPaddingRight;
+ final int ptop = mPaddingTop;
+ final int pbottom = mPaddingBottom;
int widthSize;
int heightSize;
@@ -975,7 +973,7 @@
if (resizeWidth || resizeHeight) {
/* If we get here, it means we want to resize to match the
drawables aspect ratio, and we have the freedom to change at
- least one dimension.
+ least one dimension.
*/
// Get the max possible width given our constraints
@@ -986,13 +984,13 @@
if (desiredAspect != 0.0f) {
// See what our actual aspect ratio is
- float actualAspect = (float)(widthSize - pleft - pright) /
+ final float actualAspect = (float)(widthSize - pleft - pright) /
(heightSize - ptop - pbottom);
-
+
if (Math.abs(actualAspect - desiredAspect) > 0.0000001) {
-
+
boolean done = false;
-
+
// Try adjusting width to be proportional to height
if (resizeWidth) {
int newWidth = (int)(desiredAspect * (heightSize - ptop - pbottom)) +
@@ -1006,9 +1004,9 @@
if (newWidth <= widthSize) {
widthSize = newWidth;
done = true;
- }
+ }
}
-
+
// Try adjusting height to be proportional to width
if (!done && resizeHeight) {
int newHeight = (int)((widthSize - pleft - pright) / desiredAspect) +
@@ -1033,7 +1031,7 @@
*/
w += pleft + pright;
h += ptop + pbottom;
-
+
w = Math.max(w, getSuggestedMinimumWidth());
h = Math.max(h, getSuggestedMinimumHeight());
@@ -1047,8 +1045,8 @@
private int resolveAdjustedSize(int desiredSize, int maxSize,
int measureSpec) {
int result = desiredSize;
- int specMode = MeasureSpec.getMode(measureSpec);
- int specSize = MeasureSpec.getSize(measureSpec);
+ final int specMode = MeasureSpec.getMode(measureSpec);
+ final int specSize = MeasureSpec.getSize(measureSpec);
switch (specMode) {
case MeasureSpec.UNSPECIFIED:
/* Parent says we can be as big as we want. Just don't be larger
@@ -1057,8 +1055,8 @@
result = Math.min(desiredSize, maxSize);
break;
case MeasureSpec.AT_MOST:
- // Parent says we can be as big as we want, up to specSize.
- // Don't be larger than specSize, and don't be larger than
+ // Parent says we can be as big as we want, up to specSize.
+ // Don't be larger than specSize, and don't be larger than
// the max size imposed on ourselves.
result = Math.min(Math.min(desiredSize, specSize), maxSize);
break;
@@ -1072,7 +1070,7 @@
@Override
protected boolean setFrame(int l, int t, int r, int b) {
- boolean changed = super.setFrame(l, t, r, b);
+ final boolean changed = super.setFrame(l, t, r, b);
mHaveFrame = true;
configureBounds();
return changed;
@@ -1083,14 +1081,14 @@
return;
}
- int dwidth = mDrawableWidth;
- int dheight = mDrawableHeight;
+ final int dwidth = mDrawableWidth;
+ final int dheight = mDrawableHeight;
- int vwidth = getWidth() - mPaddingLeft - mPaddingRight;
- int vheight = getHeight() - mPaddingTop - mPaddingBottom;
+ final int vwidth = getWidth() - mPaddingLeft - mPaddingRight;
+ final int vheight = getHeight() - mPaddingTop - mPaddingBottom;
- boolean fits = (dwidth < 0 || vwidth == dwidth) &&
- (dheight < 0 || vheight == dheight);
+ final boolean fits = (dwidth < 0 || vwidth == dwidth)
+ && (dheight < 0 || vheight == dheight);
if (dwidth <= 0 || dheight <= 0 || ScaleType.FIT_XY == mScaleType) {
/* If the drawable has no intrinsic size, or we're told to
@@ -1125,7 +1123,7 @@
float dx = 0, dy = 0;
if (dwidth * vheight > vwidth * dheight) {
- scale = (float) vheight / (float) dheight;
+ scale = (float) vheight / (float) dheight;
dx = (vwidth - dwidth * scale) * 0.5f;
} else {
scale = (float) vwidth / (float) dwidth;
@@ -1139,14 +1137,14 @@
float scale;
float dx;
float dy;
-
+
if (dwidth <= vwidth && dheight <= vheight) {
scale = 1.0f;
} else {
scale = Math.min((float) vwidth / (float) dwidth,
(float) vheight / (float) dheight);
}
-
+
dx = Math.round((vwidth - dwidth * scale) * 0.5f);
dy = Math.round((vheight - dheight * scale) * 0.5f);
@@ -1156,7 +1154,7 @@
// Generate the required transform.
mTempSrc.set(0, 0, dwidth, dheight);
mTempDst.set(0, 0, vwidth, vheight);
-
+
mDrawMatrix = mMatrix;
mDrawMatrix.setRectToRect(mTempSrc, mTempDst, scaleTypeToScaleToFit(mScaleType));
}
@@ -1166,7 +1164,8 @@
@Override
protected void drawableStateChanged() {
super.drawableStateChanged();
- Drawable d = mDrawable;
+
+ final Drawable d = mDrawable;
if (d != null && d.isStateful()) {
d.setState(getDrawableState());
}
@@ -1213,9 +1212,9 @@
if (mDrawMatrix == null && mPaddingTop == 0 && mPaddingLeft == 0) {
mDrawable.draw(canvas);
} else {
- int saveCount = canvas.getSaveCount();
+ final int saveCount = canvas.getSaveCount();
canvas.save();
-
+
if (mCropToPadding) {
final int scrollX = mScrollX;
final int scrollY = mScrollY;
@@ -1223,7 +1222,7 @@
scrollX + mRight - mLeft - mPaddingRight,
scrollY + mBottom - mTop - mPaddingBottom);
}
-
+
canvas.translate(mPaddingLeft, mPaddingTop);
if (mDrawMatrix != null) {
@@ -1258,7 +1257,7 @@
*
* @param baseline The baseline to use, or -1 if none is to be provided.
*
- * @see #setBaseline(int)
+ * @see #setBaseline(int)
* @attr ref android.R.styleable#ImageView_baseline
*/
public void setBaseline(int baseline) {
@@ -1295,11 +1294,11 @@
/**
* Set a tinting option for the image.
- *
+ *
* @param color Color tint to apply.
* @param mode How to apply the color. The standard mode is
* {@link PorterDuff.Mode#SRC_ATOP}
- *
+ *
* @attr ref android.R.styleable#ImageView_tint
*/
public final void setColorFilter(int color, PorterDuff.Mode mode) {
diff --git a/core/java/android/widget/LinearLayout.java b/core/java/android/widget/LinearLayout.java
index b5e08ca..ad939be 100644
--- a/core/java/android/widget/LinearLayout.java
+++ b/core/java/android/widget/LinearLayout.java
@@ -25,6 +25,7 @@
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.drawable.Drawable;
+import android.os.Build;
import android.util.AttributeSet;
import android.view.Gravity;
import android.view.View;
@@ -99,6 +100,13 @@
public static final int SHOW_DIVIDER_END = 4;
/**
+ * Compatibility check. Old versions of the platform would give different
+ * results from measurement passes using EXACTLY and non-EXACTLY modes,
+ * even when the resulting size was the same.
+ */
+ private final boolean mAllowInconsistentMeasurement;
+
+ /**
* Whether the children of this layout are baseline aligned. Only applicable
* if {@link #mOrientation} is horizontal.
*/
@@ -231,6 +239,9 @@
mShowDividers = a.getInt(R.styleable.LinearLayout_showDividers, SHOW_DIVIDER_NONE);
mDividerPadding = a.getDimensionPixelSize(R.styleable.LinearLayout_dividerPadding, 0);
+ final int version = context.getApplicationInfo().targetSdkVersion;
+ mAllowInconsistentMeasurement = version <= Build.VERSION_CODES.M;
+
a.recycle();
}
@@ -699,6 +710,7 @@
final boolean useLargestChild = mUseLargestChild;
int largestChildHeight = Integer.MIN_VALUE;
+ int consumedExcessSpace = 0;
// See how tall everyone is. Also remember max width.
for (int i = 0; i < count; ++i) {
@@ -718,26 +730,25 @@
mTotalLength += mDividerHeight;
}
- LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) child.getLayoutParams();
+ final LayoutParams lp = (LayoutParams) child.getLayoutParams();
totalWeight += lp.weight;
-
- if (heightMode == MeasureSpec.EXACTLY && lp.height == 0 && lp.weight > 0) {
- // Optimization: don't bother measuring children who are going to use
- // leftover space. These views will get measured again down below if
- // there is any leftover space.
+
+ final boolean useExcessSpace = lp.height == 0 && lp.weight > 0;
+ if (heightMode == MeasureSpec.EXACTLY && useExcessSpace) {
+ // Optimization: don't bother measuring children who are only
+ // laid out using excess space. These views will get measured
+ // later if we have space to distribute.
final int totalLength = mTotalLength;
mTotalLength = Math.max(totalLength, totalLength + lp.topMargin + lp.bottomMargin);
skippedMeasure = true;
} else {
- int oldHeight = Integer.MIN_VALUE;
-
- if (lp.height == 0 && lp.weight > 0) {
- // heightMode is either UNSPECIFIED or AT_MOST, and this
- // child wanted to stretch to fill available space.
- // Translate that to WRAP_CONTENT so that it does not end up
- // with a height of 0
- oldHeight = 0;
+ if (useExcessSpace) {
+ // The heightMode is either UNSPECIFIED or AT_MOST, and
+ // this child is only laid out using excess space. Measure
+ // using WRAP_CONTENT so that we can find out the view's
+ // optimal height. We'll restore the original height of 0
+ // after measurement.
lp.height = LayoutParams.WRAP_CONTENT;
}
@@ -745,15 +756,19 @@
// previous children have given a weight, then we allow it to
// use all available space (and we will shrink things later
// if needed).
- measureChildBeforeLayout(
- child, i, widthMeasureSpec, 0, heightMeasureSpec,
- totalWeight == 0 ? mTotalLength : 0);
-
- if (oldHeight != Integer.MIN_VALUE) {
- lp.height = oldHeight;
- }
+ final int usedHeight = totalWeight == 0 ? mTotalLength : 0;
+ measureChildBeforeLayout(child, i, widthMeasureSpec, 0,
+ heightMeasureSpec, usedHeight);
final int childHeight = child.getMeasuredHeight();
+ if (useExcessSpace) {
+ // Restore the original height and record how much space
+ // we've allocated to excess-only children so that we can
+ // match the behavior of EXACTLY measurement.
+ lp.height = 0;
+ consumedExcessSpace += childHeight;
+ }
+
final int totalLength = mTotalLength;
mTotalLength = Math.max(totalLength, totalLength + childHeight + lp.topMargin +
lp.bottomMargin + getNextLocationOffset(child));
@@ -857,52 +872,42 @@
// Either expand children with weight to take up available space or
// shrink them if they extend beyond our current bounds. If we skipped
// measurement on any children, we need to measure them now.
- int delta = heightSize - mTotalLength;
+ final int delta = heightSize - mTotalLength
+ + (mAllowInconsistentMeasurement ? 0 : consumedExcessSpace);
if (skippedMeasure || delta != 0 && totalWeight > 0.0f) {
- float weightSum = mWeightSum > 0.0f ? mWeightSum : totalWeight;
+ final float weightSum = mWeightSum > 0.0f ? mWeightSum : totalWeight;
mTotalLength = 0;
for (int i = 0; i < count; ++i) {
final View child = getVirtualChildAt(i);
-
- if (child.getVisibility() == View.GONE) {
+ if (child == null || child.getVisibility() == View.GONE) {
continue;
}
-
- LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) child.getLayoutParams();
-
- float childExtra = lp.weight;
+
+ final LayoutParams lp = (LayoutParams) child.getLayoutParams();
+ final float childExtra = lp.weight;
if (childExtra > 0) {
- // Child said it could absorb extra space -- give him his share
- int share = (int) (childExtra * delta / weightSum);
- weightSum -= childExtra;
- delta -= share;
-
- final int childWidthMeasureSpec = getChildMeasureSpec(widthMeasureSpec,
- mPaddingLeft + mPaddingRight +
- lp.leftMargin + lp.rightMargin, lp.width);
-
- // TODO: Use a field like lp.isMeasured to figure out if this
- // child has been previously measured
- if ((lp.height != 0) || (heightMode != MeasureSpec.EXACTLY)) {
- // child was measured once already above...
- // base new measurement on stored values
- int childHeight = child.getMeasuredHeight() + share;
- if (childHeight < 0) {
- childHeight = 0;
- }
-
- child.measure(childWidthMeasureSpec,
- MeasureSpec.makeMeasureSpec(childHeight, MeasureSpec.EXACTLY));
+ final int share = (int) (childExtra * delta / weightSum);
+ final int childHeight;
+ if (lp.height == 0 && (!mAllowInconsistentMeasurement
+ || heightMode == MeasureSpec.EXACTLY)) {
+ // This child needs to be laid out from scratch using
+ // only its share of excess space.
+ childHeight = share;
} else {
- // child was skipped in the loop above.
- // Measure for this first time here
- child.measure(childWidthMeasureSpec,
- MeasureSpec.makeMeasureSpec(share > 0 ? share : 0,
- MeasureSpec.EXACTLY));
+ // This child had some intrinsic height to which we
+ // need to add its share of excess space.
+ childHeight = child.getMeasuredHeight() + share;
}
+ final int childHeightMeasureSpec = MeasureSpec.makeMeasureSpec(
+ Math.max(0, childHeight), MeasureSpec.EXACTLY);
+ final int childWidthMeasureSpec = getChildMeasureSpec(widthMeasureSpec,
+ mPaddingLeft + mPaddingRight + lp.leftMargin + lp.rightMargin,
+ lp.width);
+ child.measure(childWidthMeasureSpec, childHeightMeasureSpec);
+
// Child may now not fit in vertical dimension.
childState = combineMeasuredStates(childState, child.getMeasuredState()
& (MEASURED_STATE_MASK>>MEASURED_HEIGHT_STATE_SHIFT));
@@ -1043,6 +1048,7 @@
final boolean isExactly = widthMode == MeasureSpec.EXACTLY;
int largestChildWidth = Integer.MIN_VALUE;
+ int usedExcessSpace = 0;
// See how wide everyone is. Also remember max height.
for (int i = 0; i < count; ++i) {
@@ -1062,15 +1068,15 @@
mTotalLength += mDividerWidth;
}
- final LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams)
- child.getLayoutParams();
+ final LayoutParams lp = (LayoutParams) child.getLayoutParams();
totalWeight += lp.weight;
-
- if (widthMode == MeasureSpec.EXACTLY && lp.width == 0 && lp.weight > 0) {
- // Optimization: don't bother measuring children who are going to use
- // leftover space. These views will get measured again down below if
- // there is any leftover space.
+
+ final boolean useExcessSpace = lp.width == 0 && lp.weight > 0;
+ if (widthMode == MeasureSpec.EXACTLY && useExcessSpace) {
+ // Optimization: don't bother measuring children who are only
+ // laid out using excess space. These views will get measured
+ // later if we have space to distribute.
if (isExactly) {
mTotalLength += lp.leftMargin + lp.rightMargin;
} else {
@@ -1094,14 +1100,12 @@
skippedMeasure = true;
}
} else {
- int oldWidth = Integer.MIN_VALUE;
-
- if (lp.width == 0 && lp.weight > 0) {
- // widthMode is either UNSPECIFIED or AT_MOST, and this
- // child
- // wanted to stretch to fill available space. Translate that to
- // WRAP_CONTENT so that it does not end up with a width of 0
- oldWidth = 0;
+ if (useExcessSpace) {
+ // The widthMode is either UNSPECIFIED or AT_MOST, and
+ // this child is only laid out using excess space. Measure
+ // using WRAP_CONTENT so that we can find out the view's
+ // optimal width. We'll restore the original width of 0
+ // after measurement.
lp.width = LayoutParams.WRAP_CONTENT;
}
@@ -1109,22 +1113,26 @@
// previous children have given a weight, then we allow it to
// use all available space (and we will shrink things later
// if needed).
- measureChildBeforeLayout(child, i, widthMeasureSpec,
- totalWeight == 0 ? mTotalLength : 0,
+ final int usedWidth = totalWeight == 0 ? mTotalLength : 0;
+ measureChildBeforeLayout(child, i, widthMeasureSpec, usedWidth,
heightMeasureSpec, 0);
- if (oldWidth != Integer.MIN_VALUE) {
- lp.width = oldWidth;
+ final int childWidth = child.getMeasuredWidth();
+ if (useExcessSpace) {
+ // Restore the original width and record how much space
+ // we've allocated to excess-only children so that we can
+ // match the behavior of EXACTLY measurement.
+ lp.width = 0;
+ usedExcessSpace += childWidth;
}
- final int childWidth = child.getMeasuredWidth();
if (isExactly) {
- mTotalLength += childWidth + lp.leftMargin + lp.rightMargin +
- getNextLocationOffset(child);
+ mTotalLength += childWidth + lp.leftMargin + lp.rightMargin
+ + getNextLocationOffset(child);
} else {
final int totalLength = mTotalLength;
- mTotalLength = Math.max(totalLength, totalLength + childWidth + lp.leftMargin +
- lp.rightMargin + getNextLocationOffset(child));
+ mTotalLength = Math.max(totalLength, totalLength + childWidth + lp.leftMargin
+ + lp.rightMargin + getNextLocationOffset(child));
}
if (useLargestChild) {
@@ -1242,9 +1250,10 @@
// Either expand children with weight to take up available space or
// shrink them if they extend beyond our current bounds. If we skipped
// measurement on any children, we need to measure them now.
- int delta = widthSize - mTotalLength;
+ final int delta = widthSize - mTotalLength
+ + (mAllowInconsistentMeasurement ? 0 : usedExcessSpace);
if (skippedMeasure || delta != 0 && totalWeight > 0.0f) {
- float weightSum = mWeightSum > 0.0f ? mWeightSum : totalWeight;
+ final float weightSum = mWeightSum > 0.0f ? mWeightSum : totalWeight;
maxAscent[0] = maxAscent[1] = maxAscent[2] = maxAscent[3] = -1;
maxDescent[0] = maxDescent[1] = maxDescent[2] = maxDescent[3] = -1;
@@ -1254,45 +1263,32 @@
for (int i = 0; i < count; ++i) {
final View child = getVirtualChildAt(i);
-
if (child == null || child.getVisibility() == View.GONE) {
continue;
}
-
- final LinearLayout.LayoutParams lp =
- (LinearLayout.LayoutParams) child.getLayoutParams();
- float childExtra = lp.weight;
+ final LayoutParams lp = (LayoutParams) child.getLayoutParams();
+ final float childExtra = lp.weight;
if (childExtra > 0) {
- // Child said it could absorb extra space -- give him his share
- int share = (int) (childExtra * delta / weightSum);
- weightSum -= childExtra;
- delta -= share;
+ final int share = (int) (childExtra * delta / weightSum);
+ final int childWidth;
+ if (lp.width == 0 && (!mAllowInconsistentMeasurement
+ || widthMode == MeasureSpec.EXACTLY)) {
+ // This child needs to be laid out from scratch using
+ // only its share of excess space.
+ childWidth = share;
+ } else {
+ // This child had some intrinsic width to which we
+ // need to add its share of excess space.
+ childWidth = child.getMeasuredWidth() + share;
+ }
- final int childHeightMeasureSpec = getChildMeasureSpec(
- heightMeasureSpec,
+ final int childWidthMeasureSpec = MeasureSpec.makeMeasureSpec(
+ Math.max(0, childWidth), MeasureSpec.EXACTLY);
+ final int childHeightMeasureSpec = getChildMeasureSpec(heightMeasureSpec,
mPaddingTop + mPaddingBottom + lp.topMargin + lp.bottomMargin,
lp.height);
-
- // TODO: Use a field like lp.isMeasured to figure out if this
- // child has been previously measured
- if ((lp.width != 0) || (widthMode != MeasureSpec.EXACTLY)) {
- // child was measured once already above ... base new measurement
- // on stored values
- int childWidth = child.getMeasuredWidth() + share;
- if (childWidth < 0) {
- childWidth = 0;
- }
-
- child.measure(
- MeasureSpec.makeMeasureSpec(childWidth, MeasureSpec.EXACTLY),
- childHeightMeasureSpec);
- } else {
- // child was skipped in the loop above. Measure for this first time here
- child.measure(MeasureSpec.makeMeasureSpec(
- share > 0 ? share : 0, MeasureSpec.EXACTLY),
- childHeightMeasureSpec);
- }
+ child.measure(childWidthMeasureSpec, childHeightMeasureSpec);
// Child may now not fit in horizontal dimension.
childState = combineMeasuredStates(childState,
diff --git a/core/java/android/widget/SearchView.java b/core/java/android/widget/SearchView.java
index 088adbb..ad2b4a7 100644
--- a/core/java/android/widget/SearchView.java
+++ b/core/java/android/widget/SearchView.java
@@ -816,7 +816,15 @@
mSearchButton.setVisibility(visCollapsed);
updateSubmitButton(hasText);
mSearchEditFrame.setVisibility(collapsed ? GONE : VISIBLE);
- mCollapsedIcon.setVisibility(mIconifiedByDefault ? GONE : VISIBLE);
+
+ final int iconVisibility;
+ if (mCollapsedIcon.getDrawable() == null || mIconifiedByDefault) {
+ iconVisibility = GONE;
+ } else {
+ iconVisibility = VISIBLE;
+ }
+ mCollapsedIcon.setVisibility(iconVisibility);
+
updateCloseButton();
updateVoiceButton(!hasText);
updateSubmitArea();
diff --git a/core/java/com/android/internal/widget/LockPatternUtils.java b/core/java/com/android/internal/widget/LockPatternUtils.java
index 1995694..0579ce7d 100644
--- a/core/java/com/android/internal/widget/LockPatternUtils.java
+++ b/core/java/com/android/internal/widget/LockPatternUtils.java
@@ -1284,6 +1284,12 @@
*/
public static final int SOME_AUTH_REQUIRED_AFTER_USER_REQUEST = 0x4;
+ /**
+ * Strong authentication is required because the user has been locked out after too many
+ * attempts.
+ */
+ public static final int STRONG_AUTH_REQUIRED_AFTER_LOCKOUT = 0x8;
+
public static final int DEFAULT = STRONG_AUTH_REQUIRED_AFTER_BOOT;
private static final int ALLOWING_FINGERPRINT = SOME_AUTH_REQUIRED_AFTER_USER_REQUEST;
diff --git a/core/jni/android_media_AudioErrors.h b/core/jni/android_media_AudioErrors.h
index 4907830..c17a020 100644
--- a/core/jni/android_media_AudioErrors.h
+++ b/core/jni/android_media_AudioErrors.h
@@ -32,6 +32,7 @@
AUDIO_JAVA_PERMISSION_DENIED = -4,
AUDIO_JAVA_NO_INIT = -5,
AUDIO_JAVA_DEAD_OBJECT = -6,
+ AUDIO_JAVA_WOULD_BLOCK = -7,
};
static inline jint nativeToJavaStatus(status_t status) {
@@ -46,6 +47,8 @@
return AUDIO_JAVA_PERMISSION_DENIED;
case NO_INIT:
return AUDIO_JAVA_NO_INIT;
+ case WOULD_BLOCK:
+ return AUDIO_JAVA_WOULD_BLOCK;
case DEAD_OBJECT:
return AUDIO_JAVA_DEAD_OBJECT;
default:
diff --git a/core/jni/android_view_GraphicBuffer.cpp b/core/jni/android_view_GraphicBuffer.cpp
index aa79d70..17d2a5e 100644
--- a/core/jni/android_view_GraphicBuffer.cpp
+++ b/core/jni/android_view_GraphicBuffer.cpp
@@ -158,7 +158,7 @@
sp<GraphicBuffer> buffer(wrapper->buffer);
- Rect rect;
+ Rect rect(Rect::EMPTY_RECT);
if (dirtyRect) {
rect.left = GET_INT(dirtyRect, gRectClassInfo.left);
rect.top = GET_INT(dirtyRect, gRectClassInfo.top);
diff --git a/core/jni/android_view_Surface.cpp b/core/jni/android_view_Surface.cpp
index abd2409..4a311d31 100644
--- a/core/jni/android_view_Surface.cpp
+++ b/core/jni/android_view_Surface.cpp
@@ -292,7 +292,7 @@
return 0;
}
- Rect dirtyRect;
+ Rect dirtyRect(Rect::EMPTY_RECT);
Rect* dirtyRectPtr = NULL;
if (dirtyRectObj) {
diff --git a/core/jni/android_view_TextureView.cpp b/core/jni/android_view_TextureView.cpp
index 7e05793..beb83b1 100644
--- a/core/jni/android_view_TextureView.cpp
+++ b/core/jni/android_view_TextureView.cpp
@@ -142,7 +142,7 @@
ANativeWindow_Buffer buffer;
- Rect rect;
+ Rect rect(Rect::EMPTY_RECT);
if (dirtyRect) {
rect.left = GET_INT(dirtyRect, gRectClassInfo.left);
rect.top = GET_INT(dirtyRect, gRectClassInfo.top);
diff --git a/core/res/res/values-mcc219-mnc02/config.xml b/core/res/res/values-mcc219-mnc02/config.xml
new file mode 100644
index 0000000..2ac6ba6
--- /dev/null
+++ b/core/res/res/values-mcc219-mnc02/config.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2015, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- Don't use roaming icon for considered operators -->
+ <string-array translatable="false" name="config_operatorConsideredNonRoaming">
+ <item>21901</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml
index cfdd69b..d77dca1f 100644
--- a/core/res/res/values-nl/strings.xml
+++ b/core/res/res/values-nl/strings.xml
@@ -39,7 +39,7 @@
<string name="durationMinuteSecond" msgid="3989228718067466680">"<xliff:g id="MINUTES">%1$d</xliff:g> min <xliff:g id="SECONDS">%2$d</xliff:g> sec"</string>
<string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> seconden"</string>
<string name="durationSecond" msgid="985669622276420331">"<xliff:g id="SECONDS">%1$d</xliff:g> seconde"</string>
- <string name="untitled" msgid="4638956954852782576">"<Zonder titel>"</string>
+ <string name="untitled" msgid="4638956954852782576">"<Naamloos>"</string>
<string name="emptyPhoneNumber" msgid="7694063042079676517">"(Geen telefoonnummer)"</string>
<string name="unknownName" msgid="6867811765370350269">"Onbekend"</string>
<string name="defaultVoiceMailAlphaTag" msgid="2660020990097733077">"Voicemail"</string>
diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml
index 2cf1d1e..d215d4c 100644
--- a/core/res/res/values-ro/strings.xml
+++ b/core/res/res/values-ro/strings.xml
@@ -50,7 +50,7 @@
<string name="serviceEnabledFor" msgid="6856228140453471041">"Serviciul a fost activat pentru:"</string>
<string name="serviceDisabled" msgid="1937553226592516411">"Serviciul a fost dezactivat."</string>
<string name="serviceRegistered" msgid="6275019082598102493">"Înregistrarea a reuşit."</string>
- <string name="serviceErased" msgid="1288584695297200972">"Ștergerea a reuşit."</string>
+ <string name="serviceErased" msgid="1288584695297200972">"Ștergerea a reușit."</string>
<string name="passwordIncorrect" msgid="7612208839450128715">"Parolă incorectă."</string>
<string name="mmiComplete" msgid="8232527495411698359">"MMI finalizat."</string>
<string name="badPin" msgid="9015277645546710014">"Codul PIN vechi introdus nu este corect."</string>
@@ -59,7 +59,7 @@
<string name="invalidPin" msgid="3850018445187475377">"Introduceţi un cod PIN alcătuit din 4 până la 8 cifre."</string>
<string name="invalidPuk" msgid="8761456210898036513">"Introduceţi un cod PUK care să aibă 8 cifre sau mai mult."</string>
<string name="needPuk" msgid="919668385956251611">"Cardul SIM este blocat cu codul PUK. Introduceţi codul PUK pentru a-l debloca."</string>
- <string name="needPuk2" msgid="4526033371987193070">"Introduceţi codul PUK2 pentru a debloca cardul SIM."</string>
+ <string name="needPuk2" msgid="4526033371987193070">"Introduceți codul PUK2 pentru a debloca cardul SIM."</string>
<string name="enablePin" msgid="209412020907207950">"Operațiunea nu a reușit. Activați blocarea cardului SIM/RUIM."</string>
<plurals name="pinpuk_attempts" formatted="false" msgid="1251012001539225582">
<item quantity="few">V-au mai rămas <xliff:g id="NUMBER_1">%d</xliff:g> încercări până la blocarea cardului SIM.</item>
@@ -85,8 +85,8 @@
<string name="DndMmi" msgid="1265478932418334331">"Nu deranjaţi"</string>
<string name="CLIRDefaultOnNextCallOn" msgid="429415409145781923">"ID-ul apelantului este restricţionat în mod prestabilit. Apelul următor: restricţionat"</string>
<string name="CLIRDefaultOnNextCallOff" msgid="3092918006077864624">"ID-ul apelantului este restricționat în mod prestabilit. Apelul următor: nerestricționat"</string>
- <string name="CLIRDefaultOffNextCallOn" msgid="6179425182856418465">"ID-ul apelantului este nerestricţionat în mod prestabilit. Apelul următor: Restricţionat."</string>
- <string name="CLIRDefaultOffNextCallOff" msgid="2567998633124408552">"ID-ul apelantului este nerestricţionat în mod prestabilit. Apelul următor: nerestricţionat"</string>
+ <string name="CLIRDefaultOffNextCallOn" msgid="6179425182856418465">"ID-ul apelantului este nerestricționat în mod prestabilit. Apelul următor: Restricționat."</string>
+ <string name="CLIRDefaultOffNextCallOff" msgid="2567998633124408552">"ID-ul apelantului este nerestricționat în mod prestabilit. Apelul următor: nerestricționat"</string>
<string name="serviceNotProvisioned" msgid="8614830180508686666">"Nu se asigură accesul la acest serviciu."</string>
<string name="CLIRPermanent" msgid="3377371145926835671">"Nu puteți să modificaţi setarea pentru ID-ul apelantului."</string>
<string name="RestrictedChangedTitle" msgid="5592189398956187498">"Acces restricționat modificat"</string>
@@ -181,7 +181,7 @@
<string name="power_dialog" product="tv" msgid="6153888706430556356">"Opțiuni TV"</string>
<string name="power_dialog" product="default" msgid="1319919075463988638">"Opţiuni telefon"</string>
<string name="silent_mode" msgid="7167703389802618663">"Mod Silențios"</string>
- <string name="turn_on_radio" msgid="3912793092339962371">"Activați funcţia wireless"</string>
+ <string name="turn_on_radio" msgid="3912793092339962371">"Activați funcția wireless"</string>
<string name="turn_off_radio" msgid="8198784949987062346">"Dezactivați funcția wireless"</string>
<string name="screen_lock" msgid="799094655496098153">"Blocați ecranul"</string>
<string name="power_off" msgid="4266614107412865048">"Opriți alimentarea"</string>
@@ -266,9 +266,9 @@
<string name="permlab_processOutgoingCalls" msgid="3906007831192990946">"redirecţionează apelurile efectuate"</string>
<string name="permdesc_processOutgoingCalls" msgid="5156385005547315876">"Permite aplicației să vadă numărul format în timpul unui apel de ieșire, cu opțiunea de a redirecționa apelul către un alt număr sau de a întrerupe apelul."</string>
<string name="permlab_receiveSms" msgid="8673471768947895082">"primeşte mesaje text (SMS)"</string>
- <string name="permdesc_receiveSms" msgid="6424387754228766939">"Permite aplicației să primească și să proceseze mesaje SMS. Acest lucru înseamnă că aplicația ar putea monitoriza sau şterge mesajele trimise pe dispozitivul dvs. fără a vi le arăta."</string>
+ <string name="permdesc_receiveSms" msgid="6424387754228766939">"Permite aplicației să primească și să proceseze mesaje SMS. Acest lucru înseamnă că aplicația ar putea monitoriza sau șterge mesajele trimise pe dispozitivul dvs. fără a vi le arăta."</string>
<string name="permlab_receiveMms" msgid="1821317344668257098">"primeşte mesaje text (MMS)"</string>
- <string name="permdesc_receiveMms" msgid="533019437263212260">"Permite aplicației să primească și să proceseze mesaje MMS. Acest lucru înseamnă că aplicația ar putea monitoriza sau şterge mesajele trimise pe dispozitivul dvs. fără a vi le arăta."</string>
+ <string name="permdesc_receiveMms" msgid="533019437263212260">"Permite aplicației să primească și să proceseze mesaje MMS. Acest lucru înseamnă că aplicația ar putea monitoriza sau șterge mesajele trimise pe dispozitivul dvs. fără a vi le arăta."</string>
<string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"citeşte mesajele cu transmisie celulară"</string>
<string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"Permite aplicației să citească mesajele primite prin transmisie celulară de dispozitivul dvs. Alertele cu transmisie celulară sunt difuzate în unele locații pentru a vă avertiza cu privire la situaţiile de urgenţă. Aplicaţiile rău intenţionate pot afecta performanţa sau funcţionarea dispozitivului dvs. când este primită o transmisie celulară de urgenţă."</string>
<string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"citire feeduri abonat"</string>
@@ -280,7 +280,7 @@
<string name="permdesc_readSms" product="tv" msgid="5102425513647038535">"Permite aplicației să citească mesajele SMS stocate pe televizor sau pe cardul SIM. Cu această permisiune, aplicația poate citi toate mesajele SMS, indiferent de conținutul sau de gradul de confidențialitate al acestora."</string>
<string name="permdesc_readSms" product="default" msgid="3695967533457240550">"Permite aplicației să citească mesajele SMS stocate pe telefon sau pe cardul SIM. În acest fel, aplicația poate citi toate mesajele SMS, indiferent de conţinutul sau de gradul de confidenţialitate al acestora."</string>
<string name="permlab_receiveWapPush" msgid="5991398711936590410">"primeşte mesaje text (WAP)"</string>
- <string name="permdesc_receiveWapPush" msgid="748232190220583385">"Permite aplicației să primească și să proceseze mesaje WAP. Această permisiune include capacitatea de a monitoriza sau şterge mesajele care v-au fost trimise fără a vi le arăta."</string>
+ <string name="permdesc_receiveWapPush" msgid="748232190220583385">"Permite aplicației să primească și să proceseze mesaje WAP. Această permisiune include capacitatea de a monitoriza sau șterge mesajele care v-au fost trimise fără a vi le arăta."</string>
<string name="permlab_getTasks" msgid="6466095396623933906">"preluare aplicații care rulează"</string>
<string name="permdesc_getTasks" msgid="7454215995847658102">"Permite aplicației să preia informațiile despre activităţile care rulează în prezent și care au rulat recent. În acest fel, aplicația poate descoperi informații despre aplicațiile care sunt utilizate pe dispozitiv."</string>
<string name="permlab_manageProfileAndDeviceOwners" msgid="5979288447973722097">"Gestionează proprietarii de profiluri și proprietarul dispozitivului"</string>
@@ -314,17 +314,17 @@
<string name="permdesc_readContacts" product="tv" msgid="1839238344654834087">"Permite aplicației să citească datele despre persoanele de contact salvate pe televizor, inclusiv frecvența cu care ați apelat, ați trimis e-mailuri sau ați comunicat în alte moduri cu anumite persoane. Cu această permisiune, aplicațiile pot salva datele de contact, iar aplicațiile rău-intenționate pot permite accesul la datele de contact fără cunoștința dvs."</string>
<string name="permdesc_readContacts" product="default" msgid="8440654152457300662">"Permite aplicației să citească datele despre persoanele din agenda stocată pe telefon, inclusiv frecvenţa cu care aţi apelat, aţi trimis e-mailuri sau aţi comunicat în alte moduri cu anumite persoane. Cu această permisiune aplicația salvează datele dvs. de contact, iar aplicațiile rău intenţionate pot distribui datele de contact fără ştirea dvs."</string>
<string name="permlab_writeContacts" msgid="5107492086416793544">"modifică agenda"</string>
- <string name="permdesc_writeContacts" product="tablet" msgid="897243932521953602">"Permite aplicației să modifice datele despre persoanele din agenda stocată pe tabletă, inclusiv frecvenţa cu care aţi apelat, aţi trimis e-mailuri sau aţi comunicat în alte moduri cu anumite persoane din agendă. Cu această permisiune aplicația poate şterge datele de contact."</string>
+ <string name="permdesc_writeContacts" product="tablet" msgid="897243932521953602">"Permite aplicației să modifice datele despre persoanele din agenda stocată pe tabletă, inclusiv frecvenţa cu care aţi apelat, aţi trimis e-mailuri sau aţi comunicat în alte moduri cu anumite persoane din agendă. Cu această permisiune aplicația poate șterge datele de contact."</string>
<string name="permdesc_writeContacts" product="tv" msgid="5438230957000018959">"Permite aplicației să modifice datele despre persoanele de contact salvate pe televizor, inclusiv frecvența cu care ați apelat, ați trimis e-mailuri sau ați comunicat în alte moduri cu anumite persoane de contact. Cu această permisiune, aplicația poate șterge datele de contact."</string>
- <string name="permdesc_writeContacts" product="default" msgid="589869224625163558">"Permite aplicației să modifice datele despre persoanele din agenda stocată pe telefon, inclusiv frecvenţa cu care aţi apelat, aţi trimis e-mailuri sau aţi comunicat în alte moduri cu anumite persoane din agendă. Cu această permisiune aplicația poate şterge datele de contact."</string>
+ <string name="permdesc_writeContacts" product="default" msgid="589869224625163558">"Permite aplicației să modifice datele despre persoanele din agenda stocată pe telefon, inclusiv frecvenţa cu care aţi apelat, aţi trimis e-mailuri sau aţi comunicat în alte moduri cu anumite persoane din agendă. Cu această permisiune aplicația poate șterge datele de contact."</string>
<string name="permlab_readCallLog" msgid="3478133184624102739">"citeşte jurnalul de apeluri"</string>
<string name="permdesc_readCallLog" product="tablet" msgid="3700645184870760285">"Permite aplicației să citească jurnalul de apeluri al tabletei, inclusiv datele despre apelurile primite și efectuate. Cu această permisiune aplicația salvează datele dvs. din jurnalul de apeluri, iar aplicațiile rău intenţionate pot distribui aceste date fără ştirea dvs."</string>
<string name="permdesc_readCallLog" product="tv" msgid="5611770887047387926">"Permite aplicației să citească jurnalul de apeluri al televizorului, inclusiv datele despre apelurile primite și efectuate. Cu această permisiune, aplicațiile pot să salveze datele din jurnalul de apeluri, iar aplicațiile rău-intenționate pot permite accesul la datele din jurnalul de apeluri fără cunoștința dvs."</string>
<string name="permdesc_readCallLog" product="default" msgid="5777725796813217244">"Permite aplicației să citească jurnalul de apeluri al telefonului, inclusiv datele despre apelurile primite și efectuate. Cu această permisiune aplicația salvează datele dvs. din jurnalul de apeluri, iar aplicațiile rău intenţionate pot distribui aceste date fără ştirea dvs."</string>
<string name="permlab_writeCallLog" msgid="8552045664743499354">"scrie jurnalul de apeluri"</string>
- <string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"Permite aplicației să modifice jurnalul de apeluri al tabletei dvs., inclusiv datele despre apelurile primite sau efectuate. Aplicaţiile rău intenţionate pot utiliza această permisiune pentru a şterge sau pentru a modifica jurnalul dvs. de apeluri."</string>
+ <string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"Permite aplicației să modifice jurnalul de apeluri al tabletei dvs., inclusiv datele despre apelurile primite sau efectuate. Aplicaţiile rău intenţionate pot utiliza această permisiune pentru a șterge sau pentru a modifica jurnalul dvs. de apeluri."</string>
<string name="permdesc_writeCallLog" product="tv" msgid="4225034892248398019">"Permite aplicației să modifice jurnalul de apeluri al televizorului, inclusiv datele despre apelurile primite sau efectuate. Aplicațiile rău-intenționate pot utiliza această permisiune pentru a șterge sau pentru a modifica jurnalul de apeluri."</string>
- <string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"Permite aplicației să modifice jurnalul de apeluri al telefonului dvs., inclusiv datele despre apelurile primite sau efectuate. Aplicaţiile rău intenţionate pot utiliza această permisiune pentru a şterge sau pentru a modifica jurnalul dvs. de apeluri."</string>
+ <string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"Permite aplicației să modifice jurnalul de apeluri al telefonului dvs., inclusiv datele despre apelurile primite sau efectuate. Aplicaţiile rău intenţionate pot utiliza această permisiune pentru a șterge sau pentru a modifica jurnalul dvs. de apeluri."</string>
<string name="permlab_bodySensors" msgid="4871091374767171066">"senzori (ex.: senzori de ritm cardiac)"</string>
<string name="permdesc_bodySensors" product="default" msgid="4380015021754180431">"Permite aplicației să acceseze date de la senzorii care vă monitorizează starea fizică, cum ar fi ritmul cardiac."</string>
<string name="permlab_readCalendar" msgid="5972727560257612398">"citirea evenimentelor din calendar și a informaţiilor confidenţiale"</string>
@@ -335,7 +335,7 @@
<string name="permdesc_writeCalendar" product="tablet" msgid="6679035520113668528">"Permite aplicației să adauge, să elimine și să modifice evenimentele pe care le puteți modifica pe tabletă, inclusiv cele ale prietenilor sau colegilor dvs. În acest fel, aplicația poate trimite mesaje care par să vină de la proprietarii calendarelor sau să modifice evenimentele fără ştirea proprietarilor."</string>
<string name="permdesc_writeCalendar" product="tv" msgid="1273290605500902507">"Permite aplicației să adauge, să elimine și să modifice evenimentele pe care le puteți modifica pe televizor, inclusiv pe cele ale prietenilor sau ale colegilor. Cu această permisiune, aplicația poate să trimită mesaje care par că vin din partea proprietarilor calendarului sau să modifice evenimentele fără cunoștința acestora."</string>
<string name="permdesc_writeCalendar" product="default" msgid="2324469496327249376">"Permite aplicației să adauge, să elimine și să modifice evenimentele pe care le puteți modifica pe telefon, inclusiv cele ale prietenilor sau colegilor dvs. În acest fel, aplicația poate trimite mesaje care par să vină de la proprietarii calendarelor sau să modifice evenimentele fără ştirea proprietarilor."</string>
- <string name="permlab_accessLocationExtraCommands" msgid="2836308076720553837">"accesare comenzi suplimentare ale furnizorului locaţiei"</string>
+ <string name="permlab_accessLocationExtraCommands" msgid="2836308076720553837">"accesare comenzi suplimentare ale furnizorului locației"</string>
<string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"Permite aplicației să acceseze comenzi suplimentare pentru furnizorul locației. Aplicația ar putea să utilizeze această permisiune pentru a influența operațiile GPS sau ale altor surse de locații."</string>
<string name="permlab_accessFineLocation" msgid="1191898061965273372">"locaţia exactă (bazată pe rețea și GPS)"</string>
<string name="permdesc_accessFineLocation" msgid="5295047563564981250">"Permite aplicației să obţină locaţia dvs. exactă utilizând sistemul GPS (Global Positioning System) sau surse de localizare prin rețele, cum ar fi cele prin turn de celule și Wi-Fi. Pentru a fi utilizate de aplicație, aceste servicii de localizare trebuie să fie activate și disponibile pe dispozitivul dvs. Aplicaţiile pot utiliza această permisiune pentru a determina locaţia dvs. și pot să consume mai multă energie a bateriei."</string>
@@ -446,8 +446,8 @@
<string name="permlab_sdcardRead" product="default" msgid="2188156462934977940">"citeşte conţinutul cardului SD"</string>
<string name="permdesc_sdcardRead" product="nosdcard" msgid="3446988712598386079">"Permite aplic. citirea conținutului stoc. USB."</string>
<string name="permdesc_sdcardRead" product="default" msgid="2607362473654975411">"Permite aplicației citirea conținutul cardului SD."</string>
- <string name="permlab_sdcardWrite" product="nosdcard" msgid="8485979062254666748">"modifică sau şterge conţinutul stocării USB"</string>
- <string name="permlab_sdcardWrite" product="default" msgid="8805693630050458763">"modifică sau şterge conţinutul cardului SD"</string>
+ <string name="permlab_sdcardWrite" product="nosdcard" msgid="8485979062254666748">"modifică sau șterge conţinutul stocării USB"</string>
+ <string name="permlab_sdcardWrite" product="default" msgid="8805693630050458763">"modifică sau șterge conţinutul cardului SD"</string>
<string name="permdesc_sdcardWrite" product="nosdcard" msgid="6175406299445710888">"Permite scriere în stoc. USB."</string>
<string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"Permite aplicației să scrie pe cardul SD."</string>
<string name="permlab_use_sip" msgid="2052499390128979920">"efectuarea/primirea apelurilor SIP"</string>
@@ -650,10 +650,10 @@
<string name="keyguard_password_enter_pin_password_code" msgid="6391755146112503443">"Introduceţi codul PIN pentru a debloca"</string>
<string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"Cod PIN incorect."</string>
<string name="keyguard_label_text" msgid="861796461028298424">"Pentru a debloca, apăsaţi Meniu, apoi 0."</string>
- <string name="emergency_call_dialog_number_for_display" msgid="696192103195090970">"Număr de urgenţă"</string>
+ <string name="emergency_call_dialog_number_for_display" msgid="696192103195090970">"Număr de urgență"</string>
<string name="lockscreen_carrier_default" msgid="8963839242565653192">"Fără serviciu."</string>
<string name="lockscreen_screen_locked" msgid="7288443074806832904">"Ecranul este blocat."</string>
- <string name="lockscreen_instructions_when_pattern_enabled" msgid="46154051614126049">"Apăsaţi Meniu pentru a debloca sau pentru a efectua apeluri de urgenţă."</string>
+ <string name="lockscreen_instructions_when_pattern_enabled" msgid="46154051614126049">"Apăsați Meniu pentru a debloca sau pentru a efectua apeluri de urgență."</string>
<string name="lockscreen_instructions_when_pattern_disabled" msgid="686260028797158364">"Apăsaţi Meniu pentru deblocare."</string>
<string name="lockscreen_pattern_instructions" msgid="7478703254964810302">"Desenaţi modelul pentru a debloca"</string>
<string name="lockscreen_emergency_call" msgid="5298642613417801888">"Urgență"</string>
@@ -710,7 +710,7 @@
<string name="lockscreen_sound_on_label" msgid="9068877576513425970">"Sunet activat"</string>
<string name="lockscreen_sound_off_label" msgid="996822825154319026">"Sunet dezactivat"</string>
<string name="lockscreen_access_pattern_start" msgid="3941045502933142847">"Desenarea modelului a început"</string>
- <string name="lockscreen_access_pattern_cleared" msgid="5583479721001639579">"Modelul a fost şters"</string>
+ <string name="lockscreen_access_pattern_cleared" msgid="5583479721001639579">"Modelul a fost șters"</string>
<string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"Celulă adăugată"</string>
<string name="lockscreen_access_pattern_cell_added_verbose" msgid="7264580781744026939">"Celula <xliff:g id="CELL_INDEX">%1$s</xliff:g> a fost adăugată"</string>
<string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"Modelul a fost desenat"</string>
@@ -755,7 +755,7 @@
<string name="js_dialog_before_unload_positive_button" msgid="3112752010600484130">"Părăsiți această pagină"</string>
<string name="js_dialog_before_unload_negative_button" msgid="5614861293026099715">"Rămâneți în această pagină"</string>
<string name="js_dialog_before_unload" msgid="3468816357095378590">"<xliff:g id="MESSAGE">%s</xliff:g>\n\nSigur doriți să părăsiți această pagină?"</string>
- <string name="save_password_label" msgid="6860261758665825069">"Confirmaţi"</string>
+ <string name="save_password_label" msgid="6860261758665825069">"Confirmați"</string>
<string name="double_tap_toast" msgid="4595046515400268881">"Sfat: măriţi și micşoraţi prin dublă atingere."</string>
<string name="autofill_this_form" msgid="4616758841157816676">"Automat"</string>
<string name="setup_autofill" msgid="7103495070180590814">"Conf.Compl.auto."</string>
@@ -778,9 +778,9 @@
<string name="permlab_readHistoryBookmarks" msgid="3775265775405106983">"citeşte marcajele și istoricul web"</string>
<string name="permdesc_readHistoryBookmarks" msgid="8462378226600439658">"Permite aplicației să citească istoricul tuturor adreselor URL accesate de Browser și toate marcajele din Browser. Notă: această permisiune nu poate fi aplicată de browsere terţă parte sau de alte aplicații cu capacităţi de navigare pe web."</string>
<string name="permlab_writeHistoryBookmarks" msgid="3714785165273314490">"scrie în marcajele și în istoricul web"</string>
- <string name="permdesc_writeHistoryBookmarks" product="tablet" msgid="6825527469145760922">"Permite aplicației să modifice istoricul Browserului sau marcajele stocate pe tabletă. În acest fel, aplicația poate şterge sau modifica datele din Browser. Notă: această permisiune nu poate fi aplicată de browsere terţă parte sau de alte aplicații cu capacităţi de navigare pe web."</string>
+ <string name="permdesc_writeHistoryBookmarks" product="tablet" msgid="6825527469145760922">"Permite aplicației să modifice istoricul Browserului sau marcajele stocate pe tabletă. În acest fel, aplicația poate șterge sau modifica datele din Browser. Notă: această permisiune nu poate fi aplicată de browsere terţă parte sau de alte aplicații cu capacităţi de navigare pe web."</string>
<string name="permdesc_writeHistoryBookmarks" product="tv" msgid="7007393823197766548">"Permite aplicației să modifice istoricul sau marcajele browserului stocate pe televizor. Cu această permisiune, aplicația poate șterge sau modifica datele din browser. Notă: această permisiune nu poate fi aplicată de browsere terță parte sau de alte aplicații cu capacități de navigare pe web."</string>
- <string name="permdesc_writeHistoryBookmarks" product="default" msgid="8497389531014185509">"Permite aplicației să modifice istoricul Browserului sau marcajele stocate pe telefon. În acest fel, aplicația poate şterge sau modifica datele din Browser. Notă: această permisiune nu poate fi aplicată de browsere terţă parte sau de alte aplicații cu capacităţi de navigare pe web."</string>
+ <string name="permdesc_writeHistoryBookmarks" product="default" msgid="8497389531014185509">"Permite aplicației să modifice istoricul Browserului sau marcajele stocate pe telefon. În acest fel, aplicația poate șterge sau modifica datele din Browser. Notă: această permisiune nu poate fi aplicată de browsere terţă parte sau de alte aplicații cu capacităţi de navigare pe web."</string>
<string name="permlab_setAlarm" msgid="1379294556362091814">"setează o alarmă"</string>
<string name="permdesc_setAlarm" msgid="316392039157473848">"Permite aplicației să seteze o alarmă într-o aplicație de ceas cu alarmă instalată. Este posibil ca unele aplicații de ceas cu alarmă să nu implementeze această funcție."</string>
<string name="permlab_addVoicemail" msgid="5525660026090959044">"adăugare mesagerie vocală"</string>
@@ -795,7 +795,7 @@
<string name="text_copied" msgid="4985729524670131385">"Text copiat în clipboard."</string>
<string name="more_item_label" msgid="4650918923083320495">"Mai multe"</string>
<string name="prepend_shortcut_label" msgid="2572214461676015642">"Meniu+"</string>
- <string name="menu_space_shortcut_label" msgid="2410328639272162537">"spaţiu"</string>
+ <string name="menu_space_shortcut_label" msgid="2410328639272162537">"spațiu"</string>
<string name="menu_enter_shortcut_label" msgid="2743362785111309668">"enter"</string>
<string name="menu_delete_shortcut_label" msgid="3658178007202748164">"delete"</string>
<string name="search_go" msgid="8298016669822141719">"Căutați"</string>
@@ -1140,8 +1140,8 @@
<item quantity="one">Un rezultat</item>
</plurals>
<string name="action_mode_done" msgid="7217581640461922289">"Terminat"</string>
- <string name="progress_erasing" product="nosdcard" msgid="4521573321524340058">"Se şterge stocarea USB..."</string>
- <string name="progress_erasing" product="default" msgid="6596988875507043042">"Se şterge cardul SD..."</string>
+ <string name="progress_erasing" product="nosdcard" msgid="4521573321524340058">"Se șterge stocarea USB..."</string>
+ <string name="progress_erasing" product="default" msgid="6596988875507043042">"Se șterge cardul SD..."</string>
<string name="share" msgid="1778686618230011964">"Distribuiţi"</string>
<string name="find" msgid="4808270900322985960">"Găsiţi"</string>
<string name="websearch" msgid="4337157977400211589">"Căutare pe web"</string>
diff --git a/core/res/res/values-watch/strings.xml b/core/res/res/values-watch/strings.xml
index 4ea2b52..e5991fc 100644
--- a/core/res/res/values-watch/strings.xml
+++ b/core/res/res/values-watch/strings.xml
@@ -23,4 +23,50 @@
<string name="android_upgrading_apk">App
<xliff:g id="number" example="123">%1$d</xliff:g> of
<xliff:g id="number" example="123">%2$d</xliff:g>.</string>
+
+ <!-- Title of a category of application permissions, listed so the user can choose whether they want to allow the application to do this. Override from base which says "Body Sensors". [CHAR_LIMIT=25] -->
+ <string name="permgrouplab_sensors">Sensors</string>
+
+ <!-- Description of a permissions, listed so the user can choose whether they want to allow the application to do this. [CHAR_LIMIT=100] -->
+ <string name="permgrouplab_contactswear">access your contacts</string>
+ <!-- Description of a permissions, listed so the user can choose whether they want to allow the application to do this. [CHAR_LIMIT=100] -->
+ <string name="permgrouplab_locationwear">access this watch\'s location</string>
+ <!-- Description of a permissions, listed so the user can choose whether they want to allow the application to do this. [CHAR_LIMIT=100] -->
+ <string name="permgrouplab_calendarwear">access your calendar</string>
+ <!-- Description of a permissions, listed so the user can choose whether they want to allow the application to do this. [CHAR_LIMIT=100] -->
+ <string name="permgrouplab_smswear">send and view SMS messages</string>
+ <!-- Description of a permissions, listed so the user can choose whether they want to allow the application to do this. [CHAR_LIMIT=100] -->
+ <string name="permgrouplab_storagewear">access photos, media, and files on your watch</string>
+ <!-- Description of a permissions, listed so the user can choose whether they want to allow the application to do this. [CHAR_LIMIT=100] -->
+ <string name="permgrouplab_microphonewear">record audio</string>
+ <!-- Description of a permissions, listed so the user can choose whether they want to allow the application to do this. [CHAR_LIMIT=100] -->
+ <string name="permgrouplab_camerawear">take pictures and record video</string>
+ <!-- Description of a permissions, listed so the user can choose whether they want to allow the application to do this. [CHAR_LIMIT=100] -->
+ <string name="permgrouplab_phonewear">make and manage phone calls</string>
+ <!-- Description of a permissions, listed so the user can choose whether they want to allow the application to do this. [CHAR_LIMIT=100] -->
+ <string name="permgrouplab_sensorswear">access sensor data about your vital signs</string>
+ <!-- Description of a permissions, listed so the user can choose whether they want to allow the application to do this. [CHAR_LIMIT=100] -->
+ <string name="permlab_statusBarServicewear">be the status bar</string>
+ <!-- Description of a permissions, listed so the user can choose whether they want to allow the application to do this. [CHAR_LIMIT=100] -->
+ <string name="permlab_bodySensorswear">access body sensors (like heart rate monitors)</string>
+ <!-- Description of a permissions, listed so the user can choose whether they want to allow the application to do this. [CHAR_LIMIT=100] -->
+ <string name="permlab_accessFineLocationwear">access precise location (GPS and network-based)</string>
+ <!-- Description of a permissions, listed so the user can choose whether they want to allow the application to do this. [CHAR_LIMIT=100] -->
+ <string name="permlab_accessCoarseLocationwear">access approximate location (network-based)</string>
+ <!-- Description of a permissions, listed so the user can choose whether they want to allow the application to do this. [CHAR_LIMIT=100] -->
+ <string name="permlab_sim_communicationwear">send commands to the SIM</string>
+ <!-- Description of a permissions, listed so the user can choose whether they want to allow the application to do this. [CHAR_LIMIT=100] -->
+ <string name="permlab_createNetworkSocketswear">have full network access</string>
+ <!-- Description of a permissions, listed so the user can choose whether they want to allow the application to do this. [CHAR_LIMIT=100] -->
+ <string name="permlab_manageProfileAndDeviceOwnerswear">manage profile and device owners</string>
+ <!-- Description of a permissions, listed so the user can choose whether they want to allow the application to do this. [CHAR_LIMIT=100] -->
+ <string name="permlab_changeWimaxStatewear">change WiMAX state</string>
+ <!-- Description of a permissions, listed so the user can choose whether they want to allow the application to do this. [CHAR_LIMIT=100] -->
+ <string name="permlab_handoverStatuswear">receive Android Beam transfer status</string>
+ <!-- Description of a permissions, listed so the user can choose whether they want to allow the application to do this. [CHAR_LIMIT=100] -->
+ <string name="permlab_route_media_outputwear">route media output</string>
+ <!-- Description of a permissions, listed so the user can choose whether they want to allow the application to do this. [CHAR_LIMIT=100] -->
+ <string name="permlab_readInstallSessionswear">read install sessions</string>
+ <!-- Description of a permissions, listed so the user can choose whether they want to allow the application to do this. [CHAR_LIMIT=100] -->
+ <string name="permlab_requestInstallPackageswear">request install packages</string>
</resources>
diff --git a/core/res/res/values/attrs_manifest.xml b/core/res/res/values/attrs_manifest.xml
index 74fd1ec..1a2600d 100644
--- a/core/res/res/values/attrs_manifest.xml
+++ b/core/res/res/values/attrs_manifest.xml
@@ -2200,10 +2200,10 @@
<declare-styleable name="AndroidManifestInitialLayout" parent="AndroidManifestActivity">
<!-- Initial width of the activity. Can be either a fixed value or fraction, in which case
the width will be constructed as a fraction of the total available width. -->
- <attr name="activity_width" format="dimension|fraction" />
+ <attr name="activityWidth" format="dimension|fraction" />
<!-- Initial height of the activity. Can be either a fixed value or fraction, in which case
the height will be constructed as a fraction of the total available height. -->
- <attr name="activity_height" format="dimension|fraction" />
+ <attr name="activityHeight" format="dimension|fraction" />
<!-- Where to initially position the activity inside the available space. Uses constants
defined in {@link android.view.Gravity}. -->
<attr name="gravity" />
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 2c940ae..ef4e261 100755
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -2029,10 +2029,6 @@
IMS service implementation will do both.i.e.hold followed by merge. -->
<bool name="skipHoldBeforeMerge">true</bool>
- <!-- Flag indicating emergency calls will always use IMS irrespective of the state of
- the IMS connection -->
- <bool name="useImsAlwaysForEmergencyCall">true</bool>
-
<!-- Flag indicating whether the IMS service can be turned off. If false then
the service will not be turned-off completely (the ImsManager.turnOffIms() will
be disabled) but individual Features can be disabled using ImsConfig.setFeatureValue() -->
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index cabb56c..d2089cd 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -2679,5 +2679,7 @@
<public type="style" name="Theme.Material.DayNight.DialogWhenLarge.DarkActionBar" />
<public type="id" name="accessibilityActionSetProgress" />
+ <public type="attr" name="activityWidth" />
+ <public type="attr" name="activityHeight" />
</resources>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index a55258c..e04c743 100755
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -2138,7 +2138,6 @@
<java-symbol type="bool" name="config_carrier_vt_available" />
<java-symbol type="bool" name="config_device_wfc_ims_available" />
<java-symbol type="bool" name="config_carrier_wfc_ims_available" />
- <java-symbol type="bool" name="useImsAlwaysForEmergencyCall" />
<java-symbol type="attr" name="touchscreenBlocksFocus" />
<java-symbol type="layout" name="resolver_list_with_default" />
<java-symbol type="string" name="whichApplicationNamed" />
diff --git a/core/tests/coretests/src/android/app/backup/FullBackupTest.java b/core/tests/coretests/src/android/app/backup/FullBackupTest.java
index 8c9c63c..c3afbf6 100644
--- a/core/tests/coretests/src/android/app/backup/FullBackupTest.java
+++ b/core/tests/coretests/src/android/app/backup/FullBackupTest.java
@@ -114,12 +114,14 @@
public void testparseBackupSchemeFromXml_lotsOfIncludesAndExcludes() throws Exception {
mXpp.setInput(new StringReader(
"<full-backup-content>" +
- "<exclude path=\"exclude1.txt\" domain=\"file\"/>" +
+ "<exclude path=\"exclude1.txt\" domain=\"file\"/>" +
"<include path=\"include1.txt\" domain=\"file\"/>" +
"<exclude path=\"exclude2.txt\" domain=\"database\"/>" +
"<include path=\"include2.txt\" domain=\"database\"/>" +
- "<exclude path=\"exclude3.txt\" domain=\"sharedpref\"/>" +
- "<include path=\"include3.txt\" domain=\"sharedpref\"/>" +
+ "<exclude path=\"exclude3\" domain=\"sharedpref\"/>" +
+ "<include path=\"include3\" domain=\"sharedpref\"/>" +
+ "<exclude path=\"exclude4.xml\" domain=\"sharedpref\"/>" +
+ "<include path=\"include4.xml\" domain=\"sharedpref\"/>" +
"</full-backup-content>"));
@@ -146,16 +148,27 @@
"include2.txt-journal")
.getCanonicalPath()));
- Set<String> sharedPrefDomainIncludes = includeMap.get(FullBackup.SHAREDPREFS_TREE_TOKEN);
+ List<String> sharedPrefDomainIncludes = new ArrayList<String>(
+ includeMap.get(FullBackup.SHAREDPREFS_TREE_TOKEN));
+ Collections.sort(sharedPrefDomainIncludes);
+
assertEquals("Didn't find expected sharedpref domain include.",
- 1, sharedPrefDomainIncludes.size());
+ 3, sharedPrefDomainIncludes.size());
assertEquals("Invalid path parsed for <include/>",
- new File(mContext.getSharedPrefsFile("foo").getParentFile(), "include3.txt")
+ new File(mContext.getSharedPrefsFile("foo").getParentFile(), "include3")
.getCanonicalPath(),
- sharedPrefDomainIncludes.iterator().next());
+ sharedPrefDomainIncludes.get(0));
+ assertEquals("Invalid path parsed for <include/>",
+ new File(mContext.getSharedPrefsFile("foo").getParentFile(), "include3.xml")
+ .getCanonicalPath(),
+ sharedPrefDomainIncludes.get(1));
+ assertEquals("Invalid path parsed for <include/>",
+ new File(mContext.getSharedPrefsFile("foo").getParentFile(), "include4.xml")
+ .getCanonicalPath(),
+ sharedPrefDomainIncludes.get(2));
- assertEquals("Unexpected number of <exclude/>s", 4, excludesSet.size());
+ assertEquals("Unexpected number of <exclude/>s", 6, excludesSet.size());
// Sets are annoying to iterate over b/c order isn't enforced - convert to an array and
// sort lexicographically.
List<String> arrayedSet = new ArrayList<String>(excludesSet);
@@ -173,9 +186,17 @@
new File(mContext.getFilesDir(), "exclude1.txt").getCanonicalPath(),
arrayedSet.get(2));
assertEquals("Invalid path parsed for <exclude/>",
- new File(mContext.getSharedPrefsFile("foo").getParentFile(), "exclude3.txt")
+ new File(mContext.getSharedPrefsFile("foo").getParentFile(), "exclude3")
.getCanonicalPath(),
arrayedSet.get(3));
+ assertEquals("Invalid path parsed for <exclude/>",
+ new File(mContext.getSharedPrefsFile("foo").getParentFile(), "exclude3.xml")
+ .getCanonicalPath(),
+ arrayedSet.get(4));
+ assertEquals("Invalid path parsed for <exclude/>",
+ new File(mContext.getSharedPrefsFile("foo").getParentFile(), "exclude4.xml")
+ .getCanonicalPath(),
+ arrayedSet.get(5));
}
public void testParseBackupSchemeFromXml_invalidXmlFails() throws Exception {
diff --git a/docs/html/sdk/index.jd b/docs/html/sdk/index.jd
index dbc0f35..39822e5 100644
--- a/docs/html/sdk/index.jd
+++ b/docs/html/sdk/index.jd
@@ -5,28 +5,28 @@
header.hide=1
page.metaDescription=Download the official Android IDE and developer tools to build apps for Android phones, tablets, wearables, TVs, and more.
-studio.version=1.3.1.0
+studio.version=1.3.2.0
-studio.linux_bundle_download=android-studio-ide-141.2135290-linux.zip
-studio.linux_bundle_bytes=351992670
-studio.linux_bundle_checksum=51e5f5de2b82883d87f85ee38cf7b7b8b2e7debf
+studio.linux_bundle_download=android-studio-ide-141.2178183-linux.zip
+studio.linux_bundle_bytes=352010593
+studio.linux_bundle_checksum=cf780413f8c8223eb348bd27c19a9c04b75eaeb2
-studio.mac_bundle_download=android-studio-ide-141.2135290-mac.dmg
-studio.mac_bundle_bytes=368321249
-studio.mac_bundle_checksum=9fc12b5657ff52c761b7e7c115feade2a9728386
+studio.mac_bundle_download=android-studio-ide-141.2178183-mac.dmg
+studio.mac_bundle_bytes=368335367
+studio.mac_bundle_checksum=75b67eb15a34a152a40e7189484ab0ebc375b877
-studio.win_bundle_download=android-studio-ide-141.2135290-windows.zip
-studio.win_bundle_bytes=344406793
-studio.win_bundle_checksum=3b4c4924cb9495e56db61ca0e8c8d2bf588c4b97
+studio.win_bundle_download=android-studio-ide-141.2178183-windows.zip
+studio.win_bundle_bytes=344424713
+studio.win_bundle_checksum=3134f226b5f3c3f74d4fc2d9cff03a4458f01d69
-studio.win_bundle_exe_download=android-studio-bundle-141.2135290-windows.exe
-studio.win_bundle_exe_bytes=1008506096
-studio.win_bundle_exe_checksum=8cff590f2e08e339f8c2491b287a840ae87c7383
+studio.win_bundle_exe_download=android-studio-bundle-141.2178183-windows.exe
+studio.win_bundle_exe_bytes=1136982712
+studio.win_bundle_exe_checksum=c7d39c529dd434489da9d086ff689d34dc791526
-studio.win_notools_exe_download=android-studio-ide-141.2135290-windows.exe
-studio.win_notools_exe_bytes=321791312
-studio.win_notools_exe_checksum=d70fb49d03db9dded19c891a92452601e39272f4
+studio.win_notools_exe_download=android-studio-ide-141.2178183-windows.exe
+studio.win_notools_exe_bytes=321810248
+studio.win_notools_exe_checksum=b5d1aaa000729c03a3cf980add79d1b93121c56d
@@ -289,7 +289,7 @@
</ul>
<a class="online landing-button green download-bundle-button"
-href="#Other" >Download Android Studio</a>
+href="#Other" >Download Android Studio<br/><span class='small'></span></a>
<!-- this appears when viewing the offline docs -->
<p class="offline">
diff --git a/docs/html/tools/revisions/studio.jd b/docs/html/tools/revisions/studio.jd
index c922b28..298b173 100644
--- a/docs/html/tools/revisions/studio.jd
+++ b/docs/html/tools/revisions/studio.jd
@@ -43,6 +43,29 @@
<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 v1.3.2</a> <em>(August 2015)</em>
+ </p>
+ <div class="toggle-content-toggleme">
+ <p>Fixes and enhancements:</p>
+ <ul>
+ <li>Added support for Android 6.0 (API level 23), including new icons and AVD Manager
+ support for creating devices with new screen densities.</li>
+ <li>Fixed an exception that was occuring during update checks.
+ <a href="http://b.android.com/183068">Issue: 183068</a></li>
+ <li>Fixed problem where unresolved view coordinates could cause the layout editor to crash.
+ <a href="http://b.android.com/178690">Issue: 178690</a></li>
+ <li>Fixed issue with invalid resource type warnings.
+ <a href="http://b.android.com/182433">Issue: 182433</a></li>
+ <li>Fixed lint check that was incorrectly flagging resources as private.
+ <a href="http://b.android.com/183120">Issue: 183120</a></li>
+ </ul>
+ </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 v1.3.1</a> <em>(August 2015)</em>
</p>
<div class="toggle-content-toggleme">
@@ -60,8 +83,6 @@
</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"
@@ -100,7 +121,7 @@
<li>Added <a href="{@docRoot}tools/data-binding/guide.html">data binding</a> support to
create declarative layouts that bind your application logic to layout elements. </li>
<li>Added support for a separate
- <a href="{@docRoot}tools/studio/studio-features.html#test-module">test APK module</a>
+ <a href="{@docRoot}tools/studio/studio-features.html#test-module">test APK module</a>
to build test APKs in Android Studio. </li>
<li>Updated the <a href="{@docRoot}tools/help/avd-manager.html">AVD Manager</a> with HAXM
optimizations and improved notifications. </li>
diff --git a/docs/html/tools/sdk/eclipse-adt.jd b/docs/html/tools/sdk/eclipse-adt.jd
index 08634da..3c12a64 100644
--- a/docs/html/tools/sdk/eclipse-adt.jd
+++ b/docs/html/tools/sdk/eclipse-adt.jd
@@ -53,6 +53,39 @@
<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=""/>ADT 23.0.7</a> <em>(August 2015)</em>
+ </p>
+
+ <div class="toggle-content-toggleme">
+<dl>
+ <dt>Dependencies:</dt>
+
+ <dd>
+ <ul>
+ <li>Java 7 or higher is required if you are targeting Android 5.0 and higher.</li>
+ <li>Java 1.6 or higher is required if you are targeting other releases.</li>
+ <li>Eclipse Indigo (Version 3.7.2) or higher is required.</li>
+ <li>This version of ADT is designed for use with
+ <a href="{@docRoot}tools/sdk/tools-notes.html">SDK Tools r24.1.2</a>.
+ If you haven't already installed SDK Tools r24.1.2 into your SDK, use the
+ Android SDK Manager to do so.</li>
+ </ul>
+ </dd>
+
+ <dt>General Notes:</dt>
+ <dd>
+ <ul>
+ <li>Fixed issues with the rendering library for the visual layout editor.</li>
+ </ul>
+ </dd>
+</dl>
+</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=""/>ADT 23.0.6</a> <em>(March 2015)</em>
</p>
@@ -75,7 +108,7 @@
<dt>General Notes:</dt>
<dd>
<ul>
- <li>Fixed issues with the rendering library.</li>
+ <li>Fixed issues with the rendering library for the visual layout editor.</li>
</ul>
</dd>
</dl>
diff --git a/docs/html/tools/support-library/features.jd b/docs/html/tools/support-library/features.jd
index b3af7a2..19f93e9 100644
--- a/docs/html/tools/support-library/features.jd
+++ b/docs/html/tools/support-library/features.jd
@@ -307,8 +307,8 @@
on how to set up your project, follow the instructions in <a
href="{@docRoot}tools/support-library/setup.html#libs-with-res">Adding libraries
with resources</a>. If you are developing in Eclipse/ADT, make sure to include
-both the <code>android-support-v7-mediarouter.jar</code> and
-<code>android-support-v7-appcompat.jar</code> files.</p>
+the <code>android-support-v7-mediarouter.jar</code>, <code>android-support-v7-appcompat.jar</code>,
+and <code>android-support-v7-palette.jar</code> files.</p>
<p>If you are using Android Studio, all you need to do is specify the Gradle build
script dependency identifier <code>com.android.support:support-v7-mediarouter:<revision></code>,
diff --git a/graphics/java/android/graphics/drawable/RippleBackground.java b/graphics/java/android/graphics/drawable/RippleBackground.java
index 1c14e2f..f9474ef 100644
--- a/graphics/java/android/graphics/drawable/RippleBackground.java
+++ b/graphics/java/android/graphics/drawable/RippleBackground.java
@@ -48,8 +48,8 @@
// Software rendering properties.
private float mOpacity = 0;
- public RippleBackground(RippleDrawable owner, Rect bounds) {
- super(owner, bounds);
+ public RippleBackground(RippleDrawable owner, Rect bounds, boolean forceSoftware) {
+ super(owner, bounds, forceSoftware);
}
public boolean isVisible() {
@@ -131,15 +131,7 @@
mPropX = CanvasProperty.createFloat(0);
mPropY = CanvasProperty.createFloat(0);
- // Linear "fast" enter based on current opacity.
final int fastEnterDuration = (int) ((1 - mOpacity) * OPACITY_ENTER_DURATION_FAST);
- if (fastEnterDuration > 0) {
- final RenderNodeAnimator enter = new RenderNodeAnimator(
- mPropPaint, RenderNodeAnimator.PAINT_ALPHA, targetAlpha);
- enter.setInterpolator(LINEAR_INTERPOLATOR);
- enter.setDuration(fastEnterDuration);
- set.add(enter);
- }
// Linear exit after enter is completed.
final RenderNodeAnimator exit = new RenderNodeAnimator(
@@ -149,6 +141,15 @@
exit.setStartDelay(fastEnterDuration);
set.add(exit);
+ // Linear "fast" enter based on current opacity.
+ if (fastEnterDuration > 0) {
+ final RenderNodeAnimator enter = new RenderNodeAnimator(
+ mPropPaint, RenderNodeAnimator.PAINT_ALPHA, targetAlpha);
+ enter.setInterpolator(LINEAR_INTERPOLATOR);
+ enter.setDuration(fastEnterDuration);
+ set.add(enter);
+ }
+
return set;
}
diff --git a/graphics/java/android/graphics/drawable/RippleComponent.java b/graphics/java/android/graphics/drawable/RippleComponent.java
index 23a3ee3..2d378c6 100644
--- a/graphics/java/android/graphics/drawable/RippleComponent.java
+++ b/graphics/java/android/graphics/drawable/RippleComponent.java
@@ -52,9 +52,16 @@
/** Screen density used to adjust pixel-based constants. */
protected float mDensity;
- public RippleComponent(RippleDrawable owner, Rect bounds) {
+ /**
+ * If set, force all ripple animations to not run on RenderThread, even if it would be
+ * available.
+ */
+ private final boolean mForceSoftware;
+
+ public RippleComponent(RippleDrawable owner, Rect bounds, boolean forceSoftware) {
mOwner = owner;
mBounds = bounds;
+ mForceSoftware = forceSoftware;
}
public void onBoundsChange() {
@@ -143,7 +150,7 @@
* @return {@code true} if something was drawn, {@code false} otherwise
*/
public boolean draw(Canvas c, Paint p) {
- final boolean hasDisplayListCanvas = c.isHardwareAccelerated()
+ final boolean hasDisplayListCanvas = !mForceSoftware && c.isHardwareAccelerated()
&& c instanceof DisplayListCanvas;
if (mHasDisplayListCanvas != hasDisplayListCanvas) {
mHasDisplayListCanvas = hasDisplayListCanvas;
diff --git a/graphics/java/android/graphics/drawable/RippleDrawable.java b/graphics/java/android/graphics/drawable/RippleDrawable.java
index 464f3de..2690223 100644
--- a/graphics/java/android/graphics/drawable/RippleDrawable.java
+++ b/graphics/java/android/graphics/drawable/RippleDrawable.java
@@ -166,6 +166,12 @@
private boolean mOverrideBounds;
/**
+ * If set, force all ripple animations to not run on RenderThread, even if it would be
+ * available.
+ */
+ private boolean mForceSoftware;
+
+ /**
* Constructor used for drawable inflation.
*/
RippleDrawable() {
@@ -546,7 +552,7 @@
*/
private void tryBackgroundEnter(boolean focused) {
if (mBackground == null) {
- mBackground = new RippleBackground(this, mHotspotBounds);
+ mBackground = new RippleBackground(this, mHotspotBounds, mForceSoftware);
}
mBackground.setup(mState.mMaxRadius, mDensity);
@@ -584,7 +590,7 @@
}
final boolean isBounded = isBounded();
- mRipple = new RippleForeground(this, mHotspotBounds, x, y, isBounded);
+ mRipple = new RippleForeground(this, mHotspotBounds, x, y, isBounded, mForceSoftware);
}
mRipple.setup(mState.mMaxRadius, mDensity);
@@ -949,6 +955,16 @@
}
}
+ /**
+ * Sets whether to disable RenderThread animations for this ripple.
+ *
+ * @param forceSoftware true if RenderThread animations should be disabled, false otherwise
+ * @hide
+ */
+ public void setForceSoftware(boolean forceSoftware) {
+ mForceSoftware = forceSoftware;
+ }
+
@Override
public ConstantState getConstantState() {
return mState;
diff --git a/graphics/java/android/graphics/drawable/RippleForeground.java b/graphics/java/android/graphics/drawable/RippleForeground.java
index 4853b04..c660846 100644
--- a/graphics/java/android/graphics/drawable/RippleForeground.java
+++ b/graphics/java/android/graphics/drawable/RippleForeground.java
@@ -87,8 +87,8 @@
private boolean mHasFinishedExit;
public RippleForeground(RippleDrawable owner, Rect bounds, float startingX, float startingY,
- boolean isBounded) {
- super(owner, bounds);
+ boolean isBounded, boolean forceSoftware) {
+ super(owner, bounds, forceSoftware);
mIsBounded = isBounded;
mStartingX = startingX;
diff --git a/media/java/android/media/AudioAttributes.java b/media/java/android/media/AudioAttributes.java
index 0f1be6b..e92f294 100644
--- a/media/java/android/media/AudioAttributes.java
+++ b/media/java/android/media/AudioAttributes.java
@@ -671,15 +671,15 @@
case USAGE_VOICE_COMMUNICATION:
return new String("USAGE_VOICE_COMMUNICATION");
case USAGE_VOICE_COMMUNICATION_SIGNALLING:
- return new String("USAGE_VOICE_COMMUNICATION");
+ return new String("USAGE_VOICE_COMMUNICATION_SIGNALLING");
case USAGE_ALARM:
return new String("USAGE_ALARM");
case USAGE_NOTIFICATION:
return new String("USAGE_NOTIFICATION");
case USAGE_NOTIFICATION_RINGTONE:
- return new String("USAGE_NOTIFICATION");
+ return new String("USAGE_NOTIFICATION_RINGTONE");
case USAGE_NOTIFICATION_COMMUNICATION_REQUEST:
- return new String("USAGE_NOTIFICATION");
+ return new String("USAGE_NOTIFICATION_COMMUNICATION_REQUEST");
case USAGE_NOTIFICATION_COMMUNICATION_INSTANT:
return new String("USAGE_NOTIFICATION_COMMUNICATION_INSTANT");
case USAGE_NOTIFICATION_COMMUNICATION_DELAYED:
diff --git a/media/java/android/media/AudioSystem.java b/media/java/android/media/AudioSystem.java
index e99a37a..c59d1c7 100644
--- a/media/java/android/media/AudioSystem.java
+++ b/media/java/android/media/AudioSystem.java
@@ -279,6 +279,7 @@
public static final int PERMISSION_DENIED = -4;
public static final int NO_INIT = -5;
public static final int DEAD_OBJECT = -6;
+ public static final int WOULD_BLOCK = -7;
/*
* AudioPolicyService methods
diff --git a/media/java/android/media/AudioTrack.java b/media/java/android/media/AudioTrack.java
index 8880dad..bb4f7d9 100644
--- a/media/java/android/media/AudioTrack.java
+++ b/media/java/android/media/AudioTrack.java
@@ -158,6 +158,18 @@
* Denotes a failure due to the improper use of a method.
*/
public static final int ERROR_INVALID_OPERATION = AudioSystem.INVALID_OPERATION;
+ /**
+ * An error code indicating that the object reporting it is no longer valid and needs to
+ * be recreated.
+ * @hide
+ */
+ public static final int ERROR_DEAD_OBJECT = AudioSystem.DEAD_OBJECT;
+ /**
+ * {@link #getTimestampWithStatus(AudioTimestamp)} is called in STOPPED or FLUSHED state,
+ * or immediately after start/ACTIVE.
+ * @hide
+ */
+ public static final int ERROR_WOULD_BLOCK = AudioSystem.WOULD_BLOCK;
// Error codes:
// to keep in sync with frameworks/base/core/jni/android_media_AudioTrack.cpp
@@ -1225,6 +1237,44 @@
return true;
}
+ /**
+ * Poll for a timestamp on demand.
+ * <p>
+ * Same as {@link #getTimestamp(AudioTimestamp)} but with a more useful return code.
+ *
+ * @param timestamp a reference to a non-null AudioTimestamp instance allocated
+ * and owned by caller.
+ * @return {@link #SUCCESS} if a timestamp is available
+ * {@link #ERROR_WOULD_BLOCK} if called in STOPPED or FLUSHED state, or if called
+ * immediately after start/ACTIVE, when the number of frames consumed is less than the
+ * overall hardware latency to physical output. In WOULD_BLOCK cases, one might poll
+ * again, or use {@link #getPlaybackHeadPosition}, or use 0 position and current time
+ * for the timestamp.
+ * {@link #ERROR_DEAD_OBJECT} if the AudioTrack is not valid anymore and
+ * needs to be recreated.
+ * {@link #ERROR_INVALID_OPERATION} if current route does not support
+ * timestamps. In this case, the approximate frame position can be obtained
+ * using {@link #getPlaybackHeadPosition}.
+ *
+ * The AudioTimestamp instance is filled in with a position in frame units, together
+ * with the estimated time when that frame was presented or is committed to
+ * be presented.
+ * @hide
+ */
+ // Add this text when the "on new timestamp" API is added:
+ // Use if you need to get the most recent timestamp outside of the event callback handler.
+ public int getTimestampWithStatus(AudioTimestamp timestamp)
+ {
+ if (timestamp == null) {
+ throw new IllegalArgumentException();
+ }
+ // It's unfortunate, but we have to either create garbage every time or use synchronized
+ long[] longArray = new long[2];
+ int ret = native_get_timestamp(longArray);
+ timestamp.framePosition = longArray[0];
+ timestamp.nanoTime = longArray[1];
+ return ret;
+ }
//--------------------------------------------------------------------------
// Initialization / configuration
diff --git a/packages/DocumentsUI/AndroidManifest.xml b/packages/DocumentsUI/AndroidManifest.xml
index a0e3868..d578769 100644
--- a/packages/DocumentsUI/AndroidManifest.xml
+++ b/packages/DocumentsUI/AndroidManifest.xml
@@ -48,8 +48,8 @@
</activity>
<activity
- android:name=".StandaloneActivity"
- android:theme="@style/StandaloneTheme"
+ android:name=".FilesActivity"
+ android:theme="@style/FilesTheme"
android:icon="@drawable/ic_files_app"
android:label="@string/files_label"
android:enabled="@bool/productivity_device">
diff --git a/packages/DocumentsUI/res/layout/activity.xml b/packages/DocumentsUI/res/layout/drawer_layout.xml
similarity index 100%
rename from packages/DocumentsUI/res/layout/activity.xml
rename to packages/DocumentsUI/res/layout/drawer_layout.xml
diff --git a/packages/DocumentsUI/res/layout-sw720dp/activity.xml b/packages/DocumentsUI/res/layout/fixed_layout.xml
similarity index 100%
rename from packages/DocumentsUI/res/layout-sw720dp/activity.xml
rename to packages/DocumentsUI/res/layout/fixed_layout.xml
diff --git a/packages/DocumentsUI/res/values-sw720dp-land/layouts.xml b/packages/DocumentsUI/res/values-sw720dp-land/layouts.xml
new file mode 100644
index 0000000..0e1807c
--- /dev/null
+++ b/packages/DocumentsUI/res/values-sw720dp-land/layouts.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<resources>
+ <item name="files_activity" type="layout">@layout/fixed_layout</item>
+</resources>
diff --git a/packages/DocumentsUI/res/values-sw720dp/layouts.xml b/packages/DocumentsUI/res/values-sw720dp/layouts.xml
new file mode 100644
index 0000000..7d28f9c
--- /dev/null
+++ b/packages/DocumentsUI/res/values-sw720dp/layouts.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<resources>
+ <item name="docs_activity" type="layout">@layout/fixed_layout</item>
+</resources>
diff --git a/packages/DocumentsUI/res/values/layouts.xml b/packages/DocumentsUI/res/values/layouts.xml
new file mode 100644
index 0000000..c73a1cb
--- /dev/null
+++ b/packages/DocumentsUI/res/values/layouts.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<resources>
+ <item name="docs_activity" type="layout">@layout/drawer_layout</item>
+ <item name="files_activity" type="layout">@layout/drawer_layout</item>
+</resources>
diff --git a/packages/DocumentsUI/res/values/styles.xml b/packages/DocumentsUI/res/values/styles.xml
index 95c1d9c..fa94ff1 100644
--- a/packages/DocumentsUI/res/values/styles.xml
+++ b/packages/DocumentsUI/res/values/styles.xml
@@ -63,7 +63,7 @@
<item name="android:colorAccent">@color/material_blue_700</item>
</style>
- <style name="StandaloneTheme" parent="@android:style/Theme.Material.DayNight.DarkActionBar">
+ <style name="FilesTheme" parent="@android:style/Theme.Material.DayNight.DarkActionBar">
<item name="android:actionBarWidgetTheme">@null</item>
<item name="android:colorPrimaryDark">@color/status_bar_background</item>
diff --git a/packages/DocumentsUI/src/com/android/documentsui/BaseActivity.java b/packages/DocumentsUI/src/com/android/documentsui/BaseActivity.java
index a804e9a..2835106 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/BaseActivity.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/BaseActivity.java
@@ -37,6 +37,7 @@
import android.os.Parcelable;
import android.provider.DocumentsContract;
import android.provider.DocumentsContract.Root;
+import android.support.annotation.LayoutRes;
import android.support.annotation.Nullable;
import android.util.Log;
import android.util.SparseArray;
@@ -46,6 +47,7 @@
import android.view.MenuItem.OnActionExpandListener;
import android.view.View;
import android.view.ViewGroup;
+import android.view.ViewStub;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.BaseAdapter;
@@ -74,9 +76,13 @@
static final String EXTRA_STATE = "state";
+ State mState;
RootsCache mRoots;
SearchManager mSearchManager;
+ DrawerController mDrawer;
+ @LayoutRes
+ private int mLayoutId;
private final String mTag;
public abstract State getDisplayState();
@@ -87,16 +93,28 @@
abstract void onDirectoryChanged(int anim);
abstract void updateActionBar();
abstract void saveStackBlocking();
+ abstract State buildDefaultState();
- public BaseActivity(String tag) {
+ public BaseActivity(@LayoutRes int layoutId, String tag) {
+ mLayoutId = layoutId;
mTag = tag;
}
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
+
+ mState = (icicle != null)
+ ? icicle.<State>getParcelable(EXTRA_STATE)
+ : buildDefaultState();
+
+ setContentView(mLayoutId);
+
mRoots = DocumentsApplication.getRootsCache(this);
mSearchManager = new SearchManager();
+
+ // Base classes must update result in their onCreate.
+ setResult(Activity.RESULT_CANCELED);
}
@Override
@@ -525,6 +543,30 @@
}
}
+ @Override
+ public void onBackPressed() {
+ // While action bar is expanded, the state stack UI is hidden.
+ if (mSearchManager.cancelSearch()) {
+ return;
+ }
+
+ if (!mState.stackTouched) {
+ super.onBackPressed();
+ return;
+ }
+
+ final int size = mState.stack.size();
+
+ if (mDrawer.isOpen()) {
+ mDrawer.setOpen(false);
+ } else if (size > 1) {
+ mState.stack.pop();
+ onCurrentDirectoryChanged(ANIM_UP);
+ } else {
+ super.onBackPressed();
+ }
+ }
+
public void onStackPicked(DocumentStack stack) {
try {
// Update the restored stack to ensure we have freshest data
diff --git a/packages/DocumentsUI/src/com/android/documentsui/CopyService.java b/packages/DocumentsUI/src/com/android/documentsui/CopyService.java
index 14155d5..8b92331 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/CopyService.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/CopyService.java
@@ -167,7 +167,7 @@
if (mFailedFiles.size() > 0) {
final Context context = getApplicationContext();
- final Intent navigateIntent = new Intent(context, StandaloneActivity.class);
+ final Intent navigateIntent = new Intent(context, FilesActivity.class);
navigateIntent.putExtra(EXTRA_STACK, (Parcelable) stack);
navigateIntent.putExtra(EXTRA_FAILURE, FAILURE_COPY);
navigateIntent.putParcelableArrayListExtra(EXTRA_SRC_LIST, mFailedFiles);
@@ -213,7 +213,7 @@
mIsCancelled = false;
final Context context = getApplicationContext();
- final Intent navigateIntent = new Intent(context, StandaloneActivity.class);
+ final Intent navigateIntent = new Intent(context, FilesActivity.class);
navigateIntent.putExtra(EXTRA_STACK, (Parcelable) stack);
final String contentTitle = getString(copying ? R.string.copy_notification_title
diff --git a/packages/DocumentsUI/src/com/android/documentsui/DirectoryFragment.java b/packages/DocumentsUI/src/com/android/documentsui/DirectoryFragment.java
index 704e607..240cdda 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/DirectoryFragment.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/DirectoryFragment.java
@@ -738,7 +738,7 @@
new GetDocumentsTask() {
@Override
void onDocumentsReady(List<DocumentInfo> docs) {
- // TODO: Implement support in standalone for opening multiple docs.
+ // TODO: Implement support in Files activity for opening multiple docs.
BaseActivity.get(DirectoryFragment.this).onDocumentsPicked(docs);
}
}.execute(selected);
@@ -1684,7 +1684,7 @@
private FragmentTuner pickFragmentTuner(final State state) {
return state.action == ACTION_BROWSE_ALL
- ? new StandaloneTuner()
+ ? new FilesTuner()
: new DefaultTuner(state);
}
@@ -1749,7 +1749,7 @@
copyTo.setVisible(manageOrBrowse && dirType != TYPE_RECENT_OPEN);
moveTo.setVisible(SystemProperties.getBoolean("debug.documentsui.enable_move", false));
- // Only shown in standalone mode.
+ // Only shown in files mode.
copyToClipboard.setVisible(false);
}
@@ -1758,9 +1758,9 @@
}
/**
- * Provides support for Standalone specific specializations of DirectoryFragment.
+ * Provides support for Files activity specific specializations of DirectoryFragment.
*/
- private static final class StandaloneTuner implements FragmentTuner {
+ private static final class FilesTuner implements FragmentTuner {
@Override
public void updateActionMenu(Menu menu, int dirType, boolean canDelete) {
menu.findItem(R.id.menu_share).setVisible(true);
diff --git a/packages/DocumentsUI/src/com/android/documentsui/DocumentsActivity.java b/packages/DocumentsUI/src/com/android/documentsui/DocumentsActivity.java
index 2c6bdb3..fdc4bb0 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/DocumentsActivity.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/DocumentsActivity.java
@@ -25,7 +25,6 @@
import static com.android.documentsui.BaseActivity.State.ACTION_OPEN_TREE;
import static com.android.documentsui.DirectoryFragment.ANIM_DOWN;
import static com.android.documentsui.DirectoryFragment.ANIM_NONE;
-import static com.android.documentsui.DirectoryFragment.ANIM_UP;
import android.app.Activity;
import android.app.Fragment;
@@ -77,24 +76,18 @@
private Toolbar mRootsToolbar;
- private DrawerController mDrawer;
-
private DirectoryContainerView mDirectoryContainer;
- private State mState;
-
private ItemSelectedListener mStackListener;
private BaseAdapter mStackAdapter;
public DocumentsActivity() {
- super(TAG);
+ super(R.layout.docs_activity, TAG);
}
@Override
public void onCreate(Bundle icicle) {
- mState = (icicle != null)
- ? icicle.<State>getParcelable(EXTRA_STATE)
- : buildDefaultState();
+ super.onCreate(icicle);
final Resources res = getResources();
mShowAsDialog = res.getBoolean(R.bool.show_as_dialog) && mState.action != ACTION_MANAGE &&
@@ -104,11 +97,6 @@
setTheme(R.style.DocumentsNonDialogTheme);
}
- super.onCreate(icicle);
-
- setResult(Activity.RESULT_CANCELED);
- setContentView(R.layout.activity);
-
final Context context = this;
if (mShowAsDialog) {
@@ -191,7 +179,8 @@
}
}
- private State buildDefaultState() {
+ @Override
+ State buildDefaultState() {
State state = new State();
final Intent intent = getIntent();
@@ -455,30 +444,6 @@
}
@Override
- public void onBackPressed() {
- // While action bar is expanded, the state stack UI is hidden.
- if (mSearchManager.cancelSearch()) {
- return;
- }
-
- if (!mState.stackTouched) {
- super.onBackPressed();
- return;
- }
-
- final int size = mState.stack.size();
- if (size > 1) {
- mState.stack.pop();
- onCurrentDirectoryChanged(ANIM_UP);
- } else if (size == 1 && !mDrawer.isOpen()) {
- // TODO: open root drawer once we can capture back key
- super.onBackPressed();
- } else {
- super.onBackPressed();
- }
- }
-
- @Override
public State getDisplayState() {
return mState;
}
diff --git a/packages/DocumentsUI/src/com/android/documentsui/DrawerController.java b/packages/DocumentsUI/src/com/android/documentsui/DrawerController.java
index cf16c3f..df3ac1b 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/DrawerController.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/DrawerController.java
@@ -35,6 +35,7 @@
abstract void setOpen(boolean open);
abstract void lockOpen();
abstract void lockClosed();
+ abstract boolean isPresent();
abstract boolean isOpen();
abstract boolean isUnlocked();
abstract void syncState();
@@ -104,6 +105,11 @@
}
@Override
+ boolean isPresent() {
+ return true;
+ }
+
+ @Override
void syncState() {
mToggle.syncState();
}
@@ -155,9 +161,7 @@
private static final class DummyDrawerController extends DrawerController {
@Override
- boolean isOpen() {
- return false;
- }
+ void setOpen(boolean open) {}
@Override
void syncState() {}
@@ -169,11 +173,21 @@
void lockClosed() {}
@Override
+ boolean isOpen() {
+ return false;
+ }
+
+ @Override
boolean isUnlocked() {
return true;
}
@Override
+ boolean isPresent() {
+ return false;
+ }
+
+ @Override
boolean onOptionsItemSelected(MenuItem item) {
return false;
}
@@ -189,8 +203,5 @@
@Override
public void onDrawerStateChanged(int newState) {}
-
- @Override
- void setOpen(boolean open) {}
}
}
diff --git a/packages/DocumentsUI/src/com/android/documentsui/StandaloneActivity.java b/packages/DocumentsUI/src/com/android/documentsui/FilesActivity.java
similarity index 91%
rename from packages/DocumentsUI/src/com/android/documentsui/StandaloneActivity.java
rename to packages/DocumentsUI/src/com/android/documentsui/FilesActivity.java
index 7ca3954..7c445bf 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/StandaloneActivity.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/FilesActivity.java
@@ -18,7 +18,6 @@
import static com.android.documentsui.DirectoryFragment.ANIM_DOWN;
import static com.android.documentsui.DirectoryFragment.ANIM_NONE;
-import static com.android.documentsui.DirectoryFragment.ANIM_UP;
import android.app.Activity;
import android.app.FragmentManager;
@@ -57,7 +56,7 @@
/**
* Standalone file management activity.
*/
-public class StandaloneActivity extends BaseActivity {
+public class FilesActivity extends BaseActivity {
public static final String TAG = "StandaloneFileManagement";
static final boolean DEBUG = false;
@@ -66,32 +65,22 @@
private Spinner mToolbarStack;
private Toolbar mRootsToolbar;
private DirectoryContainerView mDirectoryContainer;
- private State mState;
private ItemSelectedListener mStackListener;
private BaseAdapter mStackAdapter;
private DocumentClipper mClipper;
- private DrawerController mDrawer;
- private boolean mCompactMode;
- public StandaloneActivity() {
- super(TAG);
+ public FilesActivity() {
+ super(R.layout.files_activity, TAG);
}
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
- setResult(Activity.RESULT_CANCELED);
- setContentView(R.layout.activity);
-
final Context context = this;
mDirectoryContainer = (DirectoryContainerView) findViewById(R.id.container_directory);
- mState = (icicle != null)
- ? icicle.<State> getParcelable(EXTRA_STATE)
- : buildDefaultState();
-
mToolbar = (Toolbar) findViewById(R.id.toolbar);
mToolbar.setTitleTextAppearance(context,
android.R.style.TextAppearance_DeviceDefault_Widget_ActionBar_Title);
@@ -109,19 +98,12 @@
setActionBar(mToolbar);
-
- // "show as dialog" is true on BIG screens. But we *assume* a big screen
- // and specialize for smaller screens by moving roots into an auto-hide drawer.
- // This works in conjunction with the specialized layouts defined for sw720dp.
- mCompactMode = !getResources().getBoolean(R.bool.show_as_dialog);
-
- if (mCompactMode) {
+ mClipper = new DocumentClipper(this);
+ mDrawer = DrawerController.create(this);
+ if (mDrawer.isPresent()) {
setTheme(R.style.DocumentsNonDialogTheme);
}
- mDrawer = DrawerController.create(this);
-
- mClipper = new DocumentClipper(this);
RootsFragment.show(getFragmentManager(), null);
if (!mState.restored) {
@@ -144,7 +126,8 @@
}
}
- private State buildDefaultState() {
+ @Override
+ State buildDefaultState() {
State state = new State();
final Intent intent = getIntent();
@@ -179,7 +162,7 @@
public void updateActionBar() {
final RootInfo root = getCurrentRoot();
- if (mCompactMode) {
+ if (mDrawer.isPresent()) {
mToolbar.setNavigationIcon(R.drawable.ic_hamburger);
mToolbar.setNavigationContentDescription(R.string.drawer_open);
mToolbar.setNavigationOnClickListener(
@@ -263,22 +246,6 @@
}
@Override
- public void onBackPressed() {
- if (!mState.stackTouched) {
- super.onBackPressed();
- return;
- }
-
- final int size = mState.stack.size();
- if (size > 1) {
- mState.stack.pop();
- onCurrentDirectoryChanged(ANIM_UP);
- } else {
- super.onBackPressed();
- }
- }
-
- @Override
public State getDisplayState() {
return mState;
}
diff --git a/packages/SettingsLib/res/values/dimens.xml b/packages/SettingsLib/res/values/dimens.xml
index 1c4b05f..3ad8f21 100644
--- a/packages/SettingsLib/res/values/dimens.xml
+++ b/packages/SettingsLib/res/values/dimens.xml
@@ -21,4 +21,6 @@
<!-- The translation for disappearing security views after having solved them. -->
<dimen name="disappear_y_translation">-32dp</dimen>
-</resources>
\ No newline at end of file
+
+ <dimen name="circle_avatar_size">40dp</dimen>
+</resources>
diff --git a/packages/SettingsLib/res/values/strings.xml b/packages/SettingsLib/res/values/strings.xml
index b03f100..9b1f103 100644
--- a/packages/SettingsLib/res/values/strings.xml
+++ b/packages/SettingsLib/res/values/strings.xml
@@ -195,4 +195,34 @@
<!-- Content description of the WIFI signal when it is full for accessibility (not shown on the screen). [CHAR LIMIT=NONE] -->
<string name="accessibility_wifi_signal_full">Wifi signal full.</string>
+ <!-- Label for kernel threads in battery usage -->
+ <string name="process_kernel_label">Android OS</string>
+ <!-- Title of data usage item that represents all uninstalled applications. [CHAR LIMIT=48] -->
+ <string name="data_usage_uninstalled_apps">Removed apps</string>
+ <!-- Title of data usage item that represents all uninstalled applications or removed users. [CHAR LIMIT=48] -->
+ <string name="data_usage_uninstalled_apps_users">Removed apps and users</string>
+
+ <!-- Tethering controls, item title to go into the tethering settings -->
+ <!-- Tethering controls, item title to go into the tethering settings when only USB tethering is available [CHAR LIMIT=25]-->
+ <string name="tether_settings_title_usb">USB tethering</string>
+ <!-- Tethering controls, item title to go into the tethering settings when only Wifi tethering is available [CHAR LIMIT=25]-->
+ <string name="tether_settings_title_wifi">Portable hotspot</string>
+ <!-- Tethering controls, item title to go into the tethering settings when only Bluetooth tethering is available [CHAR LIMIT=25]-->
+ <string name="tether_settings_title_bluetooth">Bluetooth tethering</string>
+ <!-- Tethering controls, item title to go into the tethering settings when USB and Bluetooth tethering are available [CHAR LIMIT=25]-->
+ <string name="tether_settings_title_usb_bluetooth">Tethering</string>
+ <!-- Tethering controls, item title to go into the tethering settings when USB, Bluetooth and Wifi tethering are available [CHAR LIMIT=25]-->
+ <string name="tether_settings_title_all">Tethering & portable hotspot</string>
+
+ <!-- Title for a work profile. [CHAR LIMIT=25] -->
+ <string name="managed_user_title">Work profile</string>
+
+ <!-- Title for Guest user [CHAR LIMIT=35] -->
+ <string name="user_guest">Guest</string>
+
+ <!-- Manage apps, individual app screen, substituted for the application's label when the app's label CAN NOT be determined.-->
+ <string name="unknown">Unknown</string>
+
+ <!-- [CHAR LIMIT=NONE] Label of a running process that represents another user -->
+ <string name="running_process_item_user_label">User: <xliff:g id="user_name">%1$s</xliff:g></string>
</resources>
diff --git a/packages/SettingsLib/src/com/android/settingslib/Utils.java b/packages/SettingsLib/src/com/android/settingslib/Utils.java
new file mode 100644
index 0000000..621a09cd
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/Utils.java
@@ -0,0 +1,84 @@
+package com.android.settingslib;
+
+import android.content.Context;
+import android.content.pm.UserInfo;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.graphics.drawable.Drawable;
+import android.net.ConnectivityManager;
+import android.os.UserManager;
+
+import com.android.internal.util.UserIcons;
+import com.android.settingslib.drawable.CircleFramedDrawable;
+
+public final class Utils {
+
+ /**
+ * Return string resource that best describes combination of tethering
+ * options available on this device.
+ */
+ public static int getTetheringLabel(ConnectivityManager cm) {
+ String[] usbRegexs = cm.getTetherableUsbRegexs();
+ String[] wifiRegexs = cm.getTetherableWifiRegexs();
+ String[] bluetoothRegexs = cm.getTetherableBluetoothRegexs();
+
+ boolean usbAvailable = usbRegexs.length != 0;
+ boolean wifiAvailable = wifiRegexs.length != 0;
+ boolean bluetoothAvailable = bluetoothRegexs.length != 0;
+
+ if (wifiAvailable && usbAvailable && bluetoothAvailable) {
+ return R.string.tether_settings_title_all;
+ } else if (wifiAvailable && usbAvailable) {
+ return R.string.tether_settings_title_all;
+ } else if (wifiAvailable && bluetoothAvailable) {
+ return R.string.tether_settings_title_all;
+ } else if (wifiAvailable) {
+ return R.string.tether_settings_title_wifi;
+ } else if (usbAvailable && bluetoothAvailable) {
+ return R.string.tether_settings_title_usb_bluetooth;
+ } else if (usbAvailable) {
+ return R.string.tether_settings_title_usb;
+ } else {
+ return R.string.tether_settings_title_bluetooth;
+ }
+ }
+
+ /**
+ * Returns a label for the user, in the form of "User: user name" or "Work profile".
+ */
+ public static String getUserLabel(Context context, UserInfo info) {
+ String name = info != null ? info.name : null;
+ if (info.isManagedProfile()) {
+ // We use predefined values for managed profiles
+ return context.getString(R.string.managed_user_title);
+ } else if (info.isGuest()) {
+ name = context.getString(R.string.user_guest);
+ }
+ if (name == null && info != null) {
+ name = Integer.toString(info.id);
+ } else if (info == null) {
+ name = context.getString(R.string.unknown);
+ }
+ return context.getResources().getString(R.string.running_process_item_user_label, name);
+ }
+
+ /**
+ * Returns a circular icon for a user.
+ */
+ public static Drawable getUserIcon(Context context, UserManager um, UserInfo user) {
+ if (user.isManagedProfile()) {
+ // We use predefined values for managed profiles
+ Bitmap b = BitmapFactory.decodeResource(context.getResources(),
+ com.android.internal.R.drawable.ic_corp_icon);
+ return CircleFramedDrawable.getInstance(context, b);
+ }
+ if (user.iconPath != null) {
+ Bitmap icon = um.getUserIcon(user.id);
+ if (icon != null) {
+ return CircleFramedDrawable.getInstance(context, icon);
+ }
+ }
+ return CircleFramedDrawable.getInstance(context, UserIcons.convertToBitmap(
+ UserIcons.getDefaultUserIcon(user.id, /* light= */ false)));
+ }
+}
diff --git a/packages/SettingsLib/src/com/android/settingslib/drawable/CircleFramedDrawable.java b/packages/SettingsLib/src/com/android/settingslib/drawable/CircleFramedDrawable.java
new file mode 100644
index 0000000..278b57d
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/drawable/CircleFramedDrawable.java
@@ -0,0 +1,136 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settingslib.drawable;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.graphics.Bitmap;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.ColorFilter;
+import android.graphics.Paint;
+import android.graphics.Path;
+import android.graphics.PixelFormat;
+import android.graphics.PorterDuff;
+import android.graphics.PorterDuffXfermode;
+import android.graphics.Rect;
+import android.graphics.RectF;
+import android.graphics.drawable.Drawable;
+
+import com.android.settingslib.R;
+
+/**
+ * Converts the user avatar icon to a circularly clipped one.
+ * TODO: Move this to an internal framework class and share with the one in Keyguard.
+ */
+public class CircleFramedDrawable extends Drawable {
+
+ private final Bitmap mBitmap;
+ private final int mSize;
+ private final Paint mPaint;
+
+ private float mScale;
+ private Rect mSrcRect;
+ private RectF mDstRect;
+
+ public static CircleFramedDrawable getInstance(Context context, Bitmap icon) {
+ Resources res = context.getResources();
+ float iconSize = res.getDimension(R.dimen.circle_avatar_size);
+
+ CircleFramedDrawable instance = new CircleFramedDrawable(icon, (int) iconSize);
+ return instance;
+ }
+
+ public CircleFramedDrawable(Bitmap icon, int size) {
+ super();
+ mSize = size;
+
+ mBitmap = Bitmap.createBitmap(mSize, mSize, Bitmap.Config.ARGB_8888);
+ final Canvas canvas = new Canvas(mBitmap);
+
+ final int width = icon.getWidth();
+ final int height = icon.getHeight();
+ final int square = Math.min(width, height);
+
+ final Rect cropRect = new Rect((width - square) / 2, (height - square) / 2, square, square);
+ final RectF circleRect = new RectF(0f, 0f, mSize, mSize);
+
+ final Path fillPath = new Path();
+ fillPath.addArc(circleRect, 0f, 360f);
+
+ canvas.drawColor(0, PorterDuff.Mode.CLEAR);
+
+ // opaque circle matte
+ mPaint = new Paint();
+ mPaint.setAntiAlias(true);
+ mPaint.setColor(Color.BLACK);
+ mPaint.setStyle(Paint.Style.FILL);
+ canvas.drawPath(fillPath, mPaint);
+
+ // mask in the icon where the bitmap is opaque
+ mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
+ canvas.drawBitmap(icon, cropRect, circleRect, mPaint);
+
+ // prepare paint for frame drawing
+ mPaint.setXfermode(null);
+
+ mScale = 1f;
+
+ mSrcRect = new Rect(0, 0, mSize, mSize);
+ mDstRect = new RectF(0, 0, mSize, mSize);
+ }
+
+ @Override
+ public void draw(Canvas canvas) {
+ final float inside = mScale * mSize;
+ final float pad = (mSize - inside) / 2f;
+
+ mDstRect.set(pad, pad, mSize - pad, mSize - pad);
+ canvas.drawBitmap(mBitmap, mSrcRect, mDstRect, null);
+ }
+
+ public void setScale(float scale) {
+ mScale = scale;
+ }
+
+ public float getScale() {
+ return mScale;
+ }
+
+ @Override
+ public int getOpacity() {
+ return PixelFormat.TRANSLUCENT;
+ }
+
+ @Override
+ public void setAlpha(int alpha) {
+ }
+
+ @Override
+ public void setColorFilter(ColorFilter cf) {
+ }
+
+ @Override
+ public int getIntrinsicWidth() {
+ return mSize;
+ }
+
+ @Override
+ public int getIntrinsicHeight() {
+ return mSize;
+ }
+}
diff --git a/packages/SettingsLib/src/com/android/settingslib/net/SummaryForAllUidLoader.java b/packages/SettingsLib/src/com/android/settingslib/net/SummaryForAllUidLoader.java
new file mode 100644
index 0000000..572bae1
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/net/SummaryForAllUidLoader.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settingslib.net;
+
+import android.content.AsyncTaskLoader;
+import android.content.Context;
+import android.net.INetworkStatsSession;
+import android.net.NetworkStats;
+import android.net.NetworkTemplate;
+import android.os.Bundle;
+import android.os.RemoteException;
+
+public class SummaryForAllUidLoader extends AsyncTaskLoader<NetworkStats> {
+ private static final String KEY_TEMPLATE = "template";
+ private static final String KEY_START = "start";
+ private static final String KEY_END = "end";
+
+ private final INetworkStatsSession mSession;
+ private final Bundle mArgs;
+
+ public static Bundle buildArgs(NetworkTemplate template, long start, long end) {
+ final Bundle args = new Bundle();
+ args.putParcelable(KEY_TEMPLATE, template);
+ args.putLong(KEY_START, start);
+ args.putLong(KEY_END, end);
+ return args;
+ }
+
+ public SummaryForAllUidLoader(Context context, INetworkStatsSession session, Bundle args) {
+ super(context);
+ mSession = session;
+ mArgs = args;
+ }
+
+ @Override
+ protected void onStartLoading() {
+ super.onStartLoading();
+ forceLoad();
+ }
+
+ @Override
+ public NetworkStats loadInBackground() {
+ final NetworkTemplate template = mArgs.getParcelable(KEY_TEMPLATE);
+ final long start = mArgs.getLong(KEY_START);
+ final long end = mArgs.getLong(KEY_END);
+
+ try {
+ return mSession.getSummaryForAllUid(template, start, end, false);
+ } catch (RemoteException e) {
+ return null;
+ }
+ }
+
+ @Override
+ protected void onStopLoading() {
+ super.onStopLoading();
+ cancelLoad();
+ }
+
+ @Override
+ protected void onReset() {
+ super.onReset();
+ cancelLoad();
+ }
+}
diff --git a/packages/SettingsLib/src/com/android/settingslib/net/UidDetail.java b/packages/SettingsLib/src/com/android/settingslib/net/UidDetail.java
new file mode 100644
index 0000000..5e42281
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/net/UidDetail.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settingslib.net;
+
+import android.graphics.drawable.Drawable;
+
+public class UidDetail {
+ public CharSequence label;
+ public CharSequence contentDescription;
+ public CharSequence[] detailLabels;
+ public CharSequence[] detailContentDescriptions;
+ public Drawable icon;
+}
diff --git a/packages/SettingsLib/src/com/android/settingslib/net/UidDetailProvider.java b/packages/SettingsLib/src/com/android/settingslib/net/UidDetailProvider.java
new file mode 100644
index 0000000..224b967
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/net/UidDetailProvider.java
@@ -0,0 +1,194 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settingslib.net;
+
+import android.app.AppGlobals;
+import android.content.Context;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.IPackageManager;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.PackageManager.NameNotFoundException;
+import android.content.pm.UserInfo;
+import android.content.res.Resources;
+import android.graphics.drawable.Drawable;
+import android.net.ConnectivityManager;
+import android.net.TrafficStats;
+import android.os.UserManager;
+import android.os.UserHandle;
+import android.os.RemoteException;
+import android.text.TextUtils;
+import android.util.Log;
+import android.util.SparseArray;
+
+import com.android.settingslib.R;
+import com.android.settingslib.Utils;
+
+/**
+ * Return details about a specific UID, handling special cases like
+ * {@link TrafficStats#UID_TETHERING} and {@link UserInfo}.
+ */
+public class UidDetailProvider {
+ private static final String TAG = "DataUsage";
+ private final Context mContext;
+ private final SparseArray<UidDetail> mUidDetailCache;
+
+ public static final int OTHER_USER_RANGE_START = -2000;
+
+ public static int buildKeyForUser(int userHandle) {
+ return OTHER_USER_RANGE_START - userHandle;
+ }
+
+ public static boolean isKeyForUser(int key) {
+ return key <= OTHER_USER_RANGE_START;
+ }
+
+ public static int getUserIdForKey(int key) {
+ return OTHER_USER_RANGE_START - key;
+ }
+
+ public UidDetailProvider(Context context) {
+ mContext = context.getApplicationContext();
+ mUidDetailCache = new SparseArray<UidDetail>();
+ }
+
+ public void clearCache() {
+ synchronized (mUidDetailCache) {
+ mUidDetailCache.clear();
+ }
+ }
+
+ /**
+ * Resolve best descriptive label for the given UID.
+ */
+ public UidDetail getUidDetail(int uid, boolean blocking) {
+ UidDetail detail;
+
+ synchronized (mUidDetailCache) {
+ detail = mUidDetailCache.get(uid);
+ }
+
+ if (detail != null) {
+ return detail;
+ } else if (!blocking) {
+ return null;
+ }
+
+ detail = buildUidDetail(uid);
+
+ synchronized (mUidDetailCache) {
+ mUidDetailCache.put(uid, detail);
+ }
+
+ return detail;
+ }
+
+ /**
+ * Build {@link UidDetail} object, blocking until all {@link Drawable}
+ * lookup is finished.
+ */
+ private UidDetail buildUidDetail(int uid) {
+ final Resources res = mContext.getResources();
+ final PackageManager pm = mContext.getPackageManager();
+
+ final UidDetail detail = new UidDetail();
+ detail.label = pm.getNameForUid(uid);
+ detail.icon = pm.getDefaultActivityIcon();
+
+ // handle special case labels
+ switch (uid) {
+ case android.os.Process.SYSTEM_UID:
+ detail.label = res.getString(R.string.process_kernel_label);
+ detail.icon = pm.getDefaultActivityIcon();
+ return detail;
+ case TrafficStats.UID_REMOVED:
+ detail.label = res.getString(UserManager.supportsMultipleUsers()
+ ? R.string.data_usage_uninstalled_apps_users
+ : R.string.data_usage_uninstalled_apps);
+ detail.icon = pm.getDefaultActivityIcon();
+ return detail;
+ case TrafficStats.UID_TETHERING:
+ final ConnectivityManager cm = (ConnectivityManager) mContext.getSystemService(
+ Context.CONNECTIVITY_SERVICE);
+ detail.label = res.getString(Utils.getTetheringLabel(cm));
+ detail.icon = pm.getDefaultActivityIcon();
+ return detail;
+ }
+
+ final UserManager um = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
+
+ // Handle keys that are actually user handles
+ if (isKeyForUser(uid)) {
+ final int userHandle = getUserIdForKey(uid);
+ final UserInfo info = um.getUserInfo(userHandle);
+ if (info != null) {
+ detail.label = Utils.getUserLabel(mContext, info);
+ detail.icon = Utils.getUserIcon(mContext, um, info);
+ return detail;
+ }
+ }
+
+ // otherwise fall back to using packagemanager labels
+ final String[] packageNames = pm.getPackagesForUid(uid);
+ final int length = packageNames != null ? packageNames.length : 0;
+ try {
+ final int userId = UserHandle.getUserId(uid);
+ UserHandle userHandle = new UserHandle(userId);
+ IPackageManager ipm = AppGlobals.getPackageManager();
+ if (length == 1) {
+ final ApplicationInfo info = ipm.getApplicationInfo(packageNames[0],
+ 0 /* no flags */, userId);
+ if (info != null) {
+ detail.label = info.loadLabel(pm).toString();
+ detail.icon = um.getBadgedIconForUser(info.loadIcon(pm),
+ new UserHandle(userId));
+ }
+ } else if (length > 1) {
+ detail.detailLabels = new CharSequence[length];
+ detail.detailContentDescriptions = new CharSequence[length];
+ for (int i = 0; i < length; i++) {
+ final String packageName = packageNames[i];
+ final PackageInfo packageInfo = pm.getPackageInfo(packageName, 0);
+ final ApplicationInfo appInfo = ipm.getApplicationInfo(packageName,
+ 0 /* no flags */, userId);
+
+ if (appInfo != null) {
+ detail.detailLabels[i] = appInfo.loadLabel(pm).toString();
+ detail.detailContentDescriptions[i] = um.getBadgedLabelForUser(
+ detail.detailLabels[i], userHandle);
+ if (packageInfo.sharedUserLabel != 0) {
+ detail.label = pm.getText(packageName, packageInfo.sharedUserLabel,
+ packageInfo.applicationInfo).toString();
+ detail.icon = um.getBadgedIconForUser(appInfo.loadIcon(pm), userHandle);
+ }
+ }
+ }
+ }
+ detail.contentDescription = um.getBadgedLabelForUser(detail.label, userHandle);
+ } catch (NameNotFoundException e) {
+ Log.w(TAG, "Error while building UI detail for uid "+uid, e);
+ } catch (RemoteException e) {
+ Log.w(TAG, "Error while building UI detail for uid "+uid, e);
+ }
+
+ if (TextUtils.isEmpty(detail.label)) {
+ detail.label = Integer.toString(uid);
+ }
+
+ return detail;
+ }
+}
diff --git a/packages/SystemUI/res/values-af/strings.xml b/packages/SystemUI/res/values-af/strings.xml
index 26d5274..9294a16 100644
--- a/packages/SystemUI/res/values-af/strings.xml
+++ b/packages/SystemUI/res/values-af/strings.xml
@@ -433,4 +433,6 @@
<string name="remove_from_settings" msgid="8389591916603406378">"Verwyder uit Instellings"</string>
<string name="remove_from_settings_prompt" msgid="6069085993355887748">"Verwyder Stelsel-UI-ontvanger uit Instellings en staak die gebruik van al sy kenmerke?"</string>
<string name="activity_not_found" msgid="348423244327799974">"Program is nie op jou toestel geïnstalleer nie"</string>
+ <string name="clock_seconds" msgid="7689554147579179507">"Wys horlosiesekondes"</string>
+ <string name="clock_seconds_desc" msgid="6282693067130470675">"Wys horlosiesekondes op die statusbalk. Sal batterylewe dalk beïnvloed."</string>
</resources>
diff --git a/packages/SystemUI/res/values-am/strings.xml b/packages/SystemUI/res/values-am/strings.xml
index e61b6c3..13f768d 100644
--- a/packages/SystemUI/res/values-am/strings.xml
+++ b/packages/SystemUI/res/values-am/strings.xml
@@ -433,4 +433,6 @@
<string name="remove_from_settings" msgid="8389591916603406378">"ከቅንብሮች አስወግድ"</string>
<string name="remove_from_settings_prompt" msgid="6069085993355887748">"ከቅንብሮች ላይ የስርዓት በይነገጽ መቃኛ ተወግዶ ሁሉም ባህሪዎቹን መጠቀም ይቁም?"</string>
<string name="activity_not_found" msgid="348423244327799974">"መተግበሪያ በእርስዎ መሣሪያ ላይ አልተጫነም"</string>
+ <string name="clock_seconds" msgid="7689554147579179507">"የሰዓት ሰከንዶችን አሳይ"</string>
+ <string name="clock_seconds_desc" msgid="6282693067130470675">"የሰዓት ሰከንዶችን በሁኔታ አሞሌ ውስጥ አሳይ። በባትሪ ዕድሜ ላይ ተጽዕኖ ሊኖርው ይችል ይሆናል።"</string>
</resources>
diff --git a/packages/SystemUI/res/values-ar/strings.xml b/packages/SystemUI/res/values-ar/strings.xml
index 2e358a1..6889a43 100644
--- a/packages/SystemUI/res/values-ar/strings.xml
+++ b/packages/SystemUI/res/values-ar/strings.xml
@@ -437,4 +437,6 @@
<string name="remove_from_settings" msgid="8389591916603406378">"إزالة من الإعدادات"</string>
<string name="remove_from_settings_prompt" msgid="6069085993355887748">"هل تريد إزالة أداة ضبط واجهة مستخدم النظام من الإعدادات وإيقاف استخدام كل ميزاتها؟"</string>
<string name="activity_not_found" msgid="348423244327799974">"التطبيق غير مثبّت على جهازك"</string>
+ <string name="clock_seconds" msgid="7689554147579179507">"عرض ثواني الساعة"</string>
+ <string name="clock_seconds_desc" msgid="6282693067130470675">"عرض ثواني الساعة في شريط الحالة. قد يؤثر ذلك في عمر البطارية."</string>
</resources>
diff --git a/packages/SystemUI/res/values-az-rAZ/strings.xml b/packages/SystemUI/res/values-az-rAZ/strings.xml
index b82b42e..51513bd 100644
--- a/packages/SystemUI/res/values-az-rAZ/strings.xml
+++ b/packages/SystemUI/res/values-az-rAZ/strings.xml
@@ -433,4 +433,6 @@
<string name="remove_from_settings" msgid="8389591916603406378">"Ayarlardan Silin"</string>
<string name="remove_from_settings_prompt" msgid="6069085993355887748">"System UI Tuner Ayarlardan silinsin və onun bütün funksiyalarından istifadə dayandırılsın?"</string>
<string name="activity_not_found" msgid="348423244327799974">"Tətbiq cihazınızda quraşdırılmayıb"</string>
+ <string name="clock_seconds" msgid="7689554147579179507">"Saatın saniyəsini göstərin"</string>
+ <string name="clock_seconds_desc" msgid="6282693067130470675">"Saatın saniyəsini status panelində göstərin. Batareyaya təsir edə bilər."</string>
</resources>
diff --git a/packages/SystemUI/res/values-bg/strings.xml b/packages/SystemUI/res/values-bg/strings.xml
index 82ace52..014d802 100644
--- a/packages/SystemUI/res/values-bg/strings.xml
+++ b/packages/SystemUI/res/values-bg/strings.xml
@@ -433,4 +433,6 @@
<string name="remove_from_settings" msgid="8389591916603406378">"Премахване от „Настройки“"</string>
<string name="remove_from_settings_prompt" msgid="6069085993355887748">"Да се премахне ли от „Настройки“ тунерът на системния потребителски интерфейс и да се спре ли използването на всичките му функции?"</string>
<string name="activity_not_found" msgid="348423244327799974">"Приложението не е инсталирано на устройството ви"</string>
+ <string name="clock_seconds" msgid="7689554147579179507">"Показване на секундите на часовника"</string>
+ <string name="clock_seconds_desc" msgid="6282693067130470675">"Показване на секундите на часовника в лентата на състоянието. Може да се отрази на живота на батерията."</string>
</resources>
diff --git a/packages/SystemUI/res/values-bn-rBD/strings.xml b/packages/SystemUI/res/values-bn-rBD/strings.xml
index 884fc42..0860019 100644
--- a/packages/SystemUI/res/values-bn-rBD/strings.xml
+++ b/packages/SystemUI/res/values-bn-rBD/strings.xml
@@ -433,4 +433,6 @@
<string name="remove_from_settings" msgid="8389591916603406378">"সেটিংস থেকে সরান"</string>
<string name="remove_from_settings_prompt" msgid="6069085993355887748">"সেটিংস থেকে সিস্টেম UI টিউনার সরাতে এবং এটির সমস্ত বৈশিষ্ট্য ব্যবহার করা বন্ধ করতে চান?"</string>
<string name="activity_not_found" msgid="348423244327799974">"আপনার ডিভাইসে অ্যাপ্লিকেশান ইনস্টল করা নেই"</string>
+ <string name="clock_seconds" msgid="7689554147579179507">"ঘড়ির সেকেন্ড দেখায়"</string>
+ <string name="clock_seconds_desc" msgid="6282693067130470675">"স্থিতি দন্ডে ঘড়ির সেকেন্ড দেখায়৷ ব্যাটারি লাইফকে প্রভাবিত করতে পারে৷"</string>
</resources>
diff --git a/packages/SystemUI/res/values-ca/strings.xml b/packages/SystemUI/res/values-ca/strings.xml
index cc04fd6..7dd11eb 100644
--- a/packages/SystemUI/res/values-ca/strings.xml
+++ b/packages/SystemUI/res/values-ca/strings.xml
@@ -435,4 +435,6 @@
<string name="remove_from_settings" msgid="8389591916603406378">"Treu de Configuració"</string>
<string name="remove_from_settings_prompt" msgid="6069085993355887748">"Vols treure el Configurador de la UI del sistema de Configuració i deixar d\'utilitzar-ne totes les funcions?"</string>
<string name="activity_not_found" msgid="348423244327799974">"L\'aplicació no està instal·lada al dispositiu"</string>
+ <string name="clock_seconds" msgid="7689554147579179507">"Mostra els segons del rellotge"</string>
+ <string name="clock_seconds_desc" msgid="6282693067130470675">"Mostra els segons del rellotge a la barra d\'estat. Això pot afectar la durada de la bateria."</string>
</resources>
diff --git a/packages/SystemUI/res/values-cs/strings.xml b/packages/SystemUI/res/values-cs/strings.xml
index 7f94577..4d96a01 100644
--- a/packages/SystemUI/res/values-cs/strings.xml
+++ b/packages/SystemUI/res/values-cs/strings.xml
@@ -437,4 +437,6 @@
<string name="remove_from_settings" msgid="8389591916603406378">"Odstranit z Nastavení"</string>
<string name="remove_from_settings_prompt" msgid="6069085993355887748">"Chcete nástroj na ladění uživatelského rozhraní systému odstranit z Nastavení a přestat používat všechny jeho funkce?"</string>
<string name="activity_not_found" msgid="348423244327799974">"Aplikace není v zařízení nainstalována."</string>
+ <string name="clock_seconds" msgid="7689554147579179507">"Zobrazit sekundovou ručičku"</string>
+ <string name="clock_seconds_desc" msgid="6282693067130470675">"Na stavovém řádku se bude zobrazovat sekundová ručička. Může být ovlivněna výdrž baterie."</string>
</resources>
diff --git a/packages/SystemUI/res/values-da/strings.xml b/packages/SystemUI/res/values-da/strings.xml
index 2129f03..7f005a3 100644
--- a/packages/SystemUI/res/values-da/strings.xml
+++ b/packages/SystemUI/res/values-da/strings.xml
@@ -433,4 +433,6 @@
<string name="remove_from_settings" msgid="8389591916603406378">"Fjern fra Indstillinger"</string>
<string name="remove_from_settings_prompt" msgid="6069085993355887748">"Vil du fjerne System UI Tuner fra Indstillinger og stoppe med at bruge alle dens funktioner?"</string>
<string name="activity_not_found" msgid="348423244327799974">"Applikationen er ikke installeret på din enhed."</string>
+ <string name="clock_seconds" msgid="7689554147579179507">"Vis sekunder"</string>
+ <string name="clock_seconds_desc" msgid="6282693067130470675">"Vis sekunder i statuslinjen. Dette kan påvirke batteriets levetid."</string>
</resources>
diff --git a/packages/SystemUI/res/values-de/strings.xml b/packages/SystemUI/res/values-de/strings.xml
index 30a2baf..36f3c98 100644
--- a/packages/SystemUI/res/values-de/strings.xml
+++ b/packages/SystemUI/res/values-de/strings.xml
@@ -435,4 +435,6 @@
<string name="remove_from_settings" msgid="8389591916603406378">"Aus \"Einstellungen\" entfernen"</string>
<string name="remove_from_settings_prompt" msgid="6069085993355887748">"System UI Tuner aus \"Einstellungen\" entfernen und die Verwendung von allen zugehörigen Funktionen beenden?"</string>
<string name="activity_not_found" msgid="348423244327799974">"Die App ist nicht auf Ihrem Gerät installiert."</string>
+ <string name="clock_seconds" msgid="7689554147579179507">"Uhrsekunden anzeigen"</string>
+ <string name="clock_seconds_desc" msgid="6282693067130470675">"Uhrsekunden in der Statusleiste anzeigen. Kann sich auf die Akkulaufzeit auswirken."</string>
</resources>
diff --git a/packages/SystemUI/res/values-el/strings.xml b/packages/SystemUI/res/values-el/strings.xml
index f2fc602..8e73b21 100644
--- a/packages/SystemUI/res/values-el/strings.xml
+++ b/packages/SystemUI/res/values-el/strings.xml
@@ -435,4 +435,6 @@
<string name="remove_from_settings" msgid="8389591916603406378">"Κατάργηση από τις Ρυθμίσεις"</string>
<string name="remove_from_settings_prompt" msgid="6069085993355887748">"Κατάργηση System UI Tuner από τις Ρυθμίσεις και διακοπή χρήσης όλων των λειτουργιών του;"</string>
<string name="activity_not_found" msgid="348423244327799974">"Η εφαρμογή δεν έχει εγκατασταθεί στη συσκευή σας"</string>
+ <string name="clock_seconds" msgid="7689554147579179507">"Εμφάνιση δευτερολέπτων ρολογιού"</string>
+ <string name="clock_seconds_desc" msgid="6282693067130470675">"Εμφάνιση δευτερολέπτων ρολογιού στη γραμμή κατάστασης. Ενδέχεται να επηρεάσει τη διάρκεια ζωής της μπαταρίας."</string>
</resources>
diff --git a/packages/SystemUI/res/values-en-rAU/strings.xml b/packages/SystemUI/res/values-en-rAU/strings.xml
index f1aafb6..0b49955 100644
--- a/packages/SystemUI/res/values-en-rAU/strings.xml
+++ b/packages/SystemUI/res/values-en-rAU/strings.xml
@@ -433,4 +433,6 @@
<string name="remove_from_settings" msgid="8389591916603406378">"Remove from settings"</string>
<string name="remove_from_settings_prompt" msgid="6069085993355887748">"Remove System UI Tuner from Settings and stop using all of its features?"</string>
<string name="activity_not_found" msgid="348423244327799974">"Application is not installed on your device"</string>
+ <string name="clock_seconds" msgid="7689554147579179507">"Show clock seconds"</string>
+ <string name="clock_seconds_desc" msgid="6282693067130470675">"Show clock seconds in the status bar. May impact battery life."</string>
</resources>
diff --git a/packages/SystemUI/res/values-en-rGB/strings.xml b/packages/SystemUI/res/values-en-rGB/strings.xml
index f1aafb6..0b49955 100644
--- a/packages/SystemUI/res/values-en-rGB/strings.xml
+++ b/packages/SystemUI/res/values-en-rGB/strings.xml
@@ -433,4 +433,6 @@
<string name="remove_from_settings" msgid="8389591916603406378">"Remove from settings"</string>
<string name="remove_from_settings_prompt" msgid="6069085993355887748">"Remove System UI Tuner from Settings and stop using all of its features?"</string>
<string name="activity_not_found" msgid="348423244327799974">"Application is not installed on your device"</string>
+ <string name="clock_seconds" msgid="7689554147579179507">"Show clock seconds"</string>
+ <string name="clock_seconds_desc" msgid="6282693067130470675">"Show clock seconds in the status bar. May impact battery life."</string>
</resources>
diff --git a/packages/SystemUI/res/values-en-rIN/strings.xml b/packages/SystemUI/res/values-en-rIN/strings.xml
index f1aafb6..0b49955 100644
--- a/packages/SystemUI/res/values-en-rIN/strings.xml
+++ b/packages/SystemUI/res/values-en-rIN/strings.xml
@@ -433,4 +433,6 @@
<string name="remove_from_settings" msgid="8389591916603406378">"Remove from settings"</string>
<string name="remove_from_settings_prompt" msgid="6069085993355887748">"Remove System UI Tuner from Settings and stop using all of its features?"</string>
<string name="activity_not_found" msgid="348423244327799974">"Application is not installed on your device"</string>
+ <string name="clock_seconds" msgid="7689554147579179507">"Show clock seconds"</string>
+ <string name="clock_seconds_desc" msgid="6282693067130470675">"Show clock seconds in the status bar. May impact battery life."</string>
</resources>
diff --git a/packages/SystemUI/res/values-es-rUS/strings.xml b/packages/SystemUI/res/values-es-rUS/strings.xml
index 5136545..c4dca9c 100644
--- a/packages/SystemUI/res/values-es-rUS/strings.xml
+++ b/packages/SystemUI/res/values-es-rUS/strings.xml
@@ -435,4 +435,6 @@
<string name="remove_from_settings" msgid="8389591916603406378">"Quitar de Configuración"</string>
<string name="remove_from_settings_prompt" msgid="6069085993355887748">"¿Quieres quitar el sintonizador de IU del sistema de Configuración y dejar de utilizar todas sus funciones?"</string>
<string name="activity_not_found" msgid="348423244327799974">"La aplicación no está instalada en el dispositivo"</string>
+ <string name="clock_seconds" msgid="7689554147579179507">"Mostrar los segundos del reloj"</string>
+ <string name="clock_seconds_desc" msgid="6282693067130470675">"Muestra los segundos del reloj en la barra de estado. Puede afectar la duración de la batería."</string>
</resources>
diff --git a/packages/SystemUI/res/values-es/strings.xml b/packages/SystemUI/res/values-es/strings.xml
index 82fd6fc..e316a94 100644
--- a/packages/SystemUI/res/values-es/strings.xml
+++ b/packages/SystemUI/res/values-es/strings.xml
@@ -433,4 +433,6 @@
<string name="remove_from_settings" msgid="8389591916603406378">"Eliminar de Ajustes"</string>
<string name="remove_from_settings_prompt" msgid="6069085993355887748">"¿Eliminar el configurador de IU del sistema de Ajustes y dejar de utilizar sus funciones?"</string>
<string name="activity_not_found" msgid="348423244327799974">"La aplicación no está instalada en tu dispositivo"</string>
+ <string name="clock_seconds" msgid="7689554147579179507">"Mostrar los segundos del reloj"</string>
+ <string name="clock_seconds_desc" msgid="6282693067130470675">"Muestra los segundos del reloj en la barra de estado. Puede afectar a la duración de la batería."</string>
</resources>
diff --git a/packages/SystemUI/res/values-et-rEE/strings.xml b/packages/SystemUI/res/values-et-rEE/strings.xml
index dd3d823..a151bce 100644
--- a/packages/SystemUI/res/values-et-rEE/strings.xml
+++ b/packages/SystemUI/res/values-et-rEE/strings.xml
@@ -433,4 +433,6 @@
<string name="remove_from_settings" msgid="8389591916603406378">"Eemalda seadetest"</string>
<string name="remove_from_settings_prompt" msgid="6069085993355887748">"Kas eemaldada seadetest süsteemi kasutajaliidese tuuner ja lõpetada kõikide selle funktsioonide kasutamine?"</string>
<string name="activity_not_found" msgid="348423244327799974">"Rakendust pole teie seadmesse installitud"</string>
+ <string name="clock_seconds" msgid="7689554147579179507">"Kella sekundite kuvamine"</string>
+ <string name="clock_seconds_desc" msgid="6282693067130470675">"Olekuribal kella sekundite kuvamine. See võib mõjutada aku kasutusaega."</string>
</resources>
diff --git a/packages/SystemUI/res/values-eu-rES/strings.xml b/packages/SystemUI/res/values-eu-rES/strings.xml
index a856c09..37cdee7 100644
--- a/packages/SystemUI/res/values-eu-rES/strings.xml
+++ b/packages/SystemUI/res/values-eu-rES/strings.xml
@@ -433,4 +433,6 @@
<string name="remove_from_settings" msgid="8389591916603406378">"Kendu Ezarpenak ataletik"</string>
<string name="remove_from_settings_prompt" msgid="6069085993355887748">"Sistemako erabiltzaile-interfazearen konfiguratzailea ezarpenetatik kendu nahi duzu, eta haren eginbide guztiak erabiltzeari utzi nahi diozu?"</string>
<string name="activity_not_found" msgid="348423244327799974">"Aplikazioa ez dago gailuan instalatuta"</string>
+ <string name="clock_seconds" msgid="7689554147579179507">"Erakutsi erlojuko segundoak"</string>
+ <string name="clock_seconds_desc" msgid="6282693067130470675">"Erakutsi erlojuko segundoak egoera-barran. Baliteke bateria gehiago erabiltzea."</string>
</resources>
diff --git a/packages/SystemUI/res/values-fa/strings.xml b/packages/SystemUI/res/values-fa/strings.xml
index 412f808..80d0918 100644
--- a/packages/SystemUI/res/values-fa/strings.xml
+++ b/packages/SystemUI/res/values-fa/strings.xml
@@ -433,4 +433,6 @@
<string name="remove_from_settings" msgid="8389591916603406378">"حذف از تنظیمات"</string>
<string name="remove_from_settings_prompt" msgid="6069085993355887748">"«تنظیمکننده واسط کاربری سیستم» از تنظیمات حذف شود و همه ویژگیهای آن متوقف شوند؟"</string>
<string name="activity_not_found" msgid="348423244327799974">"برنامه در دستگاه شما نصب نیست"</string>
+ <string name="clock_seconds" msgid="7689554147579179507">"نمایش ثانیههای ساعت"</string>
+ <string name="clock_seconds_desc" msgid="6282693067130470675">"ثانیههای ساعت را در نوار وضعیت نشان میدهد. ممکن است بر ماندگاری باتری تأثیر بگذارد."</string>
</resources>
diff --git a/packages/SystemUI/res/values-fi/strings.xml b/packages/SystemUI/res/values-fi/strings.xml
index 836b136..b86247a 100644
--- a/packages/SystemUI/res/values-fi/strings.xml
+++ b/packages/SystemUI/res/values-fi/strings.xml
@@ -433,4 +433,6 @@
<string name="remove_from_settings" msgid="8389591916603406378">"Poista Asetuksista"</string>
<string name="remove_from_settings_prompt" msgid="6069085993355887748">"Haluatko poistaa System UI Tunerin Asetuksista ja lopettaa sen ominaisuuksien käytön?"</string>
<string name="activity_not_found" msgid="348423244327799974">"Sovellusta ei ole asennettu laitteellesi."</string>
+ <string name="clock_seconds" msgid="7689554147579179507">"Näytä sekunnit kellossa"</string>
+ <string name="clock_seconds_desc" msgid="6282693067130470675">"Näytä sekunnit tilapalkin kellossa. Tämä voi vaikuttaa akun kestoon."</string>
</resources>
diff --git a/packages/SystemUI/res/values-fr-rCA/strings.xml b/packages/SystemUI/res/values-fr-rCA/strings.xml
index 8c6773f..4e57f2b5 100644
--- a/packages/SystemUI/res/values-fr-rCA/strings.xml
+++ b/packages/SystemUI/res/values-fr-rCA/strings.xml
@@ -435,4 +435,6 @@
<string name="remove_from_settings" msgid="8389591916603406378">"Supprimer des paramètres"</string>
<string name="remove_from_settings_prompt" msgid="6069085993355887748">"Supprimer « System UI Tuner » des paramètres et arrêter d\'utiliser toutes ses fonctionnalités?"</string>
<string name="activity_not_found" msgid="348423244327799974">"L\'application n\'est pas installée sur votre appareil"</string>
+ <string name="clock_seconds" msgid="7689554147579179507">"Afficher les secondes de l\'horloge"</string>
+ <string name="clock_seconds_desc" msgid="6282693067130470675">"Afficher les secondes de l\'horloge dans la barre d\'état. Cela peut influer sur l\'autonomie de la pile."</string>
</resources>
diff --git a/packages/SystemUI/res/values-fr/strings.xml b/packages/SystemUI/res/values-fr/strings.xml
index 666c0ef..aada1eb 100644
--- a/packages/SystemUI/res/values-fr/strings.xml
+++ b/packages/SystemUI/res/values-fr/strings.xml
@@ -435,4 +435,6 @@
<string name="remove_from_settings" msgid="8389591916603406378">"Supprimer l\'outil des paramètres"</string>
<string name="remove_from_settings_prompt" msgid="6069085993355887748">"Supprimer System UI Tuner des paramètres et arrêter d\'utiliser toutes ses fonctionnalités ?"</string>
<string name="activity_not_found" msgid="348423244327799974">"L\'application n\'est pas installée sur votre appareil."</string>
+ <string name="clock_seconds" msgid="7689554147579179507">"Afficher les secondes sur l\'horloge"</string>
+ <string name="clock_seconds_desc" msgid="6282693067130470675">"Afficher les secondes dans la barre d\'état. Cela risque de réduire l\'autonomie de la batterie."</string>
</resources>
diff --git a/packages/SystemUI/res/values-gl-rES/strings.xml b/packages/SystemUI/res/values-gl-rES/strings.xml
index d192257..951809f 100644
--- a/packages/SystemUI/res/values-gl-rES/strings.xml
+++ b/packages/SystemUI/res/values-gl-rES/strings.xml
@@ -435,4 +435,6 @@
<string name="remove_from_settings" msgid="8389591916603406378">"Eliminar da Configuración"</string>
<string name="remove_from_settings_prompt" msgid="6069085993355887748">"Queres eliminar o configurador da IU do sistema da Configuración e deixar de usar todas as súas funcións?"</string>
<string name="activity_not_found" msgid="348423244327799974">"A aplicación non está instalada no teu dispositivo"</string>
+ <string name="clock_seconds" msgid="7689554147579179507">"Mostrar segundos do reloxo"</string>
+ <string name="clock_seconds_desc" msgid="6282693067130470675">"Mostra os segundos do reloxo na barra de estado. Pode influír na duración da batería."</string>
</resources>
diff --git a/packages/SystemUI/res/values-gu-rIN/strings.xml b/packages/SystemUI/res/values-gu-rIN/strings.xml
index 81dab35..02e4e52 100644
--- a/packages/SystemUI/res/values-gu-rIN/strings.xml
+++ b/packages/SystemUI/res/values-gu-rIN/strings.xml
@@ -433,4 +433,6 @@
<string name="remove_from_settings" msgid="8389591916603406378">"સેટિંગ્સમાંથી દૂર કરો"</string>
<string name="remove_from_settings_prompt" msgid="6069085993355887748">"સેટિંગ્સમાંથી સિસ્ટમ UI ટ્યૂનર દૂર કરી અને તેની તમામ સુવિધાઓનો ઉપયોગ કરવાનું બંધ કરીએ?"</string>
<string name="activity_not_found" msgid="348423244327799974">"તમારા ઉપકરણ પર એપ્લિકેશન ઇન્સ્ટોલ થયેલ નથી"</string>
+ <string name="clock_seconds" msgid="7689554147579179507">"ઘડિયાળ સેકન્ડ બતાવો"</string>
+ <string name="clock_seconds_desc" msgid="6282693067130470675">"ઘડિયાળ સેકન્ડ સ્થિતિ બારમાં બતાવો. બૅટરીની આવરદા પર અસર કરી શકે છે."</string>
</resources>
diff --git a/packages/SystemUI/res/values-hi/strings.xml b/packages/SystemUI/res/values-hi/strings.xml
index a4bf691..3ed090c 100644
--- a/packages/SystemUI/res/values-hi/strings.xml
+++ b/packages/SystemUI/res/values-hi/strings.xml
@@ -433,4 +433,6 @@
<string name="remove_from_settings" msgid="8389591916603406378">"सेटिंग से निकालें"</string>
<string name="remove_from_settings_prompt" msgid="6069085993355887748">"सेटिंग से सिस्टम UI ट्यूनर निकालें और इसकी सभी सुविधाओं का उपयोग रोक दें?"</string>
<string name="activity_not_found" msgid="348423244327799974">"ऐप्लिकेशन आपके डिवाइस पर इंस्टॉल नहीं है"</string>
+ <string name="clock_seconds" msgid="7689554147579179507">"घड़ी के सेकंड दिखाएं"</string>
+ <string name="clock_seconds_desc" msgid="6282693067130470675">"स्थिति बार में घड़ी के सेकंड दिखाएं. इससे बैटरी के जीवनकाल पर प्रभाव पड़ सकता है."</string>
</resources>
diff --git a/packages/SystemUI/res/values-hr/strings.xml b/packages/SystemUI/res/values-hr/strings.xml
index d18c04b..9698aba 100644
--- a/packages/SystemUI/res/values-hr/strings.xml
+++ b/packages/SystemUI/res/values-hr/strings.xml
@@ -434,4 +434,6 @@
<string name="remove_from_settings" msgid="8389591916603406378">"Ukloni iz Postavki"</string>
<string name="remove_from_settings_prompt" msgid="6069085993355887748">"Želite li ukloniti Ugađanje korisničkog sučelja sustava iz Postavki i prestati upotrebljavati njegove značajke?"</string>
<string name="activity_not_found" msgid="348423244327799974">"Aplikacija nije instalirana na vašem uređaju"</string>
+ <string name="clock_seconds" msgid="7689554147579179507">"Prikaži sekunde na satu"</string>
+ <string name="clock_seconds_desc" msgid="6282693067130470675">"Prikazuju se sekunde na satu na traci statusa. Može utjecati na trajanje baterije."</string>
</resources>
diff --git a/packages/SystemUI/res/values-hu/strings.xml b/packages/SystemUI/res/values-hu/strings.xml
index 49543cb..37cb0a8 100644
--- a/packages/SystemUI/res/values-hu/strings.xml
+++ b/packages/SystemUI/res/values-hu/strings.xml
@@ -433,4 +433,6 @@
<string name="remove_from_settings" msgid="8389591916603406378">"Eltávolítás a Beállítások közül"</string>
<string name="remove_from_settings_prompt" msgid="6069085993355887748">"Eltávolítja a Kezelőfelület-hangolót a Beállításokból, és nem használja tovább egyik funkcióját sem?"</string>
<string name="activity_not_found" msgid="348423244327799974">"Az alkalmazás nincs telepítve eszközén."</string>
+ <string name="clock_seconds" msgid="7689554147579179507">"Másodpercek megjelenítése az órán"</string>
+ <string name="clock_seconds_desc" msgid="6282693067130470675">"Másodpercek megjelenítése az állapotsor óráján. Ez hatással lehet az akkumulátor üzemidejére."</string>
</resources>
diff --git a/packages/SystemUI/res/values-hy-rAM/strings.xml b/packages/SystemUI/res/values-hy-rAM/strings.xml
index 8cf062f..e31cf49 100644
--- a/packages/SystemUI/res/values-hy-rAM/strings.xml
+++ b/packages/SystemUI/res/values-hy-rAM/strings.xml
@@ -433,4 +433,6 @@
<string name="remove_from_settings" msgid="8389591916603406378">"Հեռացնել կարգավորումներից"</string>
<string name="remove_from_settings_prompt" msgid="6069085993355887748">"Հեռացնե՞լ Համակարգի ՕՄ-ի կարգավորիչը կարգավորումներից և չօգտվել այլևս նրա գործառույթներից:"</string>
<string name="activity_not_found" msgid="348423244327799974">"Հավելվածը տեղադրված չէ սարքի վրա"</string>
+ <string name="clock_seconds" msgid="7689554147579179507">"Ցույց տալ ժամացույցի վայրկյանները"</string>
+ <string name="clock_seconds_desc" msgid="6282693067130470675">"Ցույց տալ ժամացույցի վայրկյանները կարգավիճակի տողում: Կարող է ազդել մարտկոցի աշխատանքի ժամանակի վրա:"</string>
</resources>
diff --git a/packages/SystemUI/res/values-in/strings.xml b/packages/SystemUI/res/values-in/strings.xml
index 6e738de..ad8141b 100644
--- a/packages/SystemUI/res/values-in/strings.xml
+++ b/packages/SystemUI/res/values-in/strings.xml
@@ -433,4 +433,6 @@
<string name="remove_from_settings" msgid="8389591916603406378">"Hapus dari Setelan"</string>
<string name="remove_from_settings_prompt" msgid="6069085993355887748">"Hapus Penyetel Antarmuka Pengguna Sistem dari Setelan dan berhenti menggunakan semua fiturnya?"</string>
<string name="activity_not_found" msgid="348423244327799974">"Aplikasi tidak dipasang di perangkat"</string>
+ <string name="clock_seconds" msgid="7689554147579179507">"Tampilkan detik jam"</string>
+ <string name="clock_seconds_desc" msgid="6282693067130470675">"Tampilkan detik jam di bilah status. Dapat memengaruhi masa pakai baterai."</string>
</resources>
diff --git a/packages/SystemUI/res/values-is-rIS/strings.xml b/packages/SystemUI/res/values-is-rIS/strings.xml
index 4c5bffb..02caf17 100644
--- a/packages/SystemUI/res/values-is-rIS/strings.xml
+++ b/packages/SystemUI/res/values-is-rIS/strings.xml
@@ -433,4 +433,6 @@
<string name="remove_from_settings" msgid="8389591916603406378">"Fjarlægja úr stillingum"</string>
<string name="remove_from_settings_prompt" msgid="6069085993355887748">"Viltu fjarlægja fínstillingar kerfisviðmóts úr stillingum og hætta að nota eiginleika þeirra?"</string>
<string name="activity_not_found" msgid="348423244327799974">"Forritið er ekki uppsett í tækinu."</string>
+ <string name="clock_seconds" msgid="7689554147579179507">"Sýna sekúndur á klukku"</string>
+ <string name="clock_seconds_desc" msgid="6282693067130470675">"Sýna sekúndur á klukku í stöðustikunni. Getur haft áhrif á endingu rafhlöðu."</string>
</resources>
diff --git a/packages/SystemUI/res/values-it/strings.xml b/packages/SystemUI/res/values-it/strings.xml
index 75ea3f6..ab5d8beab 100644
--- a/packages/SystemUI/res/values-it/strings.xml
+++ b/packages/SystemUI/res/values-it/strings.xml
@@ -435,4 +435,6 @@
<string name="remove_from_settings" msgid="8389591916603406378">"Rimuovi dalle impostazioni"</string>
<string name="remove_from_settings_prompt" msgid="6069085993355887748">"Vuoi rimuovere il sintetizzatore interfaccia utente di sistema dalle impostazioni e smettere di utilizzare tutte le sue funzioni?"</string>
<string name="activity_not_found" msgid="348423244327799974">"Applicazione non installata sul dispositivo"</string>
+ <string name="clock_seconds" msgid="7689554147579179507">"Mostra i secondi nell\'orologio"</string>
+ <string name="clock_seconds_desc" msgid="6282693067130470675">"Mostra i secondi nell\'orologio nella barra di stato. Ciò potrebbe ridurre la durata della carica della batteria."</string>
</resources>
diff --git a/packages/SystemUI/res/values-iw/strings.xml b/packages/SystemUI/res/values-iw/strings.xml
index 4db88bd..9dad8aa 100644
--- a/packages/SystemUI/res/values-iw/strings.xml
+++ b/packages/SystemUI/res/values-iw/strings.xml
@@ -435,4 +435,6 @@
<string name="remove_from_settings" msgid="8389591916603406378">"הסר מההגדרות"</string>
<string name="remove_from_settings_prompt" msgid="6069085993355887748">"האם להסיר את System UI Tuner ולהפסיק להשתמש בכל התכונות שלו?"</string>
<string name="activity_not_found" msgid="348423244327799974">"האפליקציה אינה מותקנת במכשיר"</string>
+ <string name="clock_seconds" msgid="7689554147579179507">"הצג שניות בשעון"</string>
+ <string name="clock_seconds_desc" msgid="6282693067130470675">"הצג שניות בשעון בשורת הסטטוס. פעולה זו עשויה להשפיע על אורך חיי הסוללה."</string>
</resources>
diff --git a/packages/SystemUI/res/values-ja/strings.xml b/packages/SystemUI/res/values-ja/strings.xml
index d7b687b..b9bfba9 100644
--- a/packages/SystemUI/res/values-ja/strings.xml
+++ b/packages/SystemUI/res/values-ja/strings.xml
@@ -435,4 +435,6 @@
<string name="remove_from_settings" msgid="8389591916603406378">"設定から削除"</string>
<string name="remove_from_settings_prompt" msgid="6069085993355887748">"設定からシステムUI調整ツールを削除して、全機能の使用を停止しますか?"</string>
<string name="activity_not_found" msgid="348423244327799974">"アプリが端末にインストールされていません"</string>
+ <string name="clock_seconds" msgid="7689554147579179507">"時計の秒を表示"</string>
+ <string name="clock_seconds_desc" msgid="6282693067130470675">"ステータスバーに時計の秒を表示します。電池使用量に影響する可能性があります。"</string>
</resources>
diff --git a/packages/SystemUI/res/values-ka-rGE/strings.xml b/packages/SystemUI/res/values-ka-rGE/strings.xml
index 2097996..a9728b2 100644
--- a/packages/SystemUI/res/values-ka-rGE/strings.xml
+++ b/packages/SystemUI/res/values-ka-rGE/strings.xml
@@ -433,4 +433,6 @@
<string name="remove_from_settings" msgid="8389591916603406378">"პარამეტრებიდან წაშლა"</string>
<string name="remove_from_settings_prompt" msgid="6069085993355887748">"გსურთ სისტემის UI ტუნერის პარამეტრებიდან წაშლა და მისი ყველა ფუნქციის გამოყენების შეწყვეტა?"</string>
<string name="activity_not_found" msgid="348423244327799974">"აპლიკაცია თქვენს მოწყობილობაზე დაყენებული არ არის"</string>
+ <string name="clock_seconds" msgid="7689554147579179507">"საათის წამების ჩვენება"</string>
+ <string name="clock_seconds_desc" msgid="6282693067130470675">"საათის წამების ჩვენება სტატუსის ზოლში. შეიძლება გავლენა იქონიოს ბატარეაზე."</string>
</resources>
diff --git a/packages/SystemUI/res/values-kk-rKZ/strings.xml b/packages/SystemUI/res/values-kk-rKZ/strings.xml
index bd49612..1d61372 100644
--- a/packages/SystemUI/res/values-kk-rKZ/strings.xml
+++ b/packages/SystemUI/res/values-kk-rKZ/strings.xml
@@ -433,4 +433,6 @@
<string name="remove_from_settings" msgid="8389591916603406378">"Параметрлерден жою"</string>
<string name="remove_from_settings_prompt" msgid="6069085993355887748">"Жүйелік пайдаланушылық интерфейс тюнерін \"Параметрлер\" тармағынан жойып, оның барлық мүмкіндіктерін пайдалануды тоқтату керек пе?"</string>
<string name="activity_not_found" msgid="348423244327799974">"Қолданба құрылғыда орнатылмаған"</string>
+ <string name="clock_seconds" msgid="7689554147579179507">"Сағат секундтарын көрсету"</string>
+ <string name="clock_seconds_desc" msgid="6282693067130470675">"Күйін көрсету жолағында сағат секундтарын көрсету. Батареяның қызмет көрсету мерзіміне әсер етуі мүмкін."</string>
</resources>
diff --git a/packages/SystemUI/res/values-km-rKH/strings.xml b/packages/SystemUI/res/values-km-rKH/strings.xml
index db5057e..c233f83 100644
--- a/packages/SystemUI/res/values-km-rKH/strings.xml
+++ b/packages/SystemUI/res/values-km-rKH/strings.xml
@@ -433,4 +433,6 @@
<string name="remove_from_settings" msgid="8389591916603406378">"យកចេញពីការកំណត់"</string>
<string name="remove_from_settings_prompt" msgid="6069085993355887748">"យកកម្មវិធីសម្រួល UI ប្រព័ន្ធចេញពីការកំណត់ ហើយឈប់ប្រើលក្ខណៈពិសេសរបស់វាទាំងអស់?"</string>
<string name="activity_not_found" msgid="348423244327799974">"កម្មវិធីមិនបានដំឡើងនៅលើឧបករណ៍របស់អ្នកទេ"</string>
+ <string name="clock_seconds" msgid="7689554147579179507">"បង្ហាញវិនាទី"</string>
+ <string name="clock_seconds_desc" msgid="6282693067130470675">"បង្ហាញវិនាទីនៅលើរបារស្ថានភាពអាចនឹងប៉ះពាល់ដល់ថាមពលថ្ម។"</string>
</resources>
diff --git a/packages/SystemUI/res/values-kn-rIN/strings.xml b/packages/SystemUI/res/values-kn-rIN/strings.xml
index 7d88681e..d486e56 100644
--- a/packages/SystemUI/res/values-kn-rIN/strings.xml
+++ b/packages/SystemUI/res/values-kn-rIN/strings.xml
@@ -433,4 +433,6 @@
<string name="remove_from_settings" msgid="8389591916603406378">"ಸೆಟ್ಟಿಂಗ್ಗಳಿಂದ ತೆಗೆದುಹಾಕಿ"</string>
<string name="remove_from_settings_prompt" msgid="6069085993355887748">"ಸೆಟ್ಟಿಂಗ್ಗಳಿಂದ ಸಿಸ್ಟಮ್ UI ಟ್ಯೂನರ್ ತೆಗೆದುಹಾಕುವುದೇ ಮತ್ತು ಅದರ ಎಲ್ಲಾ ವೈಶಿಷ್ಟ್ಯಗಳನ್ನು ಬಳಸುವುದನ್ನು ನಿಲ್ಲಿಸುವುದೇ?"</string>
<string name="activity_not_found" msgid="348423244327799974">"ನಿಮ್ಮ ಸಾಧನದಲ್ಲಿ ಅಪ್ಲಿಕೇಶನ್ ಅನ್ನು ಸ್ಥಾಪಿಸಲಾಗಿಲ್ಲ"</string>
+ <string name="clock_seconds" msgid="7689554147579179507">"ಗಡಿಯಾರದ ಸೆಕೆಂಡುಗಳನ್ನು ತೋರಿಸು"</string>
+ <string name="clock_seconds_desc" msgid="6282693067130470675">"ಸ್ಥಿತಿ ಪಟ್ಟಿಯಲ್ಲಿ ಗಡಿಯಾರ ಸೆಕೆಂಡುಗಳನ್ನು ತೋರಿಸು. ಇದಕ್ಕೆ ಬ್ಯಾಟರಿ ಬಾಳಿಕೆಯು ಪರಿಣಾಮಬೀರಬಹುದು."</string>
</resources>
diff --git a/packages/SystemUI/res/values-ko/strings.xml b/packages/SystemUI/res/values-ko/strings.xml
index af02943..3505754 100644
--- a/packages/SystemUI/res/values-ko/strings.xml
+++ b/packages/SystemUI/res/values-ko/strings.xml
@@ -433,4 +433,6 @@
<string name="remove_from_settings" msgid="8389591916603406378">"설정에서 삭제"</string>
<string name="remove_from_settings_prompt" msgid="6069085993355887748">"시스템 UI 튜너를 설정에서 삭제하고 모든 관련 기능의 사용을 중지하시겠습니까?"</string>
<string name="activity_not_found" msgid="348423244327799974">"기기에 애플리케이션이 설치되어 있지 않습니다."</string>
+ <string name="clock_seconds" msgid="7689554147579179507">"시계 초 단위 표시"</string>
+ <string name="clock_seconds_desc" msgid="6282693067130470675">"상태 표시줄에 시계 초 단위를 표시합니다. 배터리 수명에 영향을 줄 수도 있습니다."</string>
</resources>
diff --git a/packages/SystemUI/res/values-ky-rKG/strings.xml b/packages/SystemUI/res/values-ky-rKG/strings.xml
index 058cc18..968a65a 100644
--- a/packages/SystemUI/res/values-ky-rKG/strings.xml
+++ b/packages/SystemUI/res/values-ky-rKG/strings.xml
@@ -433,4 +433,6 @@
<string name="remove_from_settings" msgid="8389591916603406378">"Жөндөөлөрдөн алып салуу"</string>
<string name="remove_from_settings_prompt" msgid="6069085993355887748">"System UI Tuner Жөндөөлөрдөн алынып салынып, анын бардык функциялары токтотулсунбу?"</string>
<string name="activity_not_found" msgid="348423244327799974">"Колдонмо сиздин түзмөгүңүздө орнотулган эмес"</string>
+ <string name="clock_seconds" msgid="7689554147579179507">"Сааттын секунддары көрсөтүлсүн"</string>
+ <string name="clock_seconds_desc" msgid="6282693067130470675">"Абал тилкесинен сааттын секунддары көрсөтүлсүн. Батареянын кубаты көбүрөөк сарпталышы мүмкүн."</string>
</resources>
diff --git a/packages/SystemUI/res/values-lo-rLA/strings.xml b/packages/SystemUI/res/values-lo-rLA/strings.xml
index 3067fb7..f34c70e 100644
--- a/packages/SystemUI/res/values-lo-rLA/strings.xml
+++ b/packages/SystemUI/res/values-lo-rLA/strings.xml
@@ -433,4 +433,6 @@
<string name="remove_from_settings" msgid="8389591916603406378">"ເອົາອອກຈາກການຕັ້ງຄ່າ"</string>
<string name="remove_from_settings_prompt" msgid="6069085993355887748">"ເອົາ System UI Tuner ອອກຈາກການຕັ້ງຄ່າ ແລະຢຸດການໃຊ້ທຸກຄຸນສົມບັດໃຊ້ງານຂອງມັນ?"</string>
<string name="activity_not_found" msgid="348423244327799974">"ແອັບພລິເຄຊັນບໍ່ຖືກຕິດຕັ້ງຢູ່ໃນອຸປະກອນຂອງທ່ານ"</string>
+ <string name="clock_seconds" msgid="7689554147579179507">"ສະແດງວິນາທີໂມງ"</string>
+ <string name="clock_seconds_desc" msgid="6282693067130470675">"ສະແດງວິນາທີໂມງຢູ່ໃນແຖບສະຖານະ. ອາດຈະມີຜົນກະທົບຕໍ່ອາຍຸແບັດເຕີຣີ."</string>
</resources>
diff --git a/packages/SystemUI/res/values-lt/strings.xml b/packages/SystemUI/res/values-lt/strings.xml
index e195444..cf70d6b 100644
--- a/packages/SystemUI/res/values-lt/strings.xml
+++ b/packages/SystemUI/res/values-lt/strings.xml
@@ -435,4 +435,6 @@
<string name="remove_from_settings" msgid="8389591916603406378">"Pašalinti iš nustatymų"</string>
<string name="remove_from_settings_prompt" msgid="6069085993355887748">"Ar norite pašalinti sistemos naudotojo sąsajos derinimo priemonę iš nustatymų ir nebenaudoti jokių jos funkcijų?"</string>
<string name="activity_not_found" msgid="348423244327799974">"Programa neįdiegta įrenginyje"</string>
+ <string name="clock_seconds" msgid="7689554147579179507">"Rodyti laikrodžio sekundes"</string>
+ <string name="clock_seconds_desc" msgid="6282693067130470675">"Rodyti laikrodžio sekundes būsenos juostoje. Tai gali paveikti akumuliatoriaus naudojimo laiką."</string>
</resources>
diff --git a/packages/SystemUI/res/values-lv/strings.xml b/packages/SystemUI/res/values-lv/strings.xml
index 4350876..5e2db80 100644
--- a/packages/SystemUI/res/values-lv/strings.xml
+++ b/packages/SystemUI/res/values-lv/strings.xml
@@ -434,4 +434,6 @@
<string name="remove_from_settings" msgid="8389591916603406378">"Noņemt no iestatījumiem"</string>
<string name="remove_from_settings_prompt" msgid="6069085993355887748">"Vai noņemt sistēmas saskarnes regulatoru no iestatījumiem un pārtraukt izmantot visas tā funkcijas?"</string>
<string name="activity_not_found" msgid="348423244327799974">"Lietojumprogramma nav instalēta jūsu ierīcē."</string>
+ <string name="clock_seconds" msgid="7689554147579179507">"Rādīt pulksteņa sekundes"</string>
+ <string name="clock_seconds_desc" msgid="6282693067130470675">"Statusa joslā rādīt pulksteņa sekundes. Var ietekmēt akumulatora darbības laiku."</string>
</resources>
diff --git a/packages/SystemUI/res/values-mk-rMK/strings.xml b/packages/SystemUI/res/values-mk-rMK/strings.xml
index 9e7a717..fe781b6 100644
--- a/packages/SystemUI/res/values-mk-rMK/strings.xml
+++ b/packages/SystemUI/res/values-mk-rMK/strings.xml
@@ -435,4 +435,6 @@
<string name="remove_from_settings" msgid="8389591916603406378">"Отстрани од поставки"</string>
<string name="remove_from_settings_prompt" msgid="6069085993355887748">"Да се отстрани Адаптерот на УИ на системот од Поставки и да престанат да се користат сите негови функции?"</string>
<string name="activity_not_found" msgid="348423244327799974">"Апликацијата не е инсталирана на уредот"</string>
+ <string name="clock_seconds" msgid="7689554147579179507">"Прикажи ги секундите на часовникот"</string>
+ <string name="clock_seconds_desc" msgid="6282693067130470675">"Прикажи ги секундите на часовникот на статусната лента. Може да влијае на траењето на батеријата."</string>
</resources>
diff --git a/packages/SystemUI/res/values-ml-rIN/strings.xml b/packages/SystemUI/res/values-ml-rIN/strings.xml
index e941427..6e6fc55 100644
--- a/packages/SystemUI/res/values-ml-rIN/strings.xml
+++ b/packages/SystemUI/res/values-ml-rIN/strings.xml
@@ -433,4 +433,6 @@
<string name="remove_from_settings" msgid="8389591916603406378">"ക്രമീകരണത്തിൽ നിന്ന് നീക്കംചെയ്യുക"</string>
<string name="remove_from_settings_prompt" msgid="6069085993355887748">"ക്രമീകരണത്തിൽ നിന്ന് സിസ്റ്റം UI ട്യൂണർ നീക്കംചെയ്യുകയും അതിന്റെ ഫീച്ചറുകളെല്ലാം ഉപയോഗിക്കുന്നത് നിർത്തുകയും ചെയ്യണോ?"</string>
<string name="activity_not_found" msgid="348423244327799974">"നിങ്ങളുടെ ഉപകരണത്തിൽ അപ്ലിക്കേഷൻ ഇൻസ്റ്റാൾ ചെയ്തിട്ടില്ല"</string>
+ <string name="clock_seconds" msgid="7689554147579179507">"ക്ലോക്ക് സെക്കൻഡ് കാണിക്കുക"</string>
+ <string name="clock_seconds_desc" msgid="6282693067130470675">"സ്റ്റാറ്റസ് ബാറിൽ ക്ലോക്ക് സെക്കൻഡ് കാണിക്കുന്നത് ബാറ്ററിയുടെ ലൈഫിനെ ബാധിക്കാം."</string>
</resources>
diff --git a/packages/SystemUI/res/values-mn-rMN/strings.xml b/packages/SystemUI/res/values-mn-rMN/strings.xml
index 69a94c2..65250bb 100644
--- a/packages/SystemUI/res/values-mn-rMN/strings.xml
+++ b/packages/SystemUI/res/values-mn-rMN/strings.xml
@@ -431,4 +431,6 @@
<string name="remove_from_settings" msgid="8389591916603406378">"Тохиргооноос устгах"</string>
<string name="remove_from_settings_prompt" msgid="6069085993355887748">"Системийн UI Тохируулагчийг тохиргооноос устгаж, үүнтэй холбоотой бүх тохиргоог ашиглахаа болих уу?"</string>
<string name="activity_not_found" msgid="348423244327799974">"Апп-ыг таны төхөөрөмжид суулгаагүй байна"</string>
+ <string name="clock_seconds" msgid="7689554147579179507">"Цагийн секундыг харуулах"</string>
+ <string name="clock_seconds_desc" msgid="6282693067130470675">"Статус талбарт цагийн секундыг харуулах. Энэ нь тэжээлийн цэнэгт нөлөөлж болно."</string>
</resources>
diff --git a/packages/SystemUI/res/values-mr-rIN/strings.xml b/packages/SystemUI/res/values-mr-rIN/strings.xml
index 3184de5..0f71b4b 100644
--- a/packages/SystemUI/res/values-mr-rIN/strings.xml
+++ b/packages/SystemUI/res/values-mr-rIN/strings.xml
@@ -433,4 +433,6 @@
<string name="remove_from_settings" msgid="8389591916603406378">"सेटिंग्ज मधून काढा"</string>
<string name="remove_from_settings_prompt" msgid="6069085993355887748">"सेटिंग्ज मधून सिस्टीम UI ट्यूनर काढून त्याची सर्व वैशिष्ट्ये वापरणे थांबवायचे?"</string>
<string name="activity_not_found" msgid="348423244327799974">"अनुप्रयोग आपल्या डिव्हाइसवर स्थापित केलेला नाही"</string>
+ <string name="clock_seconds" msgid="7689554147579179507">"घड्याळ सेकंद दर्शवा"</string>
+ <string name="clock_seconds_desc" msgid="6282693067130470675">"स्टेटस बारमध्ये घड्याळ सेकंद दर्शवा. कदाचित बॅटरी आयुष्य प्रभावित होऊ शकते."</string>
</resources>
diff --git a/packages/SystemUI/res/values-ms-rMY/strings.xml b/packages/SystemUI/res/values-ms-rMY/strings.xml
index b12046b..596275c 100644
--- a/packages/SystemUI/res/values-ms-rMY/strings.xml
+++ b/packages/SystemUI/res/values-ms-rMY/strings.xml
@@ -433,4 +433,6 @@
<string name="remove_from_settings" msgid="8389591916603406378">"Alih keluar daripada Tetapan"</string>
<string name="remove_from_settings_prompt" msgid="6069085993355887748">"Alih keluar Penala UI Sistem daripada Tetapan dan berhenti menggunakan semua cirinya?"</string>
<string name="activity_not_found" msgid="348423244327799974">"Aplikasi tidak dipasang pada peranti anda"</string>
+ <string name="clock_seconds" msgid="7689554147579179507">"Tunjukkan saat jam"</string>
+ <string name="clock_seconds_desc" msgid="6282693067130470675">"Tunjukkan saat jam dalam bar status. Mungkin menjejaskan hayat bateri."</string>
</resources>
diff --git a/packages/SystemUI/res/values-my-rMM/strings.xml b/packages/SystemUI/res/values-my-rMM/strings.xml
index 6f843b0..3147d0c 100644
--- a/packages/SystemUI/res/values-my-rMM/strings.xml
+++ b/packages/SystemUI/res/values-my-rMM/strings.xml
@@ -433,4 +433,6 @@
<string name="remove_from_settings" msgid="8389591916603406378">"ဆက်တင် အထဲမှ ဖယ်ရှားရန်"</string>
<string name="remove_from_settings_prompt" msgid="6069085993355887748">"ဆက်တင် အထဲမှ စနစ် UI ဖမ်းစက်ကို ဖယ်ရှားလျက် ၎င်း၏ အင်္ဂါရပ်များ အားလုံး အသုံးပြုမှု ရပ်တန့်ရမလား?"</string>
<string name="activity_not_found" msgid="348423244327799974">"အပလီကေးရှင်းကို သင်၏ ကိရိယာထဲသို့ တပ်ဆင်မပေးရသေးပါ။"</string>
+ <string name="clock_seconds" msgid="7689554147579179507">"နာရီ စက္ကန့်များကို ပြရန်"</string>
+ <string name="clock_seconds_desc" msgid="6282693067130470675">"အခြေအနေပြနေရာမှာ နာရီ စက္ကန့်များကို ပြပါ။ ဘက်ထရီ သက်တမ်းကို အကျိုးသက်ရောက်နိုင်တယ်။"</string>
</resources>
diff --git a/packages/SystemUI/res/values-nb/strings.xml b/packages/SystemUI/res/values-nb/strings.xml
index 3a34cdd..f1bfbe1 100644
--- a/packages/SystemUI/res/values-nb/strings.xml
+++ b/packages/SystemUI/res/values-nb/strings.xml
@@ -433,4 +433,6 @@
<string name="remove_from_settings" msgid="8389591916603406378">"Fjern fra Innstillinger"</string>
<string name="remove_from_settings_prompt" msgid="6069085993355887748">"Vil du fjerne System UI Tuner fra Innstillinger og slutte å bruke alle de tilknyttede funksjonene?"</string>
<string name="activity_not_found" msgid="348423244327799974">"Appen er ikke installert på enheten din"</string>
+ <string name="clock_seconds" msgid="7689554147579179507">"Vis sekunder på klokken"</string>
+ <string name="clock_seconds_desc" msgid="6282693067130470675">"Vis sekunder i statusfeltet på klokken. Det kan påvirke batteritiden."</string>
</resources>
diff --git a/packages/SystemUI/res/values-ne-rNP/strings.xml b/packages/SystemUI/res/values-ne-rNP/strings.xml
index 5fadbde..461a15f 100644
--- a/packages/SystemUI/res/values-ne-rNP/strings.xml
+++ b/packages/SystemUI/res/values-ne-rNP/strings.xml
@@ -433,4 +433,6 @@
<string name="remove_from_settings" msgid="8389591916603406378">"सेटिङहरूबाट हटाउनुहोस्"</string>
<string name="remove_from_settings_prompt" msgid="6069085993355887748">"प्रणाली UI ट्युनर सेटिङहरूबाट हटाउने र यसका सबै सुविधाहरू प्रयोग गर्न रोक्ने हो?"</string>
<string name="activity_not_found" msgid="348423244327799974">"तपाईँको यन्त्रमा अनुप्रयोग स्थापना भएको छैन"</string>
+ <string name="clock_seconds" msgid="7689554147579179507">"घडीमा सेकेन्ड देखाउनुहोस्"</string>
+ <string name="clock_seconds_desc" msgid="6282693067130470675">"वस्तुस्थिति पट्टीको घडीमा सेकेन्ड देखाउनुहोस्। ब्याट्री आयु प्रभावित हुन सक्छ।"</string>
</resources>
diff --git a/packages/SystemUI/res/values-nl/strings.xml b/packages/SystemUI/res/values-nl/strings.xml
index 9b7e3409..b74f91d 100644
--- a/packages/SystemUI/res/values-nl/strings.xml
+++ b/packages/SystemUI/res/values-nl/strings.xml
@@ -433,4 +433,6 @@
<string name="remove_from_settings" msgid="8389591916603406378">"Verwijderen uit Instellingen"</string>
<string name="remove_from_settings_prompt" msgid="6069085993355887748">"Systeem-UI-tuner uit Instellingen verwijderen en het gebruik van alle functies daarvan stopzetten?"</string>
<string name="activity_not_found" msgid="348423244327799974">"Deze app is niet geïnstalleerd op uw apparaat"</string>
+ <string name="clock_seconds" msgid="7689554147579179507">"Klokseconden weergeven"</string>
+ <string name="clock_seconds_desc" msgid="6282693067130470675">"Klokseconden op de statusbalk weergeven. Kan van invloed zijn op de accuduur."</string>
</resources>
diff --git a/packages/SystemUI/res/values-pa-rIN/strings.xml b/packages/SystemUI/res/values-pa-rIN/strings.xml
index 2d70c8a..06746cc 100644
--- a/packages/SystemUI/res/values-pa-rIN/strings.xml
+++ b/packages/SystemUI/res/values-pa-rIN/strings.xml
@@ -433,4 +433,6 @@
<string name="remove_from_settings" msgid="8389591916603406378">"ਸੈਟਿੰਗਜ਼ ਤੋਂ ਹਟਾਓ"</string>
<string name="remove_from_settings_prompt" msgid="6069085993355887748">"ਕੀ ਸੈਟਿੰਗਜ਼ ਤੋਂ ਸਿਸਟਮ UI ਟਿਊਨਰ ਨੂੰ ਹਟਾਉਣਾ ਹੈ ਅਤੇ ਇਸਦੀਆਂ ਸਾਰੀਆਂ ਵਿਸ਼ੇਸ਼ਤਾਵਾਂ ਨੂੰ ਉਪਯੋਗ ਕਰਨ ਤੋਂ ਰੋਕਣਾ ਹੈ?"</string>
<string name="activity_not_found" msgid="348423244327799974">"ਐਪਲੀਕੇਸ਼ਨ ਤੁਹਾਡੀ ਡਿਵਾਈਸ ਤੇ ਇੰਸਟੌਲ ਨਹੀਂ ਕੀਤੀ ਗਈ ਹੈ"</string>
+ <string name="clock_seconds" msgid="7689554147579179507">"ਘੜੀ ਸਕਿੰਟ ਦਿਖਾਓ"</string>
+ <string name="clock_seconds_desc" msgid="6282693067130470675">"ਸਥਿਤੀ ਬਾਰ ਵਿੱਚ ਘੜੀ ਸਕਿੰਟ ਦਿਖਾਓ। ਬੈਟਰੀ ਸਮਰੱਥਾ ਤੇ ਅਸਰ ਪੈ ਸਕਦਾ ਹੈ।"</string>
</resources>
diff --git a/packages/SystemUI/res/values-pl/strings.xml b/packages/SystemUI/res/values-pl/strings.xml
index 93fa170..66100c1 100644
--- a/packages/SystemUI/res/values-pl/strings.xml
+++ b/packages/SystemUI/res/values-pl/strings.xml
@@ -435,4 +435,6 @@
<string name="remove_from_settings" msgid="8389591916603406378">"Usuń z Ustawień"</string>
<string name="remove_from_settings_prompt" msgid="6069085993355887748">"Usunąć Kalibrator System UI z Ustawień i przestać używać wszystkich jego funkcji?"</string>
<string name="activity_not_found" msgid="348423244327799974">"Aplikacja nie jest zainstalowana na urządzeniu"</string>
+ <string name="clock_seconds" msgid="7689554147579179507">"Pokaż sekundy na zegarku"</string>
+ <string name="clock_seconds_desc" msgid="6282693067130470675">"Pokaż sekundy na zegarku na pasku stanu. Może mieć wpływ na czas pracy baterii."</string>
</resources>
diff --git a/packages/SystemUI/res/values-pt-rBR/strings.xml b/packages/SystemUI/res/values-pt-rBR/strings.xml
index 78eee7b..53cea01 100644
--- a/packages/SystemUI/res/values-pt-rBR/strings.xml
+++ b/packages/SystemUI/res/values-pt-rBR/strings.xml
@@ -435,4 +435,6 @@
<string name="remove_from_settings" msgid="8389591916603406378">"Remover das configurações"</string>
<string name="remove_from_settings_prompt" msgid="6069085993355887748">"Remover sintonizador System UI das configurações e parar de usar todos os seus recursos?"</string>
<string name="activity_not_found" msgid="348423244327799974">"O app não está instalado no seu dispositivo"</string>
+ <string name="clock_seconds" msgid="7689554147579179507">"Mostrar segundos do relógio"</string>
+ <string name="clock_seconds_desc" msgid="6282693067130470675">"Mostrar segundos do relógio na barra de status. Pode afetar a duração da bateria."</string>
</resources>
diff --git a/packages/SystemUI/res/values-pt-rPT/strings.xml b/packages/SystemUI/res/values-pt-rPT/strings.xml
index 9c221dd..5006413 100644
--- a/packages/SystemUI/res/values-pt-rPT/strings.xml
+++ b/packages/SystemUI/res/values-pt-rPT/strings.xml
@@ -433,4 +433,6 @@
<string name="remove_from_settings" msgid="8389591916603406378">"Remover das Definições"</string>
<string name="remove_from_settings_prompt" msgid="6069085993355887748">"Pretende remover o Sintonizador da interface do sistema das Definições e deixar de utilizar todas as respetivas funcionalidades?"</string>
<string name="activity_not_found" msgid="348423244327799974">"A aplicação não está instalada no dispositivo"</string>
+ <string name="clock_seconds" msgid="7689554147579179507">"Mostrar segundos do relógio"</string>
+ <string name="clock_seconds_desc" msgid="6282693067130470675">"Mostrar segundos do relógio na barra de estado. Pode afetar a autonomia da bateria."</string>
</resources>
diff --git a/packages/SystemUI/res/values-pt/strings.xml b/packages/SystemUI/res/values-pt/strings.xml
index 78eee7b..53cea01 100644
--- a/packages/SystemUI/res/values-pt/strings.xml
+++ b/packages/SystemUI/res/values-pt/strings.xml
@@ -435,4 +435,6 @@
<string name="remove_from_settings" msgid="8389591916603406378">"Remover das configurações"</string>
<string name="remove_from_settings_prompt" msgid="6069085993355887748">"Remover sintonizador System UI das configurações e parar de usar todos os seus recursos?"</string>
<string name="activity_not_found" msgid="348423244327799974">"O app não está instalado no seu dispositivo"</string>
+ <string name="clock_seconds" msgid="7689554147579179507">"Mostrar segundos do relógio"</string>
+ <string name="clock_seconds_desc" msgid="6282693067130470675">"Mostrar segundos do relógio na barra de status. Pode afetar a duração da bateria."</string>
</resources>
diff --git a/packages/SystemUI/res/values-ro/strings.xml b/packages/SystemUI/res/values-ro/strings.xml
index e9ff595..d97e16b 100644
--- a/packages/SystemUI/res/values-ro/strings.xml
+++ b/packages/SystemUI/res/values-ro/strings.xml
@@ -434,4 +434,6 @@
<string name="remove_from_settings" msgid="8389591916603406378">"Eliminați din Setări"</string>
<string name="remove_from_settings_prompt" msgid="6069085993355887748">"Eliminați System UI Tuner din Setări și încetați utilizarea tuturor funcțiilor sale?"</string>
<string name="activity_not_found" msgid="348423244327799974">"Aplicația nu este instalată pe dispozitiv"</string>
+ <string name="clock_seconds" msgid="7689554147579179507">"Afișează secundele pe ceas"</string>
+ <string name="clock_seconds_desc" msgid="6282693067130470675">"Afișează secundele pe ceas în bara de stare. Poate afecta autonomia bateriei."</string>
</resources>
diff --git a/packages/SystemUI/res/values-ru/strings.xml b/packages/SystemUI/res/values-ru/strings.xml
index 8691233..d67ad38 100644
--- a/packages/SystemUI/res/values-ru/strings.xml
+++ b/packages/SystemUI/res/values-ru/strings.xml
@@ -437,4 +437,6 @@
<string name="remove_from_settings" msgid="8389591916603406378">"Удалить из настроек"</string>
<string name="remove_from_settings_prompt" msgid="6069085993355887748">"Убрать функцию System UI Tuner из меню настроек и прекратить ее работу?"</string>
<string name="activity_not_found" msgid="348423244327799974">"Приложение не установлено на вашем устройстве"</string>
+ <string name="clock_seconds" msgid="7689554147579179507">"Показывать секунды"</string>
+ <string name="clock_seconds_desc" msgid="6282693067130470675">"Показывать в строке состояния время с точностью до секунды (заряд батареи может расходоваться быстрее)."</string>
</resources>
diff --git a/packages/SystemUI/res/values-si-rLK/strings.xml b/packages/SystemUI/res/values-si-rLK/strings.xml
index 02533f5..06cb626 100644
--- a/packages/SystemUI/res/values-si-rLK/strings.xml
+++ b/packages/SystemUI/res/values-si-rLK/strings.xml
@@ -433,4 +433,6 @@
<string name="remove_from_settings" msgid="8389591916603406378">"සැකසීම් වෙතින් ඉවත් කරන්න"</string>
<string name="remove_from_settings_prompt" msgid="6069085993355887748">"සැකසීම් වෙතින් පද්ධති UI සුසරකය ඉවත් කර සහ එහි සියලු අංග භාවිතය නවත් වන්නද?"</string>
<string name="activity_not_found" msgid="348423244327799974">"යෙදුම ඔබේ උපාංගය මත ස්ථාපනය කර නැත"</string>
+ <string name="clock_seconds" msgid="7689554147579179507">"ඔරලෝසු තත්පර පෙන්වන්න"</string>
+ <string name="clock_seconds_desc" msgid="6282693067130470675">"තත්ත්ව තීරුවෙහි ඔරලෝසු තත්පර පෙන්වන්න. බැටරි ආයු කාලයට බලපෑමට හැකිය."</string>
</resources>
diff --git a/packages/SystemUI/res/values-sk/strings.xml b/packages/SystemUI/res/values-sk/strings.xml
index 522d0a6..037074b 100644
--- a/packages/SystemUI/res/values-sk/strings.xml
+++ b/packages/SystemUI/res/values-sk/strings.xml
@@ -437,4 +437,6 @@
<string name="remove_from_settings" msgid="8389591916603406378">"Odstrániť z Nastavení"</string>
<string name="remove_from_settings_prompt" msgid="6069085993355887748">"Chcete odstrániť tuner používateľského rozhrania systému z Nastavení a prestať používať všetky jeho funkcie?"</string>
<string name="activity_not_found" msgid="348423244327799974">"Aplikácia nie je nainštalovaná na zariadení"</string>
+ <string name="clock_seconds" msgid="7689554147579179507">"Zobraziť sekundy"</string>
+ <string name="clock_seconds_desc" msgid="6282693067130470675">"Zobrazí sekundy v stavovom riadku. Môže to ovplyvňovať výdrž batérie."</string>
</resources>
diff --git a/packages/SystemUI/res/values-sl/strings.xml b/packages/SystemUI/res/values-sl/strings.xml
index 770844e..31fe5d8 100644
--- a/packages/SystemUI/res/values-sl/strings.xml
+++ b/packages/SystemUI/res/values-sl/strings.xml
@@ -435,4 +435,6 @@
<string name="remove_from_settings" msgid="8389591916603406378">"Odstrani iz nastavitev"</string>
<string name="remove_from_settings_prompt" msgid="6069085993355887748">"Ali želite odstraniti Uglaševalnik uporabniškega vmesnika sistema iz nastavitev in prenehati uporabljati vse njegove funkcije?"</string>
<string name="activity_not_found" msgid="348423244327799974">"Aplikacija ni nameščena v napravi"</string>
+ <string name="clock_seconds" msgid="7689554147579179507">"Prikaz sekund pri uri"</string>
+ <string name="clock_seconds_desc" msgid="6282693067130470675">"Prikaže sekunde pri uri v vrstici stanja. To lahko vpliva na čas delovanja pri akumulatorskem napajanju."</string>
</resources>
diff --git a/packages/SystemUI/res/values-sq-rAL/strings.xml b/packages/SystemUI/res/values-sq-rAL/strings.xml
index 1072b54..ffb8bea 100644
--- a/packages/SystemUI/res/values-sq-rAL/strings.xml
+++ b/packages/SystemUI/res/values-sq-rAL/strings.xml
@@ -433,4 +433,6 @@
<string name="remove_from_settings" msgid="8389591916603406378">"Hiqe nga Cilësimet"</string>
<string name="remove_from_settings_prompt" msgid="6069085993355887748">"Të hiqet Sintonizuesi i Sistemit të Ndërfaqes së Përdoruesit nga Cilësimet dhe të ndërpritet përdorimi i të gjitha funksioneve të tij?"</string>
<string name="activity_not_found" msgid="348423244327799974">"Aplikacioni nuk është instaluar në pajisjen tënde."</string>
+ <string name="clock_seconds" msgid="7689554147579179507">"Trego sekondat e orës"</string>
+ <string name="clock_seconds_desc" msgid="6282693067130470675">"Trego sekondat e orës në shiritin e statusit. Mund të ndikojë te jeta e baterisë."</string>
</resources>
diff --git a/packages/SystemUI/res/values-sr/strings.xml b/packages/SystemUI/res/values-sr/strings.xml
index 5df6d62..bae0284 100644
--- a/packages/SystemUI/res/values-sr/strings.xml
+++ b/packages/SystemUI/res/values-sr/strings.xml
@@ -434,4 +434,6 @@
<string name="remove_from_settings" msgid="8389591916603406378">"Уклони из Подешавања"</string>
<string name="remove_from_settings_prompt" msgid="6069085993355887748">"Желите ли да уклоните Тјунер за кориснички интерфејс система из Подешавања и да престанете да користите све његове функције?"</string>
<string name="activity_not_found" msgid="348423244327799974">"Апликација није инсталирана на уређају"</string>
+ <string name="clock_seconds" msgid="7689554147579179507">"Приказуј секунде на сату"</string>
+ <string name="clock_seconds_desc" msgid="6282693067130470675">"Секунде на сату се приказују на статусној траци. То може да утиче на трајање батерије."</string>
</resources>
diff --git a/packages/SystemUI/res/values-sv/strings.xml b/packages/SystemUI/res/values-sv/strings.xml
index 807c53e..6588f10 100644
--- a/packages/SystemUI/res/values-sv/strings.xml
+++ b/packages/SystemUI/res/values-sv/strings.xml
@@ -433,4 +433,6 @@
<string name="remove_from_settings" msgid="8389591916603406378">"Ta bort från inställningarna"</string>
<string name="remove_from_settings_prompt" msgid="6069085993355887748">"Vill du ta bort inställningar för systemgränssnitt från inställningarna och sluta använda alla tillhörande funktioner?"</string>
<string name="activity_not_found" msgid="348423244327799974">"Appen är inte installerad på enheten"</string>
+ <string name="clock_seconds" msgid="7689554147579179507">"Visa klocksekunder"</string>
+ <string name="clock_seconds_desc" msgid="6282693067130470675">"Visa klocksekunder i statusfältet. Detta kan påverka batteritiden."</string>
</resources>
diff --git a/packages/SystemUI/res/values-sw/strings.xml b/packages/SystemUI/res/values-sw/strings.xml
index 1bb6c0b..623f12c 100644
--- a/packages/SystemUI/res/values-sw/strings.xml
+++ b/packages/SystemUI/res/values-sw/strings.xml
@@ -433,4 +433,6 @@
<string name="remove_from_settings" msgid="8389591916603406378">"Ondoa kwenye Mipangilio"</string>
<string name="remove_from_settings_prompt" msgid="6069085993355887748">"Je, ungependa kuondoa Kipokea ishara cha SystemUI kwenye Mipangilio na uache kutumia vipengele vyake vyote?"</string>
<string name="activity_not_found" msgid="348423244327799974">"Programu haijasakinishwa kwenye kifaa chako"</string>
+ <string name="clock_seconds" msgid="7689554147579179507">"Onyesha sekunde za saa"</string>
+ <string name="clock_seconds_desc" msgid="6282693067130470675">"Onyesha sekunde za saa katika sehemu ya arifa. Inaweza kuathiri muda wa matumizi ya betri."</string>
</resources>
diff --git a/packages/SystemUI/res/values-ta-rIN/strings.xml b/packages/SystemUI/res/values-ta-rIN/strings.xml
index 8e64e85..c6cb337 100644
--- a/packages/SystemUI/res/values-ta-rIN/strings.xml
+++ b/packages/SystemUI/res/values-ta-rIN/strings.xml
@@ -433,4 +433,6 @@
<string name="remove_from_settings" msgid="8389591916603406378">"அமைப்புகளிலிருந்து அகற்று"</string>
<string name="remove_from_settings_prompt" msgid="6069085993355887748">"அமைப்புகளிலிருந்து System UI Tunerஐ அகற்றிவிட்டு, அதன் எல்லா அம்சங்களையும் பயன்படுத்துவதை நிறுத்தவா?"</string>
<string name="activity_not_found" msgid="348423244327799974">"சாதனத்தில் பயன்பாடு நிறுவப்படவில்லை"</string>
+ <string name="clock_seconds" msgid="7689554147579179507">"கடிகார வினாடிகளைக் காட்டு"</string>
+ <string name="clock_seconds_desc" msgid="6282693067130470675">"நிலைப் பட்டியில் கடிகார வினாடிகளைக் காட்டும். பேட்டரியின் ஆயுளைக் குறைக்கலாம்."</string>
</resources>
diff --git a/packages/SystemUI/res/values-te-rIN/strings.xml b/packages/SystemUI/res/values-te-rIN/strings.xml
index 36b00f8..c0717c1 100644
--- a/packages/SystemUI/res/values-te-rIN/strings.xml
+++ b/packages/SystemUI/res/values-te-rIN/strings.xml
@@ -433,4 +433,6 @@
<string name="remove_from_settings" msgid="8389591916603406378">"సెట్టింగ్ల నుండి తీసివేయి"</string>
<string name="remove_from_settings_prompt" msgid="6069085993355887748">"సిస్టమ్ UI ట్యూనర్ను సెట్టింగ్ల నుండి తీసివేసి, దాని అన్ని లక్షణాలను ఉపయోగించడం ఆపివేయాలా?"</string>
<string name="activity_not_found" msgid="348423244327799974">"అనువర్తనం మీ పరికరంలో ఇన్స్టాల్ చేయలేదు"</string>
+ <string name="clock_seconds" msgid="7689554147579179507">"గడియారం సెకన్లు చూపు"</string>
+ <string name="clock_seconds_desc" msgid="6282693067130470675">"స్థితి పట్టీలో గడియారం సెకన్లు చూపుతుంది. బ్యాటరీ శక్తి ప్రభావితం చేయవచ్చు."</string>
</resources>
diff --git a/packages/SystemUI/res/values-th/strings.xml b/packages/SystemUI/res/values-th/strings.xml
index 0ef2c66..e16fdd2 100644
--- a/packages/SystemUI/res/values-th/strings.xml
+++ b/packages/SystemUI/res/values-th/strings.xml
@@ -433,4 +433,6 @@
<string name="remove_from_settings" msgid="8389591916603406378">"นำออกจากการตั้งค่า"</string>
<string name="remove_from_settings_prompt" msgid="6069085993355887748">"นำตัวรับสัญญาณ UI ระบบออกจากการตั้งค่าและหยุดใช้คุณลักษณะทั้งหมดของตัวรับสัญญาณใช่ไหม"</string>
<string name="activity_not_found" msgid="348423244327799974">"ยังไม่ได้ติดตั้งแอปพลิเคชันบนอุปกรณ์ของคุณ"</string>
+ <string name="clock_seconds" msgid="7689554147579179507">"แสดงวินาทีของนาฬิกา"</string>
+ <string name="clock_seconds_desc" msgid="6282693067130470675">"แสดงวินาทีของนาฬิกาในแถบสถานะ อาจส่งผลต่ออายุแบตเตอรี"</string>
</resources>
diff --git a/packages/SystemUI/res/values-tl/strings.xml b/packages/SystemUI/res/values-tl/strings.xml
index a208c96..d970084 100644
--- a/packages/SystemUI/res/values-tl/strings.xml
+++ b/packages/SystemUI/res/values-tl/strings.xml
@@ -433,4 +433,6 @@
<string name="remove_from_settings" msgid="8389591916603406378">"Alisin sa Mga Setting"</string>
<string name="remove_from_settings_prompt" msgid="6069085993355887748">"Alisin ang Tuner ng System UI sa Mga Setting at ihinto ang paggamit ng lahat ng feature nito?"</string>
<string name="activity_not_found" msgid="348423244327799974">"Hindi naka-install ang application sa iyong device"</string>
+ <string name="clock_seconds" msgid="7689554147579179507">"Ipakita ang mga segundo ng orasan"</string>
+ <string name="clock_seconds_desc" msgid="6282693067130470675">"Ipakita ang mga segundo ng orasan sa status bar. Maaaring makaapekto sa tagal ng baterya."</string>
</resources>
diff --git a/packages/SystemUI/res/values-tr/strings.xml b/packages/SystemUI/res/values-tr/strings.xml
index d359cf1..b22b4fb 100644
--- a/packages/SystemUI/res/values-tr/strings.xml
+++ b/packages/SystemUI/res/values-tr/strings.xml
@@ -433,4 +433,6 @@
<string name="remove_from_settings" msgid="8389591916603406378">"Ayarlar\'dan kaldır"</string>
<string name="remove_from_settings_prompt" msgid="6069085993355887748">"Sistem Kullanıcı Arayüzü Ayarlayıcısı Ayarlar\'dan kaldırılsın ve tüm özelliklerinin kullanılması durdurulsun mu?"</string>
<string name="activity_not_found" msgid="348423244327799974">"Uygulama, cihazınızda yüklü değil"</string>
+ <string name="clock_seconds" msgid="7689554147579179507">"Saatin saniyelerini göster"</string>
+ <string name="clock_seconds_desc" msgid="6282693067130470675">"Durum çubuğunda saatin saniyelerini gösterir. Pil ömrünü etkileyebilir."</string>
</resources>
diff --git a/packages/SystemUI/res/values-uk/strings.xml b/packages/SystemUI/res/values-uk/strings.xml
index 3e34a1f..5c0966c 100644
--- a/packages/SystemUI/res/values-uk/strings.xml
+++ b/packages/SystemUI/res/values-uk/strings.xml
@@ -435,4 +435,6 @@
<string name="remove_from_settings" msgid="8389591916603406378">"Видалити з додатка Налаштування"</string>
<string name="remove_from_settings_prompt" msgid="6069085993355887748">"Видалити інструмент System UI Tuner із додатка Налаштування та припинити користуватися всіма його функціями?"</string>
<string name="activity_not_found" msgid="348423244327799974">"Додаток не встановлено на вашому пристрої"</string>
+ <string name="clock_seconds" msgid="7689554147579179507">"Показувати секунди на годиннику"</string>
+ <string name="clock_seconds_desc" msgid="6282693067130470675">"Показувати секунди на годиннику в рядку стану. Акумулятор може розряджатися швидше."</string>
</resources>
diff --git a/packages/SystemUI/res/values-ur-rPK/strings.xml b/packages/SystemUI/res/values-ur-rPK/strings.xml
index 650095d..d5683e1 100644
--- a/packages/SystemUI/res/values-ur-rPK/strings.xml
+++ b/packages/SystemUI/res/values-ur-rPK/strings.xml
@@ -433,4 +433,6 @@
<string name="remove_from_settings" msgid="8389591916603406378">"ترتیبات سے ہٹائیں"</string>
<string name="remove_from_settings_prompt" msgid="6069085993355887748">"ترتیبات سے سسٹم UI ٹیونر کو ہٹائیں اور اس کی سبھی خصوصیات کا استعمال بند کریں؟"</string>
<string name="activity_not_found" msgid="348423244327799974">"ایپلیکیشن آپ کے آلہ پر انسٹال نہیں ہے"</string>
+ <string name="clock_seconds" msgid="7689554147579179507">"گھڑی کے سیکنڈز دکھائیں"</string>
+ <string name="clock_seconds_desc" msgid="6282693067130470675">"گھڑی کے سیکنڈز اسٹیٹس بار میں دکھائیں۔ اس کا بیٹری کی زندگی پر اثر پڑ سکتا ہے۔"</string>
</resources>
diff --git a/packages/SystemUI/res/values-uz-rUZ/strings.xml b/packages/SystemUI/res/values-uz-rUZ/strings.xml
index e3073bc..e31af6b 100644
--- a/packages/SystemUI/res/values-uz-rUZ/strings.xml
+++ b/packages/SystemUI/res/values-uz-rUZ/strings.xml
@@ -433,4 +433,6 @@
<string name="remove_from_settings" msgid="8389591916603406378">"Sozlamalardan olib tashlash"</string>
<string name="remove_from_settings_prompt" msgid="6069085993355887748">"System UI Tuner Sozlamalardan olib tashlanib, uning barcha funksiyalaridan foydalanish to‘xtatilsinmi?"</string>
<string name="activity_not_found" msgid="348423244327799974">"Ilova qurilmangizga o‘rnatilmagan"</string>
+ <string name="clock_seconds" msgid="7689554147579179507">"Soat soniyalari ko‘rsatilsin"</string>
+ <string name="clock_seconds_desc" msgid="6282693067130470675">"Holat panelida soat soniyalari ko‘rsatilsin. Bu batareya resursiga ta’sir qilishi mumkin."</string>
</resources>
diff --git a/packages/SystemUI/res/values-vi/strings.xml b/packages/SystemUI/res/values-vi/strings.xml
index 4459497..030bbbe 100644
--- a/packages/SystemUI/res/values-vi/strings.xml
+++ b/packages/SystemUI/res/values-vi/strings.xml
@@ -433,4 +433,6 @@
<string name="remove_from_settings" msgid="8389591916603406378">"Xóa khỏi Cài đặt"</string>
<string name="remove_from_settings_prompt" msgid="6069085993355887748">"Xóa Bộ điều hướng giao diện người dùng hệ thống khỏi Cài đặt và ngừng sử dụng tất cả tính năng của ứng dụng này?"</string>
<string name="activity_not_found" msgid="348423244327799974">"Ứng dụng chưa được cài đặt trên thiết bị của bạn"</string>
+ <string name="clock_seconds" msgid="7689554147579179507">"Hiển thị giây đồng hồ"</string>
+ <string name="clock_seconds_desc" msgid="6282693067130470675">"Hiển thị giây đồng hồ trong thanh trạng thái. Có thể ảnh hưởng đến thời lượng pin."</string>
</resources>
diff --git a/packages/SystemUI/res/values-zh-rCN/strings.xml b/packages/SystemUI/res/values-zh-rCN/strings.xml
index 0272328..b046415 100644
--- a/packages/SystemUI/res/values-zh-rCN/strings.xml
+++ b/packages/SystemUI/res/values-zh-rCN/strings.xml
@@ -435,4 +435,6 @@
<string name="remove_from_settings" msgid="8389591916603406378">"从“设置”中移除"</string>
<string name="remove_from_settings_prompt" msgid="6069085993355887748">"要将系统界面调谐器从“设置”中移除,并停止使用所有相关功能吗?"</string>
<string name="activity_not_found" msgid="348423244327799974">"您的设备中未安装此应用"</string>
+ <string name="clock_seconds" msgid="7689554147579179507">"显示时钟的秒数"</string>
+ <string name="clock_seconds_desc" msgid="6282693067130470675">"在状态栏中显示时钟的秒数。这可能会影响电池的续航时间。"</string>
</resources>
diff --git a/packages/SystemUI/res/values-zh-rHK/strings.xml b/packages/SystemUI/res/values-zh-rHK/strings.xml
index 8adaeac..d568dba 100644
--- a/packages/SystemUI/res/values-zh-rHK/strings.xml
+++ b/packages/SystemUI/res/values-zh-rHK/strings.xml
@@ -435,4 +435,6 @@
<string name="remove_from_settings" msgid="8389591916603406378">"從「設定」移除"</string>
<string name="remove_from_settings_prompt" msgid="6069085993355887748">"要從「設定」移除系統使用者介面調諧器,並停止其所有功能嗎?"</string>
<string name="activity_not_found" msgid="348423244327799974">"尚未在裝置安裝應用程式"</string>
+ <string name="clock_seconds" msgid="7689554147579179507">"顯示時鐘秒數"</string>
+ <string name="clock_seconds_desc" msgid="6282693067130470675">"在狀態列中顯示時鐘秒數,但可能會影響電池壽命。"</string>
</resources>
diff --git a/packages/SystemUI/res/values-zh-rTW/strings.xml b/packages/SystemUI/res/values-zh-rTW/strings.xml
index 759b585..702ad53 100644
--- a/packages/SystemUI/res/values-zh-rTW/strings.xml
+++ b/packages/SystemUI/res/values-zh-rTW/strings.xml
@@ -435,4 +435,6 @@
<string name="remove_from_settings" msgid="8389591916603406378">"從設定中移除"</string>
<string name="remove_from_settings_prompt" msgid="6069085993355887748">"要將系統使用者介面調整精靈從設定中移除,並停止使用所有相關功能嗎?"</string>
<string name="activity_not_found" msgid="348423244327799974">"您的裝置未安裝這個應用程式"</string>
+ <string name="clock_seconds" msgid="7689554147579179507">"顯示時鐘秒數"</string>
+ <string name="clock_seconds_desc" msgid="6282693067130470675">"在狀態列中顯示時鐘秒數。這可能會影響電池續航力。"</string>
</resources>
diff --git a/packages/SystemUI/res/values-zu/strings.xml b/packages/SystemUI/res/values-zu/strings.xml
index 1e7be90..8774036 100644
--- a/packages/SystemUI/res/values-zu/strings.xml
+++ b/packages/SystemUI/res/values-zu/strings.xml
@@ -433,4 +433,6 @@
<string name="remove_from_settings" msgid="8389591916603406378">"Susa kusuka kuzilungiselelo"</string>
<string name="remove_from_settings_prompt" msgid="6069085993355887748">"Susa isishuni se-UI yesistimu kusuka kuzilungiselelo futhi uyeke ukusebenzisa zonke izici zakhona?"</string>
<string name="activity_not_found" msgid="348423244327799974">"Uhlelo lokusebenza alufakiwe kudivayisi yakho"</string>
+ <string name="clock_seconds" msgid="7689554147579179507">"Bonisa amasekhondi wewashi"</string>
+ <string name="clock_seconds_desc" msgid="6282693067130470675">"Bonisa amasekhondi wewashi kubha yesimo. Ingathinta impilo yebhethri."</string>
</resources>
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaProjectionPermissionActivity.java b/packages/SystemUI/src/com/android/systemui/media/MediaProjectionPermissionActivity.java
index 2a84362..adc9b36 100644
--- a/packages/SystemUI/src/com/android/systemui/media/MediaProjectionPermissionActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaProjectionPermissionActivity.java
@@ -22,6 +22,7 @@
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
+import android.graphics.Typeface;
import android.media.projection.MediaProjectionManager;
import android.media.projection.IMediaProjectionManager;
import android.media.projection.IMediaProjection;
@@ -29,7 +30,14 @@
import android.os.IBinder;
import android.os.RemoteException;
import android.os.ServiceManager;
+import android.text.BidiFormatter;
+import android.text.Spannable;
+import android.text.SpannableString;
+import android.text.TextPaint;
+import android.text.TextUtils;
+import android.text.style.StyleSpan;
import android.util.Log;
+import android.util.TypedValue;
import android.view.WindowManager;
import android.widget.CheckBox;
import android.widget.CompoundButton;
@@ -39,6 +47,8 @@
implements DialogInterface.OnClickListener, CheckBox.OnCheckedChangeListener,
DialogInterface.OnCancelListener {
private static final String TAG = "MediaProjectionPermissionActivity";
+ private static final float MAX_APP_NAME_SIZE_PX = 500f;
+ private static final String ELLIPSIS = "\u2026";
private boolean mPermanentGrant;
private String mPackageName;
@@ -84,11 +94,49 @@
return;
}
- String appName = aInfo.loadLabel(packageManager).toString();
+ TextPaint paint = new TextPaint();
+ paint.setTextSize(42);
+
+ String label = aInfo.loadLabel(packageManager).toString();
+
+ // If the label contains new line characters it may push the security
+ // message below the fold of the dialog. Labels shouldn't have new line
+ // characters anyways, so just truncate the message the first time one
+ // is seen.
+ final int labelLength = label.length();
+ int offset = 0;
+ while (offset < labelLength) {
+ final int codePoint = label.codePointAt(offset);
+ final int type = Character.getType(codePoint);
+ if (type == Character.LINE_SEPARATOR
+ || type == Character.CONTROL
+ || type == Character.PARAGRAPH_SEPARATOR) {
+ label = label.substring(0, offset) + ELLIPSIS;
+ break;
+ }
+ offset += Character.charCount(codePoint);
+ }
+
+ if (label.isEmpty()) {
+ label = mPackageName;
+ }
+
+ String unsanitizedAppName = TextUtils.ellipsize(label,
+ paint, MAX_APP_NAME_SIZE_PX, TextUtils.TruncateAt.END).toString();
+ String appName = BidiFormatter.getInstance().unicodeWrap(unsanitizedAppName);
+
+ String actionText = getString(R.string.media_projection_dialog_text, appName);
+ SpannableString message = new SpannableString(actionText);
+
+ int appNameIndex = actionText.indexOf(appName);
+ if (appNameIndex >= 0) {
+ message.setSpan(new StyleSpan(Typeface.BOLD),
+ appNameIndex, appNameIndex + appName.length(), 0);
+ }
mDialog = new AlertDialog.Builder(this)
.setIcon(aInfo.loadIcon(packageManager))
- .setMessage(getString(R.string.media_projection_dialog_text, appName))
+ .setMessage(message)
.setPositiveButton(R.string.media_projection_action_text, this)
.setNegativeButton(android.R.string.cancel, this)
.setView(R.layout.remember_permission_checkbox)
diff --git a/packages/SystemUI/src/com/android/systemui/media/NotificationPlayer.java b/packages/SystemUI/src/com/android/systemui/media/NotificationPlayer.java
index 803a014..728d558 100644
--- a/packages/SystemUI/src/com/android/systemui/media/NotificationPlayer.java
+++ b/packages/SystemUI/src/com/android/systemui/media/NotificationPlayer.java
@@ -21,6 +21,7 @@
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnCompletionListener;
+import android.media.MediaPlayer.OnErrorListener;
import android.net.Uri;
import android.os.Looper;
import android.os.PowerManager;
@@ -36,7 +37,7 @@
* - whenever audio is played, audio focus is requested,
* - whenever audio playback is stopped or the playback completed, audio focus is abandoned.
*/
-public class NotificationPlayer implements OnCompletionListener {
+public class NotificationPlayer implements OnCompletionListener, OnErrorListener {
private static final int PLAY = 1;
private static final int STOP = 2;
private static final boolean mDebug = false;
@@ -112,6 +113,7 @@
// done playing. This class should be modified to use a single thread, on which
// command are issued, and on which it receives the completion callbacks.
player.setOnCompletionListener(NotificationPlayer.this);
+ player.setOnErrorListener(NotificationPlayer.this);
player.start();
if (mPlayer != null) {
mPlayer.release();
@@ -245,6 +247,13 @@
}
}
+ public boolean onError(MediaPlayer mp, int what, int extra) {
+ Log.e(mTag, "error " + what + " (extra=" + extra + ") playing notification");
+ // error happened, handle it just like a completion
+ onCompletion(mp);
+ return true;
+ }
+
private String mTag;
private CmdThread mThread;
private CreationAndCompletionThread mCompletionThread;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
index 2f6aec7..564a60a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
@@ -24,6 +24,7 @@
import android.graphics.drawable.AnimationDrawable;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
+import android.graphics.drawable.RippleDrawable;
import android.service.notification.StatusBarNotification;
import android.util.AttributeSet;
import android.view.MotionEvent;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationBackgroundView.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationBackgroundView.java
index 01aa8d1..8688c28 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationBackgroundView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationBackgroundView.java
@@ -86,6 +86,9 @@
if (mBackground != null) {
mBackground.setCallback(this);
}
+ if (mBackground instanceof RippleDrawable) {
+ ((RippleDrawable) mBackground).setForceSoftware(true);
+ }
invalidate();
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/AppInfo.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/AppInfo.java
index 5ec5147..e34c821 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/AppInfo.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/AppInfo.java
@@ -17,24 +17,26 @@
package com.android.systemui.statusbar.phone;
import android.content.ComponentName;
+import android.os.UserHandle;
/**
* Navigation bar app information.
*/
class AppInfo {
private final ComponentName mComponentName;
- private final long mUserSerialNumber;
+ private final UserHandle mUser;
- public AppInfo(ComponentName componentName, long userSerialNumber) {
+ public AppInfo(ComponentName componentName, UserHandle user) {
+ if (componentName == null || user == null) throw new IllegalArgumentException();
mComponentName = componentName;
- mUserSerialNumber = userSerialNumber;
+ mUser = user;
}
public ComponentName getComponentName() {
return mComponentName;
}
- public long getUserSerialNumber() {
- return mUserSerialNumber;
+ public UserHandle getUser() {
+ return mUser;
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/FingerprintUnlockController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/FingerprintUnlockController.java
index 28d4a42ef..4e69999 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/FingerprintUnlockController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/FingerprintUnlockController.java
@@ -183,8 +183,11 @@
mStatusBarKeyguardViewManager.animateCollapsePanels(
FINGERPRINT_COLLAPSE_SPEEDUP_FACTOR);
break;
- case MODE_WAKE_AND_UNLOCK:
case MODE_WAKE_AND_UNLOCK_PULSING:
+ mPhoneStatusBar.updateMediaMetaData(false /* metaDataChanged */);
+ // Fall through.
+ case MODE_WAKE_AND_UNLOCK:
+ mStatusBarWindowManager.setStatusBarFocusable(false);
mDozeScrimController.abortPulsing();
mKeyguardViewMediator.onWakeAndUnlocking();
mScrimController.setWakeAndUnlocking();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/GetActivityIconTask.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/GetActivityIconTask.java
index 076378e..f46d1a6 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/GetActivityIconTask.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/GetActivityIconTask.java
@@ -16,20 +16,21 @@
package com.android.systemui.statusbar.phone;
-import android.content.ComponentName;
+import android.app.AppGlobals;
+import android.content.pm.ActivityInfo;
+import android.content.pm.IPackageManager;
import android.content.pm.PackageManager;
-import android.content.pm.PackageManager.NameNotFoundException;
import android.graphics.drawable.Drawable;
import android.os.AsyncTask;
+import android.os.RemoteException;
import android.util.Slog;
-import android.view.View;
import android.widget.ImageView;
/**
* Retrieves the icon for an activity and sets it as the Drawable on an ImageView. The ImageView
* is hidden if the activity isn't recognized or if there is no icon.
*/
-class GetActivityIconTask extends AsyncTask<ComponentName, Void, Drawable> {
+class GetActivityIconTask extends AsyncTask<AppInfo, Void, Drawable> {
private final static String TAG = "GetActivityIconTask";
private final PackageManager mPackageManager;
@@ -43,15 +44,27 @@
}
@Override
- protected Drawable doInBackground(ComponentName... params) {
+ protected Drawable doInBackground(AppInfo... params) {
if (params.length != 1) {
throw new IllegalArgumentException("Expected one parameter");
}
- ComponentName activityName = params[0];
+ AppInfo appInfo = params[0];
try {
- return mPackageManager.getActivityIcon(activityName);
- } catch (NameNotFoundException e) {
- Slog.w(TAG, "Icon not found for " + activityName);
+ IPackageManager mPM = AppGlobals.getPackageManager();
+ ActivityInfo ai = mPM.getActivityInfo(
+ appInfo.getComponentName(),
+ 0,
+ appInfo.getUser().getIdentifier());
+
+ if (ai == null) {
+ Slog.w(TAG, "Icon not found for " + appInfo);
+ return null;
+ }
+
+ Drawable unbadgedIcon = ai.loadIcon(mPackageManager);
+ return mPackageManager.getUserBadgedIcon(unbadgedIcon, appInfo.getUser());
+ } catch (RemoteException e) {
+ Slog.w(TAG, "Icon not found for " + appInfo, e);
return null;
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarApps.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarApps.java
index cb5c125..613a17b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarApps.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarApps.java
@@ -28,14 +28,12 @@
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.ApplicationInfo;
-import android.content.pm.IPackageManager;
import android.content.pm.PackageManager;
import android.graphics.Rect;
import android.os.Bundle;
import android.os.UserHandle;
import android.os.UserManager;
import android.util.AttributeSet;
-import android.util.Log;
import android.util.Slog;
import android.view.DragEvent;
import android.view.LayoutInflater;
@@ -48,8 +46,6 @@
import com.android.internal.content.PackageMonitor;
import com.android.systemui.R;
-import java.util.List;
-
/**
* Container for application icons that appear in the navigation bar. Their appearance is similar
* to the launcher hotseat. Clicking an icon launches the associated activity. A long click will
@@ -84,8 +80,6 @@
// When the user is not dragging this member is null.
private View mDragView;
- private long mCurrentUserSerialNumber = -1;
-
private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
@@ -173,17 +167,17 @@
}
private void removeIfUnlauncheable(String packageName, UserHandle user) {
- long appUserSerialNumber = mUserManager.getSerialNumberForUser(user);
-
// Remove icons for all apps that match a package that perhaps became unlauncheable.
for(int i = sAppsModel.getAppCount() - 1; i >= 0; --i) {
AppInfo appInfo = sAppsModel.getApp(i);
- if (appInfo.getUserSerialNumber() != appUserSerialNumber) continue;
+ if (!appInfo.getUser().equals(user)) continue;
ComponentName appComponentName = appInfo.getComponentName();
if (!appComponentName.getPackageName().equals(packageName)) continue;
- if (sAppsModel.buildAppLaunchIntent(appComponentName, user) != null) continue;
+ if (sAppsModel.buildAppLaunchIntent(new AppInfo(appComponentName, user)) != null) {
+ continue;
+ }
removeViewAt(i);
sAppsModel.removeApp(i);
@@ -206,10 +200,7 @@
transition.enableTransitionType(LayoutTransition.CHANGING);
parent.setLayoutTransition(transition);
- int currentUserId = ActivityManager.getCurrentUser();
- mCurrentUserSerialNumber = mUserManager.getSerialNumberForUser(
- new UserHandle(currentUserId));
- sAppsModel.setCurrentUser(currentUserId);
+ sAppsModel.setCurrentUser(ActivityManager.getCurrentUser());
recreateAppButtons();
IntentFilter filter = new IntentFilter();
@@ -244,7 +235,7 @@
button.setContentDescription(appLabel);
// Load the icon asynchronously.
- new GetActivityIconTask(mPackageManager, button).execute(app.getComponentName());
+ new GetActivityIconTask(mPackageManager, button).execute(app);
}
}
@@ -280,7 +271,7 @@
*/
@Nullable
static CharSequence getAppLabel(PackageManager packageManager,
- ComponentName activityName) {
+ ComponentName activityName) {
String packageName = activityName.getPackageName();
ApplicationInfo info;
try {
@@ -296,7 +287,10 @@
static void startAppDrag(ImageView icon, AppInfo appInfo) {
// The drag data is an Intent to launch the activity.
Intent mainIntent = Intent.makeMainActivity(appInfo.getComponentName());
- mainIntent.putExtra(EXTRA_PROFILE, appInfo.getUserSerialNumber());
+ UserManager userManager =
+ (UserManager) icon.getContext().getSystemService(Context.USER_SERVICE);
+ long userSerialNumber = userManager.getSerialNumberForUser(appInfo.getUser());
+ mainIntent.putExtra(EXTRA_PROFILE, userSerialNumber);
ClipData dragData = ClipData.newIntent("", mainIntent);
// Use the ImageView to create the shadow.
View.DragShadowBuilder shadow = new AppIconDragShadowBuilder(icon);
@@ -472,17 +466,17 @@
// Validate the received user serial number.
UserHandle appUser = mUserManager.getUserForSerialNumber(userSerialNumber);
if (appUser == null) {
- userSerialNumber = mCurrentUserSerialNumber;
+ appUser = new UserHandle(ActivityManager.getCurrentUser());
}
- return new AppInfo(intent.getComponent(), userSerialNumber);
+ return new AppInfo(intent.getComponent(), appUser);
}
/** Updates the app at a given view index. */
private void updateAppAt(int index, AppInfo appInfo) {
sAppsModel.setApp(index, appInfo);
ImageView button = (ImageView) getChildAt(index);
- new GetActivityIconTask(mPackageManager, button).execute(appInfo.getComponentName());
+ new GetActivityIconTask(mPackageManager, button).execute(appInfo);
}
/** Removes the empty placeholder view and cleans up the data model. */
@@ -540,20 +534,10 @@
@Override
public void onClick(View v) {
AppInfo appInfo = sAppsModel.getApp(indexOfChild(v));
- ComponentName component = appInfo.getComponentName();
-
- long appUserSerialNumber = appInfo.getUserSerialNumber();
- UserHandle appUser = mUserManager.getUserForSerialNumber(appUserSerialNumber);
- if (appUser == null) {
- Toast.makeText(getContext(), R.string.activity_not_found, Toast.LENGTH_SHORT).show();
- Log.e(TAG, "Can't start activity " + component +
- " because its user doesn't exist.");
- return;
- }
-
- Intent launchIntent = sAppsModel.buildAppLaunchIntent(component, appUser);
+ Intent launchIntent = sAppsModel.buildAppLaunchIntent(appInfo);
if (launchIntent == null) {
- Toast.makeText(getContext(), R.string.activity_not_found, Toast.LENGTH_SHORT).show();
+ Toast.makeText(
+ getContext(), R.string.activity_not_found, Toast.LENGTH_SHORT).show();
return;
}
@@ -568,18 +552,12 @@
Bundle optsBundle = opts.toBundle();
launchIntent.setSourceBounds(sourceBounds);
- mContext.startActivityAsUser(launchIntent, optsBundle, appUser);
+ mContext.startActivityAsUser(launchIntent, optsBundle, appInfo.getUser());
}
}
private void onUserSwitched(int currentUserId) {
- final long newUserSerialNumber =
- mUserManager.getSerialNumberForUser(new UserHandle(currentUserId));
-
- if (newUserSerialNumber != mCurrentUserSerialNumber) {
- mCurrentUserSerialNumber = newUserSerialNumber;
- sAppsModel.setCurrentUser(currentUserId);
- recreateAppButtons();
- }
+ sAppsModel.setCurrentUser(currentUserId);
+ recreateAppButtons();
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarAppsModel.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarAppsModel.java
index c4c31fd..71d30a9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarAppsModel.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarAppsModel.java
@@ -106,9 +106,10 @@
return AppGlobals.getPackageManager();
}
- // Returns a launch intent for a given component, or null if the component is unlauncheable.
- public Intent buildAppLaunchIntent(ComponentName component, UserHandle appUser) {
- int appUserId = appUser.getIdentifier();
+ // Returns a launch intent for a given app info, or null if the app info is unlauncheable.
+ public Intent buildAppLaunchIntent(AppInfo appInfo) {
+ ComponentName component = appInfo.getComponentName();
+ int appUserId = appInfo.getUser().getIdentifier();
// This code is based on LauncherAppsService.startActivityAsUser code.
Intent launchIntent = new Intent(Intent.ACTION_MAIN);
@@ -250,7 +251,8 @@
final AppInfo appInfo = mApps.get(i);
String componentNameString = appInfo.getComponentName().flattenToString();
edit.putString(prefNameForApp(i), componentNameString);
- edit.putLong(prefUserForApp(i), appInfo.getUserSerialNumber());
+ long userSerialNumber = mUserManager.getSerialNumberForUser(appInfo.getUser());
+ edit.putLong(prefUserForApp(i), userSerialNumber);
}
// Start an asynchronous disk write.
edit.apply();
@@ -278,8 +280,9 @@
continue;
}
UserHandle appUser = mUserManager.getUserForSerialNumber(userSerialNumber);
- if (appUser != null && buildAppLaunchIntent(componentName, appUser) != null) {
- mApps.add(new AppInfo(componentName, userSerialNumber));
+ AppInfo appInfo = new AppInfo(componentName, appUser);
+ if (appUser != null && buildAppLaunchIntent(appInfo) != null) {
+ mApps.add(appInfo);
} else {
hadUnlauncheableApps = true;
}
@@ -301,7 +304,7 @@
ResolveInfo ri = apps.get(i);
ComponentName componentName = new ComponentName(
ri.activityInfo.packageName, ri.activityInfo.name);
- mApps.add(new AppInfo(componentName, mCurrentUserSerialNumber));
+ mApps.add(new AppInfo(componentName, new UserHandle(mCurrentUserId)));
}
savePrefs();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarRecents.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarRecents.java
index b024ec4..1f71bc0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarRecents.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarRecents.java
@@ -25,11 +25,12 @@
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
import android.os.Handler;
import android.os.RemoteException;
import android.os.UserHandle;
-import android.os.UserManager;
import android.util.AttributeSet;
+import android.util.Log;
import android.util.Slog;
import android.util.SparseBooleanArray;
import android.view.LayoutInflater;
@@ -160,7 +161,8 @@
button.setVisibility(View.VISIBLE);
// Load the activity icon on a background thread.
- new GetActivityIconTask(mPackageManager, button).execute(getRealActivityForTask(task));
+ AppInfo app = new AppInfo(activityName, new UserHandle(task.userId));
+ new GetActivityIconTask(mPackageManager, button).execute(app);
final int taskPersistentId = task.persistentId;
button.setOnClickListener(new View.OnClickListener() {
@@ -171,7 +173,9 @@
try {
manager.startActivityFromRecents(taskPersistentId, null /* options */);
} catch (RemoteException e) {
- e.printStackTrace();
+ Log.e(TAG, "Exception when activating a recent task", e);
+ } catch (IllegalArgumentException e) {
+ Log.e(TAG, "Exception when activating a recent task", e);
}
}
});
@@ -218,6 +222,35 @@
mContext = context;
}
+ private ComponentName getLaunchComponentForPackage(String packageName, int userId) {
+ // This code is based on ApplicationPackageManager.getLaunchIntentForPackage.
+ PackageManager packageManager = mContext.getPackageManager();
+
+ // First see if the package has an INFO activity; the existence of
+ // such an activity is implied to be the desired front-door for the
+ // overall package (such as if it has multiple launcher entries).
+ Intent intentToResolve = new Intent(Intent.ACTION_MAIN);
+ intentToResolve.addCategory(Intent.CATEGORY_INFO);
+ intentToResolve.setPackage(packageName);
+ List<ResolveInfo> ris = packageManager.queryIntentActivitiesAsUser(
+ intentToResolve, 0, userId);
+
+ // Otherwise, try to find a main launcher activity.
+ if (ris == null || ris.size() <= 0) {
+ // reuse the intent instance
+ intentToResolve.removeCategory(Intent.CATEGORY_INFO);
+ intentToResolve.addCategory(Intent.CATEGORY_LAUNCHER);
+ intentToResolve.setPackage(packageName);
+ ris = packageManager.queryIntentActivitiesAsUser(intentToResolve, 0, userId);
+ }
+ if (ris == null || ris.size() <= 0) {
+ Log.e(TAG, "Failed to build intent for " + packageName);
+ return null;
+ }
+ return new ComponentName(ris.get(0).activityInfo.packageName,
+ ris.get(0).activityInfo.name);
+ }
+
@Override
public boolean onLongClick(View v) {
ImageView icon = (ImageView) v;
@@ -226,17 +259,15 @@
// for the task's package.
RecentTaskInfo task = (RecentTaskInfo) v.getTag();
String packageName = getRealActivityForTask(task).getPackageName();
- Intent intent = mContext.getPackageManager().getLaunchIntentForPackage(packageName);
- if (intent == null) {
+ ComponentName component = getLaunchComponentForPackage(packageName, task.userId);
+ if (component == null) {
return false;
}
- if (DEBUG) Slog.d(TAG, "Start drag with " + intent);
+ if (DEBUG) Slog.d(TAG, "Start drag with " + component);
- UserManager userManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
- long userSerialNumber = userManager.getSerialNumberForUser(new UserHandle(task.userId));
NavigationBarApps.startAppDrag(
- icon, new AppInfo(intent.getComponent(), userSerialNumber));
+ icon, new AppInfo(component, new UserHandle(task.userId)));
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 1cdbd97..278a7e7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -1724,7 +1724,9 @@
final boolean hasArtwork = artworkBitmap != null;
- if ((hasArtwork || DEBUG_MEDIA_FAKE_ARTWORK) && mState != StatusBarState.SHADE) {
+ if ((hasArtwork || DEBUG_MEDIA_FAKE_ARTWORK) && mState != StatusBarState.SHADE
+ && mFingerprintUnlockController.getMode()
+ != FingerprintUnlockController.MODE_WAKE_AND_UNLOCK_PULSING) {
// time to show some art!
if (mBackdrop.getVisibility() != View.VISIBLE) {
mBackdrop.setVisibility(View.VISIBLE);
@@ -1779,31 +1781,40 @@
if (DEBUG_MEDIA) {
Log.v(TAG, "DEBUG_MEDIA: Fading out album artwork");
}
- mBackdrop.animate()
- // Never let the alpha become zero - otherwise the RenderNode
- // won't draw anything and uninitialized memory will show through
- // if mScrimSrcModeEnabled. Note that 0.001 is rounded down to 0 in libhwui.
- .alpha(0.002f)
- .setInterpolator(mBackdropInterpolator)
- .setDuration(300)
- .setStartDelay(0)
- .withEndAction(new Runnable() {
- @Override
- public void run() {
- mBackdrop.setVisibility(View.GONE);
- mBackdropFront.animate().cancel();
- mBackdropBack.animate().cancel();
- mHandler.post(mHideBackdropFront);
- }
- });
- if (mKeyguardFadingAway) {
- mBackdrop.animate()
+ if (mFingerprintUnlockController.getMode()
+ == FingerprintUnlockController.MODE_WAKE_AND_UNLOCK_PULSING) {
- // Make it disappear faster, as the focus should be on the activity behind.
- .setDuration(mKeyguardFadingAwayDuration / 2)
- .setStartDelay(mKeyguardFadingAwayDelay)
- .setInterpolator(mLinearInterpolator)
- .start();
+ // We are unlocking directly - no animation!
+ mBackdrop.setVisibility(View.GONE);
+ } else {
+ mBackdrop.animate()
+ // Never let the alpha become zero - otherwise the RenderNode
+ // won't draw anything and uninitialized memory will show through
+ // if mScrimSrcModeEnabled. Note that 0.001 is rounded down to 0 in
+ // libhwui.
+ .alpha(0.002f)
+ .setInterpolator(mBackdropInterpolator)
+ .setDuration(300)
+ .setStartDelay(0)
+ .withEndAction(new Runnable() {
+ @Override
+ public void run() {
+ mBackdrop.setVisibility(View.GONE);
+ mBackdropFront.animate().cancel();
+ mBackdropBack.animate().cancel();
+ mHandler.post(mHideBackdropFront);
+ }
+ });
+ if (mKeyguardFadingAway) {
+ mBackdrop.animate()
+
+ // Make it disappear faster, as the focus should be on the activity
+ // behind.
+ .setDuration(mKeyguardFadingAwayDuration / 2)
+ .setStartDelay(mKeyguardFadingAwayDelay)
+ .setInterpolator(mLinearInterpolator)
+ .start();
+ }
}
}
}
@@ -2465,8 +2476,12 @@
|| mStatusBarMode == MODE_LIGHTS_OUT_TRANSPARENT);
boolean allowLight = isTransparentBar && !mBatteryController.isPowerSave();
boolean light = (vis & View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR) != 0;
-
- mIconController.setIconsDark(allowLight && light);
+ boolean animate = mFingerprintUnlockController == null
+ || (mFingerprintUnlockController.getMode()
+ != FingerprintUnlockController.MODE_WAKE_AND_UNLOCK_PULSING
+ && mFingerprintUnlockController.getMode()
+ != FingerprintUnlockController.MODE_WAKE_AND_UNLOCK);
+ mIconController.setIconsDark(allowLight && light, animate);
}
// restore the recents bit
if (wasRecentsVisible) {
@@ -4089,8 +4104,9 @@
public void appTransitionStarting(long startTime, long duration) {
// Use own timings when Keyguard is going away, see keyguardGoingAway and
- // setKeyguardFadingAway
- if (!mKeyguardFadingAway) {
+ // setKeyguardFadingAway. When duration is 0, skip this one because no animation is really
+ // playing.
+ if (!mKeyguardFadingAway && duration > 0) {
mIconController.appTransitionStarting(startTime, duration);
}
if (mIconPolicy != null) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/SettingsButton.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/SettingsButton.java
index a1e9ece..18db5b8 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/SettingsButton.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/SettingsButton.java
@@ -19,6 +19,7 @@
import android.animation.Animator.AnimatorListener;
import android.animation.ObjectAnimator;
import android.content.Context;
+import android.graphics.drawable.RippleDrawable;
import android.os.Handler;
import android.os.Message;
import android.util.AttributeSet;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarHeaderView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarHeaderView.java
index 7ee47df..e9c4e49 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarHeaderView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarHeaderView.java
@@ -26,6 +26,7 @@
import android.graphics.Rect;
import android.graphics.drawable.Animatable;
import android.graphics.drawable.Drawable;
+import android.graphics.drawable.RippleDrawable;
import android.util.AttributeSet;
import android.util.MathUtils;
import android.util.TypedValue;
@@ -184,6 +185,12 @@
}
});
requestCaptureValues();
+
+ // RenderThread is doing more harm than good when touching the header (to expand quick
+ // settings), so disable it for this view
+ ((RippleDrawable) getBackground()).setForceSoftware(true);
+ ((RippleDrawable) mSettingsButton.getBackground()).setForceSoftware(true);
+ ((RippleDrawable) mSystemIconsSuperContainer.getBackground()).setForceSoftware(true);
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconController.java
index 067e50e..5de1c13 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconController.java
@@ -335,8 +335,10 @@
}
}
- public void setIconsDark(boolean dark) {
- if (mTransitionPending) {
+ public void setIconsDark(boolean dark, boolean animate) {
+ if (!animate) {
+ setIconTintInternal(dark ? 1.0f : 0.0f);
+ } else if (mTransitionPending) {
deferIconTintChange(dark ? 1.0f : 0.0f);
} else if (mTransitionDeferring) {
animateIconTint(dark ? 1.0f : 0.0f,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SecurityControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SecurityControllerImpl.java
index 6af9854..6d791bf 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SecurityControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SecurityControllerImpl.java
@@ -178,7 +178,8 @@
mCurrentUserId = newUserId;
if (mUserManager.getUserInfo(newUserId).isRestricted()) {
// VPN for a restricted profile is routed through its owner user
- mVpnUserId = UserHandle.USER_OWNER;
+ // TODO: http://b/22950929
+ mVpnUserId = UserHandle.USER_SYSTEM;
} else {
mVpnUserId = mCurrentUserId;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java
index 82064a7..cf696a1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java
@@ -127,7 +127,7 @@
mCollapseSecondCardPadding = context.getResources().getDimensionPixelSize(
R.dimen.notification_collapse_second_card_padding);
mScaleDimmed = context.getResources().getDisplayMetrics().densityDpi
- >= DisplayMetrics.DENSITY_XXHIGH;
+ >= DisplayMetrics.DENSITY_420;
}
public boolean shouldScaleDimmed() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NavigationBarAppsModelTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NavigationBarAppsModelTest.java
index 4d0e28b..2f7be0b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NavigationBarAppsModelTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NavigationBarAppsModelTest.java
@@ -84,9 +84,12 @@
when(mMockPrefs.getInt("version", -1)).thenReturn(3);
when(mMockPrefs.edit()).thenReturn(mMockEdit);
- when(mMockUserManager.getSerialNumberForUser(new UserHandle(2))).thenReturn(22L);
- when(mMockUserManager.getUserForSerialNumber(45L)).thenReturn(new UserHandle(4));
- when(mMockUserManager.getUserForSerialNumber(239L)).thenReturn(new UserHandle(5));
+ when(mMockUserManager.getSerialNumberForUser(new UserHandle(2))).thenReturn(222L);
+ when(mMockUserManager.getSerialNumberForUser(new UserHandle(4))).thenReturn(444L);
+ when(mMockUserManager.getSerialNumberForUser(new UserHandle(5))).thenReturn(555L);
+ when(mMockUserManager.getUserForSerialNumber(222L)).thenReturn(new UserHandle(2));
+ when(mMockUserManager.getUserForSerialNumber(444L)).thenReturn(new UserHandle(4));
+ when(mMockUserManager.getUserForSerialNumber(555L)).thenReturn(new UserHandle(5));
mModel = new NavigationBarAppsModel(context) {
@Override
@@ -136,17 +139,17 @@
// Unlauncheable (for various reasons) apps.
assertEquals(null, mModel.buildAppLaunchIntent(
- new ComponentName("package0", "class0"), new UserHandle(3)));
+ new AppInfo(new ComponentName("package0", "class0"), new UserHandle(3))));
assertEquals(null, mModel.buildAppLaunchIntent(
- new ComponentName("package1", "class1"), new UserHandle(4)));
+ new AppInfo(new ComponentName("package1", "class1"), new UserHandle(4))));
assertEquals(null, mModel.buildAppLaunchIntent(
- new ComponentName("package2", "class2"), new UserHandle(5)));
+ new AppInfo(new ComponentName("package2", "class2"), new UserHandle(5))));
assertEquals(null, mModel.buildAppLaunchIntent(
- new ComponentName("package3", "class3"), new UserHandle(6)));
+ new AppInfo(new ComponentName("package3", "class3"), new UserHandle(6))));
// A launcheable app.
Intent intent = mModel.buildAppLaunchIntent(
- new ComponentName("package4", "class4"), new UserHandle(7));
+ new AppInfo(new ComponentName("package4", "class4"), new UserHandle(7)));
assertNotNull(intent);
assertEquals(new ComponentName("package4", "class4"), intent.getComponent());
assertEquals("package4", intent.getPackage());
@@ -155,13 +158,13 @@
/** Initializes the model from SharedPreferences for a few app activites. */
private void initializeModelFromPrefs() {
// Assume several apps are stored.
- when(mMockPrefs.getInt("22|app_count", -1)).thenReturn(3);
- when(mMockPrefs.getString("22|app_0", null)).thenReturn("package0/class0");
- when(mMockPrefs.getLong("22|app_user_0", -1)).thenReturn(-1L);
- when(mMockPrefs.getString("22|app_1", null)).thenReturn("package1/class1");
- when(mMockPrefs.getLong("22|app_user_1", -1)).thenReturn(45L);
- when(mMockPrefs.getString("22|app_2", null)).thenReturn("package2/class2");
- when(mMockPrefs.getLong("22|app_user_2", -1)).thenReturn(239L);
+ when(mMockPrefs.getInt("222|app_count", -1)).thenReturn(3);
+ when(mMockPrefs.getString("222|app_0", null)).thenReturn("package0/class0");
+ when(mMockPrefs.getLong("222|app_user_0", -1)).thenReturn(-1L);
+ when(mMockPrefs.getString("222|app_1", null)).thenReturn("package1/class1");
+ when(mMockPrefs.getLong("222|app_user_1", -1)).thenReturn(444L);
+ when(mMockPrefs.getString("222|app_2", null)).thenReturn("package2/class2");
+ when(mMockPrefs.getLong("222|app_user_2", -1)).thenReturn(555L);
ActivityInfo mockActivityInfo = new ActivityInfo();
mockActivityInfo.exported = true;
@@ -204,15 +207,15 @@
initializeModelFromPrefs();
assertEquals(2, mModel.getAppCount());
assertEquals("package1/class1", mModel.getApp(0).getComponentName().flattenToString());
- assertEquals(45L, mModel.getApp(0).getUserSerialNumber());
+ assertEquals(new UserHandle(4), mModel.getApp(0).getUser());
assertEquals("package2/class2", mModel.getApp(1).getComponentName().flattenToString());
- assertEquals(239L, mModel.getApp(1).getUserSerialNumber());
+ assertEquals(new UserHandle(5), mModel.getApp(1).getUser());
}
/** Tests initializing the model when the SharedPreferences aren't available. */
public void testInitializeDefaultApps() {
// Assume the user's app count pref isn't available.
- when(mMockPrefs.getInt("22|app_count", -1)).thenReturn(-1);
+ when(mMockPrefs.getInt("222|app_count", -1)).thenReturn(-1);
// Assume some installed activities.
ActivityInfo ai1 = new ActivityInfo();
@@ -233,16 +236,16 @@
mModel.setCurrentUser(2);
assertEquals(2, mModel.getAppCount());
assertEquals("package1/class1", mModel.getApp(0).getComponentName().flattenToString());
- assertEquals(22L, mModel.getApp(0).getUserSerialNumber());
+ assertEquals(new UserHandle(2), mModel.getApp(0).getUser());
assertEquals("package2/class2", mModel.getApp(1).getComponentName().flattenToString());
- assertEquals(22L, mModel.getApp(1).getUserSerialNumber());
+ assertEquals(new UserHandle(2), mModel.getApp(1).getUser());
InOrder order = inOrder(mMockEdit);
order.verify(mMockEdit).apply();
- order.verify(mMockEdit).putInt("22|app_count", 2);
- order.verify(mMockEdit).putString("22|app_0", "package1/class1");
- order.verify(mMockEdit).putLong("22|app_user_0", 22L);
- order.verify(mMockEdit).putString("22|app_1", "package2/class2");
- order.verify(mMockEdit).putLong("22|app_user_1", 22L);
+ order.verify(mMockEdit).putInt("222|app_count", 2);
+ order.verify(mMockEdit).putString("222|app_0", "package1/class1");
+ order.verify(mMockEdit).putLong("222|app_user_0", 222L);
+ order.verify(mMockEdit).putString("222|app_1", "package2/class2");
+ order.verify(mMockEdit).putLong("222|app_user_1", 222L);
order.verify(mMockEdit).apply();
verifyNoMoreInteractions(mMockEdit);
}
@@ -250,12 +253,12 @@
/** Tests initializing the model if one of the prefs is missing. */
public void testInitializeWithMissingPref() {
// Assume two apps are nominally stored.
- when(mMockPrefs.getInt("22|app_count", -1)).thenReturn(2);
- when(mMockPrefs.getString("22|app_0", null)).thenReturn("package0/class0");
- when(mMockPrefs.getLong("22|app_user_0", -1)).thenReturn(239L);
+ when(mMockPrefs.getInt("222|app_count", -1)).thenReturn(2);
+ when(mMockPrefs.getString("222|app_0", null)).thenReturn("package0/class0");
+ when(mMockPrefs.getLong("222|app_user_0", -1)).thenReturn(555L);
// But assume one pref is missing.
- when(mMockPrefs.getString("22|app_1", null)).thenReturn(null);
+ when(mMockPrefs.getString("222|app_1", null)).thenReturn(null);
ActivityInfo mockActivityInfo = new ActivityInfo();
mockActivityInfo.exported = true;
@@ -279,18 +282,18 @@
mModel.setCurrentUser(2);
assertEquals(1, mModel.getAppCount());
assertEquals("package0/class0", mModel.getApp(0).getComponentName().flattenToString());
- assertEquals(239L, mModel.getApp(0).getUserSerialNumber());
+ assertEquals(new UserHandle(5), mModel.getApp(0).getUser());
verifyNoMoreInteractions(mMockEdit);
}
/** Tests initializing the model if one of the apps is unlauncheable. */
public void testInitializeWithUnlauncheableApp() {
// Assume two apps are nominally stored.
- when(mMockPrefs.getInt("22|app_count", -1)).thenReturn(2);
- when(mMockPrefs.getString("22|app_0", null)).thenReturn("package0/class0");
- when(mMockPrefs.getLong("22|app_user_0", -1)).thenReturn(239L);
- when(mMockPrefs.getString("22|app_1", null)).thenReturn("package1/class1");
- when(mMockPrefs.getLong("22|app_user_1", -1)).thenReturn(45L);
+ when(mMockPrefs.getInt("222|app_count", -1)).thenReturn(2);
+ when(mMockPrefs.getString("222|app_0", null)).thenReturn("package0/class0");
+ when(mMockPrefs.getLong("222|app_user_0", -1)).thenReturn(555L);
+ when(mMockPrefs.getString("222|app_1", null)).thenReturn("package1/class1");
+ when(mMockPrefs.getLong("222|app_user_1", -1)).thenReturn(444L);
ActivityInfo mockActivityInfo = new ActivityInfo();
mockActivityInfo.exported = true;
@@ -314,13 +317,13 @@
mModel.setCurrentUser(2);
assertEquals(1, mModel.getAppCount());
assertEquals("package0/class0", mModel.getApp(0).getComponentName().flattenToString());
- assertEquals(239L, mModel.getApp(0).getUserSerialNumber());
+ assertEquals(new UserHandle(5), mModel.getApp(0).getUser());
// Once an unlauncheable app is detected, the model should save all apps excluding the
// unlauncheable one.
- verify(mMockEdit).putInt("22|app_count", 1);
- verify(mMockEdit).putString("22|app_0", "package0/class0");
- verify(mMockEdit).putLong("22|app_user_0", 239L);
+ verify(mMockEdit).putInt("222|app_count", 1);
+ verify(mMockEdit).putString("222|app_0", "package0/class0");
+ verify(mMockEdit).putLong("222|app_user_0", 555L);
verify(mMockEdit).apply();
verifyNoMoreInteractions(mMockEdit);
}
@@ -330,11 +333,11 @@
initializeModelFromPrefs();
mModel.savePrefs();
- verify(mMockEdit).putInt("22|app_count", 2);
- verify(mMockEdit).putString("22|app_0", "package1/class1");
- verify(mMockEdit).putLong("22|app_user_0", 45L);
- verify(mMockEdit).putString("22|app_1", "package2/class2");
- verify(mMockEdit).putLong("22|app_user_1", 239L);
+ verify(mMockEdit).putInt("222|app_count", 2);
+ verify(mMockEdit).putString("222|app_0", "package1/class1");
+ verify(mMockEdit).putLong("222|app_user_0", 444L);
+ verify(mMockEdit).putString("222|app_1", "package2/class2");
+ verify(mMockEdit).putLong("222|app_user_1", 555L);
verify(mMockEdit).apply();
verifyNoMoreInteractions(mMockEdit);
}
@@ -367,7 +370,7 @@
// Assume the user's app count pref isn't available. This will trigger clearing deleted
// users' prefs.
- when(mMockPrefs.getInt("22|app_count", -1)).thenReturn(-1);
+ when(mMockPrefs.getInt("222|app_count", -1)).thenReturn(-1);
final Map allPrefs = new HashMap<String, Object>();
allPrefs.put("version", null);
diff --git a/services/core/java/com/android/server/InputMethodManagerService.java b/services/core/java/com/android/server/InputMethodManagerService.java
index 0a0ee3f..b418aba 100644
--- a/services/core/java/com/android/server/InputMethodManagerService.java
+++ b/services/core/java/com/android/server/InputMethodManagerService.java
@@ -15,8 +15,6 @@
package com.android.server;
-import android.annotation.NonNull;
-import android.content.pm.PackageManagerInternal;
import com.android.internal.content.PackageMonitor;
import com.android.internal.inputmethod.InputMethodSubtypeSwitchingController;
import com.android.internal.inputmethod.InputMethodSubtypeSwitchingController.ImeSubtypeListItem;
@@ -27,21 +25,21 @@
import com.android.internal.util.FastXmlSerializer;
import com.android.internal.view.IInputContext;
import com.android.internal.view.IInputMethod;
-import com.android.internal.view.IInputSessionCallback;
import com.android.internal.view.IInputMethodClient;
import com.android.internal.view.IInputMethodManager;
import com.android.internal.view.IInputMethodSession;
+import com.android.internal.view.IInputSessionCallback;
import com.android.internal.view.InputBindResult;
import com.android.server.statusbar.StatusBarManagerService;
-import com.android.server.wm.WindowManagerService;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlSerializer;
+import android.annotation.NonNull;
import android.app.ActivityManagerNative;
-import android.app.AppGlobals;
import android.app.AlertDialog;
+import android.app.AppGlobals;
import android.app.AppOpsManager;
import android.app.IUserSwitchObserver;
import android.app.KeyguardManager;
@@ -61,6 +59,7 @@
import android.content.pm.ApplicationInfo;
import android.content.pm.IPackageManager;
import android.content.pm.PackageManager;
+import android.content.pm.PackageManagerInternal;
import android.content.pm.ResolveInfo;
import android.content.pm.ServiceInfo;
import android.content.pm.UserInfo;
@@ -80,8 +79,8 @@
import android.os.IInterface;
import android.os.IRemoteCallback;
import android.os.Message;
-import android.os.Process;
import android.os.Parcel;
+import android.os.Process;
import android.os.RemoteException;
import android.os.ResultReceiver;
import android.os.ServiceManager;
@@ -90,7 +89,6 @@
import android.os.UserManager;
import android.provider.Settings;
import android.text.TextUtils;
-import android.text.TextUtils.SimpleStringSplitter;
import android.text.style.SuggestionSpan;
import android.util.ArrayMap;
import android.util.ArraySet;
@@ -109,6 +107,7 @@
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
+import android.view.WindowManagerInternal;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputBinding;
import android.view.inputmethod.InputMethod;
@@ -182,11 +181,11 @@
final InputMethodSettings mSettings;
final SettingsObserver mSettingsObserver;
final IWindowManager mIWindowManager;
+ final WindowManagerInternal mWindowManagerInternal;
final HandlerCaller mCaller;
final boolean mHasFeature;
private InputMethodFileManager mFileManager;
private final HardKeyboardListener mHardKeyboardListener;
- private final WindowManagerService mWindowManagerService;
private final AppOpsManager mAppOpsManager;
final InputBindResult mNoBinding = new InputBindResult(null, null, null, -1, -1);
@@ -710,7 +709,7 @@
}
private class HardKeyboardListener
- implements WindowManagerService.OnHardKeyboardStatusChangeListener {
+ implements WindowManagerInternal.OnHardKeyboardStatusChangeListener {
@Override
public void onHardKeyboardStatusChange(boolean available) {
mHandler.sendMessage(mHandler.obtainMessage(MSG_HARD_KEYBOARD_SWITCH_CHANGED,
@@ -732,7 +731,7 @@
}
}
- public InputMethodManagerService(Context context, WindowManagerService windowManager) {
+ public InputMethodManagerService(Context context) {
mIPackageManager = AppGlobals.getPackageManager();
mContext = context;
mRes = context.getResources();
@@ -741,13 +740,13 @@
mSettingsObserver = new SettingsObserver(mHandler);
mIWindowManager = IWindowManager.Stub.asInterface(
ServiceManager.getService(Context.WINDOW_SERVICE));
+ mWindowManagerInternal = LocalServices.getService(WindowManagerInternal.class);
mCaller = new HandlerCaller(context, null, new HandlerCaller.Callback() {
@Override
public void executeMessage(Message msg) {
handleMessage(msg);
}
}, true /*asyncHandler*/);
- mWindowManagerService = windowManager;
mAppOpsManager = (AppOpsManager) mContext.getSystemService(Context.APP_OPS_SERVICE);
mHardKeyboardListener = new HardKeyboardListener();
mHasFeature = context.getPackageManager().hasSystemFeature(
@@ -1045,7 +1044,7 @@
mShowOngoingImeSwitcherForPhones = mRes.getBoolean(
com.android.internal.R.bool.show_ongoing_ime_switcher);
if (mShowOngoingImeSwitcherForPhones) {
- mWindowManagerService.setOnHardKeyboardStatusChangeListener(
+ mWindowManagerInternal.setOnHardKeyboardStatusChangeListener(
mHardKeyboardListener);
}
buildInputMethodListLocked(mMethodList, mMethodMap,
@@ -1507,7 +1506,7 @@
if (DEBUG) Slog.v(TAG, "Removing window token: " + mCurToken);
if ((mImeWindowVis & InputMethodService.IME_ACTIVE) != 0 && savePosition) {
// The current IME is shown. Hence an IME switch (transition) is happening.
- mWindowManagerService.saveLastInputMethodWindowForTransition();
+ mWindowManagerInternal.saveLastInputMethodWindowForTransition();
}
mIWindowManager.removeWindowToken(mCurToken);
} catch (RemoteException e) {
@@ -1641,7 +1640,7 @@
if (mSwitchingDialog != null) return false;
if (isScreenLocked()) return false;
if ((visibility & InputMethodService.IME_ACTIVE) == 0) return false;
- if (mWindowManagerService.isHardKeyboardAvailable()) {
+ if (mWindowManagerInternal.isHardKeyboardAvailable()) {
// When physical keyboard is attached, we show the ime switcher (or notification if
// NavBar is not available) because SHOW_IME_WITH_HARD_KEYBOARD settings currently
// exists in the IME switcher dialog. Might be OK to remove this condition once
@@ -1753,15 +1752,18 @@
mImeSwitcherNotification.setContentTitle(title)
.setContentText(summary)
.setContentIntent(mImeSwitchPendingIntent);
- if ((mNotificationManager != null)
- && !mWindowManagerService.hasNavigationBar()) {
- if (DEBUG) {
- Slog.d(TAG, "--- show notification: label = " + summary);
+ try {
+ if ((mNotificationManager != null)
+ && !mIWindowManager.hasNavigationBar()) {
+ if (DEBUG) {
+ Slog.d(TAG, "--- show notification: label = " + summary);
+ }
+ mNotificationManager.notifyAsUser(null,
+ com.android.internal.R.string.select_input_method,
+ mImeSwitcherNotification.build(), UserHandle.ALL);
+ mNotificationShown = true;
}
- mNotificationManager.notifyAsUser(null,
- com.android.internal.R.string.select_input_method,
- mImeSwitcherNotification.build(), UserHandle.ALL);
- mNotificationShown = true;
+ } catch (RemoteException e) {
}
} else {
if (mNotificationShown && mNotificationManager != null) {
@@ -2527,7 +2529,7 @@
@Override
public int getInputMethodWindowVisibleHeight() {
- return mWindowManagerService.getInputMethodWindowVisibleHeight();
+ return mWindowManagerInternal.getInputMethodWindowVisibleHeight();
}
@Override
@@ -3041,7 +3043,7 @@
mSwitchingDialogTitleView = tv;
mSwitchingDialogTitleView
.findViewById(com.android.internal.R.id.hard_keyboard_section)
- .setVisibility(mWindowManagerService.isHardKeyboardAvailable()
+ .setVisibility(mWindowManagerInternal.isHardKeyboardAvailable()
? View.VISIBLE : View.GONE);
final Switch hardKeySwitch = (Switch) mSwitchingDialogTitleView.findViewById(
com.android.internal.R.id.hard_keyboard_switch);
diff --git a/services/core/java/com/android/server/LockSettingsService.java b/services/core/java/com/android/server/LockSettingsService.java
index 7e4bcdc..c7e0c98 100644
--- a/services/core/java/com/android/server/LockSettingsService.java
+++ b/services/core/java/com/android/server/LockSettingsService.java
@@ -29,6 +29,8 @@
import static android.Manifest.permission.ACCESS_KEYGUARD_SECURE_STORAGE;
import static android.content.Context.USER_SERVICE;
import static android.Manifest.permission.READ_CONTACTS;
+import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_LOCKOUT;
+
import android.database.sqlite.SQLiteDatabase;
import android.os.Binder;
import android.os.IBinder;
@@ -664,6 +666,10 @@
if (shouldReEnroll) {
credentialUtil.setCredential(credential, credential, userId);
}
+ } else if (response.getResponseCode() == VerifyCredentialResponse.RESPONSE_RETRY) {
+ if (response.getTimeout() > 0) {
+ requireStrongAuth(STRONG_AUTH_REQUIRED_AFTER_LOCKOUT, userId);
+ }
}
return response;
diff --git a/services/core/java/com/android/server/MountService.java b/services/core/java/com/android/server/MountService.java
index 0d64540..72cece3 100644
--- a/services/core/java/com/android/server/MountService.java
+++ b/services/core/java/com/android/server/MountService.java
@@ -165,6 +165,8 @@
public void onBootPhase(int phase) {
if (phase == SystemService.PHASE_ACTIVITY_MANAGER_READY) {
mMountService.systemReady();
+ } else if (phase == SystemService.PHASE_BOOT_COMPLETED) {
+ mMountService.bootCompleted();
}
}
@@ -405,6 +407,7 @@
private final NativeDaemonConnector mCryptConnector;
private volatile boolean mSystemReady = false;
+ private volatile boolean mBootCompleted = false;
private volatile boolean mDaemonConnected = false;
private PackageManagerService mPms;
@@ -1244,7 +1247,9 @@
mCallbacks.notifyVolumeStateChanged(vol, oldState, newState);
- if (isBroadcastWorthy(vol)) {
+ // Do not broadcast before boot has completed to avoid launching the
+ // processes that receive the intent unnecessarily.
+ if (mBootCompleted && isBroadcastWorthy(vol)) {
final Intent intent = new Intent(VolumeInfo.ACTION_VOLUME_STATE_CHANGED);
intent.putExtra(VolumeInfo.EXTRA_VOLUME_ID, vol.id);
intent.putExtra(VolumeInfo.EXTRA_VOLUME_STATE, newState);
@@ -1429,6 +1434,10 @@
mHandler.obtainMessage(H_SYSTEM_READY).sendToTarget();
}
+ private void bootCompleted() {
+ mBootCompleted = true;
+ }
+
private String getDefaultPrimaryStorageUuid() {
if (SystemProperties.getBoolean(StorageManager.PROP_PRIMARY_PHYSICAL, false)) {
return StorageManager.UUID_PRIMARY_PHYSICAL;
diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java
index fcd596f..965f5b6 100644
--- a/services/core/java/com/android/server/am/ActivityStack.java
+++ b/services/core/java/com/android/server/am/ActivityStack.java
@@ -4543,7 +4543,7 @@
TaskRecord task = new TaskRecord(mService, taskId, info, intent, voiceSession,
voiceInteractor);
if (mTaskPositioner != null) {
- mTaskPositioner.updateDefaultBounds(task, mTaskHistory);
+ mTaskPositioner.updateDefaultBounds(task, mTaskHistory, info.initialLayout);
}
addTask(task, toTop, false);
return task;
diff --git a/services/core/java/com/android/server/am/BatteryStatsService.java b/services/core/java/com/android/server/am/BatteryStatsService.java
index 9bf4f5f..335288d 100644
--- a/services/core/java/com/android/server/am/BatteryStatsService.java
+++ b/services/core/java/com/android/server/am/BatteryStatsService.java
@@ -1263,8 +1263,8 @@
Slog.v(TAG, "WiFi energy data was reset, new WiFi energy data is " + result);
}
- // There is some accuracy error in reports so allow 30 milliseconds of error.
- final long SAMPLE_ERROR_MILLIS = 30;
+ // There is some accuracy error in reports so allow some slop in the results.
+ final long SAMPLE_ERROR_MILLIS = 750;
final long totalTimeMs = result.mControllerIdleTimeMs + result.mControllerRxTimeMs +
result.mControllerTxTimeMs;
if (totalTimeMs > timePeriodMs + SAMPLE_ERROR_MILLIS) {
diff --git a/services/core/java/com/android/server/am/LaunchingTaskPositioner.java b/services/core/java/com/android/server/am/LaunchingTaskPositioner.java
index 3005c86..5c4fd13 100644
--- a/services/core/java/com/android/server/am/LaunchingTaskPositioner.java
+++ b/services/core/java/com/android/server/am/LaunchingTaskPositioner.java
@@ -16,16 +16,30 @@
package com.android.server.am;
+import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
+import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
+
+import android.annotation.Nullable;
+import android.content.pm.ActivityInfo;
import android.graphics.Point;
import android.graphics.Rect;
+import android.util.Slog;
import android.view.Display;
+import android.view.Gravity;
import java.util.ArrayList;
/**
* Determines where a launching task should be positioned and sized on the display.
+ *
+ * The positioner is fairly simple. For the new task it tries default position based on the gravity
+ * and compares corners of the task with corners of existing tasks. If some two pairs of corners are
+ * sufficiently close enough, it shifts the bounds of the new task and tries again. When it exhausts
+ * all possible shifts, it gives up and puts the task in the original position.
*/
class LaunchingTaskPositioner {
+ private static final String TAG = TAG_WITH_CLASS_NAME ? "LaunchingTaskPositioner" : TAG_AM;
+
// Determines how close window frames/corners have to be to call them colliding.
private static final int BOUNDS_CONFLICT_MIN_DISTANCE = 4;
@@ -42,8 +56,19 @@
// We always want to step by at least this.
private static final int MINIMAL_STEP = 1;
+ // Used to indicate if positioning algorithm is allowed to restart from the beginning, when it
+ // reaches the end of stack bounds.
+ private static final boolean ALLOW_RESTART = true;
+
+ private static final int SHIFT_POLICY_DIAGONAL_DOWN = 1;
+ private static final int SHIFT_POLICY_HORIZONTAL_RIGHT = 2;
+ private static final int SHIFT_POLICY_HORIZONTAL_LEFT = 3;
+
private boolean mDefaultStartBoundsConfigurationSet = false;
private final Rect mAvailableRect = new Rect();
+ private final Rect mTmpProposal = new Rect();
+ private final Rect mTmpOriginal = new Rect();
+
private int mDefaultFreeformStartX;
private int mDefaultFreeformStartY;
private int mDefaultFreeformWidth;
@@ -84,51 +109,167 @@
*
* @param task Task for which we want to find bounds that won't collide with other.
* @param tasks Existing tasks with which we don't want to collide.
+ * @param initialLayout Optional information from the client about how it would like to be sized
+ * and positioned.
*/
- void updateDefaultBounds(TaskRecord task, ArrayList<TaskRecord> tasks) {
+ void updateDefaultBounds(TaskRecord task, ArrayList<TaskRecord> tasks,
+ @Nullable ActivityInfo.InitialLayout initialLayout) {
if (!mDefaultStartBoundsConfigurationSet) {
return;
}
- int startX = mDefaultFreeformStartX;
- int startY = mDefaultFreeformStartY;
- final int right = mAvailableRect.right;
- final int bottom = mAvailableRect.bottom;
+ if (initialLayout == null) {
+ positionCenter(task, tasks, mDefaultFreeformWidth, mDefaultFreeformHeight);
+ return;
+ }
+ int width = getFinalWidth(initialLayout);
+ int height = getFinalHeight(initialLayout);
+ int verticalGravity = initialLayout.gravity & Gravity.VERTICAL_GRAVITY_MASK;
+ int horizontalGravity = initialLayout.gravity & Gravity.HORIZONTAL_GRAVITY_MASK;
+ if (verticalGravity == Gravity.TOP) {
+ if (horizontalGravity == Gravity.RIGHT) {
+ positionTopRight(task, tasks, width, height);
+ } else {
+ positionTopLeft(task, tasks, width, height);
+ }
+ } else if (verticalGravity == Gravity.BOTTOM) {
+ if (horizontalGravity == Gravity.RIGHT) {
+ positionBottomRight(task, tasks, width, height);
+ } else {
+ positionBottomLeft(task, tasks, width, height);
+ }
+ } else {
+ // Some fancy gravity setting that we don't support yet. We just put the activity in the
+ // center.
+ Slog.w(TAG, "Received unsupported gravity: " + initialLayout.gravity
+ + ", positioning in the center instead.");
+ positionCenter(task, tasks, width, height);
+ }
+ }
+
+ private int getFinalWidth(ActivityInfo.InitialLayout initialLayout) {
+ int width = mDefaultFreeformWidth;
+ if (initialLayout.width > 0) {
+ width = initialLayout.width;
+ }
+ if (initialLayout.widthFraction > 0) {
+ width = (int) (mAvailableRect.width() * initialLayout.widthFraction);
+ }
+ return width;
+ }
+
+ private int getFinalHeight(ActivityInfo.InitialLayout initialLayout) {
+ int height = mDefaultFreeformHeight;
+ if (initialLayout.height > 0) {
+ height = initialLayout.height;
+ }
+ if (initialLayout.heightFraction > 0) {
+ height = (int) (mAvailableRect.height() * initialLayout.heightFraction);
+ }
+ return height;
+ }
+
+ private void positionBottomLeft(TaskRecord task, ArrayList<TaskRecord> tasks, int width,
+ int height) {
+ mTmpProposal.set(mAvailableRect.left, mAvailableRect.bottom - height,
+ mAvailableRect.left + width, mAvailableRect.bottom);
+ position(task, tasks, mTmpProposal, !ALLOW_RESTART, SHIFT_POLICY_HORIZONTAL_RIGHT);
+ }
+
+ private void positionBottomRight(TaskRecord task, ArrayList<TaskRecord> tasks, int width,
+ int height) {
+ mTmpProposal.set(mAvailableRect.right - width, mAvailableRect.bottom - height,
+ mAvailableRect.right, mAvailableRect.bottom);
+ position(task, tasks, mTmpProposal, !ALLOW_RESTART, SHIFT_POLICY_HORIZONTAL_LEFT);
+ }
+
+ private void positionTopLeft(TaskRecord task, ArrayList<TaskRecord> tasks, int width,
+ int height) {
+ mTmpProposal.set(mAvailableRect.left, mAvailableRect.top,
+ mAvailableRect.left + width, mAvailableRect.top + height);
+ position(task, tasks, mTmpProposal, !ALLOW_RESTART, SHIFT_POLICY_HORIZONTAL_RIGHT);
+ }
+
+ private void positionTopRight(TaskRecord task, ArrayList<TaskRecord> tasks, int width,
+ int height) {
+ mTmpProposal.set(mAvailableRect.right - width, mAvailableRect.top,
+ mAvailableRect.right, mAvailableRect.top + height);
+ position(task, tasks, mTmpProposal, !ALLOW_RESTART, SHIFT_POLICY_HORIZONTAL_LEFT);
+ }
+
+ private void positionCenter(TaskRecord task, ArrayList<TaskRecord> tasks, int width,
+ int height) {
+ mTmpProposal.set(mDefaultFreeformStartX, mDefaultFreeformStartY,
+ mDefaultFreeformStartX + width, mDefaultFreeformStartY + height);
+ position(task, tasks, mTmpProposal, ALLOW_RESTART, SHIFT_POLICY_DIAGONAL_DOWN);
+ }
+
+ private void position(TaskRecord task, ArrayList<TaskRecord> tasks, Rect proposal,
+ boolean allowRestart, int shiftPolicy) {
+ mTmpOriginal.set(proposal);
boolean restarted = false;
- while (boundsConflict(startX, startY, tasks)) {
+ while (boundsConflict(proposal, tasks)) {
// Unfortunately there is already a task at that spot, so we need to look for some
// other place.
- startX += mDefaultFreeformStepHorizontal;
- startY += mDefaultFreeformStepVertical;
- if (startX + mDefaultFreeformWidth > right
- || startY + mDefaultFreeformHeight > bottom) {
- // We don't want the task to go outside of the display, because it won't look
- // nice. Let's restart from the top instead, because there should be some space
- // there.
- startX = mAvailableRect.left;
- startY = mAvailableRect.top;
+ shiftStartingPoint(proposal, shiftPolicy);
+ if (shiftedToFar(proposal, shiftPolicy)) {
+ // We don't want the task to go outside of the stack, because it won't look
+ // nice. Depending on the starting point we either restart, or immediately give up.
+ if (!allowRestart) {
+ proposal.set(mTmpOriginal);
+ break;
+ }
+ // We must have started not from the top. Let's restart from there because there
+ // might be some space there.
+ proposal.set(mAvailableRect.left, mAvailableRect.top,
+ mAvailableRect.left + proposal.width(),
+ mAvailableRect.top + proposal.height());
restarted = true;
}
- if (restarted
- && (startX > mDefaultFreeformStartX || startY > mDefaultFreeformStartY)) {
+ if (restarted && (proposal.left > mDefaultFreeformStartX
+ || proposal.top > mDefaultFreeformStartY)) {
// If we restarted and crossed the initial position, let's not struggle anymore.
// The user already must have ton of tasks visible, we can just smack the new
// one in the center.
- startX = mDefaultFreeformStartX;
- startY = mDefaultFreeformStartY;
+ proposal.set(mTmpOriginal);
break;
}
}
- task.setInitialBounds(startX, startY, startX + mDefaultFreeformWidth,
- startY + mDefaultFreeformHeight);
+ task.setInitialBounds(proposal);
}
- private boolean boundsConflict(int startX, int startY, ArrayList<TaskRecord> tasks) {
+ private boolean shiftedToFar(Rect start, int shiftPolicy) {
+ switch (shiftPolicy) {
+ case SHIFT_POLICY_HORIZONTAL_LEFT:
+ return start.left < mAvailableRect.left;
+ case SHIFT_POLICY_HORIZONTAL_RIGHT:
+ return start.right > mAvailableRect.right;
+ default: // SHIFT_POLICY_DIAGONAL_DOWN
+ return start.right > mAvailableRect.right || start.bottom > mAvailableRect.bottom;
+ }
+ }
+
+ private void shiftStartingPoint(Rect posposal, int shiftPolicy) {
+ switch (shiftPolicy) {
+ case SHIFT_POLICY_HORIZONTAL_LEFT:
+ posposal.offset(-mDefaultFreeformStepHorizontal, 0);
+ break;
+ case SHIFT_POLICY_HORIZONTAL_RIGHT:
+ posposal.offset(mDefaultFreeformStepHorizontal, 0);
+ break;
+ default: // SHIFT_POLICY_DIAGONAL_DOWN:
+ posposal.offset(mDefaultFreeformStepHorizontal, mDefaultFreeformStepVertical);
+ break;
+ }
+ }
+
+ private static boolean boundsConflict(Rect proposal, ArrayList<TaskRecord> tasks) {
for (int i = tasks.size() - 1; i >= 0; i--) {
TaskRecord task = tasks.get(i);
- if (!task.mActivities.isEmpty()) {
+ if (!task.mActivities.isEmpty() && task.mBounds != null) {
Rect bounds = task.mBounds;
- if (bounds != null && (Math.abs(bounds.left - startX) < BOUNDS_CONFLICT_MIN_DISTANCE
- || Math.abs(bounds.top - startY) < BOUNDS_CONFLICT_MIN_DISTANCE)) {
+ if (closeLeftTopCorner(proposal, bounds) || closeRightTopCorner(proposal, bounds)
+ || closeLeftBottomCorner(proposal, bounds)
+ || closeRightBottomCorner(proposal, bounds)) {
return true;
}
}
@@ -136,6 +277,26 @@
return false;
}
+ private static final boolean closeLeftTopCorner(Rect first, Rect second) {
+ return Math.abs(first.left - second.left) < BOUNDS_CONFLICT_MIN_DISTANCE
+ && Math.abs(first.top - second.top) < BOUNDS_CONFLICT_MIN_DISTANCE;
+ }
+
+ private static final boolean closeRightTopCorner(Rect first, Rect second) {
+ return Math.abs(first.right - second.right) < BOUNDS_CONFLICT_MIN_DISTANCE
+ && Math.abs(first.top - second.top) < BOUNDS_CONFLICT_MIN_DISTANCE;
+ }
+
+ private static final boolean closeLeftBottomCorner(Rect first, Rect second) {
+ return Math.abs(first.left - second.left) < BOUNDS_CONFLICT_MIN_DISTANCE
+ && Math.abs(first.bottom - second.bottom) < BOUNDS_CONFLICT_MIN_DISTANCE;
+ }
+
+ private static final boolean closeRightBottomCorner(Rect first, Rect second) {
+ return Math.abs(first.right - second.right) < BOUNDS_CONFLICT_MIN_DISTANCE
+ && Math.abs(first.bottom - second.bottom) < BOUNDS_CONFLICT_MIN_DISTANCE;
+ }
+
void reset() {
mDefaultStartBoundsConfigurationSet = false;
}
diff --git a/services/core/java/com/android/server/am/TaskRecord.java b/services/core/java/com/android/server/am/TaskRecord.java
index ff412d1..712b8cc 100644
--- a/services/core/java/com/android/server/am/TaskRecord.java
+++ b/services/core/java/com/android/server/am/TaskRecord.java
@@ -1217,11 +1217,11 @@
return mLastNonFullscreenBounds;
}
- void setInitialBounds(int left, int top, int right, int bottom) {
+ void setInitialBounds(Rect rect) {
if (mBounds == null) {
mBounds = new Rect();
}
- mBounds.set(left, top, right, bottom);
+ mBounds.set(rect);
mLastNonFullscreenBounds = mBounds;
}
diff --git a/services/core/java/com/android/server/camera/CameraService.java b/services/core/java/com/android/server/camera/CameraService.java
index 0be24f4..f82454a 100644
--- a/services/core/java/com/android/server/camera/CameraService.java
+++ b/services/core/java/com/android/server/camera/CameraService.java
@@ -23,13 +23,17 @@
import android.content.pm.UserInfo;
import android.hardware.ICameraService;
import android.hardware.ICameraServiceProxy;
+import android.nfc.INfcAdapter;
import android.os.Handler;
import android.os.IBinder;
+import android.os.Binder;
import android.os.Message;
import android.os.Process;
import android.os.RemoteException;
import android.os.UserManager;
+import android.os.SystemProperties;
import android.util.Slog;
+import android.util.ArraySet;
import com.android.server.ServiceThread;
import com.android.server.SystemService;
@@ -44,8 +48,10 @@
*
* @hide
*/
-public class CameraService extends SystemService implements Handler.Callback {
+public class CameraService extends SystemService
+ implements Handler.Callback, IBinder.DeathRecipient {
private static final String TAG = "CameraService_proxy";
+ private static final boolean DEBUG = false;
/**
* This must match the ICameraService.aidl definition
@@ -58,6 +64,16 @@
public static final int NO_EVENT = 0; // NOOP
public static final int USER_SWITCHED = 1; // User changed, argument is the new user handle
+ // State arguments to use with the notifyCameraState call from camera service:
+ public static final int CAMERA_STATE_OPEN = 0;
+ public static final int CAMERA_STATE_ACTIVE = 1;
+ public static final int CAMERA_STATE_IDLE = 2;
+ public static final int CAMERA_STATE_CLOSED = 3;
+
+ // Flags arguments to NFC adapter to enable/disable NFC
+ public static final int DISABLE_POLLING_FLAGS = 0x1000;
+ public static final int ENABLE_POLLING_FLAGS = 0x0000;
+
// Handler message codes
private static final int MSG_SWITCH_USER = 1;
@@ -72,6 +88,17 @@
private Set<Integer> mEnabledCameraUsers;
private int mLastUser;
+ private ICameraService mCameraServiceRaw;
+
+ private final ArraySet<String> mActiveCameraIds = new ArraySet<>();
+
+ private static final String NFC_NOTIFICATION_PROP = "ro.camera.notify_nfc";
+ private static final String NFC_SERVICE_BINDER_NAME = "nfc";
+ private static final IBinder nfcInterfaceToken = new Binder();
+
+ private final boolean mNotifyNfc;
+ private int mActiveCameraCount = 0;
+
private final BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
@@ -102,6 +129,14 @@
public void pingForUserUpdate() {
notifySwitchWithRetries(30);
}
+
+ @Override
+ public void notifyCameraState(String cameraId, int newCameraState) {
+ String state = cameraStateToString(newCameraState);
+ if (DEBUG) Slog.v(TAG, "Camera " + cameraId + " state now " + state);
+
+ updateActivityCount(cameraId, newCameraState);
+ }
};
public CameraService(Context context) {
@@ -110,6 +145,9 @@
mHandlerThread = new ServiceThread(TAG, Process.THREAD_PRIORITY_DISPLAY, /*allowTo*/false);
mHandlerThread.start();
mHandler = new Handler(mHandlerThread.getLooper(), this);
+
+ mNotifyNfc = SystemProperties.getInt(NFC_NOTIFICATION_PROP, 0) > 0;
+ if (DEBUG) Slog.v(TAG, "Notify NFC behavior is " + (mNotifyNfc ? "active" : "disabled"));
}
@Override
@@ -161,13 +199,32 @@
}
}
+ /**
+ * Handle the death of the native camera service
+ */
+ @Override
+ public void binderDied() {
+ if (DEBUG) Slog.w(TAG, "Native camera service has died");
+ synchronized(mLock) {
+ mCameraServiceRaw = null;
+
+ // All cameras reset to idle on camera service death
+ boolean wasEmpty = mActiveCameraIds.isEmpty();
+ mActiveCameraIds.clear();
+
+ if ( mNotifyNfc && !wasEmpty ) {
+ notifyNfcService(/*enablePolling*/ true);
+ }
+ }
+ }
+
private void switchUserLocked(int userHandle) {
Set<Integer> currentUserHandles = getEnabledUserHandles(userHandle);
mLastUser = userHandle;
if (mEnabledCameraUsers == null || !mEnabledCameraUsers.equals(currentUserHandles)) {
// Some user handles have been added or removed, update mediaserver.
mEnabledCameraUsers = currentUserHandles;
- notifyMediaserver(USER_SWITCHED, currentUserHandles);
+ notifyMediaserverLocked(USER_SWITCHED, currentUserHandles);
}
}
@@ -187,7 +244,7 @@
if (mEnabledCameraUsers == null) {
return;
}
- if (notifyMediaserver(USER_SWITCHED, mEnabledCameraUsers)) {
+ if (notifyMediaserverLocked(USER_SWITCHED, mEnabledCameraUsers)) {
retries = 0;
}
}
@@ -199,19 +256,27 @@
RETRY_DELAY_TIME);
}
- private boolean notifyMediaserver(int eventType, Set<Integer> updatedUserHandles) {
+ private boolean notifyMediaserverLocked(int eventType, Set<Integer> updatedUserHandles) {
// Forward the user switch event to the native camera service running in the mediaserver
// process.
- IBinder cameraServiceBinder = getBinderService(CAMERA_SERVICE_BINDER_NAME);
- if (cameraServiceBinder == null) {
- Slog.w(TAG, "Could not notify mediaserver, camera service not available.");
- return false; // Camera service not active, cannot evict user clients.
+ if (mCameraServiceRaw == null) {
+ IBinder cameraServiceBinder = getBinderService(CAMERA_SERVICE_BINDER_NAME);
+ if (cameraServiceBinder == null) {
+ Slog.w(TAG, "Could not notify mediaserver, camera service not available.");
+ return false; // Camera service not active, cannot evict user clients.
+ }
+ try {
+ cameraServiceBinder.linkToDeath(this, /*flags*/ 0);
+ } catch (RemoteException e) {
+ Slog.w(TAG, "Could not link to death of native camera service");
+ return false;
+ }
+
+ mCameraServiceRaw = ICameraService.Stub.asInterface(cameraServiceBinder);
}
- ICameraService cameraServiceRaw = ICameraService.Stub.asInterface(cameraServiceBinder);
-
try {
- cameraServiceRaw.notifySystemEvent(eventType, toArray(updatedUserHandles));
+ mCameraServiceRaw.notifySystemEvent(eventType, toArray(updatedUserHandles));
} catch (RemoteException e) {
Slog.w(TAG, "Could not notify mediaserver, remote exception: " + e);
// Not much we can do if camera service is dead.
@@ -220,6 +285,44 @@
return true;
}
+ private void updateActivityCount(String cameraId, int newCameraState) {
+ synchronized(mLock) {
+ boolean wasEmpty = mActiveCameraIds.isEmpty();
+ switch (newCameraState) {
+ case CAMERA_STATE_OPEN:
+ break;
+ case CAMERA_STATE_ACTIVE:
+ mActiveCameraIds.add(cameraId);
+ break;
+ case CAMERA_STATE_IDLE:
+ case CAMERA_STATE_CLOSED:
+ mActiveCameraIds.remove(cameraId);
+ break;
+ }
+ boolean isEmpty = mActiveCameraIds.isEmpty();
+ if ( mNotifyNfc && (wasEmpty != isEmpty) ) {
+ notifyNfcService(isEmpty);
+ }
+ }
+ }
+
+ private void notifyNfcService(boolean enablePolling) {
+
+ IBinder nfcServiceBinder = getBinderService(NFC_SERVICE_BINDER_NAME);
+ if (nfcServiceBinder == null) {
+ Slog.w(TAG, "Could not connect to NFC service to notify it of camera state");
+ return;
+ }
+ INfcAdapter nfcAdapterRaw = INfcAdapter.Stub.asInterface(nfcServiceBinder);
+ int flags = enablePolling ? ENABLE_POLLING_FLAGS : DISABLE_POLLING_FLAGS;
+ if (DEBUG) Slog.v(TAG, "Setting NFC reader mode to flags " + flags);
+ try {
+ nfcAdapterRaw.setReaderMode(nfcInterfaceToken, null, flags, null);
+ } catch (RemoteException e) {
+ Slog.w(TAG, "Could not notify NFC service, remote exception: " + e);
+ }
+ }
+
private static int[] toArray(Collection<Integer> c) {
int len = c.size();
int[] ret = new int[len];
@@ -229,4 +332,15 @@
}
return ret;
}
+
+ private static String cameraStateToString(int newCameraState) {
+ switch (newCameraState) {
+ case CAMERA_STATE_OPEN: return "CAMERA_STATE_OPEN";
+ case CAMERA_STATE_ACTIVE: return "CAMERA_STATE_ACTIVE";
+ case CAMERA_STATE_IDLE: return "CAMERA_STATE_IDLE";
+ case CAMERA_STATE_CLOSED: return "CAMERA_STATE_CLOSED";
+ default: break;
+ }
+ return "CAMERA_STATE_UNKNOWN";
+ }
}
diff --git a/services/core/java/com/android/server/connectivity/Vpn.java b/services/core/java/com/android/server/connectivity/Vpn.java
index 2846185..3df3cd0 100644
--- a/services/core/java/com/android/server/connectivity/Vpn.java
+++ b/services/core/java/com/android/server/connectivity/Vpn.java
@@ -146,7 +146,8 @@
} catch (RemoteException e) {
Log.wtf(TAG, "Problem registering observer", e);
}
- if (userHandle == UserHandle.USER_OWNER) {
+ // TODO: http://b/22950929
+ if (userHandle == UserHandle.USER_SYSTEM) {
// Owner's VPN also needs to handle restricted users
mUserIntentReceiver = new BroadcastReceiver() {
@Override
diff --git a/services/core/java/com/android/server/fingerprint/FingerprintService.java b/services/core/java/com/android/server/fingerprint/FingerprintService.java
index befa311..470bd5a 100644
--- a/services/core/java/com/android/server/fingerprint/FingerprintService.java
+++ b/services/core/java/com/android/server/fingerprint/FingerprintService.java
@@ -298,6 +298,7 @@
final int result = daemon.enroll(cryptoToken, groupId, timeout);
if (result != 0) {
Slog.w(TAG, "startEnroll failed, result=" + result);
+ dispatchError(mHalDeviceId, FingerprintManager.FINGERPRINT_ERROR_HW_UNAVAILABLE);
}
} catch (RemoteException e) {
Slog.e(TAG, "startEnroll failed", e);
@@ -391,6 +392,7 @@
final int result = daemon.authenticate(opId, groupId);
if (result != 0) {
Slog.w(TAG, "startAuthentication failed, result=" + result);
+ dispatchError(mHalDeviceId, FingerprintManager.FINGERPRINT_ERROR_HW_UNAVAILABLE);
}
} catch (RemoteException e) {
Slog.e(TAG, "startAuthentication failed", e);
@@ -433,12 +435,14 @@
return;
}
+ stopPendingOperations(true);
mRemoveClient = new ClientMonitor(token, receiver, userId, restricted);
// The fingerprint template ids will be removed when we get confirmation from the HAL
try {
final int result = daemon.remove(fingerId, userId);
if (result != 0) {
Slog.w(TAG, "startRemove with id = " + fingerId + " failed, result=" + result);
+ dispatchError(mHalDeviceId, FingerprintManager.FINGERPRINT_ERROR_HW_UNAVAILABLE);
}
} catch (RemoteException e) {
Slog.e(TAG, "startRemove failed", e);
@@ -764,6 +768,7 @@
mHandler.post(new Runnable() {
@Override
public void run() {
+ MetricsLogger.histogram(mContext, "fingerprint_token", opId != 0L ? 1 : 0);
startAuthentication(token, opId, effectiveGroupId, receiver, flags, restricted);
}
});
diff --git a/services/core/java/com/android/server/location/GpsLocationProvider.java b/services/core/java/com/android/server/location/GpsLocationProvider.java
index 57ca552..5c60a61 100644
--- a/services/core/java/com/android/server/location/GpsLocationProvider.java
+++ b/services/core/java/com/android/server/location/GpsLocationProvider.java
@@ -2200,14 +2200,18 @@
@Override
public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
StringBuilder s = new StringBuilder();
- s.append(" mFixInterval=").append(mFixInterval).append("\n");
- s.append(" mDisableGps (battery saver mode)=").append(mDisableGps).append("\n");
- s.append(" mEngineCapabilities=0x").append(Integer.toHexString(mEngineCapabilities)).append(" (");
- if (hasCapability(GPS_CAPABILITY_SCHEDULING)) s.append("SCHED ");
+ s.append(" mFixInterval=").append(mFixInterval).append('\n');
+ s.append(" mDisableGps (battery saver mode)=").append(mDisableGps).append('\n');
+ s.append(" mEngineCapabilities=0x").append(Integer.toHexString(mEngineCapabilities));
+ s.append(" ( ");
+ if (hasCapability(GPS_CAPABILITY_SCHEDULING)) s.append("SCHEDULING ");
if (hasCapability(GPS_CAPABILITY_MSB)) s.append("MSB ");
if (hasCapability(GPS_CAPABILITY_MSA)) s.append("MSA ");
if (hasCapability(GPS_CAPABILITY_SINGLE_SHOT)) s.append("SINGLE_SHOT ");
if (hasCapability(GPS_CAPABILITY_ON_DEMAND_TIME)) s.append("ON_DEMAND_TIME ");
+ if (hasCapability(GPS_CAPABILITY_GEOFENCING)) s.append("GEOFENCING ");
+ if (hasCapability(GPS_CAPABILITY_MEASUREMENTS)) s.append("MEASUREMENTS ");
+ if (hasCapability(GPS_CAPABILITY_NAV_MESSAGES)) s.append("NAV_MESSAGES ");
s.append(")\n");
s.append(native_get_internal_state());
diff --git a/services/core/java/com/android/server/notification/ZenModeHelper.java b/services/core/java/com/android/server/notification/ZenModeHelper.java
index edd274b..0a12d5a 100644
--- a/services/core/java/com/android/server/notification/ZenModeHelper.java
+++ b/services/core/java/com/android/server/notification/ZenModeHelper.java
@@ -413,8 +413,7 @@
applyRestrictions(muteNotifications, USAGE_NOTIFICATION);
// call restrictions
- final boolean muteCalls = zen && !mConfig.allowCalls && !mConfig.allowRepeatCallers
- || mEffectsSuppressed;
+ final boolean muteCalls = zen && !mConfig.allowCalls && !mConfig.allowRepeatCallers;
applyRestrictions(muteCalls, USAGE_NOTIFICATION_RINGTONE);
// alarm restrictions
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index a559116..f5f494a 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -4644,7 +4644,7 @@
if (result == null) {
result = new CrossProfileDomainInfo();
result.resolveInfo =
- createForwardingResolveInfo(null, sourceUserId, parentUserId);
+ createForwardingResolveInfo(new IntentFilter(), sourceUserId, parentUserId);
result.bestDomainVerificationStatus = status;
} else {
result.bestDomainVerificationStatus = bestDomainVerificationStatus(status,
diff --git a/services/core/java/com/android/server/policy/StatusBarController.java b/services/core/java/com/android/server/policy/StatusBarController.java
index da23f45..b935f5a 100644
--- a/services/core/java/com/android/server/policy/StatusBarController.java
+++ b/services/core/java/com/android/server/policy/StatusBarController.java
@@ -72,7 +72,9 @@
if (statusbar != null) {
long startTime = calculateStatusBarTransitionStartTime(openAnimation,
closeAnimation);
- statusbar.appTransitionStarting(startTime, TRANSITION_DURATION);
+ long duration = closeAnimation != null || openAnimation != null
+ ? TRANSITION_DURATION : 0;
+ statusbar.appTransitionStarting(startTime, duration);
}
} catch (RemoteException e) {
Slog.e(mTag, "RemoteException when app transition is starting", e);
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index a200678..52aaf64 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -552,7 +552,7 @@
boolean mHardKeyboardAvailable;
boolean mShowImeWithHardKeyboard;
- OnHardKeyboardStatusChangeListener mHardKeyboardStatusChangeListener;
+ WindowManagerInternal.OnHardKeyboardStatusChangeListener mHardKeyboardStatusChangeListener;
SettingsObserver mSettingsObserver;
private final class SettingsObserver extends ContentObserver {
@@ -6808,12 +6808,6 @@
mPolicy.adjustConfigurationLw(config, keyboardPresence, navigationPresence);
}
- public boolean isHardKeyboardAvailable() {
- synchronized (mWindowMap) {
- return mHardKeyboardAvailable;
- }
- }
-
public void updateShowImeWithHardKeyboard() {
synchronized (mWindowMap) {
final boolean showImeWithHardKeyboard = Settings.Secure.getIntForUser(
@@ -6826,16 +6820,9 @@
}
}
- public void setOnHardKeyboardStatusChangeListener(
- OnHardKeyboardStatusChangeListener listener) {
- synchronized (mWindowMap) {
- mHardKeyboardStatusChangeListener = listener;
- }
- }
-
void notifyHardKeyboardStatusChange() {
final boolean available;
- final OnHardKeyboardStatusChangeListener listener;
+ final WindowManagerInternal.OnHardKeyboardStatusChangeListener listener;
synchronized (mWindowMap) {
listener = mHardKeyboardStatusChangeListener;
available = mHardKeyboardAvailable;
@@ -9778,8 +9765,8 @@
": removed=" + win.mRemoved + " visible=" + win.isVisibleLw() +
" mHasSurface=" + win.mHasSurface +
" drawState=" + win.mWinAnimator.mDrawState);
- if (win.mRemoved || !win.mHasSurface) {
- // Window has been removed; no draw will now happen, so stop waiting.
+ if (win.mRemoved || !win.mHasSurface || !win.mPolicyVisibility) {
+ // Window has been removed or hidden; no draw will now happen, so stop waiting.
if (DEBUG_SCREEN_ON) Slog.w(TAG, "Aborted waiting for drawn: " + win);
mWaitingForDrawn.remove(win);
} else if (win.hasDrawnLw()) {
@@ -10431,23 +10418,6 @@
}
}
- // It is assumed that this method is called only by InputMethodManagerService.
- public void saveLastInputMethodWindowForTransition() {
- synchronized (mWindowMap) {
- // TODO(multidisplay): Pass in the displayID.
- DisplayContent displayContent = getDefaultDisplayContentLocked();
- if (mInputMethodWindow != null) {
- mPolicy.setLastInputMethodWindowLw(mInputMethodWindow, mInputMethodTarget);
- }
- }
- }
-
- public int getInputMethodWindowVisibleHeight() {
- synchronized (mWindowMap) {
- return mPolicy.getInputMethodWindowVisibleHeightLw();
- }
- }
-
@Override
public boolean hasNavigationBar() {
return mPolicy.hasNavigationBar();
@@ -11037,10 +11007,6 @@
synchronized (mWindowMap) { }
}
- public interface OnHardKeyboardStatusChangeListener {
- public void onHardKeyboardStatusChange(boolean available);
- }
-
void debugLayoutRepeats(final String msg, int pendingLayoutChanges) {
if (mLayoutRepeatCount >= LAYOUT_REPEAT_THRESHOLD) {
Slog.v(TAG, "Layouts looping: " + msg + ", mPendingLayoutChanges = 0x" +
@@ -11348,5 +11314,39 @@
mAppTransition.registerListenerLocked(listener);
}
}
+
+ @Override
+ public int getInputMethodWindowVisibleHeight() {
+ synchronized (mWindowMap) {
+ return mPolicy.getInputMethodWindowVisibleHeightLw();
+ }
+ }
+
+ @Override
+ public void saveLastInputMethodWindowForTransition() {
+ synchronized (mWindowMap) {
+ // TODO(multidisplay): Pass in the displayID.
+ DisplayContent displayContent = getDefaultDisplayContentLocked();
+ if (mInputMethodWindow != null) {
+ mPolicy.setLastInputMethodWindowLw(mInputMethodWindow, mInputMethodTarget);
+ }
+ }
+ }
+
+ @Override
+ public boolean isHardKeyboardAvailable() {
+ synchronized (mWindowMap) {
+ return mHardKeyboardAvailable;
+ }
+ }
+
+ @Override
+ public void setOnHardKeyboardStatusChangeListener(
+ OnHardKeyboardStatusChangeListener listener) {
+ synchronized (mWindowMap) {
+ mHardKeyboardStatusChangeListener = listener;
+ }
+ }
+
}
}
diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java
index 7aa48ab..109e627 100644
--- a/services/core/java/com/android/server/wm/WindowStateAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java
@@ -1590,8 +1590,6 @@
final int left = ((int) shownFrame.left) - attrs.surfaceInsets.left;
final int top = ((int) shownFrame.top) - attrs.surfaceInsets.top;
if (mSurfaceX != left || mSurfaceY != top) {
- mSurfaceX = left;
- mSurfaceY = top;
if (mAnimating) {
// If this window (or its app token) is animating, then the position
// of the surface will be re-computed on the next animation frame.
@@ -1599,6 +1597,8 @@
// transformation is being applied by the animation.
return;
}
+ mSurfaceX = left;
+ mSurfaceY = top;
if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG, ">>> OPEN TRANSACTION setWallpaperOffset");
SurfaceControl.openTransaction();
try {
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index ed32c76..21dd647b 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -546,7 +546,7 @@
if (mFactoryTestMode != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
try {
Slog.i(TAG, "Input Method Service");
- imm = new InputMethodManagerService(context, wm);
+ imm = new InputMethodManagerService(context);
ServiceManager.addService(Context.INPUT_METHOD_SERVICE, imm);
} catch (Throwable e) {
reportWtf("starting Input Manager Service", e);
diff --git a/services/tests/servicestests/src/com/android/server/pm/UserManagerTest.java b/services/tests/servicestests/src/com/android/server/pm/UserManagerTest.java
index 2d47c24..86f5ed7 100644
--- a/services/tests/servicestests/src/com/android/server/pm/UserManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/UserManagerTest.java
@@ -38,7 +38,8 @@
@Override
public void setUp() throws Exception {
- mUserManager = (UserManager) getContext().getSystemService(Context.USER_SERVICE);
+ super.setUp();
+ mUserManager = UserManager.get(getContext());
IntentFilter filter = new IntentFilter(Intent.ACTION_USER_REMOVED);
getContext().registerReceiver(new BroadcastReceiver() {
@Override
@@ -64,14 +65,18 @@
private void removeExistingUsers() {
List<UserInfo> list = mUserManager.getUsers();
for (UserInfo user : list) {
- if (user.id != UserHandle.USER_OWNER) {
+ // Keep system and primary user.
+ // We do not have to keep primary user, but in split system user mode, we need it
+ // until http://b/22976637 is fixed. Right now in split system user mode, you need to
+ // switch to primary user and run tests under primary user.
+ if (user.id != UserHandle.USER_SYSTEM && !user.isPrimary()) {
removeUser(user.id);
}
}
}
- public void testHasPrimary() throws Exception {
- assertTrue(findUser(0));
+ public void testHasSystemUser() throws Exception {
+ assertTrue(findUser(UserHandle.USER_SYSTEM));
}
public void testAddUser() throws Exception {
@@ -122,10 +127,11 @@
// Make sure only one managed profile can be created
public void testAddManagedProfile() throws Exception {
+ final int primaryUserId = mUserManager.getPrimaryUser().id;
UserInfo userInfo1 = createProfileForUser("Managed 1",
- UserInfo.FLAG_MANAGED_PROFILE, UserHandle.USER_OWNER);
+ UserInfo.FLAG_MANAGED_PROFILE, primaryUserId);
UserInfo userInfo2 = createProfileForUser("Managed 2",
- UserInfo.FLAG_MANAGED_PROFILE, UserHandle.USER_OWNER);
+ UserInfo.FLAG_MANAGED_PROFILE, primaryUserId);
assertNotNull(userInfo1);
assertNull(userInfo2);
// Verify that current user is not a managed profile
@@ -133,17 +139,18 @@
}
public void testGetUserCreationTime() throws Exception {
+ final int primaryUserId = mUserManager.getPrimaryUser().id;
UserInfo profile = createProfileForUser("Managed 1",
- UserInfo.FLAG_MANAGED_PROFILE, UserHandle.USER_OWNER);
+ UserInfo.FLAG_MANAGED_PROFILE, primaryUserId);
assertNotNull(profile);
assertTrue("creationTime must be set when the profile is created",
profile.creationTime > 0);
assertEquals(profile.creationTime, mUserManager.getUserCreationTime(
new UserHandle(profile.id)));
- long ownerCreationTime = mUserManager.getUserInfo(UserHandle.USER_OWNER).creationTime;
+ long ownerCreationTime = mUserManager.getUserInfo(primaryUserId).creationTime;
assertEquals(ownerCreationTime, mUserManager.getUserCreationTime(
- new UserHandle(UserHandle.USER_OWNER)));
+ new UserHandle(primaryUserId)));
try {
int noSuchUserId = 100500;
@@ -177,11 +184,11 @@
}
public void testSerialNumber() {
- UserInfo user1 = createUser("User 1", UserInfo.FLAG_RESTRICTED);
+ UserInfo user1 = createUser("User 1", 0);
int serialNumber1 = user1.serialNumber;
assertEquals(serialNumber1, mUserManager.getUserSerialNumber(user1.id));
assertEquals(user1.id, mUserManager.getUserHandle(serialNumber1));
- UserInfo user2 = createUser("User 2", UserInfo.FLAG_RESTRICTED);
+ UserInfo user2 = createUser("User 2", 0);
int serialNumber2 = user2.serialNumber;
assertFalse(serialNumber1 == serialNumber2);
assertEquals(serialNumber2, mUserManager.getUserSerialNumber(user2.id));
@@ -203,17 +210,15 @@
}
public void testRestrictions() {
- List<UserInfo> users = mUserManager.getUsers();
- if (users.size() > 1) {
- Bundle restrictions = new Bundle();
- restrictions.putBoolean(UserManager.DISALLOW_INSTALL_APPS, true);
- restrictions.putBoolean(UserManager.DISALLOW_CONFIG_WIFI, false);
- mUserManager.setUserRestrictions(restrictions, new UserHandle(users.get(1).id));
- Bundle stored = mUserManager.getUserRestrictions(new UserHandle(users.get(1).id));
- assertEquals(stored.getBoolean(UserManager.DISALLOW_CONFIG_WIFI), false);
- assertEquals(stored.getBoolean(UserManager.DISALLOW_UNINSTALL_APPS), false);
- assertEquals(stored.getBoolean(UserManager.DISALLOW_INSTALL_APPS), true);
- }
+ UserInfo testUser = createUser("User 1", 0);
+ Bundle restrictions = new Bundle();
+ restrictions.putBoolean(UserManager.DISALLOW_INSTALL_APPS, true);
+ restrictions.putBoolean(UserManager.DISALLOW_CONFIG_WIFI, false);
+ mUserManager.setUserRestrictions(restrictions, new UserHandle(testUser.id));
+ Bundle stored = mUserManager.getUserRestrictions(new UserHandle(testUser.id));
+ assertEquals(stored.getBoolean(UserManager.DISALLOW_CONFIG_WIFI), false);
+ assertEquals(stored.getBoolean(UserManager.DISALLOW_UNINSTALL_APPS), false);
+ assertEquals(stored.getBoolean(UserManager.DISALLOW_INSTALL_APPS), true);
}
private void removeUser(int userId) {
diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java
index 31f1d7f..e3f3c75 100644
--- a/telephony/java/android/telephony/CarrierConfigManager.java
+++ b/telephony/java/android/telephony/CarrierConfigManager.java
@@ -266,6 +266,13 @@
public static final String KEY_CARRIER_INSTANT_LETTERING_AVAILABLE_BOOL =
"carrier_instant_lettering_available_bool";
+ /*
+ * Flag specifying whether IMS should be the first phone attempted for E911 even if the
+ * phone is not in service.
+ */
+ public static final String KEY_CARRIER_USE_IMS_FIRST_FOR_EMERGENCY_BOOL
+ = "carrier_use_ims_first_for_emergency_bool";
+
/**
* If Voice Radio Technology is RIL_RADIO_TECHNOLOGY_LTE:14 or RIL_RADIO_TECHNOLOGY_UNKNOWN:0
* this is the value that should be used instead. A configuration value of
@@ -425,6 +432,7 @@
sDefaults.putBoolean(KEY_CARRIER_VOLTE_TTY_SUPPORTED_BOOL, true);
sDefaults.putBoolean(KEY_CARRIER_ALLOW_TURNOFF_IMS_BOOL, true);
sDefaults.putBoolean(KEY_CARRIER_INSTANT_LETTERING_AVAILABLE_BOOL, false);
+ sDefaults.putBoolean(KEY_CARRIER_USE_IMS_FIRST_FOR_EMERGENCY_BOOL, true);
sDefaults.putBoolean(KEY_DISABLE_CDMA_ACTIVATION_CODE_BOOL, false);
sDefaults.putBoolean(KEY_DTMF_TYPE_ENABLED_BOOL, false);
sDefaults.putBoolean(KEY_ENABLE_DIALER_KEY_VIBRATION_BOOL, true);