Merge "Potential fix for bug 7352816" into jb-mr1-dev
diff --git a/api/17.txt b/api/17.txt
index ee9a973..84c2a93 100644
--- a/api/17.txt
+++ b/api/17.txt
@@ -28617,7 +28617,6 @@
method public void setHeight(int);
method public void setHorizontalOffset(int);
method public void setInputMethodMode(int);
- method public void setLayoutDirection(int);
method public void setListSelector(android.graphics.drawable.Drawable);
method public void setModal(boolean);
method public void setOnDismissListener(android.widget.PopupWindow.OnDismissListener);
diff --git a/api/current.txt b/api/current.txt
index ee9a973..d7f4e11 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -8263,6 +8263,7 @@
method public int getScaledWidth(int);
method public final int getWidth();
method public final boolean hasAlpha();
+ method public final boolean hasMipMap();
method public final boolean isMutable();
method public final boolean isPremultiplied();
method public final boolean isRecycled();
@@ -8271,6 +8272,7 @@
method public boolean sameAs(android.graphics.Bitmap);
method public void setDensity(int);
method public void setHasAlpha(boolean);
+ method public final void setHasMipMap(boolean);
method public void setPixel(int, int, int);
method public void setPixels(int[], int, int, int, int, int, int);
method public void writeToParcel(android.os.Parcel, int);
@@ -28617,7 +28619,6 @@
method public void setHeight(int);
method public void setHorizontalOffset(int);
method public void setInputMethodMode(int);
- method public void setLayoutDirection(int);
method public void setListSelector(android.graphics.drawable.Drawable);
method public void setModal(boolean);
method public void setOnDismissListener(android.widget.PopupWindow.OnDismissListener);
diff --git a/cmds/pm/src/com/android/commands/pm/Pm.java b/cmds/pm/src/com/android/commands/pm/Pm.java
index 16d4ad6..42c9d34 100644
--- a/cmds/pm/src/com/android/commands/pm/Pm.java
+++ b/cmds/pm/src/com/android/commands/pm/Pm.java
@@ -1131,6 +1131,19 @@
}
private void runClear() {
+ int userId = 0;
+ String option = nextOption();
+ if (option != null && option.equals("--user")) {
+ String optionData = nextOptionData();
+ if (optionData == null || !isNumber(optionData)) {
+ System.err.println("Error: no USER_ID specified");
+ showUsage();
+ return;
+ } else {
+ userId = Integer.parseInt(optionData);
+ }
+ }
+
String pkg = nextArg();
if (pkg == null) {
System.err.println("Error: no package specified");
@@ -1140,8 +1153,7 @@
ClearDataObserver obs = new ClearDataObserver();
try {
- // XXX TO DO: add user arg
- if (!ActivityManagerNative.getDefault().clearApplicationUserData(pkg, obs, 0)) {
+ if (!ActivityManagerNative.getDefault().clearApplicationUserData(pkg, obs, userId)) {
System.err.println("Failed");
}
@@ -1179,7 +1191,7 @@
return "unknown";
}
- private boolean isNumber(String s) {
+ private static boolean isNumber(String s) {
try {
Integer.parseInt(s);
} catch (NumberFormatException nfe) {
@@ -1452,7 +1464,7 @@
System.err.println(" [--algo <algorithm name> --key <key-in-hex> --iv <IV-in-hex>]");
System.err.println(" [--originating-uri <URI>] [--referrer <URI>] PATH");
System.err.println(" pm uninstall [-k] PACKAGE");
- System.err.println(" pm clear PACKAGE");
+ System.err.println(" pm clear [--user USER_ID] PACKAGE");
System.err.println(" pm enable [--user USER_ID] PACKAGE_OR_COMPONENT");
System.err.println(" pm disable [--user USER_ID] PACKAGE_OR_COMPONENT");
System.err.println(" pm disable-user [--user USER_ID] PACKAGE_OR_COMPONENT");
diff --git a/core/java/android/accounts/AccountManagerService.java b/core/java/android/accounts/AccountManagerService.java
index 5cde65c..03e0c0f 100644
--- a/core/java/android/accounts/AccountManagerService.java
+++ b/core/java/android/accounts/AccountManagerService.java
@@ -247,7 +247,6 @@
}
public void systemReady() {
- initUser(UserHandle.USER_OWNER);
}
private UserManager getUserManager() {
diff --git a/core/java/android/bluetooth/BluetoothSocket.java b/core/java/android/bluetooth/BluetoothSocket.java
index aba8710..8cbf5b1 100644
--- a/core/java/android/bluetooth/BluetoothSocket.java
+++ b/core/java/android/bluetooth/BluetoothSocket.java
@@ -19,6 +19,7 @@
import java.io.InputStream;
import java.io.OutputStream;
import java.util.List;
+import java.util.UUID;
import android.net.LocalSocket;
import java.nio.ByteOrder;
import java.nio.ByteBuffer;
@@ -140,7 +141,9 @@
throw new IOException("Invalid RFCOMM channel: " + port);
}
}
- mUuid = uuid;
+ if(uuid != null)
+ mUuid = uuid;
+ else mUuid = new ParcelUuid(new UUID(0, 0));
mType = type;
mAuth = auth;
mEncrypt = encrypt;
diff --git a/core/java/android/content/SyncManager.java b/core/java/android/content/SyncManager.java
index 1e4ad76..bb0c686 100644
--- a/core/java/android/content/SyncManager.java
+++ b/core/java/android/content/SyncManager.java
@@ -21,7 +21,6 @@
import android.accounts.AccountManager;
import android.accounts.AccountManagerService;
import android.app.ActivityManager;
-import android.app.ActivityManagerNative;
import android.app.AlarmManager;
import android.app.Notification;
import android.app.NotificationManager;
@@ -56,6 +55,7 @@
import android.util.EventLog;
import android.util.Log;
import android.util.Pair;
+import android.util.Slog;
import com.android.internal.R;
import com.android.internal.util.IndentingPrintWriter;
@@ -154,7 +154,9 @@
private AlarmManager mAlarmService = null;
private SyncStorageEngine mSyncStorageEngine;
- final public SyncQueue mSyncQueue;
+
+ // @GuardedBy("mSyncQueue")
+ private final SyncQueue mSyncQueue;
protected final ArrayList<ActiveSyncContext> mActiveSyncContexts = Lists.newArrayList();
@@ -310,13 +312,10 @@
if (userId == UserHandle.USER_NULL) return;
if (Intent.ACTION_USER_REMOVED.equals(action)) {
- Log.i(TAG, "User removed: u" + userId);
onUserRemoved(userId);
} else if (Intent.ACTION_USER_STARTING.equals(action)) {
- Log.i(TAG, "User starting: u" + userId);
onUserStarting(userId);
} else if (Intent.ACTION_USER_STOPPING.equals(action)) {
- Log.i(TAG, "User stopping: u" + userId);
onUserStopping(userId);
}
}
@@ -337,6 +336,10 @@
}
}
+ /**
+ * Should only be created after {@link ContentService#systemReady()} so that
+ * {@link PackageManager} is ready to query.
+ */
public SyncManager(Context context, boolean factoryTest) {
// Initialize the SyncStorageEngine first, before registering observers
// and creating threads and so on; it may fail if the disk is full.
@@ -440,9 +443,6 @@
UserHandle.ALL,
new IntentFilter(AccountManager.LOGIN_ACCOUNTS_CHANGED_ACTION),
null, null);
-
- // do this synchronously to ensure we have the accounts before this call returns
- onUserStarting(UserHandle.USER_OWNER);
}
// Pick a random second in a day to seed all periodic syncs
@@ -902,7 +902,9 @@
updateRunningAccounts();
- mSyncQueue.addPendingOperations(userId);
+ synchronized (mSyncQueue) {
+ mSyncQueue.addPendingOperations(userId);
+ }
// Schedule sync for any accounts under started user
final Account[] accounts = AccountManagerService.getSingleton().getAccounts(userId);
@@ -1957,10 +1959,10 @@
synchronized (mSyncQueue) {
if (isLoggable) {
Log.v(TAG, "build the operation array, syncQueue size is "
- + mSyncQueue.mOperationsMap.size());
+ + mSyncQueue.getOperations().size());
}
- Iterator<SyncOperation> operationIterator =
- mSyncQueue.mOperationsMap.values().iterator();
+ final Iterator<SyncOperation> operationIterator = mSyncQueue.getOperations()
+ .iterator();
final ActivityManager activityManager
= (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE);
@@ -2153,7 +2155,7 @@
runSyncFinishedOrCanceledLocked(null, toReschedule);
scheduleSyncOperation(toReschedule.mSyncOperation);
}
- synchronized (mSyncQueue){
+ synchronized (mSyncQueue) {
mSyncQueue.remove(candidate);
}
dispatchSyncOperation(candidate);
diff --git a/core/java/android/content/SyncQueue.java b/core/java/android/content/SyncQueue.java
index 395658c..c9a325e 100644
--- a/core/java/android/content/SyncQueue.java
+++ b/core/java/android/content/SyncQueue.java
@@ -27,11 +27,14 @@
import com.google.android.collect.Maps;
import java.util.ArrayList;
+import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
/**
+ * Queue of pending sync operations. Not inherently thread safe, external
+ * callers are responsible for locking.
*
* @hide
*/
@@ -43,13 +46,11 @@
// A Map of SyncOperations operationKey -> SyncOperation that is designed for
// quick lookup of an enqueued SyncOperation.
- public final HashMap<String, SyncOperation> mOperationsMap = Maps.newHashMap();
+ private final HashMap<String, SyncOperation> mOperationsMap = Maps.newHashMap();
public SyncQueue(SyncStorageEngine syncStorageEngine, final SyncAdaptersCache syncAdapters) {
mSyncStorageEngine = syncStorageEngine;
mSyncAdapters = syncAdapters;
-
- addPendingOperations(UserHandle.USER_OWNER);
}
public void addPendingOperations(int userId) {
@@ -198,6 +199,10 @@
}
}
+ public Collection<SyncOperation> getOperations() {
+ return mOperationsMap.values();
+ }
+
public void dump(StringBuilder sb) {
final long now = SystemClock.elapsedRealtime();
sb.append("SyncQueue: ").append(mOperationsMap.size()).append(" operation(s)\n");
diff --git a/core/java/android/content/SyncStorageEngine.java b/core/java/android/content/SyncStorageEngine.java
index de97481..10e7bff 100644
--- a/core/java/android/content/SyncStorageEngine.java
+++ b/core/java/android/content/SyncStorageEngine.java
@@ -609,23 +609,25 @@
public void clearAllBackoffs(SyncQueue syncQueue) {
boolean changed = false;
synchronized (mAuthorities) {
- for (AccountInfo accountInfo : mAccounts.values()) {
- for (AuthorityInfo authorityInfo : accountInfo.authorities.values()) {
- if (authorityInfo.backoffTime != NOT_IN_BACKOFF_MODE
- || authorityInfo.backoffDelay != NOT_IN_BACKOFF_MODE) {
- if (Log.isLoggable(TAG, Log.VERBOSE)) {
- Log.v(TAG, "clearAllBackoffs:"
- + " authority:" + authorityInfo.authority
- + " account:" + accountInfo.accountAndUser.account.name
- + " user:" + accountInfo.accountAndUser.userId
- + " backoffTime was: " + authorityInfo.backoffTime
- + " backoffDelay was: " + authorityInfo.backoffDelay);
+ synchronized (syncQueue) {
+ for (AccountInfo accountInfo : mAccounts.values()) {
+ for (AuthorityInfo authorityInfo : accountInfo.authorities.values()) {
+ if (authorityInfo.backoffTime != NOT_IN_BACKOFF_MODE
+ || authorityInfo.backoffDelay != NOT_IN_BACKOFF_MODE) {
+ if (Log.isLoggable(TAG, Log.VERBOSE)) {
+ Log.v(TAG, "clearAllBackoffs:"
+ + " authority:" + authorityInfo.authority
+ + " account:" + accountInfo.accountAndUser.account.name
+ + " user:" + accountInfo.accountAndUser.userId
+ + " backoffTime was: " + authorityInfo.backoffTime
+ + " backoffDelay was: " + authorityInfo.backoffDelay);
+ }
+ authorityInfo.backoffTime = NOT_IN_BACKOFF_MODE;
+ authorityInfo.backoffDelay = NOT_IN_BACKOFF_MODE;
+ syncQueue.onBackoffChanged(accountInfo.accountAndUser.account,
+ accountInfo.accountAndUser.userId, authorityInfo.authority, 0);
+ changed = true;
}
- authorityInfo.backoffTime = NOT_IN_BACKOFF_MODE;
- authorityInfo.backoffDelay = NOT_IN_BACKOFF_MODE;
- syncQueue.onBackoffChanged(accountInfo.accountAndUser.account,
- accountInfo.accountAndUser.userId, authorityInfo.authority, 0);
- changed = true;
}
}
}
diff --git a/core/java/android/content/pm/ApplicationInfo.java b/core/java/android/content/pm/ApplicationInfo.java
index a0283d3..32cc7fd 100644
--- a/core/java/android/content/pm/ApplicationInfo.java
+++ b/core/java/android/content/pm/ApplicationInfo.java
@@ -554,6 +554,7 @@
manageSpaceActivityName = orig.manageSpaceActivityName;
descriptionRes = orig.descriptionRes;
uiOptions = orig.uiOptions;
+ backupAgentName = orig.backupAgentName;
}
diff --git a/core/java/android/content/pm/RegisteredServicesCache.java b/core/java/android/content/pm/RegisteredServicesCache.java
index 0b91786..6def4a1 100644
--- a/core/java/android/content/pm/RegisteredServicesCache.java
+++ b/core/java/android/content/pm/RegisteredServicesCache.java
@@ -264,7 +264,8 @@
if (user.services == null) {
generateServicesMap(userId);
}
- return Collections.unmodifiableCollection(user.services.values());
+ return Collections.unmodifiableCollection(
+ new ArrayList<ServiceInfo<V>>(user.services.values()));
}
}
diff --git a/core/java/android/os/AsyncTask.java b/core/java/android/os/AsyncTask.java
index 69e1de9..ce5f163 100644
--- a/core/java/android/os/AsyncTask.java
+++ b/core/java/android/os/AsyncTask.java
@@ -110,7 +110,7 @@
* <h2>The 4 steps</h2>
* <p>When an asynchronous task is executed, the task goes through 4 steps:</p>
* <ol>
- * <li>{@link #onPreExecute()}, invoked on the UI thread immediately after the task
+ * <li>{@link #onPreExecute()}, invoked on the UI thread before the task
* is executed. This step is normally used to setup the task, for instance by
* showing a progress bar in the user interface.</li>
* <li>{@link #doInBackground}, invoked on the background thread
diff --git a/core/java/android/server/search/SearchManagerService.java b/core/java/android/server/search/SearchManagerService.java
index de4dd88..affeb90 100644
--- a/core/java/android/server/search/SearchManagerService.java
+++ b/core/java/android/server/search/SearchManagerService.java
@@ -283,6 +283,8 @@
@Override
public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+ mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DUMP, TAG);
+
IndentingPrintWriter ipw = new IndentingPrintWriter(pw, " ");
synchronized (mSearchables) {
for (int i = 0; i < mSearchables.size(); i++) {
diff --git a/core/java/android/service/dreams/DreamService.java b/core/java/android/service/dreams/DreamService.java
index c72b714..4820c5e 100644
--- a/core/java/android/service/dreams/DreamService.java
+++ b/core/java/android/service/dreams/DreamService.java
@@ -612,18 +612,23 @@
View.SYSTEM_UI_FLAG_LOW_PROFILE);
getWindowManager().addView(mWindow.getDecorView(), mWindow.getAttributes());
} catch (Throwable t) {
- Slog.w("Crashed adding window view", t);
+ Slog.w(TAG, "Crashed adding window view", t);
safelyFinish();
return;
}
// start it up
- try {
- onDreamingStarted();
- } catch (Throwable t) {
- Slog.w("Crashed in onDreamingStarted()", t);
- safelyFinish();
- }
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ try {
+ onDreamingStarted();
+ } catch (Throwable t) {
+ Slog.w(TAG, "Crashed in onDreamingStarted()", t);
+ safelyFinish();
+ }
+ }
+ });
}
private void safelyFinish() {
diff --git a/core/java/android/view/HardwareRenderer.java b/core/java/android/view/HardwareRenderer.java
index 37e0a36..ec1695e 100644
--- a/core/java/android/view/HardwareRenderer.java
+++ b/core/java/android/view/HardwareRenderer.java
@@ -925,8 +925,17 @@
sEgl.eglGetConfigAttrib(sEglDisplay, config, EGL_STENCIL_SIZE, value);
Log.d(LOG_TAG, " STENCIL_SIZE = " + value[0]);
+ sEgl.eglGetConfigAttrib(sEglDisplay, config, EGL_SAMPLE_BUFFERS, value);
+ Log.d(LOG_TAG, " SAMPLE_BUFFERS = " + value[0]);
+
+ sEgl.eglGetConfigAttrib(sEglDisplay, config, EGL_SAMPLES, value);
+ Log.d(LOG_TAG, " SAMPLES = " + value[0]);
+
sEgl.eglGetConfigAttrib(sEglDisplay, config, EGL_SURFACE_TYPE, value);
Log.d(LOG_TAG, " SURFACE_TYPE = 0x" + Integer.toHexString(value[0]));
+
+ sEgl.eglGetConfigAttrib(sEglDisplay, config, EGL_CONFIG_CAVEAT, value);
+ Log.d(LOG_TAG, " CONFIG_CAVEAT = 0x" + Integer.toHexString(value[0]));
}
GL createEglSurface(Surface surface) throws Surface.OutOfResourcesException {
@@ -1433,6 +1442,7 @@
EGL_BLUE_SIZE, 8,
EGL_ALPHA_SIZE, 8,
EGL_DEPTH_SIZE, 0,
+ EGL_CONFIG_CAVEAT, EGL_NONE,
// TODO: Find a better way to choose the stencil size
EGL_STENCIL_SIZE, mShowOverdraw ? GLES20Canvas.getStencilSize() : 0,
EGL_SURFACE_TYPE, EGL_WINDOW_BIT |
diff --git a/core/java/android/view/IDisplayContentChangeListener.aidl b/core/java/android/view/IDisplayContentChangeListener.aidl
index 8f23ff6..ef7edea 100644
--- a/core/java/android/view/IDisplayContentChangeListener.aidl
+++ b/core/java/android/view/IDisplayContentChangeListener.aidl
@@ -28,5 +28,6 @@
oneway interface IDisplayContentChangeListener {
void onWindowTransition(int displayId, int transition, in WindowInfo info);
void onRectangleOnScreenRequested(int displayId, in Rect rectangle, boolean immediate);
+ void onWindowLayersChanged(int displayId);
void onRotationChanged(int rotation);
}
diff --git a/core/java/android/view/Surface.java b/core/java/android/view/Surface.java
index 07bb8f9..7ef6939 100644
--- a/core/java/android/view/Surface.java
+++ b/core/java/android/view/Surface.java
@@ -245,6 +245,7 @@
private static native void nativeOpenTransaction();
private static native void nativeCloseTransaction();
+ private static native void nativeSetAnimationTransaction();
private native void nativeSetLayer(int zorder);
private native void nativeSetPosition(float x, float y);
@@ -525,6 +526,11 @@
nativeCloseTransaction();
}
+ /** flag the transaction as an animation @hide */
+ public static void setAnimationTransaction() {
+ nativeSetAnimationTransaction();
+ }
+
/** @hide */
public void setLayer(int zorder) {
nativeSetLayer(zorder);
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 946965b..b4ba871 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -4906,7 +4906,7 @@
*
* @param outRect The output location
*/
- private void getBoundsOnScreen(Rect outRect) {
+ void getBoundsOnScreen(Rect outRect) {
if (mAttachInfo == null) {
return;
}
@@ -8661,7 +8661,9 @@
/**
* Return the visible drawing bounds of your view. Fills in the output
* rectangle with the values from getScrollX(), getScrollY(),
- * getWidth(), and getHeight().
+ * getWidth(), and getHeight(). These bounds do not account for any
+ * transformation properties currently set on the view, such as
+ * {@link #setScaleX(float)} or {@link #setRotation(float)}.
*
* @param outRect The (scrolled) drawing bounds of the view.
*/
@@ -10515,9 +10517,6 @@
* <p>Causes the Runnable to be added to the message queue.
* The runnable will be run on the user interface thread.</p>
*
- * <p>This method can be invoked from outside of the UI thread
- * only when this View is attached to a window.</p>
- *
* @param action The Runnable that will be executed.
*
* @return Returns true if the Runnable was successfully placed in to the
@@ -10542,9 +10541,6 @@
* after the specified amount of time elapses.
* The runnable will be run on the user interface thread.</p>
*
- * <p>This method can be invoked from outside of the UI thread
- * only when this View is attached to a window.</p>
- *
* @param action The Runnable that will be executed.
* @param delayMillis The delay (in milliseconds) until the Runnable
* will be executed.
@@ -10573,9 +10569,6 @@
* <p>Causes the Runnable to execute on the next animation time step.
* The runnable will be run on the user interface thread.</p>
*
- * <p>This method can be invoked from outside of the UI thread
- * only when this View is attached to a window.</p>
- *
* @param action The Runnable that will be executed.
*
* @see #postOnAnimationDelayed
@@ -10597,9 +10590,6 @@
* after the specified amount of time elapses.
* The runnable will be run on the user interface thread.</p>
*
- * <p>This method can be invoked from outside of the UI thread
- * only when this View is attached to a window.</p>
- *
* @param action The Runnable that will be executed.
* @param delayMillis The delay (in milliseconds) until the Runnable
* will be executed.
@@ -10621,9 +10611,6 @@
/**
* <p>Removes the specified Runnable from the message queue.</p>
*
- * <p>This method can be invoked from outside of the UI thread
- * only when this View is attached to a window.</p>
- *
* @param action The Runnable to remove from the message handling queue
*
* @return true if this view could ask the Handler to remove the Runnable,
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index 9ce7df9..b95e1bd 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -3383,7 +3383,7 @@
}
if (child.isLayoutDirectionInherited()) {
- child.resetResolvedLayoutDirection();
+ child.resetRtlProperties();
child.resolveRtlPropertiesIfNeeded();
}
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 0475283..67452ec 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -29,12 +29,14 @@
import android.content.res.Configuration;
import android.content.res.Resources;
import android.graphics.Canvas;
+import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.PixelFormat;
import android.graphics.Point;
import android.graphics.PointF;
import android.graphics.PorterDuff;
import android.graphics.Rect;
+import android.graphics.RectF;
import android.graphics.Region;
import android.graphics.drawable.Drawable;
import android.media.AudioManager;
@@ -885,11 +887,13 @@
// Intersect with the bounds of the window to skip
// updates that lie outside of the visible region
final float appScale = mAttachInfo.mApplicationScale;
- localDirty.intersect(0, 0,
- (int) (mWidth * appScale + 0.5f), (int) (mHeight * appScale + 0.5f));
-
- if (!mWillDrawSoon) {
- scheduleTraversals();
+ if (localDirty.intersect(0, 0,
+ (int) (mWidth * appScale + 0.5f), (int) (mHeight * appScale + 0.5f))) {
+ if (!mWillDrawSoon) {
+ scheduleTraversals();
+ }
+ } else {
+ localDirty.setEmpty();
}
return null;
@@ -1182,6 +1186,7 @@
viewVisibilityChanged = false;
mLastConfiguration.setTo(host.getResources().getConfiguration());
mLastSystemUiVisibility = mAttachInfo.mSystemUiVisibility;
+ host.setLayoutDirection(mLastConfiguration.getLayoutDirection());
host.dispatchAttachedToWindow(attachInfo, 0);
mFitSystemWindowsInsets.set(mAttachInfo.mContentInsets);
host.fitSystemWindows(mFitSystemWindowsInsets);
@@ -2319,24 +2324,14 @@
mAccessibilityFocusedHost.getAccessibilityNodeProvider();
Rect bounds = mView.mAttachInfo.mTmpInvalRect;
if (provider == null) {
- mAccessibilityFocusedHost.getDrawingRect(bounds);
- if (mView instanceof ViewGroup) {
- ViewGroup viewGroup = (ViewGroup) mView;
- try {
- viewGroup.offsetDescendantRectToMyCoords(mAccessibilityFocusedHost, bounds);
- } catch (IllegalArgumentException iae) {
- Log.e(TAG, "Temporary detached view that was neither removed not reattached: "
- + mAccessibilityFocusedHost);
- return;
- }
- }
+ mAccessibilityFocusedHost.getBoundsOnScreen(bounds);
} else {
if (mAccessibilityFocusedVirtualView == null) {
return;
}
mAccessibilityFocusedVirtualView.getBoundsInScreen(bounds);
- bounds.offset(-mAttachInfo.mWindowLeft, -mAttachInfo.mWindowTop);
}
+ bounds.offset(-mAttachInfo.mWindowLeft, -mAttachInfo.mWindowTop);
drawable.setBounds(bounds);
drawable.draw(canvas);
}
@@ -2684,7 +2679,12 @@
// the one in them which may be newer.
config = mView.getResources().getConfiguration();
if (force || mLastConfiguration.diff(config) != 0) {
+ final int lastLayoutDirection = mLastConfiguration.getLayoutDirection();
+ final int currentLayoutDirection = config.getLayoutDirection();
mLastConfiguration.setTo(config);
+ if (lastLayoutDirection != currentLayoutDirection) {
+ mView.setLayoutDirection(currentLayoutDirection);
+ }
mView.dispatchConfigurationChanged(config);
}
}
diff --git a/core/java/android/widget/AbsSeekBar.java b/core/java/android/widget/AbsSeekBar.java
index 646fe7e..3b5e75b 100644
--- a/core/java/android/widget/AbsSeekBar.java
+++ b/core/java/android/widget/AbsSeekBar.java
@@ -241,6 +241,7 @@
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
+ super.onSizeChanged(w, h, oldw, oldh);
updateThumbPos(w, h);
}
@@ -555,4 +556,23 @@
}
return false;
}
+
+ @Override
+ public void onRtlPropertiesChanged(int layoutDirection) {
+ super.onRtlPropertiesChanged(layoutDirection);
+
+ int max = getMax();
+ float scale = max > 0 ? (float) getProgress() / (float) max : 0;
+
+ Drawable thumb = mThumb;
+ if (thumb != null) {
+ setThumbPos(getWidth(), thumb, scale, Integer.MIN_VALUE);
+ /*
+ * Since we draw translated, the drawable's bounds that it signals
+ * for invalidation won't be the actual bounds we want invalidated,
+ * so just invalidate this whole view.
+ */
+ invalidate();
+ }
+ }
}
diff --git a/core/java/android/widget/AutoCompleteTextView.java b/core/java/android/widget/AutoCompleteTextView.java
index 75d1471..f0eb94f 100644
--- a/core/java/android/widget/AutoCompleteTextView.java
+++ b/core/java/android/widget/AutoCompleteTextView.java
@@ -1093,7 +1093,6 @@
mPopup.setInputMethodMode(ListPopupWindow.INPUT_METHOD_NEEDED);
mPopup.setListItemExpandMax(EXPAND_MAX);
}
- mPopup.setLayoutDirection(getLayoutDirection());
mPopup.show();
mPopup.getListView().setOverScrollMode(View.OVER_SCROLL_ALWAYS);
}
diff --git a/core/java/android/widget/ListPopupWindow.java b/core/java/android/widget/ListPopupWindow.java
index 1c81d11..3d6b69e 100644
--- a/core/java/android/widget/ListPopupWindow.java
+++ b/core/java/android/widget/ListPopupWindow.java
@@ -1021,8 +1021,6 @@
mDropDownList.setOnItemSelectedListener(mItemSelectedListener);
}
- mDropDownList.setLayoutDirection(mLayoutDirection);
-
dropDownView = mDropDownList;
View hintView = mPromptView;
@@ -1132,21 +1130,6 @@
}
/**
- * Set the layout direction for this popup. Should be a resolved direction as the
- * popup as no capacity to do the resolution on his own.
- *
- * @param layoutDirection One of {@link View#LAYOUT_DIRECTION_LTR},
- * {@link View#LAYOUT_DIRECTION_RTL},
- *
- */
- public void setLayoutDirection(int layoutDirection) {
- mLayoutDirection = layoutDirection;
- if (mDropDownList != null) {
- mDropDownList.setLayoutDirection(mLayoutDirection);
- }
- }
-
- /**
* <p>Wrapper class for a ListView. This wrapper can hijack the focus to
* make sure the list uses the appropriate drawables and states when
* displayed on screen within a drop down. The focus is never actually
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index b3c679c..8e5ff40 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -367,6 +367,7 @@
private boolean mSingleLine;
private int mDesiredHeightAtMeasure = -1;
private boolean mIncludePad = true;
+ private int mDeferScroll = -1;
// tmp primitives, so we don't alloc them on each draw
private Rect mTempRect;
@@ -6317,6 +6318,11 @@
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
+ if (mDeferScroll >= 0) {
+ int curs = mDeferScroll;
+ mDeferScroll = -1;
+ bringPointIntoView(Math.min(curs, mText.length()));
+ }
if (changed && mEditor != null) mEditor.invalidateTextDisplayList();
}
@@ -6399,6 +6405,10 @@
* This has to be called after layout. Returns true if anything changed.
*/
public boolean bringPointIntoView(int offset) {
+ if (isLayoutRequested()) {
+ mDeferScroll = offset;
+ return false;
+ }
boolean changed = false;
Layout layout = isShowingHint() ? mHintLayout: mLayout;
@@ -7108,13 +7118,13 @@
registerForPreDraw();
}
+ checkForResize();
+
if (curs >= 0) {
mHighlightPathBogus = true;
if (mEditor != null) mEditor.makeBlink();
bringPointIntoView(curs);
}
-
- checkForResize();
}
/**
@@ -7161,6 +7171,7 @@
if (oldStart >= 0 || newStart >= 0) {
invalidateCursor(Selection.getSelectionStart(buf), oldStart, newStart);
+ checkForResize();
registerForPreDraw();
if (mEditor != null) mEditor.makeBlink();
}
diff --git a/core/jni/android/graphics/Bitmap.cpp b/core/jni/android/graphics/Bitmap.cpp
index fd7a6a7..f485e03 100644
--- a/core/jni/android/graphics/Bitmap.cpp
+++ b/core/jni/android/graphics/Bitmap.cpp
@@ -7,7 +7,7 @@
#include "SkUnPreMultiply.h"
#include <binder/Parcel.h>
-#include "android_os_Parcel.h"
+#include "android_os_Parcel.h"
#include "android_util_Binder.h"
#include "android_nio_utils.h"
#include "CreateJavaOutputStreamAdaptor.h"
@@ -353,6 +353,15 @@
bitmap->setIsOpaque(!hasAlpha);
}
+static jboolean Bitmap_hasMipMap(JNIEnv* env, jobject, SkBitmap* bitmap) {
+ return bitmap->hasHardwareMipMap();
+}
+
+static void Bitmap_setHasMipMap(JNIEnv* env, jobject, SkBitmap* bitmap,
+ jboolean hasMipMap) {
+ bitmap->setHasHardwareMipMap(hasMipMap);
+}
+
///////////////////////////////////////////////////////////////////////////////
static jobject Bitmap_createFromParcel(JNIEnv* env, jobject, jobject parcel) {
@@ -666,6 +675,8 @@
{ "nativeConfig", "(I)I", (void*)Bitmap_config },
{ "nativeHasAlpha", "(I)Z", (void*)Bitmap_hasAlpha },
{ "nativeSetHasAlpha", "(IZ)V", (void*)Bitmap_setHasAlpha },
+ { "nativeHasMipMap", "(I)Z", (void*)Bitmap_hasMipMap },
+ { "nativeSetHasMipMap", "(IZ)V", (void*)Bitmap_setHasMipMap },
{ "nativeCreateFromParcel",
"(Landroid/os/Parcel;)Landroid/graphics/Bitmap;",
(void*)Bitmap_createFromParcel },
diff --git a/core/jni/android/graphics/YuvToJpegEncoder.cpp b/core/jni/android/graphics/YuvToJpegEncoder.cpp
index 8333e00..f386905 100644
--- a/core/jni/android/graphics/YuvToJpegEncoder.cpp
+++ b/core/jni/android/graphics/YuvToJpegEncoder.cpp
@@ -90,8 +90,9 @@
// process 16 lines of Y and 8 lines of U/V each time.
while (cinfo->next_scanline < cinfo->image_height) {
//deitnerleave u and v
- deinterleave(vuPlanar, uRows, vRows, cinfo->next_scanline, width);
+ deinterleave(vuPlanar, uRows, vRows, cinfo->next_scanline, width, height);
+ // Jpeg library ignores the rows whose indices are greater than height.
for (int i = 0; i < 16; i++) {
// y row
y[i] = yPlanar + (cinfo->next_scanline + i) * fStrides[0];
@@ -112,8 +113,10 @@
}
void Yuv420SpToJpegEncoder::deinterleave(uint8_t* vuPlanar, uint8_t* uRows,
- uint8_t* vRows, int rowIndex, int width) {
- for (int row = 0; row < 8; ++row) {
+ uint8_t* vRows, int rowIndex, int width, int height) {
+ int numRows = (height - rowIndex) / 2;
+ if (numRows > 8) numRows = 8;
+ for (int row = 0; row < numRows; ++row) {
int offset = ((rowIndex >> 1) + row) * fStrides[1];
uint8_t* vu = vuPlanar + offset;
for (int i = 0; i < (width >> 1); ++i) {
@@ -164,6 +167,7 @@
while (cinfo->next_scanline < cinfo->image_height) {
deinterleave(yuvOffset, yRows, uRows, vRows, cinfo->next_scanline, width, height);
+ // Jpeg library ignores the rows whose indices are greater than height.
for (int i = 0; i < 16; i++) {
// y row
y[i] = yRows + i * width;
@@ -185,7 +189,9 @@
void Yuv422IToJpegEncoder::deinterleave(uint8_t* yuv, uint8_t* yRows, uint8_t* uRows,
uint8_t* vRows, int rowIndex, int width, int height) {
- for (int row = 0; row < 16; ++row) {
+ int numRows = height - rowIndex;
+ if (numRows > 16) numRows = 16;
+ for (int row = 0; row < numRows; ++row) {
uint8_t* yuvSeg = yuv + (rowIndex + row) * fStrides[0];
for (int i = 0; i < (width >> 1); ++i) {
int indexY = row * width + (i << 1);
diff --git a/core/jni/android/graphics/YuvToJpegEncoder.h b/core/jni/android/graphics/YuvToJpegEncoder.h
index 97106ce..0d418ed 100644
--- a/core/jni/android/graphics/YuvToJpegEncoder.h
+++ b/core/jni/android/graphics/YuvToJpegEncoder.h
@@ -55,7 +55,7 @@
void deinterleaveYuv(uint8_t* yuv, int width, int height,
uint8_t*& yPlanar, uint8_t*& uPlanar, uint8_t*& vPlanar);
void deinterleave(uint8_t* vuPlanar, uint8_t* uRows, uint8_t* vRows,
- int rowIndex, int width);
+ int rowIndex, int width, int height);
void compress(jpeg_compress_struct* cinfo, uint8_t* yuv, int* offsets);
};
diff --git a/core/jni/android_view_GLES20Canvas.cpp b/core/jni/android_view_GLES20Canvas.cpp
index 1b71b43..5d306d2 100644
--- a/core/jni/android_view_GLES20Canvas.cpp
+++ b/core/jni/android_view_GLES20Canvas.cpp
@@ -829,7 +829,6 @@
static void android_view_GLES20Canvas_setTextureLayerTransform(JNIEnv* env, jobject clazz,
Layer* layer, SkMatrix* matrix) {
-
layer->getTransform().load(*matrix);
}
diff --git a/core/jni/android_view_Surface.cpp b/core/jni/android_view_Surface.cpp
index 4982f31..531445f 100644
--- a/core/jni/android_view_Surface.cpp
+++ b/core/jni/android_view_Surface.cpp
@@ -526,6 +526,10 @@
SurfaceComposerClient::closeGlobalTransaction();
}
+static void nativeSetAnimationTransaction(JNIEnv* env, jclass clazz) {
+ SurfaceComposerClient::setAnimationTransaction();
+}
+
static void nativeSetLayer(JNIEnv* env, jobject surfaceObj, jint zorder) {
sp<SurfaceControl> surface(getSurfaceControl(env, surfaceObj));
if (surface == NULL) return;
@@ -819,6 +823,8 @@
(void*)nativeOpenTransaction },
{"nativeCloseTransaction", "()V",
(void*)nativeCloseTransaction },
+ {"nativeSetAnimationTransaction", "()V",
+ (void*)nativeSetAnimationTransaction },
{"nativeSetLayer", "(I)V",
(void*)nativeSetLayer },
{"nativeSetPosition", "(FF)V",
diff --git a/core/res/res/drawable-hdpi/ic_notify_wifidisplay.png b/core/res/res/drawable-hdpi/ic_notify_wifidisplay.png
new file mode 100644
index 0000000..35f27df
--- /dev/null
+++ b/core/res/res/drawable-hdpi/ic_notify_wifidisplay.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_notify_wifidisplay.png b/core/res/res/drawable-mdpi/ic_notify_wifidisplay.png
new file mode 100644
index 0000000..f9c8678
--- /dev/null
+++ b/core/res/res/drawable-mdpi/ic_notify_wifidisplay.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_notify_wifidisplay.png b/core/res/res/drawable-xhdpi/ic_notify_wifidisplay.png
new file mode 100644
index 0000000..4cc0ee8
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_notify_wifidisplay.png
Binary files differ
diff --git a/core/res/res/layout-land/keyguard_status_area.xml b/core/res/res/layout-land/keyguard_status_area.xml
index 78bf931..f562d9f 100644
--- a/core/res/res/layout-land/keyguard_status_area.xml
+++ b/core/res/res/layout-land/keyguard_status_area.xml
@@ -41,6 +41,8 @@
<TextView
android:id="@+id/alarm_status"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
android:layout_gravity="end"
android:layout_marginTop="28dp"
android:layout_marginEnd="@dimen/kg_status_line_font_right_margin"
@@ -53,6 +55,8 @@
<TextView
android:id="@+id/owner_info"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
android:layout_gravity="end"
android:layout_marginTop="4dp"
android:layout_marginEnd="@dimen/kg_status_line_font_right_margin"
@@ -64,6 +68,8 @@
<TextView
android:id="@+id/status1"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
android:layout_gravity="end"
android:layout_marginTop="4dp"
android:layout_marginEnd="@dimen/kg_status_line_font_right_margin"
@@ -75,6 +81,8 @@
<TextView
android:id="@+id/status_security_message"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
android:layout_gravity="center"
android:gravity="right"
android:layout_marginTop="12dp"
diff --git a/core/res/res/layout-port/keyguard_host_view.xml b/core/res/res/layout-port/keyguard_host_view.xml
index 20726d0..981fe6d 100644
--- a/core/res/res/layout-port/keyguard_host_view.xml
+++ b/core/res/res/layout-port/keyguard_host_view.xml
@@ -33,7 +33,8 @@
<com.android.internal.policy.impl.keyguard.KeyguardSecurityViewFlipper
android:id="@+id/view_flipper"
- android:layout_height="0dp"
+ android:layout_width="match_parent"
+ android:layout_height="0dip"
android:clipChildren="false"
android:clipToPadding="false"
android:layout_weight="1"
diff --git a/core/res/res/layout-port/keyguard_status_area.xml b/core/res/res/layout-port/keyguard_status_area.xml
index 00aac7b..c1f6aab 100644
--- a/core/res/res/layout-port/keyguard_status_area.xml
+++ b/core/res/res/layout-port/keyguard_status_area.xml
@@ -45,6 +45,8 @@
<TextView
android:id="@+id/alarm_status"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
android:layout_marginEnd="@dimen/kg_status_line_font_right_margin"
android:singleLine="true"
android:ellipsize="marquee"
@@ -56,6 +58,8 @@
<TextView
android:id="@+id/owner_info"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
android:layout_gravity="right"
android:layout_marginTop="4dp"
android:layout_marginEnd="@dimen/kg_status_line_font_right_margin"
@@ -67,6 +71,8 @@
<TextView
android:id="@+id/status1"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
android:layout_gravity="right"
android:layout_marginTop="4dp"
android:layout_marginEnd="@dimen/kg_status_line_font_right_margin"
@@ -78,6 +84,8 @@
<TextView
android:id="@+id/status_security_message"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
android:layout_gravity="right"
android:layout_marginTop="4dp"
android:layout_marginEnd="@dimen/kg_status_line_font_right_margin"
@@ -87,4 +95,4 @@
android:textSize="@dimen/kg_status_line_font_size"
/>
-</LinearLayout>
\ No newline at end of file
+</LinearLayout>
diff --git a/core/res/res/layout-sw600dp-port/keyguard_status_area.xml b/core/res/res/layout-sw600dp-port/keyguard_status_area.xml
index 679aebd..405ac14 100644
--- a/core/res/res/layout-sw600dp-port/keyguard_status_area.xml
+++ b/core/res/res/layout-sw600dp-port/keyguard_status_area.xml
@@ -41,6 +41,8 @@
<TextView
android:id="@+id/alarm_status"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
android:layout_gravity="end"
android:layout_marginTop="28dp"
android:layout_marginEnd="@dimen/kg_status_line_font_right_margin"
@@ -53,6 +55,8 @@
<TextView
android:id="@+id/owner_info"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
android:layout_gravity="end"
android:layout_marginTop="4dp"
android:layout_marginEnd="@dimen/kg_status_line_font_right_margin"
@@ -64,6 +68,8 @@
<TextView
android:id="@+id/status1"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
android:layout_gravity="end"
android:layout_marginTop="4dp"
android:layout_marginEnd="@dimen/kg_status_line_font_right_margin"
@@ -72,4 +78,4 @@
android:textAppearance="?android:attr/textAppearance"
android:textSize="@dimen/kg_status_line_font_size"
/>
-</LinearLayout>
\ No newline at end of file
+</LinearLayout>
diff --git a/core/res/res/layout/default_navigation.xml b/core/res/res/layout/default_navigation.xml
index b13103c..b216ded 100644
--- a/core/res/res/layout/default_navigation.xml
+++ b/core/res/res/layout/default_navigation.xml
@@ -18,6 +18,8 @@
-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/keyguard_click_area"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
android:gravity="center">
<!-- message area for security screen -->
diff --git a/core/res/res/layout/keyguard_password_view.xml b/core/res/res/layout/keyguard_password_view.xml
index ab8aa85..81916f7 100644
--- a/core/res/res/layout/keyguard_password_view.xml
+++ b/core/res/res/layout/keyguard_password_view.xml
@@ -53,6 +53,7 @@
since the backspace/IME switcher looks better inside -->
<LinearLayout
android:layout_gravity="center_vertical|fill_horizontal"
+ android:layout_height="wrap_content"
android:layout_width="match_parent"
android:orientation="horizontal"
android:background="#70000000"
diff --git a/core/res/res/layout/keyguard_sim_pin_view.xml b/core/res/res/layout/keyguard_sim_pin_view.xml
index 163dc15..ae59d1d 100644
--- a/core/res/res/layout/keyguard_sim_pin_view.xml
+++ b/core/res/res/layout/keyguard_sim_pin_view.xml
@@ -91,6 +91,7 @@
<!-- Numeric keyboard -->
<com.android.internal.widget.PasswordEntryKeyboardView android:id="@+id/keyboard"
android:layout_width="match_parent"
+ android:layout_height="wrap_content"
android:layout_marginStart="4dip"
android:layout_marginEnd="4dip"
android:paddingTop="4dip"
diff --git a/core/res/res/layout/keyguard_sim_puk_view.xml b/core/res/res/layout/keyguard_sim_puk_view.xml
index 6e45b0b..414806f 100644
--- a/core/res/res/layout/keyguard_sim_puk_view.xml
+++ b/core/res/res/layout/keyguard_sim_puk_view.xml
@@ -93,6 +93,7 @@
<!-- Numeric keyboard -->
<com.android.internal.widget.PasswordEntryKeyboardView android:id="@+id/keyboard"
android:layout_width="match_parent"
+ android:layout_height="wrap_content"
android:layout_marginStart="4dip"
android:layout_marginEnd="4dip"
android:paddingTop="4dip"
diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml
index 0f73ff5..3e8892b 100644
--- a/core/res/res/values-af/strings.xml
+++ b/core/res/res/values-af/strings.xml
@@ -1418,8 +1418,7 @@
<string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Jy het jou ontsluitpatroon <xliff:g id="NUMBER_0">%d</xliff:g> keer verkeerdelik geteken. Na nog <xliff:g id="NUMBER_1">%d</xliff:g> onsuksesvolle pogings, sal jy gevra word om jou tablet te ontsluit deur middel van \'n e-posrekening."\n\n" Probeer weer oor <xliff:g id="NUMBER_2">%d</xliff:g> sekondes."</string>
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Jy het jou ontsluitpatroon <xliff:g id="NUMBER_0">%d</xliff:g> keer verkeerdelik geteken. Na nog <xliff:g id="NUMBER_1">%d</xliff:g> onsuksesvolle pogings, sal jy gevra word om jou foon te ontsluit deur middel van \'n e-posrekening."\n\n" Probeer weer oor <xliff:g id="NUMBER_2">%d</xliff:g> sekondes."</string>
<string name="safe_media_volume_warning" product="default" msgid="7382971871993371648">"Moet volume bo veilige vlak verhoog word?"\n"Deur vir lang tydperke op hoë volume te luister, kan jou gehoor beskadig."</string>
- <!-- no translation found for continue_to_enable_accessibility (1626427372316070258) -->
- <skip />
+ <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"Hou aan met twee vingers inhou om toeganklikheid te aktiveer."</string>
<string name="accessibility_enabled" msgid="1381972048564547685">"Toeganklikheid geaktiveer."</string>
<string name="enable_accessibility_canceled" msgid="3833923257966635673">"Toeganklikheid gekanselleer."</string>
<string name="user_switched" msgid="3768006783166984410">"Huidige gebruiker <xliff:g id="NAME">%1$s</xliff:g> ."</string>
diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml
index f60ac3e..495c0e2 100644
--- a/core/res/res/values-am/strings.xml
+++ b/core/res/res/values-am/strings.xml
@@ -1418,8 +1418,7 @@
<string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"የመክፈቻ ስርዓተ ጥለቱን <xliff:g id="NUMBER_0">%d</xliff:g> ጊዜ በትክክል አልሳሉትም። ከ<xliff:g id="NUMBER_1">%d</xliff:g> ተጨማሪ ያልተሳኩ ሙከራዎች በኋላ የኢሜይል መለያ ተጠቅመው ጡባዊ ቱኮዎን እንዲከፍቱ ይጠየቃሉ።"\n\n" ከ<xliff:g id="NUMBER_2">%d</xliff:g> ከሰከንዶች በኋላ እንደገና ይሞክሩ።"</string>
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"የመክፈቻ ስርዓተ ጥለቱን <xliff:g id="NUMBER_0">%d</xliff:g> ጊዜ በትክክል አልሳሉትም። ከ<xliff:g id="NUMBER_1">%d</xliff:g> ተጨማሪ ያልተሳኩ ሙከራዎች በኋላ የኢሜይል መለያ ተጠቅመው ስልክዎን እንዲከፍቱ ይጠየቃሉ።"\n\n"እባክዎ ከ<xliff:g id="NUMBER_2">%d</xliff:g> ሰከንዶች በኋላ እንደገና ይሞክሩ።"</string>
<string name="safe_media_volume_warning" product="default" msgid="7382971871993371648">"ድምጽ አደጋ ከሌለው መጠን በላይ ይጨመር??"\n"ለረጅም ጊዜ በከፍተኛ ድምጽ መስማት የመስማት ችሎታዎን ሊጎዳይ ይችላል።"</string>
- <!-- no translation found for continue_to_enable_accessibility (1626427372316070258) -->
- <skip />
+ <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"ተደራሽነትን ለማንቃት ሁለት ጣቶችዎን ባሉበት ያቆዩዋቸው።"</string>
<string name="accessibility_enabled" msgid="1381972048564547685">"ተደራሽነት ነቅቷል።"</string>
<string name="enable_accessibility_canceled" msgid="3833923257966635673">"ተደራሽነት ተሰርዟል።"</string>
<string name="user_switched" msgid="3768006783166984410">"የአሁኑ ተጠቃሚ <xliff:g id="NAME">%1$s</xliff:g>።"</string>
diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml
index dfa8834..61ec74d 100644
--- a/core/res/res/values-ar/strings.xml
+++ b/core/res/res/values-ar/strings.xml
@@ -1418,8 +1418,7 @@
<string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"لقد رسمت نقش إلغاء التأمين بشكل غير صحيح <xliff:g id="NUMBER_0">%d</xliff:g> مرة. بعد إجراء <xliff:g id="NUMBER_1">%d</xliff:g> من المحاولات غير الناجحة الأخرى، ستطالَب بإلغاء تأمين الجهاز اللوحي باستخدام معلومات حساب بريد إلكتروني."\n\n" أعد المحاولة خلال <xliff:g id="NUMBER_2">%d</xliff:g> ثانية."</string>
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"لقد رسمت نقش إلغاء التأمين بشكل غير صحيح <xliff:g id="NUMBER_0">%d</xliff:g> مرة. بعد إجراء <xliff:g id="NUMBER_1">%d</xliff:g> من المحاولات غير الناجحة الأخرى، ستُطالب بإلغاء تأمين الهاتف باستخدام حساب بريد إلكتروني لإلغاء تأمين الهاتف."\n\n" أعد المحاولة خلال <xliff:g id="NUMBER_2">%d</xliff:g> ثانية."</string>
<string name="safe_media_volume_warning" product="default" msgid="7382971871993371648">"هل تريد رفع مستوى الصوت فوق المستوى الآمن؟"\n"قد يضر سماع صوت عالٍ لفترات طويلة بسمعك."</string>
- <!-- no translation found for continue_to_enable_accessibility (1626427372316070258) -->
- <skip />
+ <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"اضغط بإصبعين لأسفل مع الاستمرار لتمكين تسهيل الدخول."</string>
<string name="accessibility_enabled" msgid="1381972048564547685">"تم تمكين إمكانية الدخول."</string>
<string name="enable_accessibility_canceled" msgid="3833923257966635673">"تم إلغاء تسهيل الدخول."</string>
<string name="user_switched" msgid="3768006783166984410">"المستخدم الحالي <xliff:g id="NAME">%1$s</xliff:g>."</string>
diff --git a/core/res/res/values-be/strings.xml b/core/res/res/values-be/strings.xml
index 4403f97..dd16a34 100644
--- a/core/res/res/values-be/strings.xml
+++ b/core/res/res/values-be/strings.xml
@@ -1419,8 +1419,7 @@
<string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Вы няправільна ўвялі графічны ключ разблакiроўкi пэўную колькасць разоў: <xliff:g id="NUMBER_0">%d</xliff:g>. Пасля яшчэ некалькiх няўдалых спроб (<xliff:g id="NUMBER_1">%d</xliff:g>) вам будзе прапанавана разблакiраваць тэлефон, увайшоўшы ў Google."\n\n" Паўтарыце спробу праз <xliff:g id="NUMBER_2">%d</xliff:g> с."</string>
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Вы няправільна ўвялі графічны ключ разблакiроўкi пэўную колькасць разоў: <xliff:g id="NUMBER_0">%d</xliff:g>. Пасля яшчэ некалькiх няўдалых спроб (<xliff:g id="NUMBER_1">%d</xliff:g>) вам будзе прапанавана разблакiраваць тэлефон, увайшоўшы ў Google."\n\n" Паўтарыце спробу праз <xliff:g id="NUMBER_2">%d</xliff:g> с."</string>
<string name="safe_media_volume_warning" product="default" msgid="7382971871993371648">"Павялiчыць гук больш за рэкамендаваны ўзровень?"\n"Доўгае слуханне музыкi на вялiкай гучнасцi можа пашкодзiць ваш слых."</string>
- <!-- no translation found for continue_to_enable_accessibility (1626427372316070258) -->
- <skip />
+ <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"Утрымлiвайце два пальцы, каб уключыць доступ."</string>
<string name="accessibility_enabled" msgid="1381972048564547685">"Даступнасць уключана."</string>
<string name="enable_accessibility_canceled" msgid="3833923257966635673">"Даступнасць адменена."</string>
<string name="user_switched" msgid="3768006783166984410">"Бягучы карыстальнік <xliff:g id="NAME">%1$s</xliff:g>."</string>
diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml
index b46e30a..ad806db 100644
--- a/core/res/res/values-bg/strings.xml
+++ b/core/res/res/values-bg/strings.xml
@@ -1418,8 +1418,7 @@
<string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Начертахте неправилно фигурата си за отключване <xliff:g id="NUMBER_0">%d</xliff:g> пъти. След още <xliff:g id="NUMBER_1">%d</xliff:g> неуспешни опита ще бъдете помолени да отключите таблета посредством имейл адрес."\n\n" Опитайте отново след <xliff:g id="NUMBER_2">%d</xliff:g> секунди."</string>
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Начертахте неправилно фигурата си за отключване <xliff:g id="NUMBER_0">%d</xliff:g> пъти. След още <xliff:g id="NUMBER_1">%d</xliff:g> неуспешни опита ще бъдете помолени да отключите телефона посредством имейл адрес."\n\n" Опитайте отново след <xliff:g id="NUMBER_2">%d</xliff:g> секунди."</string>
<string name="safe_media_volume_warning" product="default" msgid="7382971871993371648">"Да се увеличи ли силата на звука над безопасното ниво?"\n"Продължителното слушане при висока сила на звука може да увреди слуха ви."</string>
- <!-- no translation found for continue_to_enable_accessibility (1626427372316070258) -->
- <skip />
+ <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"Продължете да натискате с два пръста, за да активирате функцията за достъпност."</string>
<string name="accessibility_enabled" msgid="1381972048564547685">"Достъпността е активирана."</string>
<string name="enable_accessibility_canceled" msgid="3833923257966635673">"Функцията за достъпност е анулирана."</string>
<string name="user_switched" msgid="3768006783166984410">"Текущ потребител <xliff:g id="NAME">%1$s</xliff:g>."</string>
diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml
index 501946b..6fa8b50 100644
--- a/core/res/res/values-ca/strings.xml
+++ b/core/res/res/values-ca/strings.xml
@@ -1418,8 +1418,7 @@
<string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Has dibuixat el patró de desbloqueig <xliff:g id="NUMBER_0">%d</xliff:g> vegades de manera incorrecta. Després de <xliff:g id="NUMBER_1">%d</xliff:g> intents incorrectes més, se\'t demanarà que desbloquegis la tauleta amb un compte de correu electrònic."\n\n" Torna-ho a provar d\'aquí a <xliff:g id="NUMBER_2">%d</xliff:g> segons."</string>
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Has dibuixat el patró de desbloqueig <xliff:g id="NUMBER_0">%d</xliff:g> vegades de manera incorrecta. Després de <xliff:g id="NUMBER_1">%d</xliff:g> intents incorrectes més, se\'t demanarà que desbloquegis el telèfon amb un compte de correu electrònic."\n\n" Torna-ho a provar d\'aquí a <xliff:g id="NUMBER_2">%d</xliff:g> segons."</string>
<string name="safe_media_volume_warning" product="default" msgid="7382971871993371648">"Vols augmentar el volum per sobre del nivell de seguretat?"\n"Escoltar música a un volum alt durant períodes llargs pot perjudicar l\'oïda."</string>
- <!-- no translation found for continue_to_enable_accessibility (1626427372316070258) -->
- <skip />
+ <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"Mantén premuts els dos dits per activar l\'accessibilitat."</string>
<string name="accessibility_enabled" msgid="1381972048564547685">"S\'ha activat l\'accessibilitat."</string>
<string name="enable_accessibility_canceled" msgid="3833923257966635673">"Accessibilitat cancel·lada."</string>
<string name="user_switched" msgid="3768006783166984410">"Usuari actual: <xliff:g id="NAME">%1$s</xliff:g>."</string>
diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml
index 7381366..5d43397 100644
--- a/core/res/res/values-cs/strings.xml
+++ b/core/res/res/values-cs/strings.xml
@@ -1418,8 +1418,7 @@
<string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Již <xliff:g id="NUMBER_0">%d</xliff:g>krát jste nesprávně nakreslili své heslo odemknutí. Po <xliff:g id="NUMBER_1">%d</xliff:g>dalších neúspěšných pokusech budete požádáni o odemčení tabletu pomocí e-mailového účtu."\n\n" Zkuste to znovu za <xliff:g id="NUMBER_2">%d</xliff:g> s."</string>
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Již <xliff:g id="NUMBER_0">%d</xliff:g>krát jste nesprávně nakreslili své heslo odemknutí. Po <xliff:g id="NUMBER_1">%d</xliff:g> dalších neúspěšných pokusech budete požádáni o odemčení telefonu pomocí e-mailového účtu."\n\n" Zkuste to znovu za <xliff:g id="NUMBER_2">%d</xliff:g> s."</string>
<string name="safe_media_volume_warning" product="default" msgid="7382971871993371648">"Chcete hlasitost zvýšit nad bezpečnou úroveň?"\n"Dlouhodobý poslech hlasitého zvuku může poškodit sluch."</string>
- <!-- no translation found for continue_to_enable_accessibility (1626427372316070258) -->
- <skip />
+ <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"Usnadnění zapnete dlouhým stisknutím dvěma prsty."</string>
<string name="accessibility_enabled" msgid="1381972048564547685">"Usnadnění přístupu je aktivováno."</string>
<string name="enable_accessibility_canceled" msgid="3833923257966635673">"Usnadnění zrušeno."</string>
<string name="user_switched" msgid="3768006783166984410">"Aktuální uživatel je <xliff:g id="NAME">%1$s</xliff:g>."</string>
diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml
index e14e7de..db09717 100644
--- a/core/res/res/values-da/strings.xml
+++ b/core/res/res/values-da/strings.xml
@@ -1418,8 +1418,7 @@
<string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Du har tegnet dit oplåsningsmønster forkert <xliff:g id="NUMBER_0">%d</xliff:g> gange. Efter <xliff:g id="NUMBER_1">%d</xliff:g> yderligere mislykkede forsøg vil du blive bedt om at låse din tablet op ved hjælp af en e-mailkonto"\n\n" Prøv igen om <xliff:g id="NUMBER_2">%d</xliff:g> sekunder."</string>
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Du har tegnet dit oplåsningsmønster forkert <xliff:g id="NUMBER_0">%d</xliff:g> gange. Efter <xliff:g id="NUMBER_1">%d</xliff:g> yderligere mislykkede forsøg til vil du blive bedt om at låse din telefon op ved hjælp af en e-mailkonto."\n\n" Prøv igen om <xliff:g id="NUMBER_2">%d</xliff:g> sekunder."</string>
<string name="safe_media_volume_warning" product="default" msgid="7382971871993371648">"Skal lydstyrken være over det sikre niveau?"\n"Du kan skade din hørelse ved at lytte ved høj lydstyrke i længere tid."</string>
- <!-- no translation found for continue_to_enable_accessibility (1626427372316070258) -->
- <skip />
+ <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"Hold fortsat to fingre nede for at aktivere tilgængelighed."</string>
<string name="accessibility_enabled" msgid="1381972048564547685">"Tilgængelighed aktiveret."</string>
<string name="enable_accessibility_canceled" msgid="3833923257966635673">"Tilgængelighed er annulleret."</string>
<string name="user_switched" msgid="3768006783166984410">"Nuværende bruger <xliff:g id="NAME">%1$s</xliff:g>."</string>
diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml
index c938ca5..d66665b 100644
--- a/core/res/res/values-de/strings.xml
+++ b/core/res/res/values-de/strings.xml
@@ -1418,8 +1418,7 @@
<string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Sie haben Ihr Entsperrungsmuster <xliff:g id="NUMBER_0">%d</xliff:g>-mal falsch gezeichnet. Nach <xliff:g id="NUMBER_1">%d</xliff:g> weiteren erfolglosen Versuchen werden Sie aufgefordert, Ihr Tablet mithilfe eines E-Mail-Kontos zu entsperren."\n\n" Versuchen Sie es in <xliff:g id="NUMBER_2">%d</xliff:g> Sekunden erneut."</string>
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Sie haben Ihr Entsperrungsmuster <xliff:g id="NUMBER_0">%d</xliff:g>-mal falsch gezeichnet. Nach <xliff:g id="NUMBER_1">%d</xliff:g> weiteren erfolglosen Versuchen werden Sie aufgefordert, Ihr Telefon mithilfe eines E-Mail-Kontos zu entsperren."\n\n" Versuchen Sie es in <xliff:g id="NUMBER_2">%d</xliff:g> Sekunden erneut."</string>
<string name="safe_media_volume_warning" product="default" msgid="7382971871993371648">"Lautstärke höher als Schwellenwert stellen?"\n"Wenn Sie über längere Zeiträume hinweg Musik in hoher Lautstärke hören, kann dies Ihr Gehör schädigen."</string>
- <!-- no translation found for continue_to_enable_accessibility (1626427372316070258) -->
- <skip />
+ <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"Drücken Sie mit zwei Fingern, um die Bedienungshilfen zu aktivieren."</string>
<string name="accessibility_enabled" msgid="1381972048564547685">"Bedienungshilfen aktiviert"</string>
<string name="enable_accessibility_canceled" msgid="3833923257966635673">"Bedienungshilfen abgebrochen"</string>
<string name="user_switched" msgid="3768006783166984410">"Aktueller Nutzer <xliff:g id="NAME">%1$s</xliff:g>"</string>
diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml
index 9ced98c..e55a272 100644
--- a/core/res/res/values-el/strings.xml
+++ b/core/res/res/values-el/strings.xml
@@ -1418,8 +1418,7 @@
<string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Σχεδιάσατε το μοτίβο ξεκλειδώματος εσφαλμένα <xliff:g id="NUMBER_0">%d</xliff:g> φορές. Μετά από <xliff:g id="NUMBER_1">%d</xliff:g> ανεπιτυχείς προσπάθειες ακόμη, θα σας ζητηθεί να ξεκλειδώσετε το tablet σας με τη χρήση ενός λογαριασμού ηλεκτρονικού ταχυδρομείου."\n\n" Δοκιμάστε να συνδεθείτε ξανά σε <xliff:g id="NUMBER_2">%d</xliff:g> δευτερόλεπτα."</string>
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Σχεδιάσατε το μοτίβο ξεκλειδώματος εσφαλμένα <xliff:g id="NUMBER_0">%d</xliff:g> φορές. Μετά από <xliff:g id="NUMBER_1">%d</xliff:g> ανεπιτυχείς προσπάθειες ακόμη, θα σας ζητηθεί να ξεκλειδώσετε το τηλέφωνό σας με τη χρήση ενός λογαριασμού ηλεκτρονικού ταχυδρομείου."\n\n" Δοκιμάστε ξανά σε <xliff:g id="NUMBER_2">%d</xliff:g> δευτερόλεπτα."</string>
<string name="safe_media_volume_warning" product="default" msgid="7382971871993371648">"Αύξηση έντασης ήχου πάνω από το επίπεδο ασφαλείας;"\n"Αν ακούτε μουσική σε υψηλή ένταση για μεγάλο χρονικό διάστημα ενδέχεται να προκληθεί βλάβη στην ακοή σας."</string>
- <!-- no translation found for continue_to_enable_accessibility (1626427372316070258) -->
- <skip />
+ <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"Αγγίξτε παρατεταμένα με δύο δάχτυλα για να ενεργοποιήσετε τη λειτουργία προσβασιμότητας."</string>
<string name="accessibility_enabled" msgid="1381972048564547685">"Ενεργοποιήθηκε η προσβασιμότητα."</string>
<string name="enable_accessibility_canceled" msgid="3833923257966635673">"Η λειτουργία προσβασιμότητας ακυρώθηκε."</string>
<string name="user_switched" msgid="3768006783166984410">"Τρέχων χρήστης <xliff:g id="NAME">%1$s</xliff:g>."</string>
diff --git a/core/res/res/values-en-rGB/strings.xml b/core/res/res/values-en-rGB/strings.xml
index 9011e9d..a96995a 100644
--- a/core/res/res/values-en-rGB/strings.xml
+++ b/core/res/res/values-en-rGB/strings.xml
@@ -1418,8 +1418,7 @@
<string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"You have incorrectly drawn your unlock pattern <xliff:g id="NUMBER_0">%d</xliff:g> times. After <xliff:g id="NUMBER_1">%d</xliff:g> more unsuccessful attempts, you will be asked to unlock your tablet using an email account."\n\n" Try again in <xliff:g id="NUMBER_2">%d</xliff:g> seconds."</string>
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"You have incorrectly drawn your unlock pattern <xliff:g id="NUMBER_0">%d</xliff:g> times. After <xliff:g id="NUMBER_1">%d</xliff:g> more unsuccessful attempts, you will be asked to unlock your phone using an email account."\n\n" Try again in <xliff:g id="NUMBER_2">%d</xliff:g> seconds."</string>
<string name="safe_media_volume_warning" product="default" msgid="7382971871993371648">"Raise volume above safe level?"\n"Listening at high volume for long periods may damage your hearing."</string>
- <!-- no translation found for continue_to_enable_accessibility (1626427372316070258) -->
- <skip />
+ <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"Keep holding down two fingers to enable accessibility."</string>
<string name="accessibility_enabled" msgid="1381972048564547685">"Accessibility enabled."</string>
<string name="enable_accessibility_canceled" msgid="3833923257966635673">"Accessibility cancelled."</string>
<string name="user_switched" msgid="3768006783166984410">"Current user <xliff:g id="NAME">%1$s</xliff:g>."</string>
diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml
index d0a1cd9..ef6962f 100644
--- a/core/res/res/values-es-rUS/strings.xml
+++ b/core/res/res/values-es-rUS/strings.xml
@@ -1418,8 +1418,7 @@
<string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Dibujaste incorrectamente tu patrón de desbloqueo <xliff:g id="NUMBER_0">%d</xliff:g> veces. Luego de <xliff:g id="NUMBER_1">%d</xliff:g> intentos incorrectos más, se te solicitará que desbloquees tu tableta mediante el uso de una cuenta de correo."\n\n" Vuelve a intentarlo en <xliff:g id="NUMBER_2">%d</xliff:g> segundos."</string>
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Dibujaste incorrectamente tu patrón de desbloqueo <xliff:g id="NUMBER_0">%d</xliff:g> veces. Luego de <xliff:g id="NUMBER_1">%d</xliff:g> intentos incorrectos más, se te solicitará que desbloquees tu dispositivo mediante el uso de una cuenta de correo."\n\n" Vuelve a intentarlo en <xliff:g id="NUMBER_2">%d</xliff:g> segundos."</string>
<string name="safe_media_volume_warning" product="default" msgid="7382971871993371648">"¿Aumentar el volumen por encima del nivel seguro?"\n"Si escuchas con el volumen alto durante períodos prolongados, puedes dañar tu audición."</string>
- <!-- no translation found for continue_to_enable_accessibility (1626427372316070258) -->
- <skip />
+ <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"Mantén presionado con dos dedos para activar la accesibilidad."</string>
<string name="accessibility_enabled" msgid="1381972048564547685">"Se activó la accesibilidad."</string>
<string name="enable_accessibility_canceled" msgid="3833923257966635673">"Se canceló la accesibilidad."</string>
<string name="user_switched" msgid="3768006783166984410">"Usuario actual: <xliff:g id="NAME">%1$s</xliff:g>"</string>
diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml
index b45f001..d41ce82 100644
--- a/core/res/res/values-es/strings.xml
+++ b/core/res/res/values-es/strings.xml
@@ -1418,8 +1418,7 @@
<string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Has fallado <xliff:g id="NUMBER_0">%d</xliff:g> veces al dibujar el patrón de desbloqueo. Si fallas otras <xliff:g id="NUMBER_1">%d</xliff:g> veces, deberás usar una cuenta de correo electrónico para desbloquear el tablet."\n\n" Inténtalo de nuevo en <xliff:g id="NUMBER_2">%d</xliff:g> segundos."</string>
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Has fallado <xliff:g id="NUMBER_0">%d</xliff:g> veces al dibujar el patrón de desbloqueo. Si fallas otras <xliff:g id="NUMBER_1">%d</xliff:g> veces, deberás usar una cuenta de correo electrónico para desbloquear el teléfono."\n\n" Inténtalo de nuevo en <xliff:g id="NUMBER_2">%d</xliff:g> segundos."</string>
<string name="safe_media_volume_warning" product="default" msgid="7382971871993371648">"¿Subir el volumen por encima del nivel de seguridad?"\n"Escuchar sonidos a alto volumen durante largos períodos de tiempo puede dañar tus oídos."</string>
- <!-- no translation found for continue_to_enable_accessibility (1626427372316070258) -->
- <skip />
+ <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"Mantén la pantalla pulsada con dos dedos para habilitar las funciones de accesibilidad."</string>
<string name="accessibility_enabled" msgid="1381972048564547685">"Accesibilidad habilitada"</string>
<string name="enable_accessibility_canceled" msgid="3833923257966635673">"Accesibilidad cancelada"</string>
<string name="user_switched" msgid="3768006783166984410">"Usuario actual: <xliff:g id="NAME">%1$s</xliff:g>"</string>
diff --git a/core/res/res/values-et/strings.xml b/core/res/res/values-et/strings.xml
index fbb9f3e..cf237dc 100644
--- a/core/res/res/values-et/strings.xml
+++ b/core/res/res/values-et/strings.xml
@@ -1418,8 +1418,7 @@
<string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Joonistasite oma avamismustri <xliff:g id="NUMBER_0">%d</xliff:g> korda valesti. Pärast veel <xliff:g id="NUMBER_1">%d</xliff:g> ebaõnnestunud katset palutakse teil tahvelarvuti avada meilikontoga."\n\n" Proovige uuesti <xliff:g id="NUMBER_2">%d</xliff:g> sekundi pärast."</string>
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Joonistasite oma avamismustri <xliff:g id="NUMBER_0">%d</xliff:g> korda valesti. Pärast veel <xliff:g id="NUMBER_1">%d</xliff:g> ebaõnnestunud katset palutakse teil telefon avada meilikontoga."\n\n" Proovige uuesti <xliff:g id="NUMBER_2">%d</xliff:g> sekundi pärast."</string>
<string name="safe_media_volume_warning" product="default" msgid="7382971871993371648">"Kas suurendada helitugevust üle ohutu piiri?"\n"Pikaajaline suure helitugevusega muusika kuulamine võib kahjustada kuulmist."</string>
- <!-- no translation found for continue_to_enable_accessibility (1626427372316070258) -->
- <skip />
+ <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"Hõlbustuse lubamiseks hoidke kaht sõrme all."</string>
<string name="accessibility_enabled" msgid="1381972048564547685">"Hõlbustus on lubatud."</string>
<string name="enable_accessibility_canceled" msgid="3833923257966635673">"Hõlbustus on tühistatud."</string>
<string name="user_switched" msgid="3768006783166984410">"Praegune kasutaja <xliff:g id="NAME">%1$s</xliff:g>."</string>
diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml
index ae0ca2b..a50947c 100644
--- a/core/res/res/values-fa/strings.xml
+++ b/core/res/res/values-fa/strings.xml
@@ -1418,8 +1418,7 @@
<string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"شما الگوی بازگشایی قفل خود را <xliff:g id="NUMBER_0">%d</xliff:g> بار اشتباه کشیدهاید. بعد از <xliff:g id="NUMBER_1">%d</xliff:g> تلاش ناموفق، از شما خواسته میشود که با استفاده از یک حساب ایمیل قفل رایانه لوحی خود را باز کنید."\n\n" لطفاً پس از <xliff:g id="NUMBER_2">%d</xliff:g> ثانیه دوباره امتحان کنید."</string>
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"شما الگوی بازگشایی قفل خود را <xliff:g id="NUMBER_0">%d</xliff:g> بار اشتباه کشیدهاید. پس از <xliff:g id="NUMBER_1">%d</xliff:g> تلاش ناموفق، از شما خواسته میشود که با استفاده از یک حساب ایمیل قفل تلفن خود را باز کنید."\n\n" لطفاً پس از <xliff:g id="NUMBER_2">%d</xliff:g> ثانیه دوباره امتحان کنید."</string>
<string name="safe_media_volume_warning" product="default" msgid="7382971871993371648">"صدا به بالاتر از سطح ایمن افزایش یابد؟"\n"گوش دادن به صدای بلند برای زمانهای طولانی میتواند به شنوایی شما آسیب برساند."</string>
- <!-- no translation found for continue_to_enable_accessibility (1626427372316070258) -->
- <skip />
+ <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"برای فعال کردن قابلیت دسترسی، با دو انگشت خود همچنان به طرف پایین فشار دهید."</string>
<string name="accessibility_enabled" msgid="1381972048564547685">"قابلیت دسترسی فعال شد."</string>
<string name="enable_accessibility_canceled" msgid="3833923257966635673">"قابلیت دسترسی لغو شد."</string>
<string name="user_switched" msgid="3768006783166984410">"کاربر کنونی <xliff:g id="NAME">%1$s</xliff:g>."</string>
diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml
index ae2a4cb..ef2f047 100644
--- a/core/res/res/values-fi/strings.xml
+++ b/core/res/res/values-fi/strings.xml
@@ -1418,8 +1418,7 @@
<string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Piirsit lukituksenpoistokuvion väärin <xliff:g id="NUMBER_0">%d</xliff:g> kertaa. Jos piirrät kuvion väärin vielä <xliff:g id="NUMBER_1">%d</xliff:g> kertaa, sinua pyydetään poistamaan tablet-laitteesi lukitus sähköpostitilin avulla."\n\n" Yritä uudelleen <xliff:g id="NUMBER_2">%d</xliff:g> sekunnin kuluttua."</string>
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Piirsit lukituksenpoistokuvion väärin <xliff:g id="NUMBER_0">%d</xliff:g> kertaa. Jos piirrät kuvion väärin vielä <xliff:g id="NUMBER_1">%d</xliff:g> kertaa, sinua pyydetään poistamaan puhelimesi lukitus sähköpostitilin avulla."\n\n" Yritä uudelleen <xliff:g id="NUMBER_2">%d</xliff:g> sekunnin kuluttua."</string>
<string name="safe_media_volume_warning" product="default" msgid="7382971871993371648">"Nostetaanko äänenvoimakkuus turvallista tasoa voimakkaammaksi?"\n"Jos kuuntelet suurella äänenvoimakkuudella pitkiä aikoja, kuulosi voi vahingoittua."</string>
- <!-- no translation found for continue_to_enable_accessibility (1626427372316070258) -->
- <skip />
+ <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"Ota esteettömyystila käyttöön koskettamalla pitkään kahdella sormella."</string>
<string name="accessibility_enabled" msgid="1381972048564547685">"Esteettömyystila käytössä."</string>
<string name="enable_accessibility_canceled" msgid="3833923257966635673">"Esteettömyystila peruutettu."</string>
<string name="user_switched" msgid="3768006783166984410">"Nykyinen käyttäjä: <xliff:g id="NAME">%1$s</xliff:g>."</string>
diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml
index aa4f91e..cefc2b8 100644
--- a/core/res/res/values-fr/strings.xml
+++ b/core/res/res/values-fr/strings.xml
@@ -1418,8 +1418,7 @@
<string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Vous avez dessiné un schéma de déverrouillage incorrect à <xliff:g id="NUMBER_0">%d</xliff:g> reprises. Si vous échouez encore <xliff:g id="NUMBER_1">%d</xliff:g> fois, vous devrez déverrouiller votre tablette à l\'aide d\'un compte de messagerie électronique."\n\n" Veuillez réessayer dans <xliff:g id="NUMBER_2">%d</xliff:g> secondes."</string>
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Vous avez dessiné un schéma de déverrouillage incorrect à <xliff:g id="NUMBER_0">%d</xliff:g> reprises. Si vous échouez encore <xliff:g id="NUMBER_1">%d</xliff:g> fois, vous devrez déverrouiller votre téléphone à l\'aide d\'un compte de messagerie électronique."\n\n" Veuillez réessayer dans <xliff:g id="NUMBER_2">%d</xliff:g> secondes."</string>
<string name="safe_media_volume_warning" product="default" msgid="7382971871993371648">"Augmenter le volume au-dessus du niveau de sécurité ?"\n"L\'écoute à un volume élevé pendant des périodes prolongées peut endommager votre audition."</string>
- <!-- no translation found for continue_to_enable_accessibility (1626427372316070258) -->
- <skip />
+ <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"Pour activer l\'accessibilité, appuyez de manière prolongée avec deux doigts."</string>
<string name="accessibility_enabled" msgid="1381972048564547685">"L\'accessibilité a bien été activée."</string>
<string name="enable_accessibility_canceled" msgid="3833923257966635673">"Accessibilité annulée."</string>
<string name="user_switched" msgid="3768006783166984410">"Utilisateur actuel : <xliff:g id="NAME">%1$s</xliff:g>"</string>
diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml
index d0f1dc5..6bf3d09 100644
--- a/core/res/res/values-hi/strings.xml
+++ b/core/res/res/values-hi/strings.xml
@@ -1262,7 +1262,7 @@
<string name="media_shared" product="nosdcard" msgid="5830814349250834225">"USB संग्रहण का उपयोग वर्तमान में एक कंप्यूटर द्वारा किया जा रहा है."</string>
<string name="media_shared" product="default" msgid="5706130568133540435">"SD कार्ड का उपयोग वर्तमान में एक कंप्यूटर द्वारा किया जा रहा है."</string>
<string name="media_unknown_state" msgid="729192782197290385">"बाह्य मीडिया अज्ञात स्थिति में है."</string>
- <string name="share" msgid="1778686618230011964">"शेयर करें"</string>
+ <string name="share" msgid="1778686618230011964">"साझा करें"</string>
<string name="find" msgid="4808270900322985960">"ढूंढें"</string>
<string name="websearch" msgid="4337157977400211589">"वेब खोज"</string>
<string name="find_next" msgid="5742124618942193978">"अगला ढूंढें"</string>
@@ -1418,8 +1418,7 @@
<string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"आपने अपने अनलॉक प्रतिमान को <xliff:g id="NUMBER_0">%d</xliff:g> बार गलत तरीके से आरेखित किया है. <xliff:g id="NUMBER_1">%d</xliff:g> और असफल प्रयासों के बाद, आपसे अपने टेबलेट को किसी ईमेल खाते के उपयोग से अनलॉक करने के लिए कहा जाएगा."\n\n" <xliff:g id="NUMBER_2">%d</xliff:g> सेकंड में पुन: प्रयास करें."</string>
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"आपने अपने अनलॉक प्रतिमान को <xliff:g id="NUMBER_0">%d</xliff:g> बार गलत तरीके से आरेखित किया है. <xliff:g id="NUMBER_1">%d</xliff:g> और असफल प्रयासों के बाद, आपसे अपने फ़ोन को किसी ईमेल खाते का उपयोग करके अनलॉक करने के लिए कहा जाएगा."\n\n" <xliff:g id="NUMBER_2">%d</xliff:g> सेकंड में पुन: प्रयास करें."</string>
<string name="safe_media_volume_warning" product="default" msgid="7382971871993371648">"वॉल्यूम को सुरक्षित स्तर से अधिक करें?"\n"अधिक देर तक उच्च वॉल्यूम पर सुनने से आपकी सुनने की क्षमता को नुकसान हो सकता है."</string>
- <!-- no translation found for continue_to_enable_accessibility (1626427372316070258) -->
- <skip />
+ <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"पहुंच-योग्यता को सक्षम करने के लिए दो अंगुलियों से नीचे दबाए रखें."</string>
<string name="accessibility_enabled" msgid="1381972048564547685">"पहुंच-योग्यता सक्षम कर दी है."</string>
<string name="enable_accessibility_canceled" msgid="3833923257966635673">"पहुंच-योग्यता रद्द की गई."</string>
<string name="user_switched" msgid="3768006783166984410">"वर्तमान उपयोगकर्ता <xliff:g id="NAME">%1$s</xliff:g>."</string>
diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml
index f223fa6..588960b 100644
--- a/core/res/res/values-hr/strings.xml
+++ b/core/res/res/values-hr/strings.xml
@@ -1418,8 +1418,7 @@
<string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Netočno ste iscrtali obrazac za otključavanje <xliff:g id="NUMBER_0">%d</xliff:g> puta. Nakon još ovoliko neuspješnih pokušaja: <xliff:g id="NUMBER_1">%d</xliff:g> morat ćete otključati tabletno računalo pomoću računa e-pošte."\n\n" Pokušajte ponovo za <xliff:g id="NUMBER_2">%d</xliff:g> s."</string>
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Netočno ste iscrtali obrazac za otključavanje <xliff:g id="NUMBER_0">%d</xliff:g> puta. Nakon još ovoliko neuspješnih pokušaja: <xliff:g id="NUMBER_1">%d</xliff:g> morat ćete otključati telefon pomoću računa e-pošte."\n\n" Pokušajte ponovo za <xliff:g id="NUMBER_2">%d</xliff:g> s."</string>
<string name="safe_media_volume_warning" product="default" msgid="7382971871993371648">"Pojačati iznad sigurne razine?"\n"Dulje slušanje preglasne glazbe može vam oštetiti sluh."</string>
- <!-- no translation found for continue_to_enable_accessibility (1626427372316070258) -->
- <skip />
+ <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"Nastavite držati s dva prsta kako biste omogućili pristupačnost."</string>
<string name="accessibility_enabled" msgid="1381972048564547685">"Dostupnost je omogućena."</string>
<string name="enable_accessibility_canceled" msgid="3833923257966635673">"Pristupačnost otkazana."</string>
<string name="user_switched" msgid="3768006783166984410">"Trenutačni korisnik <xliff:g id="NAME">%1$s</xliff:g>."</string>
diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml
index 3815c38..4645842 100644
--- a/core/res/res/values-hu/strings.xml
+++ b/core/res/res/values-hu/strings.xml
@@ -1418,8 +1418,7 @@
<string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"<xliff:g id="NUMBER_0">%d</xliff:g> alkalommal helytelenül rajzolta le a feloldási mintát. További <xliff:g id="NUMBER_1">%d</xliff:g> sikertelen kísérlet után egy e-mail fiók használatával kell feloldania a táblagépét."\n\n" Kérjük, próbálja újra <xliff:g id="NUMBER_2">%d</xliff:g> másodperc múlva."</string>
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"<xliff:g id="NUMBER_0">%d</xliff:g> alkalommal helytelenül rajzolta le a feloldási mintát. További <xliff:g id="NUMBER_1">%d</xliff:g> sikertelen kísérlet után egy e-mail fiók használatával kell feloldania a telefonját."\n\n" Kérjük, próbálja újra <xliff:g id="NUMBER_2">%d</xliff:g> másodperc múlva."</string>
<string name="safe_media_volume_warning" product="default" msgid="7382971871993371648">"A biztonságos szint fölé emeli a hangerőt?"\n"Ha hosszú ideig hangosan hallgatja a zenét, az károsíthatja a hallását."</string>
- <!-- no translation found for continue_to_enable_accessibility (1626427372316070258) -->
- <skip />
+ <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"Továbbra is tartsa lenyomva két ujját a hozzáférés engedélyezéséhez."</string>
<string name="accessibility_enabled" msgid="1381972048564547685">"Hozzáférés engedélyezve"</string>
<string name="enable_accessibility_canceled" msgid="3833923257966635673">"Hozzáférés megszakítva."</string>
<string name="user_switched" msgid="3768006783166984410">"<xliff:g id="NAME">%1$s</xliff:g> az aktuális felhasználó."</string>
diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml
index 17b4944..7b04c96 100644
--- a/core/res/res/values-in/strings.xml
+++ b/core/res/res/values-in/strings.xml
@@ -1418,8 +1418,7 @@
<string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Anda telah <xliff:g id="NUMBER_0">%d</xliff:g> kali salah menggambar pola pembuka kunci. Setelah <xliff:g id="NUMBER_1">%d</xliff:g> lagi upaya gagal, Anda akan diminta membuka kunci tablet menggunakan akun email."\n\n"Coba lagi dalam <xliff:g id="NUMBER_2">%d</xliff:g> detik."</string>
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Anda telah <xliff:g id="NUMBER_0">%d</xliff:g> kali salah menggambar pola pembuka kunci. Setelah <xliff:g id="NUMBER_1">%d</xliff:g> lagi upaya gagal, Anda akan diminta membuka kunci ponsel menggunakan akun email."\n\n"Coba lagi dalam <xliff:g id="NUMBER_2">%d</xliff:g> detik."</string>
<string name="safe_media_volume_warning" product="default" msgid="7382971871993371648">"Naikkan volume di atas tingkat aman?"\n"Mendengarkan volume tinggi dalam jangka waktu yang lama dapat merusak pendengaran Anda."</string>
- <!-- no translation found for continue_to_enable_accessibility (1626427372316070258) -->
- <skip />
+ <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"Tahan terus dua jari untuk mengaktifkan aksesibilitas."</string>
<string name="accessibility_enabled" msgid="1381972048564547685">"Aksesibilitas diaktifkan."</string>
<string name="enable_accessibility_canceled" msgid="3833923257966635673">"Aksesibilitas dibatalkan."</string>
<string name="user_switched" msgid="3768006783166984410">"Pengguna saat ini <xliff:g id="NAME">%1$s</xliff:g>."</string>
diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml
index 3a91039..5357009 100644
--- a/core/res/res/values-it/strings.xml
+++ b/core/res/res/values-it/strings.xml
@@ -1418,8 +1418,7 @@
<string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"<xliff:g id="NUMBER_0">%d</xliff:g> tentativi errati di inserimento della sequenza di sblocco. Dopo altri <xliff:g id="NUMBER_1">%d</xliff:g> tentativi falliti, ti verrà chiesto di sbloccare il tablet con un account email."\n\n" Riprova tra <xliff:g id="NUMBER_2">%d</xliff:g> secondi."</string>
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"<xliff:g id="NUMBER_0">%d</xliff:g> tentativi errati di inserimento della sequenza di sblocco. Dopo altri <xliff:g id="NUMBER_1">%d</xliff:g> tentativi falliti, ti verrà chiesto di sbloccare il telefono con un account email."\n\n" Riprova tra <xliff:g id="NUMBER_2">%d</xliff:g> secondi."</string>
<string name="safe_media_volume_warning" product="default" msgid="7382971871993371648">"Aumentare il volume oltre il livello di sicurezza?"\n"Ascoltare musica ad alto volume per lunghi periodi potrebbe danneggiare l\'udito."</string>
- <!-- no translation found for continue_to_enable_accessibility (1626427372316070258) -->
- <skip />
+ <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"Continua a tenere premuto con due dita per attivare l\'accessibilità."</string>
<string name="accessibility_enabled" msgid="1381972048564547685">"Accessibilità attivata."</string>
<string name="enable_accessibility_canceled" msgid="3833923257966635673">"Accessibilità annullata."</string>
<string name="user_switched" msgid="3768006783166984410">"Utente corrente <xliff:g id="NAME">%1$s</xliff:g>."</string>
diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml
index bd1ffb7..46ca017 100644
--- a/core/res/res/values-iw/strings.xml
+++ b/core/res/res/values-iw/strings.xml
@@ -1418,8 +1418,7 @@
<string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"שרטטת את קו ביטול הנעילה באופן שגוי <xliff:g id="NUMBER_0">%d</xliff:g> פעמים. לאחר <xliff:g id="NUMBER_1">%d</xliff:g> ניסיונות כושלים נוספים, תתבקש לבטל את נעילת הטאבלט באמצעות חשבון דוא\"ל."\n\n"נסה שוב בעוד <xliff:g id="NUMBER_2">%d</xliff:g> שניות."</string>
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"שרטטת את קו ביטול הנעילה באופן שגוי <xliff:g id="NUMBER_0">%d</xliff:g> פעמים. לאחר <xliff:g id="NUMBER_1">%d</xliff:g> ניסיונות כושלים נוספים, תתבקש לבטל את נעילת הטלפון באמצעות חשבון דוא\"ל."\n\n"נסה שוב בעוד <xliff:g id="NUMBER_2">%d</xliff:g> שניות."</string>
<string name="safe_media_volume_warning" product="default" msgid="7382971871993371648">"האם להעלות את עוצמת הקול מעל לרמה הבטוחה?"\n"האזנה בעוצמת קול גבוהה למשך זמן ארוך עלולה לפגוע בשמיעה."</string>
- <!-- no translation found for continue_to_enable_accessibility (1626427372316070258) -->
- <skip />
+ <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"המשך לגעת בשתי אצבעות כדי להפעיל נגישות."</string>
<string name="accessibility_enabled" msgid="1381972048564547685">"נגישות הופעלה."</string>
<string name="enable_accessibility_canceled" msgid="3833923257966635673">"נגישות בוטלה."</string>
<string name="user_switched" msgid="3768006783166984410">"המשתמש הנוכחי <xliff:g id="NAME">%1$s</xliff:g>."</string>
diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml
index 97a1675..d97753b 100644
--- a/core/res/res/values-ja/strings.xml
+++ b/core/res/res/values-ja/strings.xml
@@ -1418,8 +1418,7 @@
<string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"ロック解除パターンの入力を<xliff:g id="NUMBER_0">%d</xliff:g>回間違えました。あと<xliff:g id="NUMBER_1">%d</xliff:g>回間違えると、タブレットのロック解除にメールアカウントが必要になります。"\n\n"<xliff:g id="NUMBER_2">%d</xliff:g>秒以内にもう一度お試しください。"</string>
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"ロック解除パターンの入力を<xliff:g id="NUMBER_0">%d</xliff:g>回間違えました。あと<xliff:g id="NUMBER_1">%d</xliff:g>回間違えると、携帯端末のロック解除にメールアカウントが必要になります。"\n\n"<xliff:g id="NUMBER_2">%d</xliff:g>秒以内にもう一度お試しください。"</string>
<string name="safe_media_volume_warning" product="default" msgid="7382971871993371648">"安全レベルを超えるまで音量を上げますか?"\n"大音量で長時間聞き続けると、聴力を損なう恐れがあります。"</string>
- <!-- no translation found for continue_to_enable_accessibility (1626427372316070258) -->
- <skip />
+ <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"ユーザー補助機能を有効にするには2本の指で押し続けてください。"</string>
<string name="accessibility_enabled" msgid="1381972048564547685">"ユーザー補助が有効になりました。"</string>
<string name="enable_accessibility_canceled" msgid="3833923257966635673">"ユーザー補助をキャンセルしました。"</string>
<string name="user_switched" msgid="3768006783166984410">"現在のユーザーは<xliff:g id="NAME">%1$s</xliff:g>です。"</string>
diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml
index e10fd3f..332e320 100644
--- a/core/res/res/values-ko/strings.xml
+++ b/core/res/res/values-ko/strings.xml
@@ -1418,8 +1418,7 @@
<string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"잠금해제 패턴을 <xliff:g id="NUMBER_0">%d</xliff:g>회 잘못 그렸습니다. <xliff:g id="NUMBER_1">%d</xliff:g>회 더 실패하면 이메일 계정을 사용하여 태블릿을 잠금해제해야 합니다."\n\n" <xliff:g id="NUMBER_2">%d</xliff:g>초 후에 다시 시도해 주세요."</string>
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"잠금해제 패턴을 <xliff:g id="NUMBER_0">%d</xliff:g>회 잘못 그렸습니다. <xliff:g id="NUMBER_1">%d</xliff:g>회 더 실패하면 이메일 계정을 사용하여 휴대전화를 잠금해제해야 합니다."\n\n" <xliff:g id="NUMBER_2">%d</xliff:g>초 후에 다시 시도해 주세요."</string>
<string name="safe_media_volume_warning" product="default" msgid="7382971871993371648">"안전한 수준 이상으로 볼륨을 높이시겠습니까?"\n"높은 볼륨으로 장시간 청취하면 청력에 손상이 올 수 있습니다."</string>
- <!-- no translation found for continue_to_enable_accessibility (1626427372316070258) -->
- <skip />
+ <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"두 손가락으로 길게 누르면 접근성을 사용하도록 설정됩니다."</string>
<string name="accessibility_enabled" msgid="1381972048564547685">"접근성을 사용 설정했습니다."</string>
<string name="enable_accessibility_canceled" msgid="3833923257966635673">"접근성이 취소되었습니다."</string>
<string name="user_switched" msgid="3768006783166984410">"현재 사용자는 <xliff:g id="NAME">%1$s</xliff:g>님입니다."</string>
diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml
index ee0260a..1240d6c 100644
--- a/core/res/res/values-lt/strings.xml
+++ b/core/res/res/values-lt/strings.xml
@@ -1418,8 +1418,7 @@
<string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Netinkamai nupiešėte atrakinimo piešinį <xliff:g id="NUMBER_0">%d</xliff:g> k. Po dar <xliff:g id="NUMBER_1">%d</xliff:g> nesėkm. band. būsite paprašyti atrakinti planšetinį kompiuterį naudodami „Google“ prisijungimo duomenis."\n\n" Bandykite dar kartą po <xliff:g id="NUMBER_2">%d</xliff:g> sek."</string>
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Netinkamai nupiešėte atrakinimo piešinį <xliff:g id="NUMBER_0">%d</xliff:g> k. Po dar <xliff:g id="NUMBER_1">%d</xliff:g> nesėkm. band. būsite paprašyti atrakinti telefoną naudodami „Google“ prisijungimo duomenis."\n\n" Bandykite dar kartą po <xliff:g id="NUMBER_2">%d</xliff:g> sek."</string>
<string name="safe_media_volume_warning" product="default" msgid="7382971871993371648">"Padidinti garsumą viršijant saugų lygį?"\n"Ilgai klausantis dideliu garsumu gali sutrikti klausa."</string>
- <!-- no translation found for continue_to_enable_accessibility (1626427372316070258) -->
- <skip />
+ <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"Laikykite palietę dviem pirštais, kad įgalintumėte pritaikymo neįgaliesiems režimą."</string>
<string name="accessibility_enabled" msgid="1381972048564547685">"Pritaikymas neįgaliesiems įgalintas."</string>
<string name="enable_accessibility_canceled" msgid="3833923257966635673">"Pritaikymo neįgaliesiems režimas atšauktas."</string>
<string name="user_switched" msgid="3768006783166984410">"Dabartinis naudotojas: <xliff:g id="NAME">%1$s</xliff:g>."</string>
diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml
index dd26946..25c036b 100644
--- a/core/res/res/values-lv/strings.xml
+++ b/core/res/res/values-lv/strings.xml
@@ -1418,8 +1418,7 @@
<string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Jūs nepareizi norādījāt atbloķēšanas kombināciju <xliff:g id="NUMBER_0">%d</xliff:g> reizes. Pēc vēl <xliff:g id="NUMBER_1">%d</xliff:g> neveiksmīgiem mēģinājumiem planšetdators būs jāatbloķē, izmantojot e-pasta kontu."\n\n"Mēģiniet vēlreiz pēc <xliff:g id="NUMBER_2">%d</xliff:g> sekundēm."</string>
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Jūs nepareizi norādījāt atbloķēšanas kombināciju <xliff:g id="NUMBER_0">%d</xliff:g> reizes. Pēc vēl <xliff:g id="NUMBER_1">%d</xliff:g> neveiksmīgiem mēģinājumiem tālrunis būs jāatbloķē, izmantojot e-pasta kontu."\n\n"Mēģiniet vēlreiz pēc <xliff:g id="NUMBER_2">%d</xliff:g> sekundēm."</string>
<string name="safe_media_volume_warning" product="default" msgid="7382971871993371648">"Vai palielināt skaļumu virs drošības līmeņa?"\n"Ilgstoši klausoties skaņu lielā skaļumā, var tikt bojāta dzirde."</string>
- <!-- no translation found for continue_to_enable_accessibility (1626427372316070258) -->
- <skip />
+ <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"Lai iespējotu pieejamību, turiet nospiestus divus pirkstus."</string>
<string name="accessibility_enabled" msgid="1381972048564547685">"Pieejamības režīms ir iespējots."</string>
<string name="enable_accessibility_canceled" msgid="3833923257966635673">"Pieejamība ir atcelta."</string>
<string name="user_switched" msgid="3768006783166984410">"Pašreizējais lietotājs: <xliff:g id="NAME">%1$s</xliff:g>."</string>
diff --git a/core/res/res/values-ms/strings.xml b/core/res/res/values-ms/strings.xml
index 79eefef..920865b 100644
--- a/core/res/res/values-ms/strings.xml
+++ b/core/res/res/values-ms/strings.xml
@@ -1418,8 +1418,7 @@
<string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Anda telah tersilap melukis corak buka kunci sebanyak <xliff:g id="NUMBER_0">%d</xliff:g> kali. Selepas <xliff:g id="NUMBER_1">%d</xliff:g> lagi percubaan yang tidak berjaya, anda akan diminta membuka kunci tablet anda menggunakan log masuk Google anda."\n\n" Cuba lagi dalam <xliff:g id="NUMBER_2">%d</xliff:g> saat."</string>
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Anda telah tersilap lukis corak buka kunci sebanyak <xliff:g id="NUMBER_0">%d</xliff:g> kali. Selepas <xliff:g id="NUMBER_1">%d</xliff:g> lagi percubaan yang tidak berjaya, anda akan diminta membuka kunci telefon anda menggunakan log masuk Google anda."\n\n" Cuba lagi dalam <xliff:g id="NUMBER_2">%d</xliff:g> saat."</string>
<string name="safe_media_volume_warning" product="default" msgid="7382971871993371648">"Tingkatkan kelantangan di atas tahap selamat?"\n"Mendengar pada kelantangan tinggi untuk tempoh yang panjang boleh merosakkan pendengaran anda."</string>
- <!-- no translation found for continue_to_enable_accessibility (1626427372316070258) -->
- <skip />
+ <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"Teruskan menahan dengan dua jari untuk mendayakan kebolehcapaian."</string>
<string name="accessibility_enabled" msgid="1381972048564547685">"Kebolehcapaian didayakan."</string>
<string name="enable_accessibility_canceled" msgid="3833923257966635673">"Kebolehcapaian dibatalkan."</string>
<string name="user_switched" msgid="3768006783166984410">"Pengguna semasa <xliff:g id="NAME">%1$s</xliff:g>."</string>
diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml
index c10d7b4..78cc0e9 100644
--- a/core/res/res/values-nb/strings.xml
+++ b/core/res/res/values-nb/strings.xml
@@ -1418,8 +1418,7 @@
<string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Du har tegnet opplåsningsmønsteret feil <xliff:g id="NUMBER_0">%d</xliff:g> ganger. Etter ytterligere <xliff:g id="NUMBER_1">%d</xliff:g> gale forsøk, blir du bedt om å låse opp nettbrettet via en e-postkonto."\n\n" Prøv på nytt om <xliff:g id="NUMBER_2">%d</xliff:g> sekunder."</string>
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Du har tegnet opplåsningsmønsteret feil <xliff:g id="NUMBER_0">%d</xliff:g> ganger. Etter ytterligere <xliff:g id="NUMBER_1">%d</xliff:g> gale forsøk, blir du bedt om å låse opp telefonen via en e-postkonto."\n\n" Prøv på nytt om <xliff:g id="NUMBER_2">%d</xliff:g> sekunder."</string>
<string name="safe_media_volume_warning" product="default" msgid="7382971871993371648">"Vil du øke lydnivået over trygt nivå?"\n"Lytting på høyt lydnivå i lange perioder kan skade hørselen din."</string>
- <!-- no translation found for continue_to_enable_accessibility (1626427372316070258) -->
- <skip />
+ <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"Fortsett å holde nede to fingre for å aktivere tilgjengelighet."</string>
<string name="accessibility_enabled" msgid="1381972048564547685">"Tilgjengelighet er aktivert."</string>
<string name="enable_accessibility_canceled" msgid="3833923257966635673">"Tilgjengelighetstjenesten ble avbrutt."</string>
<string name="user_switched" msgid="3768006783166984410">"Gjeldende bruker: <xliff:g id="NAME">%1$s</xliff:g>."</string>
diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml
index 41037d6..df8ec78 100644
--- a/core/res/res/values-nl/strings.xml
+++ b/core/res/res/values-nl/strings.xml
@@ -1418,8 +1418,7 @@
<string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"U heeft uw ontgrendelingspatroon <xliff:g id="NUMBER_0">%d</xliff:g> keer onjuist getekend. Na nog eens <xliff:g id="NUMBER_1">%d</xliff:g> mislukte pogingen wordt u gevraagd uw tablet te ontgrendelen via een e-mailaccount."\n\n" Probeer het over <xliff:g id="NUMBER_2">%d</xliff:g> seconden opnieuw."</string>
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"U heeft uw ontgrendelingspatroon <xliff:g id="NUMBER_0">%d</xliff:g> keer onjuist getekend. Na nog eens <xliff:g id="NUMBER_1">%d</xliff:g> mislukte pogingen wordt u gevraagd uw telefoon te ontgrendelen via een e-mailaccount."\n\n" Probeer het over <xliff:g id="NUMBER_2">%d</xliff:g> seconden opnieuw."</string>
<string name="safe_media_volume_warning" product="default" msgid="7382971871993371648">"Wilt u het volume verhogen tot boven het aanbevolen geluidsniveau?"\n"Te lang luisteren op een te hoog volume kan leiden tot gehoorbeschadiging."</string>
- <!-- no translation found for continue_to_enable_accessibility (1626427372316070258) -->
- <skip />
+ <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"Blijf het scherm met twee vingers aanraken om toegankelijkheid in te schakelen."</string>
<string name="accessibility_enabled" msgid="1381972048564547685">"Toegankelijkheid ingeschakeld."</string>
<string name="enable_accessibility_canceled" msgid="3833923257966635673">"Toegankelijkheid geannuleerd."</string>
<string name="user_switched" msgid="3768006783166984410">"Huidige gebruiker <xliff:g id="NAME">%1$s</xliff:g>."</string>
diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml
index 7381794b..6fa3c51 100644
--- a/core/res/res/values-pl/strings.xml
+++ b/core/res/res/values-pl/strings.xml
@@ -1419,8 +1419,7 @@
<string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Po raz <xliff:g id="NUMBER_0">%d</xliff:g> nieprawidłowo narysowałeś wzór odblokowania. Po kolejnych <xliff:g id="NUMBER_1">%d</xliff:g> nieudanych próbach konieczne będzie odblokowanie tabletu przy użyciu danych logowania na konto Google."\n\n" Spróbuj ponownie za <xliff:g id="NUMBER_2">%d</xliff:g> s."</string>
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Po raz <xliff:g id="NUMBER_0">%d</xliff:g> nieprawidłowo narysowałeś wzór odblokowania. Po kolejnych <xliff:g id="NUMBER_1">%d</xliff:g> nieudanych próbach konieczne będzie odblokowanie telefonu przy użyciu danych logowania na konto Google."\n\n" Spróbuj ponownie za <xliff:g id="NUMBER_2">%d</xliff:g> s."</string>
<string name="safe_media_volume_warning" product="default" msgid="7382971871993371648">"Chcesz ustawić głośność powyżej bezpiecznego poziomu?"\n"Słuchanie przy dużym poziomie głośności przez dłuższy czas może doprowadzić do uszkodzenia słuchu."</string>
- <!-- no translation found for continue_to_enable_accessibility (1626427372316070258) -->
- <skip />
+ <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"Aby włączyć ułatwienia dostępu, przytrzymaj dwa palce."</string>
<string name="accessibility_enabled" msgid="1381972048564547685">"Włączono ułatwienia dostępu."</string>
<string name="enable_accessibility_canceled" msgid="3833923257966635673">"Ułatwienia dostępu zostały anulowane."</string>
<string name="user_switched" msgid="3768006783166984410">"Bieżący użytkownik: <xliff:g id="NAME">%1$s</xliff:g>."</string>
diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml
index 9a06263..1a22702 100644
--- a/core/res/res/values-pt-rPT/strings.xml
+++ b/core/res/res/values-pt-rPT/strings.xml
@@ -1418,8 +1418,7 @@
<string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Desenhou a sequência de desbloqueio incorretamente <xliff:g id="NUMBER_0">%d</xliff:g> vezes. Depois de mais <xliff:g id="NUMBER_1">%d</xliff:g> tentativas sem sucesso, ser-lhe-á pedido para desbloquear o tablet através de uma conta de email."\n\n" Tente novamente dentro de <xliff:g id="NUMBER_2">%d</xliff:g> segundos."</string>
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Desenhou a sequência de desbloqueio incorretamente <xliff:g id="NUMBER_0">%d</xliff:g> vezes. Depois de mais <xliff:g id="NUMBER_1">%d</xliff:g> tentativas sem sucesso, ser-lhe-á pedido para desbloquear o telemóvel através de uma conta de email."\n\n" Tente novamente dentro de <xliff:g id="NUMBER_2">%d</xliff:g> segundos."</string>
<string name="safe_media_volume_warning" product="default" msgid="7382971871993371648">"Aumentar o volume acima do nível de segurança?"\n"Ouvir em volume alto durante longos períodos de tempo poderá prejudicar a sua audição."</string>
- <!-- no translation found for continue_to_enable_accessibility (1626427372316070258) -->
- <skip />
+ <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"Mantenha os dois dedos para ativar a acessibilidade."</string>
<string name="accessibility_enabled" msgid="1381972048564547685">"Acessibilidade ativada."</string>
<string name="enable_accessibility_canceled" msgid="3833923257966635673">"Acessibilidade cancelada."</string>
<string name="user_switched" msgid="3768006783166984410">"<xliff:g id="NAME">%1$s</xliff:g> do utilizador atual."</string>
diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml
index 55f727a2..36f2ded 100644
--- a/core/res/res/values-pt/strings.xml
+++ b/core/res/res/values-pt/strings.xml
@@ -1418,8 +1418,7 @@
<string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Você desenhou sua sequência de desbloqueio incorretamente <xliff:g id="NUMBER_0">%d</xliff:g> vezes. Se fizer mais <xliff:g id="NUMBER_1">%d</xliff:g> tentativas incorretas, será solicitado que você use o login do Google para desbloquear seu tablet."\n\n" Tente novamente em <xliff:g id="NUMBER_2">%d</xliff:g> segundos."</string>
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Você desenhou sua sequência de desbloqueio incorretamente <xliff:g id="NUMBER_0">%d</xliff:g> vezes. Se fizer mais <xliff:g id="NUMBER_1">%d</xliff:g> tentativas incorretas, será solicitado que você use o login do Google para desbloquear."\n\n" Tente novamente em <xliff:g id="NUMBER_2">%d</xliff:g> segundos."</string>
<string name="safe_media_volume_warning" product="default" msgid="7382971871993371648">"Aumentar o volume acima do nível seguro?"\n"A audição em volume elevado por períodos longos pode prejudicar sua audição."</string>
- <!-- no translation found for continue_to_enable_accessibility (1626427372316070258) -->
- <skip />
+ <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"Mantenha pressionado com dois dedos para ativar a acessibilidade."</string>
<string name="accessibility_enabled" msgid="1381972048564547685">"Acessibilidade ativada."</string>
<string name="enable_accessibility_canceled" msgid="3833923257966635673">"Acessibilidade cancelada."</string>
<string name="user_switched" msgid="3768006783166984410">"Usuário atual <xliff:g id="NAME">%1$s</xliff:g>."</string>
diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml
index 81aaaa0..263e56b 100644
--- a/core/res/res/values-ro/strings.xml
+++ b/core/res/res/values-ro/strings.xml
@@ -1418,8 +1418,7 @@
<string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Aţi desenat incorect modelul pentru deblocare de <xliff:g id="NUMBER_0">%d</xliff:g> ori. După încă <xliff:g id="NUMBER_1">%d</xliff:g> încercări nereuşite, vi se va solicita să deblocaţi tableta cu ajutorul unui cont de e-mail."\n\n" Încercaţi din nou peste <xliff:g id="NUMBER_2">%d</xliff:g> (de) secunde."</string>
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Aţi desenat incorect modelul pentru deblocare de <xliff:g id="NUMBER_0">%d</xliff:g> ori. După încă <xliff:g id="NUMBER_1">%d</xliff:g> încercări nereuşite, vi se va solicita să deblocaţi telefonul cu ajutorul unui cont de e-mail."\n\n" Încercaţi din nou peste <xliff:g id="NUMBER_2">%d</xliff:g> (de) secunde."</string>
<string name="safe_media_volume_warning" product="default" msgid="7382971871993371648">"Ridicaţi volumul mai sus de nivelul sigur?"\n"Ascultarea la volum ridicat pe perioade lungi de timp vă poate afecta auzul."</string>
- <!-- no translation found for continue_to_enable_accessibility (1626427372316070258) -->
- <skip />
+ <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"Menţineţi două degete pe ecran pentru a activa accesibilitatea."</string>
<string name="accessibility_enabled" msgid="1381972048564547685">"S-a activat accesibilitatea."</string>
<string name="enable_accessibility_canceled" msgid="3833923257966635673">"Accesibilitatea a fost anulată"</string>
<string name="user_switched" msgid="3768006783166984410">"Utilizator curent: <xliff:g id="NAME">%1$s</xliff:g>."</string>
diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml
index 0b3d009..f008479 100644
--- a/core/res/res/values-ru/strings.xml
+++ b/core/res/res/values-ru/strings.xml
@@ -1418,8 +1418,7 @@
<string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Вы <xliff:g id="NUMBER_0">%d</xliff:g> раз неверно указали графический ключ. После <xliff:g id="NUMBER_1">%d</xliff:g> неверных попыток для разблокировки планшетного ПК потребуется войти в аккаунт Google."\n\n"Повтор через <xliff:g id="NUMBER_2">%d</xliff:g> сек."</string>
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Вы <xliff:g id="NUMBER_0">%d</xliff:g> раз неверно указали графический ключ. После <xliff:g id="NUMBER_1">%d</xliff:g> неверных попыток для разблокировки телефона потребуется войти в аккаунт Google."\n\n"Повтор через <xliff:g id="NUMBER_2">%d</xliff:g> сек."</string>
<string name="safe_media_volume_warning" product="default" msgid="7382971871993371648">"Увеличить громкость до небезопасного уровня?"\n"Долговременное прослушивание на такой громкости может повредить слух."</string>
- <!-- no translation found for continue_to_enable_accessibility (1626427372316070258) -->
- <skip />
+ <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"Чтобы включить специальные возможности, удерживайте пальцы на экране."</string>
<string name="accessibility_enabled" msgid="1381972048564547685">"Специальные возможности включены."</string>
<string name="enable_accessibility_canceled" msgid="3833923257966635673">"Специальные возможности не будут включены."</string>
<string name="user_switched" msgid="3768006783166984410">"Выбран аккаунт пользователя <xliff:g id="NAME">%1$s</xliff:g>."</string>
diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml
index e6a3b38..9be07a9 100644
--- a/core/res/res/values-sk/strings.xml
+++ b/core/res/res/values-sk/strings.xml
@@ -1418,8 +1418,7 @@
<string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"<xliff:g id="NUMBER_0">%d</xliff:g>-krát ste nesprávne nakreslili svoj bezpečnostný vzor. Po ďalších <xliff:g id="NUMBER_1">%d</xliff:g> neúspešných pokusoch sa zobrazí výzva na odomknutie tabletu pomocou e-mailového účtu."\n\n" Skúste to znova o <xliff:g id="NUMBER_2">%d</xliff:g> s."</string>
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"<xliff:g id="NUMBER_0">%d</xliff:g>-krát ste nesprávne nakreslili svoj bezpečnostný vzor. Po <xliff:g id="NUMBER_1">%d</xliff:g> ďalších neúspešných pokusoch sa zobrazí výzva na odomknutie telefónu pomocou e-mailového účtu."\n\n" Skúste to znova o <xliff:g id="NUMBER_2">%d</xliff:g> s."</string>
<string name="safe_media_volume_warning" product="default" msgid="7382971871993371648">"Chcete zvýšiť hlasitosť nad bezpečnú úroveň?"\n"Dlhodobé počúvanie pri vysokej hlasitosti môže viesť k poškodeniu vášho sluchu."</string>
- <!-- no translation found for continue_to_enable_accessibility (1626427372316070258) -->
- <skip />
+ <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"Zjednodušenie ovládania povolíte dlhým stlačením dvoma prstami."</string>
<string name="accessibility_enabled" msgid="1381972048564547685">"Zjednodušenie ovládania je povolené."</string>
<string name="enable_accessibility_canceled" msgid="3833923257966635673">"Zjednodušenie ovládania bolo zrušené."</string>
<string name="user_switched" msgid="3768006783166984410">"Aktuálny používateľ je <xliff:g id="NAME">%1$s</xliff:g>."</string>
diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml
index cdd8d11..42cf0af 100644
--- a/core/res/res/values-sl/strings.xml
+++ b/core/res/res/values-sl/strings.xml
@@ -1418,8 +1418,7 @@
<string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Vzorec za odklepanje ste <xliff:g id="NUMBER_0">%d</xliff:g>-krat napačno vnesli. Po nadaljnjih <xliff:g id="NUMBER_1">%d</xliff:g> neuspešnih poskusih boste pozvani, da tablični računalnik odklenete z e-poštnim računom."\n\n"Poskusite znova čez <xliff:g id="NUMBER_2">%d</xliff:g> s."</string>
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Vzorec za odklepanje ste <xliff:g id="NUMBER_0">%d</xliff:g>-krat napačno vnesli. Po nadaljnjih <xliff:g id="NUMBER_1">%d</xliff:g> neuspešnih poskusih boste pozvani, da odklenete telefon z Googlovimi podatki za prijavo."\n\n"Poskusite znova čez <xliff:g id="NUMBER_2">%d</xliff:g> s."</string>
<string name="safe_media_volume_warning" product="default" msgid="7382971871993371648">"Želite povečati glasnost nad varno raven?"\n"Dolgotrajna izpostavljenost glasnim tonom lahko poškoduje sluh."</string>
- <!-- no translation found for continue_to_enable_accessibility (1626427372316070258) -->
- <skip />
+ <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"Če želite omogočiti pripomočke za ljudi s posebnimi potrebami, na zaslonu pridržite z dvema prstoma."</string>
<string name="accessibility_enabled" msgid="1381972048564547685">"Pripomočki za ljudi s posebnimi potrebami so omogočeni."</string>
<string name="enable_accessibility_canceled" msgid="3833923257966635673">"Omogočanje pripomočkov za ljudi s posebnimi potrebami preklicano."</string>
<string name="user_switched" msgid="3768006783166984410">"Trenutni uporabnik <xliff:g id="NAME">%1$s</xliff:g>."</string>
diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml
index bfeb021..e69bd5d 100644
--- a/core/res/res/values-sr/strings.xml
+++ b/core/res/res/values-sr/strings.xml
@@ -1418,8 +1418,7 @@
<string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Нацртали сте шаблон за откључавање неисправно <xliff:g id="NUMBER_0">%d</xliff:g> пута. После још <xliff:g id="NUMBER_1">%d</xliff:g> неуспешна(их) покушаја, од вас ће бити затражено да откључате таблет помоћу налога е-поште."\n\n"Покушајте поново за <xliff:g id="NUMBER_2">%d</xliff:g> секунде(и)."</string>
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Нацртали сте шаблон за откључавање неисправно <xliff:g id="NUMBER_0">%d</xliff:g> пута. После још <xliff:g id="NUMBER_1">%d</xliff:g> неуспешна(их) покушаја, од вас ће бити затражено да откључате телефон помоћу налога е-поште."\n\n"Покушајте поново за <xliff:g id="NUMBER_2">%d</xliff:g> секунде(и)."</string>
<string name="safe_media_volume_warning" product="default" msgid="7382971871993371648">"Желите да појачате звук изнад безбедног нивоа?"\n"Ако дуже време слушате гласну музику, може доћи до оштећења слуха."</string>
- <!-- no translation found for continue_to_enable_accessibility (1626427372316070258) -->
- <skip />
+ <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"Држите са два прста да бисте омогућили приступачност."</string>
<string name="accessibility_enabled" msgid="1381972048564547685">"Приступачност је омогућена."</string>
<string name="enable_accessibility_canceled" msgid="3833923257966635673">"Приступачност је отказана."</string>
<string name="user_switched" msgid="3768006783166984410">"Актуелни корисник <xliff:g id="NAME">%1$s</xliff:g>."</string>
diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml
index 428e3d6..e295e2d 100644
--- a/core/res/res/values-sv/strings.xml
+++ b/core/res/res/values-sv/strings.xml
@@ -1418,8 +1418,7 @@
<string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Du har ritat ditt grafiska lösenord fel <xliff:g id="NUMBER_0">%d</xliff:g> gånger. Efter ytterligare <xliff:g id="NUMBER_1">%d</xliff:g> försök ombeds du låsa upp surfplattan med ett e-postkonto."\n\n" Försök igen om <xliff:g id="NUMBER_2">%d</xliff:g> sekunder."</string>
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Du har ritat ditt grafiska lösenord fel <xliff:g id="NUMBER_0">%d</xliff:g> gånger. Efter ytterligare <xliff:g id="NUMBER_1">%d</xliff:g> försök ombeds du låsa upp mobilen med hjälp av ett e-postkonto."\n\n" Försök igen om <xliff:g id="NUMBER_2">%d</xliff:g> sekunder."</string>
<string name="safe_media_volume_warning" product="default" msgid="7382971871993371648">"Vill du höja volymen över den säkra nivån?"\n"Om du lyssnar på hög volym under långa perioder kan din hörsel skadas."</string>
- <!-- no translation found for continue_to_enable_accessibility (1626427372316070258) -->
- <skip />
+ <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"Fortsätt trycka med två fingrar om du vill aktivera tillgänglighetsläget."</string>
<string name="accessibility_enabled" msgid="1381972048564547685">"Tillgänglighetsläget har aktiverats."</string>
<string name="enable_accessibility_canceled" msgid="3833923257966635673">"Byte till tillgänglighetsläge avbrutet."</string>
<string name="user_switched" msgid="3768006783166984410">"Nuvarande användare: <xliff:g id="NAME">%1$s</xliff:g>."</string>
diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml
index ddc4e04..b712146 100644
--- a/core/res/res/values-sw/strings.xml
+++ b/core/res/res/values-sw/strings.xml
@@ -1304,8 +1304,8 @@
<string name="keyboardview_keycode_shift" msgid="2270748814315147690">"Songa"</string>
<string name="keyboardview_keycode_enter" msgid="2985864015076059467">"Ingiza"</string>
<string name="activitychooserview_choose_application" msgid="2125168057199941199">"Chagua programu"</string>
- <string name="shareactionprovider_share_with" msgid="806688056141131819">"Gawa na"</string>
- <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Gawa na <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
+ <string name="shareactionprovider_share_with" msgid="806688056141131819">"Shiriki na"</string>
+ <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Shiriki na <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
<string name="content_description_sliding_handle" msgid="415975056159262248">"Utambo unaosonga. Gusa & shika"</string>
<string name="description_direction_up" msgid="7169032478259485180">"Sogeza juu kwa <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> ."</string>
<string name="description_direction_down" msgid="5087739728639014595">"Sogeza chini kwa <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
@@ -1418,8 +1418,7 @@
<string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Umekosea katika kuweka mchoro wako wa kufungua mara <xliff:g id="NUMBER_0">%d</xliff:g>. Baada ya majaribio <xliff:g id="NUMBER_1">%d</xliff:g> bila kufaulu, utaombwa kufungua kompyuta yako ndogo kwa kutumia akaunti yako ya barua pepe."\n\n" Jaribu tena baada ya sekunde <xliff:g id="NUMBER_2">%d</xliff:g>."</string>
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Umekosea kuchora mchoro wako wa kufungua mara <xliff:g id="NUMBER_0">%d</xliff:g>. Baada ya majaribio <xliff:g id="NUMBER_1">%d</xliff:g> yasiyofaulu, utaombwa kufungua simu yako kwa kutumia akaunti ya barua pepe."\n\n" Jaribu tena baada ya sekunde <xliff:g id="NUMBER_2">%d</xliff:g>."</string>
<string name="safe_media_volume_warning" product="default" msgid="7382971871993371648">"Ongeza sauti zaidi ya kiwango salama? "\n"Kusikiliza kwa sauti ya juu kwa muda mrefu kunaweza kuharibu uwezo wako wa kusikia."</string>
- <!-- no translation found for continue_to_enable_accessibility (1626427372316070258) -->
- <skip />
+ <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"Endelea kushikilia chini kwa vidole vyako viwili ili kuwezesha ufikivu."</string>
<string name="accessibility_enabled" msgid="1381972048564547685">"Ufikivu umewezeshwa."</string>
<string name="enable_accessibility_canceled" msgid="3833923257966635673">"Ufikivu umeghairiwa."</string>
<string name="user_switched" msgid="3768006783166984410">"Mtumiaji wa sasa <xliff:g id="NAME">%1$s</xliff:g>."</string>
diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml
index a619a36..3dc4bff 100644
--- a/core/res/res/values-th/strings.xml
+++ b/core/res/res/values-th/strings.xml
@@ -1418,8 +1418,7 @@
<string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"คุณวาดรูปแบบการปลดล็อกไม่ถูกต้อง <xliff:g id="NUMBER_0">%d</xliff:g> ครั้งแล้ว หากทำไม่สำเร็จอีก <xliff:g id="NUMBER_1">%d</xliff:g> ครั้ง ระบบจะขอให้คุณปลดล็อกแท็บเล็ตโดยใช้บัญชีอีเมล"\n\n" โปรดลองอีกครั้งใน <xliff:g id="NUMBER_2">%d</xliff:g> วินาที"</string>
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"คุณวาดรูปแบบการปลดล็อกไม่ถูกต้อง <xliff:g id="NUMBER_0">%d</xliff:g> ครั้งแล้ว หากทำไม่สำเร็จอีก <xliff:g id="NUMBER_1">%d</xliff:g> ครั้ง ระบบจะขอให้คุณปลดล็อกโทรศัพท์โดยใช้ับัญชีอีเมล"\n\n" โปรดลองอีกครั้งในอีก <xliff:g id="NUMBER_2">%d</xliff:g> วินาที"</string>
<string name="safe_media_volume_warning" product="default" msgid="7382971871993371648">"เพิ่มระดับเสียงจนเกินระดับที่ปลอดภัยหรือไม่"\n"การฟังเสียงดังเป็นเวลานานอาจทำให้การได้ยินของคุณบกพร่องได้"</string>
- <!-- no translation found for continue_to_enable_accessibility (1626427372316070258) -->
- <skip />
+ <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"ใช้สองนิ้วแตะค้างไว้เพื่อเปิดใช้งานการเข้าถึง"</string>
<string name="accessibility_enabled" msgid="1381972048564547685">"เปิดใช้งานการเข้าถึงแล้ว"</string>
<string name="enable_accessibility_canceled" msgid="3833923257966635673">"ยกเลิกการเข้าถึงแล้ว"</string>
<string name="user_switched" msgid="3768006783166984410">"ผู้ใช้ปัจจุบัน <xliff:g id="NAME">%1$s</xliff:g>"</string>
diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml
index cfe58c7..201d77b 100644
--- a/core/res/res/values-tl/strings.xml
+++ b/core/res/res/values-tl/strings.xml
@@ -1418,8 +1418,7 @@
<string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Naguhit mo nang hindi tama ang iyong pattern sa pag-unlock nang <xliff:g id="NUMBER_0">%d</xliff:g> (na) beses. Pagkatapos ng <xliff:g id="NUMBER_1">%d</xliff:g> pang hindi matagumpay na pagtatangka, hihilingin sa iyong i-unlock ang tablet mo gamit ang isang email account."\n\n" Subukang muli sa loob ng <xliff:g id="NUMBER_2">%d</xliff:g> (na) segundo."</string>
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Naguhit mo nang hindi tama ang iyong pattern sa pag-unlock nang <xliff:g id="NUMBER_0">%d</xliff:g> (na) beses. Pagkatapos ng <xliff:g id="NUMBER_1">%d</xliff:g> pang hindi matagumpay na pagtatangka, hihilingin sa iyong i-unlock ang telepono mo gamit ang isang email account."\n\n" Subukang muli sa loob ng <xliff:g id="NUMBER_2">%d</xliff:g> (na) segundo."</string>
<string name="safe_media_volume_warning" product="default" msgid="7382971871993371648">"Lakasan ang volume nang lagpas sa ligtas na antas?"\n"Maaaring mapinsala ng pakikinig sa malakas na volume sa loob ng mahahabang panahon ang iyong pandinig."</string>
- <!-- no translation found for continue_to_enable_accessibility (1626427372316070258) -->
- <skip />
+ <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"Panatilihing nakapindot nang matagal ang iyong dalawang daliri upang paganahin ang pagiging naa-access."</string>
<string name="accessibility_enabled" msgid="1381972048564547685">"Pinagana ang accessibility."</string>
<string name="enable_accessibility_canceled" msgid="3833923257966635673">"Nakansela ang pagiging naa-access."</string>
<string name="user_switched" msgid="3768006783166984410">"Kasalukuyang user <xliff:g id="NAME">%1$s</xliff:g>."</string>
diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml
index 2c9407b..fd59e41 100644
--- a/core/res/res/values-tr/strings.xml
+++ b/core/res/res/values-tr/strings.xml
@@ -1418,8 +1418,7 @@
<string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Kilit açma deseninizi <xliff:g id="NUMBER_0">%d</xliff:g> kez yanlış çizdiniz. <xliff:g id="NUMBER_1">%d</xliff:g> başarısız denemeden sonra, tabletinizi bir e-posta hesabı kullanarak açmanız istenir."\n\n" <xliff:g id="NUMBER_2">%d</xliff:g> saniye içinde tekrar deneyin."</string>
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Kilit açma deseninizi <xliff:g id="NUMBER_0">%d</xliff:g> kez yanlış çizdiniz. <xliff:g id="NUMBER_1">%d</xliff:g> başarısız denemeden sonra telefonunuzu bir e-posta hesabı kullanarak açmanız istenir."\n\n" <xliff:g id="NUMBER_2">%d</xliff:g> saniye içinde tekrar deneyin."</string>
<string name="safe_media_volume_warning" product="default" msgid="7382971871993371648">"Ses düzeyi güvenli seviyenin üzerine çıkarılsın mı?"\n"Yüksek sesle uzun süre dinlemek işitme yetinize zarar verebilir."</string>
- <!-- no translation found for continue_to_enable_accessibility (1626427372316070258) -->
- <skip />
+ <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"Erişilebilirliği etkinleştirmek için iki parmağınızı basılı tutmaya devam edin."</string>
<string name="accessibility_enabled" msgid="1381972048564547685">"Erişilebilirlik etkinleştirildi."</string>
<string name="enable_accessibility_canceled" msgid="3833923257966635673">"Erişilebilirlik iptal edildi."</string>
<string name="user_switched" msgid="3768006783166984410">"Geçerli kullanıcı: <xliff:g id="NAME">%1$s</xliff:g>."</string>
diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml
index 3072cb9..5547f56 100644
--- a/core/res/res/values-uk/strings.xml
+++ b/core/res/res/values-uk/strings.xml
@@ -1418,8 +1418,7 @@
<string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Ключ розблокування неправильно намальовано стільки разів: <xliff:g id="NUMBER_0">%d</xliff:g>. У вас є ще стільки спроб: <xliff:g id="NUMBER_1">%d</xliff:g>. У разі невдачі з’явиться запит розблокувати планшетний ПК за допомогою облікового запису електронної пошти."\n\n" Повторіть спробу через <xliff:g id="NUMBER_2">%d</xliff:g> сек."</string>
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Ключ розблокування неправильно намальовано стільки разів: <xliff:g id="NUMBER_0">%d</xliff:g>. У вас є ще стільки спроб: <xliff:g id="NUMBER_1">%d</xliff:g>. У разі невдачі з’явиться запит розблокувати телефон за допомогою облікового запису електронної пошти."\n\n" Повторіть спробу через <xliff:g id="NUMBER_2">%d</xliff:g> сек."</string>
<string name="safe_media_volume_warning" product="default" msgid="7382971871993371648">"Збільшити гучність понад безпечний рівень?"\n"Надто гучне прослуховування впродовж тривалого періоду може пошкодити слух."</string>
- <!-- no translation found for continue_to_enable_accessibility (1626427372316070258) -->
- <skip />
+ <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"Утримуйте двома пальцями, щоб увімкнути доступність."</string>
<string name="accessibility_enabled" msgid="1381972048564547685">"Доступність увімкнено."</string>
<string name="enable_accessibility_canceled" msgid="3833923257966635673">"Доступність скасовано."</string>
<string name="user_switched" msgid="3768006783166984410">"Поточний користувач: <xliff:g id="NAME">%1$s</xliff:g>."</string>
diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml
index 3dbe71b..df5d184 100644
--- a/core/res/res/values-vi/strings.xml
+++ b/core/res/res/values-vi/strings.xml
@@ -1418,8 +1418,7 @@
<string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Bạn đã <xliff:g id="NUMBER_0">%d</xliff:g> lần vẽ không chính xác hình mở khóa của mình. Sau <xliff:g id="NUMBER_1">%d</xliff:g> lần thử không thành công nữa, bạn sẽ được yêu cầu mở khóa máy tính bảng bằng tài khoản email."\n\n" Vui lòng thử lại sau <xliff:g id="NUMBER_2">%d</xliff:g> giây."</string>
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Bạn đã <xliff:g id="NUMBER_0">%d</xliff:g> lần vẽ không chính xác hình mở khóa của mình. Sau <xliff:g id="NUMBER_1">%d</xliff:g> lần thử không thành công nữa, bạn sẽ được yêu cầu mở khóa điện thoại bằng tài khoản email."\n\n" Vui lòng thử lại sau <xliff:g id="NUMBER_2">%d</xliff:g> giây."</string>
<string name="safe_media_volume_warning" product="default" msgid="7382971871993371648">"Tăng âm lượng trên mức an toàn?"\n"Nghe ở âm lượng cao trong thời gian dài có thể gây hại cho thính giác của bạn."</string>
- <!-- no translation found for continue_to_enable_accessibility (1626427372316070258) -->
- <skip />
+ <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"Tiếp tục giữ hai ngón tay để bật trợ năng."</string>
<string name="accessibility_enabled" msgid="1381972048564547685">"Trợ năng đã được bật."</string>
<string name="enable_accessibility_canceled" msgid="3833923257966635673">"Đã hủy trợ năng."</string>
<string name="user_switched" msgid="3768006783166984410">"Người dùng hiện tại <xliff:g id="NAME">%1$s</xliff:g>."</string>
diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml
index ea55480..d4c8ac0 100644
--- a/core/res/res/values-zh-rCN/strings.xml
+++ b/core/res/res/values-zh-rCN/strings.xml
@@ -777,7 +777,7 @@
<string name="lockscreen_transport_pause_description" msgid="7659088786780128001">"“暂停”按钮"</string>
<string name="lockscreen_transport_play_description" msgid="5888422938351019426">"“播放”按钮"</string>
<string name="lockscreen_transport_stop_description" msgid="4562318378766987601">"“停止”按钮"</string>
- <string name="emergency_calls_only" msgid="6733978304386365407">"只能使用紧急呼救"</string>
+ <string name="emergency_calls_only" msgid="6733978304386365407">"只能拨打紧急呼救电话"</string>
<string name="lockscreen_network_locked_message" msgid="143389224986028501">"网络已锁定"</string>
<string name="lockscreen_sim_puk_locked_message" msgid="7441797339976230">"SIM 卡已用 PUK 码锁定"</string>
<string name="lockscreen_sim_puk_locked_instructions" msgid="8127916255245181063">"请参阅《用户指南》或与客服人员联系。"</string>
@@ -1418,8 +1418,7 @@
<string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"您已经 <xliff:g id="NUMBER_0">%d</xliff:g> 次错误地绘制了解锁图案。如果再尝试 <xliff:g id="NUMBER_1">%d</xliff:g> 次后仍不成功,系统就会要求您使用自己的电子邮件帐户解锁平板电脑。"\n\n"请在 <xliff:g id="NUMBER_2">%d</xliff:g> 秒后重试。"</string>
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"您已经 <xliff:g id="NUMBER_0">%d</xliff:g> 次错误地绘制了解锁图案。如果再尝试 <xliff:g id="NUMBER_1">%d</xliff:g> 次后仍不成功,系统就会要求您使用自己的电子邮件帐户解锁手机。"\n\n"请在 <xliff:g id="NUMBER_2">%d</xliff:g> 秒后重试。"</string>
<string name="safe_media_volume_warning" product="default" msgid="7382971871993371648">"将音量调高到安全级别以上?"\n"长时间聆听高音量可能会损伤听力。"</string>
- <!-- no translation found for continue_to_enable_accessibility (1626427372316070258) -->
- <skip />
+ <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"持续按住双指即可启用辅助功能。"</string>
<string name="accessibility_enabled" msgid="1381972048564547685">"辅助功能已启用。"</string>
<string name="enable_accessibility_canceled" msgid="3833923257966635673">"已取消辅助功能。"</string>
<string name="user_switched" msgid="3768006783166984410">"当前用户是<xliff:g id="NAME">%1$s</xliff:g>。"</string>
diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml
index 3301945..12c7f41 100644
--- a/core/res/res/values-zh-rTW/strings.xml
+++ b/core/res/res/values-zh-rTW/strings.xml
@@ -1418,8 +1418,7 @@
<string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"您的解鎖圖形已畫錯 <xliff:g id="NUMBER_0">%d</xliff:g> 次,如果再嘗試 <xliff:g id="NUMBER_1">%d</xliff:g> 次仍未成功,系統就會要求您透過電子郵件帳戶解除平板電腦的鎖定狀態。"\n\n"請在 <xliff:g id="NUMBER_2">%d</xliff:g> 秒後再試一次。"</string>
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"您的解鎖圖形已畫錯 <xliff:g id="NUMBER_0">%d</xliff:g> 次,如果再嘗試 <xliff:g id="NUMBER_1">%d</xliff:g> 次仍未成功,系統就會要求您透過電子郵件帳戶解除手機的鎖定狀態。"\n\n"請在 <xliff:g id="NUMBER_2">%d</xliff:g> 秒後再試一次。"</string>
<string name="safe_media_volume_warning" product="default" msgid="7382971871993371648">"要將音量調高到安全等級以上嗎?"\n"長時間聆聽偏高音量可能會損害您的聽力。"</string>
- <!-- no translation found for continue_to_enable_accessibility (1626427372316070258) -->
- <skip />
+ <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"持續用兩指按住即可啟用協助工具。"</string>
<string name="accessibility_enabled" msgid="1381972048564547685">"協助工具已啟用。"</string>
<string name="enable_accessibility_canceled" msgid="3833923257966635673">"協助工具已取消。"</string>
<string name="user_switched" msgid="3768006783166984410">"目前的使用者是 <xliff:g id="NAME">%1$s</xliff:g>。"</string>
diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml
index ef48346..75142fb 100644
--- a/core/res/res/values-zu/strings.xml
+++ b/core/res/res/values-zu/strings.xml
@@ -1418,8 +1418,7 @@
<string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Udwebe ngokungalungile iphathini yakho yokuvula izikhathi ezingu-<xliff:g id="NUMBER_0">%d</xliff:g>. Emva <xliff:g id="NUMBER_1">%d</xliff:g> kweminye imizamo engaphumelelanga, uzocelwa ukuvula ithebhulethi yakho usebenzisa ukungena ngemvume kwi-Google."\n\n" Sicela uzame futhi kwengu-<xliff:g id="NUMBER_2">%d</xliff:g> imizuzwana."</string>
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Ukulayisha ungenisa iphathini yakho yokuvula ngendlela engalungile izikhathi ezi-<xliff:g id="NUMBER_0">%d</xliff:g> Emva kweminye imizamo engu-<xliff:g id="NUMBER_1">%d</xliff:g>, uzocelwa ukuvula ifoni yakho usebenzisa ukungena ngemvume ku-Google"\n\n" Zame futhi emumva kwengu- <xliff:g id="NUMBER_2">%d</xliff:g> imizuzwana."</string>
<string name="safe_media_volume_warning" product="default" msgid="7382971871993371648">"Khulisa ivolomu ngaphezu kweleveli yokuphepha?"\n"Ukulalela ngevolomu ephezulu izikhathi ezide kungalimaza ukuzwa kwakho."</string>
- <!-- no translation found for continue_to_enable_accessibility (1626427372316070258) -->
- <skip />
+ <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"Gcina ucindezele iminwe yakho emibili ukuze unike amandla ukufinyelela."</string>
<string name="accessibility_enabled" msgid="1381972048564547685">"Ukufinyelela kunikwe amandla."</string>
<string name="enable_accessibility_canceled" msgid="3833923257966635673">"Ukufinyelela kukhanseliwe."</string>
<string name="user_switched" msgid="3768006783166984410">"Umsebenzisi wamanje <xliff:g id="NAME">%1$s</xliff:g>."</string>
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 72de22c..f8dbd84 100755
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -3821,6 +3821,13 @@
<!-- Title text to show within the overlay. [CHAR LIMIT=50] -->
<string name="display_manager_overlay_display_title"><xliff:g id="name">%1$s</xliff:g>: <xliff:g id="width">%2$d</xliff:g>x<xliff:g id="height">%3$d</xliff:g>, <xliff:g id="dpi">%4$d</xliff:g> dpi</string>
+ <!-- Title of the notification to indicate an active wifi display connection. [CHAR LIMIT=50] -->
+ <string name="wifi_display_notification_title">Wireless display is connected</string>
+ <!-- Message of the notification to indicate an active wifi display connection. [CHAR LIMIT=80] -->
+ <string name="wifi_display_notification_message">This screen is showing on another device</string>
+ <!-- Label of a button to disconnect an active wifi display connection. [CHAR LIMIT=25] -->
+ <string name="wifi_display_notification_disconnect">Disconnect</string>
+
<!-- Keyguard strings -->
<!-- Label shown on emergency call button in keyguard -->
<string name="kg_emergency_call_label">Emergency call</string>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index e76b67b..b3af161 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -1486,6 +1486,7 @@
<java-symbol type="bool" name="show_ongoing_ime_switcher" />
<java-symbol type="color" name="config_defaultNotificationColor" />
<java-symbol type="drawable" name="ic_notification_ime_default" />
+ <java-symbol type="drawable" name="ic_notify_wifidisplay" />
<java-symbol type="drawable" name="stat_notify_car_mode" />
<java-symbol type="drawable" name="stat_notify_disabled" />
<java-symbol type="drawable" name="stat_notify_disk_full" />
@@ -1621,6 +1622,9 @@
<java-symbol type="string" name="vpn_lockdown_error" />
<java-symbol type="string" name="vpn_lockdown_reset" />
<java-symbol type="string" name="wallpaper_binding_label" />
+ <java-symbol type="string" name="wifi_display_notification_title" />
+ <java-symbol type="string" name="wifi_display_notification_message" />
+ <java-symbol type="string" name="wifi_display_notification_disconnect" />
<java-symbol type="style" name="Theme.Dialog.AppError" />
<java-symbol type="style" name="Theme.Toast" />
<java-symbol type="xml" name="storage_list" />
diff --git a/core/tests/ConnectivityManagerTest/AndroidManifest.xml b/core/tests/ConnectivityManagerTest/AndroidManifest.xml
index 05f8b39..1bbc7df 100644
--- a/core/tests/ConnectivityManagerTest/AndroidManifest.xml
+++ b/core/tests/ConnectivityManagerTest/AndroidManifest.xml
@@ -72,5 +72,6 @@
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.DEVICE_POWER" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
-
+ <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS_FULL" />
+ <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS" />
</manifest>
diff --git a/data/fonts/DroidNaskh-Bold.ttf b/data/fonts/DroidNaskh-Bold.ttf
index 692b796..14d8768 100644
--- a/data/fonts/DroidNaskh-Bold.ttf
+++ b/data/fonts/DroidNaskh-Bold.ttf
Binary files differ
diff --git a/data/fonts/DroidNaskh-Regular.ttf b/data/fonts/DroidNaskh-Regular.ttf
index da9a45f..03662f2 100644
--- a/data/fonts/DroidNaskh-Regular.ttf
+++ b/data/fonts/DroidNaskh-Regular.ttf
Binary files differ
diff --git a/data/sounds/AudioPackage10.mk b/data/sounds/AudioPackage10.mk
new file mode 100755
index 0000000..cb55bba
--- /dev/null
+++ b/data/sounds/AudioPackage10.mk
@@ -0,0 +1,64 @@
+#
+# Audio Package 10 - Mako
+#
+# Include this file in a product makefile to include these audio files
+#
+#
+
+LOCAL_PATH:= frameworks/base/data/sounds
+
+PRODUCT_COPY_FILES += \
+ $(LOCAL_PATH)/alarms/ogg/Argon.ogg:system/media/audio/alarms/Argon.ogg \
+ $(LOCAL_PATH)/alarms/ogg/Carbon.ogg:system/media/audio/alarms/Carbon.ogg \
+ $(LOCAL_PATH)/alarms/ogg/Helium.ogg:system/media/audio/alarms/Helium.ogg \
+ $(LOCAL_PATH)/alarms/ogg/Krypton.ogg:system/media/audio/alarms/Krypton.ogg \
+ $(LOCAL_PATH)/alarms/ogg/Neon.ogg:system/media/audio/alarms/Neon.ogg \
+ $(LOCAL_PATH)/alarms/ogg/Oxygen.ogg:system/media/audio/alarms/Oxygen.ogg \
+ $(LOCAL_PATH)/alarms/ogg/Osmium.ogg:system/media/audio/alarms/Osmium.ogg \
+ $(LOCAL_PATH)/alarms/ogg/Platinum.ogg:system/media/audio/alarms/Platinum.ogg \
+ $(LOCAL_PATH)/effects/ogg/Effect_Tick.ogg:system/media/audio/ui/Effect_Tick.ogg \
+ $(LOCAL_PATH)/effects/ogg/KeypressStandard_120.ogg:system/media/audio/ui/KeypressStandard.ogg \
+ $(LOCAL_PATH)/effects/ogg/KeypressSpacebar_120.ogg:system/media/audio/ui/KeypressSpacebar.ogg \
+ $(LOCAL_PATH)/effects/ogg/KeypressDelete_120.ogg:system/media/audio/ui/KeypressDelete.ogg \
+ $(LOCAL_PATH)/effects/ogg/KeypressReturn_120.ogg:system/media/audio/ui/KeypressReturn.ogg \
+ $(LOCAL_PATH)/effects/ogg/VideoRecord.ogg:system/media/audio/ui/VideoRecord.ogg \
+ $(LOCAL_PATH)/effects/ogg/camera_click.ogg:system/media/audio/ui/camera_click.ogg \
+ $(LOCAL_PATH)/effects/ogg/camera_focus.ogg:system/media/audio/ui/camera_focus.ogg \
+ $(LOCAL_PATH)/effects/ogg/LowBattery.ogg:system/media/audio/ui/LowBattery.ogg \
+ $(LOCAL_PATH)/effects/ogg/Dock.ogg:system/media/audio/ui/Dock.ogg \
+ $(LOCAL_PATH)/effects/ogg/Undock.ogg:system/media/audio/ui/Undock.ogg \
+ $(LOCAL_PATH)/effects/ogg/Lock.ogg:system/media/audio/ui/Lock.ogg \
+ $(LOCAL_PATH)/effects/ogg/Unlock.ogg:system/media/audio/ui/Unlock.ogg \
+ $(LOCAL_PATH)/notifications/ogg/Adara.ogg:system/media/audio/notifications/Adara.ogg \
+ $(LOCAL_PATH)/notifications/ogg/Alya.ogg:system/media/audio/notifications/Alya.ogg \
+ $(LOCAL_PATH)/notifications/ogg/Arcturus.ogg:system/media/audio/notifications/Arcturus.ogg \
+ $(LOCAL_PATH)/notifications/ogg/Capella.ogg:system/media/audio/notifications/Capella.ogg \
+ $(LOCAL_PATH)/notifications/ogg/CetiAlpha.ogg:system/media/audio/notifications/CetiAlpha.ogg \
+ $(LOCAL_PATH)/notifications/ogg/Hojus.ogg:system/media/audio/notifications/Hojus.ogg \
+ $(LOCAL_PATH)/notifications/ogg/Mira.ogg:system/media/audio/notifications/Mira.ogg \
+ $(LOCAL_PATH)/notifications/ogg/Pollux.ogg:system/media/audio/notifications/Pollux.ogg \
+ $(LOCAL_PATH)/notifications/ogg/Procyon.ogg:system/media/audio/notifications/Procyon.ogg \
+ $(LOCAL_PATH)/notifications/ogg/Shaula.ogg:system/media/audio/notifications/Shaula.ogg \
+ $(LOCAL_PATH)/notifications/ogg/Spica.ogg:system/media/audio/notifications/Spica.ogg \
+ $(LOCAL_PATH)/notifications/ogg/Syrma.ogg:system/media/audio/notifications/Syrma.ogg \
+ $(LOCAL_PATH)/notifications/ogg/Talitha.ogg:system/media/audio/notifications/Talitha.ogg \
+ $(LOCAL_PATH)/notifications/ogg/Tejat.ogg:system/media/audio/notifications/Tejat.ogg \
+ $(LOCAL_PATH)/notifications/ogg/Vega.ogg:system/media/audio/notifications/Vega.ogg \
+ $(LOCAL_PATH)/ringtones/ogg/Andromeda.ogg:system/media/audio/ringtones/Andromeda.ogg \
+ $(LOCAL_PATH)/ringtones/ogg/Aquila.ogg:system/media/audio/ringtones/Aquila.ogg \
+ $(LOCAL_PATH)/ringtones/ogg/Atria.ogg:system/media/audio/ringtones/Atria.ogg \
+ $(LOCAL_PATH)/ringtones/ogg/ArgoNavis.ogg:system/media/audio/ringtones/ArgoNavis.ogg \
+ $(LOCAL_PATH)/ringtones/ogg/Centaurus.ogg:system/media/audio/ringtones/Centaurus.ogg \
+ $(LOCAL_PATH)/ringtones/ogg/Girtab.ogg:system/media/audio/ringtones/Girtab.ogg \
+ $(LOCAL_PATH)/ringtones/ogg/Hydra.ogg:system/media/audio/ringtones/Hydra.ogg \
+ $(LOCAL_PATH)/ringtones/ogg/Kuma.ogg:system/media/audio/ringtones/Kuma.ogg \
+ $(LOCAL_PATH)/ringtones/ogg/Machina.ogg:system/media/audio/ringtones/Machina.ogg \
+ $(LOCAL_PATH)/ringtones/ogg/Orion.ogg:system/media/audio/ringtones/Orion.ogg \
+ $(LOCAL_PATH)/ringtones/ogg/Pegasus.ogg:system/media/audio/ringtones/Pegasus.ogg \
+ $(LOCAL_PATH)/ringtones/ogg/Pyxis.ogg:system/media/audio/ringtones/Pyxis.ogg \
+ $(LOCAL_PATH)/ringtones/ogg/Rasalas.ogg:system/media/audio/ringtones/Rasalas.ogg \
+ $(LOCAL_PATH)/ringtones/ogg/Scarabaeus.ogg:system/media/audio/ringtones/Scarabaeus.ogg \
+ $(LOCAL_PATH)/ringtones/ogg/Sceptrum.ogg:system/media/audio/ringtones/Sceptrum.ogg \
+ $(LOCAL_PATH)/ringtones/ogg/Solarium.ogg:system/media/audio/ringtones/Solarium.ogg \
+ $(LOCAL_PATH)/ringtones/ogg/Themos.ogg:system/media/audio/ringtones/Themos.ogg \
+ $(LOCAL_PATH)/ringtones/ogg/Zeta.ogg:system/media/audio/ringtones/Zeta.ogg
diff --git a/data/sounds/AudioPackage9.mk b/data/sounds/AudioPackage9.mk
new file mode 100755
index 0000000..73e4fd3
--- /dev/null
+++ b/data/sounds/AudioPackage9.mk
@@ -0,0 +1,47 @@
+#
+# Audio Package 9 - Manta
+#
+# Include this file in a product makefile to include these audio files
+#
+#
+
+LOCAL_PATH:= frameworks/base/data/sounds
+
+PRODUCT_COPY_FILES += \
+ $(LOCAL_PATH)/alarms/ogg/Argon.ogg:system/media/audio/alarms/Argon.ogg \
+ $(LOCAL_PATH)/alarms/ogg/Carbon.ogg:system/media/audio/alarms/Carbon.ogg \
+ $(LOCAL_PATH)/alarms/ogg/Helium.ogg:system/media/audio/alarms/Helium.ogg \
+ $(LOCAL_PATH)/alarms/ogg/Krypton.ogg:system/media/audio/alarms/Krypton.ogg \
+ $(LOCAL_PATH)/alarms/ogg/Neon.ogg:system/media/audio/alarms/Neon.ogg \
+ $(LOCAL_PATH)/alarms/ogg/Oxygen.ogg:system/media/audio/alarms/Oxygen.ogg \
+ $(LOCAL_PATH)/alarms/ogg/Osmium.ogg:system/media/audio/alarms/Osmium.ogg \
+ $(LOCAL_PATH)/alarms/ogg/Platinum.ogg:system/media/audio/alarms/Platinum.ogg \
+ $(LOCAL_PATH)/effects/ogg/Effect_Tick.ogg:system/media/audio/ui/Effect_Tick.ogg \
+ $(LOCAL_PATH)/effects/ogg/KeypressStandard_120.ogg:system/media/audio/ui/KeypressStandard.ogg \
+ $(LOCAL_PATH)/effects/ogg/KeypressSpacebar_120.ogg:system/media/audio/ui/KeypressSpacebar.ogg \
+ $(LOCAL_PATH)/effects/ogg/KeypressDelete_120.ogg:system/media/audio/ui/KeypressDelete.ogg \
+ $(LOCAL_PATH)/effects/ogg/KeypressReturn_120.ogg:system/media/audio/ui/KeypressReturn.ogg \
+ $(LOCAL_PATH)/effects/ogg/VideoRecord.ogg:system/media/audio/ui/VideoRecord.ogg \
+ $(LOCAL_PATH)/effects/ogg/camera_click.ogg:system/media/audio/ui/camera_click.ogg \
+ $(LOCAL_PATH)/effects/ogg/camera_focus.ogg:system/media/audio/ui/camera_focus.ogg \
+ $(LOCAL_PATH)/effects/ogg/LowBattery.ogg:system/media/audio/ui/LowBattery.ogg \
+ $(LOCAL_PATH)/effects/ogg/Dock.ogg:system/media/audio/ui/Dock.ogg \
+ $(LOCAL_PATH)/effects/ogg/Undock.ogg:system/media/audio/ui/Undock.ogg \
+ $(LOCAL_PATH)/effects/ogg/Lock.ogg:system/media/audio/ui/Lock.ogg \
+ $(LOCAL_PATH)/effects/ogg/Unlock.ogg:system/media/audio/ui/Unlock.ogg \
+ $(LOCAL_PATH)/notifications/ogg/Adara.ogg:system/media/audio/notifications/Adara.ogg \
+ $(LOCAL_PATH)/notifications/ogg/Alya.ogg:system/media/audio/notifications/Alya.ogg \
+ $(LOCAL_PATH)/notifications/ogg/Arcturus.ogg:system/media/audio/notifications/Arcturus.ogg \
+ $(LOCAL_PATH)/notifications/ogg/Capella.ogg:system/media/audio/notifications/Capella.ogg \
+ $(LOCAL_PATH)/notifications/ogg/CetiAlpha.ogg:system/media/audio/notifications/CetiAlpha.ogg \
+ $(LOCAL_PATH)/notifications/ogg/Hojus.ogg:system/media/audio/notifications/Hojus.ogg \
+ $(LOCAL_PATH)/notifications/ogg/Mira.ogg:system/media/audio/notifications/Mira.ogg \
+ $(LOCAL_PATH)/notifications/ogg/Pollux.ogg:system/media/audio/notifications/Pollux.ogg \
+ $(LOCAL_PATH)/notifications/ogg/Procyon.ogg:system/media/audio/notifications/Procyon.ogg \
+ $(LOCAL_PATH)/notifications/ogg/Shaula.ogg:system/media/audio/notifications/Shaula.ogg \
+ $(LOCAL_PATH)/notifications/ogg/Spica.ogg:system/media/audio/notifications/Spica.ogg \
+ $(LOCAL_PATH)/notifications/ogg/Syrma.ogg:system/media/audio/notifications/Syrma.ogg \
+ $(LOCAL_PATH)/notifications/ogg/Talitha.ogg:system/media/audio/notifications/Talitha.ogg \
+ $(LOCAL_PATH)/notifications/ogg/Tejat.ogg:system/media/audio/notifications/Tejat.ogg \
+ $(LOCAL_PATH)/notifications/ogg/Vega.ogg:system/media/audio/notifications/Vega.ogg \
+ $(LOCAL_PATH)/ringtones/ogg/Girtab.ogg:system/media/audio/ringtones/Girtab.ogg
diff --git a/data/sounds/alarms/ogg/Argon.ogg b/data/sounds/alarms/ogg/Argon.ogg
new file mode 100644
index 0000000..35addf5
--- /dev/null
+++ b/data/sounds/alarms/ogg/Argon.ogg
Binary files differ
diff --git a/data/sounds/alarms/ogg/Carbon.ogg b/data/sounds/alarms/ogg/Carbon.ogg
new file mode 100644
index 0000000..b02a1cc
--- /dev/null
+++ b/data/sounds/alarms/ogg/Carbon.ogg
Binary files differ
diff --git a/data/sounds/alarms/ogg/Helium.ogg b/data/sounds/alarms/ogg/Helium.ogg
new file mode 100644
index 0000000..36694cb
--- /dev/null
+++ b/data/sounds/alarms/ogg/Helium.ogg
Binary files differ
diff --git a/data/sounds/alarms/ogg/Krypton.ogg b/data/sounds/alarms/ogg/Krypton.ogg
new file mode 100755
index 0000000..48f956b
--- /dev/null
+++ b/data/sounds/alarms/ogg/Krypton.ogg
Binary files differ
diff --git a/data/sounds/alarms/ogg/Neon.ogg b/data/sounds/alarms/ogg/Neon.ogg
new file mode 100644
index 0000000..3089a27
--- /dev/null
+++ b/data/sounds/alarms/ogg/Neon.ogg
Binary files differ
diff --git a/data/sounds/alarms/ogg/Oxygen.ogg b/data/sounds/alarms/ogg/Oxygen.ogg
new file mode 100644
index 0000000..4dc8ade
--- /dev/null
+++ b/data/sounds/alarms/ogg/Oxygen.ogg
Binary files differ
diff --git a/data/sounds/alarms/ogg/Platinum.ogg b/data/sounds/alarms/ogg/Platinum.ogg
new file mode 100644
index 0000000..d5f0893
--- /dev/null
+++ b/data/sounds/alarms/ogg/Platinum.ogg
Binary files differ
diff --git a/data/sounds/alarms/ogg/Promethium.ogg b/data/sounds/alarms/ogg/Promethium.ogg
index 2a195a3..d5f0893 100644
--- a/data/sounds/alarms/ogg/Promethium.ogg
+++ b/data/sounds/alarms/ogg/Promethium.ogg
Binary files differ
diff --git a/data/sounds/alarms/wav/Argon.wav b/data/sounds/alarms/wav/Argon.wav
new file mode 100755
index 0000000..56e57fc
--- /dev/null
+++ b/data/sounds/alarms/wav/Argon.wav
Binary files differ
diff --git a/data/sounds/alarms/wav/Carbon.wav b/data/sounds/alarms/wav/Carbon.wav
new file mode 100755
index 0000000..2b855e1
--- /dev/null
+++ b/data/sounds/alarms/wav/Carbon.wav
Binary files differ
diff --git a/data/sounds/alarms/wav/Helium.wav b/data/sounds/alarms/wav/Helium.wav
new file mode 100644
index 0000000..17710b0
--- /dev/null
+++ b/data/sounds/alarms/wav/Helium.wav
Binary files differ
diff --git a/data/sounds/alarms/wav/Krypton.wav b/data/sounds/alarms/wav/Krypton.wav
new file mode 100644
index 0000000..9095e30
--- /dev/null
+++ b/data/sounds/alarms/wav/Krypton.wav
Binary files differ
diff --git a/data/sounds/alarms/wav/Neon.wav b/data/sounds/alarms/wav/Neon.wav
new file mode 100644
index 0000000..0e9101a
--- /dev/null
+++ b/data/sounds/alarms/wav/Neon.wav
Binary files differ
diff --git a/data/sounds/alarms/wav/Oxygen.wav b/data/sounds/alarms/wav/Oxygen.wav
new file mode 100644
index 0000000..bd41869
--- /dev/null
+++ b/data/sounds/alarms/wav/Oxygen.wav
Binary files differ
diff --git a/data/sounds/alarms/wav/Platinum.wav b/data/sounds/alarms/wav/Platinum.wav
new file mode 100755
index 0000000..08ea03e
--- /dev/null
+++ b/data/sounds/alarms/wav/Platinum.wav
Binary files differ
diff --git a/data/sounds/ringtones/ogg/ArgoNavis.ogg b/data/sounds/ringtones/ogg/ArgoNavis.ogg
index 8bee29e..d25b5e8 100644
--- a/data/sounds/ringtones/ogg/ArgoNavis.ogg
+++ b/data/sounds/ringtones/ogg/ArgoNavis.ogg
Binary files differ
diff --git a/data/sounds/ringtones/ogg/Perseus.ogg b/data/sounds/ringtones/ogg/Perseus.ogg
index e5f3fc2..48348e5 100644
--- a/data/sounds/ringtones/ogg/Perseus.ogg
+++ b/data/sounds/ringtones/ogg/Perseus.ogg
Binary files differ
diff --git a/data/sounds/ringtones/ogg/Rigel.ogg b/data/sounds/ringtones/ogg/Rigel.ogg
index 4fcb3c0..de3d92f 100644
--- a/data/sounds/ringtones/ogg/Rigel.ogg
+++ b/data/sounds/ringtones/ogg/Rigel.ogg
Binary files differ
diff --git a/graphics/java/android/graphics/Bitmap.java b/graphics/java/android/graphics/Bitmap.java
index 6238edb..22ecc61 100644
--- a/graphics/java/android/graphics/Bitmap.java
+++ b/graphics/java/android/graphics/Bitmap.java
@@ -1030,6 +1030,51 @@
}
/**
+ * Indicates whether the renderer responsible for drawing this
+ * bitmap should attempt to use mipmaps when this bitmap is drawn
+ * scaled down.
+ *
+ * If you know that you are going to draw this bitmap at less than
+ * 50% of its original size, you may be able to obtain a higher
+ * quality
+ *
+ * This property is only a suggestion that can be ignored by the
+ * renderer. It is not guaranteed to have any effect.
+ *
+ * @return true if the renderer should attempt to use mipmaps,
+ * false otherwise
+ *
+ * @see #setHasMipMap(boolean)
+ */
+ public final boolean hasMipMap() {
+ return nativeHasMipMap(mNativeBitmap);
+ }
+
+ /**
+ * Set a hint for the renderer responsible for drawing this bitmap
+ * indicating that it should attempt to use mipmaps when this bitmap
+ * is drawn scaled down.
+ *
+ * If you know that you are going to draw this bitmap at less than
+ * 50% of its original size, you may be able to obtain a higher
+ * quality by turning this property on.
+ *
+ * Note that if the renderer respects this hint it might have to
+ * allocate extra memory to hold the mipmap levels for this bitmap.
+ *
+ * This property is only a suggestion that can be ignored by the
+ * renderer. It is not guaranteed to have any effect.
+ *
+ * @param hasMipMap indicates whether the renderer should attempt
+ * to use mipmaps
+ *
+ * @see #hasMipMap()
+ */
+ public final void setHasMipMap(boolean hasMipMap) {
+ nativeSetHasMipMap(mNativeBitmap, hasMipMap);
+ }
+
+ /**
* Fills the bitmap's pixels with the specified {@link Color}.
*
* @throws IllegalStateException if the bitmap is not mutable.
@@ -1356,7 +1401,6 @@
private static native int nativeHeight(int nativeBitmap);
private static native int nativeRowBytes(int nativeBitmap);
private static native int nativeConfig(int nativeBitmap);
- private static native boolean nativeHasAlpha(int nativeBitmap);
private static native int nativeGetPixel(int nativeBitmap, int x, int y);
private static native void nativeGetPixels(int nativeBitmap, int[] pixels,
@@ -1385,7 +1429,10 @@
int[] offsetXY);
private static native void nativePrepareToDraw(int nativeBitmap);
+ private static native boolean nativeHasAlpha(int nativeBitmap);
private static native void nativeSetHasAlpha(int nBitmap, boolean hasAlpha);
+ private static native boolean nativeHasMipMap(int nativeBitmap);
+ private static native void nativeSetHasMipMap(int nBitmap, boolean hasMipMap);
private static native boolean nativeSameAs(int nb0, int nb1);
/* package */ final int ni() {
diff --git a/graphics/java/android/renderscript/ScriptIntrinsicBlur.java b/graphics/java/android/renderscript/ScriptIntrinsicBlur.java
index 2a04b42..11164e3 100644
--- a/graphics/java/android/renderscript/ScriptIntrinsicBlur.java
+++ b/graphics/java/android/renderscript/ScriptIntrinsicBlur.java
@@ -63,7 +63,7 @@
*/
public void setInput(Allocation ain) {
mInput = ain;
- bindAllocation(ain, 1);
+ setVar(1, ain);
}
/**
diff --git a/graphics/java/android/renderscript/ScriptIntrinsicConvolve3x3.java b/graphics/java/android/renderscript/ScriptIntrinsicConvolve3x3.java
index d7e9f32..91efa02 100644
--- a/graphics/java/android/renderscript/ScriptIntrinsicConvolve3x3.java
+++ b/graphics/java/android/renderscript/ScriptIntrinsicConvolve3x3.java
@@ -68,7 +68,7 @@
*/
public void setInput(Allocation ain) {
mInput = ain;
- bindAllocation(ain, 1);
+ setVar(1, ain);
}
/**
diff --git a/graphics/java/android/renderscript/ScriptIntrinsicConvolve5x5.java b/graphics/java/android/renderscript/ScriptIntrinsicConvolve5x5.java
index ff31270..1f52e3f 100644
--- a/graphics/java/android/renderscript/ScriptIntrinsicConvolve5x5.java
+++ b/graphics/java/android/renderscript/ScriptIntrinsicConvolve5x5.java
@@ -61,7 +61,7 @@
*/
public void setInput(Allocation ain) {
mInput = ain;
- bindAllocation(ain, 1);
+ setVar(1, ain);
}
/**
diff --git a/graphics/java/android/renderscript/ScriptIntrinsicLUT.java b/graphics/java/android/renderscript/ScriptIntrinsicLUT.java
index 188e04c..41bdd25 100644
--- a/graphics/java/android/renderscript/ScriptIntrinsicLUT.java
+++ b/graphics/java/android/renderscript/ScriptIntrinsicLUT.java
@@ -41,7 +41,7 @@
mCache[ct + 512] = (byte)ct;
mCache[ct + 768] = (byte)ct;
}
- bindAllocation(mTables, 0);
+ setVar(0, mTables);
}
/**
diff --git a/graphics/java/android/renderscript/ScriptIntrinsicYuvToRGB.java b/graphics/java/android/renderscript/ScriptIntrinsicYuvToRGB.java
index 415061c..dc8a5aa 100644
--- a/graphics/java/android/renderscript/ScriptIntrinsicYuvToRGB.java
+++ b/graphics/java/android/renderscript/ScriptIntrinsicYuvToRGB.java
@@ -56,7 +56,7 @@
*/
public void setInput(Allocation ain) {
mInput = ain;
- bindAllocation(ain, 0);
+ setVar(0, ain);
}
/**
diff --git a/libs/hwui/Caches.cpp b/libs/hwui/Caches.cpp
index d18a5b0..e7085b0 100644
--- a/libs/hwui/Caches.cpp
+++ b/libs/hwui/Caches.cpp
@@ -399,9 +399,20 @@
if (scissorEnabled && (x != mScissorX || y != mScissorY ||
width != mScissorWidth || height != mScissorHeight)) {
- if (x < 0) x = 0;
- if (y < 0) y = 0;
-
+ if (x < 0) {
+ width += x;
+ x = 0;
+ }
+ if (y < 0) {
+ height += y;
+ y = 0;
+ }
+ if (width < 0) {
+ width = 0;
+ }
+ if (height < 0) {
+ height = 0;
+ }
glScissor(x, y, width, height);
mScissorX = x;
diff --git a/libs/hwui/Layer.h b/libs/hwui/Layer.h
index 69be317..448e3da 100644
--- a/libs/hwui/Layer.h
+++ b/libs/hwui/Layer.h
@@ -209,6 +209,9 @@
}
inline void allocateTexture(GLenum format, GLenum storage) {
+#if DEBUG_LAYERS
+ ALOGD(" Allocate layer: %dx%d", getWidth(), getHeight());
+#endif
glTexImage2D(renderTarget, 0, format, getWidth(), getHeight(), 0, format, storage, NULL);
}
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index cc536f2..b6be5b3 100644
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -49,7 +49,7 @@
#define ALPHA_THRESHOLD 0
-#define FILTER(paint) (paint && paint->isFilterBitmap() ? GL_LINEAR : GL_NEAREST)
+#define FILTER(paint) (!paint || paint->isFilterBitmap() ? GL_LINEAR : GL_NEAREST)
///////////////////////////////////////////////////////////////////////////////
// Globals
@@ -895,12 +895,6 @@
void OpenGLRenderer::drawTextureLayer(Layer* layer, const Rect& rect) {
float alpha = layer->getAlpha() / 255.0f;
- mat4& transform = layer->getTransform();
- if (!transform.isIdentity()) {
- save(0);
- mSnapshot->transform->multiply(transform);
- }
-
setupDraw();
if (layer->getRenderTarget() == GL_TEXTURE_2D) {
setupDrawWithTexture();
@@ -937,10 +931,6 @@
glDrawArrays(GL_TRIANGLE_STRIP, 0, gMeshCount);
finishDrawTexture();
-
- if (!transform.isIdentity()) {
- restore();
- }
}
void OpenGLRenderer::composeLayerRect(Layer* layer, const Rect& rect, bool swap) {
@@ -1730,35 +1720,22 @@
status_t OpenGLRenderer::drawBitmapMesh(SkBitmap* bitmap, int meshWidth, int meshHeight,
float* vertices, int* colors, SkPaint* paint) {
- // TODO: Do a quickReject
if (!vertices || mSnapshot->isIgnored()) {
return DrawGlInfo::kStatusDone;
}
- mCaches.activeTexture(0);
- Texture* texture = mCaches.textureCache.get(bitmap);
- if (!texture) return DrawGlInfo::kStatusDone;
- const AutoTexture autoCleanup(texture);
-
- texture->setWrap(GL_CLAMP_TO_EDGE, true);
- texture->setFilter(FILTER(paint), true);
-
- int alpha;
- SkXfermode::Mode mode;
- getAlphaAndMode(paint, &alpha, &mode);
-
- const uint32_t count = meshWidth * meshHeight * 6;
-
+ // TODO: We should compute the bounding box when recording the display list
float left = FLT_MAX;
float top = FLT_MAX;
float right = FLT_MIN;
float bottom = FLT_MIN;
- const bool hasActiveLayer = hasLayer();
+ const uint32_t count = meshWidth * meshHeight * 6;
// TODO: Support the colors array
TextureVertex mesh[count];
TextureVertex* vertex = mesh;
+
for (int32_t y = 0; y < meshHeight; y++) {
for (int32_t x = 0; x < meshWidth; x++) {
uint32_t i = (y * (meshWidth + 1) + x) * 2;
@@ -1785,17 +1762,31 @@
TextureVertex::set(vertex++, vertices[cx], vertices[cy], u2, v1);
TextureVertex::set(vertex++, vertices[dx], vertices[dy], u2, v2);
- if (hasActiveLayer) {
- // TODO: This could be optimized to avoid unnecessary ops
- left = fminf(left, fminf(vertices[ax], fminf(vertices[bx], vertices[cx])));
- top = fminf(top, fminf(vertices[ay], fminf(vertices[by], vertices[cy])));
- right = fmaxf(right, fmaxf(vertices[ax], fmaxf(vertices[bx], vertices[cx])));
- bottom = fmaxf(bottom, fmaxf(vertices[ay], fmaxf(vertices[by], vertices[cy])));
- }
+ // TODO: This could be optimized to avoid unnecessary ops
+ left = fminf(left, fminf(vertices[ax], fminf(vertices[bx], vertices[cx])));
+ top = fminf(top, fminf(vertices[ay], fminf(vertices[by], vertices[cy])));
+ right = fmaxf(right, fmaxf(vertices[ax], fmaxf(vertices[bx], vertices[cx])));
+ bottom = fmaxf(bottom, fmaxf(vertices[ay], fmaxf(vertices[by], vertices[cy])));
}
}
- if (hasActiveLayer) {
+ if (quickReject(left, top, right, bottom)) {
+ return DrawGlInfo::kStatusDone;
+ }
+
+ mCaches.activeTexture(0);
+ Texture* texture = mCaches.textureCache.get(bitmap);
+ if (!texture) return DrawGlInfo::kStatusDone;
+ const AutoTexture autoCleanup(texture);
+
+ texture->setWrap(GL_CLAMP_TO_EDGE, true);
+ texture->setFilter(FILTER(paint), true);
+
+ int alpha;
+ SkXfermode::Mode mode;
+ getAlphaAndMode(paint, &alpha, &mode);
+
+ if (hasLayer()) {
dirtyLayer(left, top, right, bottom, *mSnapshot->transform);
}
@@ -2427,17 +2418,39 @@
}
status_t OpenGLRenderer::drawArc(float left, float top, float right, float bottom,
- float startAngle, float sweepAngle, bool useCenter, SkPaint* paint) {
- if (mSnapshot->isIgnored()) return DrawGlInfo::kStatusDone;
-
- if (fabs(sweepAngle) >= 360.0f) {
- return drawOval(left, top, right, bottom, paint);
+ float startAngle, float sweepAngle, bool useCenter, SkPaint* p) {
+ if (mSnapshot->isIgnored() || quickRejectPreStroke(left, top, right, bottom, p)) {
+ return DrawGlInfo::kStatusDone;
}
- mCaches.activeTexture(0);
- const PathTexture* texture = mCaches.arcShapeCache.getArc(right - left, bottom - top,
- startAngle, sweepAngle, useCenter, paint);
- return drawShape(left, top, texture, paint);
+ if (fabs(sweepAngle) >= 360.0f) {
+ return drawOval(left, top, right, bottom, p);
+ }
+
+ // TODO: support fills (accounting for concavity if useCenter && sweepAngle > 180)
+ if (p->getStyle() != SkPaint::kStroke_Style || p->getPathEffect() != 0 || p->getStrokeCap() != SkPaint::kButt_Cap) {
+ mCaches.activeTexture(0);
+ const PathTexture* texture = mCaches.arcShapeCache.getArc(right - left, bottom - top,
+ startAngle, sweepAngle, useCenter, p);
+ return drawShape(left, top, texture, p);
+ }
+
+ SkRect rect = SkRect::MakeLTRB(left, top, right, bottom);
+ if (p->getStyle() == SkPaint::kStrokeAndFill_Style) {
+ rect.outset(p->getStrokeWidth() / 2, p->getStrokeWidth() / 2);
+ }
+
+ SkPath path;
+ if (useCenter) {
+ path.moveTo(rect.centerX(), rect.centerY());
+ }
+ path.arcTo(rect, startAngle, sweepAngle, !useCenter);
+ if (useCenter) {
+ path.close();
+ }
+ drawConvexPath(path, p);
+
+ return DrawGlInfo::kStatusDrew;
}
// See SkPaintDefaults.h
@@ -2769,12 +2782,24 @@
return DrawGlInfo::kStatusDone;
}
+ mat4* transform = NULL;
+ if (layer->isTextureLayer()) {
+ transform = &layer->getTransform();
+ if (!transform->isIdentity()) {
+ save(0);
+ mSnapshot->transform->multiply(*transform);
+ }
+ }
+
Rect transformed;
Rect clip;
const bool rejected = quickRejectNoScissor(x, y,
x + layer->layer.getWidth(), y + layer->layer.getHeight(), transformed, clip);
if (rejected) {
+ if (transform && !transform->isIdentity()) {
+ restore();
+ }
return DrawGlInfo::kStatusDone;
}
@@ -2835,6 +2860,10 @@
}
}
+ if (transform && !transform->isIdentity()) {
+ restore();
+ }
+
return DrawGlInfo::kStatusDrew;
}
diff --git a/libs/hwui/PathRenderer.cpp b/libs/hwui/PathRenderer.cpp
index 58d6cb8..dd13d79 100644
--- a/libs/hwui/PathRenderer.cpp
+++ b/libs/hwui/PathRenderer.cpp
@@ -80,11 +80,24 @@
*
* Note that we can't add and normalize the two vectors, that would result in a rectangle having an
* offset of (sqrt(2)/2, sqrt(2)/2) at each corner, instead of (1, 1)
+ *
+ * NOTE: assumes angles between normals 90 degrees or less
*/
inline vec2 totalOffsetFromNormals(const vec2& normalA, const vec2& normalB) {
return (normalA + normalB) / (1 + fabs(normalA.dot(normalB)));
}
+inline void scaleOffsetForStrokeWidth(vec2& offset, float halfStrokeWidth,
+ float inverseScaleX, float inverseScaleY) {
+ if (halfStrokeWidth == 0.0f) {
+ // hairline - compensate for scale
+ offset.x *= 0.5f * inverseScaleX;
+ offset.y *= 0.5f * inverseScaleY;
+ } else {
+ offset *= halfStrokeWidth;
+ }
+}
+
void getFillVerticesFromPerimeter(const Vector<Vertex>& perimeter, VertexBuffer& vertexBuffer) {
Vertex* buffer = vertexBuffer.alloc<Vertex>(perimeter.size());
@@ -119,13 +132,7 @@
nextNormal.normalize();
vec2 totalOffset = totalOffsetFromNormals(lastNormal, nextNormal);
- if (halfStrokeWidth == 0.0f) {
- // hairline - compensate for scale
- totalOffset.x *= 0.5f * inverseScaleX;
- totalOffset.y *= 0.5f * inverseScaleY;
- } else {
- totalOffset *= halfStrokeWidth;
- }
+ scaleOffsetForStrokeWidth(totalOffset, halfStrokeWidth, inverseScaleX, inverseScaleY);
Vertex::set(&buffer[currentIndex++],
current->position[0] + totalOffset.x,
@@ -145,6 +152,55 @@
copyVertex(&buffer[currentIndex++], &buffer[1]);
}
+void getStrokeVerticesFromUnclosedVertices(const Vector<Vertex>& vertices, float halfStrokeWidth,
+ VertexBuffer& vertexBuffer, float inverseScaleX, float inverseScaleY) {
+ Vertex* buffer = vertexBuffer.alloc<Vertex>(vertices.size() * 2);
+
+ int currentIndex = 0;
+ const Vertex* current = &(vertices[0]);
+ vec2 lastNormal;
+ for (unsigned int i = 0; i < vertices.size() - 1; i++) {
+ const Vertex* next = &(vertices[i + 1]);
+ vec2 nextNormal(next->position[1] - current->position[1],
+ current->position[0] - next->position[0]);
+ nextNormal.normalize();
+
+ vec2 totalOffset;
+ if (i == 0) {
+ totalOffset = nextNormal;
+ } else {
+ totalOffset = totalOffsetFromNormals(lastNormal, nextNormal);
+ }
+ scaleOffsetForStrokeWidth(totalOffset, halfStrokeWidth, inverseScaleX, inverseScaleY);
+
+ Vertex::set(&buffer[currentIndex++],
+ current->position[0] + totalOffset.x,
+ current->position[1] + totalOffset.y);
+
+ Vertex::set(&buffer[currentIndex++],
+ current->position[0] - totalOffset.x,
+ current->position[1] - totalOffset.y);
+
+ current = next;
+ lastNormal = nextNormal;
+ }
+
+ vec2 totalOffset = lastNormal;
+ scaleOffsetForStrokeWidth(totalOffset, halfStrokeWidth, inverseScaleX, inverseScaleY);
+
+ Vertex::set(&buffer[currentIndex++],
+ current->position[0] + totalOffset.x,
+ current->position[1] + totalOffset.y);
+ Vertex::set(&buffer[currentIndex++],
+ current->position[0] - totalOffset.x,
+ current->position[1] - totalOffset.y);
+#if VERTEX_DEBUG
+ for (unsigned int i = 0; i < vertexBuffer.getSize(); i++) {
+ ALOGD("point at %f %f", buffer[i].position[0], buffer[i].position[1]);
+ }
+#endif
+}
+
void getFillVerticesFromPerimeterAA(const Vector<Vertex>& perimeter, VertexBuffer& vertexBuffer,
float inverseScaleX, float inverseScaleY) {
AlphaVertex* buffer = vertexBuffer.alloc<AlphaVertex>(perimeter.size() * 3 + 2);
@@ -202,11 +258,167 @@
#if VERTEX_DEBUG
for (unsigned int i = 0; i < vertexBuffer.getSize(); i++) {
- ALOGD("point at %f %f", buffer[i].position[0], buffer[i].position[1]);
+ ALOGD("point at %f %f, alpha %f", buffer[i].position[0], buffer[i].position[1], buffer[i].alpha);
}
#endif
}
+
+void getStrokeVerticesFromUnclosedVerticesAA(const Vector<Vertex>& vertices, float halfStrokeWidth,
+ VertexBuffer& vertexBuffer, float inverseScaleX, float inverseScaleY) {
+ AlphaVertex* buffer = vertexBuffer.alloc<AlphaVertex>(6 * vertices.size() + 2);
+
+ // avoid lines smaller than hairline since they break triangle based sampling. instead reducing
+ // alpha value (TODO: support different X/Y scale)
+ float maxAlpha = 1.0f;
+ if (halfStrokeWidth != 0 && inverseScaleX == inverseScaleY &&
+ halfStrokeWidth * inverseScaleX < 0.5f) {
+ maxAlpha *= (2 * halfStrokeWidth) / inverseScaleX;
+ halfStrokeWidth = 0.0f;
+ }
+
+ // there is no outer/inner here, using them for consistency with below approach
+ int offset = 2 * (vertices.size() - 2);
+ int currentAAOuterIndex = 2;
+ int currentAAInnerIndex = 2 * offset + 5; // reversed
+ int currentStrokeIndex = currentAAInnerIndex + 7;
+
+ const Vertex* last = &(vertices[0]);
+ const Vertex* current = &(vertices[1]);
+ vec2 lastNormal(current->position[1] - last->position[1],
+ last->position[0] - current->position[0]);
+ lastNormal.normalize();
+
+ {
+ // start cap
+ vec2 totalOffset = lastNormal;
+ vec2 AAOffset = totalOffset;
+ AAOffset.x *= 0.5f * inverseScaleX;
+ AAOffset.y *= 0.5f * inverseScaleY;
+
+ vec2 innerOffset = totalOffset;
+ scaleOffsetForStrokeWidth(innerOffset, halfStrokeWidth, inverseScaleX, inverseScaleY);
+ vec2 outerOffset = innerOffset + AAOffset;
+ innerOffset -= AAOffset;
+
+ // TODO: support square cap by changing this offset to incorporate halfStrokeWidth
+ vec2 capAAOffset(AAOffset.y, -AAOffset.x);
+ AlphaVertex::set(&buffer[0],
+ last->position[0] + outerOffset.x + capAAOffset.x,
+ last->position[1] + outerOffset.y + capAAOffset.y,
+ 0.0f);
+ AlphaVertex::set(&buffer[1],
+ last->position[0] + innerOffset.x - capAAOffset.x,
+ last->position[1] + innerOffset.y - capAAOffset.y,
+ maxAlpha);
+
+ AlphaVertex::set(&buffer[2 * offset + 6],
+ last->position[0] - outerOffset.x + capAAOffset.x,
+ last->position[1] - outerOffset.y + capAAOffset.y,
+ 0.0f);
+ AlphaVertex::set(&buffer[2 * offset + 7],
+ last->position[0] - innerOffset.x - capAAOffset.x,
+ last->position[1] - innerOffset.y - capAAOffset.y,
+ maxAlpha);
+ copyAlphaVertex(&buffer[2 * offset + 8], &buffer[0]);
+ copyAlphaVertex(&buffer[2 * offset + 9], &buffer[1]);
+ copyAlphaVertex(&buffer[2 * offset + 10], &buffer[1]); // degenerate tris (the only two!)
+ copyAlphaVertex(&buffer[2 * offset + 11], &buffer[2 * offset + 7]);
+ }
+
+ for (unsigned int i = 1; i < vertices.size() - 1; i++) {
+ const Vertex* next = &(vertices[i + 1]);
+ vec2 nextNormal(next->position[1] - current->position[1],
+ current->position[0] - next->position[0]);
+ nextNormal.normalize();
+
+ vec2 totalOffset = totalOffsetFromNormals(lastNormal, nextNormal);
+ vec2 AAOffset = totalOffset;
+ AAOffset.x *= 0.5f * inverseScaleX;
+ AAOffset.y *= 0.5f * inverseScaleY;
+
+ vec2 innerOffset = totalOffset;
+ scaleOffsetForStrokeWidth(innerOffset, halfStrokeWidth, inverseScaleX, inverseScaleY);
+ vec2 outerOffset = innerOffset + AAOffset;
+ innerOffset -= AAOffset;
+
+ AlphaVertex::set(&buffer[currentAAOuterIndex++],
+ current->position[0] + outerOffset.x,
+ current->position[1] + outerOffset.y,
+ 0.0f);
+ AlphaVertex::set(&buffer[currentAAOuterIndex++],
+ current->position[0] + innerOffset.x,
+ current->position[1] + innerOffset.y,
+ maxAlpha);
+
+ AlphaVertex::set(&buffer[currentStrokeIndex++],
+ current->position[0] + innerOffset.x,
+ current->position[1] + innerOffset.y,
+ maxAlpha);
+ AlphaVertex::set(&buffer[currentStrokeIndex++],
+ current->position[0] - innerOffset.x,
+ current->position[1] - innerOffset.y,
+ maxAlpha);
+
+ AlphaVertex::set(&buffer[currentAAInnerIndex--],
+ current->position[0] - innerOffset.x,
+ current->position[1] - innerOffset.y,
+ maxAlpha);
+ AlphaVertex::set(&buffer[currentAAInnerIndex--],
+ current->position[0] - outerOffset.x,
+ current->position[1] - outerOffset.y,
+ 0.0f);
+
+ last = current;
+ current = next;
+ lastNormal = nextNormal;
+ }
+
+ {
+ // end cap
+ vec2 totalOffset = lastNormal;
+ vec2 AAOffset = totalOffset;
+ AAOffset.x *= 0.5f * inverseScaleX;
+ AAOffset.y *= 0.5f * inverseScaleY;
+
+ vec2 innerOffset = totalOffset;
+ scaleOffsetForStrokeWidth(innerOffset, halfStrokeWidth, inverseScaleX, inverseScaleY);
+ vec2 outerOffset = innerOffset + AAOffset;
+ innerOffset -= AAOffset;
+
+ // TODO: support square cap by changing this offset to incorporate halfStrokeWidth
+ vec2 capAAOffset(-AAOffset.y, AAOffset.x);
+
+ AlphaVertex::set(&buffer[offset + 2],
+ current->position[0] + outerOffset.x + capAAOffset.x,
+ current->position[1] + outerOffset.y + capAAOffset.y,
+ 0.0f);
+ AlphaVertex::set(&buffer[offset + 3],
+ current->position[0] + innerOffset.x - capAAOffset.x,
+ current->position[1] + innerOffset.y - capAAOffset.y,
+ maxAlpha);
+
+ AlphaVertex::set(&buffer[offset + 4],
+ current->position[0] - outerOffset.x + capAAOffset.x,
+ current->position[1] - outerOffset.y + capAAOffset.y,
+ 0.0f);
+ AlphaVertex::set(&buffer[offset + 5],
+ current->position[0] - innerOffset.x - capAAOffset.x,
+ current->position[1] - innerOffset.y - capAAOffset.y,
+ maxAlpha);
+
+ copyAlphaVertex(&buffer[vertexBuffer.getSize() - 2], &buffer[offset + 3]);
+ copyAlphaVertex(&buffer[vertexBuffer.getSize() - 1], &buffer[offset + 5]);
+ }
+
+#if VERTEX_DEBUG
+ for (unsigned int i = 0; i < vertexBuffer.getSize(); i++) {
+ ALOGD("point at %f %f, alpha %f", buffer[i].position[0], buffer[i].position[1], buffer[i].alpha);
+ }
+#endif
+}
+
+
void getStrokeVerticesFromPerimeterAA(const Vector<Vertex>& perimeter, float halfStrokeWidth,
VertexBuffer& vertexBuffer, float inverseScaleX, float inverseScaleY) {
AlphaVertex* buffer = vertexBuffer.alloc<AlphaVertex>(6 * perimeter.size() + 8);
@@ -242,13 +454,7 @@
AAOffset.y *= 0.5f * inverseScaleY;
vec2 innerOffset = totalOffset;
- if (halfStrokeWidth == 0.0f) {
- // hairline! - compensate for scale
- innerOffset.x *= 0.5f * inverseScaleX;
- innerOffset.y *= 0.5f * inverseScaleY;
- } else {
- innerOffset *= halfStrokeWidth;
- }
+ scaleOffsetForStrokeWidth(innerOffset, halfStrokeWidth, inverseScaleX, inverseScaleY);
vec2 outerOffset = innerOffset + AAOffset;
innerOffset -= AAOffset;
@@ -296,6 +502,12 @@
copyAlphaVertex(&buffer[currentAAInnerIndex++], &buffer[2 * offset]);
copyAlphaVertex(&buffer[currentAAInnerIndex++], &buffer[2 * offset + 1]);
// don't need to create last degenerate tri
+
+#if VERTEX_DEBUG
+ for (unsigned int i = 0; i < vertexBuffer.getSize(); i++) {
+ ALOGD("point at %f %f, alpha %f", buffer[i].position[0], buffer[i].position[1], buffer[i].alpha);
+ }
+#endif
}
void PathRenderer::convexPathVertices(const SkPath &path, const SkPaint* paint,
@@ -320,7 +532,10 @@
threshInvScaleY *= bounds.height() / (bounds.height() + paint->getStrokeWidth());
}
}
- convexPathPerimeterVertices(path, threshInvScaleX * threshInvScaleX,
+
+ // force close if we're filling the path, since fill path expects closed perimeter.
+ bool forceClose = style != SkPaint::kStroke_Style;
+ bool wasClosed = convexPathPerimeterVertices(path, forceClose, threshInvScaleX * threshInvScaleX,
threshInvScaleY * threshInvScaleY, tempVertices);
if (!tempVertices.size()) {
@@ -337,11 +552,22 @@
if (style == SkPaint::kStroke_Style) {
float halfStrokeWidth = paint->getStrokeWidth() * 0.5f;
if (!isAA) {
- getStrokeVerticesFromPerimeter(tempVertices, halfStrokeWidth, vertexBuffer,
- inverseScaleX, inverseScaleY);
+ if (wasClosed) {
+ getStrokeVerticesFromPerimeter(tempVertices, halfStrokeWidth, vertexBuffer,
+ inverseScaleX, inverseScaleY);
+ } else {
+ getStrokeVerticesFromUnclosedVertices(tempVertices, halfStrokeWidth, vertexBuffer,
+ inverseScaleX, inverseScaleY);
+ }
+
} else {
- getStrokeVerticesFromPerimeterAA(tempVertices, halfStrokeWidth, vertexBuffer,
- inverseScaleX, inverseScaleY);
+ if (wasClosed) {
+ getStrokeVerticesFromPerimeterAA(tempVertices, halfStrokeWidth, vertexBuffer,
+ inverseScaleX, inverseScaleY);
+ } else {
+ getStrokeVerticesFromUnclosedVerticesAA(tempVertices, halfStrokeWidth, vertexBuffer,
+ inverseScaleX, inverseScaleY);
+ }
}
} else {
// For kStrokeAndFill style, the path should be adjusted externally, as it will be treated as a fill here.
@@ -354,19 +580,27 @@
}
-void PathRenderer::convexPathPerimeterVertices(const SkPath& path,
+void pushToVector(Vector<Vertex>& vertices, float x, float y) {
+ // TODO: make this not yuck
+ vertices.push();
+ Vertex* newVertex = &(vertices.editArray()[vertices.size() - 1]);
+ Vertex::set(newVertex, x, y);
+}
+
+bool PathRenderer::convexPathPerimeterVertices(const SkPath& path, bool forceClose,
float sqrInvScaleX, float sqrInvScaleY, Vector<Vertex>& outputVertices) {
ATRACE_CALL();
- SkPath::Iter iter(path, true);
- SkPoint pos;
+ // TODO: to support joins other than sharp miter, join vertices should be labelled in the
+ // perimeter, or resolved into more vertices. Reconsider forceClose-ing in that case.
+ SkPath::Iter iter(path, forceClose);
SkPoint pts[4];
SkPath::Verb v;
Vertex* newVertex = 0;
while (SkPath::kDone_Verb != (v = iter.next(pts))) {
switch (v) {
case SkPath::kMove_Verb:
- pos = pts[0];
+ pushToVector(outputVertices, pts[0].x(), pts[0].y());
ALOGV("Move to pos %f %f", pts[0].x(), pts[0].y());
break;
case SkPath::kClose_Verb:
@@ -377,10 +611,7 @@
pts[0].x(), pts[0].y(),
pts[1].x(), pts[1].y());
- // TODO: make this not yuck
- outputVertices.push();
- newVertex = &(outputVertices.editArray()[outputVertices.size() - 1]);
- Vertex::set(newVertex, pts[1].x(), pts[1].y());
+ pushToVector(outputVertices, pts[1].x(), pts[1].y());
break;
case SkPath::kQuad_Verb:
ALOGV("kQuad_Verb");
@@ -403,6 +634,14 @@
break;
}
}
+
+ int size = outputVertices.size();
+ if (size >= 2 && outputVertices[0].position[0] == outputVertices[size - 1].position[0] &&
+ outputVertices[0].position[1] == outputVertices[size - 1].position[1]) {
+ outputVertices.pop();
+ return true;
+ }
+ return false;
}
void PathRenderer::recursiveCubicBezierVertices(
@@ -419,10 +658,7 @@
if (d * d < THRESHOLD * THRESHOLD * (dx * dx * sqrInvScaleY + dy * dy * sqrInvScaleX)) {
// below thresh, draw line by adding endpoint
- // TODO: make this not yuck
- outputVertices.push();
- Vertex* newVertex = &(outputVertices.editArray()[outputVertices.size() - 1]);
- Vertex::set(newVertex, p2x, p2y);
+ pushToVector(outputVertices, p2x, p2y);
} else {
float p1c1x = (p1x + c1x) * 0.5f;
float p1c1y = (p1y + c1y) * 0.5f;
@@ -463,10 +699,7 @@
if (d * d < THRESHOLD * THRESHOLD * (dx * dx * sqrInvScaleY + dy * dy * sqrInvScaleX)) {
// below thresh, draw line by adding endpoint
- // TODO: make this not yuck
- outputVertices.push();
- Vertex* newVertex = &(outputVertices.editArray()[outputVertices.size() - 1]);
- Vertex::set(newVertex, bx, by);
+ pushToVector(outputVertices, bx, by);
} else {
float acx = (ax + cx) * 0.5f;
float bcx = (bx + cx) * 0.5f;
diff --git a/libs/hwui/PathRenderer.h b/libs/hwui/PathRenderer.h
index 28a5b90..e9f347b 100644
--- a/libs/hwui/PathRenderer.h
+++ b/libs/hwui/PathRenderer.h
@@ -71,10 +71,8 @@
const mat4 *transform, VertexBuffer& vertexBuffer);
private:
- static void convexPathPerimeterVertices(
- const SkPath &path,
- float sqrInvScaleX, float sqrInvScaleY,
- Vector<Vertex> &outputVertices);
+ static bool convexPathPerimeterVertices(const SkPath &path, bool forceClose,
+ float sqrInvScaleX, float sqrInvScaleY, Vector<Vertex> &outputVertices);
/*
endpoints a & b,
diff --git a/libs/hwui/Texture.h b/libs/hwui/Texture.h
index 03e2172..8d88bdc 100644
--- a/libs/hwui/Texture.h
+++ b/libs/hwui/Texture.h
@@ -36,6 +36,8 @@
minFilter = GL_NEAREST;
magFilter = GL_NEAREST;
+ mipMap = false;
+
firstFilter = true;
firstWrap = true;
@@ -83,6 +85,8 @@
glBindTexture(renderTarget, id);
}
+ if (mipMap && min == GL_LINEAR) min = GL_LINEAR_MIPMAP_LINEAR;
+
glTexParameteri(renderTarget, GL_TEXTURE_MIN_FILTER, min);
glTexParameteri(renderTarget, GL_TEXTURE_MAG_FILTER, mag);
}
@@ -116,7 +120,12 @@
* Optional, size of the original bitmap.
*/
uint32_t bitmapSize;
+ /**
+ * Indicates whether this texture will use trilinear filtering.
+ */
+ bool mipMap;
+private:
/**
* Last wrap modes set on this texture. Defaults to GL_CLAMP_TO_EDGE.
*/
@@ -129,7 +138,6 @@
GLenum minFilter;
GLenum magFilter;
-private:
bool firstFilter;
bool firstWrap;
}; // struct Texture
diff --git a/libs/hwui/TextureCache.cpp b/libs/hwui/TextureCache.cpp
index 9fb61e4..10d112a 100644
--- a/libs/hwui/TextureCache.cpp
+++ b/libs/hwui/TextureCache.cpp
@@ -22,6 +22,7 @@
#include <utils/threads.h>
+#include "Caches.h"
#include "TextureCache.h"
#include "Properties.h"
@@ -216,8 +217,15 @@
return;
}
+ // We could also enable mipmapping if both bitmap dimensions are powers
+ // of 2 but we'd have to deal with size changes. Let's keep this simple
+ const bool canMipMap = Caches::getInstance().extensions.hasNPot();
+
+ // If the texture had mipmap enabled but not anymore,
+ // force a glTexImage2D to discard the mipmap levels
const bool resize = !regenerate || bitmap->width() != int(texture->width) ||
- bitmap->height() != int(texture->height);
+ bitmap->height() != int(texture->height) ||
+ (regenerate && canMipMap && texture->mipMap && !bitmap->hasHardwareMipMap());
if (!regenerate) {
glGenTextures(1, &texture->id);
@@ -228,25 +236,22 @@
texture->height = bitmap->height();
glBindTexture(GL_TEXTURE_2D, texture->id);
- if (!regenerate) {
- glPixelStorei(GL_UNPACK_ALIGNMENT, bitmap->bytesPerPixel());
- }
switch (bitmap->getConfig()) {
case SkBitmap::kA8_Config:
- if (!regenerate) {
- glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
- }
+ glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
uploadToTexture(resize, GL_ALPHA, bitmap->rowBytesAsPixels(), texture->height,
GL_UNSIGNED_BYTE, bitmap->getPixels());
texture->blend = true;
break;
case SkBitmap::kRGB_565_Config:
+ glPixelStorei(GL_UNPACK_ALIGNMENT, bitmap->bytesPerPixel());
uploadToTexture(resize, GL_RGB, bitmap->rowBytesAsPixels(), texture->height,
GL_UNSIGNED_SHORT_5_6_5, bitmap->getPixels());
texture->blend = false;
break;
case SkBitmap::kARGB_8888_Config:
+ glPixelStorei(GL_UNPACK_ALIGNMENT, bitmap->bytesPerPixel());
uploadToTexture(resize, GL_RGBA, bitmap->rowBytesAsPixels(), texture->height,
GL_UNSIGNED_BYTE, bitmap->getPixels());
// Do this after calling getPixels() to make sure Skia's deferred
@@ -255,6 +260,7 @@
break;
case SkBitmap::kARGB_4444_Config:
case SkBitmap::kIndex8_Config:
+ glPixelStorei(GL_UNPACK_ALIGNMENT, bitmap->bytesPerPixel());
uploadLoFiTexture(resize, bitmap, texture->width, texture->height);
texture->blend = !bitmap->isOpaque();
break;
@@ -263,6 +269,13 @@
break;
}
+ if (canMipMap) {
+ texture->mipMap = bitmap->hasHardwareMipMap();
+ if (texture->mipMap) {
+ glGenerateMipmap(GL_TEXTURE_2D);
+ }
+ }
+
if (!regenerate) {
texture->setFilter(GL_NEAREST);
texture->setWrap(GL_CLAMP_TO_EDGE);
diff --git a/media/java/android/media/AudioService.java b/media/java/android/media/AudioService.java
index f26d322..f77cbfb 100644
--- a/media/java/android/media/AudioService.java
+++ b/media/java/android/media/AudioService.java
@@ -153,11 +153,10 @@
private static final int MSG_SET_A2DP_CONNECTION_STATE = 22;
// end of messages handled under wakelock
private static final int MSG_SET_RSX_CONNECTION_STATE = 23; // change remote submix connection
- private static final int MSG_SET_FORCE_RSX_USE = 24; // force remote submix audio routing
- private static final int MSG_CHECK_MUSIC_ACTIVE = 25;
- private static final int MSG_BROADCAST_AUDIO_BECOMING_NOISY = 26;
- private static final int MSG_CONFIGURE_SAFE_MEDIA_VOLUME = 27;
- private static final int MSG_CONFIGURE_SAFE_MEDIA_VOLUME_FORCED = 28;
+ private static final int MSG_CHECK_MUSIC_ACTIVE = 24;
+ private static final int MSG_BROADCAST_AUDIO_BECOMING_NOISY = 25;
+ private static final int MSG_CONFIGURE_SAFE_MEDIA_VOLUME = 26;
+ private static final int MSG_CONFIGURE_SAFE_MEDIA_VOLUME_FORCED = 27;
// flags for MSG_PERSIST_VOLUME indicating if current and/or last audible volume should be
// persisted
@@ -2221,13 +2220,6 @@
on ? 1 : 0 /*arg1*/,
address /*arg2*/,
null/*obj*/, 0/*delay*/);
-
- // Note that we are currently forcing use of remote submix as soon as corresponding device
- // is made available
- sendMsg(mAudioHandler, MSG_SET_FORCE_RSX_USE, SENDMSG_REPLACE,
- AudioSystem.FOR_MEDIA,
- on ? AudioSystem.FORCE_REMOTE_SUBMIX : AudioSystem.FORCE_NONE,
- null/*obj*/, 0/*delay*/);
}
private void onSetRsxConnectionState(int available, int address) {
@@ -3320,7 +3312,6 @@
case MSG_SET_FORCE_USE:
case MSG_SET_FORCE_BT_A2DP_USE:
- case MSG_SET_FORCE_RSX_USE:
setForceUse(msg.arg1, msg.arg2);
break;
diff --git a/media/java/android/media/AudioSystem.java b/media/java/android/media/AudioSystem.java
index 260ddc7..dde2979 100644
--- a/media/java/android/media/AudioSystem.java
+++ b/media/java/android/media/AudioSystem.java
@@ -360,9 +360,8 @@
public static final int FORCE_ANALOG_DOCK = 8;
public static final int FORCE_DIGITAL_DOCK = 9;
public static final int FORCE_NO_BT_A2DP = 10;
- public static final int FORCE_REMOTE_SUBMIX = 11;
- public static final int FORCE_SYSTEM_ENFORCED = 12;
- private static final int NUM_FORCE_CONFIG = 13;
+ public static final int FORCE_SYSTEM_ENFORCED = 11;
+ private static final int NUM_FORCE_CONFIG = 12;
public static final int FORCE_DEFAULT = FORCE_NONE;
// usage for setForceUse, must match AudioSystem::force_use
diff --git a/media/java/android/media/videoeditor/MediaArtistNativeHelper.java b/media/java/android/media/videoeditor/MediaArtistNativeHelper.java
index 4756078..f4fccbe 100644
--- a/media/java/android/media/videoeditor/MediaArtistNativeHelper.java
+++ b/media/java/android/media/videoeditor/MediaArtistNativeHelper.java
@@ -3831,6 +3831,7 @@
outWidth, outHeight, Bitmap.Config.ARGB_8888);
// Copy int[] to IntBuffer
+ decBuffer.rewind();
decBuffer.put(decArray, 0, thumbnailSize);
decBuffer.rewind();
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/performance/MediaPlayerPerformance.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/performance/MediaPlayerPerformance.java
index 9b1098e..1c60401 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/performance/MediaPlayerPerformance.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/performance/MediaPlayerPerformance.java
@@ -114,10 +114,10 @@
mProcMemWriter = new BufferedWriter(new FileWriter
(new File(MEDIA_PROCMEM_OUTPUT), true));
mProcMemWriter.write(this.getName() + "\n");
- mMemWriter = new BufferedWriter(new FileWriter
- (new File(MEDIA_MEMORY_OUTPUT), true));
}
-
+ mMemWriter = new BufferedWriter(new FileWriter
+ (new File(MEDIA_MEMORY_OUTPUT), true));
+ mMemWriter.write(this.getName() + "\n");
}
@Override
@@ -126,10 +126,10 @@
MediaTestUtil.getNativeHeapDump(this.getName() + "_after");
if (MediaFrameworkPerfTestRunner.mGetProcmem) {
- mMemWriter.write("\n");
mProcMemWriter.close();
- mMemWriter.close();
}
+ mMemWriter.write("\n");
+ mMemWriter.close();
super.tearDown();
}
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_notifications_normal.png b/packages/SystemUI/res/drawable-hdpi/ic_notifications_normal.png
new file mode 100644
index 0000000..62afe76
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/ic_notifications_normal.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_notify_clear_normal.png b/packages/SystemUI/res/drawable-hdpi/ic_notify_clear_normal.png
index a54761f..ead184d 100644
--- a/packages/SystemUI/res/drawable-hdpi/ic_notify_clear_normal.png
+++ b/packages/SystemUI/res/drawable-hdpi/ic_notify_clear_normal.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_notify_clear_pressed.png b/packages/SystemUI/res/drawable-hdpi/ic_notify_clear_pressed.png
index f3f336c..203e232 100644
--- a/packages/SystemUI/res/drawable-hdpi/ic_notify_clear_pressed.png
+++ b/packages/SystemUI/res/drawable-hdpi/ic_notify_clear_pressed.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_notify_open_normal.png b/packages/SystemUI/res/drawable-hdpi/ic_notify_open_normal.png
new file mode 100644
index 0000000..2adafea
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/ic_notify_open_normal.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_notify_open_pressed.png b/packages/SystemUI/res/drawable-hdpi/ic_notify_open_pressed.png
new file mode 100644
index 0000000..8521ffc
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/ic_notify_open_pressed.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_notify_quicksettings_normal.png b/packages/SystemUI/res/drawable-hdpi/ic_notify_quicksettings_normal.png
index 55c46b0..4436359 100644
--- a/packages/SystemUI/res/drawable-hdpi/ic_notify_quicksettings_normal.png
+++ b/packages/SystemUI/res/drawable-hdpi/ic_notify_quicksettings_normal.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_notify_quicksettings_pressed.png b/packages/SystemUI/res/drawable-hdpi/ic_notify_quicksettings_pressed.png
index e30cb8f..c86710d 100644
--- a/packages/SystemUI/res/drawable-hdpi/ic_notify_quicksettings_pressed.png
+++ b/packages/SystemUI/res/drawable-hdpi/ic_notify_quicksettings_pressed.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_notifications_normal.png b/packages/SystemUI/res/drawable-mdpi/ic_notifications_normal.png
new file mode 100644
index 0000000..62afe76
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/ic_notifications_normal.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_notify_clear_normal.png b/packages/SystemUI/res/drawable-mdpi/ic_notify_clear_normal.png
index b44b527..5dacccb 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_notify_clear_normal.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_notify_clear_normal.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_notify_clear_pressed.png b/packages/SystemUI/res/drawable-mdpi/ic_notify_clear_pressed.png
index 94c8165..f1f6b00 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_notify_clear_pressed.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_notify_clear_pressed.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_notify_open_normal.png b/packages/SystemUI/res/drawable-mdpi/ic_notify_open_normal.png
new file mode 100644
index 0000000..2ab0cd7
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/ic_notify_open_normal.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_notify_open_pressed.png b/packages/SystemUI/res/drawable-mdpi/ic_notify_open_pressed.png
new file mode 100644
index 0000000..49ac94b
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/ic_notify_open_pressed.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_notify_quicksettings_normal.png b/packages/SystemUI/res/drawable-mdpi/ic_notify_quicksettings_normal.png
index b1910cf..09d2c55 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_notify_quicksettings_normal.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_notify_quicksettings_normal.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_notify_quicksettings_pressed.png b/packages/SystemUI/res/drawable-mdpi/ic_notify_quicksettings_pressed.png
index 3abafdd..322d1a7 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_notify_quicksettings_pressed.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_notify_quicksettings_pressed.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_notifications_normal.png b/packages/SystemUI/res/drawable-xhdpi/ic_notifications_normal.png
new file mode 100644
index 0000000..983302c
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_notifications_normal.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_notify_clear_normal.png b/packages/SystemUI/res/drawable-xhdpi/ic_notify_clear_normal.png
index 870beb4..c882e9a 100644
--- a/packages/SystemUI/res/drawable-xhdpi/ic_notify_clear_normal.png
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_notify_clear_normal.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_notify_clear_pressed.png b/packages/SystemUI/res/drawable-xhdpi/ic_notify_clear_pressed.png
index 94a4646..992b50d 100644
--- a/packages/SystemUI/res/drawable-xhdpi/ic_notify_clear_pressed.png
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_notify_clear_pressed.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_notify_open_normal.png b/packages/SystemUI/res/drawable-xhdpi/ic_notify_open_normal.png
new file mode 100644
index 0000000..b0e35a1
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_notify_open_normal.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_notify_open_pressed.png b/packages/SystemUI/res/drawable-xhdpi/ic_notify_open_pressed.png
new file mode 100644
index 0000000..42bbbbc
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_notify_open_pressed.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_notify_quicksettings_normal.png b/packages/SystemUI/res/drawable-xhdpi/ic_notify_quicksettings_normal.png
index 5dc93c2..2d445279 100644
--- a/packages/SystemUI/res/drawable-xhdpi/ic_notify_quicksettings_normal.png
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_notify_quicksettings_normal.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_notify_quicksettings_pressed.png b/packages/SystemUI/res/drawable-xhdpi/ic_notify_quicksettings_pressed.png
index a97de79..ddf2c7a 100644
--- a/packages/SystemUI/res/drawable-xhdpi/ic_notify_quicksettings_pressed.png
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_notify_quicksettings_pressed.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable/ic_notifications.xml b/packages/SystemUI/res/drawable/ic_notifications.xml
new file mode 100644
index 0000000..68c4774
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_notifications.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2012 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:state_pressed="true"
+ android:drawable="@drawable/ic_notifications_normal" />
+ <item
+ android:drawable="@drawable/ic_notifications_normal" />
+</selector>
+
diff --git a/packages/SystemUI/res/drawable/ic_notify_button_bg.xml b/packages/SystemUI/res/drawable/ic_notify_button_bg.xml
new file mode 100644
index 0000000..85f1ea2
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_notify_button_bg.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2012 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:state_pressed="true" android:drawable="@*android:drawable/list_selector_pressed_holo_dark" />
+ <item android:drawable="@*android:drawable/list_selector_disabled_holo_dark" />
+</selector>
diff --git a/packages/SystemUI/res/drawable/ic_notify_clear.xml b/packages/SystemUI/res/drawable/ic_notify_clear.xml
index 9c432b2..2163198 100644
--- a/packages/SystemUI/res/drawable/ic_notify_clear.xml
+++ b/packages/SystemUI/res/drawable/ic_notify_clear.xml
@@ -16,6 +16,6 @@
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true"
- android:drawable="@drawable/ic_notify_clear_pressed" />
+ android:drawable="@drawable/ic_notify_clear_normal" />
<item android:drawable="@drawable/ic_notify_clear_normal" />
</selector>
diff --git a/packages/SystemUI/res/drawable/ic_notify_quicksettings.xml b/packages/SystemUI/res/drawable/ic_notify_quicksettings.xml
index d8ea524..7cf3175 100644
--- a/packages/SystemUI/res/drawable/ic_notify_quicksettings.xml
+++ b/packages/SystemUI/res/drawable/ic_notify_quicksettings.xml
@@ -16,7 +16,7 @@
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true"
- android:drawable="@drawable/ic_notify_quicksettings_pressed" />
+ android:drawable="@drawable/ic_notify_quicksettings_normal" />
<item
android:drawable="@drawable/ic_notify_quicksettings_normal" />
</selector>
diff --git a/packages/SystemUI/res/drawable/ic_notify_settings.xml b/packages/SystemUI/res/drawable/ic_notify_settings.xml
index 6579d8e..9303ca4 100644
--- a/packages/SystemUI/res/drawable/ic_notify_settings.xml
+++ b/packages/SystemUI/res/drawable/ic_notify_settings.xml
@@ -16,7 +16,7 @@
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true"
- android:drawable="@drawable/ic_notify_settings_pressed" />
+ android:drawable="@drawable/ic_notify_settings_normal" />
<item
android:drawable="@drawable/ic_notify_settings_normal" />
</selector>
diff --git a/packages/SystemUI/res/layout/flip_settings.xml b/packages/SystemUI/res/layout/flip_settings.xml
new file mode 100644
index 0000000..1b8898c5
--- /dev/null
+++ b/packages/SystemUI/res/layout/flip_settings.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2012 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<com.android.systemui.statusbar.phone.QuickSettingsScrollView
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginBottom="@dimen/close_handle_underlap"
+ android:overScrollMode="ifContentScrolls"
+ >
+ <com.android.systemui.statusbar.phone.QuickSettingsContainerView
+ android:id="@+id/quick_settings_container"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:animateLayoutChanges="true"
+ android:columnCount="@integer/quick_settings_num_columns"
+ />
+</com.android.systemui.statusbar.phone.QuickSettingsScrollView>
\ No newline at end of file
diff --git a/packages/SystemUI/res/layout/quick_settings_brightness_dialog.xml b/packages/SystemUI/res/layout/quick_settings_brightness_dialog.xml
index 5a5769b..f7b1d78 100644
--- a/packages/SystemUI/res/layout/quick_settings_brightness_dialog.xml
+++ b/packages/SystemUI/res/layout/quick_settings_brightness_dialog.xml
@@ -21,6 +21,8 @@
<ImageView
android:id="@+id/brightness_icon"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:paddingRight="10dp"
android:src="@drawable/ic_qs_brightness_auto_off"
diff --git a/packages/SystemUI/res/layout/status_bar_expanded.xml b/packages/SystemUI/res/layout/status_bar_expanded.xml
index cb4c227..b71025e 100644
--- a/packages/SystemUI/res/layout/status_bar_expanded.xml
+++ b/packages/SystemUI/res/layout/status_bar_expanded.xml
@@ -50,7 +50,7 @@
android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/close_handle_underlap"
android:orientation="vertical"
- android:animateLayoutChanges="true"
+ android:animateLayoutChanges="false"
>
<include layout="@layout/status_bar_expanded_header"
@@ -63,24 +63,35 @@
android:textAppearance="@style/TextAppearance.StatusBar.Expanded.Network.EmergencyOnly"
android:layout_height="wrap_content"
android:layout_width="match_parent"
- android:paddingBottom="4dp"
+ android:padding="4dp"
android:gravity="center"
android:visibility="gone"
/>
- <ScrollView
- android:id="@+id/scroll"
+ <FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:fadingEdge="none"
- android:overScrollMode="ifContentScrolls"
>
- <com.android.systemui.statusbar.policy.NotificationRowLayout
- android:id="@+id/latestItems"
+ <ViewStub android:id="@+id/flip_settings_stub"
+ android:layout="@layout/flip_settings"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- systemui:rowHeight="@dimen/notification_row_min_height"
/>
- </ScrollView>
+
+ <ScrollView
+ android:id="@+id/scroll"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:fadingEdge="none"
+ android:overScrollMode="ifContentScrolls"
+ >
+ <com.android.systemui.statusbar.policy.NotificationRowLayout
+ android:id="@+id/latestItems"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ systemui:rowHeight="@dimen/notification_row_min_height"
+ />
+ </ScrollView>
+ </FrameLayout>
</LinearLayout>
</com.android.systemui.statusbar.phone.NotificationPanelView><!-- end of sliding panel -->
diff --git a/packages/SystemUI/res/layout/status_bar_expanded_header.xml b/packages/SystemUI/res/layout/status_bar_expanded_header.xml
index c921837..03f03e2 100644
--- a/packages/SystemUI/res/layout/status_bar_expanded_header.xml
+++ b/packages/SystemUI/res/layout/status_bar_expanded_header.xml
@@ -20,37 +20,40 @@
xmlns:systemui="http://schemas.android.com/apk/res/com.android.systemui"
android:id="@+id/header"
android:layout_width="match_parent"
- android:layout_height="wrap_content"
+ android:layout_height="@dimen/notification_panel_header_height"
android:background="@drawable/notification_header_bg"
android:orientation="horizontal"
android:gravity="center_vertical"
android:baselineAligned="false"
>
- <LinearLayout
+ <RelativeLayout
+ android:id="@+id/datetime"
android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:orientation="horizontal"
+ android:layout_height="match_parent"
+ android:paddingLeft="8dp"
+ android:paddingRight="8dp"
+ android:background="@drawable/ic_notify_button_bg"
+ android:enabled="false"
>
<com.android.systemui.statusbar.policy.Clock
android:id="@+id/clock"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:layout_marginLeft="8dp"
+ android:layout_marginRight="8dp"
android:singleLine="true"
android:textAppearance="@style/TextAppearance.StatusBar.Expanded.Clock"
- android:gravity="bottom"
+ android:layout_centerVertical="true"
/>
<com.android.systemui.statusbar.policy.DateView android:id="@+id/date"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:layout_marginLeft="8dp"
- android:layout_marginRight="8dp"
android:singleLine="true"
android:textAppearance="@style/TextAppearance.StatusBar.Expanded.Date"
- android:gravity="bottom"
+ android:layout_toRightOf="@id/clock"
+ android:layout_alignBaseline="@id/clock"
/>
- </LinearLayout>
+ </RelativeLayout>
<Space
android:layout_width="0dp"
@@ -70,21 +73,37 @@
android:textColor="#00A040"
android:padding="2dp"
/>
-
- <ImageView android:id="@+id/settings_button"
- android:layout_width="50dp"
- android:layout_height="50dp"
- android:scaleType="center"
- android:src="@drawable/ic_notify_settings"
- android:contentDescription="@string/accessibility_settings_button"
- />
<ImageView android:id="@+id/clear_all_button"
android:layout_width="50dp"
android:layout_height="50dp"
- android:layout_marginLeft="12dp"
+ android:layout_marginRight="12dp"
android:scaleType="center"
android:src="@drawable/ic_notify_clear"
+ android:background="@drawable/ic_notify_button_bg"
android:contentDescription="@string/accessibility_clear_all"
/>
+
+ <FrameLayout
+ android:layout_width="50dp"
+ android:layout_height="50dp"
+ >
+ <ImageView android:id="@+id/settings_button"
+ android:layout_width="50dp"
+ android:layout_height="50dp"
+ android:scaleType="center"
+ android:src="@drawable/ic_notify_settings"
+ android:background="@drawable/ic_notify_button_bg"
+ android:contentDescription="@string/accessibility_settings_button"
+ />
+ <ImageView android:id="@+id/notification_button"
+ android:layout_width="50dp"
+ android:layout_height="50dp"
+ android:scaleType="center"
+ android:src="@drawable/ic_notifications"
+ android:background="@drawable/ic_notify_button_bg"
+ android:visibility="gone"
+ android:contentDescription="@string/accessibility_notifications_button"
+ />
+ </FrameLayout>
</LinearLayout>
diff --git a/packages/SystemUI/res/layout/super_status_bar.xml b/packages/SystemUI/res/layout/super_status_bar.xml
index 07aca6c..2b56618 100644
--- a/packages/SystemUI/res/layout/super_status_bar.xml
+++ b/packages/SystemUI/res/layout/super_status_bar.xml
@@ -36,7 +36,6 @@
android:id="@+id/panel_holder"
android:layout_width="match_parent"
android:layout_height="match_parent"
- android:layout_marginTop="@*android:dimen/status_bar_height"
>
<include layout="@layout/status_bar_expanded"
android:layout_width="match_parent"
diff --git a/packages/SystemUI/res/layout/system_bar_notification_panel_title.xml b/packages/SystemUI/res/layout/system_bar_notification_panel_title.xml
index 2d1bda4..59544f4 100644
--- a/packages/SystemUI/res/layout/system_bar_notification_panel_title.xml
+++ b/packages/SystemUI/res/layout/system_bar_notification_panel_title.xml
@@ -170,7 +170,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_sysbar_quicksettings"
- android:contentDescription="@string/accessibility_settings_button"
+ android:contentDescription="@string/accessibility_desc_quick_settings"
/>
<ImageView
diff --git a/packages/SystemUI/res/values-af/strings.xml b/packages/SystemUI/res/values-af/strings.xml
index d536793..69355d5 100644
--- a/packages/SystemUI/res/values-af/strings.xml
+++ b/packages/SystemUI/res/values-af/strings.xml
@@ -147,8 +147,7 @@
<string name="accessibility_notification_dismissed" msgid="854211387186306927">"Kennisgewing is toegemaak."</string>
<string name="accessibility_desc_notification_shade" msgid="4690274844447504208">"Kennisgewingskerm."</string>
<string name="accessibility_desc_quick_settings" msgid="6186378411582437046">"Vinnige instellings."</string>
- <!-- no translation found for accessibility_desc_recent_apps (9014032916410590027) -->
- <skip />
+ <string name="accessibility_desc_recent_apps" msgid="9014032916410590027">"Onlangse programme."</string>
<string name="accessibility_quick_settings_user" msgid="1104846699869476855">"Gebruiker <xliff:g id="USER">%s</xliff:g>."</string>
<string name="accessibility_quick_settings_wifi" msgid="6099781031669728709">"<xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="NETWORK">%2$s</xliff:g>"</string>
<string name="accessibility_quick_settings_mobile" msgid="4876806564086241341">"Mobiele <xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="TYPE">%2$s</xliff:g>. <xliff:g id="NETWORK">%3$s</xliff:g>."</string>
diff --git a/packages/SystemUI/res/values-am/strings.xml b/packages/SystemUI/res/values-am/strings.xml
index a588b42..735da78 100644
--- a/packages/SystemUI/res/values-am/strings.xml
+++ b/packages/SystemUI/res/values-am/strings.xml
@@ -147,8 +147,7 @@
<string name="accessibility_notification_dismissed" msgid="854211387186306927">"ማሳወቂያ ተወግዷል።"</string>
<string name="accessibility_desc_notification_shade" msgid="4690274844447504208">"የማሳወቂያ ጥላ።"</string>
<string name="accessibility_desc_quick_settings" msgid="6186378411582437046">"ፈጣን ቅንብሮች።"</string>
- <!-- no translation found for accessibility_desc_recent_apps (9014032916410590027) -->
- <skip />
+ <string name="accessibility_desc_recent_apps" msgid="9014032916410590027">"የቅርብ ጊዜ መተግበሪያዎች።"</string>
<string name="accessibility_quick_settings_user" msgid="1104846699869476855">"ተጠቃሚ <xliff:g id="USER">%s</xliff:g>።"</string>
<string name="accessibility_quick_settings_wifi" msgid="6099781031669728709">"<xliff:g id="SIGNAL">%1$s</xliff:g>። <xliff:g id="NETWORK">%2$s</xliff:g>"</string>
<string name="accessibility_quick_settings_mobile" msgid="4876806564086241341">"ተንቀሳቃሽ ስልክ <xliff:g id="SIGNAL">%1$s</xliff:g>። <xliff:g id="TYPE">%2$s</xliff:g>። <xliff:g id="NETWORK">%3$s</xliff:g>።"</string>
diff --git a/packages/SystemUI/res/values-ar/strings.xml b/packages/SystemUI/res/values-ar/strings.xml
index f7f963e..da78d29 100644
--- a/packages/SystemUI/res/values-ar/strings.xml
+++ b/packages/SystemUI/res/values-ar/strings.xml
@@ -147,8 +147,7 @@
<string name="accessibility_notification_dismissed" msgid="854211387186306927">"تم تجاهل الإشعار."</string>
<string name="accessibility_desc_notification_shade" msgid="4690274844447504208">"مركز الإشعارات."</string>
<string name="accessibility_desc_quick_settings" msgid="6186378411582437046">"الإعدادات السريعة."</string>
- <!-- no translation found for accessibility_desc_recent_apps (9014032916410590027) -->
- <skip />
+ <string name="accessibility_desc_recent_apps" msgid="9014032916410590027">"التطبيقات الحديثة"</string>
<string name="accessibility_quick_settings_user" msgid="1104846699869476855">"المستخدم <xliff:g id="USER">%s</xliff:g>."</string>
<string name="accessibility_quick_settings_wifi" msgid="6099781031669728709">"<xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="NETWORK">%2$s</xliff:g>"</string>
<string name="accessibility_quick_settings_mobile" msgid="4876806564086241341">"الجوال <xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="TYPE">%2$s</xliff:g>. <xliff:g id="NETWORK">%3$s</xliff:g>."</string>
diff --git a/packages/SystemUI/res/values-be/strings.xml b/packages/SystemUI/res/values-be/strings.xml
index 4b8aad2..79bc53a 100644
--- a/packages/SystemUI/res/values-be/strings.xml
+++ b/packages/SystemUI/res/values-be/strings.xml
@@ -149,8 +149,7 @@
<string name="accessibility_notification_dismissed" msgid="854211387186306927">"Апавяшчэнне прапушчана."</string>
<string name="accessibility_desc_notification_shade" msgid="4690274844447504208">"Цень апавяшчэння.."</string>
<string name="accessibility_desc_quick_settings" msgid="6186378411582437046">"Хуткія налады."</string>
- <!-- no translation found for accessibility_desc_recent_apps (9014032916410590027) -->
- <skip />
+ <string name="accessibility_desc_recent_apps" msgid="9014032916410590027">"Апошнія прыкладанні."</string>
<string name="accessibility_quick_settings_user" msgid="1104846699869476855">"Карыстальнік: <xliff:g id="USER">%s</xliff:g>."</string>
<string name="accessibility_quick_settings_wifi" msgid="6099781031669728709">"<xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="NETWORK">%2$s</xliff:g>"</string>
<string name="accessibility_quick_settings_mobile" msgid="4876806564086241341">"Мабiльны сiгнал: <xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="TYPE">%2$s</xliff:g>. <xliff:g id="NETWORK">%3$s</xliff:g>."</string>
diff --git a/packages/SystemUI/res/values-bg/strings.xml b/packages/SystemUI/res/values-bg/strings.xml
index c05fc59..59ba693 100644
--- a/packages/SystemUI/res/values-bg/strings.xml
+++ b/packages/SystemUI/res/values-bg/strings.xml
@@ -147,8 +147,7 @@
<string name="accessibility_notification_dismissed" msgid="854211387186306927">"Известието е отхвърлено."</string>
<string name="accessibility_desc_notification_shade" msgid="4690274844447504208">"Падащ панел с известия."</string>
<string name="accessibility_desc_quick_settings" msgid="6186378411582437046">"Бързи настройки."</string>
- <!-- no translation found for accessibility_desc_recent_apps (9014032916410590027) -->
- <skip />
+ <string name="accessibility_desc_recent_apps" msgid="9014032916410590027">"Скорошни приложения."</string>
<string name="accessibility_quick_settings_user" msgid="1104846699869476855">"Потребител: <xliff:g id="USER">%s</xliff:g>."</string>
<string name="accessibility_quick_settings_wifi" msgid="6099781031669728709">"<xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="NETWORK">%2$s</xliff:g>"</string>
<string name="accessibility_quick_settings_mobile" msgid="4876806564086241341">"Мобилно устройство: <xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="TYPE">%2$s</xliff:g>. <xliff:g id="NETWORK">%3$s</xliff:g>."</string>
diff --git a/packages/SystemUI/res/values-ca/strings.xml b/packages/SystemUI/res/values-ca/strings.xml
index 13fb675..bf10ce2 100644
--- a/packages/SystemUI/res/values-ca/strings.xml
+++ b/packages/SystemUI/res/values-ca/strings.xml
@@ -149,8 +149,7 @@
<string name="accessibility_notification_dismissed" msgid="854211387186306927">"Notificació omesa."</string>
<string name="accessibility_desc_notification_shade" msgid="4690274844447504208">"Capa de notificació."</string>
<string name="accessibility_desc_quick_settings" msgid="6186378411582437046">"Configuració ràpida."</string>
- <!-- no translation found for accessibility_desc_recent_apps (9014032916410590027) -->
- <skip />
+ <string name="accessibility_desc_recent_apps" msgid="9014032916410590027">"Aplicacions recents."</string>
<string name="accessibility_quick_settings_user" msgid="1104846699869476855">"Usuari <xliff:g id="USER">%s</xliff:g>."</string>
<string name="accessibility_quick_settings_wifi" msgid="6099781031669728709">"<xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="NETWORK">%2$s</xliff:g>"</string>
<string name="accessibility_quick_settings_mobile" msgid="4876806564086241341">"Mòbil <xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="TYPE">%2$s</xliff:g>. <xliff:g id="NETWORK">%3$s</xliff:g>."</string>
diff --git a/packages/SystemUI/res/values-cs/strings.xml b/packages/SystemUI/res/values-cs/strings.xml
index 72fe18e..5e632fa 100644
--- a/packages/SystemUI/res/values-cs/strings.xml
+++ b/packages/SystemUI/res/values-cs/strings.xml
@@ -149,8 +149,7 @@
<string name="accessibility_notification_dismissed" msgid="854211387186306927">"Oznámení je zavřeno."</string>
<string name="accessibility_desc_notification_shade" msgid="4690274844447504208">"Panel oznámení."</string>
<string name="accessibility_desc_quick_settings" msgid="6186378411582437046">"Rychlé nastavení."</string>
- <!-- no translation found for accessibility_desc_recent_apps (9014032916410590027) -->
- <skip />
+ <string name="accessibility_desc_recent_apps" msgid="9014032916410590027">"Naposledy použité aplikace"</string>
<string name="accessibility_quick_settings_user" msgid="1104846699869476855">"Uživatel <xliff:g id="USER">%s</xliff:g>."</string>
<string name="accessibility_quick_settings_wifi" msgid="6099781031669728709">"<xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="NETWORK">%2$s</xliff:g>"</string>
<string name="accessibility_quick_settings_mobile" msgid="4876806564086241341">"Mobil: <xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="TYPE">%2$s</xliff:g>. <xliff:g id="NETWORK">%3$s</xliff:g>."</string>
diff --git a/packages/SystemUI/res/values-da/strings.xml b/packages/SystemUI/res/values-da/strings.xml
index a04673b..671f292 100644
--- a/packages/SystemUI/res/values-da/strings.xml
+++ b/packages/SystemUI/res/values-da/strings.xml
@@ -147,8 +147,7 @@
<string name="accessibility_notification_dismissed" msgid="854211387186306927">"Underretningen er annulleret."</string>
<string name="accessibility_desc_notification_shade" msgid="4690274844447504208">"Underretningspanel."</string>
<string name="accessibility_desc_quick_settings" msgid="6186378411582437046">"Hurtige indstillinger."</string>
- <!-- no translation found for accessibility_desc_recent_apps (9014032916410590027) -->
- <skip />
+ <string name="accessibility_desc_recent_apps" msgid="9014032916410590027">"Seneste apps"</string>
<string name="accessibility_quick_settings_user" msgid="1104846699869476855">"Bruger <xliff:g id="USER">%s</xliff:g>."</string>
<string name="accessibility_quick_settings_wifi" msgid="6099781031669728709">"<xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="NETWORK">%2$s</xliff:g>"</string>
<string name="accessibility_quick_settings_mobile" msgid="4876806564086241341">"Mobil <xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="TYPE">%2$s</xliff:g>. <xliff:g id="NETWORK">%3$s</xliff:g>."</string>
diff --git a/packages/SystemUI/res/values-de/strings.xml b/packages/SystemUI/res/values-de/strings.xml
index 2575d2c..3e767a0 100644
--- a/packages/SystemUI/res/values-de/strings.xml
+++ b/packages/SystemUI/res/values-de/strings.xml
@@ -149,8 +149,7 @@
<string name="accessibility_notification_dismissed" msgid="854211387186306927">"Benachrichtigung geschlossen"</string>
<string name="accessibility_desc_notification_shade" msgid="4690274844447504208">"Benachrichtigungsleiste"</string>
<string name="accessibility_desc_quick_settings" msgid="6186378411582437046">"Schnelleinstellungen"</string>
- <!-- no translation found for accessibility_desc_recent_apps (9014032916410590027) -->
- <skip />
+ <string name="accessibility_desc_recent_apps" msgid="9014032916410590027">"Kürzlich geöffnete Apps"</string>
<string name="accessibility_quick_settings_user" msgid="1104846699869476855">"Nutzer: <xliff:g id="USER">%s</xliff:g>"</string>
<string name="accessibility_quick_settings_wifi" msgid="6099781031669728709">"<xliff:g id="SIGNAL">%1$s</xliff:g>, <xliff:g id="NETWORK">%2$s</xliff:g>"</string>
<string name="accessibility_quick_settings_mobile" msgid="4876806564086241341">"Mobilfunkverbindung: <xliff:g id="SIGNAL">%1$s</xliff:g>, <xliff:g id="TYPE">%2$s</xliff:g>, <xliff:g id="NETWORK">%3$s</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-el/strings.xml b/packages/SystemUI/res/values-el/strings.xml
index a73c113..0665020 100644
--- a/packages/SystemUI/res/values-el/strings.xml
+++ b/packages/SystemUI/res/values-el/strings.xml
@@ -149,8 +149,7 @@
<string name="accessibility_notification_dismissed" msgid="854211387186306927">"Η ειδοποίηση έχει απορριφθεί."</string>
<string name="accessibility_desc_notification_shade" msgid="4690274844447504208">"Πλαίσιο σκίασης ειδοποιήσεων."</string>
<string name="accessibility_desc_quick_settings" msgid="6186378411582437046">"Γρήγορες ρυθμίσεις."</string>
- <!-- no translation found for accessibility_desc_recent_apps (9014032916410590027) -->
- <skip />
+ <string name="accessibility_desc_recent_apps" msgid="9014032916410590027">"Πρόσφατες εφαρμογές"</string>
<string name="accessibility_quick_settings_user" msgid="1104846699869476855">"Χρήστης <xliff:g id="USER">%s</xliff:g>."</string>
<string name="accessibility_quick_settings_wifi" msgid="6099781031669728709">"<xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="NETWORK">%2$s</xliff:g>"</string>
<string name="accessibility_quick_settings_mobile" msgid="4876806564086241341">"Κινητό <xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="TYPE">%2$s</xliff:g>. <xliff:g id="NETWORK">%3$s</xliff:g>."</string>
diff --git a/packages/SystemUI/res/values-en-rGB/strings.xml b/packages/SystemUI/res/values-en-rGB/strings.xml
index 1ad2c06..906b5c6 100644
--- a/packages/SystemUI/res/values-en-rGB/strings.xml
+++ b/packages/SystemUI/res/values-en-rGB/strings.xml
@@ -147,8 +147,7 @@
<string name="accessibility_notification_dismissed" msgid="854211387186306927">"Notification dismissed."</string>
<string name="accessibility_desc_notification_shade" msgid="4690274844447504208">"Notification shade."</string>
<string name="accessibility_desc_quick_settings" msgid="6186378411582437046">"Quick settings."</string>
- <!-- no translation found for accessibility_desc_recent_apps (9014032916410590027) -->
- <skip />
+ <string name="accessibility_desc_recent_apps" msgid="9014032916410590027">"Recent apps"</string>
<string name="accessibility_quick_settings_user" msgid="1104846699869476855">"User <xliff:g id="USER">%s</xliff:g>."</string>
<string name="accessibility_quick_settings_wifi" msgid="6099781031669728709">"<xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="NETWORK">%2$s</xliff:g>"</string>
<string name="accessibility_quick_settings_mobile" msgid="4876806564086241341">"Mobile <xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="TYPE">%2$s</xliff:g>. <xliff:g id="NETWORK">%3$s</xliff:g>."</string>
diff --git a/packages/SystemUI/res/values-es-rUS/strings.xml b/packages/SystemUI/res/values-es-rUS/strings.xml
index 1460996..9bbd5d7 100644
--- a/packages/SystemUI/res/values-es-rUS/strings.xml
+++ b/packages/SystemUI/res/values-es-rUS/strings.xml
@@ -149,8 +149,7 @@
<string name="accessibility_notification_dismissed" msgid="854211387186306927">"Notificación ignorada"</string>
<string name="accessibility_desc_notification_shade" msgid="4690274844447504208">"Pantalla de notificaciones"</string>
<string name="accessibility_desc_quick_settings" msgid="6186378411582437046">"Configuración rápida"</string>
- <!-- no translation found for accessibility_desc_recent_apps (9014032916410590027) -->
- <skip />
+ <string name="accessibility_desc_recent_apps" msgid="9014032916410590027">"Aplicaciones recientes"</string>
<string name="accessibility_quick_settings_user" msgid="1104846699869476855">"Usuario <xliff:g id="USER">%s</xliff:g>"</string>
<string name="accessibility_quick_settings_wifi" msgid="6099781031669728709">"<xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="NETWORK">%2$s</xliff:g>"</string>
<string name="accessibility_quick_settings_mobile" msgid="4876806564086241341">"Móvil <xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="TYPE">%2$s</xliff:g>. <xliff:g id="NETWORK">%3$s</xliff:g>."</string>
diff --git a/packages/SystemUI/res/values-es/strings.xml b/packages/SystemUI/res/values-es/strings.xml
index 9f0fbda..90f93b2 100644
--- a/packages/SystemUI/res/values-es/strings.xml
+++ b/packages/SystemUI/res/values-es/strings.xml
@@ -147,8 +147,7 @@
<string name="accessibility_notification_dismissed" msgid="854211387186306927">"Notificación ignorada"</string>
<string name="accessibility_desc_notification_shade" msgid="4690274844447504208">"Pantalla de notificaciones"</string>
<string name="accessibility_desc_quick_settings" msgid="6186378411582437046">"Ajustes rápidos"</string>
- <!-- no translation found for accessibility_desc_recent_apps (9014032916410590027) -->
- <skip />
+ <string name="accessibility_desc_recent_apps" msgid="9014032916410590027">"Aplicaciones recientes"</string>
<string name="accessibility_quick_settings_user" msgid="1104846699869476855">"Usuario <xliff:g id="USER">%s</xliff:g>"</string>
<string name="accessibility_quick_settings_wifi" msgid="6099781031669728709">"<xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="NETWORK">%2$s</xliff:g>"</string>
<string name="accessibility_quick_settings_mobile" msgid="4876806564086241341">"Móvil <xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="TYPE">%2$s</xliff:g>. <xliff:g id="NETWORK">%3$s</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-et/strings.xml b/packages/SystemUI/res/values-et/strings.xml
index 7b4c31a..d77b26a 100644
--- a/packages/SystemUI/res/values-et/strings.xml
+++ b/packages/SystemUI/res/values-et/strings.xml
@@ -147,8 +147,7 @@
<string name="accessibility_notification_dismissed" msgid="854211387186306927">"Märguandest on loobutud."</string>
<string name="accessibility_desc_notification_shade" msgid="4690274844447504208">"Märguande vari."</string>
<string name="accessibility_desc_quick_settings" msgid="6186378411582437046">"Kiirseaded."</string>
- <!-- no translation found for accessibility_desc_recent_apps (9014032916410590027) -->
- <skip />
+ <string name="accessibility_desc_recent_apps" msgid="9014032916410590027">"Hiljutised rakendused"</string>
<string name="accessibility_quick_settings_user" msgid="1104846699869476855">"Kasutaja <xliff:g id="USER">%s</xliff:g>."</string>
<string name="accessibility_quick_settings_wifi" msgid="6099781031669728709">"<xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="NETWORK">%2$s</xliff:g>"</string>
<string name="accessibility_quick_settings_mobile" msgid="4876806564086241341">"Mobiili <xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="TYPE">%2$s</xliff:g>. <xliff:g id="NETWORK">%3$s</xliff:g>."</string>
diff --git a/packages/SystemUI/res/values-fa/strings.xml b/packages/SystemUI/res/values-fa/strings.xml
index d984bf8..6accc9f 100644
--- a/packages/SystemUI/res/values-fa/strings.xml
+++ b/packages/SystemUI/res/values-fa/strings.xml
@@ -147,8 +147,7 @@
<string name="accessibility_notification_dismissed" msgid="854211387186306927">"اعلان ردشد."</string>
<string name="accessibility_desc_notification_shade" msgid="4690274844447504208">"مجموعه اعلان."</string>
<string name="accessibility_desc_quick_settings" msgid="6186378411582437046">"تنظیمات سریع."</string>
- <!-- no translation found for accessibility_desc_recent_apps (9014032916410590027) -->
- <skip />
+ <string name="accessibility_desc_recent_apps" msgid="9014032916410590027">"برنامههای اخیر"</string>
<string name="accessibility_quick_settings_user" msgid="1104846699869476855">"کاربر <xliff:g id="USER">%s</xliff:g>."</string>
<string name="accessibility_quick_settings_wifi" msgid="6099781031669728709">"<xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="NETWORK">%2$s</xliff:g>"</string>
<string name="accessibility_quick_settings_mobile" msgid="4876806564086241341">"تلفن همراه <xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="TYPE">%2$s</xliff:g>. <xliff:g id="NETWORK">%3$s</xliff:g>."</string>
diff --git a/packages/SystemUI/res/values-fi/strings.xml b/packages/SystemUI/res/values-fi/strings.xml
index 9d28900..3bc0371 100644
--- a/packages/SystemUI/res/values-fi/strings.xml
+++ b/packages/SystemUI/res/values-fi/strings.xml
@@ -147,8 +147,7 @@
<string name="accessibility_notification_dismissed" msgid="854211387186306927">"Ilmoitus hylätty."</string>
<string name="accessibility_desc_notification_shade" msgid="4690274844447504208">"Ilmoitusalue."</string>
<string name="accessibility_desc_quick_settings" msgid="6186378411582437046">"Pika-asetukset."</string>
- <!-- no translation found for accessibility_desc_recent_apps (9014032916410590027) -->
- <skip />
+ <string name="accessibility_desc_recent_apps" msgid="9014032916410590027">"Viimeaikaiset sovellukset"</string>
<string name="accessibility_quick_settings_user" msgid="1104846699869476855">"Käyttäjä: <xliff:g id="USER">%s</xliff:g>."</string>
<string name="accessibility_quick_settings_wifi" msgid="6099781031669728709">"<xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="NETWORK">%2$s</xliff:g>"</string>
<string name="accessibility_quick_settings_mobile" msgid="4876806564086241341">"Mobiiliverkkoyhteys: <xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="TYPE">%2$s</xliff:g>. <xliff:g id="NETWORK">%3$s</xliff:g>."</string>
diff --git a/packages/SystemUI/res/values-fr/strings.xml b/packages/SystemUI/res/values-fr/strings.xml
index ab98d24..02eb529 100644
--- a/packages/SystemUI/res/values-fr/strings.xml
+++ b/packages/SystemUI/res/values-fr/strings.xml
@@ -149,8 +149,7 @@
<string name="accessibility_notification_dismissed" msgid="854211387186306927">"Notification masquée"</string>
<string name="accessibility_desc_notification_shade" msgid="4690274844447504208">"Volet des notifications"</string>
<string name="accessibility_desc_quick_settings" msgid="6186378411582437046">"Paramètres rapides"</string>
- <!-- no translation found for accessibility_desc_recent_apps (9014032916410590027) -->
- <skip />
+ <string name="accessibility_desc_recent_apps" msgid="9014032916410590027">"Applications récentes"</string>
<string name="accessibility_quick_settings_user" msgid="1104846699869476855">"Utilisateur <xliff:g id="USER">%s</xliff:g>"</string>
<string name="accessibility_quick_settings_wifi" msgid="6099781031669728709">"<xliff:g id="SIGNAL">%1$s</xliff:g>, <xliff:g id="NETWORK">%2$s</xliff:g>"</string>
<string name="accessibility_quick_settings_mobile" msgid="4876806564086241341">"Signal mobile : <xliff:g id="SIGNAL">%1$s</xliff:g>, <xliff:g id="TYPE">%2$s</xliff:g>, <xliff:g id="NETWORK">%3$s</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-hi/strings.xml b/packages/SystemUI/res/values-hi/strings.xml
index 718d267..e2bc2c3 100644
--- a/packages/SystemUI/res/values-hi/strings.xml
+++ b/packages/SystemUI/res/values-hi/strings.xml
@@ -147,8 +147,7 @@
<string name="accessibility_notification_dismissed" msgid="854211387186306927">"सूचना खारिज की गई."</string>
<string name="accessibility_desc_notification_shade" msgid="4690274844447504208">"सूचना शेड."</string>
<string name="accessibility_desc_quick_settings" msgid="6186378411582437046">"त्वरित सेटिंग."</string>
- <!-- no translation found for accessibility_desc_recent_apps (9014032916410590027) -->
- <skip />
+ <string name="accessibility_desc_recent_apps" msgid="9014032916410590027">"हाल ही के एप्लिकेशन."</string>
<string name="accessibility_quick_settings_user" msgid="1104846699869476855">"उपयोगकर्ता <xliff:g id="USER">%s</xliff:g>."</string>
<string name="accessibility_quick_settings_wifi" msgid="6099781031669728709">"<xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="NETWORK">%2$s</xliff:g>"</string>
<string name="accessibility_quick_settings_mobile" msgid="4876806564086241341">"मोबाइल <xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="TYPE">%2$s</xliff:g>. <xliff:g id="NETWORK">%3$s</xliff:g>."</string>
diff --git a/packages/SystemUI/res/values-hr/strings.xml b/packages/SystemUI/res/values-hr/strings.xml
index bd19a44..e318120 100644
--- a/packages/SystemUI/res/values-hr/strings.xml
+++ b/packages/SystemUI/res/values-hr/strings.xml
@@ -147,8 +147,7 @@
<string name="accessibility_notification_dismissed" msgid="854211387186306927">"Obavijest je odbačena."</string>
<string name="accessibility_desc_notification_shade" msgid="4690274844447504208">"Zaslon obavijesti."</string>
<string name="accessibility_desc_quick_settings" msgid="6186378411582437046">"Brze postavke."</string>
- <!-- no translation found for accessibility_desc_recent_apps (9014032916410590027) -->
- <skip />
+ <string name="accessibility_desc_recent_apps" msgid="9014032916410590027">"Nedavne aplikacije."</string>
<string name="accessibility_quick_settings_user" msgid="1104846699869476855">"Korisnik <xliff:g id="USER">%s</xliff:g>."</string>
<string name="accessibility_quick_settings_wifi" msgid="6099781031669728709">"<xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="NETWORK">%2$s</xliff:g>"</string>
<string name="accessibility_quick_settings_mobile" msgid="4876806564086241341">"Mobitel <xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="TYPE">%2$s</xliff:g>. <xliff:g id="NETWORK">%3$s</xliff:g>."</string>
diff --git a/packages/SystemUI/res/values-hu/strings.xml b/packages/SystemUI/res/values-hu/strings.xml
index 96bb897..3dafd2b 100644
--- a/packages/SystemUI/res/values-hu/strings.xml
+++ b/packages/SystemUI/res/values-hu/strings.xml
@@ -147,8 +147,7 @@
<string name="accessibility_notification_dismissed" msgid="854211387186306927">"Értesítés elvetve."</string>
<string name="accessibility_desc_notification_shade" msgid="4690274844447504208">"Értesítési felület."</string>
<string name="accessibility_desc_quick_settings" msgid="6186378411582437046">"Gyorsbeállítások."</string>
- <!-- no translation found for accessibility_desc_recent_apps (9014032916410590027) -->
- <skip />
+ <string name="accessibility_desc_recent_apps" msgid="9014032916410590027">"Legutóbbi alkalmazások"</string>
<string name="accessibility_quick_settings_user" msgid="1104846699869476855">"Felhasználó: <xliff:g id="USER">%s</xliff:g>."</string>
<string name="accessibility_quick_settings_wifi" msgid="6099781031669728709">"<xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="NETWORK">%2$s</xliff:g>"</string>
<string name="accessibility_quick_settings_mobile" msgid="4876806564086241341">"Mobil <xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="TYPE">%2$s</xliff:g>. <xliff:g id="NETWORK">%3$s</xliff:g>."</string>
diff --git a/packages/SystemUI/res/values-in/strings.xml b/packages/SystemUI/res/values-in/strings.xml
index dce8076..c26cdce 100644
--- a/packages/SystemUI/res/values-in/strings.xml
+++ b/packages/SystemUI/res/values-in/strings.xml
@@ -147,8 +147,7 @@
<string name="accessibility_notification_dismissed" msgid="854211387186306927">"Pemberitahuan disingkirkan."</string>
<string name="accessibility_desc_notification_shade" msgid="4690274844447504208">"Bayangan pemberitahuan."</string>
<string name="accessibility_desc_quick_settings" msgid="6186378411582437046">"Setelan cepat."</string>
- <!-- no translation found for accessibility_desc_recent_apps (9014032916410590027) -->
- <skip />
+ <string name="accessibility_desc_recent_apps" msgid="9014032916410590027">"Aplikasi terkini."</string>
<string name="accessibility_quick_settings_user" msgid="1104846699869476855">"Pengguna <xliff:g id="USER">%s</xliff:g>."</string>
<string name="accessibility_quick_settings_wifi" msgid="6099781031669728709">"<xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="NETWORK">%2$s</xliff:g>"</string>
<string name="accessibility_quick_settings_mobile" msgid="4876806564086241341">"Seluler <xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="TYPE">%2$s</xliff:g>. <xliff:g id="NETWORK">%3$s</xliff:g>."</string>
diff --git a/packages/SystemUI/res/values-it/strings.xml b/packages/SystemUI/res/values-it/strings.xml
index 8ce9f64..b5be2ac 100644
--- a/packages/SystemUI/res/values-it/strings.xml
+++ b/packages/SystemUI/res/values-it/strings.xml
@@ -149,8 +149,7 @@
<string name="accessibility_notification_dismissed" msgid="854211387186306927">"Notifica eliminata."</string>
<string name="accessibility_desc_notification_shade" msgid="4690274844447504208">"Area notifiche."</string>
<string name="accessibility_desc_quick_settings" msgid="6186378411582437046">"Impostazioni rapide."</string>
- <!-- no translation found for accessibility_desc_recent_apps (9014032916410590027) -->
- <skip />
+ <string name="accessibility_desc_recent_apps" msgid="9014032916410590027">"Applicazioni recenti."</string>
<string name="accessibility_quick_settings_user" msgid="1104846699869476855">"Utente <xliff:g id="USER">%s</xliff:g>."</string>
<string name="accessibility_quick_settings_wifi" msgid="6099781031669728709">"<xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="NETWORK">%2$s</xliff:g>"</string>
<string name="accessibility_quick_settings_mobile" msgid="4876806564086241341">"Cellulare: <xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="TYPE">%2$s</xliff:g>. <xliff:g id="NETWORK">%3$s</xliff:g>."</string>
diff --git a/packages/SystemUI/res/values-iw/strings.xml b/packages/SystemUI/res/values-iw/strings.xml
index a1e7aba..0481d63 100644
--- a/packages/SystemUI/res/values-iw/strings.xml
+++ b/packages/SystemUI/res/values-iw/strings.xml
@@ -147,8 +147,7 @@
<string name="accessibility_notification_dismissed" msgid="854211387186306927">"הודעה נדחתה."</string>
<string name="accessibility_desc_notification_shade" msgid="4690274844447504208">"תריס התראות."</string>
<string name="accessibility_desc_quick_settings" msgid="6186378411582437046">"הגדרות מהירות."</string>
- <!-- no translation found for accessibility_desc_recent_apps (9014032916410590027) -->
- <skip />
+ <string name="accessibility_desc_recent_apps" msgid="9014032916410590027">"יישומים אחרונים"</string>
<string name="accessibility_quick_settings_user" msgid="1104846699869476855">"משתמש <xliff:g id="USER">%s</xliff:g>."</string>
<string name="accessibility_quick_settings_wifi" msgid="6099781031669728709">"<xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="NETWORK">%2$s</xliff:g>"</string>
<string name="accessibility_quick_settings_mobile" msgid="4876806564086241341">"נייד <xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="TYPE">%2$s</xliff:g>. <xliff:g id="NETWORK">%3$s</xliff:g>."</string>
diff --git a/packages/SystemUI/res/values-ja/strings.xml b/packages/SystemUI/res/values-ja/strings.xml
index 23babd0..1b89e13 100644
--- a/packages/SystemUI/res/values-ja/strings.xml
+++ b/packages/SystemUI/res/values-ja/strings.xml
@@ -149,8 +149,7 @@
<string name="accessibility_notification_dismissed" msgid="854211387186306927">"通知が削除されました。"</string>
<string name="accessibility_desc_notification_shade" msgid="4690274844447504208">"通知シェード"</string>
<string name="accessibility_desc_quick_settings" msgid="6186378411582437046">"クイック設定"</string>
- <!-- no translation found for accessibility_desc_recent_apps (9014032916410590027) -->
- <skip />
+ <string name="accessibility_desc_recent_apps" msgid="9014032916410590027">"最近使ったアプリです。"</string>
<string name="accessibility_quick_settings_user" msgid="1104846699869476855">"ユーザー: <xliff:g id="USER">%s</xliff:g>"</string>
<string name="accessibility_quick_settings_wifi" msgid="6099781031669728709">"<xliff:g id="SIGNAL">%1$s</xliff:g>、<xliff:g id="NETWORK">%2$s</xliff:g>"</string>
<string name="accessibility_quick_settings_mobile" msgid="4876806564086241341">"モバイル: <xliff:g id="SIGNAL">%1$s</xliff:g>、<xliff:g id="TYPE">%2$s</xliff:g>、<xliff:g id="NETWORK">%3$s</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-ko/strings.xml b/packages/SystemUI/res/values-ko/strings.xml
index f01d7eb..71d305f 100644
--- a/packages/SystemUI/res/values-ko/strings.xml
+++ b/packages/SystemUI/res/values-ko/strings.xml
@@ -147,8 +147,7 @@
<string name="accessibility_notification_dismissed" msgid="854211387186306927">"알림이 제거되었습니다."</string>
<string name="accessibility_desc_notification_shade" msgid="4690274844447504208">"알림 세부정보"</string>
<string name="accessibility_desc_quick_settings" msgid="6186378411582437046">"빠른 설정"</string>
- <!-- no translation found for accessibility_desc_recent_apps (9014032916410590027) -->
- <skip />
+ <string name="accessibility_desc_recent_apps" msgid="9014032916410590027">"최근 앱"</string>
<string name="accessibility_quick_settings_user" msgid="1104846699869476855">"사용자 <xliff:g id="USER">%s</xliff:g>"</string>
<string name="accessibility_quick_settings_wifi" msgid="6099781031669728709">"<xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="NETWORK">%2$s</xliff:g>"</string>
<string name="accessibility_quick_settings_mobile" msgid="4876806564086241341">"모바일 <xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="TYPE">%2$s</xliff:g>. <xliff:g id="NETWORK">%3$s</xliff:g>."</string>
diff --git a/packages/SystemUI/res/values-lt/strings.xml b/packages/SystemUI/res/values-lt/strings.xml
index c6ed8d2..76de197 100644
--- a/packages/SystemUI/res/values-lt/strings.xml
+++ b/packages/SystemUI/res/values-lt/strings.xml
@@ -147,8 +147,7 @@
<string name="accessibility_notification_dismissed" msgid="854211387186306927">"Pranešimo atsisakyta."</string>
<string name="accessibility_desc_notification_shade" msgid="4690274844447504208">"Pranešimų gaubtas."</string>
<string name="accessibility_desc_quick_settings" msgid="6186378411582437046">"Spartieji nustatymai."</string>
- <!-- no translation found for accessibility_desc_recent_apps (9014032916410590027) -->
- <skip />
+ <string name="accessibility_desc_recent_apps" msgid="9014032916410590027">"Naujausios programos."</string>
<string name="accessibility_quick_settings_user" msgid="1104846699869476855">"Naudotojas <xliff:g id="USER">%s</xliff:g>."</string>
<string name="accessibility_quick_settings_wifi" msgid="6099781031669728709">"<xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="NETWORK">%2$s</xliff:g>"</string>
<string name="accessibility_quick_settings_mobile" msgid="4876806564086241341">"Mobilusis ryšys <xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="TYPE">%2$s</xliff:g>. <xliff:g id="NETWORK">%3$s</xliff:g>."</string>
diff --git a/packages/SystemUI/res/values-lv/strings.xml b/packages/SystemUI/res/values-lv/strings.xml
index 6d1b313..21299b2 100644
--- a/packages/SystemUI/res/values-lv/strings.xml
+++ b/packages/SystemUI/res/values-lv/strings.xml
@@ -147,8 +147,7 @@
<string name="accessibility_notification_dismissed" msgid="854211387186306927">"Paziņojums netiek rādīts."</string>
<string name="accessibility_desc_notification_shade" msgid="4690274844447504208">"Paziņojumu panelis"</string>
<string name="accessibility_desc_quick_settings" msgid="6186378411582437046">"Ātrie iestatījumi"</string>
- <!-- no translation found for accessibility_desc_recent_apps (9014032916410590027) -->
- <skip />
+ <string name="accessibility_desc_recent_apps" msgid="9014032916410590027">"Pēdējās izmantotās lietotnes"</string>
<string name="accessibility_quick_settings_user" msgid="1104846699869476855">"Lietotājs: <xliff:g id="USER">%s</xliff:g>"</string>
<string name="accessibility_quick_settings_wifi" msgid="6099781031669728709">"<xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="NETWORK">%2$s</xliff:g>"</string>
<string name="accessibility_quick_settings_mobile" msgid="4876806564086241341">"Mobilo sakaru tīkls. <xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="TYPE">%2$s</xliff:g>. <xliff:g id="NETWORK">%3$s</xliff:g>."</string>
diff --git a/packages/SystemUI/res/values-ms/strings.xml b/packages/SystemUI/res/values-ms/strings.xml
index a70c12e..01751b0 100644
--- a/packages/SystemUI/res/values-ms/strings.xml
+++ b/packages/SystemUI/res/values-ms/strings.xml
@@ -147,8 +147,7 @@
<string name="accessibility_notification_dismissed" msgid="854211387186306927">"Pemberitahuan diketepikan."</string>
<string name="accessibility_desc_notification_shade" msgid="4690274844447504208">"Bidai pemberitahuan."</string>
<string name="accessibility_desc_quick_settings" msgid="6186378411582437046">"Tetapan pantas."</string>
- <!-- no translation found for accessibility_desc_recent_apps (9014032916410590027) -->
- <skip />
+ <string name="accessibility_desc_recent_apps" msgid="9014032916410590027">"Apl terbaru."</string>
<string name="accessibility_quick_settings_user" msgid="1104846699869476855">"Pengguna <xliff:g id="USER">%s</xliff:g>."</string>
<string name="accessibility_quick_settings_wifi" msgid="6099781031669728709">"<xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="NETWORK">%2$s</xliff:g>"</string>
<string name="accessibility_quick_settings_mobile" msgid="4876806564086241341">"Mudah Alih <xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="TYPE">%2$s</xliff:g>. <xliff:g id="NETWORK">%3$s</xliff:g>."</string>
diff --git a/packages/SystemUI/res/values-nb/strings.xml b/packages/SystemUI/res/values-nb/strings.xml
index 88096b3..ccba8e5 100644
--- a/packages/SystemUI/res/values-nb/strings.xml
+++ b/packages/SystemUI/res/values-nb/strings.xml
@@ -147,8 +147,7 @@
<string name="accessibility_notification_dismissed" msgid="854211387186306927">"Varselet ble skjult."</string>
<string name="accessibility_desc_notification_shade" msgid="4690274844447504208">"Varselskygge."</string>
<string name="accessibility_desc_quick_settings" msgid="6186378411582437046">"Hurtiginnstillinger."</string>
- <!-- no translation found for accessibility_desc_recent_apps (9014032916410590027) -->
- <skip />
+ <string name="accessibility_desc_recent_apps" msgid="9014032916410590027">"Nylige apper."</string>
<string name="accessibility_quick_settings_user" msgid="1104846699869476855">"Bruker: <xliff:g id="USER">%s</xliff:g>."</string>
<string name="accessibility_quick_settings_wifi" msgid="6099781031669728709">"<xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="NETWORK">%2$s</xliff:g>"</string>
<string name="accessibility_quick_settings_mobile" msgid="4876806564086241341">"Mobil – <xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="TYPE">%2$s</xliff:g>. <xliff:g id="NETWORK">%3$s</xliff:g>."</string>
diff --git a/packages/SystemUI/res/values-nl/strings.xml b/packages/SystemUI/res/values-nl/strings.xml
index 24b6ff7..9978b76 100644
--- a/packages/SystemUI/res/values-nl/strings.xml
+++ b/packages/SystemUI/res/values-nl/strings.xml
@@ -147,8 +147,7 @@
<string name="accessibility_notification_dismissed" msgid="854211387186306927">"Melding verwijderd."</string>
<string name="accessibility_desc_notification_shade" msgid="4690274844447504208">"Meldingenpaneel."</string>
<string name="accessibility_desc_quick_settings" msgid="6186378411582437046">"Snelle instellingen."</string>
- <!-- no translation found for accessibility_desc_recent_apps (9014032916410590027) -->
- <skip />
+ <string name="accessibility_desc_recent_apps" msgid="9014032916410590027">"Recente apps."</string>
<string name="accessibility_quick_settings_user" msgid="1104846699869476855">"Gebruiker: <xliff:g id="USER">%s</xliff:g>."</string>
<string name="accessibility_quick_settings_wifi" msgid="6099781031669728709">"<xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="NETWORK">%2$s</xliff:g>"</string>
<string name="accessibility_quick_settings_mobile" msgid="4876806564086241341">"Mobiel <xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="TYPE">%2$s</xliff:g>. <xliff:g id="NETWORK">%3$s</xliff:g>."</string>
diff --git a/packages/SystemUI/res/values-pl/strings.xml b/packages/SystemUI/res/values-pl/strings.xml
index d3df443..98f13c7 100644
--- a/packages/SystemUI/res/values-pl/strings.xml
+++ b/packages/SystemUI/res/values-pl/strings.xml
@@ -147,8 +147,7 @@
<string name="accessibility_notification_dismissed" msgid="854211387186306927">"Zamknięto powiadomienie."</string>
<string name="accessibility_desc_notification_shade" msgid="4690274844447504208">"Obszar powiadomień."</string>
<string name="accessibility_desc_quick_settings" msgid="6186378411582437046">"Szybkie ustawienia."</string>
- <!-- no translation found for accessibility_desc_recent_apps (9014032916410590027) -->
- <skip />
+ <string name="accessibility_desc_recent_apps" msgid="9014032916410590027">"Ostatnii używane aplikacje."</string>
<string name="accessibility_quick_settings_user" msgid="1104846699869476855">"Użytkownik: <xliff:g id="USER">%s</xliff:g>."</string>
<string name="accessibility_quick_settings_wifi" msgid="6099781031669728709">"<xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="NETWORK">%2$s</xliff:g>"</string>
<string name="accessibility_quick_settings_mobile" msgid="4876806564086241341">"Sieć komórkowa: <xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="TYPE">%2$s</xliff:g>. <xliff:g id="NETWORK">%3$s</xliff:g>."</string>
diff --git a/packages/SystemUI/res/values-pt-rPT/strings.xml b/packages/SystemUI/res/values-pt-rPT/strings.xml
index c2ecb5a..639201c 100644
--- a/packages/SystemUI/res/values-pt-rPT/strings.xml
+++ b/packages/SystemUI/res/values-pt-rPT/strings.xml
@@ -147,8 +147,7 @@
<string name="accessibility_notification_dismissed" msgid="854211387186306927">"Notificação ignorada."</string>
<string name="accessibility_desc_notification_shade" msgid="4690274844447504208">"Painel de notificações."</string>
<string name="accessibility_desc_quick_settings" msgid="6186378411582437046">"Definições rápidas."</string>
- <!-- no translation found for accessibility_desc_recent_apps (9014032916410590027) -->
- <skip />
+ <string name="accessibility_desc_recent_apps" msgid="9014032916410590027">"Aplicações recentes"</string>
<string name="accessibility_quick_settings_user" msgid="1104846699869476855">"Utilizador <xliff:g id="USER">%s</xliff:g>."</string>
<string name="accessibility_quick_settings_wifi" msgid="6099781031669728709">"<xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="NETWORK">%2$s</xliff:g>"</string>
<string name="accessibility_quick_settings_mobile" msgid="4876806564086241341">"Dispositivo Móvel <xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="TYPE">%2$s</xliff:g>. <xliff:g id="NETWORK">%3$s</xliff:g>."</string>
diff --git a/packages/SystemUI/res/values-pt/strings.xml b/packages/SystemUI/res/values-pt/strings.xml
index a4a871e..9eeb01b 100644
--- a/packages/SystemUI/res/values-pt/strings.xml
+++ b/packages/SystemUI/res/values-pt/strings.xml
@@ -149,8 +149,7 @@
<string name="accessibility_notification_dismissed" msgid="854211387186306927">"Notificação dispensada."</string>
<string name="accessibility_desc_notification_shade" msgid="4690274844447504208">"Aba de notificações."</string>
<string name="accessibility_desc_quick_settings" msgid="6186378411582437046">"Configurações rápidas."</string>
- <!-- no translation found for accessibility_desc_recent_apps (9014032916410590027) -->
- <skip />
+ <string name="accessibility_desc_recent_apps" msgid="9014032916410590027">"Aplicativos recentes."</string>
<string name="accessibility_quick_settings_user" msgid="1104846699869476855">"Usuário <xliff:g id="USER">%s</xliff:g>."</string>
<string name="accessibility_quick_settings_wifi" msgid="6099781031669728709">"<xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="NETWORK">%2$s</xliff:g>"</string>
<string name="accessibility_quick_settings_mobile" msgid="4876806564086241341">"Celular <xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="TYPE">%2$s</xliff:g>. <xliff:g id="NETWORK">%3$s</xliff:g>."</string>
diff --git a/packages/SystemUI/res/values-ro/strings.xml b/packages/SystemUI/res/values-ro/strings.xml
index a73ad1a..616ddb7 100644
--- a/packages/SystemUI/res/values-ro/strings.xml
+++ b/packages/SystemUI/res/values-ro/strings.xml
@@ -147,8 +147,7 @@
<string name="accessibility_notification_dismissed" msgid="854211387186306927">"Notificarea a fost închisă."</string>
<string name="accessibility_desc_notification_shade" msgid="4690274844447504208">"Fereastră pentru notificări."</string>
<string name="accessibility_desc_quick_settings" msgid="6186378411582437046">"Setări rapide."</string>
- <!-- no translation found for accessibility_desc_recent_apps (9014032916410590027) -->
- <skip />
+ <string name="accessibility_desc_recent_apps" msgid="9014032916410590027">"Aplicaţii recente"</string>
<string name="accessibility_quick_settings_user" msgid="1104846699869476855">"Utilizatorul <xliff:g id="USER">%s</xliff:g>."</string>
<string name="accessibility_quick_settings_wifi" msgid="6099781031669728709">"<xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="NETWORK">%2$s</xliff:g>"</string>
<string name="accessibility_quick_settings_mobile" msgid="4876806564086241341">"Semnal mobil: <xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="TYPE">%2$s</xliff:g>. <xliff:g id="NETWORK">%3$s</xliff:g>."</string>
diff --git a/packages/SystemUI/res/values-ru/strings.xml b/packages/SystemUI/res/values-ru/strings.xml
index a04d732..6e10de4 100644
--- a/packages/SystemUI/res/values-ru/strings.xml
+++ b/packages/SystemUI/res/values-ru/strings.xml
@@ -149,8 +149,7 @@
<string name="accessibility_notification_dismissed" msgid="854211387186306927">"Уведомление закрыто"</string>
<string name="accessibility_desc_notification_shade" msgid="4690274844447504208">"Панель уведомлений"</string>
<string name="accessibility_desc_quick_settings" msgid="6186378411582437046">"Быстрые настройки"</string>
- <!-- no translation found for accessibility_desc_recent_apps (9014032916410590027) -->
- <skip />
+ <string name="accessibility_desc_recent_apps" msgid="9014032916410590027">"Недавние приложения"</string>
<string name="accessibility_quick_settings_user" msgid="1104846699869476855">"Пользователь <xliff:g id="USER">%s</xliff:g>"</string>
<string name="accessibility_quick_settings_wifi" msgid="6099781031669728709">"<xliff:g id="NETWORK">%2$s</xliff:g>: <xliff:g id="SIGNAL">%1$s</xliff:g>"</string>
<string name="accessibility_quick_settings_mobile" msgid="4876806564086241341">"Мобильная сеть: <xliff:g id="NETWORK">%3$s</xliff:g> (<xliff:g id="TYPE">%2$s</xliff:g>, <xliff:g id="SIGNAL">%1$s</xliff:g>)"</string>
diff --git a/packages/SystemUI/res/values-sk/strings.xml b/packages/SystemUI/res/values-sk/strings.xml
index 6d126b1..9151512 100644
--- a/packages/SystemUI/res/values-sk/strings.xml
+++ b/packages/SystemUI/res/values-sk/strings.xml
@@ -149,8 +149,7 @@
<string name="accessibility_notification_dismissed" msgid="854211387186306927">"Upozornenie bolo zrušené."</string>
<string name="accessibility_desc_notification_shade" msgid="4690274844447504208">"Panel upozornení."</string>
<string name="accessibility_desc_quick_settings" msgid="6186378411582437046">"Rýchle nastavenia."</string>
- <!-- no translation found for accessibility_desc_recent_apps (9014032916410590027) -->
- <skip />
+ <string name="accessibility_desc_recent_apps" msgid="9014032916410590027">"Nedávne aplikácie"</string>
<string name="accessibility_quick_settings_user" msgid="1104846699869476855">"Používateľ: <xliff:g id="USER">%s</xliff:g>."</string>
<string name="accessibility_quick_settings_wifi" msgid="6099781031669728709">"<xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="NETWORK">%2$s</xliff:g>"</string>
<string name="accessibility_quick_settings_mobile" msgid="4876806564086241341">"Mobil: <xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="TYPE">%2$s</xliff:g>. <xliff:g id="NETWORK">%3$s</xliff:g>."</string>
diff --git a/packages/SystemUI/res/values-sl/strings.xml b/packages/SystemUI/res/values-sl/strings.xml
index 2d4006b..7be851c 100644
--- a/packages/SystemUI/res/values-sl/strings.xml
+++ b/packages/SystemUI/res/values-sl/strings.xml
@@ -147,8 +147,7 @@
<string name="accessibility_notification_dismissed" msgid="854211387186306927">"Obvestilo je bilo odstranjeno."</string>
<string name="accessibility_desc_notification_shade" msgid="4690274844447504208">"Zaslon z obvestili."</string>
<string name="accessibility_desc_quick_settings" msgid="6186378411582437046">"Hitre nastavitve."</string>
- <!-- no translation found for accessibility_desc_recent_apps (9014032916410590027) -->
- <skip />
+ <string name="accessibility_desc_recent_apps" msgid="9014032916410590027">"Nedavne aplikacije."</string>
<string name="accessibility_quick_settings_user" msgid="1104846699869476855">"Uporabnik: <xliff:g id="USER">%s</xliff:g>."</string>
<string name="accessibility_quick_settings_wifi" msgid="6099781031669728709">"<xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="NETWORK">%2$s</xliff:g>"</string>
<string name="accessibility_quick_settings_mobile" msgid="4876806564086241341">"Mobilni telefon: <xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="TYPE">%2$s</xliff:g>. <xliff:g id="NETWORK">%3$s</xliff:g>."</string>
diff --git a/packages/SystemUI/res/values-sr/strings.xml b/packages/SystemUI/res/values-sr/strings.xml
index fce2c57..9d9da87 100644
--- a/packages/SystemUI/res/values-sr/strings.xml
+++ b/packages/SystemUI/res/values-sr/strings.xml
@@ -147,8 +147,7 @@
<string name="accessibility_notification_dismissed" msgid="854211387186306927">"Обавештење је одбачено."</string>
<string name="accessibility_desc_notification_shade" msgid="4690274844447504208">"Прозор са обавештењима."</string>
<string name="accessibility_desc_quick_settings" msgid="6186378411582437046">"Брза подешавања."</string>
- <!-- no translation found for accessibility_desc_recent_apps (9014032916410590027) -->
- <skip />
+ <string name="accessibility_desc_recent_apps" msgid="9014032916410590027">"Недавне апликације."</string>
<string name="accessibility_quick_settings_user" msgid="1104846699869476855">"Корисник: <xliff:g id="USER">%s</xliff:g>."</string>
<string name="accessibility_quick_settings_wifi" msgid="6099781031669728709">"<xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="NETWORK">%2$s</xliff:g>"</string>
<string name="accessibility_quick_settings_mobile" msgid="4876806564086241341">"Мобилна мрежа: <xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="TYPE">%2$s</xliff:g>. <xliff:g id="NETWORK">%3$s</xliff:g>."</string>
diff --git a/packages/SystemUI/res/values-sv/strings.xml b/packages/SystemUI/res/values-sv/strings.xml
index 16b8316..bae649d 100644
--- a/packages/SystemUI/res/values-sv/strings.xml
+++ b/packages/SystemUI/res/values-sv/strings.xml
@@ -147,8 +147,7 @@
<string name="accessibility_notification_dismissed" msgid="854211387186306927">"Meddelandet ignorerades."</string>
<string name="accessibility_desc_notification_shade" msgid="4690274844447504208">"Meddelandepanel."</string>
<string name="accessibility_desc_quick_settings" msgid="6186378411582437046">"Snabbinställningar."</string>
- <!-- no translation found for accessibility_desc_recent_apps (9014032916410590027) -->
- <skip />
+ <string name="accessibility_desc_recent_apps" msgid="9014032916410590027">"Senaste apparna"</string>
<string name="accessibility_quick_settings_user" msgid="1104846699869476855">"Användare <xliff:g id="USER">%s</xliff:g>."</string>
<string name="accessibility_quick_settings_wifi" msgid="6099781031669728709">"<xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="NETWORK">%2$s</xliff:g>"</string>
<string name="accessibility_quick_settings_mobile" msgid="4876806564086241341">"Mobil <xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="TYPE">%2$s</xliff:g>. <xliff:g id="NETWORK">%3$s</xliff:g>."</string>
diff --git a/packages/SystemUI/res/values-sw/strings.xml b/packages/SystemUI/res/values-sw/strings.xml
index 905e1dd..3b29b39 100644
--- a/packages/SystemUI/res/values-sw/strings.xml
+++ b/packages/SystemUI/res/values-sw/strings.xml
@@ -145,8 +145,7 @@
<string name="accessibility_notification_dismissed" msgid="854211387186306927">"Arifa imetupwa."</string>
<string name="accessibility_desc_notification_shade" msgid="4690274844447504208">"Kivuli cha arifa."</string>
<string name="accessibility_desc_quick_settings" msgid="6186378411582437046">"Mipangilio ya haraka."</string>
- <!-- no translation found for accessibility_desc_recent_apps (9014032916410590027) -->
- <skip />
+ <string name="accessibility_desc_recent_apps" msgid="9014032916410590027">"Programu za hivi karibuni."</string>
<string name="accessibility_quick_settings_user" msgid="1104846699869476855">"Mtumiaji <xliff:g id="USER">%s</xliff:g>."</string>
<string name="accessibility_quick_settings_wifi" msgid="6099781031669728709">"<xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="NETWORK">%2$s</xliff:g>"</string>
<string name="accessibility_quick_settings_mobile" msgid="4876806564086241341">"Simu <xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="TYPE">%2$s</xliff:g>. <xliff:g id="NETWORK">%3$s</xliff:g>."</string>
diff --git a/packages/SystemUI/res/values-sw600dp/config.xml b/packages/SystemUI/res/values-sw600dp/config.xml
index 50575d0..48a02ab 100644
--- a/packages/SystemUI/res/values-sw600dp/config.xml
+++ b/packages/SystemUI/res/values-sw600dp/config.xml
@@ -31,4 +31,7 @@
<!-- Whether rotation lock shows up in quick settings or not -->
<bool name="quick_settings_show_rotation_lock">true</bool>
+
+ <!-- Enable the "flip settings" panel -->
+ <bool name="config_hasFlipSettingsPanel">false</bool>
</resources>
diff --git a/packages/SystemUI/res/values-sw600dp/dimens.xml b/packages/SystemUI/res/values-sw600dp/dimens.xml
index df6ed19..fc80f5c 100644
--- a/packages/SystemUI/res/values-sw600dp/dimens.xml
+++ b/packages/SystemUI/res/values-sw600dp/dimens.xml
@@ -47,4 +47,8 @@
<!-- Minimum fraction of the screen that should be taken up by the notification panel. -->
<item type="dimen" name="notification_panel_min_height_frac">40%</item>
+
+ <!-- How far to slide the panel out when you touch it -->
+ <!-- On tablets this is just the close_handle_height -->
+ <dimen name="peek_height">@dimen/close_handle_height</dimen>
</resources>
diff --git a/packages/SystemUI/res/values-th/strings.xml b/packages/SystemUI/res/values-th/strings.xml
index 646225d..668504e 100644
--- a/packages/SystemUI/res/values-th/strings.xml
+++ b/packages/SystemUI/res/values-th/strings.xml
@@ -147,8 +147,7 @@
<string name="accessibility_notification_dismissed" msgid="854211387186306927">"ปิดการแจ้งเตือนแล้ว"</string>
<string name="accessibility_desc_notification_shade" msgid="4690274844447504208">"หน้าต่างแจ้งเตือน"</string>
<string name="accessibility_desc_quick_settings" msgid="6186378411582437046">"การตั้งค่าด่วน"</string>
- <!-- no translation found for accessibility_desc_recent_apps (9014032916410590027) -->
- <skip />
+ <string name="accessibility_desc_recent_apps" msgid="9014032916410590027">"แอปพลิเคชันล่าสุด"</string>
<string name="accessibility_quick_settings_user" msgid="1104846699869476855">"ผู้ใช้ <xliff:g id="USER">%s</xliff:g>"</string>
<string name="accessibility_quick_settings_wifi" msgid="6099781031669728709">"<xliff:g id="SIGNAL">%1$s</xliff:g> <xliff:g id="NETWORK">%2$s</xliff:g>"</string>
<string name="accessibility_quick_settings_mobile" msgid="4876806564086241341">"มือถือ <xliff:g id="SIGNAL">%1$s</xliff:g> <xliff:g id="TYPE">%2$s</xliff:g> <xliff:g id="NETWORK">%3$s</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-tl/strings.xml b/packages/SystemUI/res/values-tl/strings.xml
index 7baad61..312d8fd 100644
--- a/packages/SystemUI/res/values-tl/strings.xml
+++ b/packages/SystemUI/res/values-tl/strings.xml
@@ -147,8 +147,7 @@
<string name="accessibility_notification_dismissed" msgid="854211387186306927">"Na-dismiss ang notification."</string>
<string name="accessibility_desc_notification_shade" msgid="4690274844447504208">"Notification shade."</string>
<string name="accessibility_desc_quick_settings" msgid="6186378411582437046">"Mga mabilisang setting."</string>
- <!-- no translation found for accessibility_desc_recent_apps (9014032916410590027) -->
- <skip />
+ <string name="accessibility_desc_recent_apps" msgid="9014032916410590027">"Kamakailang apps."</string>
<string name="accessibility_quick_settings_user" msgid="1104846699869476855">"User na si <xliff:g id="USER">%s</xliff:g>."</string>
<string name="accessibility_quick_settings_wifi" msgid="6099781031669728709">"<xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="NETWORK">%2$s</xliff:g>"</string>
<string name="accessibility_quick_settings_mobile" msgid="4876806564086241341">"Mobile <xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="TYPE">%2$s</xliff:g>. <xliff:g id="NETWORK">%3$s</xliff:g>."</string>
diff --git a/packages/SystemUI/res/values-tr/strings.xml b/packages/SystemUI/res/values-tr/strings.xml
index c6ba738..5012bc5 100644
--- a/packages/SystemUI/res/values-tr/strings.xml
+++ b/packages/SystemUI/res/values-tr/strings.xml
@@ -147,8 +147,7 @@
<string name="accessibility_notification_dismissed" msgid="854211387186306927">"Bildirim kapatıldı."</string>
<string name="accessibility_desc_notification_shade" msgid="4690274844447504208">"Bildirim gölgesi."</string>
<string name="accessibility_desc_quick_settings" msgid="6186378411582437046">"Hızlı ayarlar."</string>
- <!-- no translation found for accessibility_desc_recent_apps (9014032916410590027) -->
- <skip />
+ <string name="accessibility_desc_recent_apps" msgid="9014032916410590027">"Son uygulamalar."</string>
<string name="accessibility_quick_settings_user" msgid="1104846699869476855">"Kullanıcı: <xliff:g id="USER">%s</xliff:g>."</string>
<string name="accessibility_quick_settings_wifi" msgid="6099781031669728709">"<xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="NETWORK">%2$s</xliff:g>"</string>
<string name="accessibility_quick_settings_mobile" msgid="4876806564086241341">"Mobil <xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="TYPE">%2$s</xliff:g>. <xliff:g id="NETWORK">%3$s</xliff:g>."</string>
diff --git a/packages/SystemUI/res/values-uk/strings.xml b/packages/SystemUI/res/values-uk/strings.xml
index 26ae34b..ba36be6 100644
--- a/packages/SystemUI/res/values-uk/strings.xml
+++ b/packages/SystemUI/res/values-uk/strings.xml
@@ -147,8 +147,7 @@
<string name="accessibility_notification_dismissed" msgid="854211387186306927">"Сповіщення відхилено."</string>
<string name="accessibility_desc_notification_shade" msgid="4690274844447504208">"Панель сповіщень."</string>
<string name="accessibility_desc_quick_settings" msgid="6186378411582437046">"Швидке налаштування."</string>
- <!-- no translation found for accessibility_desc_recent_apps (9014032916410590027) -->
- <skip />
+ <string name="accessibility_desc_recent_apps" msgid="9014032916410590027">"Нещодавні програми."</string>
<string name="accessibility_quick_settings_user" msgid="1104846699869476855">"Користувач <xliff:g id="USER">%s</xliff:g>."</string>
<string name="accessibility_quick_settings_wifi" msgid="6099781031669728709">"<xliff:g id="SIGNAL">%1$s</xliff:g>, <xliff:g id="NETWORK">%2$s</xliff:g>"</string>
<string name="accessibility_quick_settings_mobile" msgid="4876806564086241341">"Мобільне передавання даних: <xliff:g id="SIGNAL">%1$s</xliff:g>, <xliff:g id="TYPE">%2$s</xliff:g>, <xliff:g id="NETWORK">%3$s</xliff:g>."</string>
diff --git a/packages/SystemUI/res/values-vi/strings.xml b/packages/SystemUI/res/values-vi/strings.xml
index 468375f..ce90afc 100644
--- a/packages/SystemUI/res/values-vi/strings.xml
+++ b/packages/SystemUI/res/values-vi/strings.xml
@@ -147,8 +147,7 @@
<string name="accessibility_notification_dismissed" msgid="854211387186306927">"Đã loại bỏ thông báo."</string>
<string name="accessibility_desc_notification_shade" msgid="4690274844447504208">"Bóng thông báo."</string>
<string name="accessibility_desc_quick_settings" msgid="6186378411582437046">"Cài đặt nhanh."</string>
- <!-- no translation found for accessibility_desc_recent_apps (9014032916410590027) -->
- <skip />
+ <string name="accessibility_desc_recent_apps" msgid="9014032916410590027">"Ứng dụng gần đây."</string>
<string name="accessibility_quick_settings_user" msgid="1104846699869476855">"Người dùng <xliff:g id="USER">%s</xliff:g>."</string>
<string name="accessibility_quick_settings_wifi" msgid="6099781031669728709">"<xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="NETWORK">%2$s</xliff:g>"</string>
<string name="accessibility_quick_settings_mobile" msgid="4876806564086241341">"Di động <xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="TYPE">%2$s</xliff:g>. <xliff:g id="NETWORK">%3$s</xliff:g>."</string>
diff --git a/packages/SystemUI/res/values-zh-rCN/strings.xml b/packages/SystemUI/res/values-zh-rCN/strings.xml
index 4cfb7d0..ba0d9c8 100644
--- a/packages/SystemUI/res/values-zh-rCN/strings.xml
+++ b/packages/SystemUI/res/values-zh-rCN/strings.xml
@@ -149,8 +149,7 @@
<string name="accessibility_notification_dismissed" msgid="854211387186306927">"已关闭通知。"</string>
<string name="accessibility_desc_notification_shade" msgid="4690274844447504208">"通知栏。"</string>
<string name="accessibility_desc_quick_settings" msgid="6186378411582437046">"快速设置。"</string>
- <!-- no translation found for accessibility_desc_recent_apps (9014032916410590027) -->
- <skip />
+ <string name="accessibility_desc_recent_apps" msgid="9014032916410590027">"最近使用的应用。"</string>
<string name="accessibility_quick_settings_user" msgid="1104846699869476855">"用户:<xliff:g id="USER">%s</xliff:g>。"</string>
<string name="accessibility_quick_settings_wifi" msgid="6099781031669728709">"<xliff:g id="SIGNAL">%1$s</xliff:g>,<xliff:g id="NETWORK">%2$s</xliff:g>"</string>
<string name="accessibility_quick_settings_mobile" msgid="4876806564086241341">"移动数据连接:<xliff:g id="SIGNAL">%1$s</xliff:g>,<xliff:g id="TYPE">%2$s</xliff:g>,<xliff:g id="NETWORK">%3$s</xliff:g>。"</string>
diff --git a/packages/SystemUI/res/values-zh-rTW/strings.xml b/packages/SystemUI/res/values-zh-rTW/strings.xml
index d0323f0..a77dd8c 100644
--- a/packages/SystemUI/res/values-zh-rTW/strings.xml
+++ b/packages/SystemUI/res/values-zh-rTW/strings.xml
@@ -149,8 +149,7 @@
<string name="accessibility_notification_dismissed" msgid="854211387186306927">"已關閉通知。"</string>
<string name="accessibility_desc_notification_shade" msgid="4690274844447504208">"通知欄。"</string>
<string name="accessibility_desc_quick_settings" msgid="6186378411582437046">"快速設定。"</string>
- <!-- no translation found for accessibility_desc_recent_apps (9014032916410590027) -->
- <skip />
+ <string name="accessibility_desc_recent_apps" msgid="9014032916410590027">"最近使用的應用程式。"</string>
<string name="accessibility_quick_settings_user" msgid="1104846699869476855">"使用者:<xliff:g id="USER">%s</xliff:g>。"</string>
<string name="accessibility_quick_settings_wifi" msgid="6099781031669728709">"<xliff:g id="SIGNAL">%1$s</xliff:g>,<xliff:g id="NETWORK">%2$s</xliff:g>"</string>
<string name="accessibility_quick_settings_mobile" msgid="4876806564086241341">"行動數據連線:<xliff:g id="SIGNAL">%1$s</xliff:g>,<xliff:g id="TYPE">%2$s</xliff:g>,<xliff:g id="NETWORK">%3$s</xliff:g>。"</string>
diff --git a/packages/SystemUI/res/values-zu/strings.xml b/packages/SystemUI/res/values-zu/strings.xml
index 8cc8738..8ad1881 100644
--- a/packages/SystemUI/res/values-zu/strings.xml
+++ b/packages/SystemUI/res/values-zu/strings.xml
@@ -105,7 +105,7 @@
<string name="accessibility_wifi_one_bar" msgid="7735893178010724377">"Ibha elilodwa le-WiFi."</string>
<string name="accessibility_wifi_two_bars" msgid="4994274250497262434">"Amabha amabili we-WiFi."</string>
<string name="accessibility_wifi_three_bars" msgid="3495755044276588384">"Amabha amathathu we-WiFi."</string>
- <string name="accessibility_wifi_signal_full" msgid="6853561303586480376">"Isignali ye-WiFi igcwele."</string>
+ <string name="accessibility_wifi_signal_full" msgid="6853561303586480376">"Isiginali ye-WiFi igcwele."</string>
<string name="accessibility_no_wimax" msgid="4329180129727630368">"Ayikho i-WiMAX."</string>
<string name="accessibility_wimax_one_bar" msgid="4170994299011863648">"Ibha eyodwa ye-WiMAX."</string>
<string name="accessibility_wimax_two_bars" msgid="9176236858336502288">"Amabha amabili we-WiMAX."</string>
@@ -117,7 +117,7 @@
<string name="accessibility_one_bar" msgid="1685730113192081895">"Ibha elilodwa."</string>
<string name="accessibility_two_bars" msgid="6437363648385206679">"Amabha amabili."</string>
<string name="accessibility_three_bars" msgid="2648241415119396648">"Amabha amathathu."</string>
- <string name="accessibility_signal_full" msgid="9122922886519676839">"Isignali egcwele."</string>
+ <string name="accessibility_signal_full" msgid="9122922886519676839">"Isiginali egcwele."</string>
<string name="accessibility_desc_on" msgid="2385254693624345265">"Vula."</string>
<string name="accessibility_desc_off" msgid="6475508157786853157">"Vala."</string>
<string name="accessibility_desc_connected" msgid="8366256693719499665">"Ixhunyiwe."</string>
@@ -147,13 +147,12 @@
<string name="accessibility_notification_dismissed" msgid="854211387186306927">"Isaziso sichithiwe."</string>
<string name="accessibility_desc_notification_shade" msgid="4690274844447504208">"Umthunzi wesaziso."</string>
<string name="accessibility_desc_quick_settings" msgid="6186378411582437046">"Izilingiselelo ezisheshayo."</string>
- <!-- no translation found for accessibility_desc_recent_apps (9014032916410590027) -->
- <skip />
+ <string name="accessibility_desc_recent_apps" msgid="9014032916410590027">"Izinhlelo zokusebenza zakamuva"</string>
<string name="accessibility_quick_settings_user" msgid="1104846699869476855">"Umsebenzisi <xliff:g id="USER">%s</xliff:g>."</string>
<string name="accessibility_quick_settings_wifi" msgid="6099781031669728709">"<xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="NETWORK">%2$s</xliff:g>"</string>
<string name="accessibility_quick_settings_mobile" msgid="4876806564086241341">"Iselula <xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="TYPE">%2$s</xliff:g>. <xliff:g id="NETWORK">%3$s</xliff:g>."</string>
<string name="accessibility_quick_settings_battery" msgid="1480931583381408972">"Ibhethri <xliff:g id="STATE">%s</xliff:g>."</string>
- <string name="accessibility_quick_settings_airplane" msgid="4196876722090224753">"I-Airplane Mode <xliff:g id="STATE">%s</xliff:g>."</string>
+ <string name="accessibility_quick_settings_airplane" msgid="4196876722090224753">"Imodi yendiza <xliff:g id="STATE">%s</xliff:g>."</string>
<string name="accessibility_quick_settings_bluetooth" msgid="5749054971341882340">"I-Bluetooth <xliff:g id="STATE">%s</xliff:g>."</string>
<string name="accessibility_quick_settings_alarm" msgid="3959908972897295660">"I-alamu isethiwe ngo-<xliff:g id="TIME">%s</xliff:g>."</string>
<string name="data_usage_disabled_dialog_3g_title" msgid="5257833881698644687">"idatha ye-2G-3G ivimbelwe"</string>
diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml
index aec9555..a27630d 100644
--- a/packages/SystemUI/res/values/config.xml
+++ b/packages/SystemUI/res/values/config.xml
@@ -97,7 +97,10 @@
<integer name="blinds_pop_duration_ms">10</integer>
- <!-- Disable quick settings by default -->
- <bool name="config_hasSettingsPanel">false</bool>
+ <!-- Disable the separate quick settings panel -->
+ <bool name="config_hasSettingsPanel">true</bool>
+
+ <!-- Enable the "flip settings" panel -->
+ <bool name="config_hasFlipSettingsPanel">true</bool>
</resources>
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index 4de0891..ed08115 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -201,4 +201,8 @@
<!-- The size of the gesture span needed to activate the "pull" notification expansion -->
<dimen name="pull_span_min">25dp</dimen>
+
+ <!-- How far to slide the panel out when you touch it -->
+ <!-- For phones, this is close_handle_height + header_height -->
+ <dimen name="peek_height">84dp</dimen>
</resources>
diff --git a/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java b/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java
index 356689f..0958f70 100644
--- a/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java
+++ b/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java
@@ -31,8 +31,10 @@
import android.renderscript.Matrix4f;
import android.service.wallpaper.WallpaperService;
import android.util.Log;
+import android.view.Display;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
+import android.view.WindowManager;
import javax.microedition.khronos.egl.EGL10;
import javax.microedition.khronos.egl.EGLConfig;
@@ -108,6 +110,7 @@
Bitmap mBackground;
int mBackgroundWidth = -1, mBackgroundHeight = -1;
+ int mLastRotation = -1;
float mXOffset;
float mYOffset;
@@ -156,7 +159,7 @@
mBackgroundWidth = mBackgroundHeight = -1;
mBackground = null;
mRedrawNeeded = true;
- drawFrameLocked(false);
+ drawFrameLocked();
}
}
}
@@ -225,7 +228,7 @@
@Override
public void onVisibilityChanged(boolean visible) {
if (DEBUG) {
- Log.d(TAG, "onVisibilityChanged: visible=" + visible);
+ Log.d(TAG, "onVisibilityChanged: mVisible, visible=" + mVisible + ", " + visible);
}
synchronized (mLock) {
@@ -234,7 +237,7 @@
Log.d(TAG, "Visibility changed to visible=" + visible);
}
mVisible = visible;
- drawFrameLocked(false);
+ drawFrameLocked();
}
}
}
@@ -263,7 +266,7 @@
mYOffset = yOffset;
mOffsetsChanged = true;
}
- drawFrameLocked(false);
+ drawFrameLocked();
}
}
@@ -276,80 +279,81 @@
super.onSurfaceChanged(holder, format, width, height);
synchronized (mLock) {
- mRedrawNeeded = true;
- mBackgroundWidth = mBackgroundHeight = -1;
- drawFrameLocked(true);
+ drawFrameLocked();
}
}
@Override
+ public void onSurfaceDestroyed(SurfaceHolder holder) {
+ super.onSurfaceDestroyed(holder);
+ mBackgroundWidth = mBackgroundHeight = -1;
+ }
+
+ @Override
+ public void onSurfaceCreated(SurfaceHolder holder) {
+ super.onSurfaceCreated(holder);
+ mBackgroundWidth = mBackgroundHeight = -1;
+ }
+
+ @Override
public void onSurfaceRedrawNeeded(SurfaceHolder holder) {
if (DEBUG) {
- Log.d(TAG, "onSurfaceRedrawNeeded:");
+ Log.d(TAG, "onSurfaceRedrawNeeded");
}
super.onSurfaceRedrawNeeded(holder);
synchronized (mLock) {
- mRedrawNeeded = true;
- drawFrameLocked(false);
+ drawFrameLocked();
}
}
- void drawFrameLocked(boolean force) {
- if (!force) {
- if (!mVisible) {
- if (DEBUG) {
- Log.d(TAG, "Suppressed drawFrame since wallpaper is not visible.");
- }
- return;
- }
- if (!mRedrawNeeded && !mOffsetsChanged) {
- if (DEBUG) {
- Log.d(TAG, "Suppressed drawFrame since redraw is not needed "
- + "and offsets have not changed.");
- }
- return;
- }
- }
- // If we don't yet know the size of the wallpaper bitmap,
- // we need to get it now.
- boolean updateWallpaper = mBackgroundWidth < 0 || mBackgroundHeight < 0 ;
-
- // If we somehow got to this point after we have last flushed
- // the wallpaper, well we really need it to draw again. So
- // seems like we need to reload it. Ouch.
- updateWallpaper = updateWallpaper || mBackground == null;
-
- if (updateWallpaper) {
- updateWallpaperLocked();
- }
-
+ void drawFrameLocked() {
SurfaceHolder sh = getSurfaceHolder();
final Rect frame = sh.getSurfaceFrame();
final int dw = frame.width();
final int dh = frame.height();
+ int newRotation = ((WindowManager) getSystemService(WINDOW_SERVICE)).
+ getDefaultDisplay().getRotation();
+
+ boolean redrawNeeded = dw != mBackgroundWidth || dh != mBackgroundHeight ||
+ newRotation != mLastRotation;
+ if (!redrawNeeded && !mOffsetsChanged) {
+ if (DEBUG) {
+ Log.d(TAG, "Suppressed drawFrame since redraw is not needed "
+ + "and offsets have not changed.");
+ }
+ return;
+ }
+ mLastRotation = newRotation;
+
+ // Load bitmap if it is not yet loaded or if it was loaded at a different size
+ if (mBackground == null || dw != mBackgroundWidth || dw != mBackgroundHeight) {
+ if (DEBUG) {
+ Log.d(TAG, "Reloading bitmap");
+ }
+ mWallpaperManager.forgetLoadedWallpaper();
+ updateWallpaperLocked();
+ }
+
final int availw = dw - mBackgroundWidth;
final int availh = dh - mBackgroundHeight;
int xPixels = availw < 0 ? (int)(availw * mXOffset + .5f) : (availw / 2);
int yPixels = availh < 0 ? (int)(availh * mYOffset + .5f) : (availh / 2);
mOffsetsChanged = false;
- if (!force && !mRedrawNeeded
- && xPixels == mLastXTranslation && yPixels == mLastYTranslation) {
+ mRedrawNeeded = false;
+ mLastXTranslation = xPixels;
+ mLastYTranslation = yPixels;
+ if (!redrawNeeded && xPixels == mLastXTranslation && yPixels == mLastYTranslation) {
if (DEBUG) {
Log.d(TAG, "Suppressed drawFrame since the image has not "
+ "actually moved an integral number of pixels.");
}
return;
}
- mRedrawNeeded = false;
- mLastXTranslation = xPixels;
- mLastYTranslation = yPixels;
if (DEBUG) {
- Log.d(TAG, "drawFrameUnlocked(" + force + "): mBackgroundWxH=" + mBackgroundWidth + "x"
- + mBackgroundHeight + " SurfaceFrame=" + frame.toShortString()
- + " X,YOffset=" + mXOffset + "," + mYOffset);
+ Log.d(TAG, "Redrawing wallpaper");
}
if (mIsHwAccelerated) {
if (!drawWallpaperWithOpenGL(sh, availw, availh, xPixels, yPixels)) {
@@ -429,7 +433,6 @@
final float bottom = top + mBackgroundHeight;
final Rect frame = sh.getSurfaceFrame();
-
final Matrix4f ortho = new Matrix4f();
ortho.loadOrtho(0.0f, frame.width(), frame.height(), 0.0f, -1.0f, 1.0f);
@@ -437,7 +440,7 @@
final int texture = loadTexture(mBackground);
final int program = buildProgram(sSimpleVS, sSimpleFS);
-
+
final int attribPosition = glGetAttribLocation(program, "position");
final int attribTexCoords = glGetAttribLocation(program, "texCoords");
final int uniformTexture = glGetUniformLocation(program, "texture");
@@ -460,7 +463,7 @@
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glClear(GL_COLOR_BUFFER_BIT);
}
-
+
// drawQuad
triangleVertices.position(TRIANGLE_VERTICES_DATA_POS_OFFSET);
glVertexAttribPointer(attribPosition, 3, GL_FLOAT, false,
@@ -471,12 +474,12 @@
TRIANGLE_VERTICES_DATA_STRIDE_BYTES, triangleVertices);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
-
+
if (!mEgl.eglSwapBuffers(mEglDisplay, mEglSurface)) {
throw new RuntimeException("Cannot swap buffers");
}
checkEglError();
-
+
finishGL();
return true;
@@ -665,6 +668,7 @@
EGL_ALPHA_SIZE, 0,
EGL_DEPTH_SIZE, 0,
EGL_STENCIL_SIZE, 0,
+ EGL_CONFIG_CAVEAT, EGL_NONE,
EGL_NONE
};
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
index c832fb8..248a516 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
@@ -21,6 +21,8 @@
import android.graphics.Canvas;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
+import android.util.Slog;
+import android.view.MotionEvent;
import android.view.View;
import com.android.systemui.R;
@@ -31,11 +33,18 @@
Drawable mHandleBar;
float mHandleBarHeight;
View mHandleView;
+ int mFingers;
+ PhoneStatusBar mStatusBar;
+ boolean mOkToFlip;
public NotificationPanelView(Context context, AttributeSet attrs) {
super(context, attrs);
}
+ public void setStatusBar(PhoneStatusBar bar) {
+ mStatusBar = bar;
+ }
+
@Override
protected void onFinishInflate() {
super.onFinishInflate();
@@ -79,4 +88,35 @@
mHandleBar.draw(canvas);
canvas.translate(0, -off);
}
+
+ @Override
+ public boolean onTouchEvent(MotionEvent event) {
+ if (PhoneStatusBar.SETTINGS_DRAG_SHORTCUT && mStatusBar.mHasFlipSettings) {
+ switch (event.getActionMasked()) {
+ case MotionEvent.ACTION_DOWN:
+ mOkToFlip = getExpandedHeight() == 0;
+ break;
+ case MotionEvent.ACTION_POINTER_DOWN:
+ if (mOkToFlip) {
+ float miny = event.getY(0);
+ float maxy = miny;
+ for (int i=1; i<event.getPointerCount(); i++) {
+ final float y = event.getY(i);
+ if (y < miny) miny = y;
+ if (y > maxy) maxy = y;
+ }
+ if (maxy - miny < mHandleBarHeight) {
+ if (getMeasuredHeight() < mHandleBarHeight) {
+ mStatusBar.switchToSettings();
+ } else {
+ mStatusBar.flipToSettings();
+ }
+ mOkToFlip = false;
+ }
+ }
+ break;
+ }
+ }
+ return mHandleView.dispatchTouchEvent(event);
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelBar.java
index d0fc340..c9a137c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelBar.java
@@ -102,7 +102,7 @@
startOpeningPanel(panel);
}
final boolean result = mTouchingPanel != null
- ? mTouchingPanel.getHandle().dispatchTouchEvent(event)
+ ? mTouchingPanel.onTouchEvent(event)
: true;
return result;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
index 7eb84e1..6184e30 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
@@ -98,7 +98,7 @@
if (mPeekAnimator == null) {
mPeekAnimator = ObjectAnimator.ofFloat(this,
"expandedHeight", mPeekHeight)
- .setDuration(300);
+ .setDuration(250);
}
mPeekAnimator.start();
}
@@ -206,7 +206,7 @@
mFlingGestureMaxOutputVelocityPx = res.getDimension(R.dimen.fling_gesture_max_output_velocity);
- mPeekHeight = res.getDimension(R.dimen.close_handle_height)
+ mPeekHeight = res.getDimension(R.dimen.peek_height)
+ getPaddingBottom() // our window might have a dropshadow
- (mHandleView == null ? 0 : mHandleView.getPaddingTop()); // the handle might have a topshadow
}
@@ -250,6 +250,7 @@
case MotionEvent.ACTION_DOWN:
mTracking = true;
mHandleView.setPressed(true);
+ postInvalidate(); // catch the press state change
mInitialTouchY = y;
mVelocityTracker = VelocityTracker.obtain();
trackMovement(event);
@@ -283,6 +284,7 @@
mFinalTouchY = y;
mTracking = false;
mHandleView.setPressed(false);
+ postInvalidate(); // catch the press state change
mBar.onTrackingStopped(PanelView.this);
trackMovement(event);
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 75a2598..27a4db5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -20,6 +20,7 @@
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
+import android.animation.TimeInterpolator;
import android.app.ActivityManager;
import android.app.ActivityManagerNative;
import android.app.Notification;
@@ -61,6 +62,7 @@
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewGroup.LayoutParams;
+import android.view.ViewPropertyAnimator;
import android.view.ViewStub;
import android.view.WindowManager;
import android.view.animation.AccelerateInterpolator;
@@ -108,6 +110,8 @@
public static final boolean ENABLE_NOTIFICATION_PANEL_CLING = false;
+ public static final boolean SETTINGS_DRAG_SHORTCUT = true;
+
// additional instrumentation for testing purposes; intended to be left on during development
public static final boolean CHATTY = DEBUG;
@@ -178,7 +182,7 @@
View mMoreIcon;
// expanded notifications
- PanelView mNotificationPanel; // the sliding/resizing panel within the notification window
+ NotificationPanelView mNotificationPanel; // the sliding/resizing panel within the notification window
ScrollView mScrollView;
View mExpandedContents;
int mNotificationPanelGravity;
@@ -188,13 +192,18 @@
TextView mNotificationPanelDebugText;
// settings
- boolean mHasSettingsPanel;
+ QuickSettings mQS;
+ boolean mHasSettingsPanel, mHasFlipSettings;
SettingsPanelView mSettingsPanel;
+ View mFlipSettingsView;
+ QuickSettingsContainerView mSettingsContainer;
int mSettingsPanelGravity;
// top bar
+ View mNotificationPanelHeader;
+ View mDateTimeView;
View mClearButton;
- ImageView mSettingsButton;
+ ImageView mSettingsButton, mNotificationButton;
// carrier/wifi label
private TextView mCarrierLabel;
@@ -290,8 +299,12 @@
if (MULTIUSER_DEBUG) Slog.d(TAG, String.format("User setup changed: " +
"selfChange=%s userSetup=%s mUserSetup=%s",
selfChange, userSetup, mUserSetup));
- if (mSettingsPanel != null)
+ if (mSettingsButton != null && !mHasSettingsPanel) {
+ mSettingsButton.setVisibility(userSetup ? View.VISIBLE : View.INVISIBLE);
+ }
+ if (mSettingsPanel != null) {
mSettingsPanel.setEnabled(userSetup);
+ }
if (userSetup != mUserSetup) {
mUserSetup = userSetup;
if (!mUserSetup && mStatusBarView != null)
@@ -352,13 +365,10 @@
PanelHolder holder = (PanelHolder) mStatusBarWindow.findViewById(R.id.panel_holder);
mStatusBarView.setPanelHolder(holder);
- mNotificationPanel = (PanelView) mStatusBarWindow.findViewById(R.id.notification_panel);
+ mNotificationPanel = (NotificationPanelView) mStatusBarWindow.findViewById(R.id.notification_panel);
+ mNotificationPanel.setStatusBar(this);
mNotificationPanelIsFullScreenWidth =
(mNotificationPanel.getLayoutParams().width == ViewGroup.LayoutParams.MATCH_PARENT);
- mNotificationPanel.setSystemUiVisibility(
- View.STATUS_BAR_DISABLE_NOTIFICATION_TICKER |
- View.STATUS_BAR_DISABLE_NOTIFICATION_ICONS |
- View.STATUS_BAR_DISABLE_CLOCK);
// make the header non-responsive to clicks
mNotificationPanel.findViewById(R.id.header).setOnTouchListener(
@@ -415,6 +425,8 @@
mPile.setLongPressListener(getNotificationLongClicker());
mExpandedContents = mPile; // was: expanded.findViewById(R.id.notificationLinearLayout);
+ mNotificationPanelHeader = mStatusBarWindow.findViewById(R.id.header);
+
mClearButton = mStatusBarWindow.findViewById(R.id.clear_all_button);
mClearButton.setOnClickListener(mClearButtonListener);
mClearButton.setAlpha(0f);
@@ -423,6 +435,13 @@
mDateView = (DateView)mStatusBarWindow.findViewById(R.id.date);
mHasSettingsPanel = res.getBoolean(R.bool.config_hasSettingsPanel);
+ mHasFlipSettings = res.getBoolean(R.bool.config_hasFlipSettingsPanel);
+
+ mDateTimeView = mNotificationPanelHeader.findViewById(R.id.datetime);
+ if (mHasFlipSettings) {
+ mDateTimeView.setOnClickListener(mClockClickListener);
+ mDateTimeView.setEnabled(true);
+ }
mSettingsButton = (ImageView) mStatusBarWindow.findViewById(R.id.settings_button);
if (mSettingsButton != null) {
@@ -442,9 +461,21 @@
mSettingsButton.setImageResource(R.drawable.ic_notify_settings);
}
}
-
+ if (mHasFlipSettings) {
+ mNotificationButton = (ImageView) mStatusBarWindow.findViewById(R.id.notification_button);
+ if (mNotificationButton != null) {
+ mNotificationButton.setOnClickListener(mNotificationButtonListener);
+ }
+ }
+
mScrollView = (ScrollView)mStatusBarWindow.findViewById(R.id.scroll);
mScrollView.setVerticalScrollBarEnabled(false); // less drawing during pulldowns
+ if (!mNotificationPanelIsFullScreenWidth) {
+ mScrollView.setSystemUiVisibility(
+ View.STATUS_BAR_DISABLE_NOTIFICATION_TICKER |
+ View.STATUS_BAR_DISABLE_NOTIFICATION_ICONS |
+ View.STATUS_BAR_DISABLE_CLOCK);
+ }
mTicker = new MyTicker(context, mStatusBarView);
@@ -472,6 +503,8 @@
mEmergencyCallLabel = (TextView)mStatusBarWindow.findViewById(R.id.emergency_calls_only);
if (mEmergencyCallLabel != null) {
mNetworkController.addEmergencyLabelView(mEmergencyCallLabel);
+ mEmergencyCallLabel.setOnClickListener(new View.OnClickListener() {
+ public void onClick(View v) { }});
mEmergencyCallLabel.addOnLayoutChangeListener(new View.OnLayoutChangeListener() {
@Override
public void onLayoutChange(View v, int left, int top, int right, int bottom,
@@ -505,28 +538,52 @@
// Quick Settings (where available, some restrictions apply)
if (mHasSettingsPanel) {
- final View settings_stub
- = mStatusBarWindow.findViewById(R.id.quick_settings_stub);
-
- if (settings_stub != null) {
- mSettingsPanel = (SettingsPanelView) ((ViewStub)settings_stub).inflate();
+ // first, figure out where quick settings should be inflated
+ final View settings_stub;
+ if (mHasFlipSettings) {
+ // a version of quick settings that flips around behind the notifications
+ settings_stub = mStatusBarWindow.findViewById(R.id.flip_settings_stub);
+ if (settings_stub != null) {
+ mFlipSettingsView = ((ViewStub)settings_stub).inflate();
+ mFlipSettingsView.setVisibility(View.GONE);
+ mFlipSettingsView.setVerticalScrollBarEnabled(false);
+ }
} else {
- mSettingsPanel = (SettingsPanelView) mStatusBarWindow.findViewById(R.id.settings_panel);
+ // full quick settings panel
+ settings_stub = mStatusBarWindow.findViewById(R.id.quick_settings_stub);
+ if (settings_stub != null) {
+ mSettingsPanel = (SettingsPanelView) ((ViewStub)settings_stub).inflate();
+ } else {
+ mSettingsPanel = (SettingsPanelView) mStatusBarWindow.findViewById(R.id.settings_panel);
+ }
+
+ if (mSettingsPanel != null) {
+ if (!ActivityManager.isHighEndGfx()) {
+ mSettingsPanel.setBackground(new FastColorDrawable(context.getResources().getColor(
+ R.color.notification_panel_solid_background)));
+ }
+ }
}
- if (mSettingsPanel != null) {
- mSettingsPanel.setBar(mStatusBarView);
- mSettingsPanel.setService(this);
- mSettingsPanel.setup(mNetworkController, mBluetoothController, mBatteryController,
- mLocationController);
- mSettingsPanel.setSystemUiVisibility(
- View.STATUS_BAR_DISABLE_NOTIFICATION_TICKER
- | View.STATUS_BAR_DISABLE_SYSTEM_INFO);
-
- if (!ActivityManager.isHighEndGfx()) {
- mSettingsPanel.setBackground(new FastColorDrawable(context.getResources().getColor(
- R.color.notification_panel_solid_background)));
+ // wherever you find it, Quick Settings needs a container to survive
+ mSettingsContainer = (QuickSettingsContainerView)
+ mStatusBarWindow.findViewById(R.id.quick_settings_container);
+ if (mSettingsContainer != null) {
+ mQS = new QuickSettings(mContext, mSettingsContainer);
+ if (!mNotificationPanelIsFullScreenWidth) {
+ mSettingsContainer.setSystemUiVisibility(
+ View.STATUS_BAR_DISABLE_NOTIFICATION_TICKER
+ | View.STATUS_BAR_DISABLE_SYSTEM_INFO);
}
+ if (mSettingsPanel != null) {
+ mSettingsPanel.setQuickSettings(mQS);
+ }
+ mQS.setService(this);
+ mQS.setBar(mStatusBarView);
+ mQS.setup(mNetworkController, mBluetoothController, mBatteryController,
+ mLocationController);
+ } else {
+ mQS = null; // fly away, be free
}
}
@@ -984,7 +1041,8 @@
final boolean emergencyCallsShownElsewhere = mEmergencyCallLabel != null;
final boolean makeVisible =
!(emergencyCallsShownElsewhere && mNetworkController.isEmergencyOnly())
- && mPile.getHeight() < (mNotificationPanel.getHeight() - mCarrierLabelHeight - mNotificationHeaderHeight);
+ && mPile.getHeight() < (mNotificationPanel.getHeight() - mCarrierLabelHeight - mNotificationHeaderHeight)
+ && mScrollView.getVisibility() == View.VISIBLE;
if (force || mCarrierLabelVisible != makeVisible) {
mCarrierLabelVisible = makeVisible;
@@ -1024,7 +1082,13 @@
+ " any=" + any + " clearable=" + clearable);
}
- if (mClearButton.isShown()) {
+ if (mHasFlipSettings
+ && mFlipSettingsView != null
+ && mFlipSettingsView.getVisibility() == View.VISIBLE
+ && mScrollView.getVisibility() != View.VISIBLE) {
+ // the flip settings panel is unequivocally showing; we should not be shown
+ mClearButton.setVisibility(View.INVISIBLE);
+ } else if (mClearButton.isShown()) {
if (clearable != (mClearButton.getAlpha() == 1.0f)) {
ObjectAnimator clearAnimation = ObjectAnimator.ofFloat(
mClearButton, "alpha", clearable ? 1.0f : 0.0f).setDuration(250);
@@ -1225,6 +1289,10 @@
}
}
+ public Handler getHandler() {
+ return mHandler;
+ }
+
View.OnFocusChangeListener mFocusChangeListener = new View.OnFocusChangeListener() {
public void onFocusChange(View v, boolean hasFocus) {
// Because 'v' is a ViewGroup, all its children will be (un)selected
@@ -1293,6 +1361,53 @@
mStatusBarView.collapseAllPanels(true);
}
+ public ViewPropertyAnimator setVisibilityWhenDone(
+ final ViewPropertyAnimator a, final View v, final int vis) {
+ a.setListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ v.setVisibility(vis);
+ a.setListener(null); // oneshot
+ }
+ });
+ return a;
+ }
+
+ public Animator setVisibilityWhenDone(
+ final Animator a, final View v, final int vis) {
+ a.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ v.setVisibility(vis);
+ }
+ });
+ return a;
+ }
+
+ public Animator interpolator(TimeInterpolator ti, Animator a) {
+ a.setInterpolator(ti);
+ return a;
+ }
+
+ public Animator startDelay(int d, Animator a) {
+ a.setStartDelay(d);
+ return a;
+ }
+
+ public Animator start(Animator a) {
+ a.start();
+ return a;
+ }
+
+ final TimeInterpolator mAccelerateInterpolator = new AccelerateInterpolator();
+ final TimeInterpolator mDecelerateInterpolator = new DecelerateInterpolator();
+ final int FLIP_DURATION_OUT = 125;
+ final int FLIP_DURATION_IN = 225;
+ final int FLIP_DURATION = (FLIP_DURATION_IN + FLIP_DURATION_OUT);
+
+ Animator mScrollViewAnim, mFlipSettingsViewAnim, mNotificationButtonAnim,
+ mSettingsButtonAnim, mClearButtonAnim;
+
@Override
public void animateExpandNotificationsPanel() {
if (SPEW) Slog.d(TAG, "animateExpand: mExpandedVisible=" + mExpandedVisible);
@@ -1301,10 +1416,53 @@
}
mNotificationPanel.expand();
+ if (mHasFlipSettings && mScrollView.getVisibility() != View.VISIBLE) {
+ flipToNotifications();
+ }
if (false) postStartTracing();
}
+ public void flipToNotifications() {
+ if (mFlipSettingsViewAnim != null) mFlipSettingsViewAnim.cancel();
+ if (mScrollViewAnim != null) mScrollViewAnim.cancel();
+ if (mSettingsButtonAnim != null) mSettingsButtonAnim.cancel();
+ if (mNotificationButtonAnim != null) mNotificationButtonAnim.cancel();
+ if (mClearButtonAnim != null) mClearButtonAnim.cancel();
+
+ mScrollView.setVisibility(View.VISIBLE);
+ mScrollViewAnim = start(
+ startDelay(FLIP_DURATION_OUT,
+ interpolator(mDecelerateInterpolator,
+ ObjectAnimator.ofFloat(mScrollView, View.SCALE_X, 0f, 1f)
+ .setDuration(FLIP_DURATION_IN)
+ )));
+ mFlipSettingsViewAnim = start(
+ setVisibilityWhenDone(
+ interpolator(mAccelerateInterpolator,
+ ObjectAnimator.ofFloat(mFlipSettingsView, View.SCALE_X, 1f, 0f)
+ )
+ .setDuration(FLIP_DURATION_OUT),
+ mFlipSettingsView, View.INVISIBLE));
+ mNotificationButtonAnim = start(
+ setVisibilityWhenDone(
+ ObjectAnimator.ofFloat(mNotificationButton, View.ALPHA, 0f)
+ .setDuration(FLIP_DURATION),
+ mNotificationButton, View.INVISIBLE));
+ mSettingsButton.setVisibility(View.VISIBLE);
+ mSettingsButtonAnim = start(
+ ObjectAnimator.ofFloat(mSettingsButton, View.ALPHA, 1f)
+ .setDuration(FLIP_DURATION));
+ mClearButton.setVisibility(View.VISIBLE);
+ mClearButton.setAlpha(0f);
+ setAreThereNotifications(); // this will show/hide the button as necessary
+ mNotificationPanel.postDelayed(new Runnable() {
+ public void run() {
+ updateCarrierLabelVisibility(false);
+ }
+ }, FLIP_DURATION - 150);
+ }
+
@Override
public void animateExpandSettingsPanel() {
if (SPEW) Slog.d(TAG, "animateExpand: mExpandedVisible=" + mExpandedVisible);
@@ -1312,15 +1470,89 @@
return;
}
- if (mSettingsPanel != null) mSettingsPanel.expand();
+ if (mHasFlipSettings) {
+ mNotificationPanel.expand();
+ if (mFlipSettingsView.getVisibility() != View.VISIBLE) {
+ flipToSettings();
+ }
+ } else if (mSettingsPanel != null) {
+ mSettingsPanel.expand();
+ }
if (false) postStartTracing();
}
+ public void switchToSettings() {
+ mFlipSettingsView.setScaleX(1f);
+ mFlipSettingsView.setVisibility(View.VISIBLE);
+ mSettingsButton.setVisibility(View.GONE);
+ mScrollView.setVisibility(View.GONE);
+ mNotificationButton.setVisibility(View.VISIBLE);
+ mNotificationButton.setAlpha(1f);
+ mClearButton.setVisibility(View.GONE);
+ }
+
+ public void flipToSettings() {
+ if (mFlipSettingsViewAnim != null) mFlipSettingsViewAnim.cancel();
+ if (mScrollViewAnim != null) mScrollViewAnim.cancel();
+ if (mSettingsButtonAnim != null) mSettingsButtonAnim.cancel();
+ if (mNotificationButtonAnim != null) mNotificationButtonAnim.cancel();
+ if (mClearButtonAnim != null) mClearButtonAnim.cancel();
+
+ mFlipSettingsView.setVisibility(View.VISIBLE);
+ mFlipSettingsView.setScaleX(0f);
+ mFlipSettingsViewAnim = start(
+ startDelay(FLIP_DURATION_OUT,
+ interpolator(mDecelerateInterpolator,
+ ObjectAnimator.ofFloat(mFlipSettingsView, View.SCALE_X, 0f, 1f)
+ .setDuration(FLIP_DURATION_IN)
+ )));
+ mScrollViewAnim = start(
+ setVisibilityWhenDone(
+ interpolator(mAccelerateInterpolator,
+ ObjectAnimator.ofFloat(mScrollView, View.SCALE_X, 1f, 0f)
+ )
+ .setDuration(FLIP_DURATION_OUT),
+ mScrollView, View.INVISIBLE));
+ mSettingsButtonAnim = start(
+ setVisibilityWhenDone(
+ ObjectAnimator.ofFloat(mSettingsButton, View.ALPHA, 0f)
+ .setDuration(FLIP_DURATION),
+ mScrollView, View.INVISIBLE));
+ mNotificationButton.setVisibility(View.VISIBLE);
+ mNotificationButtonAnim = start(
+ ObjectAnimator.ofFloat(mNotificationButton, View.ALPHA, 1f)
+ .setDuration(FLIP_DURATION));
+ mClearButtonAnim = start(
+ setVisibilityWhenDone(
+ ObjectAnimator.ofFloat(mClearButton, View.ALPHA, 0f)
+ .setDuration(FLIP_DURATION),
+ mClearButton, View.INVISIBLE));
+ mNotificationPanel.postDelayed(new Runnable() {
+ public void run() {
+ updateCarrierLabelVisibility(false);
+ }
+ }, FLIP_DURATION - 150);
+ }
+
+ public void flipPanels() {
+ if (mHasFlipSettings) {
+ if (mFlipSettingsView.getVisibility() != View.VISIBLE) {
+ flipToSettings();
+ } else {
+ flipToNotifications();
+ }
+ }
+ }
+
public void animateCollapseQuickSettings() {
mStatusBarView.collapseAllPanels(true);
}
+ void makeExpandedInvisibleSoon() {
+ mHandler.postDelayed(new Runnable() { public void run() { makeExpandedInvisible(); }}, 50);
+ }
+
void makeExpandedInvisible() {
if (SPEW) Slog.d(TAG, "makeExpandedInvisible: mExpandedVisible=" + mExpandedVisible
+ " mExpandedVisible=" + mExpandedVisible);
@@ -1332,6 +1564,18 @@
// Ensure the panel is fully collapsed (just in case; bug 6765842, 7260868)
mStatusBarView.collapseAllPanels(/*animate=*/ false);
+ if (mHasFlipSettings) {
+ // reset things to their proper state
+ mScrollView.setScaleX(1f);
+ mScrollView.setVisibility(View.VISIBLE);
+ mSettingsButton.setAlpha(1f);
+ mSettingsButton.setVisibility(View.VISIBLE);
+ mNotificationPanel.setVisibility(View.GONE);
+ mFlipSettingsView.setVisibility(View.GONE);
+ mNotificationButton.setVisibility(View.GONE);
+ setAreThereNotifications(); // show the clear button
+ }
+
mExpandedVisible = false;
mPile.setLayoutTransitionsEnabled(false);
if (mNavigationBarView != null)
@@ -1622,7 +1866,7 @@
mCommandQueue.setNavigationIconHints(
altBack ? (mNavigationIconHints | StatusBarManager.NAVIGATION_HINT_BACK_ALT)
: (mNavigationIconHints & ~StatusBarManager.NAVIGATION_HINT_BACK_ALT));
- if (mSettingsPanel != null) mSettingsPanel.setImeWindowStatus(vis > 0);
+ if (mQS != null) mQS.setImeWindowStatus(vis > 0);
}
@Override
@@ -1942,24 +2186,42 @@
}
};
+ public void startActivityDismissingKeyguard(Intent intent, boolean onlyProvisioned) {
+ if (onlyProvisioned && !isDeviceProvisioned()) return;
+ try {
+ // Dismiss the lock screen when Settings starts.
+ ActivityManagerNative.getDefault().dismissKeyguardOnNextActivity();
+ } catch (RemoteException e) {
+ }
+ intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
+ mContext.startActivityAsUser(intent, new UserHandle(UserHandle.USER_CURRENT));
+ animateCollapsePanels();
+ }
+
private View.OnClickListener mSettingsButtonListener = new View.OnClickListener() {
public void onClick(View v) {
if (mHasSettingsPanel) {
animateExpandSettingsPanel();
} else {
- try {
- // Dismiss the lock screen when Settings starts.
- ActivityManagerNative.getDefault().dismissKeyguardOnNextActivity();
- } catch (RemoteException e) {
- }
- Intent intent = new Intent(android.provider.Settings.ACTION_SETTINGS);
- intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
- mContext.startActivityAsUser(intent, new UserHandle(UserHandle.USER_CURRENT));
- animateCollapsePanels();
+ startActivityDismissingKeyguard(
+ new Intent(android.provider.Settings.ACTION_SETTINGS), true);
}
}
};
+ private View.OnClickListener mClockClickListener = new View.OnClickListener() {
+ public void onClick(View v) {
+ startActivityDismissingKeyguard(
+ new Intent(Intent.ACTION_QUICK_CLOCK), true); // have fun, everyone
+ }
+ };
+
+ private View.OnClickListener mNotificationButtonListener = new View.OnClickListener() {
+ public void onClick(View v) {
+ animateExpandNotificationsPanel();
+ }
+ };
+
private BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
Slog.v(TAG, "onReceive: " + intent);
@@ -2050,7 +2312,7 @@
}
// Update the QuickSettings container
- if (mSettingsPanel != null) mSettingsPanel.updateResources();
+ if (mQS != null) mQS.updateResources();
loadDimens();
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java
index 3c2f0e6..af6a149 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java
@@ -154,7 +154,8 @@
@Override
public void onAllPanelsCollapsed() {
super.onAllPanelsCollapsed();
- mBar.makeExpandedInvisible();
+ // give animations time to settle
+ mBar.makeExpandedInvisibleSoon();
mFadingPanel = null;
mLastFullyOpenedPanel = null;
}
@@ -191,14 +192,34 @@
if (panel == mFadingPanel && mScrimColor != 0 && ActivityManager.isHighEndGfx()) {
if (mShouldFade) {
frac = mPanelExpandedFractionSum; // don't judge me
- // woo, special effects
- final float k = (float)(1f-0.5f*(1f-Math.cos(3.14159f * Math.pow(1f-frac, 2.2f))));
- // attenuate background color alpha by k
- final int color = (int) ((mScrimColor >>> 24) * k) << 24 | (mScrimColor & 0xFFFFFF);
- mBar.mStatusBarWindow.setBackgroundColor(color);
+ // let's start this 20% of the way down the screen
+ frac = frac * 1.2f - 0.2f;
+ if (frac <= 0) {
+ mBar.mStatusBarWindow.setBackgroundColor(0);
+ } else {
+ // woo, special effects
+ final float k = (float)(1f-0.5f*(1f-Math.cos(3.14159f * Math.pow(1f-frac, 2f))));
+ // attenuate background color alpha by k
+ final int color = (int) ((mScrimColor >>> 24) * k) << 24 | (mScrimColor & 0xFFFFFF);
+ mBar.mStatusBarWindow.setBackgroundColor(color);
+ }
}
}
+ // fade out the panel as it gets buried into the status bar to avoid overdrawing the
+ // status bar on the last frame of a close animation
+ final int H = mBar.getStatusBarHeight();
+ final float ph = panel.getExpandedHeight() + panel.getPaddingBottom();
+ float alpha = 1f;
+ if (ph < 2*H) {
+ if (ph < H) alpha = 0f;
+ else alpha = (ph - H) / H;
+ alpha = alpha * alpha; // get there faster
+ }
+ if (panel.getAlpha() != alpha) {
+ panel.setAlpha(alpha);
+ }
+
mBar.updateCarrierLabelVisibility(false);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettings.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettings.java
index faf20e2..58e3a57 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettings.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettings.java
@@ -88,7 +88,7 @@
private Context mContext;
private PanelBar mBar;
private QuickSettingsModel mModel;
- private QuickSettingsContainerView mContainerView;
+ private ViewGroup mContainerView;
private DisplayManager mDisplayManager;
private WifiDisplayStatus mWifiDisplayStatus;
@@ -145,6 +145,7 @@
IntentFilter filter = new IntentFilter();
filter.addAction(DisplayManager.ACTION_WIFI_DISPLAY_STATUS_CHANGED);
filter.addAction(BluetoothAdapter.ACTION_CONNECTION_STATE_CHANGED);
+ filter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);
filter.addAction(Intent.ACTION_USER_SWITCHED);
mContext.registerReceiver(mReceiver, filter);
@@ -321,7 +322,31 @@
parent.addView(userTile);
mDynamicSpannedTiles.add(userTile);
+ // Brightness
+ QuickSettingsTileView brightnessTile = (QuickSettingsTileView)
+ inflater.inflate(R.layout.quick_settings_tile, parent, false);
+ brightnessTile.setContent(R.layout.quick_settings_tile_brightness, inflater);
+ brightnessTile.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ mBar.collapseAllPanels(true);
+ showBrightnessDialog();
+ }
+ });
+ mModel.addBrightnessTile(brightnessTile, new QuickSettingsModel.RefreshCallback() {
+ @Override
+ public void refreshView(QuickSettingsTileView view, State state) {
+ TextView tv = (TextView) view.findViewById(R.id.brightness_textview);
+ tv.setCompoundDrawablesWithIntrinsicBounds(0, state.iconId, 0, 0);
+ tv.setText(state.label);
+ dismissBrightnessDialog(mBrightnessDialogShortTimeout);
+ }
+ });
+ parent.addView(brightnessTile);
+ mDynamicSpannedTiles.add(brightnessTile);
+
// Time tile
+ /*
QuickSettingsTileView timeTile = (QuickSettingsTileView)
inflater.inflate(R.layout.quick_settings_tile, parent, false);
timeTile.setContent(R.layout.quick_settings_tile_time, inflater);
@@ -338,6 +363,7 @@
});
parent.addView(timeTile);
mDynamicSpannedTiles.add(timeTile);
+ */
// Settings tile
QuickSettingsTileView settingsTile = (QuickSettingsTileView)
@@ -549,27 +575,6 @@
parent.addView(bluetoothTile);
}
- // Brightness
- QuickSettingsTileView brightnessTile = (QuickSettingsTileView)
- inflater.inflate(R.layout.quick_settings_tile, parent, false);
- brightnessTile.setContent(R.layout.quick_settings_tile_brightness, inflater);
- brightnessTile.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- mBar.collapseAllPanels(true);
- showBrightnessDialog();
- }
- });
- mModel.addBrightnessTile(brightnessTile, new QuickSettingsModel.RefreshCallback() {
- @Override
- public void refreshView(QuickSettingsTileView view, State state) {
- TextView tv = (TextView) view.findViewById(R.id.brightness_textview);
- tv.setCompoundDrawablesWithIntrinsicBounds(0, state.iconId, 0, 0);
- tv.setText(state.label);
- dismissBrightnessDialog(mBrightnessDialogShortTimeout);
- }
- });
- parent.addView(brightnessTile);
}
private void addTemporaryTiles(final ViewGroup parent, final LayoutInflater inflater) {
@@ -717,6 +722,7 @@
for (QuickSettingsTileView v : mDynamicSpannedTiles) {
v.setColumnSpan(span);
}
+ ((QuickSettingsContainerView)mContainerView).updateResources();
mContainerView.requestLayout();
// Reset the dialog
@@ -849,6 +855,11 @@
DisplayManager.EXTRA_WIFI_DISPLAY_STATUS);
mWifiDisplayStatus = status;
applyWifiDisplayStatus();
+ } else if (BluetoothAdapter.ACTION_STATE_CHANGED.equals(action)) {
+ int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE,
+ BluetoothAdapter.ERROR);
+ mBluetoothState.enabled = (state == BluetoothAdapter.STATE_ON);
+ applyBluetoothStatus();
} else if (BluetoothAdapter.ACTION_CONNECTION_STATE_CHANGED.equals(action)) {
int status = intent.getIntExtra(BluetoothAdapter.EXTRA_CONNECTION_STATE,
BluetoothAdapter.STATE_DISCONNECTED);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/SettingsPanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/SettingsPanelView.java
index 4e10fa3..a58eb22 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/SettingsPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/SettingsPanelView.java
@@ -53,7 +53,6 @@
super.onFinishInflate();
mQSContainer = (QuickSettingsContainerView) findViewById(R.id.quick_settings_container);
- mQS = new QuickSettings(getContext(), mQSContainer);
Resources resources = getContext().getResources();
mHandleBar = resources.getDrawable(R.drawable.status_bar_close);
@@ -62,6 +61,10 @@
setContentDescription(resources.getString(R.string.accessibility_desc_quick_settings));
}
+
+ public void setQuickSettings(QuickSettings qs) {
+ mQS = qs;
+ }
@Override
public void setBar(PanelBar panelBar) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java
index 0176f42..89c70e8 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java
@@ -42,6 +42,7 @@
private ExpandHelper mExpandHelper;
private NotificationRowLayout latestItems;
private NotificationPanelView mNotificationPanel;
+ private ScrollView mScrollView;
PhoneStatusBar mService;
@@ -55,13 +56,13 @@
protected void onAttachedToWindow () {
super.onAttachedToWindow();
latestItems = (NotificationRowLayout) findViewById(R.id.latestItems);
- ScrollView scroller = (ScrollView) findViewById(R.id.scroll);
+ mScrollView = (ScrollView) findViewById(R.id.scroll);
mNotificationPanel = (NotificationPanelView) findViewById(R.id.notification_panel);
int minHeight = getResources().getDimensionPixelSize(R.dimen.notification_row_min_height);
int maxHeight = getResources().getDimensionPixelSize(R.dimen.notification_row_max_height);
mExpandHelper = new ExpandHelper(mContext, latestItems, minHeight, maxHeight);
mExpandHelper.setEventSource(this);
- mExpandHelper.setScrollView(scroller);
+ mExpandHelper.setScrollView(mScrollView);
}
@Override
@@ -80,7 +81,7 @@
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
boolean intercept = false;
- if (mNotificationPanel.isFullyExpanded()) {
+ if (mNotificationPanel.isFullyExpanded() && mScrollView.getVisibility() == View.VISIBLE) {
intercept = mExpandHelper.onInterceptTouchEvent(ev);
}
if (!intercept) {
diff --git a/policy/src/com/android/internal/policy/impl/GlobalActions.java b/policy/src/com/android/internal/policy/impl/GlobalActions.java
index 9ea47f9..c215f1b 100644
--- a/policy/src/com/android/internal/policy/impl/GlobalActions.java
+++ b/policy/src/com/android/internal/policy/impl/GlobalActions.java
@@ -290,7 +290,7 @@
}
});
AlertDialog dialog = builder.create();
- dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_DIALOG);
+ dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG);
dialog.show();
}
@@ -339,7 +339,7 @@
return mAdapter.getItem(position).onLongPress();
}
});
- dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_DIALOG);
+ dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG);
dialog.setOnDismissListener(this);
@@ -390,11 +390,7 @@
refreshSilentMode();
mAirplaneModeOn.updateState(mAirplaneState);
mAdapter.notifyDataSetChanged();
- if (mKeyguardShowing) {
- mDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG);
- } else {
- mDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_DIALOG);
- }
+ mDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG);
if (SHOW_SILENT_TOGGLE) {
IntentFilter filter = new IntentFilter(AudioManager.RINGER_MODE_CHANGED_ACTION);
mContext.registerReceiver(mRingerModeReceiver, filter);
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindow.java b/policy/src/com/android/internal/policy/impl/PhoneWindow.java
index 72cb1dd..41d67bc 100644
--- a/policy/src/com/android/internal/policy/impl/PhoneWindow.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindow.java
@@ -2867,8 +2867,6 @@
mDecor = generateDecor();
mDecor.setDescendantFocusability(ViewGroup.FOCUS_AFTER_DESCENDANTS);
mDecor.setIsRootNamespace(true);
- mDecor.setLayoutDirection(
- getContext().getResources().getConfiguration().getLayoutDirection());
if (!mInvalidatePanelMenuPosted && mInvalidatePanelMenuFeatures != 0) {
mDecor.postOnAnimation(mInvalidatePanelMenuRunnable);
}
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
index e8af0a5..24ce9bc 100755
--- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
@@ -299,6 +299,7 @@
int mCarDockRotation;
int mDeskDockRotation;
int mHdmiRotation;
+ boolean mHdmiRotationLock;
int mUserRotationMode = WindowManagerPolicy.USER_ROTATION_FREE;
int mUserRotation = Surface.ROTATION_0;
@@ -1035,11 +1036,14 @@
mCanHideNavigationBar = false;
}
+ // For demo purposes, allow the rotation of the HDMI display to be controlled.
+ // By default, HDMI locks rotation to landscape.
if ("portrait".equals(SystemProperties.get("persist.demo.hdmirotation"))) {
mHdmiRotation = mPortraitRotation;
} else {
mHdmiRotation = mLandscapeRotation;
}
+ mHdmiRotationLock = SystemProperties.getBoolean("persist.demo.hdmirotationlock", true);
}
public void updateSettings() {
@@ -1473,16 +1477,24 @@
return getNonDecorDisplayHeight(fullWidth, fullHeight, rotation);
}
+ @Override
public boolean doesForceHide(WindowState win, WindowManager.LayoutParams attrs) {
return attrs.type == WindowManager.LayoutParams.TYPE_KEYGUARD;
}
+ @Override
public boolean canBeForceHidden(WindowState win, WindowManager.LayoutParams attrs) {
- return attrs.type != WindowManager.LayoutParams.TYPE_STATUS_BAR
- && attrs.type != WindowManager.LayoutParams.TYPE_NAVIGATION_BAR
- && attrs.type != WindowManager.LayoutParams.TYPE_WALLPAPER
- && attrs.type != WindowManager.LayoutParams.TYPE_DREAM
- && attrs.type != WindowManager.LayoutParams.TYPE_UNIVERSE_BACKGROUND;
+ switch (attrs.type) {
+ case TYPE_STATUS_BAR:
+ case TYPE_NAVIGATION_BAR:
+ case TYPE_WALLPAPER:
+ case TYPE_DREAM:
+ case TYPE_UNIVERSE_BACKGROUND:
+ case TYPE_KEYGUARD:
+ return false;
+ default:
+ return true;
+ }
}
/** {@inheritDoc} */
@@ -3865,7 +3877,7 @@
// enable 180 degree rotation while docked.
preferredRotation = mDeskDockEnablesAccelerometer
? sensorRotation : mDeskDockRotation;
- } else if (mHdmiPlugged) {
+ } else if (mHdmiPlugged && mHdmiRotationLock) {
// Ignore sensor when plugged into HDMI.
// Note that the dock orientation overrides the HDMI orientation.
preferredRotation = mHdmiRotation;
@@ -4530,5 +4542,7 @@
pw.print(" mSeascapeRotation="); pw.println(mSeascapeRotation);
pw.print(prefix); pw.print("mPortraitRotation="); pw.print(mPortraitRotation);
pw.print(" mUpsideDownRotation="); pw.println(mUpsideDownRotation);
+ pw.print(prefix); pw.print("mHdmiRotation="); pw.print(mHdmiRotation);
+ pw.print(" mHdmiRotationLock="); pw.println(mHdmiRotationLock);
}
}
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardFaceUnlockView.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardFaceUnlockView.java
index 78fdda3..04ab871 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardFaceUnlockView.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardFaceUnlockView.java
@@ -75,7 +75,7 @@
public void onDetachedFromWindow() {
if (DEBUG) Log.d(TAG, "onDetachedFromWindow()");
if (mBiometricUnlock != null) {
- mBiometricUnlock.stopAndShowBackup();
+ mBiometricUnlock.stop();
}
}
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardHostView.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardHostView.java
index eca8618..b86e5b8 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardHostView.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardHostView.java
@@ -79,7 +79,7 @@
private boolean mEnableMenuKey;
private boolean mIsVerifyUnlockOnly;
private boolean mEnableFallback; // TODO: This should get the value from KeyguardPatternView
- private SecurityMode mCurrentSecuritySelection = SecurityMode.None;
+ private SecurityMode mCurrentSecuritySelection = SecurityMode.Invalid;
protected Runnable mLaunchRunnable;
@@ -433,7 +433,8 @@
*/
private void showBackupSecurityScreen() {
if (DEBUG) Log.d(TAG, "showBackupSecurity()");
- showSecurityScreen(mSecurityModel.getBackupSecurityMode());
+ SecurityMode backup = mSecurityModel.getBackupSecurityMode(mCurrentSecuritySelection);
+ showSecurityScreen(backup);
}
public boolean showNextSecurityScreenIfPresent() {
@@ -543,6 +544,45 @@
private KeyguardStatusViewManager mKeyguardStatusViewManager;
+ // Used to ignore callbacks from methods that are no longer current (e.g. face unlock).
+ // This avoids unwanted asynchronous events from messing with the state.
+ private KeyguardSecurityCallback mNullCallback = new KeyguardSecurityCallback() {
+
+ @Override
+ public void userActivity(long timeout) {
+ }
+
+ @Override
+ public void showBackupSecurity() {
+ }
+
+ @Override
+ public void setOnDismissRunnable(Runnable runnable) {
+ }
+
+ @Override
+ public void reportSuccessfulUnlockAttempt() {
+ }
+
+ @Override
+ public void reportFailedUnlockAttempt() {
+ }
+
+ @Override
+ public boolean isVerifyUnlockOnly() {
+ return false;
+ }
+
+ @Override
+ public int getFailedAttempts() {
+ return 0;
+ }
+
+ @Override
+ public void dismiss(boolean securityVerified) {
+ }
+ };
+
@Override
public void reset() {
mIsVerifyUnlockOnly = false;
@@ -568,9 +608,11 @@
}
}
boolean simPukFullScreen = getResources().getBoolean(R.bool.kg_sim_puk_account_full_screen);
- if (view == null) {
+ int layoutId = getLayoutIdFor(securityMode);
+ if (view == null && layoutId != 0) {
final LayoutInflater inflater = LayoutInflater.from(mContext);
- View v = inflater.inflate(getLayoutIdFor(securityMode), this, false);
+ if (DEBUG) Log.v(TAG, "inflating id = " + layoutId);
+ View v = inflater.inflate(layoutId, this, false);
mSecurityViewContainer.addView(v);
updateSecurityView(v);
@@ -617,8 +659,12 @@
KeyguardSecurityView newView = getSecurityView(securityMode);
// Emulate Activity life cycle
- oldView.onPause();
+ if (oldView != null) {
+ oldView.onPause();
+ oldView.setKeyguardCallback(mNullCallback); // ignore requests from old view
+ }
newView.onResume();
+ newView.setKeyguardCallback(mCallback);
final boolean needsInput = newView.needsInput();
if (mViewMediatorCallback != null) {
@@ -749,7 +795,7 @@
case SimPin: return R.layout.keyguard_sim_pin_view;
case SimPuk: return R.layout.keyguard_sim_puk_view;
default:
- throw new RuntimeException("No layout for securityMode " + securityMode);
+ return 0;
}
}
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardPasswordView.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardPasswordView.java
index 3b37d56..1868507 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardPasswordView.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardPasswordView.java
@@ -86,6 +86,13 @@
mLockPatternUtils = utils;
}
+ @Override
+ public void onWindowFocusChanged(boolean hasWindowFocus) {
+ if (hasWindowFocus) {
+ reset();
+ }
+ }
+
public void reset() {
// start fresh
mPasswordEntry.setText("");
@@ -191,7 +198,9 @@
}
public void afterTextChanged(Editable s) {
- mCallback.userActivity(0);
+ if (mCallback != null) {
+ mCallback.userActivity(0);
+ }
}
});
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardSecurityModel.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardSecurityModel.java
index 80282c1..59e2ca9 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardSecurityModel.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardSecurityModel.java
@@ -28,6 +28,7 @@
* @see com.android.internal.policy.impl.LockPatternKeyguardView#getUnlockMode()
*/
enum SecurityMode {
+ Invalid, // NULL state
None, // No security enabled
Pattern, // Unlock by drawing a pattern.
Password, // Unlock by entering a password or PIN
@@ -53,7 +54,7 @@
* Returns true if biometric unlock is installed and selected. If this returns false there is
* no need to even construct the biometric unlock.
*/
- private boolean isBiometricUnlockEnabled() {
+ boolean isBiometricUnlockEnabled() {
return mLockPatternUtils.usingBiometricWeak()
&& mLockPatternUtils.isBiometricWeakInstalled();
}
@@ -128,15 +129,7 @@
*
* @return backup method or current security mode
*/
- SecurityMode getBackupSecurityMode() {
- SecurityMode mode = getSecurityMode();
-
- // Note that getAlternateFor() cannot be called here because we want to get the backup for
- // biometric unlock even if it's suppressed; it just has to be enabled.
- if (isBiometricUnlockEnabled()
- && (mode == SecurityMode.Password || mode == SecurityMode.Pattern)) {
- mode = SecurityMode.Biometric;
- }
+ SecurityMode getBackupSecurityMode(SecurityMode mode) {
switch(mode) {
case Biometric:
return getSecurityMode();
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardStatusViewManager.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardStatusViewManager.java
index 9615e71..5b85064 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardStatusViewManager.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardStatusViewManager.java
@@ -221,6 +221,7 @@
mHandler.removeCallbacks(mClearSecurityMessageRunnable);
mHandler.postDelayed(mClearSecurityMessageRunnable, SECURITY_MESSAGE_DURATION);
}
+ mSecurityMessage.announceForAccessibility(mSecurityMessage.getText());
}
/**
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardViewManager.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardViewManager.java
index 0ad2404..b66c883 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardViewManager.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardViewManager.java
@@ -43,7 +43,7 @@
/**
* Manages creating, showing, hiding and resetting the keyguard. Calls back
- * via {@link com.android.internal.policy.impl.KeyguardViewCallback} to poke
+ * via {@link KeyguardViewMediator.ViewMediatorCallback} to poke
* the wake lock and report that the keyguard is done, which is in turn,
* reported to this class by the current {@link KeyguardViewBase}.
*/
@@ -233,6 +233,7 @@
if (mScreenOn) {
mKeyguardView.show();
+ mKeyguardView.requestFocus();
}
}
@@ -314,22 +315,25 @@
// Caller should wait for this window to be shown before turning
// on the screen.
- if (mKeyguardHost.getVisibility() == View.VISIBLE) {
- // Keyguard may be in the process of being shown, but not yet
- // updated with the window manager... give it a chance to do so.
- mKeyguardHost.post(new Runnable() {
- public void run() {
- if (mKeyguardHost.getVisibility() == View.VISIBLE) {
- showListener.onShown(mKeyguardHost.getWindowToken());
- } else {
- showListener.onShown(null);
+ if (showListener != null) {
+ if (mKeyguardHost.getVisibility() == View.VISIBLE) {
+ // Keyguard may be in the process of being shown, but not yet
+ // updated with the window manager... give it a chance to do so.
+ mKeyguardHost.post(new Runnable() {
+ @Override
+ public void run() {
+ if (mKeyguardHost.getVisibility() == View.VISIBLE) {
+ showListener.onShown(mKeyguardHost.getWindowToken());
+ } else {
+ showListener.onShown(null);
+ }
}
- }
- });
- } else {
- showListener.onShown(null);
+ });
+ } else {
+ showListener.onShown(null);
+ }
}
- } else {
+ } else if (showListener != null) {
showListener.onShown(null);
}
}
@@ -356,10 +360,9 @@
if (mKeyguardView != null) {
mKeyguardView.wakeWhenReadyTq(keyCode);
return true;
- } else {
- Log.w(TAG, "mKeyguardView is null in wakeWhenReadyTq");
- return false;
}
+ Log.w(TAG, "mKeyguardView is null in wakeWhenReadyTq");
+ return false;
}
/**
@@ -382,6 +385,7 @@
final KeyguardViewBase lastView = mKeyguardView;
mKeyguardView = null;
mKeyguardHost.postDelayed(new Runnable() {
+ @Override
public void run() {
synchronized (KeyguardViewManager.this) {
lastView.cleanUp();
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardViewMediator.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardViewMediator.java
index 92f9dfd..ceb0325 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardViewMediator.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardViewMediator.java
@@ -629,9 +629,7 @@
mScreenOn = true;
cancelDoKeyguardLaterLocked();
if (DEBUG) Log.d(TAG, "onScreenTurnedOn, seq = " + mDelayedShowingSequence);
- if (showListener != null) {
- notifyScreenOnLocked(showListener);
- }
+ notifyScreenOnLocked(showListener);
}
maybeSendUserPresentBroadcast();
}
@@ -1365,7 +1363,7 @@
/**
* Handle message sent by {@link #verifyUnlock}
- * @see #RESET
+ * @see #VERIFY_UNLOCK
*/
private void handleVerifyUnlock() {
synchronized (KeyguardViewMediator.this) {
diff --git a/services/java/com/android/server/AppWidgetService.java b/services/java/com/android/server/AppWidgetService.java
index c18fe0e..06d37dc 100644
--- a/services/java/com/android/server/AppWidgetService.java
+++ b/services/java/com/android/server/AppWidgetService.java
@@ -98,21 +98,19 @@
IntentFilter userFilter = new IntentFilter();
userFilter.addAction(Intent.ACTION_USER_REMOVED);
+ userFilter.addAction(Intent.ACTION_USER_STOPPING);
mContext.registerReceiver(new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
- onUserRemoved(intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1));
+ if (Intent.ACTION_USER_REMOVED.equals(intent.getAction())) {
+ onUserRemoved(intent.getIntExtra(Intent.EXTRA_USER_HANDLE,
+ UserHandle.USER_NULL));
+ } else if (Intent.ACTION_USER_STOPPING.equals(intent.getAction())) {
+ onUserStopping(intent.getIntExtra(Intent.EXTRA_USER_HANDLE,
+ UserHandle.USER_NULL));
+ }
}
}, userFilter);
-
- IntentFilter userStopFilter = new IntentFilter();
- userStopFilter.addAction(Intent.ACTION_USER_STOPPED);
- mContext.registerReceiverAsUser(new BroadcastReceiver() {
- @Override
- public void onReceive(Context context, Intent intent) {
- onUserStopped(getSendingUserId());
- }
- }, UserHandle.ALL, userFilter, null, null);
}
/**
@@ -203,7 +201,7 @@
synchronized (mAppWidgetServices) {
AppWidgetServiceImpl impl = mAppWidgetServices.get(userId);
mAppWidgetServices.remove(userId);
-
+
if (impl == null) {
AppWidgetServiceImpl.getSettingsFile(userId).delete();
} else {
@@ -212,7 +210,15 @@
}
}
- public void onUserStopped(int userId) {
+ public void onUserStopping(int userId) {
+ if (userId < 1) return;
+ synchronized (mAppWidgetServices) {
+ AppWidgetServiceImpl impl = mAppWidgetServices.get(userId);
+ if (impl != null) {
+ mAppWidgetServices.remove(userId);
+ impl.onUserStopping();
+ }
+ }
}
private AppWidgetServiceImpl getImplForUser(int userId) {
@@ -304,6 +310,8 @@
@Override
public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+ mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DUMP, TAG);
+
// Dump the state of all the app widget providers
synchronized (mAppWidgetServices) {
IndentingPrintWriter ipw = new IndentingPrintWriter(pw, " ");
@@ -322,11 +330,11 @@
String action = intent.getAction();
// Slog.d(TAG, "received " + action);
if (Intent.ACTION_BOOT_COMPLETED.equals(action)) {
- int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1);
+ int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
if (userId >= 0) {
getImplForUser(userId).sendInitialBroadcasts();
} else {
- Slog.w(TAG, "Not user handle supplied in " + intent);
+ Slog.w(TAG, "Incorrect user handle supplied in " + intent);
}
} else if (Intent.ACTION_CONFIGURATION_CHANGED.equals(action)) {
for (int i = 0; i < mAppWidgetServices.size(); i++) {
diff --git a/services/java/com/android/server/AppWidgetServiceImpl.java b/services/java/com/android/server/AppWidgetServiceImpl.java
index 9fea6f3..6a313a0 100644
--- a/services/java/com/android/server/AppWidgetServiceImpl.java
+++ b/services/java/com/android/server/AppWidgetServiceImpl.java
@@ -1778,13 +1778,16 @@
return new AtomicFile(settingsFile);
}
- void onUserRemoved() {
+ void onUserStopping() {
// prune the ones we don't want to keep
int N = mInstalledProviders.size();
for (int i = N - 1; i >= 0; i--) {
Provider p = mInstalledProviders.get(i);
cancelBroadcasts(p);
}
+ }
+
+ void onUserRemoved() {
getSettingsFile(mUserId).delete();
}
diff --git a/services/java/com/android/server/EventLogTags.logtags b/services/java/com/android/server/EventLogTags.logtags
index 840e006..0fe66fc 100644
--- a/services/java/com/android/server/EventLogTags.logtags
+++ b/services/java/com/android/server/EventLogTags.logtags
@@ -52,12 +52,12 @@
# NotificationManagerService.java
# ---------------------------
# when a NotificationManager.notify is called
-2750 notification_enqueue (pkg|3),(id|1|5),(tag|3),(notification|3)
+2750 notification_enqueue (pkg|3),(id|1|5),(tag|3),(userid|1|5),(notification|3)
# when someone tries to cancel a notification, the notification manager sometimes
# calls this with flags too
-2751 notification_cancel (pkg|3),(id|1|5),(tag|3),(required_flags|1),(forbidden_flags|1)
+2751 notification_cancel (pkg|3),(id|1|5),(tag|3),(userid|1|5),(required_flags|1),(forbidden_flags|1)
# when someone tries to cancel all of the notifications for a particular package
-2752 notification_cancel_all (pkg|3),(required_flags|1),(forbidden_flags|1)
+2752 notification_cancel_all (pkg|3),(userid|1|5),(required_flags|1),(forbidden_flags|1)
# ---------------------------
diff --git a/services/java/com/android/server/LocationManagerService.java b/services/java/com/android/server/LocationManagerService.java
index c5016e6..63eeeb3 100644
--- a/services/java/com/android/server/LocationManagerService.java
+++ b/services/java/com/android/server/LocationManagerService.java
@@ -609,10 +609,9 @@
}
/**
- * Throw SecurityException if caller has neither COARSE or FINE.
- * Otherwise, return the best permission.
+ * Returns the best permission available to the caller.
*/
- private String checkPermission() {
+ private String getBestCallingPermission() {
if (mContext.checkCallingOrSelfPermission(ACCESS_FINE_LOCATION) ==
PackageManager.PERMISSION_GRANTED) {
return ACCESS_FINE_LOCATION;
@@ -620,9 +619,20 @@
PackageManager.PERMISSION_GRANTED) {
return ACCESS_COARSE_LOCATION;
}
+ return null;
+ }
- throw new SecurityException("Location requires either ACCESS_COARSE_LOCATION or" +
- " ACCESS_FINE_LOCATION permission");
+ /**
+ * Throw SecurityException if caller has neither COARSE or FINE.
+ * Otherwise, return the best permission.
+ */
+ private String checkPermission() {
+ String perm = getBestCallingPermission();
+ if (perm == null) {
+ throw new SecurityException("Location requires either ACCESS_COARSE_LOCATION or" +
+ " ACCESS_FINE_LOCATION permission");
+ }
+ return perm;
}
/**
@@ -635,19 +645,15 @@
}
}
- private boolean isAllowedProviderSafe(String provider) {
+ private String getMinimumPermissionForProvider(String provider) {
if (LocationManager.GPS_PROVIDER.equals(provider) ||
LocationManager.PASSIVE_PROVIDER.equals(provider)) {
// gps and passive providers require FINE permission
- return mContext.checkCallingOrSelfPermission(ACCESS_FINE_LOCATION)
- == PackageManager.PERMISSION_GRANTED;
+ return ACCESS_FINE_LOCATION;
} else if (LocationManager.NETWORK_PROVIDER.equals(provider) ||
LocationManager.FUSED_PROVIDER.equals(provider)) {
// network and fused providers are ok with COARSE or FINE
- return (mContext.checkCallingOrSelfPermission(ACCESS_FINE_LOCATION)
- == PackageManager.PERMISSION_GRANTED) ||
- (mContext.checkCallingOrSelfPermission(ACCESS_COARSE_LOCATION)
- == PackageManager.PERMISSION_GRANTED);
+ return ACCESS_COARSE_LOCATION;
} else {
// mock providers
LocationProviderInterface lp = mMockProviders.get(provider);
@@ -656,20 +662,43 @@
if (properties != null) {
if (properties.mRequiresSatellite) {
// provider requiring satellites require FINE permission
- return mContext.checkCallingOrSelfPermission(ACCESS_FINE_LOCATION)
- == PackageManager.PERMISSION_GRANTED;
+ return ACCESS_FINE_LOCATION;
} else if (properties.mRequiresNetwork || properties.mRequiresCell) {
// provider requiring network and or cell require COARSE or FINE
- return (mContext.checkCallingOrSelfPermission(ACCESS_FINE_LOCATION)
- == PackageManager.PERMISSION_GRANTED) ||
- (mContext.checkCallingOrSelfPermission(ACCESS_COARSE_LOCATION)
- == PackageManager.PERMISSION_GRANTED);
+ return ACCESS_COARSE_LOCATION;
}
}
}
}
- return false;
+ return null;
+ }
+
+ private boolean isPermissionSufficient(String perm, String minPerm) {
+ if (ACCESS_FINE_LOCATION.equals(minPerm)) {
+ return ACCESS_FINE_LOCATION.equals(perm);
+ } else if (ACCESS_COARSE_LOCATION.equals(minPerm)) {
+ return ACCESS_FINE_LOCATION.equals(perm) ||
+ ACCESS_COARSE_LOCATION.equals(perm);
+ } else {
+ return false;
+ }
+ }
+
+ private void checkPermissionForProvider(String perm, String provider) {
+ String minPerm = getMinimumPermissionForProvider(provider);
+ if (!isPermissionSufficient(perm, minPerm)) {
+ if (ACCESS_FINE_LOCATION.equals(minPerm)) {
+ throw new SecurityException("Location provider \"" + provider +
+ "\" requires ACCESS_FINE_LOCATION permission.");
+ } else if (ACCESS_COARSE_LOCATION.equals(minPerm)) {
+ throw new SecurityException("Location provider \"" + provider +
+ "\" requires ACCESS_COARSE_LOCATION or ACCESS_FINE_LOCATION permission.");
+ } else {
+ throw new SecurityException("Insufficient permission for location provider \"" +
+ provider + "\".");
+ }
+ }
}
/**
@@ -703,6 +732,7 @@
@Override
public List<String> getProviders(Criteria criteria, boolean enabledOnly) {
ArrayList<String> out;
+ String perm = getBestCallingPermission();
int callingUserId = UserHandle.getCallingUserId();
long identity = Binder.clearCallingIdentity();
try {
@@ -713,7 +743,7 @@
if (LocationManager.FUSED_PROVIDER.equals(name)) {
continue;
}
- if (isAllowedProviderSafe(name)) {
+ if (isPermissionSufficient(perm, getMinimumPermissionForProvider(name))) {
if (enabledOnly && !isAllowedBySettingsLocked(name, callingUserId)) {
continue;
}
@@ -980,26 +1010,12 @@
return receiver;
}
- private boolean isProviderAllowedByCoarsePermission(String provider) {
- if (LocationManager.FUSED_PROVIDER.equals(provider)) {
- return true;
- }
- if (LocationManager.PASSIVE_PROVIDER.equals(provider)) {
- return true;
- }
- if (LocationManager.NETWORK_PROVIDER.equals(provider)) {
- return true;
- }
- return false;
- }
-
private String checkPermissionAndRequest(LocationRequest request) {
- String perm = checkPermission();
+ String perm = getBestCallingPermission();
+ String provider = request.getProvider();
+ checkPermissionForProvider(perm, provider);
if (ACCESS_COARSE_LOCATION.equals(perm)) {
- if (!isProviderAllowedByCoarsePermission(request.getProvider())) {
- throw new SecurityException("Requires ACCESS_FINE_LOCATION permission");
- }
switch (request.getQuality()) {
case LocationRequest.ACCURACY_FINE:
request.setQuality(LocationRequest.ACCURACY_BLOCK);
@@ -1324,7 +1340,11 @@
*/
@Override
public ProviderProperties getProviderProperties(String provider) {
- checkPermission();
+ if (mProvidersByName.get(provider) == null) {
+ return null;
+ }
+
+ checkPermissionForProvider(getBestCallingPermission(), provider);
LocationProviderInterface p;
synchronized (mLock) {
@@ -1337,13 +1357,8 @@
@Override
public boolean isProviderEnabled(String provider) {
- String perms = checkPermission();
+ checkPermissionForProvider(getBestCallingPermission(), provider);
if (LocationManager.FUSED_PROVIDER.equals(provider)) return false;
- if (ACCESS_COARSE_LOCATION.equals(perms) &&
- !isProviderAllowedByCoarsePermission(provider)) {
- throw new SecurityException("The \"" + provider +
- "\" provider requires ACCESS_FINE_LOCATION permission");
- }
long identity = Binder.clearCallingIdentity();
try {
diff --git a/services/java/com/android/server/NotificationManagerService.java b/services/java/com/android/server/NotificationManagerService.java
index 09a606e..4a54efe 100755
--- a/services/java/com/android/server/NotificationManagerService.java
+++ b/services/java/com/android/server/NotificationManagerService.java
@@ -916,7 +916,7 @@
// behalf of the download manager without affecting other apps.
if (!pkg.equals("com.android.providers.downloads")
|| Log.isLoggable("DownloadManager", Log.VERBOSE)) {
- EventLog.writeEvent(EventLogTags.NOTIFICATION_ENQUEUE, pkg, id, tag,
+ EventLog.writeEvent(EventLogTags.NOTIFICATION_ENQUEUE, pkg, id, tag, userId,
notification.toString());
}
@@ -1207,7 +1207,7 @@
*/
private void cancelNotification(String pkg, String tag, int id, int mustHaveFlags,
int mustNotHaveFlags, boolean sendDelete, int userId) {
- EventLog.writeEvent(EventLogTags.NOTIFICATION_CANCEL, pkg, id, tag,
+ EventLog.writeEvent(EventLogTags.NOTIFICATION_CANCEL, pkg, id, tag, userId,
mustHaveFlags, mustNotHaveFlags);
synchronized (mNotificationList) {
@@ -1231,20 +1231,34 @@
}
/**
+ * Determine whether the userId applies to the notification in question, either because
+ * they match exactly, or one of them is USER_ALL (which is treated as a wildcard).
+ */
+ private boolean notificationMatchesUserId(NotificationRecord r, int userId) {
+ return
+ // looking for USER_ALL notifications? match everything
+ userId == UserHandle.USER_ALL
+ // a notification sent to USER_ALL matches any query
+ || r.userId == UserHandle.USER_ALL
+ // an exact user match
+ || r.userId == userId;
+ }
+
+ /**
* Cancels all notifications from a given package that have all of the
* {@code mustHaveFlags}.
*/
boolean cancelAllNotificationsInt(String pkg, int mustHaveFlags,
int mustNotHaveFlags, boolean doit, int userId) {
- EventLog.writeEvent(EventLogTags.NOTIFICATION_CANCEL_ALL, pkg, mustHaveFlags,
- mustNotHaveFlags);
+ EventLog.writeEvent(EventLogTags.NOTIFICATION_CANCEL_ALL, pkg, userId,
+ mustHaveFlags, mustNotHaveFlags);
synchronized (mNotificationList) {
final int N = mNotificationList.size();
boolean canceledSomething = false;
for (int i = N-1; i >= 0; --i) {
NotificationRecord r = mNotificationList.get(i);
- if (userId != UserHandle.USER_ALL && r.userId != userId) {
+ if (!notificationMatchesUserId(r, userId)) {
continue;
}
if ((r.notification.flags & mustHaveFlags) != mustHaveFlags) {
@@ -1322,7 +1336,7 @@
for (int i=N-1; i>=0; i--) {
NotificationRecord r = mNotificationList.get(i);
- if (r.userId != userId) {
+ if (!notificationMatchesUserId(r, userId)) {
continue;
}
@@ -1376,7 +1390,7 @@
final int len = list.size();
for (int i=0; i<len; i++) {
NotificationRecord r = list.get(i);
- if (r.userId != userId || r.id != id) {
+ if (!notificationMatchesUserId(r, userId) || r.id != id) {
continue;
}
if (tag == null) {
diff --git a/services/java/com/android/server/WallpaperManagerService.java b/services/java/com/android/server/WallpaperManagerService.java
index e0f3814..a02fc8d 100644
--- a/services/java/com/android/server/WallpaperManagerService.java
+++ b/services/java/com/android/server/WallpaperManagerService.java
@@ -458,15 +458,21 @@
IntentFilter userFilter = new IntentFilter();
userFilter.addAction(Intent.ACTION_USER_REMOVED);
+ userFilter.addAction(Intent.ACTION_USER_STOPPING);
mContext.registerReceiver(new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (Intent.ACTION_USER_REMOVED.equals(action)) {
- removeUser(intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0));
+ onRemoveUser(intent.getIntExtra(Intent.EXTRA_USER_HANDLE,
+ UserHandle.USER_NULL));
+ } else if (Intent.ACTION_USER_STOPPING.equals(action)) {
+ onStoppingUser(intent.getIntExtra(Intent.EXTRA_USER_HANDLE,
+ UserHandle.USER_NULL));
}
}
}, userFilter);
+
try {
ActivityManagerNative.getDefault().registerUserSwitchObserver(
new IUserSwitchObserver.Stub() {
@@ -491,13 +497,24 @@
}
}
- void removeUser(int userId) {
+ void onStoppingUser(int userId) {
+ if (userId < 1) return;
synchronized (mLock) {
WallpaperData wallpaper = mWallpaperMap.get(userId);
if (wallpaper != null) {
- wallpaper.wallpaperObserver.stopWatching();
+ if (wallpaper.wallpaperObserver != null) {
+ wallpaper.wallpaperObserver.stopWatching();
+ wallpaper.wallpaperObserver = null;
+ }
mWallpaperMap.remove(userId);
}
+ }
+ }
+
+ void onRemoveUser(int userId) {
+ if (userId < 1) return;
+ synchronized (mLock) {
+ onStoppingUser(userId);
File wallpaperFile = new File(getWallpaperDir(userId), WALLPAPER);
wallpaperFile.delete();
File wallpaperInfoFile = new File(getWallpaperDir(userId), WALLPAPER_INFO);
diff --git a/services/java/com/android/server/accessibility/ScreenMagnifier.java b/services/java/com/android/server/accessibility/ScreenMagnifier.java
index c8931f4..caf37b7 100644
--- a/services/java/com/android/server/accessibility/ScreenMagnifier.java
+++ b/services/java/com/android/server/accessibility/ScreenMagnifier.java
@@ -38,6 +38,7 @@
import android.os.Message;
import android.os.RemoteException;
import android.os.ServiceManager;
+import android.os.SystemClock;
import android.provider.Settings;
import android.util.Property;
import android.util.Slog;
@@ -662,12 +663,33 @@
while (mDelayedEventQueue != null) {
MotionEventInfo info = mDelayedEventQueue;
mDelayedEventQueue = info.mNext;
- ScreenMagnifier.this.onMotionEvent(info.mEvent, info.mRawEvent,
- info.mPolicyFlags);
+ final long offset = SystemClock.uptimeMillis() - info.mCachedTimeMillis;
+ MotionEvent event = obtainEventWithOffsetTimeAndDownTime(info.mEvent, offset);
+ MotionEvent rawEvent = obtainEventWithOffsetTimeAndDownTime(info.mRawEvent, offset);
+ ScreenMagnifier.this.onMotionEvent(event, rawEvent, info.mPolicyFlags);
+ event.recycle();
+ rawEvent.recycle();
info.recycle();
}
}
+ private MotionEvent obtainEventWithOffsetTimeAndDownTime(MotionEvent event, long offset) {
+ final int pointerCount = event.getPointerCount();
+ PointerCoords[] coords = getTempPointerCoordsWithMinSize(pointerCount);
+ PointerProperties[] properties = getTempPointerPropertiesWithMinSize(pointerCount);
+ for (int i = 0; i < pointerCount; i++) {
+ event.getPointerCoords(i, coords[i]);
+ event.getPointerProperties(i, properties[i]);
+ }
+ final long downTime = event.getDownTime() + offset;
+ final long eventTime = event.getEventTime() + offset;
+ return MotionEvent.obtain(downTime, eventTime,
+ event.getAction(), pointerCount, properties, coords,
+ event.getMetaState(), event.getButtonState(),
+ 1.0f, 1.0f, event.getDeviceId(), event.getEdgeFlags(),
+ event.getSource(), event.getFlags());
+ }
+
private void clearDelayedMotionEvents() {
while (mDelayedEventQueue != null) {
MotionEventInfo info = mDelayedEventQueue;
@@ -746,6 +768,7 @@
public MotionEvent mEvent;
public MotionEvent mRawEvent;
public int mPolicyFlags;
+ public long mCachedTimeMillis;
public static MotionEventInfo obtain(MotionEvent event, MotionEvent rawEvent,
int policyFlags) {
@@ -770,6 +793,7 @@
mEvent = MotionEvent.obtain(event);
mRawEvent = MotionEvent.obtain(rawEvent);
mPolicyFlags = policyFlags;
+ mCachedTimeMillis = SystemClock.uptimeMillis();
}
public void recycle() {
@@ -793,6 +817,7 @@
mRawEvent.recycle();
mRawEvent = null;
mPolicyFlags = 0;
+ mCachedTimeMillis = 0;
}
}
@@ -850,6 +875,7 @@
private static final int MESSAGE_ON_RECTANGLE_ON_SCREEN_REQUESTED = 3;
private static final int MESSAGE_ON_WINDOW_TRANSITION = 4;
private static final int MESSAGE_ON_ROTATION_CHANGED = 5;
+ private static final int MESSAGE_ON_WINDOW_LAYERS_CHANGED = 6;
private final Handler mHandler = new MyHandler();
@@ -880,24 +906,8 @@
mDisplayContentChangeListener = new IDisplayContentChangeListener.Stub() {
@Override
public void onWindowTransition(int displayId, int transition, WindowInfo info) {
- Message message = mHandler.obtainMessage(MESSAGE_ON_WINDOW_TRANSITION,
- transition, 0, WindowInfo.obtain(info));
- // TODO: This makes me quite unhappy but for the time being the
- // least risky fix for cases where the keyguard is removed but
- // the windows it force hides are not made visible yet. Hence,
- // we would compute the magnified frame before we have a stable
- // state. One more reason to move the magnified frame computation
- // in the window manager!
- if (info.type == WindowManager.LayoutParams.TYPE_KEYGUARD
- || info.type == WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG
- && (transition == WindowManagerPolicy.TRANSIT_EXIT
- || transition == WindowManagerPolicy.TRANSIT_HIDE)) {
- final long delay = (long) (2 * mLongAnimationDuration
- * mWindowAnimationScale);
- mHandler.sendMessageDelayed(message, delay);
- } else {
- message.sendToTarget();
- }
+ mHandler.obtainMessage(MESSAGE_ON_WINDOW_TRANSITION,
+ transition, 0, WindowInfo.obtain(info)).sendToTarget();
}
@Override
@@ -917,6 +927,11 @@
mHandler.obtainMessage(MESSAGE_ON_ROTATION_CHANGED, rotation, 0)
.sendToTarget();
}
+
+ @Override
+ public void onWindowLayersChanged(int displayId) throws RemoteException {
+ mHandler.sendEmptyMessage(MESSAGE_ON_WINDOW_LAYERS_CHANGED);
+ }
};
try {
@@ -1192,6 +1207,9 @@
final int rotation = message.arg1;
handleOnRotationChanged(rotation);
} break;
+ case MESSAGE_ON_WINDOW_LAYERS_CHANGED: {
+ mViewport.recomputeBounds(mMagnificationController.isMagnifying());
+ } break;
default: {
throw new IllegalArgumentException("Unknown message: " + action);
}
diff --git a/services/java/com/android/server/connectivity/Vpn.java b/services/java/com/android/server/connectivity/Vpn.java
index 03ff21f..bb19cc7 100644
--- a/services/java/com/android/server/connectivity/Vpn.java
+++ b/services/java/com/android/server/connectivity/Vpn.java
@@ -628,6 +628,7 @@
private final String[] mDaemons;
private final String[][] mArguments;
private final LocalSocket[] mSockets;
+ private final String mOuterInterface;
private long mTimer = -1;
@@ -638,10 +639,15 @@
// TODO: clear arguments from memory once launched
mArguments = new String[][] {racoon, mtpd};
mSockets = new LocalSocket[mDaemons.length];
+
+ // This is the interface which VPN is running on,
+ // mConfig.interfaze will change to point to OUR
+ // internal interface soon. TODO - add inner/outer to mconfig
+ mOuterInterface = mConfig.interfaze;
}
public void check(String interfaze) {
- if (interfaze.equals(mConfig.interfaze)) {
+ if (interfaze.equals(mOuterInterface)) {
Log.i(TAG, "Legacy VPN is going down with " + interfaze);
exit();
}
diff --git a/services/java/com/android/server/display/DisplayDeviceInfo.java b/services/java/com/android/server/display/DisplayDeviceInfo.java
index b4dab86..e76bf44 100644
--- a/services/java/com/android/server/display/DisplayDeviceInfo.java
+++ b/services/java/com/android/server/display/DisplayDeviceInfo.java
@@ -17,6 +17,7 @@
package com.android.server.display;
import android.util.DisplayMetrics;
+import android.view.Surface;
import libcore.util.Objects;
@@ -31,11 +32,21 @@
public static final int FLAG_DEFAULT_DISPLAY = 1 << 0;
/**
- * Flag: Indicates that this display device can rotate to show contents in a
- * different orientation. Otherwise the rotation is assumed to be fixed in the
- * natural orientation and the display manager should transform the content to fit.
+ * Flag: Indicates that the orientation of this display device is coupled to the
+ * rotation of its associated logical display.
+ * <p>
+ * This flag should be applied to the default display to indicate that the user
+ * physically rotates the display when content is presented in a different orientation.
+ * The display manager will apply a coordinate transformation assuming that the
+ * physical orientation of the display matches the logical orientation of its content.
+ * </p><p>
+ * The flag should not be set when the display device is mounted in a fixed orientation
+ * such as on a desk. The display manager will apply a coordinate transformation
+ * such as a scale and translation to letterbox or pillarbox format under the
+ * assumption that the physical orientation of the display is invariant.
+ * </p>
*/
- public static final int FLAG_SUPPORTS_ROTATION = 1 << 1;
+ public static final int FLAG_ROTATES_WITH_CONTENT = 1 << 1;
/**
* Flag: Indicates that this display device has secure video output, such as HDCP.
@@ -116,6 +127,17 @@
*/
public int touch;
+ /**
+ * The additional rotation to apply to all content presented on the display device
+ * relative to its physical coordinate system. Default is {@link Surface#ROTATION_0}.
+ * <p>
+ * This field can be used to compensate for the fact that the display has been
+ * physically rotated relative to its natural orientation such as an HDMI monitor
+ * that has been mounted sideways to appear to be portrait rather than landscape.
+ * </p>
+ */
+ public int rotation = Surface.ROTATION_0;
+
public void setAssumedDensityForExternalDisplay(int width, int height) {
densityDpi = Math.min(width, height) * DisplayMetrics.DENSITY_XHIGH / 1080;
// Technically, these values should be smaller than the apparent density
@@ -139,7 +161,8 @@
&& xDpi == other.xDpi
&& yDpi == other.yDpi
&& flags == other.flags
- && touch == other.touch;
+ && touch == other.touch
+ && rotation == other.rotation;
}
@Override
@@ -157,14 +180,18 @@
yDpi = other.yDpi;
flags = other.flags;
touch = other.touch;
+ rotation = other.rotation;
}
// For debugging purposes
@Override
public String toString() {
- return "DisplayDeviceInfo{\"" + name + "\": " + width + " x " + height + ", " + refreshRate + " fps, "
+ return "DisplayDeviceInfo{\"" + name + "\": " + width + " x " + height + ", "
+ + refreshRate + " fps, "
+ "density " + densityDpi + ", " + xDpi + " x " + yDpi + " dpi"
- + ", touch " + touchToString(touch) + flagsToString(flags) + "}";
+ + ", touch " + touchToString(touch) + flagsToString(flags)
+ + ", rotation " + rotation
+ + "}";
}
private static String touchToString(int touch) {
@@ -185,8 +212,8 @@
if ((flags & FLAG_DEFAULT_DISPLAY) != 0) {
msg.append(", FLAG_DEFAULT_DISPLAY");
}
- if ((flags & FLAG_SUPPORTS_ROTATION) != 0) {
- msg.append(", FLAG_SUPPORTS_ROTATION");
+ if ((flags & FLAG_ROTATES_WITH_CONTENT) != 0) {
+ msg.append(", FLAG_ROTATES_WITH_CONTENT");
}
if ((flags & FLAG_SECURE) != 0) {
msg.append(", FLAG_SECURE");
diff --git a/services/java/com/android/server/display/DisplayManagerService.java b/services/java/com/android/server/display/DisplayManagerService.java
index 0a42528..e58a0a5 100644
--- a/services/java/com/android/server/display/DisplayManagerService.java
+++ b/services/java/com/android/server/display/DisplayManagerService.java
@@ -127,6 +127,13 @@
// services should be started. This option may disable certain display adapters.
public boolean mOnlyCore;
+ // True if the display manager service should pretend there is only one display
+ // and only tell applications about the existence of the default logical display.
+ // The display manager can still mirror content to secondary displays but applications
+ // cannot present unique content on those displays.
+ // Used for demonstration purposes only.
+ private final boolean mSingleDisplayDemoMode;
+
// All callback records indexed by calling process id.
public final SparseArray<CallbackRecord> mCallbacks =
new SparseArray<CallbackRecord>();
@@ -182,6 +189,7 @@
mHandler = new DisplayManagerHandler(mainHandler.getLooper());
mUiHandler = uiHandler;
mDisplayAdapterListener = new DisplayAdapterListener();
+ mSingleDisplayDemoMode = SystemProperties.getBoolean("persist.demo.singledisplay", false);
mHandler.sendEmptyMessage(MSG_REGISTER_DEFAULT_DISPLAY_ADAPTER);
}
@@ -305,6 +313,8 @@
DisplayDevice device = mDisplayDevices.get(i);
device.blankLocked();
}
+
+ scheduleTraversalLocked(false);
}
}
}
@@ -322,6 +332,8 @@
DisplayDevice device = mDisplayDevices.get(i);
device.unblankLocked();
}
+
+ scheduleTraversalLocked(false);
}
}
}
@@ -627,6 +639,12 @@
isDefault = false;
}
+ if (!isDefault && mSingleDisplayDemoMode) {
+ Slog.i(TAG, "Not creating a logical display for a secondary display "
+ + " because single display demo mode is enabled: " + deviceInfo);
+ return;
+ }
+
final int displayId = assignDisplayIdLocked(isDefault);
final int layerStack = assignLayerStackLocked(displayId);
@@ -755,7 +773,9 @@
+ device.getDisplayDeviceInfoLocked());
return;
} else {
- display.configureDisplayInTransactionLocked(device);
+ boolean isBlanked = (mAllDisplayBlankStateFromPowerManager
+ == DISPLAY_BLANK_STATE_BLANKED);
+ display.configureDisplayInTransactionLocked(device, isBlanked);
}
// Update the viewports if needed.
@@ -851,6 +871,7 @@
pw.println(" mNextNonDefaultDisplayId=" + mNextNonDefaultDisplayId);
pw.println(" mDefaultViewport=" + mDefaultViewport);
pw.println(" mExternalTouchViewport=" + mExternalTouchViewport);
+ pw.println(" mSingleDisplayDemoMode=" + mSingleDisplayDemoMode);
IndentingPrintWriter ipw = new IndentingPrintWriter(pw, " ");
ipw.increaseIndent();
diff --git a/services/java/com/android/server/display/LocalDisplayAdapter.java b/services/java/com/android/server/display/LocalDisplayAdapter.java
index d780006..fe38d7f 100644
--- a/services/java/com/android/server/display/LocalDisplayAdapter.java
+++ b/services/java/com/android/server/display/LocalDisplayAdapter.java
@@ -20,6 +20,7 @@
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
+import android.os.SystemProperties;
import android.util.SparseArray;
import android.view.DisplayEventReceiver;
import android.view.Surface;
@@ -135,7 +136,7 @@
mInfo.name = getContext().getResources().getString(
com.android.internal.R.string.display_manager_built_in_display_name);
mInfo.flags |= DisplayDeviceInfo.FLAG_DEFAULT_DISPLAY
- | DisplayDeviceInfo.FLAG_SUPPORTS_ROTATION;
+ | DisplayDeviceInfo.FLAG_ROTATES_WITH_CONTENT;
mInfo.densityDpi = (int)(mPhys.density * 160 + 0.5f);
mInfo.xDpi = mPhys.xDpi;
mInfo.yDpi = mPhys.yDpi;
@@ -145,6 +146,12 @@
com.android.internal.R.string.display_manager_hdmi_display_name);
mInfo.touch = DisplayDeviceInfo.TOUCH_EXTERNAL;
mInfo.setAssumedDensityForExternalDisplay(mPhys.width, mPhys.height);
+
+ // For demonstration purposes, allow rotation of the external display.
+ // In the future we might allow the user to configure this directly.
+ if ("portrait".equals(SystemProperties.get("persist.demo.hdmirotation"))) {
+ mInfo.rotation = Surface.ROTATION_270;
+ }
}
}
return mInfo;
diff --git a/services/java/com/android/server/display/LogicalDisplay.java b/services/java/com/android/server/display/LogicalDisplay.java
index c4b749c..aa7ea82 100644
--- a/services/java/com/android/server/display/LogicalDisplay.java
+++ b/services/java/com/android/server/display/LogicalDisplay.java
@@ -55,6 +55,10 @@
final class LogicalDisplay {
private final DisplayInfo mBaseDisplayInfo = new DisplayInfo();
+ // The layer stack we use when the display has been blanked to prevent any
+ // of its content from appearing.
+ private static final int BLANK_LAYER_STACK = -1;
+
private final int mDisplayId;
private final int mLayerStack;
private DisplayInfo mOverrideDisplayInfo; // set by the window manager
@@ -217,13 +221,15 @@
* where the display is being mirrored.
*
* @param device The display device to modify.
+ * @param isBlanked True if the device is being blanked.
*/
- public void configureDisplayInTransactionLocked(DisplayDevice device) {
+ public void configureDisplayInTransactionLocked(DisplayDevice device,
+ boolean isBlanked) {
final DisplayInfo displayInfo = getDisplayInfoLocked();
final DisplayDeviceInfo displayDeviceInfo = device.getDisplayDeviceInfoLocked();
// Set the layer stack.
- device.setLayerStackInTransactionLocked(mLayerStack);
+ device.setLayerStackInTransactionLocked(isBlanked ? BLANK_LAYER_STACK : mLayerStack);
// Set the viewport.
// This is the area of the logical display that we intend to show on the
@@ -235,10 +241,13 @@
// is rotated when the contents of the logical display are rendered.
int orientation = Surface.ROTATION_0;
if (device == mPrimaryDisplayDevice
- && (displayDeviceInfo.flags & DisplayDeviceInfo.FLAG_SUPPORTS_ROTATION) != 0) {
+ && (displayDeviceInfo.flags & DisplayDeviceInfo.FLAG_ROTATES_WITH_CONTENT) != 0) {
orientation = displayInfo.rotation;
}
+ // Apply the physical rotation of the display device itself.
+ orientation = (orientation + displayDeviceInfo.rotation) % 4;
+
// Set the frame.
// The frame specifies the rotated physical coordinates into which the viewport
// is mapped. We need to take care to preserve the aspect ratio of the viewport.
diff --git a/services/java/com/android/server/display/WifiDisplayAdapter.java b/services/java/com/android/server/display/WifiDisplayAdapter.java
index 3e541dd..66eac88 100644
--- a/services/java/com/android/server/display/WifiDisplayAdapter.java
+++ b/services/java/com/android/server/display/WifiDisplayAdapter.java
@@ -16,17 +16,28 @@
package com.android.server.display;
+import com.android.internal.R;
import com.android.internal.util.DumpUtils;
import com.android.internal.util.IndentingPrintWriter;
+import android.app.Notification;
+import android.app.NotificationManager;
+import android.app.PendingIntent;
+import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.res.Resources;
import android.hardware.display.DisplayManager;
import android.hardware.display.WifiDisplay;
import android.hardware.display.WifiDisplayStatus;
import android.media.RemoteDisplay;
import android.os.Handler;
import android.os.IBinder;
+import android.os.Looper;
+import android.os.Message;
+import android.os.UserHandle;
+import android.provider.Settings;
import android.util.Slog;
import android.view.Surface;
@@ -52,8 +63,18 @@
private static final boolean DEBUG = false;
+ private static final int MSG_SEND_STATUS_CHANGE_BROADCAST = 1;
+ private static final int MSG_UPDATE_NOTIFICATION = 2;
+
+ private static final String ACTION_DISCONNECT = "android.server.display.wfd.DISCONNECT";
+
+ private final WifiDisplayHandler mHandler;
private final PersistentDataStore mPersistentDataStore;
private final boolean mSupportsProtectedBuffers;
+ private final NotificationManager mNotificationManager;
+
+ private final PendingIntent mSettingsPendingIntent;
+ private final PendingIntent mDisconnectPendingIntent;
private WifiDisplayController mDisplayController;
private WifiDisplayDevice mDisplayDevice;
@@ -67,14 +88,32 @@
private WifiDisplay[] mRememberedDisplays = WifiDisplay.EMPTY_ARRAY;
private boolean mPendingStatusChangeBroadcast;
+ private boolean mPendingNotificationUpdate;
public WifiDisplayAdapter(DisplayManagerService.SyncRoot syncRoot,
Context context, Handler handler, Listener listener,
PersistentDataStore persistentDataStore) {
super(syncRoot, context, handler, listener, TAG);
+ mHandler = new WifiDisplayHandler(handler.getLooper());
mPersistentDataStore = persistentDataStore;
mSupportsProtectedBuffers = context.getResources().getBoolean(
com.android.internal.R.bool.config_wifiDisplaySupportsProtectedBuffers);
+ mNotificationManager = (NotificationManager)context.getSystemService(
+ Context.NOTIFICATION_SERVICE);
+
+ Intent settingsIntent = new Intent(Settings.ACTION_WIFI_DISPLAY_SETTINGS);
+ settingsIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
+ | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED
+ | Intent.FLAG_ACTIVITY_CLEAR_TOP);
+ mSettingsPendingIntent = PendingIntent.getActivityAsUser(
+ context, 0, settingsIntent, 0, null, UserHandle.CURRENT);
+
+ Intent disconnectIntent = new Intent(ACTION_DISCONNECT);
+ mDisconnectPendingIntent = PendingIntent.getBroadcastAsUser(
+ context, 0, disconnectIntent, 0, UserHandle.CURRENT);
+
+ context.registerReceiverAsUser(mBroadcastReceiver, UserHandle.ALL,
+ new IntentFilter(ACTION_DISCONNECT), null, mHandler);
}
@Override
@@ -89,6 +128,7 @@
pw.println("mAvailableDisplays=" + Arrays.toString(mAvailableDisplays));
pw.println("mRememberedDisplays=" + Arrays.toString(mRememberedDisplays));
pw.println("mPendingStatusChangeBroadcast=" + mPendingStatusChangeBroadcast);
+ pw.println("mPendingNotificationUpdate=" + mPendingNotificationUpdate);
pw.println("mSupportsProtectedBuffers=" + mSupportsProtectedBuffers);
// Try to dump the controller state.
@@ -198,6 +238,12 @@
updateRememberedDisplaysLocked();
scheduleStatusChangedBroadcastLocked();
}
+
+ if (mActiveDisplay != null && mActiveDisplay.getDeviceAddress().equals(address)
+ && mDisplayDevice != null) {
+ mDisplayDevice.setNameLocked(mActiveDisplay.getFriendlyDisplayName());
+ sendDisplayDeviceEventLocked(mDisplayDevice, DISPLAY_DEVICE_EVENT_CHANGED);
+ }
}
public void requestForgetLocked(String address) {
@@ -260,6 +306,8 @@
mDisplayDevice = new WifiDisplayDevice(displayToken, name, width, height,
refreshRate, deviceFlags, surface);
sendDisplayDeviceEventLocked(mDisplayDevice, DISPLAY_DEVICE_EVENT_ADDED);
+
+ scheduleUpdateNotificationLocked();
}
private void handleDisconnectLocked() {
@@ -267,6 +315,8 @@
mDisplayDevice.clearSurfaceLocked();
sendDisplayDeviceEventLocked(mDisplayDevice, DISPLAY_DEVICE_EVENT_REMOVED);
mDisplayDevice = null;
+
+ scheduleUpdateNotificationLocked();
}
}
@@ -274,28 +324,81 @@
mCurrentStatus = null;
if (!mPendingStatusChangeBroadcast) {
mPendingStatusChangeBroadcast = true;
- getHandler().post(mStatusChangeBroadcast);
+ mHandler.sendEmptyMessage(MSG_SEND_STATUS_CHANGE_BROADCAST);
}
}
- private final Runnable mStatusChangeBroadcast = new Runnable() {
- @Override
- public void run() {
- final Intent intent;
- synchronized (getSyncRoot()) {
- if (!mPendingStatusChangeBroadcast) {
- return;
- }
+ private void scheduleUpdateNotificationLocked() {
+ if (!mPendingNotificationUpdate) {
+ mPendingNotificationUpdate = true;
+ mHandler.sendEmptyMessage(MSG_UPDATE_NOTIFICATION);
+ }
+ }
- mPendingStatusChangeBroadcast = false;
- intent = new Intent(DisplayManager.ACTION_WIFI_DISPLAY_STATUS_CHANGED);
- intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
- intent.putExtra(DisplayManager.EXTRA_WIFI_DISPLAY_STATUS,
- getWifiDisplayStatusLocked());
+ // Runs on the handler.
+ private void handleSendStatusChangeBroadcast() {
+ final Intent intent;
+ synchronized (getSyncRoot()) {
+ if (!mPendingStatusChangeBroadcast) {
+ return;
}
- // Send protected broadcast about wifi display status to registered receivers.
- getContext().sendBroadcast(intent);
+ mPendingStatusChangeBroadcast = false;
+ intent = new Intent(DisplayManager.ACTION_WIFI_DISPLAY_STATUS_CHANGED);
+ intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
+ intent.putExtra(DisplayManager.EXTRA_WIFI_DISPLAY_STATUS,
+ getWifiDisplayStatusLocked());
+ }
+
+ // Send protected broadcast about wifi display status to registered receivers.
+ getContext().sendBroadcastAsUser(intent, UserHandle.ALL);
+ }
+
+ // Runs on the handler.
+ private void handleUpdateNotification() {
+ final boolean isConnected;
+ synchronized (getSyncRoot()) {
+ if (!mPendingNotificationUpdate) {
+ return;
+ }
+
+ mPendingNotificationUpdate = false;
+ isConnected = (mDisplayDevice != null);
+ }
+
+ mNotificationManager.cancelAsUser(null,
+ R.string.wifi_display_notification_title, UserHandle.ALL);
+
+ if (isConnected) {
+ Context context = getContext();
+
+ Resources r = context.getResources();
+ Notification notification = new Notification.Builder(context)
+ .setContentTitle(r.getString(
+ R.string.wifi_display_notification_title))
+ .setContentText(r.getString(
+ R.string.wifi_display_notification_message))
+ .setContentIntent(mSettingsPendingIntent)
+ .setSmallIcon(R.drawable.ic_notify_wifidisplay)
+ .setOngoing(true)
+ .addAction(android.R.drawable.ic_menu_close_clear_cancel,
+ r.getString(R.string.wifi_display_notification_disconnect),
+ mDisconnectPendingIntent)
+ .build();
+ mNotificationManager.notifyAsUser(null,
+ R.string.wifi_display_notification_title,
+ notification, UserHandle.ALL);
+ }
+ }
+
+ private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ if (intent.getAction().equals(ACTION_DISCONNECT)) {
+ synchronized (getSyncRoot()) {
+ requestDisconnectLocked();
+ }
+ }
}
};
@@ -397,7 +500,7 @@
};
private final class WifiDisplayDevice extends DisplayDevice {
- private final String mName;
+ private String mName;
private final int mWidth;
private final int mHeight;
private final float mRefreshRate;
@@ -423,6 +526,11 @@
sendTraversalRequestLocked();
}
+ public void setNameLocked(String name) {
+ mName = name;
+ mInfo = null;
+ }
+
@Override
public void performTraversalInTransactionLocked() {
setSurfaceInTransactionLocked(mSurface);
@@ -443,4 +551,23 @@
return mInfo;
}
}
+
+ private final class WifiDisplayHandler extends Handler {
+ public WifiDisplayHandler(Looper looper) {
+ super(looper, null, true /*async*/);
+ }
+
+ @Override
+ public void handleMessage(Message msg) {
+ switch (msg.what) {
+ case MSG_SEND_STATUS_CHANGE_BROADCAST:
+ handleSendStatusChangeBroadcast();
+ break;
+
+ case MSG_UPDATE_NOTIFICATION:
+ handleUpdateNotification();
+ break;
+ }
+ }
+ }
}
diff --git a/services/java/com/android/server/pm/UserManagerService.java b/services/java/com/android/server/pm/UserManagerService.java
index 4f9375a..77e6c03 100644
--- a/services/java/com/android/server/pm/UserManagerService.java
+++ b/services/java/com/android/server/pm/UserManagerService.java
@@ -149,7 +149,7 @@
-1, -1);
mUserListFile = new File(mUsersDir, USER_LIST_FILENAME);
readUserListLocked();
- // Prune out any partially created users.
+ // Prune out any partially created/partially removed users.
ArrayList<UserInfo> partials = new ArrayList<UserInfo>();
for (int i = 0; i < mUsers.size(); i++) {
UserInfo ui = mUsers.valueAt(i);
@@ -459,7 +459,7 @@
private void fallbackToSingleUserLocked() {
// Create the primary user
UserInfo primary = new UserInfo(0, "Primary", null,
- UserInfo.FLAG_ADMIN | UserInfo.FLAG_PRIMARY);
+ UserInfo.FLAG_ADMIN | UserInfo.FLAG_PRIMARY | UserInfo.FLAG_INITIALIZED);
mUsers.put(0, primary);
mNextSerialNumber = MIN_USER_ID;
updateUserIdsLocked();
@@ -703,6 +703,11 @@
return false;
}
mRemovingUserIds.add(userHandle);
+ // Set this to a partially created user, so that the user will be purged
+ // on next startup, in case the runtime stops now before stopping and
+ // removing the user completely.
+ user.partial = true;
+ writeUserLocked(user);
}
int res;
diff --git a/services/java/com/android/server/power/PowerManagerService.java b/services/java/com/android/server/power/PowerManagerService.java
index b76ad45..b94bceb 100644
--- a/services/java/com/android/server/power/PowerManagerService.java
+++ b/services/java/com/android/server/power/PowerManagerService.java
@@ -107,6 +107,8 @@
private static final int DIRTY_PROXIMITY_POSITIVE = 1 << 9;
// Dirty bit: screen on blocker state became held or unheld
private static final int DIRTY_SCREEN_ON_BLOCKER_RELEASED = 1 << 10;
+ // Dirty bit: dock state changed
+ private static final int DIRTY_DOCK_STATE = 1 << 11;
// Wakefulness: The device is asleep and can only be awoken by a call to wakeUp().
// The screen should be off or in the process of being turned off by the display controller.
@@ -162,6 +164,11 @@
// Poll interval in milliseconds for watching boot animation finished.
private static final int BOOT_ANIMATION_POLL_INTERVAL = 200;
+ // If the battery level drops by this percentage and the user activity timeout
+ // has expired, then assume the device is receiving insufficient current to charge
+ // effectively and terminate the dream.
+ private static final int DREAM_BATTERY_LEVEL_DRAIN_CUTOFF = 5;
+
private Context mContext;
private LightsService mLightsService;
private BatteryService mBatteryService;
@@ -256,6 +263,17 @@
// The current plug type, such as BatteryManager.BATTERY_PLUGGED_WIRELESS.
private int mPlugType;
+ // The current battery level percentage.
+ private int mBatteryLevel;
+
+ // The battery level percentage at the time the dream started.
+ // This is used to terminate a dream and go to sleep if the battery is
+ // draining faster than it is charging and the user activity timeout has expired.
+ private int mBatteryLevelWhenDreamStarted;
+
+ // The current dock state.
+ private int mDockState = Intent.EXTRA_DOCK_STATE_UNDOCKED;
+
// True if the device should wake up when plugged or unplugged.
private boolean mWakeUpWhenPluggedOrUnpluggedConfig;
@@ -268,6 +286,9 @@
// True if dreams should be activated on sleep.
private boolean mDreamsActivateOnSleepSetting;
+ // True if dreams should be activated on dock.
+ private boolean mDreamsActivateOnDockSetting;
+
// The screen off timeout setting value in milliseconds.
private int mScreenOffTimeoutSetting;
@@ -427,6 +448,10 @@
filter.addAction(Intent.ACTION_USER_SWITCHED);
mContext.registerReceiver(new UserSwitchedReceiver(), filter, null, mHandler);
+ filter = new IntentFilter();
+ filter.addAction(Intent.ACTION_DOCK_EVENT);
+ mContext.registerReceiver(new DockReceiver(), filter, null, mHandler);
+
// Register for settings changes.
final ContentResolver resolver = mContext.getContentResolver();
resolver.registerContentObserver(Settings.Secure.getUriFor(
@@ -435,6 +460,9 @@
resolver.registerContentObserver(Settings.Secure.getUriFor(
Settings.Secure.SCREENSAVER_ACTIVATE_ON_SLEEP),
false, mSettingsObserver, UserHandle.USER_ALL);
+ resolver.registerContentObserver(Settings.Secure.getUriFor(
+ Settings.Secure.SCREENSAVER_ACTIVATE_ON_DOCK),
+ false, mSettingsObserver, UserHandle.USER_ALL);
resolver.registerContentObserver(Settings.System.getUriFor(
Settings.System.SCREEN_OFF_TIMEOUT),
false, mSettingsObserver, UserHandle.USER_ALL);
@@ -474,6 +502,9 @@
mDreamsActivateOnSleepSetting = (Settings.Secure.getIntForUser(resolver,
Settings.Secure.SCREENSAVER_ACTIVATE_ON_SLEEP, 0,
UserHandle.USER_CURRENT) != 0);
+ mDreamsActivateOnDockSetting = (Settings.Secure.getIntForUser(resolver,
+ Settings.Secure.SCREENSAVER_ACTIVATE_ON_DOCK, 0,
+ UserHandle.USER_CURRENT) != 0);
mScreenOffTimeoutSetting = Settings.System.getIntForUser(resolver,
Settings.System.SCREEN_OFF_TIMEOUT, DEFAULT_SCREEN_OFF_TIMEOUT,
UserHandle.USER_CURRENT);
@@ -1067,12 +1098,14 @@
final int oldPlugType = mPlugType;
mIsPowered = mBatteryService.isPowered(BatteryManager.BATTERY_PLUGGED_ANY);
mPlugType = mBatteryService.getPlugType();
+ mBatteryLevel = mBatteryService.getBatteryLevel();
if (DEBUG) {
Slog.d(TAG, "updateIsPoweredLocked: wasPowered=" + wasPowered
+ ", mIsPowered=" + mIsPowered
+ ", oldPlugType=" + oldPlugType
- + ", mPlugType=" + mPlugType);
+ + ", mPlugType=" + mPlugType
+ + ", mBatteryLevel=" + mBatteryLevel);
}
if (wasPowered != mIsPowered || oldPlugType != mPlugType) {
@@ -1126,8 +1159,7 @@
}
if (!wasPowered && mIsPowered
&& mPlugType == BatteryManager.BATTERY_PLUGGED_WIRELESS
- && mBatteryService.getBatteryLevel() >=
- WIRELESS_CHARGER_TURN_ON_BATTERY_LEVEL_LIMIT) {
+ && mBatteryLevel >= WIRELESS_CHARGER_TURN_ON_BATTERY_LEVEL_LIMIT) {
return false;
}
@@ -1325,13 +1357,14 @@
private boolean updateWakefulnessLocked(int dirty) {
boolean changed = false;
if ((dirty & (DIRTY_WAKE_LOCKS | DIRTY_USER_ACTIVITY | DIRTY_BOOT_COMPLETED
- | DIRTY_WAKEFULNESS | DIRTY_STAY_ON | DIRTY_PROXIMITY_POSITIVE)) != 0) {
+ | DIRTY_WAKEFULNESS | DIRTY_STAY_ON | DIRTY_PROXIMITY_POSITIVE
+ | DIRTY_DOCK_STATE)) != 0) {
if (mWakefulness == WAKEFULNESS_AWAKE && isItBedTimeYetLocked()) {
if (DEBUG_SPEW) {
Slog.d(TAG, "updateWakefulnessLocked: Bed time...");
}
final long time = SystemClock.uptimeMillis();
- if (mDreamsActivateOnSleepSetting) {
+ if (shouldNapAtBedTimeLocked()) {
changed = napNoUpdateLocked(time);
} else {
changed = goToSleepNoUpdateLocked(time,
@@ -1343,6 +1376,16 @@
}
/**
+ * Returns true if the device should automatically nap and start dreaming when the user
+ * activity timeout has expired and it's bedtime.
+ */
+ private boolean shouldNapAtBedTimeLocked() {
+ return mDreamsActivateOnSleepSetting
+ || (mDreamsActivateOnDockSetting
+ && mDockState != Intent.EXTRA_DOCK_STATE_UNDOCKED);
+ }
+
+ /**
* Returns true if the device should go to sleep now.
* Also used when exiting a dream to determine whether we should go back
* to being fully awake or else go to sleep for good.
@@ -1403,7 +1446,7 @@
mSandmanScheduled = false;
boolean canDream = canDreamLocked();
if (DEBUG_SPEW) {
- Log.d(TAG, "handleSandman: canDream=" + canDream
+ Slog.d(TAG, "handleSandman: canDream=" + canDream
+ ", mWakefulness=" + wakefulnessToString(mWakefulness));
}
@@ -1431,10 +1474,24 @@
if (mWakefulness == WAKEFULNESS_NAPPING) {
mWakefulness = WAKEFULNESS_DREAMING;
mDirty |= DIRTY_WAKEFULNESS;
+ mBatteryLevelWhenDreamStarted = mBatteryLevel;
updatePowerStateLocked();
continueDreaming = true;
} else if (mWakefulness == WAKEFULNESS_DREAMING) {
- continueDreaming = true;
+ if (!isBeingKeptAwakeLocked()
+ && mBatteryLevel < mBatteryLevelWhenDreamStarted
+ - DREAM_BATTERY_LEVEL_DRAIN_CUTOFF) {
+ // If the user activity timeout expired and the battery appears
+ // to be draining faster than it is charging then stop dreaming
+ // and go to sleep.
+ Slog.i(TAG, "Stopping dream because the battery appears to "
+ + "be draining faster than it is charging. "
+ + "Battery level when dream started: "
+ + mBatteryLevelWhenDreamStarted + "%. "
+ + "Battery level now: " + mBatteryLevel + "%.");
+ } else {
+ continueDreaming = true;
+ }
}
}
if (!continueDreaming) {
@@ -1704,8 +1761,11 @@
}
/**
- * Reboot the device, passing 'reason' (may be null)
- * to the underlying __reboot system call. Should not return.
+ * Reboots the device.
+ *
+ * @param confirm If true, shows a reboot confirmation dialog.
+ * @param reason The reason for the reboot, or null if none.
+ * @param wait If true, this call waits for the reboot to complete and does not return.
*/
@Override // Binder call
public void reboot(boolean confirm, String reason, boolean wait) {
@@ -1713,15 +1773,17 @@
final long ident = Binder.clearCallingIdentity();
try {
- rebootInternal(false, confirm, reason, wait);
+ shutdownOrRebootInternal(false, confirm, reason, wait);
} finally {
Binder.restoreCallingIdentity(ident);
}
}
/**
- * Shutdown the devic, passing 'reason' (may be null)
- * to the underlying __reboot system call. Should not return.
+ * Shuts down the device.
+ *
+ * @param confirm If true, shows a shutdown confirmation dialog.
+ * @param wait If true, this call waits for the shutdown to complete and does not return.
*/
@Override // Binder call
public void shutdown(boolean confirm, boolean wait) {
@@ -1729,19 +1791,20 @@
final long ident = Binder.clearCallingIdentity();
try {
- rebootInternal(true, confirm, null, wait);
+ shutdownOrRebootInternal(true, confirm, null, wait);
} finally {
Binder.restoreCallingIdentity(ident);
}
}
- private void rebootInternal(final boolean shutdown, final boolean confirm,
+ private void shutdownOrRebootInternal(final boolean shutdown, final boolean confirm,
final String reason, boolean wait) {
if (mHandler == null || !mSystemReady) {
- throw new IllegalStateException("Too early to call reboot()");
+ throw new IllegalStateException("Too early to call shutdown() or reboot()");
}
Runnable runnable = new Runnable() {
+ @Override
public void run() {
synchronized (this) {
if (shutdown) {
@@ -1789,6 +1852,7 @@
private void crashInternal(final String message) {
Thread t = new Thread("PowerManagerService.crash()") {
+ @Override
public void run() {
throw new RuntimeException(message);
}
@@ -2087,6 +2151,9 @@
pw.println(" mWakefulness=" + wakefulnessToString(mWakefulness));
pw.println(" mIsPowered=" + mIsPowered);
pw.println(" mPlugType=" + mPlugType);
+ pw.println(" mBatteryLevel=" + mBatteryLevel);
+ pw.println(" mBatteryLevelWhenDreamStarted=" + mBatteryLevelWhenDreamStarted);
+ pw.println(" mDockState=" + mDockState);
pw.println(" mStayOn=" + mStayOn);
pw.println(" mProximityPositive=" + mProximityPositive);
pw.println(" mBootCompleted=" + mBootCompleted);
@@ -2112,6 +2179,7 @@
pw.println(" mDreamsSupportedConfig=" + mDreamsSupportedConfig);
pw.println(" mDreamsEnabledSetting=" + mDreamsEnabledSetting);
pw.println(" mDreamsActivateOnSleepSetting=" + mDreamsActivateOnSleepSetting);
+ pw.println(" mDreamsActivateOnDockSetting=" + mDreamsActivateOnDockSetting);
pw.println(" mScreenOffTimeoutSetting=" + mScreenOffTimeoutSetting);
pw.println(" mMaximumScreenOffTimeoutFromDeviceAdmin="
+ mMaximumScreenOffTimeoutFromDeviceAdmin + " (enforced="
@@ -2230,6 +2298,21 @@
}
}
+ private final class DockReceiver extends BroadcastReceiver {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ synchronized (mLock) {
+ int dockState = intent.getIntExtra(Intent.EXTRA_DOCK_STATE,
+ Intent.EXTRA_DOCK_STATE_UNDOCKED);
+ if (mDockState != dockState) {
+ mDockState = dockState;
+ mDirty |= DIRTY_DOCK_STATE;
+ updatePowerStateLocked();
+ }
+ }
+ }
+ }
+
private final class SettingsObserver extends ContentObserver {
public SettingsObserver(Handler handler) {
super(handler);
diff --git a/services/java/com/android/server/wm/WindowAnimator.java b/services/java/com/android/server/wm/WindowAnimator.java
index b67fb51..269eac0 100644
--- a/services/java/com/android/server/wm/WindowAnimator.java
+++ b/services/java/com/android/server/wm/WindowAnimator.java
@@ -618,6 +618,7 @@
if (WindowManagerService.SHOW_TRANSACTIONS) Slog.i(
TAG, ">>> OPEN TRANSACTION animateLocked");
Surface.openTransaction();
+ Surface.setAnimationTransaction();
try {
updateAppWindowsLocked();
diff --git a/services/java/com/android/server/wm/WindowManagerService.java b/services/java/com/android/server/wm/WindowManagerService.java
index 77d815b..fa450ae 100755
--- a/services/java/com/android/server/wm/WindowManagerService.java
+++ b/services/java/com/android/server/wm/WindowManagerService.java
@@ -265,7 +265,7 @@
static final int DEFAULT_FADE_IN_OUT_DURATION = 400;
/** Amount of time (in milliseconds) to delay before declaring a window freeze timeout. */
- static final int WINDOW_FREEZE_TIMEOUT_DURATION = 3000;
+ static final int WINDOW_FREEZE_TIMEOUT_DURATION = 2000;
/**
* If true, the window manager will do its own custom freezing and general
@@ -2823,16 +2823,9 @@
"Relayout window turning screen on: " + win);
win.mTurnOnScreen = true;
}
- int diff = 0;
- if (win.mConfiguration != mCurConfiguration
- && (win.mConfiguration == null
- || (diff=mCurConfiguration.diff(win.mConfiguration)) != 0)) {
- win.mConfiguration = mCurConfiguration;
- if (DEBUG_CONFIGURATION) {
- Slog.i(TAG, "Window " + win + " visible with new config: "
- + win.mConfiguration + " / 0x"
- + Integer.toHexString(diff));
- }
+ if (win.isConfigChanged()) {
+ if (DEBUG_CONFIGURATION) Slog.i(TAG, "Window " + win
+ + " visible with new config: " + win.mConfiguration);
outConfig.setTo(mCurConfiguration);
}
}
@@ -6576,6 +6569,36 @@
}
}
+ private void scheduleNotifyWindowLayersChangedIfNeededLocked(DisplayContent displayContent) {
+ if (displayContent.mDisplayContentChangeListeners != null
+ && displayContent.mDisplayContentChangeListeners.getRegisteredCallbackCount() > 0) {
+ mH.obtainMessage(H.NOTIFY_WINDOW_LAYERS_CHANGED, displayContent) .sendToTarget();
+ }
+ }
+
+ private void handleNotifyWindowLayersChanged(DisplayContent displayContent) {
+ RemoteCallbackList<IDisplayContentChangeListener> callbacks = null;
+ synchronized (mWindowMap) {
+ callbacks = displayContent.mDisplayContentChangeListeners;
+ if (callbacks == null) {
+ return;
+ }
+ }
+ try {
+ final int watcherCount = callbacks.beginBroadcast();
+ for (int i = 0; i < watcherCount; i++) {
+ try {
+ callbacks.getBroadcastItem(i).onWindowLayersChanged(
+ displayContent.getDisplayId());
+ } catch (RemoteException re) {
+ /* ignore */
+ }
+ }
+ } finally {
+ callbacks.finishBroadcast();
+ }
+ }
+
public void addWindowChangeListener(WindowChangeListener listener) {
synchronized(mWindowMap) {
mWindowChangeListeners.add(listener);
@@ -7222,12 +7245,13 @@
public static final int NOTIFY_ROTATION_CHANGED = 28;
public static final int NOTIFY_WINDOW_TRANSITION = 29;
public static final int NOTIFY_RECTANGLE_ON_SCREEN_REQUESTED = 30;
+ public static final int NOTIFY_WINDOW_LAYERS_CHANGED = 31;
- public static final int DO_DISPLAY_ADDED = 31;
- public static final int DO_DISPLAY_REMOVED = 32;
- public static final int DO_DISPLAY_CHANGED = 33;
+ public static final int DO_DISPLAY_ADDED = 32;
+ public static final int DO_DISPLAY_REMOVED = 33;
+ public static final int DO_DISPLAY_CHANGED = 34;
- public static final int CLIENT_FREEZE_TIMEOUT = 34;
+ public static final int CLIENT_FREEZE_TIMEOUT = 35;
public static final int ANIMATOR_WHAT_OFFSET = 100000;
public static final int SET_TRANSPARENT_REGION = ANIMATOR_WHAT_OFFSET + 1;
@@ -7699,6 +7723,12 @@
break;
}
+ case NOTIFY_WINDOW_LAYERS_CHANGED: {
+ DisplayContent displayContent = (DisplayContent) msg.obj;
+ handleNotifyWindowLayersChanged(displayContent);
+ break;
+ }
+
case DO_DISPLAY_ADDED:
synchronized (mWindowMap) {
handleDisplayAddedLocked(msg.arg1);
@@ -8075,6 +8105,8 @@
Slog.v(TAG, "Assigning layers", here);
}
+ boolean anyLayerChanged = false;
+
for (i=0; i<N; i++) {
final WindowState w = windows.get(i);
final WindowStateAnimator winAnimator = w.mWinAnimator;
@@ -8090,6 +8122,7 @@
}
if (w.mLayer != oldLayer) {
layerChanged = true;
+ anyLayerChanged = true;
}
oldLayer = winAnimator.mAnimLayer;
if (w.mTargetAppToken != null) {
@@ -8108,6 +8141,7 @@
}
if (winAnimator.mAnimLayer != oldLayer) {
layerChanged = true;
+ anyLayerChanged = true;
}
if (layerChanged && mAnimator.isDimmingLocked(winAnimator)) {
// Force an animation pass just to update the mDimAnimator layer.
@@ -8122,10 +8156,22 @@
//System.out.println(
// "Assigned layer " + curLayer + " to " + w.mClient.asBinder());
}
+
+ if (anyLayerChanged) {
+ scheduleNotifyWindowLayersChangedIfNeededLocked(getDefaultDisplayContentLocked());
+ }
+ }
+
+ private final void performLayoutAndPlaceSurfacesLocked() {
+ do {
+ mTraversalScheduled = false;
+ performLayoutAndPlaceSurfacesLockedLoop();
+ mH.removeMessages(H.DO_TRAVERSAL);
+ } while (mTraversalScheduled);
}
private boolean mInLayout = false;
- private final void performLayoutAndPlaceSurfacesLocked() {
+ private final void performLayoutAndPlaceSurfacesLockedLoop() {
if (mInLayout) {
if (DEBUG) {
throw new RuntimeException("Recursive call!");
@@ -8260,7 +8306,7 @@
Slog.v(TAG, "1ST PASS " + win
+ ": gone=" + gone + " mHaveFrame=" + win.mHaveFrame
+ " mLayoutAttached=" + win.mLayoutAttached
- + " screen changed=" + win.isConfigDiff(ActivityInfo.CONFIG_SCREEN_SIZE));
+ + " screen changed=" + win.isConfigChanged());
final AppWindowToken atoken = win.mAppToken;
if (gone) Slog.v(TAG, " GONE: mViewVisibility="
+ win.mViewVisibility + " mRelayoutCalled="
@@ -8282,7 +8328,7 @@
// windows, since that means "perform layout as normal,
// just don't display").
if (!gone || !win.mHaveFrame || win.mLayoutNeeded
- || win.isConfigDiff(ActivityInfo.CONFIG_SCREEN_SIZE)
+ || win.isConfigChanged()
|| win.mAttrs.type == TYPE_UNIVERSE_BACKGROUND) {
if (!win.mLayoutAttached) {
if (initial) {
diff --git a/services/java/com/android/server/wm/WindowState.java b/services/java/com/android/server/wm/WindowState.java
index feb29b1..c195f45 100644
--- a/services/java/com/android/server/wm/WindowState.java
+++ b/services/java/com/android/server/wm/WindowState.java
@@ -1038,18 +1038,26 @@
}
boolean isHiddenFromUserLocked() {
- // Save some cycles by not calling getDisplayInfo unless it is an application
- // window intended for all users.
- if (mAttrs.type < WindowManager.LayoutParams.FIRST_SYSTEM_WINDOW
- && mAppToken != null && mAppToken.showWhenLocked) {
- final DisplayInfo displayInfo = mDisplayContent.getDisplayInfo();
- if (isFullscreen(displayInfo.appWidth, displayInfo.appHeight)) {
+ // Attached windows are evaluated based on the window that they are attached to.
+ WindowState win = this;
+ while (win.mAttachedWindow != null) {
+ win = win.mAttachedWindow;
+ }
+ if (win.mAttrs.type < WindowManager.LayoutParams.FIRST_SYSTEM_WINDOW
+ && win.mAppToken != null && win.mAppToken.showWhenLocked) {
+ // Save some cycles by not calling getDisplayInfo unless it is an application
+ // window intended for all users.
+ final DisplayInfo displayInfo = win.mDisplayContent.getDisplayInfo();
+ if (win.mFrame.left <= 0 && win.mFrame.top <= 0
+ && win.mFrame.right >= displayInfo.appWidth
+ && win.mFrame.bottom >= displayInfo.appHeight) {
// Is a fullscreen window, like the clock alarm. Show to everyone.
return false;
}
}
- return mShowToOwnerOnly && UserHandle.getUserId(mOwnerUid) != mService.mCurrentUserId;
+ return win.mShowToOwnerOnly
+ && UserHandle.getUserId(win.mOwnerUid) != mService.mCurrentUserId;
}
private static void applyInsets(Region outRegion, Rect frame, Rect inset) {
diff --git a/tests/HwAccelerationTest/AndroidManifest.xml b/tests/HwAccelerationTest/AndroidManifest.xml
index 4cb409d..9118aea 100644
--- a/tests/HwAccelerationTest/AndroidManifest.xml
+++ b/tests/HwAccelerationTest/AndroidManifest.xml
@@ -33,6 +33,15 @@
<meta-data android:name="android.graphics.renderThread" android:value="true" />
<activity
+ android:name="MipMapActivity"
+ android:label="_MipMap">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+
+ <activity
android:name="PathOffsetActivity"
android:label="_PathOffset">
<intent-filter>
diff --git a/tests/HwAccelerationTest/res/drawable-nodpi/very_large_photo.jpg b/tests/HwAccelerationTest/res/drawable-nodpi/very_large_photo.jpg
new file mode 100644
index 0000000..7f047b1
--- /dev/null
+++ b/tests/HwAccelerationTest/res/drawable-nodpi/very_large_photo.jpg
Binary files differ
diff --git a/tests/HwAccelerationTest/src/com/android/test/hwui/BitmapMeshActivity.java b/tests/HwAccelerationTest/src/com/android/test/hwui/BitmapMeshActivity.java
index 8cc2246..854dd69 100644
--- a/tests/HwAccelerationTest/src/com/android/test/hwui/BitmapMeshActivity.java
+++ b/tests/HwAccelerationTest/src/com/android/test/hwui/BitmapMeshActivity.java
@@ -68,9 +68,16 @@
super.onDraw(canvas);
canvas.drawARGB(255, 255, 255, 255);
+
canvas.translate(100, 100);
canvas.drawBitmapMesh(mBitmap1, 3, 3, mVertices, 0, null, 0, null);
+ canvas.save();
+ canvas.translate(0, 400);
+ canvas.clipRect(0.0f, 0.0f, 80.0f, 80.0f);
+ canvas.drawBitmapMesh(mBitmap1, 3, 3, mVertices, 0, null, 0, null);
+ canvas.restore();
+
canvas.translate(400, 0);
canvas.drawBitmapMesh(mBitmap1, 3, 3, mVertices, 0, mColors, 0, null);
}
diff --git a/tests/HwAccelerationTest/src/com/android/test/hwui/MipMapActivity.java b/tests/HwAccelerationTest/src/com/android/test/hwui/MipMapActivity.java
new file mode 100644
index 0000000..1034649
--- /dev/null
+++ b/tests/HwAccelerationTest/src/com/android/test/hwui/MipMapActivity.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.test.hwui;
+
+import android.app.Activity;
+import android.content.Context;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.graphics.PorterDuff;
+import android.graphics.PorterDuffXfermode;
+import android.os.Bundle;
+import android.util.Log;
+import android.view.Gravity;
+import android.view.View;
+import android.view.animation.Animation;
+import android.view.animation.ScaleAnimation;
+import android.widget.FrameLayout;
+
+@SuppressWarnings({"UnusedDeclaration"})
+public class MipMapActivity extends Activity {
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ final BitmapsView view = new BitmapsView(this);
+ setContentView(view);
+ }
+
+ static class BitmapsView extends View {
+ private Paint mBitmapPaint;
+ private final Bitmap mBitmap1;
+ private final Bitmap mBitmap2;
+
+ BitmapsView(Context c) {
+ super(c);
+
+ mBitmap1 = BitmapFactory.decodeResource(c.getResources(), R.drawable.very_large_photo);
+ mBitmap2 = BitmapFactory.decodeResource(c.getResources(), R.drawable.very_large_photo);
+
+ mBitmap1.setHasMipMap(true);
+
+ mBitmapPaint = new Paint();
+ mBitmapPaint.setFilterBitmap(true);
+ }
+
+ @Override
+ protected void onDraw(Canvas canvas) {
+ super.onDraw(canvas);
+
+ canvas.save();
+ canvas.scale(0.3f, 0.3f);
+ canvas.drawBitmap(mBitmap1, 0, 0, mBitmapPaint);
+ canvas.restore();
+
+ canvas.save();
+ canvas.translate(mBitmap1.getWidth() * 0.3f + 96.0f, 0.0f);
+ canvas.scale(0.3f, 0.3f);
+ canvas.drawBitmap(mBitmap2, 0, 0, mBitmapPaint);
+ canvas.restore();
+ }
+ }
+}
diff --git a/tools/layoutlib/bridge/resources/bars/hdpi/ic_sysbar_back.png b/tools/layoutlib/bridge/resources/bars/hdpi/ic_sysbar_back.png
new file mode 100644
index 0000000..84e6bc8
--- /dev/null
+++ b/tools/layoutlib/bridge/resources/bars/hdpi/ic_sysbar_back.png
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/hdpi/ic_sysbar_back_default.png b/tools/layoutlib/bridge/resources/bars/hdpi/ic_sysbar_back_default.png
deleted file mode 100644
index ac5a97b..0000000
--- a/tools/layoutlib/bridge/resources/bars/hdpi/ic_sysbar_back_default.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/hdpi/ic_sysbar_home.png b/tools/layoutlib/bridge/resources/bars/hdpi/ic_sysbar_home.png
new file mode 100644
index 0000000..38e4f45
--- /dev/null
+++ b/tools/layoutlib/bridge/resources/bars/hdpi/ic_sysbar_home.png
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/hdpi/ic_sysbar_home_default.png b/tools/layoutlib/bridge/resources/bars/hdpi/ic_sysbar_home_default.png
deleted file mode 100644
index a90dc9b..0000000
--- a/tools/layoutlib/bridge/resources/bars/hdpi/ic_sysbar_home_default.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/hdpi/ic_sysbar_recent.png b/tools/layoutlib/bridge/resources/bars/hdpi/ic_sysbar_recent.png
new file mode 100644
index 0000000..bf9f300
--- /dev/null
+++ b/tools/layoutlib/bridge/resources/bars/hdpi/ic_sysbar_recent.png
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/hdpi/ic_sysbar_recent_default.png b/tools/layoutlib/bridge/resources/bars/hdpi/ic_sysbar_recent_default.png
deleted file mode 100644
index cb3c433..0000000
--- a/tools/layoutlib/bridge/resources/bars/hdpi/ic_sysbar_recent_default.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/mdpi/ic_sysbar_back.png b/tools/layoutlib/bridge/resources/bars/mdpi/ic_sysbar_back.png
new file mode 100644
index 0000000..a00bc5b
--- /dev/null
+++ b/tools/layoutlib/bridge/resources/bars/mdpi/ic_sysbar_back.png
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/mdpi/ic_sysbar_back_default.png b/tools/layoutlib/bridge/resources/bars/mdpi/ic_sysbar_back_default.png
deleted file mode 100644
index 5ab09f0..0000000
--- a/tools/layoutlib/bridge/resources/bars/mdpi/ic_sysbar_back_default.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/mdpi/ic_sysbar_home.png b/tools/layoutlib/bridge/resources/bars/mdpi/ic_sysbar_home.png
new file mode 100644
index 0000000..dc3183b
--- /dev/null
+++ b/tools/layoutlib/bridge/resources/bars/mdpi/ic_sysbar_home.png
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/mdpi/ic_sysbar_home_default.png b/tools/layoutlib/bridge/resources/bars/mdpi/ic_sysbar_home_default.png
deleted file mode 100644
index 62ca427..0000000
--- a/tools/layoutlib/bridge/resources/bars/mdpi/ic_sysbar_home_default.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/mdpi/ic_sysbar_recent.png b/tools/layoutlib/bridge/resources/bars/mdpi/ic_sysbar_recent.png
new file mode 100644
index 0000000..b07f611
--- /dev/null
+++ b/tools/layoutlib/bridge/resources/bars/mdpi/ic_sysbar_recent.png
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/mdpi/ic_sysbar_recent_default.png b/tools/layoutlib/bridge/resources/bars/mdpi/ic_sysbar_recent_default.png
deleted file mode 100644
index ff698fb..0000000
--- a/tools/layoutlib/bridge/resources/bars/mdpi/ic_sysbar_recent_default.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/tablet_system_bar.xml b/tools/layoutlib/bridge/resources/bars/navigation_bar.xml
similarity index 76%
rename from tools/layoutlib/bridge/resources/bars/tablet_system_bar.xml
rename to tools/layoutlib/bridge/resources/bars/navigation_bar.xml
index c5acddb..599ca08 100644
--- a/tools/layoutlib/bridge/resources/bars/tablet_system_bar.xml
+++ b/tools/layoutlib/bridge/resources/bars/navigation_bar.xml
@@ -1,5 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android">
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"/>
<ImageView
android:layout_height="wrap_content"
android:layout_width="wrap_content"/>
@@ -13,12 +17,4 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"/>
- <ImageView
- android:layout_height="wrap_content"
- android:layout_width="wrap_content"/>
- <ImageView
- android:layout_height="wrap_content"
- android:layout_width="wrap_content"
- android:layout_marginLeft="3dip"
- android:layout_marginRight="15dip"/>
</merge>
diff --git a/tools/layoutlib/bridge/resources/bars/phone_system_bar.xml b/tools/layoutlib/bridge/resources/bars/status_bar.xml
similarity index 100%
rename from tools/layoutlib/bridge/resources/bars/phone_system_bar.xml
rename to tools/layoutlib/bridge/resources/bars/status_bar.xml
diff --git a/tools/layoutlib/bridge/resources/bars/xhdpi/ic_sysbar_back.png b/tools/layoutlib/bridge/resources/bars/xhdpi/ic_sysbar_back.png
new file mode 100644
index 0000000..bd60cd6
--- /dev/null
+++ b/tools/layoutlib/bridge/resources/bars/xhdpi/ic_sysbar_back.png
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/xhdpi/ic_sysbar_back_default.png b/tools/layoutlib/bridge/resources/bars/xhdpi/ic_sysbar_back_default.png
deleted file mode 100644
index 4cb305d..0000000
--- a/tools/layoutlib/bridge/resources/bars/xhdpi/ic_sysbar_back_default.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/xhdpi/ic_sysbar_home.png b/tools/layoutlib/bridge/resources/bars/xhdpi/ic_sysbar_home.png
new file mode 100644
index 0000000..c5bc5c9
--- /dev/null
+++ b/tools/layoutlib/bridge/resources/bars/xhdpi/ic_sysbar_home.png
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/xhdpi/ic_sysbar_home_default.png b/tools/layoutlib/bridge/resources/bars/xhdpi/ic_sysbar_home_default.png
deleted file mode 100644
index 31d35c8..0000000
--- a/tools/layoutlib/bridge/resources/bars/xhdpi/ic_sysbar_home_default.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/xhdpi/ic_sysbar_recent.png b/tools/layoutlib/bridge/resources/bars/xhdpi/ic_sysbar_recent.png
new file mode 100644
index 0000000..f621d9c
--- /dev/null
+++ b/tools/layoutlib/bridge/resources/bars/xhdpi/ic_sysbar_recent.png
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/xhdpi/ic_sysbar_recent_default.png b/tools/layoutlib/bridge/resources/bars/xhdpi/ic_sysbar_recent_default.png
deleted file mode 100644
index f0cc341..0000000
--- a/tools/layoutlib/bridge/resources/bars/xhdpi/ic_sysbar_recent_default.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/src/android/os/SystemClock_Delegate.java b/tools/layoutlib/bridge/src/android/os/SystemClock_Delegate.java
index 26cb97b..fd594f7 100644
--- a/tools/layoutlib/bridge/src/android/os/SystemClock_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/os/SystemClock_Delegate.java
@@ -66,7 +66,7 @@
* @return elapsed nanoseconds since boot.
*/
@LayoutlibDelegate
- /*package*/ static long elapsedRealtimeNano() {
+ /*package*/ static long elapsedRealtimeNanos() {
return System.nanoTime() - sBootTimeNano;
}
diff --git a/tools/layoutlib/bridge/src/android/view/Choreographer_Delegate.java b/tools/layoutlib/bridge/src/android/view/Choreographer_Delegate.java
new file mode 100644
index 0000000..f75ee50
--- /dev/null
+++ b/tools/layoutlib/bridge/src/android/view/Choreographer_Delegate.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.view;
+
+import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
+
+/**
+ * Delegate used to provide new implementation of a select few methods of {@link Choreographer}
+ *
+ * Through the layoutlib_create tool, the original methods of Choreographer have been
+ * replaced by calls to methods of the same name in this delegate class.
+ *
+ */
+public class Choreographer_Delegate {
+
+ @LayoutlibDelegate
+ public static float getRefreshRate() {
+ return 60.f;
+ }
+}
diff --git a/tools/layoutlib/bridge/src/android/view/Display_Delegate.java b/tools/layoutlib/bridge/src/android/view/Display_Delegate.java
index 6ccdcb6..53dc821 100644
--- a/tools/layoutlib/bridge/src/android/view/Display_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/view/Display_Delegate.java
@@ -16,11 +16,8 @@
package android.view;
-import com.android.layoutlib.bridge.android.BridgeWindowManager;
-import com.android.layoutlib.bridge.impl.RenderAction;
import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-import android.os.RemoteException;
/**
* Delegate used to provide new implementation of a select few methods of {@link Display}
@@ -31,4 +28,9 @@
*/
public class Display_Delegate {
+ @LayoutlibDelegate
+ static void updateDisplayInfoLocked(Display theDisplay) {
+ // do nothing
+ }
+
}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindowManager.java b/tools/layoutlib/bridge/src/android/view/IWindowManagerImpl.java
similarity index 95%
rename from tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindowManager.java
rename to tools/layoutlib/bridge/src/android/view/IWindowManagerImpl.java
index 3fcc8ef..da736b7 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindowManager.java
+++ b/tools/layoutlib/bridge/src/android/view/IWindowManagerImpl.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.layoutlib.bridge.android;
+package android.view;
import com.android.internal.view.IInputContext;
import com.android.internal.view.IInputMethodClient;
@@ -28,7 +28,6 @@
import android.os.RemoteException;
import android.util.DisplayMetrics;
import android.view.Display;
-import android.view.Display_Delegate;
import android.view.Gravity;
import android.view.IApplicationToken;
import android.view.IDisplayContentChangeListener;
@@ -45,16 +44,21 @@
* Basic implementation of {@link IWindowManager} so that {@link Display} (and
* {@link Display_Delegate}) can return a valid instance.
*/
-public class BridgeWindowManager implements IWindowManager {
+public class IWindowManagerImpl implements IWindowManager {
private final Configuration mConfig;
private final DisplayMetrics mMetrics;
private final int mRotation;
+ private final boolean mHasSystemNavBar;
+ private final boolean mHasNavigationBar;
- public BridgeWindowManager(Configuration config, DisplayMetrics metrics, int rotation) {
+ public IWindowManagerImpl(Configuration config, DisplayMetrics metrics, int rotation,
+ boolean hasSystemNavBar, boolean hasNavigationBar) {
mConfig = config;
mMetrics = metrics;
mRotation = rotation;
+ mHasSystemNavBar = hasSystemNavBar;
+ mHasNavigationBar = hasNavigationBar;
}
// custom API.
@@ -70,14 +74,18 @@
return mRotation;
}
- // ---- unused implementation of IWindowManager ----
+ @Override
+ public boolean hasNavigationBar() {
+ return mHasNavigationBar;
+ }
@Override
public boolean hasSystemNavBar() throws RemoteException {
- // TODO Auto-generated method stub
- return false;
+ return mHasSystemNavBar;
}
+ // ---- unused implementation of IWindowManager ----
+
@Override
public void addAppToken(int arg0, IApplicationToken arg1, int arg2, int arg3, boolean arg4,
boolean arg5)
@@ -435,11 +443,6 @@
}
@Override
- public boolean hasNavigationBar() {
- return false; // should this return something else?
- }
-
- @Override
public void lockNow(Bundle options) {
// TODO Auto-generated method stub
}
diff --git a/tools/layoutlib/bridge/src/android/view/WindowManagerGlobal_Delegate.java b/tools/layoutlib/bridge/src/android/view/WindowManagerGlobal_Delegate.java
new file mode 100644
index 0000000..2606e55
--- /dev/null
+++ b/tools/layoutlib/bridge/src/android/view/WindowManagerGlobal_Delegate.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.view;
+
+import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
+
+/**
+ * Delegate used to provide new implementation of a select few methods of
+ * {@link WindowManagerGlobal}
+ *
+ * Through the layoutlib_create tool, the original methods of WindowManagerGlobal have been
+ * replaced by calls to methods of the same name in this delegate class.
+ *
+ */
+public class WindowManagerGlobal_Delegate {
+
+ private static IWindowManager sService;
+
+ @LayoutlibDelegate
+ public static IWindowManager getWindowManagerService() {
+ return sService;
+ }
+
+ // ---- internal implementation stuff ----
+
+ public static void setWindowManagerService(IWindowManager service) {
+ sService = service;
+ }
+}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java
index daf520b..bf8658e 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java
@@ -210,7 +210,8 @@
Capability.PLAY_ANIMATION,
Capability.ANIMATED_VIEW_MANIPULATION,
Capability.ADAPTER_BINDING,
- Capability.EXTENDED_VIEWINFO);
+ Capability.EXTENDED_VIEWINFO,
+ Capability.FIXED_SCALABLE_NINE_PATCH);
BridgeAssetManager.initSystem();
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java
index 80478ba..e2fced6 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java
@@ -25,6 +25,7 @@
import com.android.ide.common.rendering.api.StyleResourceValue;
import com.android.layoutlib.bridge.Bridge;
import com.android.layoutlib.bridge.BridgeConstants;
+import com.android.layoutlib.bridge.android.view.WindowManagerImpl;
import com.android.layoutlib.bridge.impl.ParserFactory;
import com.android.layoutlib.bridge.impl.Stack;
import com.android.resources.ResourceType;
@@ -68,9 +69,9 @@
import android.view.BridgeInflater;
import android.view.CompatibilityInfoHolder;
import android.view.Display;
-import android.view.Surface;
import android.view.View;
import android.view.ViewGroup;
+import android.view.WindowManager;
import android.view.textservice.TextServicesManager;
import java.io.File;
@@ -98,7 +99,7 @@
private final Configuration mConfig;
private final ApplicationInfo mApplicationInfo;
private final IProjectCallback mProjectCallback;
- private final BridgeWindowManager mIWindowManager;
+ private final WindowManager mWindowManager;
private Resources.Theme mTheme;
@@ -139,10 +140,10 @@
mRenderResources = renderResources;
mConfig = config;
- mIWindowManager = new BridgeWindowManager(mConfig, metrics, Surface.ROTATION_0);
-
mApplicationInfo = new ApplicationInfo();
mApplicationInfo.targetSdkVersion = targetSdkVersion;
+
+ mWindowManager = new WindowManagerImpl(mMetrics);
}
/**
@@ -198,14 +199,14 @@
return mRenderResources;
}
- public BridgeWindowManager getIWindowManager() {
- return mIWindowManager;
- }
-
public Map<String, String> getDefaultPropMap(Object key) {
return mDefaultPropMaps.get(key);
}
+ public Configuration getConfiguration() {
+ return mConfig;
+ }
+
/**
* Adds a parser to the stack.
* @param parser the parser to add.
@@ -431,10 +432,8 @@
return TextServicesManager.getInstance();
}
- // AutoCompleteTextView and MultiAutoCompleteTextView want a window
- // service. We don't have any but it's not worth an exception.
if (WINDOW_SERVICE.equals(service)) {
- return null;
+ return mWindowManager;
}
// needed by SearchView
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/view/WindowManagerImpl.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/view/WindowManagerImpl.java
new file mode 100644
index 0000000..9a633bf
--- /dev/null
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/view/WindowManagerImpl.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.layoutlib.bridge.android.view;
+
+import android.util.DisplayMetrics;
+import android.view.Display;
+import android.view.DisplayInfo;
+import android.view.View;
+import android.view.WindowManager;
+
+public class WindowManagerImpl implements WindowManager {
+
+ private final DisplayMetrics mMetrics;
+ private final Display mDisplay;
+
+ public WindowManagerImpl(DisplayMetrics metrics) {
+ mMetrics = metrics;
+
+ DisplayInfo info = new DisplayInfo();
+ info.logicalHeight = mMetrics.heightPixels;
+ info.logicalWidth = mMetrics.widthPixels;
+ mDisplay = new Display(null, Display.DEFAULT_DISPLAY, info, null);
+ }
+
+ @Override
+ public Display getDefaultDisplay() {
+ return mDisplay;
+ }
+
+
+ @Override
+ public void addView(View arg0, android.view.ViewGroup.LayoutParams arg1) {
+ // pass
+ }
+
+ @Override
+ public void removeView(View arg0) {
+ // pass
+ }
+
+ @Override
+ public void updateViewLayout(View arg0, android.view.ViewGroup.LayoutParams arg1) {
+ // pass
+ }
+
+
+ @Override
+ public void removeViewImmediate(View arg0) {
+ // pass
+ }
+}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/CustomBar.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/CustomBar.java
index 62c886b..ea9d8d9 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/CustomBar.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/CustomBar.java
@@ -60,11 +60,15 @@
protected abstract TextView getStyleableTextView();
- protected CustomBar(Context context, Density density, String layoutPath, String name)
- throws XmlPullParserException {
+ protected CustomBar(Context context, Density density, int orientation, String layoutPath,
+ String name) throws XmlPullParserException {
super(context);
- setOrientation(LinearLayout.HORIZONTAL);
- setGravity(Gravity.CENTER_VERTICAL);
+ setOrientation(orientation);
+ if (orientation == LinearLayout.HORIZONTAL) {
+ setGravity(Gravity.CENTER_VERTICAL);
+ } else {
+ setGravity(Gravity.CENTER_HORIZONTAL);
+ }
LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(
Context.LAYOUT_INFLATER_SERVICE);
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/FakeActionBar.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/FakeActionBar.java
index 68f5aba..226649d 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/FakeActionBar.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/FakeActionBar.java
@@ -21,6 +21,7 @@
import org.xmlpull.v1.XmlPullParserException;
import android.content.Context;
+import android.widget.LinearLayout;
import android.widget.TextView;
public class FakeActionBar extends CustomBar {
@@ -29,7 +30,7 @@
public FakeActionBar(Context context, Density density, String label, String icon)
throws XmlPullParserException {
- super(context, density, "/bars/action_bar.xml", "action_bar.xml");
+ super(context, density, LinearLayout.HORIZONTAL, "/bars/action_bar.xml", "action_bar.xml");
// Cannot access the inside items through id because no R.id values have been
// created for them.
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/NavigationBar.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/NavigationBar.java
new file mode 100644
index 0000000..cc90d6b
--- /dev/null
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/NavigationBar.java
@@ -0,0 +1,54 @@
+/*
+ * 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.layoutlib.bridge.bars;
+
+import com.android.resources.Density;
+
+import org.xmlpull.v1.XmlPullParserException;
+
+import android.content.Context;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+
+public class NavigationBar extends CustomBar {
+
+ public NavigationBar(Context context, Density density, int orientation) throws XmlPullParserException {
+ super(context, density, orientation, "/bars/navigation_bar.xml", "navigation_bar.xml");
+
+ setBackgroundColor(0xFF000000);
+
+ // Cannot access the inside items through id because no R.id values have been
+ // created for them.
+ // We do know the order though.
+ // 0 is a spacer.
+ int back = 1;
+ int recent = 3;
+ if (orientation == LinearLayout.VERTICAL) {
+ back = 3;
+ recent = 1;
+ }
+
+ loadIcon(back, "ic_sysbar_back.png", density);
+ loadIcon(2, "ic_sysbar_home.png", density);
+ loadIcon(recent, "ic_sysbar_recent.png", density);
+ }
+
+ @Override
+ protected TextView getStyleableTextView() {
+ return null;
+ }
+}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/PhoneSystemBar.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/StatusBar.java
similarity index 86%
rename from tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/PhoneSystemBar.java
rename to tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/StatusBar.java
index 7521011..5c08412 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/PhoneSystemBar.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/StatusBar.java
@@ -25,12 +25,13 @@
import android.graphics.drawable.Drawable;
import android.graphics.drawable.LevelListDrawable;
import android.view.Gravity;
+import android.widget.LinearLayout;
import android.widget.TextView;
-public class PhoneSystemBar extends CustomBar {
+public class StatusBar extends CustomBar {
- public PhoneSystemBar(Context context, Density density) throws XmlPullParserException {
- super(context, density, "/bars/phone_system_bar.xml", "phone_system_bar.xml");
+ public StatusBar(Context context, Density density) throws XmlPullParserException {
+ super(context, density, LinearLayout.HORIZONTAL, "/bars/status_bar.xml", "status_bar.xml");
// FIXME: use FILL_H?
setGravity(Gravity.START | Gravity.TOP | Gravity.RIGHT);
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/TabletSystemBar.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/TabletSystemBar.java
deleted file mode 100644
index 456ddb4..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/TabletSystemBar.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * 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.layoutlib.bridge.bars;
-
-import com.android.resources.Density;
-import com.android.resources.ResourceType;
-
-import org.xmlpull.v1.XmlPullParserException;
-
-import android.content.Context;
-import android.graphics.drawable.Drawable;
-import android.graphics.drawable.LevelListDrawable;
-import android.widget.TextView;
-
-public class TabletSystemBar extends CustomBar {
-
- public TabletSystemBar(Context context, Density density) throws XmlPullParserException {
- super(context, density, "/bars/tablet_system_bar.xml", "tablet_system_bar.xml");
-
- setBackgroundColor(0xFF000000);
-
- // Cannot access the inside items through id because no R.id values have been
- // created for them.
- // We do know the order though.
- loadIcon(0, "ic_sysbar_back_default.png", density);
- loadIcon(1, "ic_sysbar_home_default.png", density);
- loadIcon(2, "ic_sysbar_recent_default.png", density);
- // 3 is the spacer
- loadIcon(4, "stat_sys_wifi_signal_4_fully.png", density);
- Drawable drawable = loadIcon(5, ResourceType.DRAWABLE, "stat_sys_battery_charge");
- if (drawable instanceof LevelListDrawable) {
- ((LevelListDrawable) drawable).setLevel(100);
- }
- }
-
- @Override
- protected TextView getStyleableTextView() {
- return null;
- }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/TitleBar.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/TitleBar.java
index 5f5ebc4..c27859f 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/TitleBar.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/TitleBar.java
@@ -21,6 +21,7 @@
import org.xmlpull.v1.XmlPullParserException;
import android.content.Context;
+import android.widget.LinearLayout;
import android.widget.TextView;
public class TitleBar extends CustomBar {
@@ -29,7 +30,7 @@
public TitleBar(Context context, Density density, String label)
throws XmlPullParserException {
- super(context, density, "/bars/title_bar.xml", "title_bar.xml");
+ super(context, density, LinearLayout.HORIZONTAL, "/bars/title_bar.xml", "title_bar.xml");
// Cannot access the inside items through id because no R.id values have been
// created for them.
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderAction.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderAction.java
index de65fd4..f109e39 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderAction.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderAction.java
@@ -20,11 +20,12 @@
import static com.android.ide.common.rendering.api.Result.Status.ERROR_TIMEOUT;
import static com.android.ide.common.rendering.api.Result.Status.SUCCESS;
+import com.android.ide.common.rendering.api.HardwareConfig;
import com.android.ide.common.rendering.api.LayoutLog;
import com.android.ide.common.rendering.api.RenderParams;
import com.android.ide.common.rendering.api.RenderResources;
-import com.android.ide.common.rendering.api.Result;
import com.android.ide.common.rendering.api.RenderResources.FrameworkResourceIdProvider;
+import com.android.ide.common.rendering.api.Result;
import com.android.layoutlib.bridge.Bridge;
import com.android.layoutlib.bridge.android.BridgeContext;
import com.android.resources.Density;
@@ -98,19 +99,22 @@
return result;
}
+ HardwareConfig hardwareConfig = mParams.getHardwareConfig();
+
// setup the display Metrics.
DisplayMetrics metrics = new DisplayMetrics();
- metrics.densityDpi = metrics.noncompatDensityDpi = mParams.getDensity().getDpiValue();
+ metrics.densityDpi = metrics.noncompatDensityDpi =
+ hardwareConfig.getDensity().getDpiValue();
metrics.density = metrics.noncompatDensity =
metrics.densityDpi / (float) DisplayMetrics.DENSITY_DEFAULT;
metrics.scaledDensity = metrics.noncompatScaledDensity = metrics.density;
- metrics.widthPixels = metrics.noncompatWidthPixels = mParams.getScreenWidth();
- metrics.heightPixels = metrics.noncompatHeightPixels = mParams.getScreenHeight();
- metrics.xdpi = metrics.noncompatXdpi = mParams.getXdpi();
- metrics.ydpi = metrics.noncompatYdpi = mParams.getYdpi();
+ metrics.widthPixels = metrics.noncompatWidthPixels = hardwareConfig.getScreenWidth();
+ metrics.heightPixels = metrics.noncompatHeightPixels = hardwareConfig.getScreenHeight();
+ metrics.xdpi = metrics.noncompatXdpi = hardwareConfig.getXdpi();
+ metrics.ydpi = metrics.noncompatYdpi = hardwareConfig.getYdpi();
RenderResources resources = mParams.getResources();
@@ -305,7 +309,9 @@
private Configuration getConfiguration() {
Configuration config = new Configuration();
- ScreenSize screenSize = mParams.getConfigScreenSize();
+ HardwareConfig hardwareConfig = mParams.getHardwareConfig();
+
+ ScreenSize screenSize = hardwareConfig.getScreenSize();
if (screenSize != null) {
switch (screenSize) {
case SMALL:
@@ -323,13 +329,13 @@
}
}
- Density density = mParams.getDensity();
+ Density density = hardwareConfig.getDensity();
if (density == null) {
density = Density.MEDIUM;
}
- config.screenWidthDp = mParams.getScreenWidth() / density.getDpiValue();
- config.screenHeightDp = mParams.getScreenHeight() / density.getDpiValue();
+ config.screenWidthDp = hardwareConfig.getScreenWidth() / density.getDpiValue();
+ config.screenHeightDp = hardwareConfig.getScreenHeight() / density.getDpiValue();
if (config.screenHeightDp < config.screenWidthDp) {
config.smallestScreenWidthDp = config.screenHeightDp;
} else {
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderDrawable.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderDrawable.java
index 8133210..b677131 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderDrawable.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderDrawable.java
@@ -19,6 +19,7 @@
import static com.android.ide.common.rendering.api.Result.Status.ERROR_UNKNOWN;
import com.android.ide.common.rendering.api.DrawableParams;
+import com.android.ide.common.rendering.api.HardwareConfig;
import com.android.ide.common.rendering.api.ResourceValue;
import com.android.ide.common.rendering.api.Result;
import com.android.ide.common.rendering.api.Result.Status;
@@ -59,6 +60,7 @@
try {
// get the drawable resource value
DrawableParams params = getParams();
+ HardwareConfig hardwareConfig = params.getHardwareConfig();
ResourceValue drawableResource = params.getDrawable();
// resolve it
@@ -75,15 +77,15 @@
// get the actual Drawable object to draw
Drawable d = ResourceHelper.getDrawable(drawableResource, context);
- content.setBackgroundDrawable(d);
+ content.setBackground(d);
// set the AttachInfo on the root view.
AttachInfo_Accessor.setAttachInfo(content);
// measure
- int w = params.getScreenWidth();
- int h = params.getScreenHeight();
+ int w = hardwareConfig.getScreenWidth();
+ int h = hardwareConfig.getScreenHeight();
int w_spec = MeasureSpec.makeMeasureSpec(w, MeasureSpec.EXACTLY);
int h_spec = MeasureSpec.makeMeasureSpec(h, MeasureSpec.EXACTLY);
content.measure(w_spec, h_spec);
@@ -99,11 +101,11 @@
// create an Android bitmap around the BufferedImage
Bitmap bitmap = Bitmap_Delegate.createBitmap(image,
- true /*isMutable*/, params.getDensity());
+ true /*isMutable*/, hardwareConfig.getDensity());
// create a Canvas around the Android bitmap
Canvas canvas = new Canvas(bitmap);
- canvas.setDensity(params.getDensity().getDpiValue());
+ canvas.setDensity(hardwareConfig.getDensity().getDpiValue());
// and draw
content.draw(canvas);
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderSessionImpl.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderSessionImpl.java
index e93b41d..c14af4a 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderSessionImpl.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderSessionImpl.java
@@ -24,6 +24,7 @@
import static com.android.ide.common.rendering.api.Result.Status.SUCCESS;
import com.android.ide.common.rendering.api.AdapterBinding;
+import com.android.ide.common.rendering.api.HardwareConfig;
import com.android.ide.common.rendering.api.IAnimationListener;
import com.android.ide.common.rendering.api.ILayoutPullParser;
import com.android.ide.common.rendering.api.IProjectCallback;
@@ -43,13 +44,13 @@
import com.android.layoutlib.bridge.android.BridgeLayoutParamsMapAttributes;
import com.android.layoutlib.bridge.android.BridgeXmlBlockParser;
import com.android.layoutlib.bridge.bars.FakeActionBar;
-import com.android.layoutlib.bridge.bars.PhoneSystemBar;
-import com.android.layoutlib.bridge.bars.TabletSystemBar;
+import com.android.layoutlib.bridge.bars.NavigationBar;
+import com.android.layoutlib.bridge.bars.StatusBar;
import com.android.layoutlib.bridge.bars.TitleBar;
import com.android.layoutlib.bridge.impl.binding.FakeAdapter;
import com.android.layoutlib.bridge.impl.binding.FakeExpandableAdapter;
import com.android.resources.ResourceType;
-import com.android.resources.ScreenSize;
+import com.android.resources.ScreenOrientation;
import com.android.util.Pair;
import org.xmlpull.v1.XmlPullParserException;
@@ -68,11 +69,15 @@
import android.util.TypedValue;
import android.view.AttachInfo_Accessor;
import android.view.BridgeInflater;
+import android.view.IWindowManager;
+import android.view.IWindowManagerImpl;
+import android.view.Surface;
import android.view.View;
import android.view.View.MeasureSpec;
import android.view.ViewGroup;
import android.view.ViewGroup.LayoutParams;
import android.view.ViewGroup.MarginLayoutParams;
+import android.view.WindowManagerGlobal_Delegate;
import android.widget.AbsListView;
import android.widget.AbsSpinner;
import android.widget.AdapterView;
@@ -120,7 +125,8 @@
private boolean mWindowIsFloating;
private int mStatusBarSize;
- private int mSystemBarSize;
+ private int mNavigationBarSize;
+ private int mNavigationBarOrientation = LinearLayout.HORIZONTAL;
private int mTitleBarSize;
private int mActionBarSize;
@@ -183,7 +189,15 @@
findBackground(resources);
findStatusBar(resources, metrics);
findActionBar(resources, metrics);
- findSystemBar(resources, metrics);
+ findNavigationBar(resources, metrics);
+
+ // FIXME: find those out, and possibly add them to the render params
+ boolean hasSystemNavBar = true;
+ boolean hasNavigationBar = true;
+ IWindowManager iwm = new IWindowManagerImpl(getContext().getConfiguration(),
+ metrics, Surface.ROTATION_0,
+ hasSystemNavBar, hasNavigationBar);
+ WindowManagerGlobal_Delegate.setWindowManagerService(iwm);
// build the inflater and parser.
mInflater = new BridgeInflater(context, params.getProjectCallback());
@@ -209,19 +223,57 @@
try {
SessionParams params = getParams();
+ HardwareConfig hardwareConfig = params.getHardwareConfig();
BridgeContext context = getContext();
+
// the view group that receives the window background.
ViewGroup backgroundView = null;
if (mWindowIsFloating || params.isForceNoDecor()) {
backgroundView = mViewRoot = mContentRoot = new FrameLayout(context);
} else {
+ if (hasSoftwareButtons() && mNavigationBarOrientation == LinearLayout.VERTICAL) {
+ /*
+ * This is a special case where the navigation bar is on the right.
+ +-------------------------------------------------+---+
+ | Status bar (always) | |
+ +-------------------------------------------------+ |
+ | (Layout with background drawable) | |
+ | +---------------------------------------------+ | |
+ | | Title/Action bar (optional) | | |
+ | +---------------------------------------------+ | |
+ | | Content, vertical extending | | |
+ | | | | |
+ | +---------------------------------------------+ | |
+ +-------------------------------------------------+---+
+
+ So we create a horizontal layout, with the nav bar on the right,
+ and the left part is the normal layout below without the nav bar at
+ the bottom
+ */
+ LinearLayout topLayout = new LinearLayout(context);
+ mViewRoot = topLayout;
+ topLayout.setOrientation(LinearLayout.HORIZONTAL);
+
+ try {
+ NavigationBar navigationBar = new NavigationBar(context,
+ hardwareConfig.getDensity(), LinearLayout.VERTICAL);
+ navigationBar.setLayoutParams(
+ new LinearLayout.LayoutParams(
+ mNavigationBarSize,
+ LayoutParams.MATCH_PARENT));
+ topLayout.addView(navigationBar);
+ } catch (XmlPullParserException e) {
+
+ }
+ }
+
/*
* we're creating the following layout
*
+-------------------------------------------------+
- | System bar (only in phone UI) |
+ | Status bar (always) |
+-------------------------------------------------+
| (Layout with background drawable) |
| +---------------------------------------------+ |
@@ -231,20 +283,31 @@
| | | |
| +---------------------------------------------+ |
+-------------------------------------------------+
- | System bar (only in tablet UI) |
+ | Navigation bar for soft buttons, maybe see above|
+-------------------------------------------------+
*/
LinearLayout topLayout = new LinearLayout(context);
- mViewRoot = topLayout;
topLayout.setOrientation(LinearLayout.VERTICAL);
+ // if we don't already have a view root this is it
+ if (mViewRoot == null) {
+ mViewRoot = topLayout;
+ } else {
+ LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(
+ LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT);
+ layoutParams.weight = 1;
+ topLayout.setLayoutParams(layoutParams);
+
+ // this is the case of soft buttons + vertical bar.
+ // this top layout is the first layout in the horizontal layout. see above)
+ mViewRoot.addView(topLayout, 0);
+ }
if (mStatusBarSize > 0) {
// system bar
try {
- PhoneSystemBar systemBar = new PhoneSystemBar(context,
- params.getDensity());
+ StatusBar systemBar = new StatusBar(context, hardwareConfig.getDensity());
systemBar.setLayoutParams(
new LinearLayout.LayoutParams(
LayoutParams.MATCH_PARENT, mStatusBarSize));
@@ -268,7 +331,7 @@
if (mActionBarSize > 0) {
try {
FakeActionBar actionBar = new FakeActionBar(context,
- params.getDensity(),
+ hardwareConfig.getDensity(),
params.getAppLabel(), params.getAppIcon());
actionBar.setLayoutParams(
new LinearLayout.LayoutParams(
@@ -280,7 +343,7 @@
} else if (mTitleBarSize > 0) {
try {
TitleBar titleBar = new TitleBar(context,
- params.getDensity(), params.getAppLabel());
+ hardwareConfig.getDensity(), params.getAppLabel());
titleBar.setLayoutParams(
new LinearLayout.LayoutParams(
LayoutParams.MATCH_PARENT, mTitleBarSize));
@@ -298,15 +361,16 @@
mContentRoot.setLayoutParams(layoutParams);
backgroundLayout.addView(mContentRoot);
- if (mSystemBarSize > 0) {
+ if (mNavigationBarOrientation == LinearLayout.HORIZONTAL &&
+ mNavigationBarSize > 0) {
// system bar
try {
- TabletSystemBar systemBar = new TabletSystemBar(context,
- params.getDensity());
- systemBar.setLayoutParams(
+ NavigationBar navigationBar = new NavigationBar(context,
+ hardwareConfig.getDensity(), LinearLayout.HORIZONTAL);
+ navigationBar.setLayoutParams(
new LinearLayout.LayoutParams(
- LayoutParams.MATCH_PARENT, mSystemBarSize));
- topLayout.addView(systemBar);
+ LayoutParams.MATCH_PARENT, mNavigationBarSize));
+ topLayout.addView(navigationBar);
} catch (XmlPullParserException e) {
}
@@ -334,7 +398,7 @@
// get the background drawable
if (mWindowBackground != null && backgroundView != null) {
Drawable d = ResourceHelper.getDrawable(mWindowBackground, context);
- backgroundView.setBackgroundDrawable(d);
+ backgroundView.setBackground(d);
}
return SUCCESS.createResult();
@@ -377,13 +441,14 @@
}
RenderingMode renderingMode = params.getRenderingMode();
+ HardwareConfig hardwareConfig = params.getHardwareConfig();
// only do the screen measure when needed.
boolean newRenderSize = false;
if (mMeasuredScreenWidth == -1) {
newRenderSize = true;
- mMeasuredScreenWidth = params.getScreenWidth();
- mMeasuredScreenHeight = params.getScreenHeight();
+ mMeasuredScreenWidth = hardwareConfig.getScreenWidth();
+ mMeasuredScreenHeight = hardwareConfig.getScreenHeight();
if (renderingMode != RenderingMode.NORMAL) {
int widthMeasureSpecMode = renderingMode.isHorizExpand() ?
@@ -483,11 +548,11 @@
// create an Android bitmap around the BufferedImage
Bitmap bitmap = Bitmap_Delegate.createBitmap(mImage,
- true /*isMutable*/, params.getDensity());
+ true /*isMutable*/, hardwareConfig.getDensity());
// create a Canvas around the Android bitmap
mCanvas = new Canvas(bitmap);
- mCanvas.setDensity(params.getDensity().getDpiValue());
+ mCanvas.setDensity(hardwareConfig.getDensity().getDpiValue());
}
if (freshRender && newImage == false) {
@@ -960,30 +1025,28 @@
}
}
- private boolean isTabletUi() {
- return getParams().getConfigScreenSize() == ScreenSize.XLARGE;
+ private boolean hasSoftwareButtons() {
+ return getParams().getHardwareConfig().hasSoftwareButtons();
}
private void findStatusBar(RenderResources resources, DisplayMetrics metrics) {
- if (isTabletUi() == false) {
- boolean windowFullscreen = getBooleanThemeValue(resources,
- "windowFullscreen", false /*defaultValue*/);
+ boolean windowFullscreen = getBooleanThemeValue(resources,
+ "windowFullscreen", false /*defaultValue*/);
- if (windowFullscreen == false && mWindowIsFloating == false) {
- // default value
- mStatusBarSize = DEFAULT_STATUS_BAR_HEIGHT;
+ if (windowFullscreen == false && mWindowIsFloating == false) {
+ // default value
+ mStatusBarSize = DEFAULT_STATUS_BAR_HEIGHT;
- // get the real value
- ResourceValue value = resources.getFrameworkResource(ResourceType.DIMEN,
- "status_bar_height");
+ // get the real value
+ ResourceValue value = resources.getFrameworkResource(ResourceType.DIMEN,
+ "status_bar_height");
- if (value != null) {
- TypedValue typedValue = ResourceHelper.getValue("status_bar_height",
- value.getValue(), true /*requireUnit*/);
- if (typedValue != null) {
- // compute the pixel value based on the display metrics
- mStatusBarSize = (int)typedValue.getDimension(metrics);
- }
+ if (value != null) {
+ TypedValue typedValue = ResourceHelper.getValue("status_bar_height",
+ value.getValue(), true /*requireUnit*/);
+ if (typedValue != null) {
+ // compute the pixel value based on the display metrics
+ mStatusBarSize = (int)typedValue.getDimension(metrics);
}
}
}
@@ -1050,22 +1113,48 @@
}
}
- private void findSystemBar(RenderResources resources, DisplayMetrics metrics) {
- if (isTabletUi() && mWindowIsFloating == false) {
+ private void findNavigationBar(RenderResources resources, DisplayMetrics metrics) {
+ if (hasSoftwareButtons() && mWindowIsFloating == false) {
// default value
- mSystemBarSize = 48; // ??
+ mNavigationBarSize = 48; // ??
+
+ HardwareConfig hardwareConfig = getParams().getHardwareConfig();
+
+ boolean barOnBottom = true;
+
+ if (hardwareConfig.getOrientation() == ScreenOrientation.LANDSCAPE) {
+ // compute the dp of the screen.
+ int shortSize = hardwareConfig.getScreenHeight();
+
+ // compute in dp
+ int shortSizeDp = shortSize * DisplayMetrics.DENSITY_DEFAULT / hardwareConfig.getDensity().getDpiValue();
+
+ if (shortSizeDp < 600) {
+ // 0-599dp: "phone" UI with bar on the side
+ barOnBottom = false;
+ } else {
+ // 600+dp: "tablet" UI with bar on the bottom
+ barOnBottom = true;
+ }
+ }
+
+ if (barOnBottom) {
+ mNavigationBarOrientation = LinearLayout.HORIZONTAL;
+ } else {
+ mNavigationBarOrientation = LinearLayout.VERTICAL;
+ }
// get the real value
ResourceValue value = resources.getFrameworkResource(ResourceType.DIMEN,
- "status_bar_height");
+ barOnBottom ? "navigation_bar_height" : "navigation_bar_width");
if (value != null) {
- TypedValue typedValue = ResourceHelper.getValue("status_bar_height",
+ TypedValue typedValue = ResourceHelper.getValue("navigation_bar_height",
value.getValue(), true /*requireUnit*/);
if (typedValue != null) {
// compute the pixel value based on the display metrics
- mSystemBarSize = (int)typedValue.getDimension(metrics);
+ mNavigationBarSize = (int)typedValue.getDimension(metrics);
}
}
}
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/CreateInfo.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/CreateInfo.java
index 5109810..80a1a60 100644
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/CreateInfo.java
+++ b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/CreateInfo.java
@@ -110,11 +110,13 @@
"android.os.Handler#sendMessageAtTime",
"android.os.HandlerThread#run",
"android.os.Build#getString",
- "android.view.Display#getWindowManager",
+ "android.view.Choreographer#getRefreshRate",
+ "android.view.Display#updateDisplayInfoLocked",
"android.view.LayoutInflater#rInflate",
"android.view.LayoutInflater#parseInclude",
"android.view.View#isInEditMode",
"android.view.ViewRootImpl#isInTouchMode",
+ "android.view.WindowManagerGlobal#getWindowManagerService",
"android.view.inputmethod.InputMethodManager#getInstance",
"com.android.internal.util.XmlUtils#convertValueToInt",
"com.android.internal.textservice.ITextServicesManager$Stub#asInterface",
diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java
index e913d10..b871cdc 100644
--- a/wifi/java/android/net/wifi/WifiManager.java
+++ b/wifi/java/android/net/wifi/WifiManager.java
@@ -1983,7 +1983,9 @@
protected void finalize() throws Throwable {
try {
- mHandler.getLooper().quit();
+ if (mHandler != null && mHandler.getLooper() != null) {
+ mHandler.getLooper().quit();
+ }
} finally {
super.finalize();
}
diff --git a/wifi/java/android/net/wifi/WifiMonitor.java b/wifi/java/android/net/wifi/WifiMonitor.java
index 93ab4a4..0b0d738 100644
--- a/wifi/java/android/net/wifi/WifiMonitor.java
+++ b/wifi/java/android/net/wifi/WifiMonitor.java
@@ -178,6 +178,7 @@
private static final String P2P_GO_NEG_SUCCESS_STR = "P2P-GO-NEG-SUCCESS";
+ /* P2P-GO-NEG-FAILURE status=x */
private static final String P2P_GO_NEG_FAILURE_STR = "P2P-GO-NEG-FAILURE";
private static final String P2P_GROUP_FORMATION_SUCCESS_STR =
@@ -566,6 +567,26 @@
WifiManager.ERROR, 0));
}
+ /* <event> status=<err> and the special case of <event> reason=FREQ_CONFLICT */
+ private P2pStatus p2pError(String dataString) {
+ P2pStatus err = P2pStatus.UNKNOWN;
+ String[] tokens = dataString.split(" ");
+ if (tokens.length < 2) return err;
+ String[] nameValue = tokens[1].split("=");
+ if (nameValue.length != 2) return err;
+
+ /* Handle the special case of reason=FREQ+CONFLICT */
+ if (nameValue[1].equals("FREQ_CONFLICT")) {
+ return P2pStatus.NO_COMMON_CHANNEL;
+ }
+ try {
+ err = P2pStatus.valueOf(Integer.parseInt(nameValue[1]));
+ } catch (NumberFormatException e) {
+ e.printStackTrace();
+ }
+ return err;
+ }
+
/**
* Handle p2p events
*/
@@ -582,11 +603,11 @@
} else if (dataString.startsWith(P2P_GO_NEG_SUCCESS_STR)) {
mStateMachine.sendMessage(P2P_GO_NEGOTIATION_SUCCESS_EVENT);
} else if (dataString.startsWith(P2P_GO_NEG_FAILURE_STR)) {
- mStateMachine.sendMessage(P2P_GO_NEGOTIATION_FAILURE_EVENT);
+ mStateMachine.sendMessage(P2P_GO_NEGOTIATION_FAILURE_EVENT, p2pError(dataString));
} else if (dataString.startsWith(P2P_GROUP_FORMATION_SUCCESS_STR)) {
mStateMachine.sendMessage(P2P_GROUP_FORMATION_SUCCESS_EVENT);
} else if (dataString.startsWith(P2P_GROUP_FORMATION_FAILURE_STR)) {
- mStateMachine.sendMessage(P2P_GROUP_FORMATION_FAILURE_EVENT);
+ mStateMachine.sendMessage(P2P_GROUP_FORMATION_FAILURE_EVENT, p2pError(dataString));
} else if (dataString.startsWith(P2P_GROUP_STARTED_STR)) {
mStateMachine.sendMessage(P2P_GROUP_STARTED_EVENT, new WifiP2pGroup(dataString));
} else if (dataString.startsWith(P2P_GROUP_REMOVED_STR)) {
@@ -595,17 +616,7 @@
mStateMachine.sendMessage(P2P_INVITATION_RECEIVED_EVENT,
new WifiP2pGroup(dataString));
} else if (dataString.startsWith(P2P_INVITATION_RESULT_STR)) {
- String[] tokens = dataString.split(" ");
- if (tokens.length != 2) return;
- String[] nameValue = tokens[1].split("=");
- if (nameValue.length != 2) return;
- P2pStatus err = P2pStatus.UNKNOWN;
- try {
- err = P2pStatus.valueOf(Integer.parseInt(nameValue[1]));
- } catch (NumberFormatException e) {
- e.printStackTrace();
- }
- mStateMachine.sendMessage(P2P_INVITATION_RESULT_EVENT, err);
+ mStateMachine.sendMessage(P2P_INVITATION_RESULT_EVENT, p2pError(dataString));
} else if (dataString.startsWith(P2P_PROV_DISC_PBC_REQ_STR)) {
mStateMachine.sendMessage(P2P_PROV_DISC_PBC_REQ_EVENT,
new WifiP2pProvDiscEvent(dataString));
diff --git a/wifi/java/android/net/wifi/WifiStateMachine.java b/wifi/java/android/net/wifi/WifiStateMachine.java
index db539e4..196bf2e 100644
--- a/wifi/java/android/net/wifi/WifiStateMachine.java
+++ b/wifi/java/android/net/wifi/WifiStateMachine.java
@@ -114,6 +114,7 @@
private final boolean mP2pSupported;
private final AtomicBoolean mP2pConnected = new AtomicBoolean(false);
+ private boolean mTemporarilyDisconnectWifi = false;
private final String mPrimaryDeviceType;
/* Scan results handling */
@@ -2017,6 +2018,10 @@
NetworkInfo info = (NetworkInfo) message.obj;
mP2pConnected.set(info.isConnected());
break;
+ case WifiP2pService.DISCONNECT_WIFI_REQUEST:
+ mTemporarilyDisconnectWifi = (message.arg1 == 1);
+ replyToMessage(message, WifiP2pService.DISCONNECT_WIFI_RESPONSE);
+ break;
default:
loge("Error! unhandled message" + message);
break;
@@ -3030,6 +3035,15 @@
transitionTo(mDisconnectedState);
}
break;
+ case WifiP2pService.DISCONNECT_WIFI_REQUEST:
+ if (message.arg1 == 1) {
+ mWifiNative.disconnect();
+ mTemporarilyDisconnectWifi = true;
+ } else {
+ mWifiNative.reconnect();
+ mTemporarilyDisconnectWifi = false;
+ }
+ break;
/* Do a redundant disconnect without transition */
case CMD_DISCONNECT:
mWifiNative.disconnect();
@@ -3159,6 +3173,13 @@
mWifiNative.disconnect();
transitionTo(mDisconnectingState);
break;
+ case WifiP2pService.DISCONNECT_WIFI_REQUEST:
+ if (message.arg1 == 1) {
+ mWifiNative.disconnect();
+ mTemporarilyDisconnectWifi = true;
+ transitionTo(mDisconnectingState);
+ }
+ break;
case CMD_SET_SCAN_MODE:
if (message.arg1 == SCAN_ONLY_MODE) {
sendMessage(CMD_DISCONNECT);
@@ -3465,6 +3486,13 @@
if (DBG) log(getName() + "\n");
EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
+ // We dont scan frequently if this is a temporary disconnect
+ // due to p2p
+ if (mTemporarilyDisconnectWifi) {
+ mWifiP2pChannel.sendMessage(WifiP2pService.DISCONNECT_WIFI_RESPONSE);
+ return;
+ }
+
mFrameworkScanIntervalMs = Settings.Global.getLong(mContext.getContentResolver(),
Settings.Global.WIFI_FRAMEWORK_SCAN_INTERVAL_MS,
mDefaultFrameworkScanIntervalMs);
@@ -3579,6 +3607,12 @@
sendMessageDelayed(obtainMessage(CMD_NO_NETWORKS_PERIODIC_SCAN,
++mPeriodicScanToken, 0), mSupplicantScanIntervalMs);
}
+ case CMD_RECONNECT:
+ case CMD_REASSOCIATE:
+ // Drop a third party reconnect/reassociate if we are
+ // tempoarily disconnected for p2p
+ if (mTemporarilyDisconnectWifi) ret = NOT_HANDLED;
+ break;
default:
ret = NOT_HANDLED;
}
diff --git a/wifi/java/android/net/wifi/WifiWatchdogStateMachine.java b/wifi/java/android/net/wifi/WifiWatchdogStateMachine.java
index 9c727f9..c8f0712 100644
--- a/wifi/java/android/net/wifi/WifiWatchdogStateMachine.java
+++ b/wifi/java/android/net/wifi/WifiWatchdogStateMachine.java
@@ -556,8 +556,8 @@
mLinkProperties = (LinkProperties) intent.getParcelableExtra(
WifiManager.EXTRA_LINK_PROPERTIES);
if (mPoorNetworkDetectionEnabled) {
- if (mWifiInfo == null) {
- if (DBG) logd("Ignoring link verification, mWifiInfo is NULL");
+ if (mWifiInfo == null || mCurrentBssid == null) {
+ loge("Ignore, wifiinfo " + mWifiInfo +" bssid " + mCurrentBssid);
sendLinkStatusNotification(true);
} else {
transitionTo(mVerifyingLinkState);
@@ -726,7 +726,7 @@
}
private void handleRssiChange() {
- if (mCurrentSignalLevel <= LINK_MONITOR_LEVEL_THRESHOLD) {
+ if (mCurrentSignalLevel <= LINK_MONITOR_LEVEL_THRESHOLD && mCurrentBssid != null) {
transitionTo(mLinkMonitoringState);
} else {
// stay here
@@ -920,11 +920,15 @@
if (DBG) logd("########################################");
if (isGood) {
mWsmChannel.sendMessage(GOOD_LINK_DETECTED);
- mCurrentBssid.mLastTimeGood = SystemClock.elapsedRealtime();
- logd("Good link notification is sent");
+ if (mCurrentBssid != null) {
+ mCurrentBssid.mLastTimeGood = SystemClock.elapsedRealtime();
+ }
+ if (DBG) logd("Good link notification is sent");
} else {
mWsmChannel.sendMessage(POOR_LINK_DETECTED);
- mCurrentBssid.mLastTimePoor = SystemClock.elapsedRealtime();
+ if (mCurrentBssid != null) {
+ mCurrentBssid.mLastTimePoor = SystemClock.elapsedRealtime();
+ }
logd("Poor link notification is sent");
}
}
diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pDeviceList.java b/wifi/java/android/net/wifi/p2p/WifiP2pDeviceList.java
index 2093bda..f14c305 100644
--- a/wifi/java/android/net/wifi/p2p/WifiP2pDeviceList.java
+++ b/wifi/java/android/net/wifi/p2p/WifiP2pDeviceList.java
@@ -114,6 +114,15 @@
return mDevices.remove(device.deviceAddress) != null;
}
+ /** Returns true if any device the list was removed @hide */
+ public boolean remove(WifiP2pDeviceList list) {
+ boolean ret = false;
+ for (WifiP2pDevice d : list.mDevices.values()) {
+ if (remove(d)) ret = true;
+ }
+ return ret;
+ }
+
/** Get the list of devices */
public Collection<WifiP2pDevice> getDeviceList() {
return Collections.unmodifiableCollection(mDevices.values());
diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pService.java b/wifi/java/android/net/wifi/p2p/WifiP2pService.java
index ca329e6..4b90901 100644
--- a/wifi/java/android/net/wifi/p2p/WifiP2pService.java
+++ b/wifi/java/android/net/wifi/p2p/WifiP2pService.java
@@ -149,9 +149,28 @@
private static final int PEER_CONNECTION_USER_ACCEPT = BASE + 2;
/* User rejected a peer request */
private static final int PEER_CONNECTION_USER_REJECT = BASE + 3;
+ /* User wants to disconnect wifi in favour of p2p */
+ private static final int DROP_WIFI_USER_ACCEPT = BASE + 4;
+ /* User wants to keep his wifi connection and drop p2p */
+ private static final int DROP_WIFI_USER_REJECT = BASE + 5;
+
/* Commands to the WifiStateMachine */
- public static final int P2P_CONNECTION_CHANGED = BASE + 11;
+ public static final int P2P_CONNECTION_CHANGED = BASE + 11;
+
+ /* These commands are used to tempoarily disconnect wifi when we detect
+ * a frequency conflict which would make it impossible to have with p2p
+ * and wifi active at the same time.
+ *
+ * If the user chooses to disable wifi tempoarily, we keep wifi disconnected
+ * until the p2p connection is done and terminated at which point we will
+ * bring back wifi up
+ *
+ * DISCONNECT_WIFI_REQUEST
+ * msg.arg1 = 1 enables temporary disconnect and 0 disables it.
+ */
+ public static final int DISCONNECT_WIFI_REQUEST = BASE + 12;
+ public static final int DISCONNECT_WIFI_RESPONSE = BASE + 13;
private final boolean mP2pSupported;
@@ -172,6 +191,8 @@
private NetworkInfo mNetworkInfo;
+ private boolean mTempoarilyDisconnectedWifi = false;
+
/* The transaction Id of service discovery request */
private byte mServiceTransactionId = 0;
@@ -222,7 +243,7 @@
PREVIOUS_PROTOCOL_ERROR,
/* There is no common channels the both devices can use. */
- NO_COMMON_CHANNE,
+ NO_COMMON_CHANNEL,
/* Unknown p2p group. For example, Device A tries to invoke the previous persistent group,
* but device B has removed the specified credential already. */
@@ -257,7 +278,7 @@
case 6:
return PREVIOUS_PROTOCOL_ERROR;
case 7:
- return NO_COMMON_CHANNE;
+ return NO_COMMON_CHANNEL;
case 8:
return UNKNOWN_P2P_GROUP;
case 9:
@@ -346,6 +367,7 @@
= new UserAuthorizingInvitationState();
private ProvisionDiscoveryState mProvisionDiscoveryState = new ProvisionDiscoveryState();
private GroupNegotiationState mGroupNegotiationState = new GroupNegotiationState();
+ private FrequencyConflictState mFrequencyConflictState =new FrequencyConflictState();
private GroupCreatedState mGroupCreatedState = new GroupCreatedState();
private UserAuthorizingJoinState mUserAuthorizingJoinState = new UserAuthorizingJoinState();
@@ -355,6 +377,15 @@
private WifiMonitor mWifiMonitor = new WifiMonitor(this, mWifiNative);
private final WifiP2pDeviceList mPeers = new WifiP2pDeviceList();
+ /* During a connection, supplicant can tell us that a device was lost. From a supplicant's
+ * perspective, the discovery stops during connection and it purges device since it does
+ * not get latest updates about the device without being in discovery state.
+ *
+ * From the framework perspective, the device is still there since we are connecting or
+ * connected to it. so we keep these devices in a seperate list, so that they are removed
+ * when connection is cancelled or lost
+ */
+ private final WifiP2pDeviceList mPeersLostDuringConnection = new WifiP2pDeviceList();
private final WifiP2pGroupList mGroups = new WifiP2pGroupList(null,
new GroupDeleteListener() {
@Override
@@ -391,6 +422,7 @@
addState(mUserAuthorizingInvitationState, mGroupCreatingState);
addState(mProvisionDiscoveryState, mGroupCreatingState);
addState(mGroupNegotiationState, mGroupCreatingState);
+ addState(mFrequencyConflictState, mGroupCreatingState);
addState(mGroupCreatedState, mP2pEnabledState);
addState(mUserAuthorizingJoinState, mGroupCreatedState);
addState(mOngoingGroupRemovalState, mGroupCreatedState);
@@ -546,6 +578,9 @@
case WifiStateMachine.CMD_DISABLE_P2P:
case PEER_CONNECTION_USER_ACCEPT:
case PEER_CONNECTION_USER_REJECT:
+ case DISCONNECT_WIFI_RESPONSE:
+ case DROP_WIFI_USER_ACCEPT:
+ case DROP_WIFI_USER_REJECT:
case GROUP_CREATING_TIMED_OUT:
case DhcpStateMachine.CMD_PRE_DHCP_ACTION:
case DhcpStateMachine.CMD_POST_DHCP_ACTION:
@@ -746,6 +781,10 @@
public boolean processMessage(Message message) {
if (DBG) logd(getName() + message.toString());
switch (message.what) {
+ case WifiMonitor.SUP_DISCONNECTION_EVENT:
+ loge("Unexpected loss of p2p socket connection");
+ transitionTo(mP2pDisabledState);
+ break;
case WifiStateMachine.CMD_ENABLE_P2P:
//Nothing to do
break;
@@ -1014,20 +1053,7 @@
// remain at this state.
}
break;
- case WifiMonitor.P2P_GROUP_STARTED_EVENT:
- mGroup = (WifiP2pGroup) message.obj;
- if (DBG) logd(getName() + " group started");
-
- if (mGroup.getNetworkId() == WifiP2pGroup.PERSISTENT_NET_ID) {
- // This is an invocation case.
- mAutonomousGroup = false;
- deferMessage(message);
- transitionTo(mGroupNegotiationState);
- } else {
- return NOT_HANDLED;
- }
- break;
- default:
+ default:
return NOT_HANDLED;
}
return HANDLED;
@@ -1061,12 +1087,17 @@
// mSavedPeerConfig can be empty
if (mSavedPeerConfig != null &&
!mSavedPeerConfig.deviceAddress.equals(device.deviceAddress)) {
+ if (DBG) {
+ logd("mSavedPeerConfig " + mSavedPeerConfig.deviceAddress +
+ "device " + device.deviceAddress);
+ }
// Do the regular device lost handling
ret = NOT_HANDLED;
break;
}
// Do nothing
- if (DBG) logd("Retain connecting device " + device);
+ if (DBG) logd("Add device to lost list " + device);
+ mPeersLostDuringConnection.update(device);
break;
case WifiP2pManager.DISCOVER_PEERS:
/* Discovery will break negotiation */
@@ -1255,6 +1286,12 @@
transitionTo(mGroupCreatedState);
break;
case WifiMonitor.P2P_GO_NEGOTIATION_FAILURE_EVENT:
+ P2pStatus status = (P2pStatus) message.obj;
+ if (status == P2pStatus.NO_COMMON_CHANNEL) {
+ transitionTo(mFrequencyConflictState);
+ break;
+ }
+ /* continue with group removal handling */
case WifiMonitor.P2P_GROUP_REMOVED_EVENT:
if (DBG) logd(getName() + " go failure");
handleGroupCreationFailure();
@@ -1264,9 +1301,14 @@
// a group removed event. Flushing things at group formation
// failure causes supplicant issues. Ignore right now.
case WifiMonitor.P2P_GROUP_FORMATION_FAILURE_EVENT:
+ status = (P2pStatus) message.obj;
+ if (status == P2pStatus.NO_COMMON_CHANNEL) {
+ transitionTo(mFrequencyConflictState);
+ break;
+ }
break;
case WifiMonitor.P2P_INVITATION_RESULT_EVENT:
- P2pStatus status = (P2pStatus)message.obj;
+ status = (P2pStatus)message.obj;
if (status == P2pStatus.SUCCESS) {
// invocation was succeeded.
// wait P2P_GROUP_STARTED_EVENT.
@@ -1286,6 +1328,8 @@
handleGroupCreationFailure();
transitionTo(mInactiveState);
}
+ } else if (status == P2pStatus.NO_COMMON_CHANNEL) {
+ transitionTo(mFrequencyConflictState);
} else {
handleGroupCreationFailure();
transitionTo(mInactiveState);
@@ -1298,7 +1342,90 @@
}
}
+ class FrequencyConflictState extends State {
+ private AlertDialog mFrequencyConflictDialog;
+ @Override
+ public void enter() {
+ if (DBG) logd(getName());
+ notifyFrequencyConflict();
+ }
+ private void notifyFrequencyConflict() {
+ logd("Notify frequency conflict");
+ Resources r = Resources.getSystem();
+
+ AlertDialog dialog = new AlertDialog.Builder(mContext)
+ .setMessage(r.getString(R.string.wifi_p2p_frequency_conflict_message,
+ getDeviceName(mSavedPeerConfig.deviceAddress)))
+ .setPositiveButton(r.getString(R.string.dlg_ok), new OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ sendMessage(DROP_WIFI_USER_ACCEPT);
+ }
+ })
+ .setNegativeButton(r.getString(R.string.decline), new OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ sendMessage(DROP_WIFI_USER_REJECT);
+ }
+ })
+ .setOnCancelListener(new DialogInterface.OnCancelListener() {
+ @Override
+ public void onCancel(DialogInterface arg0) {
+ sendMessage(DROP_WIFI_USER_REJECT);
+ }
+ })
+ .create();
+
+ dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
+ dialog.show();
+ mFrequencyConflictDialog = dialog;
+ }
+
+ @Override
+ public boolean processMessage(Message message) {
+ if (DBG) logd(getName() + message.toString());
+ switch (message.what) {
+ case WifiMonitor.P2P_GO_NEGOTIATION_SUCCESS_EVENT:
+ case WifiMonitor.P2P_GROUP_FORMATION_SUCCESS_EVENT:
+ loge(getName() + "group sucess during freq conflict!");
+ break;
+ case WifiMonitor.P2P_GROUP_STARTED_EVENT:
+ loge(getName() + "group started after freq conflict, handle anyway");
+ deferMessage(message);
+ transitionTo(mGroupNegotiationState);
+ break;
+ case WifiMonitor.P2P_GO_NEGOTIATION_FAILURE_EVENT:
+ case WifiMonitor.P2P_GROUP_REMOVED_EVENT:
+ case WifiMonitor.P2P_GROUP_FORMATION_FAILURE_EVENT:
+ // Ignore failures since we retry again
+ break;
+ case DROP_WIFI_USER_REJECT:
+ // User rejected dropping wifi in favour of p2p
+ handleGroupCreationFailure();
+ transitionTo(mInactiveState);
+ break;
+ case DROP_WIFI_USER_ACCEPT:
+ // User accepted dropping wifi in favour of p2p
+ mWifiChannel.sendMessage(WifiP2pService.DISCONNECT_WIFI_REQUEST, 1);
+ mTempoarilyDisconnectedWifi = true;
+ break;
+ case DISCONNECT_WIFI_RESPONSE:
+ // Got a response from wifistatemachine, retry p2p
+ if (DBG) logd(getName() + "Wifi disconnected, retry p2p");
+ transitionTo(mInactiveState);
+ sendMessage(WifiP2pManager.CONNECT, mSavedPeerConfig);
+ break;
+ default:
+ return NOT_HANDLED;
+ }
+ return HANDLED;
+ }
+
+ public void exit() {
+ if (mFrequencyConflictDialog != null) mFrequencyConflictDialog.dismiss();
+ }
+ }
class GroupCreatedState extends State {
@Override
@@ -1401,7 +1528,8 @@
device = (WifiP2pDevice) message.obj;
//Device loss for a connected device indicates it is not in discovery any more
if (mGroup.contains(device)) {
- if (DBG) logd("Lost " + device +" , do nothing");
+ if (DBG) logd("Add device to lost list " + device);
+ mPeersLostDuringConnection.update(device);
return HANDLED;
}
// Do the regular device lost handling
@@ -1853,7 +1981,7 @@
private int connect(WifiP2pConfig config, boolean tryInvocation) {
if (config == null) {
- loge("invalid argument.");
+ loge("config is null");
return CONNECT_FAILURE;
}
@@ -1863,7 +1991,7 @@
WifiP2pDevice dev = mPeers.get(config.deviceAddress);
if (dev == null) {
- loge("target device is not found.");
+ loge("target device not found " + config.deviceAddress);
return CONNECT_FAILURE;
}
@@ -2142,6 +2270,8 @@
/* After cancelling group formation, new connections on existing peers can fail
* at supplicant. Flush and restart discovery */
mWifiNative.p2pFlush();
+ if (mPeers.remove(mPeersLostDuringConnection)) sendP2pPeersChangedBroadcast();
+ mPeersLostDuringConnection.clear();
mServiceDiscReqId = null;
sendMessage(WifiP2pManager.DISCOVER_PEERS);
}
@@ -2174,8 +2304,15 @@
mGroup = null;
mWifiNative.p2pFlush();
+ if (mPeers.remove(mPeersLostDuringConnection)) sendP2pPeersChangedBroadcast();
+ mPeersLostDuringConnection.clear();
mServiceDiscReqId = null;
if (changed) sendP2pPeersChangedBroadcast();
+
+ if (mTempoarilyDisconnectedWifi) {
+ mWifiChannel.sendMessage(WifiP2pService.DISCONNECT_WIFI_REQUEST, 0);
+ mTempoarilyDisconnectedWifi = false;
+ }
}
//State machine initiated requests can have replyTo set to null indicating