Merge "Fix bug 6688060: breakage in AndroidCharacter.mirror"
diff --git a/Android.mk b/Android.mk
index 095662c..235ee96 100644
--- a/Android.mk
+++ b/Android.mk
@@ -193,6 +193,7 @@
location/java/android/location/INetInitiatedListener.aidl \
media/java/android/media/IAudioService.aidl \
media/java/android/media/IAudioFocusDispatcher.aidl \
+ media/java/android/media/IAudioRoutesObserver.aidl \
media/java/android/media/IMediaScannerListener.aidl \
media/java/android/media/IMediaScannerService.aidl \
media/java/android/media/IRemoteControlClient.aidl \
diff --git a/api/16.txt b/api/16.txt
index e4b098f..70c4032 100644
--- a/api/16.txt
+++ b/api/16.txt
@@ -11566,6 +11566,8 @@
method public java.lang.CharSequence getName(android.content.Context);
method public java.lang.CharSequence getStatus();
method public int getSupportedTypes();
+ method public java.lang.Object getTag();
+ method public void setTag(java.lang.Object);
}
public static class MediaRouter.SimpleCallback extends android.media.MediaRouter.Callback {
@@ -11580,14 +11582,12 @@
}
public static class MediaRouter.UserRouteInfo extends android.media.MediaRouter.RouteInfo {
- method public java.lang.Object getTag();
method public void setIconDrawable(android.graphics.drawable.Drawable);
method public void setIconResource(int);
method public void setName(java.lang.CharSequence);
method public void setName(int);
method public void setRemoteControlClient(android.media.RemoteControlClient);
method public void setStatus(java.lang.CharSequence);
- method public void setTag(java.lang.Object);
}
public class MediaScannerConnection implements android.content.ServiceConnection {
@@ -17372,6 +17372,8 @@
field public static final android.net.Uri CONTENT_URI;
field public static final java.lang.String NORMALIZED_NUMBER = "data4";
field public static final java.lang.String NUMBER = "data1";
+ field public static final java.lang.String SEARCH_DISPLAY_NAME_KEY = "search_display_name";
+ field public static final java.lang.String SEARCH_PHONE_NUMBER_KEY = "search_phone_number";
field public static final int TYPE_ASSISTANT = 19; // 0x13
field public static final int TYPE_CALLBACK = 8; // 0x8
field public static final int TYPE_CAR = 9; // 0x9
@@ -24374,12 +24376,6 @@
method protected boolean verifyDrawable(android.graphics.drawable.Drawable);
method public boolean willNotCacheDrawing();
method public boolean willNotDraw();
- field public static final int ACCESSIBILITY_FOCUS_BACKWARD = 4097; // 0x1001
- field public static final int ACCESSIBILITY_FOCUS_DOWN = 4226; // 0x1082
- field public static final int ACCESSIBILITY_FOCUS_FORWARD = 4098; // 0x1002
- field public static final int ACCESSIBILITY_FOCUS_LEFT = 4113; // 0x1011
- field public static final int ACCESSIBILITY_FOCUS_RIGHT = 4162; // 0x1042
- field public static final int ACCESSIBILITY_FOCUS_UP = 4129; // 0x1021
field public static final android.util.Property ALPHA;
field public static final int DRAWING_CACHE_QUALITY_AUTO = 0; // 0x0
field public static final int DRAWING_CACHE_QUALITY_HIGH = 1048576; // 0x100000
@@ -24401,7 +24397,6 @@
field protected static final int[] FOCUSED_SELECTED_WINDOW_FOCUSED_STATE_SET;
field protected static final int[] FOCUSED_STATE_SET;
field protected static final int[] FOCUSED_WINDOW_FOCUSED_STATE_SET;
- field public static final int FOCUS_ACCESSIBILITY = 4096; // 0x1000
field public static final int FOCUS_BACKWARD = 1; // 0x1
field public static final int FOCUS_DOWN = 130; // 0x82
field public static final int FOCUS_FORWARD = 2; // 0x2
@@ -25348,9 +25343,7 @@
public abstract class AccessibilityNodeProvider {
ctor public AccessibilityNodeProvider();
- method public android.view.accessibility.AccessibilityNodeInfo accessibilityFocusSearch(int, int);
method public android.view.accessibility.AccessibilityNodeInfo createAccessibilityNodeInfo(int);
- method public android.view.accessibility.AccessibilityNodeInfo findAccessibilityFocus(int);
method public java.util.List<android.view.accessibility.AccessibilityNodeInfo> findAccessibilityNodeInfosByText(java.lang.String, int);
method public boolean performAction(int, int, android.os.Bundle);
}
diff --git a/api/current.txt b/api/current.txt
index f15e17b..89f265d 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -11598,6 +11598,7 @@
}
public static class MediaRouter.UserRouteInfo extends android.media.MediaRouter.RouteInfo {
+ method public android.media.RemoteControlClient getRemoteControlClient();
method public void setIconDrawable(android.graphics.drawable.Drawable);
method public void setIconResource(int);
method public void setName(java.lang.CharSequence);
@@ -17388,6 +17389,8 @@
field public static final android.net.Uri CONTENT_URI;
field public static final java.lang.String NORMALIZED_NUMBER = "data4";
field public static final java.lang.String NUMBER = "data1";
+ field public static final java.lang.String SEARCH_DISPLAY_NAME_KEY = "search_display_name";
+ field public static final java.lang.String SEARCH_PHONE_NUMBER_KEY = "search_phone_number";
field public static final int TYPE_ASSISTANT = 19; // 0x13
field public static final int TYPE_CALLBACK = 8; // 0x8
field public static final int TYPE_CAR = 9; // 0x9
@@ -22835,10 +22838,18 @@
public abstract class ActionProvider {
ctor public ActionProvider(android.content.Context);
method public boolean hasSubMenu();
+ method public boolean isVisible();
method public abstract deprecated android.view.View onCreateActionView();
method public android.view.View onCreateActionView(android.view.MenuItem);
method public boolean onPerformDefaultAction();
method public void onPrepareSubMenu(android.view.SubMenu);
+ method public boolean overridesItemVisibility();
+ method public void refreshVisibility();
+ method public void setVisibilityListener(android.view.ActionProvider.VisibilityListener);
+ }
+
+ public static abstract interface ActionProvider.VisibilityListener {
+ method public abstract void onActionProviderVisibilityChanged(boolean);
}
public final class Choreographer {
@@ -24433,12 +24444,6 @@
method protected boolean verifyDrawable(android.graphics.drawable.Drawable);
method public boolean willNotCacheDrawing();
method public boolean willNotDraw();
- field public static final int ACCESSIBILITY_FOCUS_BACKWARD = 4097; // 0x1001
- field public static final int ACCESSIBILITY_FOCUS_DOWN = 4226; // 0x1082
- field public static final int ACCESSIBILITY_FOCUS_FORWARD = 4098; // 0x1002
- field public static final int ACCESSIBILITY_FOCUS_LEFT = 4113; // 0x1011
- field public static final int ACCESSIBILITY_FOCUS_RIGHT = 4162; // 0x1042
- field public static final int ACCESSIBILITY_FOCUS_UP = 4129; // 0x1021
field public static final android.util.Property ALPHA;
field public static final int DRAWING_CACHE_QUALITY_AUTO = 0; // 0x0
field public static final int DRAWING_CACHE_QUALITY_HIGH = 1048576; // 0x100000
@@ -24460,7 +24465,6 @@
field protected static final int[] FOCUSED_SELECTED_WINDOW_FOCUSED_STATE_SET;
field protected static final int[] FOCUSED_STATE_SET;
field protected static final int[] FOCUSED_WINDOW_FOCUSED_STATE_SET;
- field public static final int FOCUS_ACCESSIBILITY = 4096; // 0x1000
field public static final int FOCUS_BACKWARD = 1; // 0x1
field public static final int FOCUS_DOWN = 130; // 0x82
field public static final int FOCUS_FORWARD = 2; // 0x2
@@ -25431,9 +25435,7 @@
public abstract class AccessibilityNodeProvider {
ctor public AccessibilityNodeProvider();
- method public android.view.accessibility.AccessibilityNodeInfo accessibilityFocusSearch(int, int);
method public android.view.accessibility.AccessibilityNodeInfo createAccessibilityNodeInfo(int);
- method public android.view.accessibility.AccessibilityNodeInfo findAccessibilityFocus(int);
method public java.util.List<android.view.accessibility.AccessibilityNodeInfo> findAccessibilityNodeInfosByText(java.lang.String, int);
method public boolean performAction(int, int, android.os.Bundle);
}
diff --git a/cmds/installd/commands.c b/cmds/installd/commands.c
index b8a78de..1bb4935 100644
--- a/cmds/installd/commands.c
+++ b/cmds/installd/commands.c
@@ -57,19 +57,6 @@
unlink(pkgdir);
return -errno;
}
- if (chown(pkgdir, uid, gid) < 0) {
- ALOGE("cannot chown dir '%s': %s\n", pkgdir, strerror(errno));
- unlink(pkgdir);
- return -errno;
- }
-
-#ifdef HAVE_SELINUX
- if (selinux_android_setfilecon(pkgdir, pkgname, uid) < 0) {
- LOGE("cannot setfilecon dir '%s': %s\n", pkgdir, strerror(errno));
- unlink(pkgdir);
- return -errno;
- }
-#endif
if (mkdir(libdir, 0755) < 0) {
ALOGE("cannot create dir '%s': %s\n", libdir, strerror(errno));
@@ -98,6 +85,22 @@
}
#endif
+ if (chown(pkgdir, uid, gid) < 0) {
+ ALOGE("cannot chown dir '%s': %s\n", pkgdir, strerror(errno));
+ unlink(libdir);
+ unlink(pkgdir);
+ return -errno;
+ }
+
+#ifdef HAVE_SELINUX
+ if (selinux_android_setfilecon(pkgdir, pkgname, uid) < 0) {
+ LOGE("cannot setfilecon dir '%s': %s\n", pkgdir, strerror(errno));
+ unlink(libdir);
+ unlink(pkgdir);
+ return -errno;
+ }
+#endif
+
return 0;
}
diff --git a/cmds/rawbu/backup.cpp b/cmds/rawbu/backup.cpp
index 9ea046d..70e7b57 100644
--- a/cmds/rawbu/backup.cpp
+++ b/cmds/rawbu/backup.cpp
@@ -38,6 +38,7 @@
static struct stat statBuffer;
static char copyBuffer[8192];
+static char *backupFilePath = NULL;
static uint32_t inputFileVersion;
@@ -152,6 +153,10 @@
strcat(nameBuffer, "/");
} else {
+ // Don't delete the backup file
+ if (backupFilePath && strcmp(backupFilePath, nameBuffer) == 0) {
+ continue;
+ }
ret = unlink(nameBuffer);
if (ret != 0) {
@@ -279,7 +284,7 @@
continue;
}
- if (fullPath == NULL) {
+ if (fullPath != NULL) {
free(fullPath);
}
fullPath = (char*)malloc(srcLen + strlen(de->d_name) + 2);
@@ -320,8 +325,13 @@
goto done;
}
} else if (S_ISREG(statBuffer.st_mode)) {
- printf("Saving file %s...\n", fullPath);
-
+ // Skip the backup file
+ if (backupFilePath && strcmp(fullPath, backupFilePath) == 0) {
+ printf("Skipping backup file %s...\n", backupFilePath);
+ continue;
+ } else {
+ printf("Saving file %s...\n", fullPath);
+ }
if (write_header(fh, TYPE_FILE, fullPath, &statBuffer) == 0) {
result = 0;
goto done;
@@ -373,6 +383,9 @@
printf("Backing up /data to %s...\n", destPath);
+ // The path that shouldn't be backed up
+ backupFilePath = strdup(destPath);
+
if (!write_int32(fh, FILE_VERSION)) goto done;
if (!write_int32(fh, opt_backupAll)) goto done;
if (!backup_dir(fh, "/data")) goto done;
@@ -509,6 +522,9 @@
} else {
opt_backupAll = 0;
}
+
+ // The path that shouldn't be deleted
+ backupFilePath = strdup(srcPath);
printf("Wiping contents of /data...\n");
if (!wipe("/data")) {
diff --git a/core/java/android/accounts/AccountManager.java b/core/java/android/accounts/AccountManager.java
index 39e83e0..f3c6566 100644
--- a/core/java/android/accounts/AccountManager.java
+++ b/core/java/android/accounts/AccountManager.java
@@ -1916,7 +1916,8 @@
*
* <p>It is safe to call this method from the main thread.
*
- * <p>No permission is required to call this method.
+ * <p>This method requires the caller to hold the permission
+ * {@link android.Manifest.permission#GET_ACCOUNTS}.
*
* @param listener The listener to send notifications to
* @param handler {@link Handler} identifying the thread to use
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java
index b902550..5e21403 100644
--- a/core/java/android/app/ContextImpl.java
+++ b/core/java/android/app/ContextImpl.java
@@ -1187,6 +1187,9 @@
@Override
public boolean bindService(Intent service, ServiceConnection conn, int flags, int userId) {
IServiceConnection sd;
+ if (conn == null) {
+ throw new IllegalArgumentException("connection is null");
+ }
if (mPackageInfo != null) {
sd = mPackageInfo.getServiceDispatcher(conn, getOuterContext(),
mMainThread.getHandler(), flags);
@@ -1217,6 +1220,9 @@
@Override
public void unbindService(ServiceConnection conn) {
+ if (conn == null) {
+ throw new IllegalArgumentException("connection is null");
+ }
if (mPackageInfo != null) {
IServiceConnection sd = mPackageInfo.forgetServiceDispatcher(
getOuterContext(), conn);
diff --git a/core/java/android/app/DownloadManager.java b/core/java/android/app/DownloadManager.java
index 93f732c..17700f9 100644
--- a/core/java/android/app/DownloadManager.java
+++ b/core/java/android/app/DownloadManager.java
@@ -51,6 +51,9 @@
* Apps that request downloads through this API should register a broadcast receiver for
* {@link #ACTION_NOTIFICATION_CLICKED} to appropriately handle when the user clicks on a running
* download in a notification or from the downloads UI.
+ *
+ * Note that the application must have the {@link android.Manifest.permission#INTERNET}
+ * permission to use this class.
*/
public class DownloadManager {
diff --git a/core/java/android/app/KeyguardManager.java b/core/java/android/app/KeyguardManager.java
index a79a8fc..ef61af7 100644
--- a/core/java/android/app/KeyguardManager.java
+++ b/core/java/android/app/KeyguardManager.java
@@ -62,6 +62,9 @@
* Note: This call has no effect while any {@link android.app.admin.DevicePolicyManager}
* is enabled that requires a password.
*
+ * <p>This method requires the caller to hold the permission
+ * {@link android.Manifest.permission#DISABLE_KEYGUARD}.
+ *
* @see #reenableKeyguard()
*/
public void disableKeyguard() {
@@ -80,6 +83,9 @@
* Note: This call has no effect while any {@link android.app.admin.DevicePolicyManager}
* is enabled that requires a password.
*
+ * <p>This method requires the caller to hold the permission
+ * {@link android.Manifest.permission#DISABLE_KEYGUARD}.
+ *
* @see #disableKeyguard()
*/
public void reenableKeyguard() {
@@ -188,6 +194,9 @@
* This will, if the keyguard is secure, bring up the unlock screen of
* the keyguard.
*
+ * <p>This method requires the caller to hold the permission
+ * {@link android.Manifest.permission#DISABLE_KEYGUARD}.
+ *
* @param callback Let's you know whether the operation was succesful and
* it is safe to launch anything that would normally be considered safe
* once the user has gotten past the keyguard.
diff --git a/core/java/android/app/MediaRouteActionProvider.java b/core/java/android/app/MediaRouteActionProvider.java
index 4860182..c2f5ac1 100644
--- a/core/java/android/app/MediaRouteActionProvider.java
+++ b/core/java/android/app/MediaRouteActionProvider.java
@@ -27,6 +27,8 @@
import android.view.MenuItem;
import android.view.View;
+import java.lang.ref.WeakReference;
+
public class MediaRouteActionProvider extends ActionProvider {
private static final String TAG = "MediaRouteActionProvider";
@@ -35,13 +37,14 @@
private MenuItem mMenuItem;
private MediaRouteButton mView;
private int mRouteTypes;
- private final RouterCallback mRouterCallback = new RouterCallback();
private View.OnClickListener mExtendedSettingsListener;
+ private RouterCallback mCallback;
public MediaRouteActionProvider(Context context) {
super(context);
mContext = context;
mRouter = (MediaRouter) context.getSystemService(Context.MEDIA_ROUTER_SERVICE);
+ mCallback = new RouterCallback(this);
// Start with live audio by default.
// TODO Update this when new route types are added; segment by API level
@@ -50,18 +53,17 @@
}
public void setRouteTypes(int types) {
- if (types == mRouteTypes) {
- // Already registered; nothing to do.
- return;
- }
+ if (mRouteTypes == types) return;
if (mRouteTypes != 0) {
- mRouter.removeCallback(mRouterCallback);
+ mRouter.removeCallback(mCallback);
}
mRouteTypes = types;
+ if (types != 0) {
+ mRouter.addCallback(types, mCallback);
+ }
if (mView != null) {
mView.setRouteTypes(mRouteTypes);
}
- mRouter.addCallback(types, mRouterCallback);
}
@Override
@@ -78,7 +80,6 @@
}
mMenuItem = item;
mView = new MediaRouteButton(mContext);
- mMenuItem.setVisible(mRouter.getRouteCount() > 1);
mView.setRouteTypes(mRouteTypes);
mView.setExtendedSettingsClickListener(mExtendedSettingsListener);
return mView;
@@ -124,15 +125,43 @@
}
}
- private class RouterCallback extends MediaRouter.SimpleCallback {
+ @Override
+ public boolean overridesItemVisibility() {
+ return true;
+ }
+
+ @Override
+ public boolean isVisible() {
+ return mRouter.getRouteCount() > 1;
+ }
+
+ private static class RouterCallback extends MediaRouter.SimpleCallback {
+ private WeakReference<MediaRouteActionProvider> mAp;
+
+ RouterCallback(MediaRouteActionProvider ap) {
+ mAp = new WeakReference<MediaRouteActionProvider>(ap);
+ }
+
@Override
public void onRouteAdded(MediaRouter router, RouteInfo info) {
- mMenuItem.setVisible(mRouter.getRouteCount() > 1);
+ final MediaRouteActionProvider ap = mAp.get();
+ if (ap == null) {
+ router.removeCallback(this);
+ return;
+ }
+
+ ap.refreshVisibility();
}
@Override
public void onRouteRemoved(MediaRouter router, RouteInfo info) {
- mMenuItem.setVisible(mRouter.getRouteCount() > 1);
+ final MediaRouteActionProvider ap = mAp.get();
+ if (ap == null) {
+ router.removeCallback(this);
+ return;
+ }
+
+ ap.refreshVisibility();
}
}
}
diff --git a/core/java/android/app/WallpaperManager.java b/core/java/android/app/WallpaperManager.java
index 3824f44..c131549 100644
--- a/core/java/android/app/WallpaperManager.java
+++ b/core/java/android/app/WallpaperManager.java
@@ -468,6 +468,9 @@
* wallpaper; it must be a valid PNG or JPEG image. On success, the intent
* {@link Intent#ACTION_WALLPAPER_CHANGED} is broadcast.
*
+ * <p>This method requires the caller to hold the permission
+ * {@link android.Manifest.permission#SET_WALLPAPER}.
+ *
* @param resid The bitmap to save.
*
* @throws IOException If an error occurs reverting to the default
@@ -504,6 +507,9 @@
* converted to a PNG and stored as the wallpaper. On success, the intent
* {@link Intent#ACTION_WALLPAPER_CHANGED} is broadcast.
*
+ * <p>This method requires the caller to hold the permission
+ * {@link android.Manifest.permission#SET_WALLPAPER}.
+ *
* @param bitmap The bitmap to save.
*
* @throws IOException If an error occurs reverting to the default
@@ -540,6 +546,9 @@
* image. On success, the intent {@link Intent#ACTION_WALLPAPER_CHANGED}
* is broadcast.
*
+ * <p>This method requires the caller to hold the permission
+ * {@link android.Manifest.permission#SET_WALLPAPER}.
+ *
* @param data A stream containing the raw data to install as a wallpaper.
*
* @throws IOException If an error occurs reverting to the default
@@ -645,6 +654,9 @@
* <b>retrieve</b> the suggested size so they can construct a wallpaper
* that matches it.
*
+ * <p>This method requires the caller to hold the permission
+ * {@link android.Manifest.permission#SET_WALLPAPER_HINTS}.
+ *
* @param minimumWidth Desired minimum width
* @param minimumHeight Desired minimum height
*/
@@ -746,6 +758,9 @@
* wallpaper. On success, the intent {@link Intent#ACTION_WALLPAPER_CHANGED}
* is broadcast.
*
+ * <p>This method requires the caller to hold the permission
+ * {@link android.Manifest.permission#SET_WALLPAPER}.
+ *
* @throws IOException If an error occurs reverting to the default
* wallpaper.
*/
diff --git a/core/java/android/content/ContentResolver.java b/core/java/android/content/ContentResolver.java
index 34b5a30..0a5a26a9 100644
--- a/core/java/android/content/ContentResolver.java
+++ b/core/java/android/content/ContentResolver.java
@@ -1415,6 +1415,8 @@
/**
* Check if the provider should be synced when a network tickle is received
+ * <p>This method requires the caller to hold the permission
+ * {@link android.Manifest.permission#READ_SYNC_SETTINGS}.
*
* @param account the account whose setting we are querying
* @param authority the provider whose setting we are querying
@@ -1430,6 +1432,8 @@
/**
* Set whether or not the provider is synced when it receives a network tickle.
+ * <p>This method requires the caller to hold the permission
+ * {@link android.Manifest.permission#WRITE_SYNC_SETTINGS}.
*
* @param account the account whose setting we are querying
* @param authority the provider whose behavior is being controlled
@@ -1461,6 +1465,9 @@
* {@link #SYNC_EXTRAS_EXPEDITED}, {@link #SYNC_EXTRAS_MANUAL} set to true.
* If any are supplied then an {@link IllegalArgumentException} will be thrown.
*
+ * <p>This method requires the caller to hold the permission
+ * {@link android.Manifest.permission#WRITE_SYNC_SETTINGS}.
+ *
* @param account the account to specify in the sync
* @param authority the provider to specify in the sync request
* @param extras extra parameters to go along with the sync request
@@ -1497,6 +1504,8 @@
/**
* Remove a periodic sync. Has no affect if account, authority and extras don't match
* an existing periodic sync.
+ * <p>This method requires the caller to hold the permission
+ * {@link android.Manifest.permission#WRITE_SYNC_SETTINGS}.
*
* @param account the account of the periodic sync to remove
* @param authority the provider of the periodic sync to remove
@@ -1519,6 +1528,8 @@
/**
* Get the list of information about the periodic syncs for the given account and authority.
+ * <p>This method requires the caller to hold the permission
+ * {@link android.Manifest.permission#READ_SYNC_SETTINGS}.
*
* @param account the account whose periodic syncs we are querying
* @param authority the provider whose periodic syncs we are querying
@@ -1540,6 +1551,8 @@
/**
* Check if this account/provider is syncable.
+ * <p>This method requires the caller to hold the permission
+ * {@link android.Manifest.permission#READ_SYNC_SETTINGS}.
* @return >0 if it is syncable, 0 if not, and <0 if the state isn't known yet.
*/
public static int getIsSyncable(Account account, String authority) {
@@ -1552,6 +1565,8 @@
/**
* Set whether this account/provider is syncable.
+ * <p>This method requires the caller to hold the permission
+ * {@link android.Manifest.permission#WRITE_SYNC_SETTINGS}.
* @param syncable >0 denotes syncable, 0 means not syncable, <0 means unknown
*/
public static void setIsSyncable(Account account, String authority, int syncable) {
@@ -1566,6 +1581,8 @@
/**
* Gets the master auto-sync setting that applies to all the providers and accounts.
* If this is false then the per-provider auto-sync setting is ignored.
+ * <p>This method requires the caller to hold the permission
+ * {@link android.Manifest.permission#READ_SYNC_SETTINGS}.
*
* @return the master auto-sync setting that applies to all the providers and accounts
*/
@@ -1580,6 +1597,8 @@
/**
* Sets the master auto-sync setting that applies to all the providers and accounts.
* If this is false then the per-provider auto-sync setting is ignored.
+ * <p>This method requires the caller to hold the permission
+ * {@link android.Manifest.permission#WRITE_SYNC_SETTINGS}.
*
* @param sync the master auto-sync setting that applies to all the providers and accounts
*/
@@ -1595,6 +1614,8 @@
/**
* Returns true if there is currently a sync operation for the given
* account or authority in the pending list, or actively being processed.
+ * <p>This method requires the caller to hold the permission
+ * {@link android.Manifest.permission#READ_SYNC_STATS}.
* @param account the account whose setting we are querying
* @param authority the provider whose behavior is being queried
* @return true if a sync is active for the given account or authority.
@@ -1610,6 +1631,9 @@
/**
* If a sync is active returns the information about it, otherwise returns null.
* <p>
+ * This method requires the caller to hold the permission
+ * {@link android.Manifest.permission#READ_SYNC_STATS}.
+ * <p>
* @return the SyncInfo for the currently active sync or null if one is not active.
* @deprecated
* Since multiple concurrent syncs are now supported you should use
@@ -1633,6 +1657,10 @@
/**
* Returns a list with information about all the active syncs. This list will be empty
* if there are no active syncs.
+ * <p>
+ * This method requires the caller to hold the permission
+ * {@link android.Manifest.permission#READ_SYNC_STATS}.
+ * <p>
* @return a List of SyncInfo objects for the currently active syncs.
*/
public static List<SyncInfo> getCurrentSyncs() {
@@ -1660,6 +1688,8 @@
/**
* Return true if the pending status is true of any matching authorities.
+ * <p>This method requires the caller to hold the permission
+ * {@link android.Manifest.permission#READ_SYNC_STATS}.
* @param account the account whose setting we are querying
* @param authority the provider whose behavior is being queried
* @return true if there is a pending sync with the matching account and authority
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index 7588cda..2800930 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -813,6 +813,8 @@
/**
* @deprecated Use {@link android.app.WallpaperManager#setBitmap(Bitmap)
* WallpaperManager.set()} instead.
+ * <p>This method requires the caller to hold the permission
+ * {@link android.Manifest.permission#SET_WALLPAPER}.
*/
@Deprecated
public abstract void setWallpaper(Bitmap bitmap) throws IOException;
@@ -820,6 +822,8 @@
/**
* @deprecated Use {@link android.app.WallpaperManager#setStream(InputStream)
* WallpaperManager.set()} instead.
+ * <p>This method requires the caller to hold the permission
+ * {@link android.Manifest.permission#SET_WALLPAPER}.
*/
@Deprecated
public abstract void setWallpaper(InputStream data) throws IOException;
@@ -827,6 +831,8 @@
/**
* @deprecated Use {@link android.app.WallpaperManager#clear
* WallpaperManager.clear()} instead.
+ * <p>This method requires the caller to hold the permission
+ * {@link android.Manifest.permission#SET_WALLPAPER}.
*/
@Deprecated
public abstract void clearWallpaper() throws IOException;
@@ -1373,6 +1379,7 @@
* description (action, category, etc) to match an
* {@link IntentFilter} published by a service.
* @param conn Receives information as the service is started and stopped.
+ * This must be a valid ServiceConnection object; it must not be null.
* @param flags Operation options for the binding. May be 0,
* {@link #BIND_AUTO_CREATE}, {@link #BIND_DEBUG_UNBIND},
* {@link #BIND_NOT_FOREGROUND}, {@link #BIND_ABOVE_CLIENT},
@@ -1408,7 +1415,7 @@
* stop at any time.
*
* @param conn The connection interface previously supplied to
- * bindService().
+ * bindService(). This parameter must not be null.
*
* @see #bindService
*/
diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java
index ef4209f..5f8793c 100644
--- a/core/java/android/net/ConnectivityManager.java
+++ b/core/java/android/net/ConnectivityManager.java
@@ -377,6 +377,8 @@
* this network is the default route for outgoing connections. You should
* always check {@link NetworkInfo#isConnected()} before initiating network
* traffic. This may return {@code null} when no networks are available.
+ * <p>This method requires the caller to hold the permission
+ * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
*/
public NetworkInfo getActiveNetworkInfo() {
try {
@@ -451,6 +453,8 @@
* Tells the underlying networking system that the caller wants to
* begin using the named feature. The interpretation of {@code feature}
* is completely up to each networking implementation.
+ * <p>This method requires the caller to hold the permission
+ * {@link android.Manifest.permission#CHANGE_NETWORK_STATE}.
* @param networkType specifies which network the request pertains to
* @param feature the name of the feature to be used
* @return an integer value representing the outcome of the request.
@@ -471,6 +475,8 @@
* Tells the underlying networking system that the caller is finished
* using the named feature. The interpretation of {@code feature}
* is completely up to each networking implementation.
+ * <p>This method requires the caller to hold the permission
+ * {@link android.Manifest.permission#CHANGE_NETWORK_STATE}.
* @param networkType specifies which network the request pertains to
* @param feature the name of the feature that is no longer needed
* @return an integer value representing the outcome of the request.
@@ -490,6 +496,8 @@
* Ensure that a network route exists to deliver traffic to the specified
* host via the specified network interface. An attempt to add a route that
* already exists is ignored, but treated as successful.
+ * <p>This method requires the caller to hold the permission
+ * {@link android.Manifest.permission#CHANGE_NETWORK_STATE}.
* @param networkType the type of the network over which traffic to the specified
* host is to be routed
* @param hostAddress the IP address of the host to which the route is desired
diff --git a/core/java/android/os/Vibrator.java b/core/java/android/os/Vibrator.java
index 3f783c9..b67be4b 100644
--- a/core/java/android/os/Vibrator.java
+++ b/core/java/android/os/Vibrator.java
@@ -43,6 +43,8 @@
/**
* Vibrate constantly for the specified period of time.
+ * <p>This method requires the caller to hold the permission
+ * {@link android.Manifest.permission#VIBRATE}.
*
* @param milliseconds The number of milliseconds to vibrate.
*/
@@ -61,6 +63,8 @@
* To cause the pattern to repeat, pass the index into the pattern array at which
* to start the repeat, or -1 to disable repeating.
* </p>
+ * <p>This method requires the caller to hold the permission
+ * {@link android.Manifest.permission#VIBRATE}.
*
* @param pattern an array of longs of times for which to turn the vibrator on or off.
* @param repeat the index into pattern at which to repeat, or -1 if
@@ -70,6 +74,8 @@
/**
* Turn the vibrator off.
+ * <p>This method requires the caller to hold the permission
+ * {@link android.Manifest.permission#VIBRATE}.
*/
public abstract void cancel();
}
diff --git a/core/java/android/provider/ContactsContract.java b/core/java/android/provider/ContactsContract.java
index e8f87bb..8e123ac 100644
--- a/core/java/android/provider/ContactsContract.java
+++ b/core/java/android/provider/ContactsContract.java
@@ -5416,6 +5416,20 @@
public static final Uri CONTENT_FILTER_URI = Uri.withAppendedPath(CONTENT_URI,
"filter");
+ /**
+ * A boolean query parameter that can be used with {@link #CONTENT_FILTER_URI}.
+ * If "1" or "true", display names are searched. If "0" or "false", display names
+ * are not searched. Default is "1".
+ */
+ public static final String SEARCH_DISPLAY_NAME_KEY = "search_display_name";
+
+ /**
+ * A boolean query parameter that can be used with {@link #CONTENT_FILTER_URI}.
+ * If "1" or "true", phone numbers are searched. If "0" or "false", phone numbers
+ * are not searched. Default is "1".
+ */
+ public static final String SEARCH_PHONE_NUMBER_KEY = "search_phone_number";
+
public static final int TYPE_HOME = 1;
public static final int TYPE_MOBILE = 2;
public static final int TYPE_WORK = 3;
diff --git a/core/java/android/text/MeasuredText.java b/core/java/android/text/MeasuredText.java
index 715d1f2..445aac63 100644
--- a/core/java/android/text/MeasuredText.java
+++ b/core/java/android/text/MeasuredText.java
@@ -82,6 +82,10 @@
return null;
}
+ void setPos(int pos) {
+ mPos = pos;
+ }
+
/**
* Analyzes text for bidirectional runs. Allocates working buffers.
*/
@@ -113,7 +117,7 @@
if (startInPara < 0) startInPara = 0;
if (endInPara > len) endInPara = len;
for (int j = startInPara; j < endInPara; j++) {
- mChars[j] = '\uFFFC';
+ mChars[j] = '\uFFFC'; // object replacement character
}
}
}
diff --git a/core/java/android/text/StaticLayout.java b/core/java/android/text/StaticLayout.java
index 6973b2e..6a619af 100644
--- a/core/java/android/text/StaticLayout.java
+++ b/core/java/android/text/StaticLayout.java
@@ -246,12 +246,17 @@
int width = firstWidth;
float w = 0;
+ // here is the offset of the starting character of the line we are currently measuring
int here = paraStart;
+ // ok is a character offset located after a word separator (space, tab, number...) where
+ // we would prefer to cut the current line. Equals to here when no such break was found.
int ok = paraStart;
float okWidth = w;
int okAscent = 0, okDescent = 0, okTop = 0, okBottom = 0;
+ // fit is a character offset such that the [here, fit[ range fits in the allowed width.
+ // We will cut the line there if no ok position is found.
int fit = paraStart;
float fitWidth = w;
int fitAscent = 0, fitDescent = 0, fitTop = 0, fitBottom = 0;
@@ -260,30 +265,22 @@
boolean hasTab = false;
TabStops tabStops = null;
- for (int spanStart = paraStart, spanEnd = spanStart, nextSpanStart;
- spanStart < paraEnd; spanStart = nextSpanStart) {
+ for (int spanStart = paraStart, spanEnd; spanStart < paraEnd; spanStart = spanEnd) {
- if (spanStart == spanEnd) {
- if (spanned == null)
- spanEnd = paraEnd;
- else
- spanEnd = spanned.nextSpanTransition(spanStart, paraEnd,
- MetricAffectingSpan.class);
-
+ if (spanned == null) {
+ spanEnd = paraEnd;
int spanLen = spanEnd - spanStart;
- if (spanned == null) {
- measured.addStyleRun(paint, spanLen, fm);
- } else {
- MetricAffectingSpan[] spans =
+ measured.addStyleRun(paint, spanLen, fm);
+ } else {
+ spanEnd = spanned.nextSpanTransition(spanStart, paraEnd,
+ MetricAffectingSpan.class);
+ int spanLen = spanEnd - spanStart;
+ MetricAffectingSpan[] spans =
spanned.getSpans(spanStart, spanEnd, MetricAffectingSpan.class);
- spans = TextUtils.removeEmptySpans(spans, spanned,
- MetricAffectingSpan.class);
- measured.addStyleRun(paint, spans, spanLen, fm);
- }
+ spans = TextUtils.removeEmptySpans(spans, spanned, MetricAffectingSpan.class);
+ measured.addStyleRun(paint, spans, spanLen, fm);
}
- nextSpanStart = spanEnd;
-
int fmTop = fm.top;
int fmBottom = fm.bottom;
int fmAscent = fm.ascent;
@@ -343,8 +340,6 @@
w += widths[j - paraStart];
}
- // Log.e("text", "was " + before + " now " + w + " after " + c + " within " + width);
-
if (w <= width) {
fitWidth = w;
fit = j + 1;
@@ -373,7 +368,6 @@
* except for NS (non-starters), which can be broken
* after but not before.
*/
-
if (c == CHAR_SPACE || c == CHAR_TAB ||
((c == CHAR_DOT || c == CHAR_COMMA ||
c == CHAR_COLON || c == CHAR_SEMICOLON) &&
@@ -437,17 +431,9 @@
needMultiply, chdirs, dir, easy, bufEnd, includepad, trackpad,
chs, widths, paraStart, ellipsize, ellipsizedWidth,
currentTextWidth, paint, moreChars);
+
here = endPos;
-
- if (here < spanStart) {
- // didn't output all the text for this span
- // we've measured the raw widths, though, so
- // just reset the start point
- j = nextSpanStart = here;
- } else {
- j = here - 1; // continue looping
- }
-
+ j = here - 1; // restart j-span loop from here, compensating for the j++
ok = fit = here;
w = 0;
fitAscent = fitDescent = fitTop = fitBottom = 0;
@@ -456,7 +442,16 @@
if (--firstWidthLineLimit <= 0) {
width = restWidth;
}
+
+ if (here < spanStart) {
+ // The text was cut before the beginning of the current span range.
+ // Exit the span loop, and get spanStart to start over from here.
+ measured.setPos(here);
+ spanEnd = here;
+ break;
+ }
}
+ // FIXME This should be moved in the above else block which changes mLineCount
if (mLineCount >= mMaximumVisibleLineCount) {
break;
}
diff --git a/core/java/android/view/AccessibilityInteractionController.java b/core/java/android/view/AccessibilityInteractionController.java
index 29926ca..0aabc44 100644
--- a/core/java/android/view/AccessibilityInteractionController.java
+++ b/core/java/android/view/AccessibilityInteractionController.java
@@ -480,7 +480,10 @@
// focus instead fetching all provider nodes to do the search here.
AccessibilityNodeProvider provider = host.getAccessibilityNodeProvider();
if (provider != null) {
- focused = provider.findAccessibilityFocus(virtualDescendantId);
+ if (mViewRootImpl.mAccessibilityFocusedVirtualView != null) {
+ focused = AccessibilityNodeInfo.obtain(
+ mViewRootImpl.mAccessibilityFocusedVirtualView);
+ }
} else if (virtualDescendantId == View.NO_ID) {
focused = host.createAccessibilityNodeInfo();
}
@@ -804,7 +807,6 @@
if (!(root instanceof ViewGroup)) {
return;
}
- ViewGroup rootGroup = (ViewGroup) root;
HashMap<View, AccessibilityNodeInfo> addedChildren =
new HashMap<View, AccessibilityNodeInfo>();
ArrayList<View> children = mTempViewList;
diff --git a/core/java/android/view/ActionProvider.java b/core/java/android/view/ActionProvider.java
index fa79d36..c3aafde 100644
--- a/core/java/android/view/ActionProvider.java
+++ b/core/java/android/view/ActionProvider.java
@@ -17,6 +17,7 @@
package android.view;
import android.content.Context;
+import android.util.Log;
/**
* An ActionProvider defines rich menu interaction in a single component.
@@ -55,7 +56,9 @@
* @see MenuItem#getActionProvider()
*/
public abstract class ActionProvider {
+ private static final String TAG = "ActionProvider";
private SubUiVisibilityListener mSubUiVisibilityListener;
+ private VisibilityListener mVisibilityListener;
/**
* Creates a new instance. ActionProvider classes should always implement a
@@ -96,6 +99,44 @@
}
/**
+ * The result of this method determines whether or not {@link #isVisible()} will be used
+ * by the {@link MenuItem} this ActionProvider is bound to help determine its visibility.
+ *
+ * @return true if this ActionProvider overrides the visibility of the MenuItem
+ * it is bound to, false otherwise. The default implementation returns false.
+ * @see #isVisible()
+ */
+ public boolean overridesItemVisibility() {
+ return false;
+ }
+
+ /**
+ * If {@link #overridesItemVisibility()} returns true, the return value of this method
+ * will help determine the visibility of the {@link MenuItem} this ActionProvider is bound to.
+ *
+ * <p>If the MenuItem's visibility is explicitly set to false by the application,
+ * the MenuItem will not be shown, even if this method returns true.</p>
+ *
+ * @return true if the MenuItem this ActionProvider is bound to is visible, false if
+ * it is invisible. The default implementation returns true.
+ */
+ public boolean isVisible() {
+ return true;
+ }
+
+ /**
+ * If this ActionProvider is associated with an item in a menu,
+ * refresh the visibility of the item based on {@link #overridesItemVisibility()} and
+ * {@link #isVisible()}. If {@link #overridesItemVisibility()} returns false, this call
+ * will have no effect.
+ */
+ public void refreshVisibility() {
+ if (mVisibilityListener != null && overridesItemVisibility()) {
+ mVisibilityListener.onActionProviderVisibilityChanged(isVisible());
+ }
+ }
+
+ /**
* Performs an optional default action.
* <p>
* For the case of an action provider placed in a menu item not shown as an action this
@@ -181,9 +222,34 @@
}
/**
+ * Set a listener to be notified when this ActionProvider's overridden visibility changes.
+ * This should only be used by MenuItem implementations.
+ *
+ * @param listener listener to set
+ */
+ public void setVisibilityListener(VisibilityListener listener) {
+ if (mVisibilityListener != null) {
+ Log.w(TAG, "setVisibilityListener: Setting a new ActionProvider.VisibilityListener " +
+ "when one is already set. Are you reusing this " + getClass().getSimpleName() +
+ " instance while it is still in use somewhere else?");
+ }
+ mVisibilityListener = listener;
+ }
+
+ /**
* @hide Internal use only
*/
public interface SubUiVisibilityListener {
public void onSubUiVisibilityChanged(boolean isVisible);
}
+
+ /**
+ * Listens to changes in visibility as reported by {@link ActionProvider#refreshVisibility()}.
+ *
+ * @see ActionProvider#overridesItemVisibility()
+ * @see ActionProvider#isVisible()
+ */
+ public interface VisibilityListener {
+ public void onActionProviderVisibilityChanged(boolean isVisible);
+ }
}
diff --git a/core/java/android/view/Choreographer.java b/core/java/android/view/Choreographer.java
index 4d1b836..78dc86f 100644
--- a/core/java/android/view/Choreographer.java
+++ b/core/java/android/view/Choreographer.java
@@ -79,16 +79,6 @@
// be dequeued.
private static final long DEFAULT_FRAME_DELAY = 10;
- // The fake vsync delay in milliseconds.
- // When the screen is off, we might not receive real vsync pulses from the hardware
- // which would cause posted Choreographer callbacks to not run. This is bad because
- // messages in the Looper might be blocked behind a barrier that is scheduled to be
- // removed by one of those Choreographer callback (see ViewRootImpl.doTraversals).
- // Until the barrier is removed, those messages will not run. To prevent starvation
- // of the Looper, we synthesize fake vsync pulses at a reduced rate whenever the
- // display hardware stops generating them.
- private static final long FAKE_VSYNC_DELAY = 100;
-
// The number of milliseconds between animation frames.
private static volatile long sFrameDelay = DEFAULT_FRAME_DELAY;
@@ -123,7 +113,6 @@
private static final int MSG_DO_FRAME = 0;
private static final int MSG_DO_SCHEDULE_VSYNC = 1;
private static final int MSG_DO_SCHEDULE_CALLBACK = 2;
- private static final int MSG_FAKE_VSYNC = 3;
// All frame callbacks posted by applications have this token.
private static final Object FRAME_CALLBACK_TOKEN = new Object() {
@@ -598,13 +587,6 @@
private void scheduleVsyncLocked() {
mDisplayEventReceiver.scheduleVsync();
-
- // Post a message to simulate a fake vsync pulse at a reduced rate in case the
- // display hardware stops generating them. This ensures that Choreographer
- // callbacks can continue to run even if the screen is off.
- Message msg = mHandler.obtainMessage(MSG_FAKE_VSYNC);
- msg.setAsynchronous(true);
- mHandler.sendMessageDelayed(msg, FAKE_VSYNC_DELAY);
}
private boolean isRunningOnLooperThreadLocked() {
@@ -680,12 +662,6 @@
case MSG_DO_SCHEDULE_CALLBACK:
doScheduleCallback(msg.arg1);
break;
- case MSG_FAKE_VSYNC:
- if (DEBUG) {
- Log.d(TAG, "Handling fake vsync while screen is off.");
- }
- doFrame(System.nanoTime(), 0);
- break;
}
}
}
@@ -707,17 +683,6 @@
// the message queue. If there are no messages in the queue with timestamps
// earlier than the frame time, then the vsync event will be processed immediately.
// Otherwise, messages that predate the vsync event will be handled first.
- if (mHavePendingVsync) {
- if (DEBUG) {
- Log.d(TAG, "Already have a pending vsync event. There should only be "
- + "one at a time but they can double up when a fake vsync "
- + "is handled in place of a real one.");
- }
- mHandler.removeCallbacks(this);
- } else {
- mHavePendingVsync = true;
- }
-
long now = System.nanoTime();
if (timestampNanos > now) {
Log.w(TAG, "Frame time is " + ((timestampNanos - now) * 0.000001f)
@@ -726,7 +691,12 @@
timestampNanos = now;
}
- mHandler.removeMessages(MSG_FAKE_VSYNC);
+ if (mHavePendingVsync) {
+ Log.w(TAG, "Already have a pending vsync event. There should only be "
+ + "one at a time.");
+ } else {
+ mHavePendingVsync = true;
+ }
mTimestampNanos = timestampNanos;
mFrame = frame;
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 672ff02..25f6516 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -1051,36 +1051,50 @@
/**
* The accessibility focus which is the current user position when
* interacting with the accessibility framework.
+ *
+ * @hide
*/
public static final int FOCUS_ACCESSIBILITY = 0x00001000;
/**
* Use with {@link #focusSearch(int)}. Move acessibility focus left.
+ *
+ * @hide
*/
public static final int ACCESSIBILITY_FOCUS_LEFT = FOCUS_LEFT | FOCUS_ACCESSIBILITY;
/**
* Use with {@link #focusSearch(int)}. Move acessibility focus up.
+ *
+ * @hide
*/
public static final int ACCESSIBILITY_FOCUS_UP = FOCUS_UP | FOCUS_ACCESSIBILITY;
/**
* Use with {@link #focusSearch(int)}. Move acessibility focus right.
+ *
+ * @hide
*/
public static final int ACCESSIBILITY_FOCUS_RIGHT = FOCUS_RIGHT | FOCUS_ACCESSIBILITY;
/**
* Use with {@link #focusSearch(int)}. Move acessibility focus down.
+ *
+ * @hide
*/
public static final int ACCESSIBILITY_FOCUS_DOWN = FOCUS_DOWN | FOCUS_ACCESSIBILITY;
/**
* Use with {@link #focusSearch(int)}. Move acessibility focus forward.
+ *
+ * @hide
*/
public static final int ACCESSIBILITY_FOCUS_FORWARD = FOCUS_FORWARD | FOCUS_ACCESSIBILITY;
/**
* Use with {@link #focusSearch(int)}. Move acessibility focus backward.
+ *
+ * @hide
*/
public static final int ACCESSIBILITY_FOCUS_BACKWARD = FOCUS_BACKWARD | FOCUS_ACCESSIBILITY;
@@ -4538,31 +4552,6 @@
if ((event.getEventType() & POPULATING_ACCESSIBILITY_EVENT_TYPES) != 0) {
dispatchPopulateAccessibilityEvent(event);
}
- // Intercept accessibility focus events fired by virtual nodes to keep
- // track of accessibility focus position in such nodes.
- final int eventType = event.getEventType();
- switch (eventType) {
- case AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED: {
- final long virtualNodeId = AccessibilityNodeInfo.getVirtualDescendantId(
- event.getSourceNodeId());
- if (virtualNodeId != AccessibilityNodeInfo.UNDEFINED) {
- ViewRootImpl viewRootImpl = getViewRootImpl();
- if (viewRootImpl != null) {
- viewRootImpl.setAccessibilityFocusedHost(this);
- }
- }
- } break;
- case AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUS_CLEARED: {
- final long virtualNodeId = AccessibilityNodeInfo.getVirtualDescendantId(
- event.getSourceNodeId());
- if (virtualNodeId != AccessibilityNodeInfo.UNDEFINED) {
- ViewRootImpl viewRootImpl = getViewRootImpl();
- if (viewRootImpl != null) {
- viewRootImpl.setAccessibilityFocusedHost(null);
- }
- }
- } break;
- }
// In the beginning we called #isShown(), so we know that getParent() is not null.
getParent().requestSendAccessibilityEvent(this, event);
}
@@ -6286,7 +6275,7 @@
mPrivateFlags2 |= ACCESSIBILITY_FOCUSED;
ViewRootImpl viewRootImpl = getViewRootImpl();
if (viewRootImpl != null) {
- viewRootImpl.setAccessibilityFocusedHost(this);
+ viewRootImpl.setAccessibilityFocus(this, null);
}
invalidate();
sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED);
@@ -6317,7 +6306,32 @@
if (viewRootImpl != null) {
View focusHost = viewRootImpl.getAccessibilityFocusedHost();
if (focusHost != null && ViewRootImpl.isViewDescendantOf(focusHost, this)) {
- viewRootImpl.setAccessibilityFocusedHost(null);
+ viewRootImpl.setAccessibilityFocus(null, null);
+ }
+ }
+ }
+
+ private void sendAccessibilityHoverEvent(int eventType) {
+ // Since we are not delivering to a client accessibility events from not
+ // important views (unless the clinet request that) we need to fire the
+ // event from the deepest view exposed to the client. As a consequence if
+ // the user crosses a not exposed view the client will see enter and exit
+ // of the exposed predecessor followed by and enter and exit of that same
+ // predecessor when entering and exiting the not exposed descendant. This
+ // is fine since the client has a clear idea which view is hovered at the
+ // price of a couple more events being sent. This is a simple and
+ // working solution.
+ View source = this;
+ while (true) {
+ if (source.includeForAccessibility()) {
+ source.sendAccessibilityEvent(eventType);
+ return;
+ }
+ ViewParent parent = source.getParent();
+ if (parent instanceof View) {
+ source = (View) parent;
+ } else {
+ return;
}
}
}
@@ -7891,20 +7905,19 @@
|| action == MotionEvent.ACTION_HOVER_MOVE)
&& !hasHoveredChild()
&& pointInView(event.getX(), event.getY())) {
- sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_HOVER_ENTER);
+ sendAccessibilityHoverEvent(AccessibilityEvent.TYPE_VIEW_HOVER_ENTER);
mSendingHoverAccessibilityEvents = true;
- requestAccessibilityFocusFromHover();
}
} else {
if (action == MotionEvent.ACTION_HOVER_EXIT
|| (action == MotionEvent.ACTION_MOVE
&& !pointInView(event.getX(), event.getY()))) {
mSendingHoverAccessibilityEvents = false;
- sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_HOVER_EXIT);
+ sendAccessibilityHoverEvent(AccessibilityEvent.TYPE_VIEW_HOVER_EXIT);
// If the window does not have input focus we take away accessibility
// focus as soon as the user stop hovering over the view.
if (mAttachInfo != null && !mAttachInfo.mHasWindowFocus) {
- getViewRootImpl().setAccessibilityFocusedHost(null);
+ getViewRootImpl().setAccessibilityFocus(null, null);
}
}
}
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 68c8bb7..17783a4 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -488,7 +488,7 @@
// Keep track of the actual window flags supplied by the client.
mClientWindowLayoutFlags = attrs.flags;
- setAccessibilityFocusedHost(null);
+ setAccessibilityFocus(null, null);
if (view instanceof RootViewSurfaceTaker) {
mSurfaceHolderCallback =
@@ -557,7 +557,7 @@
mInputChannel = null;
mFallbackEventHandler.setView(null);
unscheduleTraversals();
- setAccessibilityFocusedHost(null);
+ setAccessibilityFocus(null, null);
throw new RuntimeException("Adding window failed", e);
} finally {
if (restore) {
@@ -577,7 +577,7 @@
mAdded = false;
mFallbackEventHandler.setView(null);
unscheduleTraversals();
- setAccessibilityFocusedHost(null);
+ setAccessibilityFocus(null, null);
switch (res) {
case WindowManagerImpl.ADD_BAD_APP_TOKEN:
case WindowManagerImpl.ADD_BAD_SUBWINDOW_TOKEN:
@@ -2319,9 +2319,6 @@
}
} else {
if (mAccessibilityFocusedVirtualView == null) {
- mAccessibilityFocusedVirtualView = provider.findAccessibilityFocus(View.NO_ID);
- }
- if (mAccessibilityFocusedVirtualView == null) {
return;
}
mAccessibilityFocusedVirtualView.getBoundsInScreen(bounds);
@@ -2497,7 +2494,7 @@
return mAccessibilityFocusedVirtualView;
}
- void setAccessibilityFocusedHost(View host) {
+ void setAccessibilityFocus(View view, AccessibilityNodeInfo node) {
// If we have a virtual view with accessibility focus we need
// to clear the focus and invalidate the virtual view bounds.
if (mAccessibilityFocusedVirtualView != null) {
@@ -2525,24 +2522,16 @@
provider.performAction(virtualNodeId,
AccessibilityNodeInfo.ACTION_CLEAR_ACCESSIBILITY_FOCUS, null);
}
+ focusNode.recycle();
}
if (mAccessibilityFocusedHost != null) {
// Clear accessibility focus in the view.
mAccessibilityFocusedHost.clearAccessibilityFocusNoCallbacks();
}
- // Set the new focus host.
- mAccessibilityFocusedHost = host;
-
- // If the host has a provide find the virtual descendant that has focus.
- if (mAccessibilityFocusedHost != null) {
- AccessibilityNodeProvider provider =
- mAccessibilityFocusedHost.getAccessibilityNodeProvider();
- if (provider != null) {
- mAccessibilityFocusedVirtualView = provider.findAccessibilityFocus(View.NO_ID);
- return;
- }
- }
+ // Set the new focus host and node.
+ mAccessibilityFocusedHost = view;
+ mAccessibilityFocusedVirtualView = node;
}
public void requestChildFocus(View child, View focused) {
@@ -2628,7 +2617,7 @@
destroyHardwareRenderer();
- setAccessibilityFocusedHost(null);
+ setAccessibilityFocus(null, null);
mView = null;
mAttachInfo.mRootView = null;
@@ -2909,7 +2898,7 @@
mHasHadWindowFocus = true;
}
- setAccessibilityFocusedHost(null);
+ setAccessibilityFocus(null, null);
if (mView != null && mAccessibilityManager.isEnabled()) {
if (hasWindowFocus) {
@@ -2981,7 +2970,7 @@
invalidateDisplayLists();
} break;
case MSG_CLEAR_ACCESSIBILITY_FOCUS_HOST: {
- setAccessibilityFocusedHost(null);
+ setAccessibilityFocus(null, null);
} break;
case MSG_DISPATCH_DONE_ANIMATING: {
handleDispatchDoneAnimating();
@@ -4537,29 +4526,35 @@
if (mView == null) {
return false;
}
- // Watch for accessibility focus change events from virtual nodes
- // to keep track of accessibility focus being on a virtual node.
+ // Intercept accessibility focus events fired by virtual nodes to keep
+ // track of accessibility focus position in such nodes.
final int eventType = event.getEventType();
switch (eventType) {
case AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED: {
- final long sourceId = event.getSourceNodeId();
- // If the event is not from a virtual node we are not interested.
- final int virtualViewId = AccessibilityNodeInfo.getVirtualDescendantId(sourceId);
- if (virtualViewId == AccessibilityNodeInfo.UNDEFINED) {
- break;
+ final long sourceNodeId = event.getSourceNodeId();
+ final int accessibilityViewId = AccessibilityNodeInfo.getAccessibilityViewId(
+ sourceNodeId);
+ View source = mView.findViewByAccessibilityId(accessibilityViewId);
+ if (source != null) {
+ AccessibilityNodeProvider provider = source.getAccessibilityNodeProvider();
+ if (provider != null) {
+ AccessibilityNodeInfo node = provider.createAccessibilityNodeInfo(
+ AccessibilityNodeInfo.getVirtualDescendantId(sourceNodeId));
+ setAccessibilityFocus(source, node);
+ }
}
- final int realViewId = AccessibilityNodeInfo.getAccessibilityViewId(sourceId);
- View focusHost = mView.findViewByAccessibilityId(realViewId);
- setAccessibilityFocusedHost(focusHost);
} break;
case AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUS_CLEARED: {
- final long sourceId = event.getSourceNodeId();
- // If the event is not from a virtual node we are not interested.
- final int virtualViewId = AccessibilityNodeInfo.getVirtualDescendantId(sourceId);
- if (virtualViewId == AccessibilityNodeInfo.UNDEFINED) {
- break;
+ final long sourceNodeId = event.getSourceNodeId();
+ final int accessibilityViewId = AccessibilityNodeInfo.getAccessibilityViewId(
+ sourceNodeId);
+ View source = mView.findViewByAccessibilityId(accessibilityViewId);
+ if (source != null) {
+ AccessibilityNodeProvider provider = source.getAccessibilityNodeProvider();
+ if (provider != null) {
+ setAccessibilityFocus(null, null);
+ }
}
- setAccessibilityFocusedHost(null);
} break;
}
mAccessibilityManager.sendAccessibilityEvent(event);
diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java
index d94275b..e6a29ea 100644
--- a/core/java/android/view/WindowManager.java
+++ b/core/java/android/view/WindowManager.java
@@ -162,6 +162,7 @@
@ViewDebug.IntToString(from = TYPE_APPLICATION_MEDIA, to = "TYPE_APPLICATION_MEDIA"),
@ViewDebug.IntToString(from = TYPE_APPLICATION_SUB_PANEL, to = "TYPE_APPLICATION_SUB_PANEL"),
@ViewDebug.IntToString(from = TYPE_APPLICATION_ATTACHED_DIALOG, to = "TYPE_APPLICATION_ATTACHED_DIALOG"),
+ @ViewDebug.IntToString(from = TYPE_APPLICATION_MEDIA_OVERLAY, to = "TYPE_APPLICATION_MEDIA_OVERLAY"),
@ViewDebug.IntToString(from = TYPE_STATUS_BAR, to = "TYPE_STATUS_BAR"),
@ViewDebug.IntToString(from = TYPE_SEARCH_BAR, to = "TYPE_SEARCH_BAR"),
@ViewDebug.IntToString(from = TYPE_PHONE, to = "TYPE_PHONE"),
@@ -170,8 +171,6 @@
@ViewDebug.IntToString(from = TYPE_TOAST, to = "TYPE_TOAST"),
@ViewDebug.IntToString(from = TYPE_SYSTEM_OVERLAY, to = "TYPE_SYSTEM_OVERLAY"),
@ViewDebug.IntToString(from = TYPE_PRIORITY_PHONE, to = "TYPE_PRIORITY_PHONE"),
- @ViewDebug.IntToString(from = TYPE_STATUS_BAR_PANEL, to = "TYPE_STATUS_BAR_PANEL"),
- @ViewDebug.IntToString(from = TYPE_STATUS_BAR_SUB_PANEL, to = "TYPE_STATUS_BAR_SUB_PANEL"),
@ViewDebug.IntToString(from = TYPE_SYSTEM_DIALOG, to = "TYPE_SYSTEM_DIALOG"),
@ViewDebug.IntToString(from = TYPE_KEYGUARD_DIALOG, to = "TYPE_KEYGUARD_DIALOG"),
@ViewDebug.IntToString(from = TYPE_SYSTEM_ERROR, to = "TYPE_SYSTEM_ERROR"),
@@ -185,7 +184,10 @@
@ViewDebug.IntToString(from = TYPE_POINTER, to = "TYPE_POINTER"),
@ViewDebug.IntToString(from = TYPE_NAVIGATION_BAR, to = "TYPE_NAVIGATION_BAR"),
@ViewDebug.IntToString(from = TYPE_VOLUME_OVERLAY, to = "TYPE_VOLUME_OVERLAY"),
- @ViewDebug.IntToString(from = TYPE_BOOT_PROGRESS, to = "TYPE_BOOT_PROGRESS")
+ @ViewDebug.IntToString(from = TYPE_BOOT_PROGRESS, to = "TYPE_BOOT_PROGRESS"),
+ @ViewDebug.IntToString(from = TYPE_HIDDEN_NAV_CONSUMER, to = "TYPE_HIDDEN_NAV_CONSUMER"),
+ @ViewDebug.IntToString(from = TYPE_DREAM, to = "TYPE_DREAM"),
+ @ViewDebug.IntToString(from = TYPE_NAVIGATION_BAR_PANEL, to = "TYPE_NAVIGATION_BAR_PANEL")
})
public int type;
diff --git a/core/java/android/view/WindowManagerPolicy.java b/core/java/android/view/WindowManagerPolicy.java
index ceb9fe6..09948b8 100644
--- a/core/java/android/view/WindowManagerPolicy.java
+++ b/core/java/android/view/WindowManagerPolicy.java
@@ -26,7 +26,6 @@
import android.os.Looper;
import android.view.animation.Animation;
-import java.io.FileDescriptor;
import java.io.PrintWriter;
/**
@@ -1122,10 +1121,9 @@
* Print the WindowManagerPolicy's state into the given stream.
*
* @param prefix Text to print at the front of each line.
- * @param fd The raw file descriptor that the dump is being sent to.
* @param writer The PrintWriter to which you should dump your state. This will be
* closed for you after you return.
* @param args additional arguments to the dump request.
*/
- public void dump(String prefix, FileDescriptor fd, PrintWriter writer, String[] args);
+ public void dump(String prefix, PrintWriter writer, String[] args);
}
diff --git a/core/java/android/view/accessibility/AccessibilityNodeInfo.java b/core/java/android/view/accessibility/AccessibilityNodeInfo.java
index 3834fd6..3ad3a55 100644
--- a/core/java/android/view/accessibility/AccessibilityNodeInfo.java
+++ b/core/java/android/view/accessibility/AccessibilityNodeInfo.java
@@ -469,13 +469,7 @@
* {@link View#FOCUS_LEFT},
* {@link View#FOCUS_RIGHT},
* {@link View#FOCUS_FORWARD},
- * {@link View#FOCUS_BACKWARD},
- * {@link View#ACCESSIBILITY_FOCUS_FORWARD},
- * {@link View#ACCESSIBILITY_FOCUS_BACKWARD},
- * {@link View#ACCESSIBILITY_FOCUS_UP},
- * {@link View#ACCESSIBILITY_FOCUS_RIGHT},
- * {@link View#ACCESSIBILITY_FOCUS_DOWN},
- * {@link View#ACCESSIBILITY_FOCUS_LEFT}.
+ * {@link View#FOCUS_BACKWARD}.
*
* @return The node info for the view that can take accessibility focus.
*/
diff --git a/core/java/android/view/accessibility/AccessibilityNodeProvider.java b/core/java/android/view/accessibility/AccessibilityNodeProvider.java
index e60716d..b3f3cee 100644
--- a/core/java/android/view/accessibility/AccessibilityNodeProvider.java
+++ b/core/java/android/view/accessibility/AccessibilityNodeProvider.java
@@ -150,6 +150,8 @@
*
* @see #createAccessibilityNodeInfo(int)
* @see AccessibilityNodeInfo
+ *
+ * @hide
*/
public AccessibilityNodeInfo findAccessibilityFocus(int virtualViewId) {
return null;
@@ -180,6 +182,8 @@
*
* @see #createAccessibilityNodeInfo(int)
* @see AccessibilityNodeInfo
+ *
+ * @hide
*/
public AccessibilityNodeInfo accessibilityFocusSearch(int direction, int virtualViewId) {
return null;
diff --git a/core/java/android/webkit/HTML5VideoFullScreen.java b/core/java/android/webkit/HTML5VideoFullScreen.java
index 62bc502..33eaad6 100644
--- a/core/java/android/webkit/HTML5VideoFullScreen.java
+++ b/core/java/android/webkit/HTML5VideoFullScreen.java
@@ -194,13 +194,6 @@
mCanPause = mCanSeekBack = mCanSeekForward = true;
}
- // mMediaController status depends on the Metadata result, so put it
- // after reading the MetaData
- if (mMediaController != null) {
- mMediaController.setEnabled(true);
- mMediaController.show();
- }
-
if (mProgressView != null) {
mProgressView.setVisibility(View.GONE);
}
@@ -215,6 +208,16 @@
if (getStartWhenPrepared()) {
mPlayer.start();
+ // Clear the flag.
+ setStartWhenPrepared(false);
+ }
+
+ // mMediaController status depends on the Metadata result, so put it
+ // after reading the MetaData.
+ // And make sure mPlayer state is updated before showing the controller.
+ if (mMediaController != null) {
+ mMediaController.setEnabled(true);
+ mMediaController.show();
}
}
diff --git a/core/java/android/webkit/HTML5VideoViewProxy.java b/core/java/android/webkit/HTML5VideoViewProxy.java
index 90db308..ab884df 100644
--- a/core/java/android/webkit/HTML5VideoViewProxy.java
+++ b/core/java/android/webkit/HTML5VideoViewProxy.java
@@ -147,6 +147,7 @@
// Save the inline video info and inherit it in the full screen
int savePosition = 0;
boolean canSkipPrepare = false;
+ boolean forceStart = false;
if (mHTML5VideoView != null) {
// We don't allow enter full screen mode while the previous
// full screen video hasn't finished yet.
@@ -154,11 +155,11 @@
Log.w(LOGTAG, "Try to reenter the full screen mode");
return;
}
+ int playerState = mHTML5VideoView.getCurrentState();
// If we are playing the same video, then it is better to
// save the current position.
if (layerId == mHTML5VideoView.getVideoLayerId()) {
savePosition = mHTML5VideoView.getCurrentPosition();
- int playerState = mHTML5VideoView.getCurrentState();
canSkipPrepare = (playerState == HTML5VideoView.STATE_PREPARING
|| playerState == HTML5VideoView.STATE_PREPARED
|| playerState == HTML5VideoView.STATE_PLAYING)
@@ -166,10 +167,14 @@
}
if (!canSkipPrepare) {
mHTML5VideoView.reset();
+ } else {
+ forceStart = playerState == HTML5VideoView.STATE_PREPARING
+ || playerState == HTML5VideoView.STATE_PLAYING;
}
}
mHTML5VideoView = new HTML5VideoFullScreen(proxy.getContext(),
layerId, savePosition, canSkipPrepare);
+ mHTML5VideoView.setStartWhenPrepared(forceStart);
mCurrentProxy = proxy;
mHTML5VideoView.setVideoURI(url, mCurrentProxy);
mHTML5VideoView.enterFullScreenVideoState(layerId, proxy, webView);
diff --git a/core/java/android/webkit/WebSettings.java b/core/java/android/webkit/WebSettings.java
index fa3cb20..9b0f61c 100644
--- a/core/java/android/webkit/WebSettings.java
+++ b/core/java/android/webkit/WebSettings.java
@@ -921,23 +921,27 @@
/**
* Sets the path to where database storage API databases should be saved.
- * Note that the WebCore Database Tracker only allows the path to be set once.
+ * In order for the database storage API to function correctly, this method
+ * must be called with a path to which the application can write. This
+ * method should only be called once: repeated calls are ignored.
*
- * @param databasePath a String path to the directory where databases should
- * be saved. May be the empty string but should never
- * be null.
+ * @param databasePath a path to the directory where databases should be
+ * saved.
*/
// This will update WebCore when the Sync runs in the C++ side.
+ // Note that the WebCore Database Tracker only allows the path to be set
+ // once.
public synchronized void setDatabasePath(String databasePath) {
throw new MustOverrideException();
}
/**
- * Sets the path where the Geolocation permissions database should be saved.
+ * Sets the path where the Geolocation databases should be saved. In order
+ * for Geolocation permissions and cached positions to be persisted, this
+ * method must be called with a path to which the application can write.
*
- * @param databasePath a String path to the directory where the Geolocation
- * permissions database should be saved. May be the
- * empty string but should never be null.
+ * @param databasePath a path to the directory where databases should be
+ * saved.
*/
// This will update WebCore when the Sync runs in the C++ side.
public synchronized void setGeolocationDatabasePath(String databasePath) {
@@ -945,7 +949,10 @@
}
/**
- * Tells the WebView to enable Application Caches API.
+ * Sets whether the Application Caches API should be enabled. The default
+ * is false. Note that in order for the Application Caches API to be
+ * enabled, a valid database path must also be supplied to
+ * {@link #setAppCachePath}.
*
* @param flag true if the WebView should enable Application Caches
*/
@@ -954,13 +961,14 @@
}
/**
- * Sets a custom path to the Application Caches files. The client
- * must ensure it exists before this call.
+ * Sets the path to the Application Caches files. In order for the
+ * Application Caches API to be enabled, this method must be called with a
+ * path to which the application can write. This method should only be
+ * called once: repeated calls are ignored.
*
* @param appCachePath a String path to the directory containing
- * Application Caches files. The appCache path can be
- * the empty string but should not be null. Passing
- * null for this parameter will result in a no-op.
+ * Application Caches files.
+ * @see setAppCacheEnabled
*/
public synchronized void setAppCachePath(String appCachePath) {
throw new MustOverrideException();
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index 31a6650..2545cd81 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -1711,6 +1711,10 @@
WebView.super.computeScroll();
}
+ public boolean super_onHoverEvent(MotionEvent event) {
+ return WebView.super.onHoverEvent(event);
+ }
+
public boolean super_performAccessibilityAction(int action, Bundle arguments) {
return WebView.super.performAccessibilityAction(action, arguments);
}
diff --git a/core/java/android/webkit/WebViewClassic.java b/core/java/android/webkit/WebViewClassic.java
index 02c8bb0..5eefbe1 100644
--- a/core/java/android/webkit/WebViewClassic.java
+++ b/core/java/android/webkit/WebViewClassic.java
@@ -5755,6 +5755,7 @@
int x = viewToContentX((int) event.getX() + getScrollX());
int y = viewToContentY((int) event.getY() + getScrollY());
mWebViewCore.sendMessage(EventHub.SET_MOVE_MOUSE, x, y);
+ mWebViewPrivate.super_onHoverEvent(event);
return true;
}
@@ -7979,8 +7980,10 @@
if (data.mSelectTextPtr != 0 &&
(data.mStart != data.mEnd ||
- (mFieldPointer == nodePointer && mFieldPointer != 0))) {
- mIsCaretSelection = (data.mStart == data.mEnd);
+ (mFieldPointer == nodePointer && mFieldPointer != 0) ||
+ (nodePointer == 0 && data.mStart == 0 && data.mEnd == 0))) {
+ mIsEditingText = (mFieldPointer == nodePointer) && nodePointer != 0;
+ mIsCaretSelection = (data.mStart == data.mEnd && nodePointer != 0);
if (mIsCaretSelection &&
(mInputConnection == null ||
mInputConnection.getEditable().length() == 0)) {
diff --git a/core/java/android/widget/GridView.java b/core/java/android/widget/GridView.java
index 71ad148..f23e1aa 100644
--- a/core/java/android/widget/GridView.java
+++ b/core/java/android/widget/GridView.java
@@ -2217,8 +2217,13 @@
int height = view.getHeight();
if (height > 0) {
final int numColumns = mNumColumns;
- final int whichRow = mFirstPosition / numColumns;
final int rowCount = (mItemCount + numColumns - 1) / numColumns;
+ // In case of stackFromBottom the calculation of whichRow needs
+ // to take into account that counting from the top the first row
+ // might not be entirely filled.
+ final int oddItemsOnFirstRow = isStackFromBottom() ? ((rowCount * numColumns) -
+ mItemCount) : 0;
+ final int whichRow = (mFirstPosition + oddItemsOnFirstRow) / numColumns;
return Math.max(whichRow * 100 - (top * 100) / height +
(int) ((float) mScrollY / getHeight() * rowCount * 100), 0);
}
diff --git a/core/java/com/android/internal/app/MediaRouteChooserDialogFragment.java b/core/java/com/android/internal/app/MediaRouteChooserDialogFragment.java
index e1a48be..b615b9c 100644
--- a/core/java/com/android/internal/app/MediaRouteChooserDialogFragment.java
+++ b/core/java/com/android/internal/app/MediaRouteChooserDialogFragment.java
@@ -25,12 +25,16 @@
import android.app.MediaRouteButton;
import android.content.Context;
import android.graphics.drawable.Drawable;
+import android.media.AudioManager;
import android.media.MediaRouter;
import android.media.MediaRouter.RouteCategory;
import android.media.MediaRouter.RouteGroup;
import android.media.MediaRouter.RouteInfo;
+import android.media.MediaRouter.UserRouteInfo;
+import android.media.RemoteControlClient;
import android.os.Bundle;
import android.text.TextUtils;
+import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@@ -41,6 +45,7 @@
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.ListView;
+import android.widget.SeekBar;
import android.widget.TextView;
import java.util.ArrayList;
@@ -67,6 +72,7 @@
};
MediaRouter mRouter;
+ AudioManager mAudio;
private int mRouteTypes;
private LayoutInflater mInflater;
@@ -74,8 +80,12 @@
private View.OnClickListener mExtendedSettingsListener;
private RouteAdapter mAdapter;
private ListView mListView;
+ private SeekBar mVolumeSlider;
+ private ImageView mVolumeIcon;
final RouteComparator mComparator = new RouteComparator();
+ final MediaRouterCallback mCallback = new MediaRouterCallback();
+ private boolean mIgnoreVolumeChanges;
public MediaRouteChooserDialogFragment() {
setStyle(STYLE_NO_TITLE, R.style.Theme_DeviceDefault_Dialog);
@@ -89,6 +99,7 @@
public void onAttach(Activity activity) {
super.onAttach(activity);
mRouter = (MediaRouter) activity.getSystemService(Context.MEDIA_ROUTER_SERVICE);
+ mAudio = (AudioManager) activity.getSystemService(Context.AUDIO_SERVICE);
}
@Override
@@ -98,20 +109,13 @@
mLauncherListener.onDetached(this);
}
if (mAdapter != null) {
- mRouter.removeCallback(mAdapter.mCallback);
mAdapter = null;
}
mInflater = null;
+ mRouter.removeCallback(mCallback);
mRouter = null;
}
- /**
- * Implemented by the MediaRouteButton that launched this dialog
- */
- public interface LauncherListener {
- public void onDetached(MediaRouteChooserDialogFragment detachedFragment);
- }
-
public void setExtendedSettingsClickListener(View.OnClickListener listener) {
mExtendedSettingsListener = listener;
}
@@ -120,14 +124,70 @@
mRouteTypes = types;
}
+ void updateVolume() {
+ final RouteInfo selectedRoute = mRouter.getSelectedRoute(mRouteTypes);
+ final boolean defaultAudioSelected = selectedRoute == mRouter.getSystemAudioRoute();
+ final boolean selectedSystemRoute =
+ selectedRoute.getCategory() == mRouter.getSystemAudioCategory();
+ mVolumeIcon.setImageResource(defaultAudioSelected ?
+ R.drawable.ic_audio_vol : R.drawable.ic_media_route_on_holo_dark);
+
+ mIgnoreVolumeChanges = true;
+ mVolumeSlider.setEnabled(true);
+ if (selectedSystemRoute) {
+ // Use the standard media audio stream
+ mVolumeSlider.setMax(mAudio.getStreamMaxVolume(AudioManager.STREAM_MUSIC));
+ mVolumeSlider.setProgress(mAudio.getStreamVolume(AudioManager.STREAM_MUSIC));
+ } else {
+ final RouteInfo firstSelected;
+ if (selectedRoute instanceof RouteGroup) {
+ firstSelected = ((RouteGroup) selectedRoute).getRouteAt(0);
+ } else {
+ firstSelected = selectedRoute;
+ }
+
+ RemoteControlClient rcc = null;
+ if (firstSelected instanceof UserRouteInfo) {
+ rcc = ((UserRouteInfo) firstSelected).getRemoteControlClient();
+ }
+
+ if (rcc == null) {
+ // No RemoteControlClient? Assume volume can't be controlled.
+ // Disable the slider and show it at max volume.
+ mVolumeSlider.setMax(1);
+ mVolumeSlider.setProgress(1);
+ mVolumeSlider.setEnabled(false);
+ } else {
+ // TODO: Connect this to the remote control volume
+ }
+ }
+ mIgnoreVolumeChanges = false;
+ }
+
+ void changeVolume(int newValue) {
+ if (mIgnoreVolumeChanges) return;
+
+ RouteCategory selectedCategory = mRouter.getSelectedRoute(mRouteTypes).getCategory();
+ if (selectedCategory == mRouter.getSystemAudioCategory()) {
+ final int maxVolume = mAudio.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
+ newValue = Math.max(0, Math.min(newValue, maxVolume));
+ mAudio.setStreamVolume(AudioManager.STREAM_MUSIC, newValue, 0);
+ }
+ }
+
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
mInflater = inflater;
final View layout = inflater.inflate(R.layout.media_route_chooser_layout, container, false);
- final View extendedSettingsButton = layout.findViewById(R.id.extended_settings);
+
+ mVolumeIcon = (ImageView) layout.findViewById(R.id.volume_icon);
+ mVolumeSlider = (SeekBar) layout.findViewById(R.id.volume_slider);
+ updateVolume();
+ mVolumeSlider.setOnSeekBarChangeListener(new VolumeSliderChangeListener());
if (mExtendedSettingsListener != null) {
+ final View extendedSettingsButton = layout.findViewById(R.id.extended_settings);
extendedSettingsButton.setVisibility(View.VISIBLE);
extendedSettingsButton.setOnClickListener(mExtendedSettingsListener);
}
@@ -138,7 +198,7 @@
list.setOnItemClickListener(mAdapter);
mListView = list;
- mRouter.addCallback(mRouteTypes, mAdapter.mCallback);
+ mRouter.addCallback(mRouteTypes, mCallback);
mAdapter.scrollToSelectedItem();
@@ -174,7 +234,6 @@
private int mSelectedItemPosition = -1;
private final ArrayList<Object> mItems = new ArrayList<Object>();
- final MediaRouterCallback mCallback = new MediaRouterCallback();
private RouteCategory mCategoryEditingGroups;
private RouteGroup mEditingGroup;
@@ -443,10 +502,6 @@
holder.text1.setText(cat.getName(getActivity()));
}
- public int getSelectedRoutePosition() {
- return mSelectedItemPosition;
- }
-
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
final int type = getItemViewType(position);
@@ -523,46 +578,49 @@
scrollToEditingGroup();
}
}
+ }
- class MediaRouterCallback extends MediaRouter.Callback {
- @Override
- public void onRouteSelected(MediaRouter router, int type, RouteInfo info) {
- update();
- }
+ class MediaRouterCallback extends MediaRouter.Callback {
+ @Override
+ public void onRouteSelected(MediaRouter router, int type, RouteInfo info) {
+ mAdapter.update();
+ updateVolume();
+ }
- @Override
- public void onRouteUnselected(MediaRouter router, int type, RouteInfo info) {
- update();
- }
+ @Override
+ public void onRouteUnselected(MediaRouter router, int type, RouteInfo info) {
+ mAdapter.update();
+ }
- @Override
- public void onRouteAdded(MediaRouter router, RouteInfo info) {
- update();
- }
+ @Override
+ public void onRouteAdded(MediaRouter router, RouteInfo info) {
+ mAdapter.update();
+ updateVolume();
+ }
- @Override
- public void onRouteRemoved(MediaRouter router, RouteInfo info) {
- if (info == mEditingGroup) {
- finishGrouping();
- }
- update();
+ @Override
+ public void onRouteRemoved(MediaRouter router, RouteInfo info) {
+ if (info == mAdapter.mEditingGroup) {
+ mAdapter.finishGrouping();
}
+ mAdapter.update();
+ updateVolume();
+ }
- @Override
- public void onRouteChanged(MediaRouter router, RouteInfo info) {
- notifyDataSetChanged();
- }
+ @Override
+ public void onRouteChanged(MediaRouter router, RouteInfo info) {
+ mAdapter.notifyDataSetChanged();
+ }
- @Override
- public void onRouteGrouped(MediaRouter router, RouteInfo info,
- RouteGroup group, int index) {
- update();
- }
+ @Override
+ public void onRouteGrouped(MediaRouter router, RouteInfo info,
+ RouteGroup group, int index) {
+ mAdapter.update();
+ }
- @Override
- public void onRouteUngrouped(MediaRouter router, RouteInfo info, RouteGroup group) {
- update();
- }
+ @Override
+ public void onRouteUngrouped(MediaRouter router, RouteInfo info, RouteGroup group) {
+ mAdapter.update();
}
}
@@ -587,5 +645,41 @@
super.onBackPressed();
}
}
+
+ public boolean onKeyDown(int keyCode, KeyEvent event) {
+ if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN && mVolumeSlider.isEnabled()) {
+ mVolumeSlider.incrementProgressBy(-1);
+ return true;
+ } else if (keyCode == KeyEvent.KEYCODE_VOLUME_UP && mVolumeSlider.isEnabled()) {
+ mVolumeSlider.incrementProgressBy(1);
+ return true;
+ } else {
+ return super.onKeyDown(keyCode, event);
+ }
+ }
+ }
+
+ /**
+ * Implemented by the MediaRouteButton that launched this dialog
+ */
+ public interface LauncherListener {
+ public void onDetached(MediaRouteChooserDialogFragment detachedFragment);
+ }
+
+ class VolumeSliderChangeListener implements SeekBar.OnSeekBarChangeListener {
+
+ @Override
+ public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
+ changeVolume(progress);
+ }
+
+ @Override
+ public void onStartTrackingTouch(SeekBar seekBar) {
+ }
+
+ @Override
+ public void onStopTrackingTouch(SeekBar seekBar) {
+ }
+
}
}
diff --git a/core/java/com/android/internal/view/ImageButtonNoParentPress.java b/core/java/com/android/internal/view/ImageButtonNoParentPress.java
deleted file mode 100644
index a6cfd86..0000000
--- a/core/java/com/android/internal/view/ImageButtonNoParentPress.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * 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.internal.view;
-
-import android.content.Context;
-import android.util.AttributeSet;
-import android.view.ViewGroup;
-import android.widget.ImageButton;
-
-public class ImageButtonNoParentPress extends ImageButton {
-
- public ImageButtonNoParentPress(Context context) {
- super(context);
- }
-
- public ImageButtonNoParentPress(Context context, AttributeSet attrs) {
- super(context, attrs);
- }
-
- public ImageButtonNoParentPress(Context context, AttributeSet attrs, int defStyle) {
- super(context, attrs, defStyle);
- }
-
- @Override
- public void setPressed(boolean pressed) {
- // Normally parents propagate pressed state to their children.
- // We don't want that to happen here; only press if our parent isn't.
- super.setPressed(((ViewGroup) getParent()).isPressed() ? false : pressed);
- }
-}
diff --git a/core/java/com/android/internal/view/menu/MenuItemImpl.java b/core/java/com/android/internal/view/menu/MenuItemImpl.java
index de75962..9f7441d 100644
--- a/core/java/com/android/internal/view/menu/MenuItemImpl.java
+++ b/core/java/com/android/internal/view/menu/MenuItemImpl.java
@@ -456,6 +456,9 @@
}
public boolean isVisible() {
+ if (mActionProvider != null && mActionProvider.overridesItemVisibility()) {
+ return (mFlags & HIDDEN) == 0 && mActionProvider.isVisible();
+ }
return (mFlags & HIDDEN) == 0;
}
@@ -586,9 +589,17 @@
}
public MenuItem setActionProvider(ActionProvider actionProvider) {
+ if (mActionProvider != null) {
+ mActionProvider.setVisibilityListener(null);
+ }
mActionView = null;
mActionProvider = actionProvider;
mMenu.onItemsChanged(true); // Measurement can be changed
+ mActionProvider.setVisibilityListener(new ActionProvider.VisibilityListener() {
+ @Override public void onActionProviderVisibilityChanged(boolean isVisible) {
+ mMenu.onItemVisibleChanged(MenuItemImpl.this);
+ }
+ });
return this;
}
diff --git a/core/java/com/android/internal/widget/multiwaveview/GlowPadView.java b/core/java/com/android/internal/widget/multiwaveview/GlowPadView.java
index 837b7b8..adea586 100644
--- a/core/java/com/android/internal/widget/multiwaveview/GlowPadView.java
+++ b/core/java/com/android/internal/widget/multiwaveview/GlowPadView.java
@@ -76,7 +76,7 @@
}
// Tuneable parameters for animation
- private static final int WAVE_ANIMATION_DURATION = 1200;
+ private static final int WAVE_ANIMATION_DURATION = 1350;
private static final int RETURN_TO_HOME_DELAY = 1200;
private static final int RETURN_TO_HOME_DURATION = 200;
private static final int HIDE_ANIMATION_DELAY = 200;
@@ -361,6 +361,7 @@
mHandleDrawable.setAlpha(0.0f);
deactivateTargets();
showTargets(true);
+ ping();
startBackgroundAnimation(INITIAL_SHOW_HANDLE_DURATION, 1.0f);
setGrabbedState(OnTriggerListener.CENTER_HANDLE);
if (AccessibilityManager.getInstance(mContext).isEnabled()) {
@@ -484,7 +485,12 @@
final int duration = animate ? HIDE_ANIMATION_DURATION : 0;
final int delay = animate ? HIDE_ANIMATION_DELAY : 0;
- final float targetScale = expanded ? TARGET_SCALE_EXPANDED : TARGET_SCALE_COLLAPSED;
+ // TODO: add an attribute for this. For now we'll show the expand for navbar, but not
+ // keyguard.
+ final boolean expandDisabled = !mAlwaysTrackFinger;
+
+ final float targetScale = (expanded || expandDisabled) ?
+ TARGET_SCALE_EXPANDED : TARGET_SCALE_COLLAPSED;
final int length = mTargetDrawables.size();
final TimeInterpolator interpolator = Ease.Cubic.easeOut;
for (int i = 0; i < length; i++) {
@@ -499,7 +505,8 @@
"onUpdate", mUpdateListener));
}
- final float ringScaleTarget = expanded ? RING_SCALE_EXPANDED : RING_SCALE_COLLAPSED;
+ final float ringScaleTarget = (expanded || expandDisabled) ?
+ RING_SCALE_EXPANDED : RING_SCALE_COLLAPSED;
mTargetAnimations.add(Tweener.to(mOuterRing, duration,
"ease", interpolator,
"alpha", 0.0f,
@@ -663,7 +670,20 @@
*/
public void ping() {
if (mFeedbackCount > 0) {
- startWaveAnimation();
+ boolean doWaveAnimation = true;
+ final AnimationBundle waveAnimations = mWaveAnimations;
+
+ // Don't do a wave if there's already one in progress
+ if (waveAnimations.size() > 0 && waveAnimations.get(0).animator.isRunning()) {
+ long t = waveAnimations.get(0).animator.getCurrentPlayTime();
+ if (t < WAVE_ANIMATION_DURATION/2) {
+ doWaveAnimation = false;
+ }
+ }
+
+ if (doWaveAnimation) {
+ startWaveAnimation();
+ }
}
}
@@ -677,7 +697,7 @@
mPointCloud.waveManager.setAlpha(1.0f);
mPointCloud.waveManager.setRadius(mHandleDrawable.getWidth()/2.0f);
mWaveAnimations.add(Tweener.to(mPointCloud.waveManager, WAVE_ANIMATION_DURATION,
- "ease", Ease.Linear.easeNone,
+ "ease", Ease.Quad.easeOut,
"delay", 0,
"radius", 2.0f * mOuterRadius,
"onUpdate", mUpdateListener,
diff --git a/core/java/com/android/internal/widget/multiwaveview/PointCloud.java b/core/java/com/android/internal/widget/multiwaveview/PointCloud.java
index 2ef8c78..1a5a9a2 100644
--- a/core/java/com/android/internal/widget/multiwaveview/PointCloud.java
+++ b/core/java/com/android/internal/widget/multiwaveview/PointCloud.java
@@ -180,17 +180,17 @@
float glowDistance = hypot(glowManager.x - point.x, glowManager.y - point.y);
float glowAlpha = 0.0f;
if (glowDistance < glowManager.radius) {
- float cosf = FloatMath.cos(PI * 0.5f * glowDistance / glowManager.radius);
- glowAlpha = glowManager.alpha * max(0.0f, (float) Math.pow(cosf, 0.5f));
+ float cosf = FloatMath.cos(PI * 0.25f * glowDistance / glowManager.radius);
+ glowAlpha = glowManager.alpha * max(0.0f, (float) Math.pow(cosf, 10.0f));
}
// Compute contribution from Wave
float radius = hypot(point.x, point.y);
- float distanceToWaveRing = Math.abs(radius - waveManager.radius);
+ float distanceToWaveRing = (radius - waveManager.radius);
float waveAlpha = 0.0f;
- if (distanceToWaveRing < waveManager.width * 0.5f) {
- float cosf = FloatMath.cos(PI * 0.5f * distanceToWaveRing / waveManager.width);
- waveAlpha = waveManager.alpha * max(0.0f, (float) Math.pow(cosf, 15.0f));
+ if (distanceToWaveRing < waveManager.width * 0.5f && distanceToWaveRing < 0.0f) {
+ float cosf = FloatMath.cos(PI * 0.25f * distanceToWaveRing / waveManager.width);
+ waveAlpha = waveManager.alpha * max(0.0f, (float) Math.pow(cosf, 20.0f));
}
return (int) (max(glowAlpha, waveAlpha) * 255);
diff --git a/core/res/res/drawable-hdpi/ic_action_assist_focused.png b/core/res/res/drawable-hdpi/ic_action_assist_focused.png
new file mode 100644
index 0000000..d98557d
--- /dev/null
+++ b/core/res/res/drawable-hdpi/ic_action_assist_focused.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_action_assist_generic_activated.png b/core/res/res/drawable-hdpi/ic_action_assist_generic_activated.png
new file mode 100644
index 0000000..c0e2098
--- /dev/null
+++ b/core/res/res/drawable-hdpi/ic_action_assist_generic_activated.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_action_assist_generic_normal.png b/core/res/res/drawable-hdpi/ic_action_assist_generic_normal.png
new file mode 100644
index 0000000..a852e2c
--- /dev/null
+++ b/core/res/res/drawable-hdpi/ic_action_assist_generic_normal.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_action_assist_focused.png b/core/res/res/drawable-mdpi/ic_action_assist_focused.png
new file mode 100644
index 0000000..3f96d03
--- /dev/null
+++ b/core/res/res/drawable-mdpi/ic_action_assist_focused.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_action_assist_generic_activated.png b/core/res/res/drawable-mdpi/ic_action_assist_generic_activated.png
new file mode 100644
index 0000000..f88f7e1
--- /dev/null
+++ b/core/res/res/drawable-mdpi/ic_action_assist_generic_activated.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_action_assist_generic_normal.png b/core/res/res/drawable-mdpi/ic_action_assist_generic_normal.png
new file mode 100644
index 0000000..7426994
--- /dev/null
+++ b/core/res/res/drawable-mdpi/ic_action_assist_generic_normal.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_action_assist_generic_activated.png b/core/res/res/drawable-xhdpi/ic_action_assist_generic_activated.png
new file mode 100644
index 0000000..500b157
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_action_assist_generic_activated.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_action_assist_generic_normal.png b/core/res/res/drawable-xhdpi/ic_action_assist_generic_normal.png
new file mode 100644
index 0000000..d0e4cf3
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_action_assist_generic_normal.png
Binary files differ
diff --git a/core/res/res/drawable/ic_lockscreen_search.xml b/core/res/res/drawable/ic_action_assist_generic.xml
similarity index 83%
rename from core/res/res/drawable/ic_lockscreen_search.xml
rename to core/res/res/drawable/ic_action_assist_generic.xml
index d7a5b00..60f5d5d 100644
--- a/core/res/res/drawable/ic_lockscreen_search.xml
+++ b/core/res/res/drawable/ic_action_assist_generic.xml
@@ -19,18 +19,18 @@
android:state_enabled="true"
android:state_active="false"
android:state_focused="false"
- android:drawable="@drawable/ic_lockscreen_google_normal" />
+ android:drawable="@drawable/ic_action_assist_generic_normal" />
<item
android:state_enabled="true"
android:state_active="true"
android:state_focused="false"
- android:drawable="@drawable/ic_lockscreen_google_activated" />
+ android:drawable="@drawable/ic_action_assist_generic_activated" />
<item
android:state_enabled="true"
android:state_active="false"
android:state_focused="true"
- android:drawable="@drawable/ic_lockscreen_google_focused" />
+ android:drawable="@drawable/ic_action_assist_generic_activated" />
</selector>
diff --git a/core/res/res/drawable/ic_lockscreen_outerring.xml b/core/res/res/drawable/ic_lockscreen_outerring.xml
index 78984b3..3886bb4 100644
--- a/core/res/res/drawable/ic_lockscreen_outerring.xml
+++ b/core/res/res/drawable/ic_lockscreen_outerring.xml
@@ -20,5 +20,5 @@
<size android:height="@dimen/keyguard_lockscreen_outerring_diameter"
android:width="@dimen/keyguard_lockscreen_outerring_diameter" />
<solid android:color="#00000000" />
- <stroke android:color="#1affffff" android:width="2dp" />
-</shape>
\ No newline at end of file
+ <stroke android:color="#00000000" android:width="2dp" />
+</shape>
diff --git a/core/res/res/layout/media_route_list_item.xml b/core/res/res/layout/media_route_list_item.xml
index ba1aaf2..8ce6327 100644
--- a/core/res/res/layout/media_route_list_item.xml
+++ b/core/res/res/layout/media_route_list_item.xml
@@ -49,7 +49,7 @@
android:textAppearance="?android:attr/textAppearanceSmall" />
</LinearLayout>
- <com.android.internal.view.ImageButtonNoParentPress
+ <ImageButton
android:layout_width="56dp"
android:layout_height="56dp"
android:id="@+id/expand_button"
diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml
index 8b13afb..df4bb57 100644
--- a/core/res/res/values-am/strings.xml
+++ b/core/res/res/values-am/strings.xml
@@ -934,10 +934,8 @@
<string name="deleteText" msgid="7070985395199629156">"ሰርዝ"</string>
<string name="inputMethod" msgid="1653630062304567879">"ግቤት ሜተድ"</string>
<string name="editTextMenuTitle" msgid="4909135564941815494">"የፅሁፍ እርምጃዎች"</string>
- <!-- no translation found for low_internal_storage_view_title (5576272496365684834) -->
- <skip />
- <!-- no translation found for low_internal_storage_view_text (6640505817617414371) -->
- <skip />
+ <string name="low_internal_storage_view_title" msgid="5576272496365684834">"የማከማቻ ቦታ እያለቀ ነው"</string>
+ <string name="low_internal_storage_view_text" msgid="6640505817617414371">"አንዳንድ የስርዓት ተግባራት ላይሰሩ ይችላሉ"</string>
<string name="ok" msgid="5970060430562524910">"እሺ"</string>
<string name="cancel" msgid="6442560571259935130">"ይቅር"</string>
<string name="yes" msgid="5362982303337969312">"እሺ"</string>
@@ -1297,8 +1295,6 @@
<string name="default_audio_route_name_dock_speakers" msgid="6240602982276591864">"የትከል ድምፅ ማጉያዎች"</string>
<string name="default_audio_route_name_hdmi" msgid="7986404173839007682">"HDMI ድምጽ"</string>
<string name="default_audio_route_category_name" msgid="3722811174003886946">"ስርዓት"</string>
- <!-- no translation found for bluetooth_a2dp_audio_route_name (8575624030406771015) -->
- <skip />
- <!-- no translation found for media_route_chooser_grouping_done (7966438307723317169) -->
- <skip />
+ <string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"የብሉቱዝ ድምጽ"</string>
+ <string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"ተከናውኗል"</string>
</resources>
diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml
index 9480c23..d2bb302 100644
--- a/core/res/res/values-ar/strings.xml
+++ b/core/res/res/values-ar/strings.xml
@@ -934,10 +934,8 @@
<string name="deleteText" msgid="7070985395199629156">"حذف"</string>
<string name="inputMethod" msgid="1653630062304567879">"طريقة الإرسال"</string>
<string name="editTextMenuTitle" msgid="4909135564941815494">"إجراءات النص"</string>
- <!-- no translation found for low_internal_storage_view_title (5576272496365684834) -->
- <skip />
- <!-- no translation found for low_internal_storage_view_text (6640505817617414371) -->
- <skip />
+ <string name="low_internal_storage_view_title" msgid="5576272496365684834">"مساحة التخزين منخفضة"</string>
+ <string name="low_internal_storage_view_text" msgid="6640505817617414371">"قد لا تعمل بعض وظائف النظام"</string>
<string name="ok" msgid="5970060430562524910">"موافق"</string>
<string name="cancel" msgid="6442560571259935130">"إلغاء"</string>
<string name="yes" msgid="5362982303337969312">"موافق"</string>
@@ -1297,8 +1295,6 @@
<string name="default_audio_route_name_dock_speakers" msgid="6240602982276591864">"مكبرات صوت للإرساء"</string>
<string name="default_audio_route_name_hdmi" msgid="7986404173839007682">"صوت HDMI"</string>
<string name="default_audio_route_category_name" msgid="3722811174003886946">"النظام"</string>
- <!-- no translation found for bluetooth_a2dp_audio_route_name (8575624030406771015) -->
- <skip />
- <!-- no translation found for media_route_chooser_grouping_done (7966438307723317169) -->
- <skip />
+ <string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"صوت بلوتوث"</string>
+ <string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"تم"</string>
</resources>
diff --git a/core/res/res/values-be/strings.xml b/core/res/res/values-be/strings.xml
index 71da677..6bd482a 100644
--- a/core/res/res/values-be/strings.xml
+++ b/core/res/res/values-be/strings.xml
@@ -934,10 +934,8 @@
<string name="deleteText" msgid="7070985395199629156">"выдаліць"</string>
<string name="inputMethod" msgid="1653630062304567879">"Метад уводу"</string>
<string name="editTextMenuTitle" msgid="4909135564941815494">"Дзеянні з тэкстам"</string>
- <!-- no translation found for low_internal_storage_view_title (5576272496365684834) -->
- <skip />
- <!-- no translation found for low_internal_storage_view_text (6640505817617414371) -->
- <skip />
+ <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Месца для захавання на зыходзе"</string>
+ <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Некаторыя сістэмныя функцыі могуць не працаваць"</string>
<string name="ok" msgid="5970060430562524910">"ОК"</string>
<string name="cancel" msgid="6442560571259935130">"Адмяніць"</string>
<string name="yes" msgid="5362982303337969312">"ОК"</string>
@@ -1299,6 +1297,5 @@
<string name="default_audio_route_category_name" msgid="3722811174003886946">"Сістэма"</string>
<!-- no translation found for bluetooth_a2dp_audio_route_name (8575624030406771015) -->
<skip />
- <!-- no translation found for media_route_chooser_grouping_done (7966438307723317169) -->
- <skip />
+ <string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Гатова"</string>
</resources>
diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml
index e5c0db5..2e9d3f1 100644
--- a/core/res/res/values-bg/strings.xml
+++ b/core/res/res/values-bg/strings.xml
@@ -934,10 +934,8 @@
<string name="deleteText" msgid="7070985395199629156">"изтриване"</string>
<string name="inputMethod" msgid="1653630062304567879">"Метод на въвеждане"</string>
<string name="editTextMenuTitle" msgid="4909135564941815494">"Действия с текста"</string>
- <!-- no translation found for low_internal_storage_view_title (5576272496365684834) -->
- <skip />
- <!-- no translation found for low_internal_storage_view_text (6640505817617414371) -->
- <skip />
+ <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Мястото в хранилището е на изчерпване"</string>
+ <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Възможно е някои функции на системата да не работят"</string>
<string name="ok" msgid="5970060430562524910">"OK"</string>
<string name="cancel" msgid="6442560571259935130">"Отказ"</string>
<string name="yes" msgid="5362982303337969312">"OK"</string>
@@ -1299,6 +1297,5 @@
<string name="default_audio_route_category_name" msgid="3722811174003886946">"Система"</string>
<!-- no translation found for bluetooth_a2dp_audio_route_name (8575624030406771015) -->
<skip />
- <!-- no translation found for media_route_chooser_grouping_done (7966438307723317169) -->
- <skip />
+ <string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Готово"</string>
</resources>
diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml
index 746b2ce..a67c3c9 100644
--- a/core/res/res/values-cs/strings.xml
+++ b/core/res/res/values-cs/strings.xml
@@ -934,10 +934,8 @@
<string name="deleteText" msgid="7070985395199629156">"smazat"</string>
<string name="inputMethod" msgid="1653630062304567879">"Metoda zadávání dat"</string>
<string name="editTextMenuTitle" msgid="4909135564941815494">"Operace s textem"</string>
- <!-- no translation found for low_internal_storage_view_title (5576272496365684834) -->
- <skip />
- <!-- no translation found for low_internal_storage_view_text (6640505817617414371) -->
- <skip />
+ <string name="low_internal_storage_view_title" msgid="5576272496365684834">"V úložišti je málo místa"</string>
+ <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Některé systémové funkce nemusí fungovat"</string>
<string name="ok" msgid="5970060430562524910">"OK"</string>
<string name="cancel" msgid="6442560571259935130">"Zrušit"</string>
<string name="yes" msgid="5362982303337969312">"OK"</string>
@@ -1299,6 +1297,5 @@
<string name="default_audio_route_category_name" msgid="3722811174003886946">"Systém"</string>
<!-- no translation found for bluetooth_a2dp_audio_route_name (8575624030406771015) -->
<skip />
- <!-- no translation found for media_route_chooser_grouping_done (7966438307723317169) -->
- <skip />
+ <string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Hotovo"</string>
</resources>
diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml
index fb9938c..570dfa3 100644
--- a/core/res/res/values-de/strings.xml
+++ b/core/res/res/values-de/strings.xml
@@ -196,31 +196,31 @@
<string name="permlab_processOutgoingCalls" msgid="3906007831192990946">"Ausgehende Anrufe umleiten"</string>
<string name="permdesc_processOutgoingCalls" msgid="5331318931937402040">"Ermöglicht der App, ausgehende Anrufe zu verarbeiten und die zu wählende Nummer zu ändern. Die Berechtigung erlaubt der App, ausgehende Anrufe zu überwachen, umzuleiten und zu unterbinden."</string>
<string name="permlab_receiveSms" msgid="8673471768947895082">"SMS empfangen"</string>
- <string name="permdesc_receiveSms" msgid="6424387754228766939">"Ermöglicht der App, SMS-Nachrichten zu empfangen und zu verarbeiten. Das bedeutet, dass die App an Ihr Gerät gesendete Nachrichten überwachen und löschen kann, ohne sie Ihnen anzuzeigen."</string>
+ <string name="permdesc_receiveSms" msgid="6424387754228766939">"Ermöglicht der App, SMS zu empfangen und zu verarbeiten. Das bedeutet, dass die App an Ihr Gerät gesendete Nachrichten überwachen und löschen kann, ohne sie Ihnen anzuzeigen."</string>
<string name="permlab_receiveMms" msgid="1821317344668257098">"MMS empfangen"</string>
- <string name="permdesc_receiveMms" msgid="533019437263212260">"Ermöglicht der App, MMS-Nachrichten zu empfangen und zu verarbeiten. Das bedeutet, dass die App an Ihr Gerät gesendete Nachrichten überwachen und löschen kann, ohne sie Ihnen anzuzeigen."</string>
+ <string name="permdesc_receiveMms" msgid="533019437263212260">"Ermöglicht der App, MMS zu empfangen und zu verarbeiten. Das bedeutet, dass die App an Ihr Gerät gesendete Nachrichten überwachen und löschen kann, ohne sie Ihnen anzuzeigen."</string>
<string name="permlab_receiveEmergencyBroadcast" msgid="1803477660846288089">"Notfall-Broadcasts empfangen"</string>
<string name="permdesc_receiveEmergencyBroadcast" msgid="848524070262431974">"Ermöglicht der App, Notfall-Broadcasts zu empfangen und zu verarbeiten. Diese Berechtigung steht nur System-Apps zur Verfügung."</string>
<string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"Cell Broadcast-Nachrichten lesen"</string>
<string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"Ermöglicht der App, von Ihrem Gerät empfangene Cell Broadcast-Nachrichten zu lesen. Cell Broadcast-Benachrichtigungen werden an einigen Standorten gesendet, um Sie über Notfallsituationen zu informieren. Schädliche Apps können die Leistung oder den Betrieb Ihres Geräts beeinträchtigen, wenn eine Cell Broadcast-Notfallbenachrichtigung eingeht."</string>
<string name="permlab_sendSms" msgid="5600830612147671529">"Kurznachrichten senden"</string>
- <string name="permdesc_sendSms" msgid="7094729298204937667">"Ermöglicht der App, SMS-Nachrichten zu senden. Dies kann zu unerwarteten Kosten führen. Schädliche Apps können Kosten verursachen, indem sie Nachrichten ohne Ihre Bestätigung senden."</string>
- <string name="permlab_sendSmsNoConfirmation" msgid="4781483105951730228">"SMS-Nachrichten ohne Bestätigung senden"</string>
- <string name="permdesc_sendSmsNoConfirmation" msgid="402569800862935907">"Ermöglicht der App, SMS-Nachrichten zu senden. Dies kann zu unerwarteten Kosten führen. Schädliche Apps können Kosten verursachen, indem sie Nachrichten ohne Ihre Bestätigung senden."</string>
+ <string name="permdesc_sendSms" msgid="7094729298204937667">"Ermöglicht der App, SMS zu senden. Dies kann zu unerwarteten Kosten führen. Schädliche Apps können Kosten verursachen, indem sie Nachrichten ohne Ihre Bestätigung senden."</string>
+ <string name="permlab_sendSmsNoConfirmation" msgid="4781483105951730228">"SMS ohne Bestätigung senden"</string>
+ <string name="permdesc_sendSmsNoConfirmation" msgid="402569800862935907">"Ermöglicht der App, SMS zu senden. Dies kann zu unerwarteten Kosten führen. Schädliche Apps können Kosten verursachen, indem sie Nachrichten ohne Ihre Bestätigung senden."</string>
<string name="permlab_readSms" msgid="8745086572213270480">"SMS oder MMS lesen"</string>
- <string name="permdesc_readSms" product="tablet" msgid="2467981548684735522">"Ermöglicht der App, auf Ihrem Tablet oder Ihrer SIM-Karte gespeicherte SMS-Nachrichten zu lesen. Die App kann alle SMS-Nachrichten lesen, unabhängig von Inhalt und Vertraulichkeit."</string>
- <string name="permdesc_readSms" product="default" msgid="3695967533457240550">"Ermöglicht der App, auf Ihrem Telefon oder Ihrer SIM-Karte gespeicherte SMS-Nachrichten zu lesen. Die App kann alle SMS-Nachrichten lesen, unabhängig von Inhalt und Vertraulichkeit."</string>
+ <string name="permdesc_readSms" product="tablet" msgid="2467981548684735522">"Ermöglicht der App, auf Ihrem Tablet oder Ihrer SIM-Karte gespeicherte SMS zu lesen. Die App kann alle SMS lesen, unabhängig von Inhalt und Vertraulichkeit."</string>
+ <string name="permdesc_readSms" product="default" msgid="3695967533457240550">"Ermöglicht der App, auf Ihrem Telefon oder Ihrer SIM-Karte gespeicherte SMS zu lesen. Die App kann alle SMS lesen, unabhängig von Inhalt und Vertraulichkeit."</string>
<string name="permlab_writeSms" msgid="3216950472636214774">"SMS oder MMS bearbeiten"</string>
<string name="permdesc_writeSms" product="tablet" msgid="5160413947794501538">"Ermöglicht der App, auf Ihrem Tablet oder Ihrer SIM-Karte gespeicherte SMS zu bearbeiten. Schädliche Apps können so Ihre Nachrichten löschen."</string>
<string name="permdesc_writeSms" product="default" msgid="7268668709052328567">"Ermöglicht der App, auf Ihrem Telefon oder Ihrer SIM-Karte gespeicherte SMS zu bearbeiten. Schädliche Apps können so Ihre Nachrichten löschen."</string>
<string name="permlab_receiveWapPush" msgid="5991398711936590410">"Textnachrichten (WAP) empfangen"</string>
<string name="permdesc_receiveWapPush" msgid="748232190220583385">"Ermöglicht der App, WAP-Nachrichten zu empfangen und zu verarbeiten. Mit der Berechtigung können Nachrichten, die an Sie gesendet wurden, überwacht und gelöscht werden, bevor sie Ihnen angezeigt werden."</string>
<string name="permlab_getTasks" msgid="6466095396623933906">"aktive Apps abrufen"</string>
- <string name="permdesc_getTasks" msgid="7454215995847658102">"Ermöglicht der App, Informationen zu aktuellen und kürzlich ausgeführten Aufgaben abzurufen. Damit kann die App möglicherweise ermitteln, welche Anwendungen auf Ihrem Gerät zum Einsatz kommen."</string>
+ <string name="permdesc_getTasks" msgid="7454215995847658102">"Ermöglicht der App, Informationen zu aktuellen und kürzlich ausgeführten Aufgaben abzurufen. Damit kann die App möglicherweise ermitteln, welche Apps auf Ihrem Gerät zum Einsatz kommen."</string>
<string name="permlab_getDetailedTasks" msgid="6229468674753529501">"Details zu ausgeführten Apps abrufen"</string>
<string name="permdesc_getDetailedTasks" msgid="153824741440717599">"Ermöglicht der App, detaillierte Informationen zu aktuellen und kürzlich ausgeführten Aufgaben abzurufen. Schädliche Apps können so geheime Informationen zu anderen Apps erhalten."</string>
<string name="permlab_reorderTasks" msgid="2018575526934422779">"Aktive Apps neu ordnen"</string>
- <string name="permdesc_reorderTasks" msgid="7734217754877439351">"Ermöglicht der App, Aufgaben in den Vorder- und Hintergrund zu verschieben, ohne dass dazu ein Eingreifen Ihrerseits notwendig ist"</string>
+ <string name="permdesc_reorderTasks" msgid="7734217754877439351">"Ermöglicht der App, Aufgaben in den Vorder- und Hintergrund zu verschieben, ohne dass dazu ein Eingreifen Ihrerseits notwendig ist."</string>
<string name="permlab_removeTasks" msgid="6821513401870377403">"Aktive Apps beenden"</string>
<string name="permdesc_removeTasks" msgid="1394714352062635493">"Ermöglicht der App, Aufgaben zu entfernen und die entsprechenden Apps zu beenden. Schädliche Apps können das Verhalten anderer Apps stören."</string>
<string name="permlab_startAnyActivity" msgid="2918768238045206456">"Beliebige Aktivität starten"</string>
@@ -301,8 +301,8 @@
<string name="permlab_signalPersistentProcesses" msgid="4539002991947376659">"Linux-Signale an Apps senden"</string>
<string name="permdesc_signalPersistentProcesses" msgid="4896992079182649141">"Ermöglicht der App, das Senden des gelieferten Signals an alle andauernden Prozesse zu fordern"</string>
<string name="permlab_persistentActivity" msgid="8841113627955563938">"App permanent ausführen"</string>
- <string name="permdesc_persistentActivity" product="tablet" msgid="8525189272329086137">"Ermöglicht der App, Teile der eigenen Anwendung dauerhaft im Speicher abzulegen. Dies kann dazu führen, dass anderen Apps weniger Arbeitsspeicher zur Verfügung steht und das Tablet langsamer wird."</string>
- <string name="permdesc_persistentActivity" product="default" msgid="4384760047508278272">"Ermöglicht der App, Teile der eigenen Anwendung dauerhaft im Speicher abzulegen. Dies kann dazu führen, dass anderen Apps weniger Arbeitsspeicher zur Verfügung steht und das Telefon langsamer wird."</string>
+ <string name="permdesc_persistentActivity" product="tablet" msgid="8525189272329086137">"Ermöglicht der App, Teile der eigenen App dauerhaft im Speicher abzulegen. Dies kann dazu führen, dass anderen Apps weniger Arbeitsspeicher zur Verfügung steht und das Tablet langsamer wird."</string>
+ <string name="permdesc_persistentActivity" product="default" msgid="4384760047508278272">"Ermöglicht der App, Teile der eigenen App dauerhaft im Speicher abzulegen. Dies kann dazu führen, dass anderen Apps weniger Arbeitsspeicher zur Verfügung steht und das Telefon langsamer wird."</string>
<string name="permlab_deletePackages" msgid="184385129537705938">"Apps löschen"</string>
<string name="permdesc_deletePackages" msgid="7411480275167205081">"Ermöglicht der App, Android-Pakete zu löschen. Schädliche Apps können so wichtige Apps löschen."</string>
<string name="permlab_clearAppUserData" msgid="274109191845842756">"Daten anderer Apps löschen"</string>
@@ -386,7 +386,7 @@
<string name="permlab_readFrameBuffer" msgid="6690504248178498136">"Frame-Puffer lesen"</string>
<string name="permdesc_readFrameBuffer" msgid="4937405521809454680">"Ermöglicht der App, den Inhalt des Frame-Puffers zu lesen"</string>
<string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"Audio-Einstellungen ändern"</string>
- <string name="permdesc_modifyAudioSettings" msgid="3522565366806248517">"Ermöglicht der App, globale Audio-Einstellungen zu ändern, etwa die Lautstärke und den Lautsprecher für die Ausgabe"</string>
+ <string name="permdesc_modifyAudioSettings" msgid="3522565366806248517">"Ermöglicht der App, globale Audio-Einstellungen zu ändern, etwa die Lautstärke und den Lautsprecher für die Ausgabe."</string>
<string name="permlab_recordAudio" msgid="3876049771427466323">"Audio aufnehmen"</string>
<string name="permdesc_recordAudio" msgid="4906839301087980680">"Ermöglicht der App, Ton mithilfe des Mikrofons aufzunehmen. Die Berechtigung erlaubt der App, Tonaufnahmen jederzeit und ohne Ihre Bestätigung durchzuführen."</string>
<string name="permlab_camera" msgid="3616391919559751192">"Bilder und Videos aufnehmen"</string>
@@ -468,8 +468,8 @@
<string name="permlab_accountManagerService" msgid="4829262349691386986">"Als Konto-Manager fungieren"</string>
<string name="permdesc_accountManagerService" msgid="1948455552333615954">"Ermöglicht der App, Anrufe an Kontoauthentifizierer zu tätigen"</string>
<string name="permlab_getAccounts" msgid="1086795467760122114">"Konten auf dem Gerät suchen"</string>
- <string name="permdesc_getAccounts" product="tablet" msgid="2741496534769660027">"Ermöglicht der App, eine Liste der dem Tablet bekannten Konten abzurufen. Dabei kann es sich um Konten handeln, die von installierten Anwendungen erstellt wurden."</string>
- <string name="permdesc_getAccounts" product="default" msgid="3448316822451807382">"Ermöglicht der App, eine Liste der dem Telefon bekannten Konten abzurufen. Dabei kann es sich um Konten handeln, die von installierten Anwendungen erstellt wurden."</string>
+ <string name="permdesc_getAccounts" product="tablet" msgid="2741496534769660027">"Ermöglicht der App, eine Liste der dem Tablet bekannten Konten abzurufen. Dabei kann es sich um Konten handeln, die von installierten Apps erstellt wurden."</string>
+ <string name="permdesc_getAccounts" product="default" msgid="3448316822451807382">"Ermöglicht der App, eine Liste der dem Telefon bekannten Konten abzurufen. Dabei kann es sich um Konten handeln, die von installierten Apps erstellt wurden."</string>
<string name="permlab_authenticateAccounts" msgid="5265908481172736933">"Konten erstellen und Passwörter festlegen"</string>
<string name="permdesc_authenticateAccounts" msgid="5472124296908977260">"Ermöglicht der App, die Kontoauthentifizierungsfunktionen des Konto-Managers zu verwenden, einschließlich der Funktionen zum Erstellen von Konten sowie zum Abrufen und Festlegen der entsprechenden Passwörter"</string>
<string name="permlab_manageAccounts" msgid="4983126304757177305">"Konten hinzufügen oder entfernen"</string>
@@ -477,9 +477,9 @@
<string name="permlab_useCredentials" msgid="235481396163877642">"Konten auf dem Gerät verwenden"</string>
<string name="permdesc_useCredentials" msgid="7984227147403346422">"Ermöglicht der App, Authentifizierungs-Token anzufordern"</string>
<string name="permlab_accessNetworkState" msgid="4951027964348974773">"Netzwerkverbindungen anzeigen"</string>
- <string name="permdesc_accessNetworkState" msgid="8318964424675960975">"Ermöglicht der App, Informationen zu Netzwerkverbindungen abzurufen, etwa welche Netzwerke existieren und verbunden sind"</string>
+ <string name="permdesc_accessNetworkState" msgid="8318964424675960975">"Ermöglicht der App, Informationen zu Netzwerkverbindungen abzurufen, etwa welche Netzwerke existieren und verbunden sind."</string>
<string name="permlab_createNetworkSockets" msgid="8018758136404323658">"Voller Netzwerkzugriff"</string>
- <string name="permdesc_createNetworkSockets" msgid="3403062187779724185">"Ermöglicht der App die Erstellung von Netzwerk-Sockets und die Verwendung benutzerdefinierter Netzwerkprotokolle. Der Browser und andere Anwendungen bieten die Möglichkeit, Daten über das Internet zu versenden. Daher ist diese Berechtigung nicht erforderlich, um Daten über das Internet versenden zu können."</string>
+ <string name="permdesc_createNetworkSockets" msgid="3403062187779724185">"Ermöglicht der App die Erstellung von Netzwerk-Sockets und die Verwendung benutzerdefinierter Netzwerkprotokolle. Der Browser und andere Apps bieten die Möglichkeit, Daten über das Internet zu versenden. Daher ist diese Berechtigung nicht erforderlich, um Daten über das Internet versenden zu können."</string>
<string name="permlab_writeApnSettings" msgid="505660159675751896">"Netzwerkeinstellungen und -verkehr ändern/abfangen"</string>
<string name="permdesc_writeApnSettings" msgid="5333798886412714193">"Ermöglicht der App, Netzwerkeinstellungen zu ändern und Netzwerkverkehr abzufangen und zu überprüfen, um beispielsweise den Proxy und den Port eines beliebigen Zugriffspunkts zu ändern. Schädliche Apps können so Netzwerkpakete ohne Ihr Wissen überwachen, weiterleiten oder ändern."</string>
<string name="permlab_changeNetworkState" msgid="958884291454327309">"Netzwerkkonnektivität ändern"</string>
@@ -489,9 +489,9 @@
<string name="permlab_changeBackgroundDataSetting" msgid="1400666012671648741">"Einstellung zur Verwendung von Hintergrunddaten ändern"</string>
<string name="permdesc_changeBackgroundDataSetting" msgid="5347729578468744379">"Ermöglicht der App, die Einstellung zur Verwendung von Hintergrunddaten zu ändern"</string>
<string name="permlab_accessWifiState" msgid="5202012949247040011">"WLAN-Verbindungen anzeigen"</string>
- <string name="permdesc_accessWifiState" msgid="5002798077387803726">"Ermöglicht der App, Informationen zu WLANs abzurufen, etwa ob ein WLAN aktiviert ist, und den Namen verbundener WLAN-Geräte"</string>
+ <string name="permdesc_accessWifiState" msgid="5002798077387803726">"Ermöglicht der App, Informationen zu WLANs abzurufen, etwa ob ein WLAN aktiviert ist, und den Namen verbundener WLAN-Geräte."</string>
<string name="permlab_changeWifiState" msgid="6550641188749128035">"WLAN-Verbindungen herstellen und trennen"</string>
- <string name="permdesc_changeWifiState" msgid="7137950297386127533">"Ermöglicht der App, eine Verbindung zu WLAN-Zugriffspunkten herzustellen und solche zu trennen und Änderungen an der Gerätekonfiguration für WLAN-Netzwerke vorzunehmen"</string>
+ <string name="permdesc_changeWifiState" msgid="7137950297386127533">"Ermöglicht der App, eine Verbindung zu WLAN-Zugriffspunkten herzustellen und solche zu trennen und Änderungen an der Gerätekonfiguration für WLAN-Netzwerke vorzunehmen."</string>
<string name="permlab_changeWifiMulticastState" msgid="1368253871483254784">"WLAN-Multicast-Empfang zulassen"</string>
<string name="permdesc_changeWifiMulticastState" product="tablet" msgid="7969774021256336548">"Ermöglicht der App, Pakete zu empfangen, die mithilfe von Multicast-Adressen an sämtliche Geräte in einem WLAN versendet wurden, nicht nur an Ihr Tablet. Dies kostet mehr Leistung als der Nicht-Multicast-Modus."</string>
<string name="permdesc_changeWifiMulticastState" product="default" msgid="6851949706025349926">"Ermöglicht der App, Pakete zu empfangen, die mithilfe von Multicast-Adressen an sämtliche Geräte in einem WLAN versendet wurden, nicht nur an Ihr Telefon. Dies kostet mehr Leistung als der Nicht-Multicast-Modus."</string>
@@ -501,11 +501,11 @@
<string name="permlab_accessWimaxState" msgid="7436749103151096452">"WiMAX-Verbindungen anzeigen"</string>
<string name="permdesc_accessWimaxState" msgid="6360102877261978887">"Ermöglicht der App festzustellen, ob WiMAX aktiviert ist. Zudem kann sie Informationen zu verbundenen WiMAX-Netzwerken abrufen."</string>
<string name="permlab_changeWimaxState" msgid="2405042267131496579">"WiMAX-Status ändern"</string>
- <string name="permdesc_changeWimaxState" product="tablet" msgid="3156456504084201805">"Ermöglicht der App, eine Verbindung zwischen dem Tablet und WiMAX-Netzwerken herzustellen und solche zu trennen"</string>
- <string name="permdesc_changeWimaxState" product="default" msgid="697025043004923798">"Ermöglicht der App, eine Verbindung zwischen dem Telefon und WiMAX-Netzwerken herzustellen und solche zu trennen"</string>
+ <string name="permdesc_changeWimaxState" product="tablet" msgid="3156456504084201805">"Ermöglicht der App, eine Verbindung zwischen dem Tablet und WiMAX-Netzwerken herzustellen und solche zu trennen."</string>
+ <string name="permdesc_changeWimaxState" product="default" msgid="697025043004923798">"Ermöglicht der App, eine Verbindung zwischen dem Telefon und WiMAX-Netzwerken herzustellen und solche zu trennen."</string>
<string name="permlab_bluetooth" msgid="6127769336339276828">"Pairing mit Bluetooth-Geräten durchführen"</string>
- <string name="permdesc_bluetooth" product="tablet" msgid="3480722181852438628">"Ermöglicht der App, die Bluetooth-Konfiguration eines Tablets einzusehen und Verbindungen zu gekoppelten Geräten herzustellen und zu akzeptieren"</string>
- <string name="permdesc_bluetooth" product="default" msgid="3207106324452312739">"Ermöglicht der App, die Bluetooth-Konfiguration des Telefons einzusehen und Verbindungen mit gekoppelten Geräten herzustellen und zu akzeptieren"</string>
+ <string name="permdesc_bluetooth" product="tablet" msgid="3480722181852438628">"Ermöglicht der App, die Bluetooth-Konfiguration eines Tablets einzusehen und Verbindungen zu gekoppelten Geräten herzustellen und zu akzeptieren."</string>
+ <string name="permdesc_bluetooth" product="default" msgid="3207106324452312739">"Ermöglicht der App, die Bluetooth-Konfiguration des Telefons einzusehen und Verbindungen mit gekoppelten Geräten herzustellen und zu akzeptieren."</string>
<string name="permlab_nfc" msgid="4423351274757876953">"Nahfeldkommunikation steuern"</string>
<string name="permdesc_nfc" msgid="7120611819401789907">"Ermöglicht der App die Kommunikation mit Tags für die Nahfeldkommunikation, Karten und Readern"</string>
<string name="permlab_disableKeyguard" msgid="3598496301486439258">"Bildschirmsperre deaktivieren"</string>
@@ -515,18 +515,18 @@
<string name="permlab_writeSyncSettings" msgid="5408694875793945314">"Synchronisierung aktivieren oder deaktivieren"</string>
<string name="permdesc_writeSyncSettings" msgid="8956262591306369868">"Ermöglicht der App, die Synchronisierungseinstellungen eines Kontos zu ändern. Dies kann beispielsweise dazu verwendet werden, die Synchronisierung von Kontakten mit einem Konto zu aktivieren."</string>
<string name="permlab_readSyncStats" msgid="7396577451360202448">"Synchronisierungsstatistiken lesen"</string>
- <string name="permdesc_readSyncStats" msgid="1510143761757606156">"Ermöglicht der App, die Synchronisierungsstatistiken eines Kontos zu lesen, einschließlich des Verlaufs von Synchronisierungsereignissen und der Menge synchronisierter Daten"</string>
+ <string name="permdesc_readSyncStats" msgid="1510143761757606156">"Ermöglicht der App, die Synchronisierungsstatistiken eines Kontos zu lesen, einschließlich des Verlaufs von Synchronisierungsereignissen und der Menge synchronisierter Daten."</string>
<string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"Abonnierte Feeds lesen"</string>
<string name="permdesc_subscribedFeedsRead" msgid="5557058907906144505">"Ermöglicht der App, Details zu den zurzeit synchronisierten Feeds abzurufen"</string>
<string name="permlab_subscribedFeedsWrite" msgid="9015246325408209296">"Abonnierte Feeds schreiben"</string>
<string name="permdesc_subscribedFeedsWrite" msgid="6928930188826089413">"Ermöglicht der App, Änderungen an kürzlich synchronisierten Feeds vorzunehmen. Schädliche Apps können so Ihre synchronisierten Feeds ändern."</string>
<string name="permlab_readDictionary" msgid="4107101525746035718">"Begriffe lesen, die Sie zum Wörterbuch hinzugefügt haben"</string>
- <string name="permdesc_readDictionary" msgid="659614600338904243">"Ermöglicht der App, alle Wörter, Namen und Ausdrücke zu lesen, die ein Nutzer in seinem Wörterbuch gespeichert hat"</string>
+ <string name="permdesc_readDictionary" msgid="659614600338904243">"Ermöglicht der App, alle Wörter, Namen und Ausdrücke zu lesen, die ein Nutzer in seinem Wörterbuch gespeichert hat."</string>
<string name="permlab_writeDictionary" msgid="2296383164914812772">"In benutzerdefiniertes Wörterbuch schreiben"</string>
<string name="permdesc_writeDictionary" msgid="8185385716255065291">"Ermöglicht der App, dem Nutzerwörterbuch neue Einträge hinzuzufügen"</string>
<string name="permlab_sdcardRead" product="nosdcard" msgid="8235341515605559677">"Zugriff auf geschützten Speicher testen"</string>
<string name="permlab_sdcardRead" product="default" msgid="8235341515605559677">"Zugriff auf geschützten Speicher testen"</string>
- <string name="permdesc_sdcardRead" product="nosdcard" msgid="5791957130190763289">"Ermöglicht der App, eine Berechtigung für USB-Speicher zu testen, die künftig auf neuen Geräten verfügbar sein wird"</string>
+ <string name="permdesc_sdcardRead" product="nosdcard" msgid="5791957130190763289">"Ermöglicht der App, eine Berechtigung für USB-Speicher zu testen, die künftig auf neuen Geräten verfügbar sein wird."</string>
<string name="permdesc_sdcardRead" product="default" msgid="5914402684685848828">"Ermöglicht der App, eine Berechtigung für SD-Karten zu testen, die künftig auf neuen Geräten verfügbar sein wird"</string>
<string name="permlab_sdcardWrite" product="nosdcard" msgid="8485979062254666748">"USB-Speicherinhalte ändern oder löschen"</string>
<string name="permlab_sdcardWrite" product="default" msgid="8805693630050458763">"SD-Karteninhalte ändern oder löschen"</string>
@@ -784,10 +784,10 @@
<string name="autofill_area" msgid="3547409050889952423">"Gebiet"</string>
<string name="autofill_emirate" msgid="2893880978835698818">"Emirat"</string>
<string name="permlab_readHistoryBookmarks" msgid="3775265775405106983">"Lesezeichen für Webseiten und das Webprotokoll lesen"</string>
- <string name="permdesc_readHistoryBookmarks" msgid="8462378226600439658">"Ermöglicht der App, den Verlauf aller mit dem Browser besuchten URLs und sämtliche Lesezeichen des Browsers zu lesen. Hinweis: Diese Berechtigung kann nicht von Browsern von Drittanbietern oder anderen Anwendungen mit Internetfunktionen erzwungen werden."</string>
+ <string name="permdesc_readHistoryBookmarks" msgid="8462378226600439658">"Ermöglicht der App, den Verlauf aller mit dem Browser besuchten URLs und sämtliche Lesezeichen des Browsers zu lesen. Hinweis: Diese Berechtigung kann nicht von Browsern von Drittanbietern oder anderen Apps mit Internetfunktionen erzwungen werden."</string>
<string name="permlab_writeHistoryBookmarks" msgid="3714785165273314490">"Lesezeichen für Webseiten setzen und das Webprotokoll aufzeichnen"</string>
- <string name="permdesc_writeHistoryBookmarks" product="tablet" msgid="6825527469145760922">"Ermöglicht der App, den Browserverlauf und die Lesezeichen auf Ihrem Tablet zu ändern. Damit kann die App Browserdaten löschen und ändern. Hinweis: Diese Berechtigung kann nicht von Browsern von Drittanbietern oder anderen Anwendungen mit Internetfunktionen erzwungen werden."</string>
- <string name="permdesc_writeHistoryBookmarks" product="default" msgid="8497389531014185509">"Ermöglicht der App, den Browserverlauf und die Lesezeichen auf Ihrem Telefon zu ändern. Damit kann die App Browserdaten löschen und ändern. Hinweis: Diese Berechtigung kann nicht von Browsern von Drittanbietern oder anderen Anwendungen mit Internetfunktionen erzwungen werden."</string>
+ <string name="permdesc_writeHistoryBookmarks" product="tablet" msgid="6825527469145760922">"Ermöglicht der App, den Browserverlauf und die Lesezeichen auf Ihrem Tablet zu ändern. Damit kann die App Browserdaten löschen und ändern. Hinweis: Diese Berechtigung kann nicht von Browsern von Drittanbietern oder anderen Apps mit Internetfunktionen erzwungen werden."</string>
+ <string name="permdesc_writeHistoryBookmarks" product="default" msgid="8497389531014185509">"Ermöglicht der App, den Browserverlauf und die Lesezeichen auf Ihrem Telefon zu ändern. Damit kann die App Browserdaten löschen und ändern. Hinweis: Diese Berechtigung kann nicht von Browsern von Drittanbietern oder anderen Apps mit Internetfunktionen erzwungen werden."</string>
<string name="permlab_setAlarm" msgid="1379294556362091814">"Wecker stellen"</string>
<string name="permdesc_setAlarm" msgid="316392039157473848">"Ermöglicht der App, einen Alarm in einer installierten Wecker-App einzurichten. Einige Wecker-Apps implementieren diese Funktion möglicherweise nicht."</string>
<string name="permlab_addVoicemail" msgid="5525660026090959044">"Mailbox-Nachrichten hinzufügen"</string>
@@ -934,10 +934,8 @@
<string name="deleteText" msgid="7070985395199629156">"Löschen"</string>
<string name="inputMethod" msgid="1653630062304567879">"Eingabemethode"</string>
<string name="editTextMenuTitle" msgid="4909135564941815494">"Textaktionen"</string>
- <!-- no translation found for low_internal_storage_view_title (5576272496365684834) -->
- <skip />
- <!-- no translation found for low_internal_storage_view_text (6640505817617414371) -->
- <skip />
+ <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Der Speicherplatz wird knapp"</string>
+ <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Einige Systemfunktionen funktionieren möglicherweise nicht."</string>
<string name="ok" msgid="5970060430562524910">"OK"</string>
<string name="cancel" msgid="6442560571259935130">"Abbruch"</string>
<string name="yes" msgid="5362982303337969312">"OK"</string>
@@ -974,7 +972,7 @@
<string name="smv_process" msgid="5120397012047462446">"Der Prozess <xliff:g id="PROCESS">%1$s</xliff:g> hat gegen seine selbsterzwungene StrictMode-Richtlinie verstoßen."</string>
<string name="android_upgrading_title" msgid="1584192285441405746">"Android wird aktualisiert..."</string>
<string name="android_upgrading_apk" msgid="7904042682111526169">"App <xliff:g id="NUMBER_0">%1$d</xliff:g> von <xliff:g id="NUMBER_1">%2$d</xliff:g> wird optimiert..."</string>
- <string name="android_upgrading_starting_apps" msgid="451464516346926713">"Apps werden gestartet."</string>
+ <string name="android_upgrading_starting_apps" msgid="451464516346926713">"Apps werden gestartet..."</string>
<string name="android_upgrading_complete" msgid="1405954754112999229">"Start wird abgeschlossen..."</string>
<string name="heavy_weight_notification" msgid="9087063985776626166">"<xliff:g id="APP">%1$s</xliff:g> läuft"</string>
<string name="heavy_weight_notification_detail" msgid="1721681741617898865">"Zum Wechseln in die App berühren"</string>
@@ -1128,7 +1126,7 @@
<string name="permlab_copyProtectedData" msgid="4341036311211406692">"Inhalte kopieren"</string>
<string name="permdesc_copyProtectedData" msgid="4390697124288317831">"Ermöglicht der App das Aufrufen des Standard-Containerdienstes zum Kopieren von Inhalten. Nicht für normale Apps vorgesehen."</string>
<string name="permlab_route_media_output" msgid="1642024455750414694">"Medienausgabe umleiten"</string>
- <string name="permdesc_route_media_output" msgid="4932818749547244346">"Ermöglicht einer Anwendung, die Medienausgabe auf andere externe Geräte umzuleiten"</string>
+ <string name="permdesc_route_media_output" msgid="4932818749547244346">"Ermöglicht einer App, die Medienausgabe auf andere externe Geräte umzuleiten."</string>
<string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"Für Zoomeinstellung zweimal berühren"</string>
<string name="gadget_host_error_inflating" msgid="4882004314906466162">"Widget konnte nicht hinzugefügt werden."</string>
<string name="ime_action_go" msgid="8320845651737369027">"Los"</string>
@@ -1297,8 +1295,6 @@
<string name="default_audio_route_name_dock_speakers" msgid="6240602982276591864">"Dock-Lautsprecher"</string>
<string name="default_audio_route_name_hdmi" msgid="7986404173839007682">"HDMI-Audio"</string>
<string name="default_audio_route_category_name" msgid="3722811174003886946">"System"</string>
- <!-- no translation found for bluetooth_a2dp_audio_route_name (8575624030406771015) -->
- <skip />
- <!-- no translation found for media_route_chooser_grouping_done (7966438307723317169) -->
- <skip />
+ <string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"Bluetooth-Audio"</string>
+ <string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Fertig"</string>
</resources>
diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml
index 7d5b30b..aa41a3e 100644
--- a/core/res/res/values-el/strings.xml
+++ b/core/res/res/values-el/strings.xml
@@ -934,10 +934,8 @@
<string name="deleteText" msgid="7070985395199629156">"διαγραφή"</string>
<string name="inputMethod" msgid="1653630062304567879">"Μέθοδος εισόδου"</string>
<string name="editTextMenuTitle" msgid="4909135564941815494">"Ενέργειες κειμένου"</string>
- <!-- no translation found for low_internal_storage_view_title (5576272496365684834) -->
- <skip />
- <!-- no translation found for low_internal_storage_view_text (6640505817617414371) -->
- <skip />
+ <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Ο χώρος αποθήκευσης εξαντλείται"</string>
+ <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Ορισμένες λειτουργίες συστήματος ενδέχεται να μην λειτουργούν"</string>
<string name="ok" msgid="5970060430562524910">"OK"</string>
<string name="cancel" msgid="6442560571259935130">"Ακύρωση"</string>
<string name="yes" msgid="5362982303337969312">"OK"</string>
@@ -1298,6 +1296,5 @@
<string name="default_audio_route_name_hdmi" msgid="7986404173839007682">"Ήχος HDMI"</string>
<string name="default_audio_route_category_name" msgid="3722811174003886946">"Σύστημα"</string>
<string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"Ήχος Bluetooth"</string>
- <!-- no translation found for media_route_chooser_grouping_done (7966438307723317169) -->
- <skip />
+ <string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Τέλος"</string>
</resources>
diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml
index b607347..0ae2da3 100644
--- a/core/res/res/values-es-rUS/strings.xml
+++ b/core/res/res/values-es-rUS/strings.xml
@@ -934,10 +934,8 @@
<string name="deleteText" msgid="7070985395199629156">"eliminar"</string>
<string name="inputMethod" msgid="1653630062304567879">"Método de entrada"</string>
<string name="editTextMenuTitle" msgid="4909135564941815494">"Acciones de texto"</string>
- <!-- no translation found for low_internal_storage_view_title (5576272496365684834) -->
- <skip />
- <!-- no translation found for low_internal_storage_view_text (6640505817617414371) -->
- <skip />
+ <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Queda poco espacio de almacenamiento"</string>
+ <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Es posible que algunas funciones del sistema no estén disponibles."</string>
<string name="ok" msgid="5970060430562524910">"Aceptar"</string>
<string name="cancel" msgid="6442560571259935130">"Cancelar"</string>
<string name="yes" msgid="5362982303337969312">"Aceptar"</string>
@@ -1299,6 +1297,5 @@
<string name="default_audio_route_category_name" msgid="3722811174003886946">"Sistema"</string>
<!-- no translation found for bluetooth_a2dp_audio_route_name (8575624030406771015) -->
<skip />
- <!-- no translation found for media_route_chooser_grouping_done (7966438307723317169) -->
- <skip />
+ <string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Listo"</string>
</resources>
diff --git a/core/res/res/values-et/strings.xml b/core/res/res/values-et/strings.xml
index 01d4260..4597ae7 100644
--- a/core/res/res/values-et/strings.xml
+++ b/core/res/res/values-et/strings.xml
@@ -934,10 +934,8 @@
<string name="deleteText" msgid="7070985395199629156">"kustuta"</string>
<string name="inputMethod" msgid="1653630062304567879">"Sisestusmeetod"</string>
<string name="editTextMenuTitle" msgid="4909135564941815494">"Tekstitoimingud"</string>
- <!-- no translation found for low_internal_storage_view_title (5576272496365684834) -->
- <skip />
- <!-- no translation found for low_internal_storage_view_text (6640505817617414371) -->
- <skip />
+ <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Talletusruum saab täis"</string>
+ <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Mõned süsteemifunktsioonid ei pruugi töötada"</string>
<string name="ok" msgid="5970060430562524910">"OK"</string>
<string name="cancel" msgid="6442560571259935130">"Tühista"</string>
<string name="yes" msgid="5362982303337969312">"OK"</string>
@@ -1297,8 +1295,6 @@
<string name="default_audio_route_name_dock_speakers" msgid="6240602982276591864">"Doki kõlarid"</string>
<string name="default_audio_route_name_hdmi" msgid="7986404173839007682">"HDMI heli"</string>
<string name="default_audio_route_category_name" msgid="3722811174003886946">"Süsteem"</string>
- <!-- no translation found for bluetooth_a2dp_audio_route_name (8575624030406771015) -->
- <skip />
- <!-- no translation found for media_route_chooser_grouping_done (7966438307723317169) -->
- <skip />
+ <string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"Bluetooth-heli"</string>
+ <string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Valmis"</string>
</resources>
diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml
index b7fbb8c..7ffdce3 100644
--- a/core/res/res/values-fi/strings.xml
+++ b/core/res/res/values-fi/strings.xml
@@ -1295,7 +1295,6 @@
<string name="default_audio_route_name_dock_speakers" msgid="6240602982276591864">"Telineen kaiuttimet"</string>
<string name="default_audio_route_name_hdmi" msgid="7986404173839007682">"HDMI-ääni"</string>
<string name="default_audio_route_category_name" msgid="3722811174003886946">"Järjestelmä"</string>
- <!-- no translation found for bluetooth_a2dp_audio_route_name (8575624030406771015) -->
- <skip />
+ <string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"Bluetooth-ääni"</string>
<string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Valmis"</string>
</resources>
diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml
index 10d0abf..946ae69 100644
--- a/core/res/res/values-hi/strings.xml
+++ b/core/res/res/values-hi/strings.xml
@@ -934,10 +934,8 @@
<string name="deleteText" msgid="7070985395199629156">"हटाएं"</string>
<string name="inputMethod" msgid="1653630062304567879">"इनपुट विधि"</string>
<string name="editTextMenuTitle" msgid="4909135564941815494">"पाठ क्रियाएं"</string>
- <!-- no translation found for low_internal_storage_view_title (5576272496365684834) -->
- <skip />
- <!-- no translation found for low_internal_storage_view_text (6640505817617414371) -->
- <skip />
+ <string name="low_internal_storage_view_title" msgid="5576272496365684834">"संग्रहण स्थान समाप्त हो रहा है"</string>
+ <string name="low_internal_storage_view_text" msgid="6640505817617414371">"हो सकता है कुछ सिस्टम फ़ंक्शन कार्य न करें"</string>
<string name="ok" msgid="5970060430562524910">"ठीक"</string>
<string name="cancel" msgid="6442560571259935130">"रद्द करें"</string>
<string name="yes" msgid="5362982303337969312">"ठीक"</string>
@@ -1299,6 +1297,5 @@
<string name="default_audio_route_category_name" msgid="3722811174003886946">"सिस्टम"</string>
<!-- no translation found for bluetooth_a2dp_audio_route_name (8575624030406771015) -->
<skip />
- <!-- no translation found for media_route_chooser_grouping_done (7966438307723317169) -->
- <skip />
+ <string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"पूर्ण"</string>
</resources>
diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml
index 5fa1868..618ec08 100644
--- a/core/res/res/values-hr/strings.xml
+++ b/core/res/res/values-hr/strings.xml
@@ -934,10 +934,8 @@
<string name="deleteText" msgid="7070985395199629156">"izbriši"</string>
<string name="inputMethod" msgid="1653630062304567879">"Način unosa"</string>
<string name="editTextMenuTitle" msgid="4909135564941815494">"Radnje s tekstom"</string>
- <!-- no translation found for low_internal_storage_view_title (5576272496365684834) -->
- <skip />
- <!-- no translation found for low_internal_storage_view_text (6640505817617414371) -->
- <skip />
+ <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Ponestaje prostora za pohranu"</string>
+ <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Neke sistemske funkcije možda neće raditi"</string>
<string name="ok" msgid="5970060430562524910">"U redu"</string>
<string name="cancel" msgid="6442560571259935130">"Odustani"</string>
<string name="yes" msgid="5362982303337969312">"U redu"</string>
@@ -1299,6 +1297,5 @@
<string name="default_audio_route_category_name" msgid="3722811174003886946">"Sustav"</string>
<!-- no translation found for bluetooth_a2dp_audio_route_name (8575624030406771015) -->
<skip />
- <!-- no translation found for media_route_chooser_grouping_done (7966438307723317169) -->
- <skip />
+ <string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Gotovo"</string>
</resources>
diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml
index aa5c897..0b86668 100644
--- a/core/res/res/values-hu/strings.xml
+++ b/core/res/res/values-hu/strings.xml
@@ -934,10 +934,8 @@
<string name="deleteText" msgid="7070985395199629156">"törlés"</string>
<string name="inputMethod" msgid="1653630062304567879">"Beviteli mód"</string>
<string name="editTextMenuTitle" msgid="4909135564941815494">"Műveletek szöveggel"</string>
- <!-- no translation found for low_internal_storage_view_title (5576272496365684834) -->
- <skip />
- <!-- no translation found for low_internal_storage_view_text (6640505817617414371) -->
- <skip />
+ <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Kevés a szabad terület"</string>
+ <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Előfordulhat, hogy néhány rendszerfunkció nem működik."</string>
<string name="ok" msgid="5970060430562524910">"OK"</string>
<string name="cancel" msgid="6442560571259935130">"Mégse"</string>
<string name="yes" msgid="5362982303337969312">"OK"</string>
@@ -1299,6 +1297,5 @@
<string name="default_audio_route_category_name" msgid="3722811174003886946">"Rendszer"</string>
<!-- no translation found for bluetooth_a2dp_audio_route_name (8575624030406771015) -->
<skip />
- <!-- no translation found for media_route_chooser_grouping_done (7966438307723317169) -->
- <skip />
+ <string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Kész"</string>
</resources>
diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml
index 930c0bc..5671f15 100644
--- a/core/res/res/values-in/strings.xml
+++ b/core/res/res/values-in/strings.xml
@@ -934,10 +934,8 @@
<string name="deleteText" msgid="7070985395199629156">"hapus"</string>
<string name="inputMethod" msgid="1653630062304567879">"Metode masukan"</string>
<string name="editTextMenuTitle" msgid="4909135564941815494">"Tindakan teks"</string>
- <!-- no translation found for low_internal_storage_view_title (5576272496365684834) -->
- <skip />
- <!-- no translation found for low_internal_storage_view_text (6640505817617414371) -->
- <skip />
+ <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Ruang penyimpanan hampir habis"</string>
+ <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Beberapa fungsi sistem mungkin tidak dapat bekerja"</string>
<string name="ok" msgid="5970060430562524910">"Oke"</string>
<string name="cancel" msgid="6442560571259935130">"Batal"</string>
<string name="yes" msgid="5362982303337969312">"Oke"</string>
@@ -1297,8 +1295,6 @@
<string name="default_audio_route_name_dock_speakers" msgid="6240602982276591864">"Pengeras suara dok"</string>
<string name="default_audio_route_name_hdmi" msgid="7986404173839007682">"Audio HDMI"</string>
<string name="default_audio_route_category_name" msgid="3722811174003886946">"Sistem"</string>
- <!-- no translation found for bluetooth_a2dp_audio_route_name (8575624030406771015) -->
- <skip />
- <!-- no translation found for media_route_chooser_grouping_done (7966438307723317169) -->
- <skip />
+ <string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"Audio Bluetooth"</string>
+ <string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Selesai"</string>
</resources>
diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml
index 09f39f0..a842118 100644
--- a/core/res/res/values-iw/strings.xml
+++ b/core/res/res/values-iw/strings.xml
@@ -934,10 +934,8 @@
<string name="deleteText" msgid="7070985395199629156">"מחק"</string>
<string name="inputMethod" msgid="1653630062304567879">"שיטת קלט"</string>
<string name="editTextMenuTitle" msgid="4909135564941815494">"פעולות טקסט"</string>
- <!-- no translation found for low_internal_storage_view_title (5576272496365684834) -->
- <skip />
- <!-- no translation found for low_internal_storage_view_text (6640505817617414371) -->
- <skip />
+ <string name="low_internal_storage_view_title" msgid="5576272496365684834">"שטח האחסון אוזל"</string>
+ <string name="low_internal_storage_view_text" msgid="6640505817617414371">"ייתכן שפונקציות מערכת מסוימות לא יפעלו"</string>
<string name="ok" msgid="5970060430562524910">"אישור"</string>
<string name="cancel" msgid="6442560571259935130">"ביטול"</string>
<string name="yes" msgid="5362982303337969312">"אישור"</string>
@@ -1297,8 +1295,6 @@
<string name="default_audio_route_name_dock_speakers" msgid="6240602982276591864">"רמקולים של מעגן"</string>
<string name="default_audio_route_name_hdmi" msgid="7986404173839007682">"אודיו HDMI"</string>
<string name="default_audio_route_category_name" msgid="3722811174003886946">"מערכת"</string>
- <!-- no translation found for bluetooth_a2dp_audio_route_name (8575624030406771015) -->
- <skip />
- <!-- no translation found for media_route_chooser_grouping_done (7966438307723317169) -->
- <skip />
+ <string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"אודיו Bluetooth"</string>
+ <string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"סיום"</string>
</resources>
diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml
index c51f5df..9269f95 100644
--- a/core/res/res/values-ko/strings.xml
+++ b/core/res/res/values-ko/strings.xml
@@ -934,10 +934,8 @@
<string name="deleteText" msgid="7070985395199629156">"삭제"</string>
<string name="inputMethod" msgid="1653630062304567879">"입력 방법"</string>
<string name="editTextMenuTitle" msgid="4909135564941815494">"텍스트 작업"</string>
- <!-- no translation found for low_internal_storage_view_title (5576272496365684834) -->
- <skip />
- <!-- no translation found for low_internal_storage_view_text (6640505817617414371) -->
- <skip />
+ <string name="low_internal_storage_view_title" msgid="5576272496365684834">"저장 공간이 부족함"</string>
+ <string name="low_internal_storage_view_text" msgid="6640505817617414371">"일부 시스템 기능이 작동하지 않을 수 있습니다."</string>
<string name="ok" msgid="5970060430562524910">"확인"</string>
<string name="cancel" msgid="6442560571259935130">"취소"</string>
<string name="yes" msgid="5362982303337969312">"확인"</string>
@@ -1299,6 +1297,5 @@
<string name="default_audio_route_category_name" msgid="3722811174003886946">"시스템"</string>
<!-- no translation found for bluetooth_a2dp_audio_route_name (8575624030406771015) -->
<skip />
- <!-- no translation found for media_route_chooser_grouping_done (7966438307723317169) -->
- <skip />
+ <string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"완료"</string>
</resources>
diff --git a/core/res/res/values-land/arrays.xml b/core/res/res/values-land/arrays.xml
index f2df3fa..6db3a508 100644
--- a/core/res/res/values-land/arrays.xml
+++ b/core/res/res/values-land/arrays.xml
@@ -23,7 +23,7 @@
<array name="lockscreen_targets_when_silent">
<item>@null</item>"
<item>@drawable/ic_lockscreen_unlock</item>
- <item>@drawable/ic_lockscreen_search</item>
+ <item>@drawable/ic_action_assist_generic</item>
<item>@drawable/ic_lockscreen_soundon</item>
</array>
@@ -44,7 +44,7 @@
<array name="lockscreen_targets_when_soundon">
<item>@null</item>
<item>@drawable/ic_lockscreen_unlock</item>
- <item>@drawable/ic_lockscreen_search</item>
+ <item>@drawable/ic_action_assist_generic</item>
<item>@drawable/ic_lockscreen_silent</item>
</array>
@@ -58,7 +58,7 @@
<array name="lockscreen_targets_with_camera">
<item>@null</item>
<item>@drawable/ic_lockscreen_unlock</item>
- <item>@drawable/ic_lockscreen_search</item>
+ <item>@drawable/ic_action_assist_generic</item>
<item>@drawable/ic_lockscreen_camera</item>
</array>
diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml
index 6275533..0971b80 100644
--- a/core/res/res/values-lt/strings.xml
+++ b/core/res/res/values-lt/strings.xml
@@ -934,10 +934,8 @@
<string name="deleteText" msgid="7070985395199629156">"ištrinti"</string>
<string name="inputMethod" msgid="1653630062304567879">"Įvesties būdas"</string>
<string name="editTextMenuTitle" msgid="4909135564941815494">"Teksto veiksmai"</string>
- <!-- no translation found for low_internal_storage_view_title (5576272496365684834) -->
- <skip />
- <!-- no translation found for low_internal_storage_view_text (6640505817617414371) -->
- <skip />
+ <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Mažėja laisvos saugyklos vietos"</string>
+ <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Kai kurios sistemos funkcijos gali neveikti"</string>
<string name="ok" msgid="5970060430562524910">"Gerai"</string>
<string name="cancel" msgid="6442560571259935130">"Atšaukti"</string>
<string name="yes" msgid="5362982303337969312">"Gerai"</string>
@@ -1297,8 +1295,6 @@
<string name="default_audio_route_name_dock_speakers" msgid="6240602982276591864">"Doko garsiakalbiai"</string>
<string name="default_audio_route_name_hdmi" msgid="7986404173839007682">"HDMI garsas"</string>
<string name="default_audio_route_category_name" msgid="3722811174003886946">"Sistema"</string>
- <!-- no translation found for bluetooth_a2dp_audio_route_name (8575624030406771015) -->
- <skip />
- <!-- no translation found for media_route_chooser_grouping_done (7966438307723317169) -->
- <skip />
+ <string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"„Bluetooth“ garsas"</string>
+ <string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Atlikta"</string>
</resources>
diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml
index 06690c7..bd76a09 100644
--- a/core/res/res/values-lv/strings.xml
+++ b/core/res/res/values-lv/strings.xml
@@ -934,10 +934,8 @@
<string name="deleteText" msgid="7070985395199629156">"dzēst"</string>
<string name="inputMethod" msgid="1653630062304567879">"Ievades metode"</string>
<string name="editTextMenuTitle" msgid="4909135564941815494">"Teksta darbības"</string>
- <!-- no translation found for low_internal_storage_view_title (5576272496365684834) -->
- <skip />
- <!-- no translation found for low_internal_storage_view_text (6640505817617414371) -->
- <skip />
+ <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Brīvās krātuves apjoms samazinās"</string>
+ <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Dažas sistēmas funkcijas var nedarboties."</string>
<string name="ok" msgid="5970060430562524910">"Labi"</string>
<string name="cancel" msgid="6442560571259935130">"Atcelt"</string>
<string name="yes" msgid="5362982303337969312">"Labi"</string>
@@ -1297,8 +1295,6 @@
<string name="default_audio_route_name_dock_speakers" msgid="6240602982276591864">"Doka skaļruņi"</string>
<string name="default_audio_route_name_hdmi" msgid="7986404173839007682">"HDMI audio"</string>
<string name="default_audio_route_category_name" msgid="3722811174003886946">"Sistēma"</string>
- <!-- no translation found for bluetooth_a2dp_audio_route_name (8575624030406771015) -->
- <skip />
- <!-- no translation found for media_route_chooser_grouping_done (7966438307723317169) -->
- <skip />
+ <string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"Bluetooth audio"</string>
+ <string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Gatavs"</string>
</resources>
diff --git a/core/res/res/values-ms/strings.xml b/core/res/res/values-ms/strings.xml
index 4a6c253..38c6a27 100644
--- a/core/res/res/values-ms/strings.xml
+++ b/core/res/res/values-ms/strings.xml
@@ -934,10 +934,8 @@
<string name="deleteText" msgid="7070985395199629156">"padam"</string>
<string name="inputMethod" msgid="1653630062304567879">"Kaedah input"</string>
<string name="editTextMenuTitle" msgid="4909135564941815494">"Tindakan teks"</string>
- <!-- no translation found for low_internal_storage_view_title (5576272496365684834) -->
- <skip />
- <!-- no translation found for low_internal_storage_view_text (6640505817617414371) -->
- <skip />
+ <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Ruang storan semakin berkurangan"</string>
+ <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Beberapa fungsi sistem mungkin tidak berfungsi"</string>
<string name="ok" msgid="5970060430562524910">"OK"</string>
<string name="cancel" msgid="6442560571259935130">"Batal"</string>
<string name="yes" msgid="5362982303337969312">"OK"</string>
@@ -1299,6 +1297,5 @@
<string name="default_audio_route_category_name" msgid="3722811174003886946">"Sistem"</string>
<!-- no translation found for bluetooth_a2dp_audio_route_name (8575624030406771015) -->
<skip />
- <!-- no translation found for media_route_chooser_grouping_done (7966438307723317169) -->
- <skip />
+ <string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Selesai"</string>
</resources>
diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml
index 1982ea0..a4ed927 100644
--- a/core/res/res/values-nb/strings.xml
+++ b/core/res/res/values-nb/strings.xml
@@ -1295,7 +1295,6 @@
<string name="default_audio_route_name_dock_speakers" msgid="6240602982276591864">"Dokkhøyttalere"</string>
<string name="default_audio_route_name_hdmi" msgid="7986404173839007682">"HDMI-lyd"</string>
<string name="default_audio_route_category_name" msgid="3722811174003886946">"System"</string>
- <!-- no translation found for bluetooth_a2dp_audio_route_name (8575624030406771015) -->
- <skip />
+ <string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"Bluetooth-lyd"</string>
<string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Fullført"</string>
</resources>
diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml
index ed74b2b..36c309e 100644
--- a/core/res/res/values-nl/strings.xml
+++ b/core/res/res/values-nl/strings.xml
@@ -934,10 +934,8 @@
<string name="deleteText" msgid="7070985395199629156">"verwijderen"</string>
<string name="inputMethod" msgid="1653630062304567879">"Invoermethode"</string>
<string name="editTextMenuTitle" msgid="4909135564941815494">"Tekstacties"</string>
- <!-- no translation found for low_internal_storage_view_title (5576272496365684834) -->
- <skip />
- <!-- no translation found for low_internal_storage_view_text (6640505817617414371) -->
- <skip />
+ <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Opslagruimte is bijna vol"</string>
+ <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Bepaalde systeemfuncties werken mogelijk niet"</string>
<string name="ok" msgid="5970060430562524910">"OK"</string>
<string name="cancel" msgid="6442560571259935130">"Annuleren"</string>
<string name="yes" msgid="5362982303337969312">"OK"</string>
@@ -1299,6 +1297,5 @@
<string name="default_audio_route_category_name" msgid="3722811174003886946">"Systeem"</string>
<!-- no translation found for bluetooth_a2dp_audio_route_name (8575624030406771015) -->
<skip />
- <!-- no translation found for media_route_chooser_grouping_done (7966438307723317169) -->
- <skip />
+ <string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Gereed"</string>
</resources>
diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml
index ee5b2be..f536b6f 100644
--- a/core/res/res/values-pl/strings.xml
+++ b/core/res/res/values-pl/strings.xml
@@ -1295,7 +1295,6 @@
<string name="default_audio_route_name_dock_speakers" msgid="6240602982276591864">"Głośniki stacji dokującej"</string>
<string name="default_audio_route_name_hdmi" msgid="7986404173839007682">"Dźwięk przez HDMI"</string>
<string name="default_audio_route_category_name" msgid="3722811174003886946">"System"</string>
- <!-- no translation found for bluetooth_a2dp_audio_route_name (8575624030406771015) -->
- <skip />
+ <string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"Dźwięk Bluetooth"</string>
<string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Gotowe"</string>
</resources>
diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml
index 6a287f1..63da834 100644
--- a/core/res/res/values-pt-rPT/strings.xml
+++ b/core/res/res/values-pt-rPT/strings.xml
@@ -1295,7 +1295,6 @@
<string name="default_audio_route_name_dock_speakers" msgid="6240602982276591864">"Altif. estação ancoragem"</string>
<string name="default_audio_route_name_hdmi" msgid="7986404173839007682">"Áudio HDMI"</string>
<string name="default_audio_route_category_name" msgid="3722811174003886946">"Sistema"</string>
- <!-- no translation found for bluetooth_a2dp_audio_route_name (8575624030406771015) -->
- <skip />
+ <string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"Áudio Bluetooth"</string>
<string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Concluído"</string>
</resources>
diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml
index a0187e9..c7b92b7 100644
--- a/core/res/res/values-pt/strings.xml
+++ b/core/res/res/values-pt/strings.xml
@@ -934,10 +934,8 @@
<string name="deleteText" msgid="7070985395199629156">"excluir"</string>
<string name="inputMethod" msgid="1653630062304567879">"Método de entrada"</string>
<string name="editTextMenuTitle" msgid="4909135564941815494">"Ações de texto"</string>
- <!-- no translation found for low_internal_storage_view_title (5576272496365684834) -->
- <skip />
- <!-- no translation found for low_internal_storage_view_text (6640505817617414371) -->
- <skip />
+ <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Pouco espaço de armazenamento"</string>
+ <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Algumas funções do sistema podem não funcionar"</string>
<string name="ok" msgid="5970060430562524910">"OK"</string>
<string name="cancel" msgid="6442560571259935130">"Cancelar"</string>
<string name="yes" msgid="5362982303337969312">"OK"</string>
@@ -1297,8 +1295,6 @@
<string name="default_audio_route_name_dock_speakers" msgid="6240602982276591864">"Alto-falantes do dock"</string>
<string name="default_audio_route_name_hdmi" msgid="7986404173839007682">"Áudio HDMI"</string>
<string name="default_audio_route_category_name" msgid="3722811174003886946">"Sistema"</string>
- <!-- no translation found for bluetooth_a2dp_audio_route_name (8575624030406771015) -->
- <skip />
- <!-- no translation found for media_route_chooser_grouping_done (7966438307723317169) -->
- <skip />
+ <string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"Áudio Bluetooth"</string>
+ <string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Concluído"</string>
</resources>
diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml
index 08be184..e534989 100644
--- a/core/res/res/values-ru/strings.xml
+++ b/core/res/res/values-ru/strings.xml
@@ -934,10 +934,8 @@
<string name="deleteText" msgid="7070985395199629156">"удалить"</string>
<string name="inputMethod" msgid="1653630062304567879">"Способ ввода"</string>
<string name="editTextMenuTitle" msgid="4909135564941815494">"Операции с текстом"</string>
- <!-- no translation found for low_internal_storage_view_title (5576272496365684834) -->
- <skip />
- <!-- no translation found for low_internal_storage_view_text (6640505817617414371) -->
- <skip />
+ <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Заканчивается пространство"</string>
+ <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Некоторые системные функции могут не работать"</string>
<string name="ok" msgid="5970060430562524910">"ОК"</string>
<string name="cancel" msgid="6442560571259935130">"Отмена"</string>
<string name="yes" msgid="5362982303337969312">"ОК"</string>
@@ -1299,6 +1297,5 @@
<string name="default_audio_route_category_name" msgid="3722811174003886946">"Система"</string>
<!-- no translation found for bluetooth_a2dp_audio_route_name (8575624030406771015) -->
<skip />
- <!-- no translation found for media_route_chooser_grouping_done (7966438307723317169) -->
- <skip />
+ <string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Готово"</string>
</resources>
diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml
index e22c246..051d6ad 100644
--- a/core/res/res/values-sk/strings.xml
+++ b/core/res/res/values-sk/strings.xml
@@ -934,10 +934,8 @@
<string name="deleteText" msgid="7070985395199629156">"odstrániť"</string>
<string name="inputMethod" msgid="1653630062304567879">"Metóda vstupu"</string>
<string name="editTextMenuTitle" msgid="4909135564941815494">"Operácie s textom"</string>
- <!-- no translation found for low_internal_storage_view_title (5576272496365684834) -->
- <skip />
- <!-- no translation found for low_internal_storage_view_text (6640505817617414371) -->
- <skip />
+ <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Nedostatok ukladacieho priestoru"</string>
+ <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Niektoré systémové funkcie nemusia fungovať"</string>
<string name="ok" msgid="5970060430562524910">"OK"</string>
<string name="cancel" msgid="6442560571259935130">"Zrušiť"</string>
<string name="yes" msgid="5362982303337969312">"OK"</string>
@@ -1299,6 +1297,5 @@
<string name="default_audio_route_category_name" msgid="3722811174003886946">"Systém"</string>
<!-- no translation found for bluetooth_a2dp_audio_route_name (8575624030406771015) -->
<skip />
- <!-- no translation found for media_route_chooser_grouping_done (7966438307723317169) -->
- <skip />
+ <string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Hotovo"</string>
</resources>
diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml
index 1376c51..ff91e43 100644
--- a/core/res/res/values-sl/strings.xml
+++ b/core/res/res/values-sl/strings.xml
@@ -934,10 +934,8 @@
<string name="deleteText" msgid="7070985395199629156">"izbriši"</string>
<string name="inputMethod" msgid="1653630062304567879">"Način vnosa"</string>
<string name="editTextMenuTitle" msgid="4909135564941815494">"Besedilna dejanja"</string>
- <!-- no translation found for low_internal_storage_view_title (5576272496365684834) -->
- <skip />
- <!-- no translation found for low_internal_storage_view_text (6640505817617414371) -->
- <skip />
+ <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Prostor za shranjevanje bo pošel"</string>
+ <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Nekatere sistemske funkcije morda ne delujejo"</string>
<string name="ok" msgid="5970060430562524910">"V redu"</string>
<string name="cancel" msgid="6442560571259935130">"Prekliči"</string>
<string name="yes" msgid="5362982303337969312">"V redu"</string>
@@ -1299,6 +1297,5 @@
<string name="default_audio_route_category_name" msgid="3722811174003886946">"Sistem"</string>
<!-- no translation found for bluetooth_a2dp_audio_route_name (8575624030406771015) -->
<skip />
- <!-- no translation found for media_route_chooser_grouping_done (7966438307723317169) -->
- <skip />
+ <string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Končano"</string>
</resources>
diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml
index 7e5fa30..8c0a55a 100644
--- a/core/res/res/values-sr/strings.xml
+++ b/core/res/res/values-sr/strings.xml
@@ -934,10 +934,8 @@
<string name="deleteText" msgid="7070985395199629156">"избриши"</string>
<string name="inputMethod" msgid="1653630062304567879">"Метод уноса"</string>
<string name="editTextMenuTitle" msgid="4909135564941815494">"Радње у вези са текстом"</string>
- <!-- no translation found for low_internal_storage_view_title (5576272496365684834) -->
- <skip />
- <!-- no translation found for low_internal_storage_view_text (6640505817617414371) -->
- <skip />
+ <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Недовољно простора за складиштење"</string>
+ <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Неке системске функције можда не функционишу"</string>
<string name="ok" msgid="5970060430562524910">"Потврди"</string>
<string name="cancel" msgid="6442560571259935130">"Откажи"</string>
<string name="yes" msgid="5362982303337969312">"Потврди"</string>
@@ -1299,6 +1297,5 @@
<string name="default_audio_route_category_name" msgid="3722811174003886946">"Систем"</string>
<!-- no translation found for bluetooth_a2dp_audio_route_name (8575624030406771015) -->
<skip />
- <!-- no translation found for media_route_chooser_grouping_done (7966438307723317169) -->
- <skip />
+ <string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Готово"</string>
</resources>
diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml
index 6109009..1ac94da 100644
--- a/core/res/res/values-sw/strings.xml
+++ b/core/res/res/values-sw/strings.xml
@@ -196,9 +196,9 @@
<string name="permlab_processOutgoingCalls" msgid="3906007831192990946">"panga upya simu zinazotoka"</string>
<string name="permdesc_processOutgoingCalls" msgid="5331318931937402040">"Inaruhusu programu kuchakata simu zinazotoka nje na kubadilisha nambari ya kupigwa. Idhini hii inaruhusu programu kuchunguza, kuelekeza upya, au kuzuia simu zinazotoka nje."</string>
<string name="permlab_receiveSms" msgid="8673471768947895082">"pokea jumbe za maandishi (SMS)"</string>
- <string name="permdesc_receiveSms" msgid="6424387754228766939">"Inaruhusu programu kupokea na kuchakata ujumbe wa SMS. Idhini hii inajumulisha uwezo wa kuchunguza na kufuta ujumbe uliotumwa kwa kifaa chako bila ya kukuonyesha."</string>
+ <string name="permdesc_receiveSms" msgid="6424387754228766939">"Inaruhusu programu kupokea na kuchakata ujumbe wa SMS. Hii inamaanisha programu hii inaweza kuchunguza na kufuta ujumbe uliotumwa katika kifaa chako bila ya kukuonyesha."</string>
<string name="permlab_receiveMms" msgid="1821317344668257098">"pokea jumbe za maandishi (MMS)"</string>
- <string name="permdesc_receiveMms" msgid="533019437263212260">"Inaruhusu programu kupokea na kuchakata ujumbe wa MMS. Idhini hii inajumulisha uwezo wa kuchunguza na kufuta ujumbe uliotumwa kwa kifaa chako bila ya kukuonyesha."</string>
+ <string name="permdesc_receiveMms" msgid="533019437263212260">"Inaruhusu programu kupokea na kuchakata ujumbe medianwai (MMS). Hii inamaanisha uwezo wa kuchunguza na kufuta ujumbe uliotumwa kwa kifaa chako bila ya kukuonyesha."</string>
<string name="permlab_receiveEmergencyBroadcast" msgid="1803477660846288089">"Pokea matangazo ya dharura"</string>
<string name="permdesc_receiveEmergencyBroadcast" msgid="848524070262431974">"Inaruhusu programu kupokea na kuchakata jumbe za dharura. Ruhusa hii inapatikana tu kwa programu za mfumo."</string>
<string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"soma jumbe za matangazo ya simu"</string>
@@ -208,19 +208,19 @@
<string name="permlab_sendSmsNoConfirmation" msgid="4781483105951730228">"Tuma ujumbe wa SMS bila ya thibitisho"</string>
<string name="permdesc_sendSmsNoConfirmation" msgid="402569800862935907">"Inaruhusu programu kutuma ujumbe wa SMS. Hii inaweza ikasababisha malipo yasiyotarajiwa. Programu hasidi zinaweza kukugharimu pesa kwa kutuma ujumbe bila uthibitisho wako."</string>
<string name="permlab_readSms" msgid="8745086572213270480">"soma jumbe zako za maandishi (SMS au MMS)"</string>
- <string name="permdesc_readSms" product="tablet" msgid="2467981548684735522">"Inaruhusu programu kusoma ujumbe wa SMS uliohifadhiwa kwenye kompyuta yako ndogo au SIM kadi. Hii inaruhusu programu kusoma ujumbe wote wa SMS, bila kujali maudhui au usiri."</string>
+ <string name="permdesc_readSms" product="tablet" msgid="2467981548684735522">"Inaruhusu programu kusoma ujumbe wa SMS uliohifadhiwa kwenye kompyuta kibao yako au SIM kadi. Hii inaruhusu programu kusoma ujumbe wote wa SMS, bila kujali maudhui au usiri."</string>
<string name="permdesc_readSms" product="default" msgid="3695967533457240550">"Inaruhusu programu kusoma ujumbe wa SMS uliohifadhiwa kwenye simu yako au SIM kadi. Hii inaruhusu programu kusoma ujumbe wote wa SMS, bila kujali maudhui au usiri."</string>
<string name="permlab_writeSms" msgid="3216950472636214774">"Hariri jumbe zako za maandishi (SMS au MMS)"</string>
<string name="permdesc_writeSms" product="tablet" msgid="5160413947794501538">"Inaruhusu programu kuandikia jumbe za SMS zinazohifadhiwa kwenye kompyuta yako kibao au SIM kadi. Programu hasidi zinaweza kufuta jumbe zako."</string>
<string name="permdesc_writeSms" product="default" msgid="7268668709052328567">"Inaruhusu programu kuandika jumbe za SMS zinazohifadhiwa kwenye simu yako au SIM kadi. programu hasidi zinaweza kufuta ujumbe zako."</string>
<string name="permlab_receiveWapPush" msgid="5991398711936590410">"pokea jumbe za maandishi (WAP)"</string>
- <string name="permdesc_receiveWapPush" msgid="748232190220583385">"Inaruhusu programu kupokea na kuchakata ujumbe wa WAP. Idhini hii inajumulisha uwezo wa kuchunguza na kufuta ujumbe uliotumwa kwako bila ya kukuonyesha."</string>
+ <string name="permdesc_receiveWapPush" msgid="748232190220583385">"Inaruhusu programu kupokea na kuchakata ujumbe wa WAP. Idhini hii inajumuisha uwezo wa kuchunguza na kufuta ujumbe uliotumwa kwako bila ya kukuonyesha."</string>
<string name="permlab_getTasks" msgid="6466095396623933906">"rudisha programu zinazoendeshwa"</string>
<string name="permdesc_getTasks" msgid="7454215995847658102">"Inaruhusu programu kurudisha taarifa kuhusu kazi zinazoendeshwa sasa na hivi karibuni. Hii inaweza kuruhusu programu kugundua taarifa kuhusu ni programu zipi zinazotumika kwenye kifaa."</string>
<string name="permlab_getDetailedTasks" msgid="6229468674753529501">"epua maelezo ya programu zinazoendeshwa"</string>
<string name="permdesc_getDetailedTasks" msgid="153824741440717599">"Huruhusu programu kuepua maelezo tondoti kuhusu kazi za sasa na zinazoendelea hivi karibuni. Programu hasidi huenda zikagundua maelezo ya kibinafsi kuhusu programu zingine."</string>
<string name="permlab_reorderTasks" msgid="2018575526934422779">"Agiza tena programu za kuendeshwa"</string>
- <string name="permdesc_reorderTasks" msgid="7734217754877439351">"Inaruhusu programu kusongesha kazi hadi kwenye mandhari-mbele na usuli. Programu inaweza kufanya haya bila ya maingizo yako."</string>
+ <string name="permdesc_reorderTasks" msgid="7734217754877439351">"Inaruhusu programu kusongesha kazi hadi kwenye mandhari-mbele na mandari nyuma. Programu inaweza kufanya haya bila ya maingizo yako."</string>
<string name="permlab_removeTasks" msgid="6821513401870377403">"Komesha programu zinazoendeshwa"</string>
<string name="permdesc_removeTasks" msgid="1394714352062635493">"Huruhusu programu kuondoa majukumu na kuua programu zao. Programu hasidi zinaweza kutatiza tabia ya programu zingine."</string>
<string name="permlab_startAnyActivity" msgid="2918768238045206456">"anzisha shughuli yoyote"</string>
@@ -301,7 +301,7 @@
<string name="permlab_signalPersistentProcesses" msgid="4539002991947376659">"Tuma ishara za Linux kwa programu"</string>
<string name="permdesc_signalPersistentProcesses" msgid="4896992079182649141">"Inaruhusu programu kuomba ishara iliyotolewa kutumwa kwa michakato inyoendelea."</string>
<string name="permlab_persistentActivity" msgid="8841113627955563938">"Fanya programu kuendeshwa kila mara"</string>
- <string name="permdesc_persistentActivity" product="tablet" msgid="8525189272329086137">"Inaruhusu programu kuendelesha vijisehemu vyake kwenye kumbukumbu. Hii inaweza kupunguza kumbukumbu inayopatikana katika programu nyingine ikipunguza kasi ya kompyuta ndogo."</string>
+ <string name="permdesc_persistentActivity" product="tablet" msgid="8525189272329086137">"Inaruhusu programu kuendeleza vijisehemu vyake kwenye kumbukumbu. Hii inaweza kupunguza kumbukumbu inayopatikana katika programu nyingine ikipunguza kasi ya kompyuta ndogo."</string>
<string name="permdesc_persistentActivity" product="default" msgid="4384760047508278272">"Inaruhusu programu kuendelesha vijisehemu vyake kwenye kumbukumbu. Hii inaweza kupunguza kumbukumbu inayopatikana katika programu nyingine ikipunguza kasi ya simu."</string>
<string name="permlab_deletePackages" msgid="184385129537705938">"futa programu"</string>
<string name="permdesc_deletePackages" msgid="7411480275167205081">"Inaruhusu programu kufuta furushi za Android. Programu hasidi zinaweza kutumia hii kufuta programu muhimu."</string>
@@ -342,17 +342,17 @@
<string name="permdesc_receiveBootCompleted" product="tablet" msgid="7390304664116880704">"Inaruhusu programu yenyewe kujianzisha baada ya mfumo kumaliza kuuanza upya. Hii inaweza kufanya ichukue muda mrefu kuanza kompyuta kibao na kuruhusu programu kupunguza kasi ya kompyuta kibao kijumla kwa kuendeshwa siku zote."</string>
<string name="permdesc_receiveBootCompleted" product="default" msgid="513950589102617504">"Inaruhusu programu kujianzisha yenyewe mfumo unapo maliza kuanza upya. Hii inaweza kuchukua muda mrefu simu kuanza na kuruhusu programu kupunguza kasi ya simu kwa jumla kwa kuendeshwa polepole kila wakati."</string>
<string name="permlab_broadcastSticky" msgid="7919126372606881614">"tuma tangazo la kulanata"</string>
- <string name="permdesc_broadcastSticky" product="tablet" msgid="7749760494399915651">"Inaruhusu programu kutuma matangazo nata, ambayo hubakia baada ya matangazo kuisha. Matumizi zaidi yanaweza kufanya kompyuta ndogo kufanya kazi polepole au kuifanya isiwe thabiti kwa kuisababisha itumie kumbukumbu kubwa zaidi."</string>
+ <string name="permdesc_broadcastSticky" product="tablet" msgid="7749760494399915651">"Inaruhusu programu kutuma matangazo nata, ambayo hubakia baada ya matangazo kuisha. Matumizi zaidi yanaweza kufanya kompyuta kibao kufanya kazi polepole au kuifanya isiwe thabiti kwa kuisababisha itumie kumbukumbu kubwa zaidi."</string>
<string name="permdesc_broadcastSticky" product="default" msgid="2825803764232445091">"Inaruhusu programu kutuma matangazo nata, ambayo hubakia baada ya matangazo kuisha. Matumizi zaidi yanaweza kufanya simu kufanya kazi polepole au kuifanya isiwe thabiti kwa kuisababisha itumie kumbukumbu kubwa zaidi."</string>
<string name="permlab_readContacts" msgid="8348481131899886131">"soma anwani zako"</string>
- <string name="permdesc_readContacts" product="tablet" msgid="5294866856941149639">"Inaruhusu programu kusoma data kuhusu anwani zako zilizohifadhiwa kwenye kompyuta yako ndogo, ikijumulisha kasi ambayo umepiga simu, kutuma barua pepe au kuwasiliana kwa njia zingine na watu maalum. Idhini hii inaruhusu programu kuhifadhi data yako ya anwani, na programu hasidi zinaweza kushiriki data ya anwani bila ya kujua kwako."</string>
- <string name="permdesc_readContacts" product="default" msgid="8440654152457300662">"Inaruhusu programu kusoma data kuhusu anwani zako zilizohifadhiwa kwenye simu yako, ikijumulisha kasi ambayo umepiga simu, kutuma barua pepe au kuwasiliana kwa njia zingine na watu maalum. Idhini hii inaruhusu programu kuhifadhi data yako ya anwani, na programu hasidi zinaweza kushiriki data ya anwani bila ya kujua kwako."</string>
+ <string name="permdesc_readContacts" product="tablet" msgid="5294866856941149639">"Inaruhusu programu kusoma data kuhusu anwani zako zilizohifadhiwa kwenye kompyuta kibao yako, ikiwa ni pamoja na mara ngapi umepiga simu, kutuma barua pepe au kuwasiliana kwa njia zingine na watu fulani. Idhini hii inaruhusu programu kuhifadhi data yako ya anwani, na programu hasidi zinaweza kushiriki data ya anwani bila ya kujua kwako."</string>
+ <string name="permdesc_readContacts" product="default" msgid="8440654152457300662">"Inaruhusu programu kusoma data kuhusu anwani zako zilizohifadhiwa kwenye simu yako, ikiwa ni pamoja na mara ngapi umepiga simu, kutuma barua pepe au kuwasiliana kwa njia zingine na watu fulani. Idhini hii inaruhusu programu kuhifadhi data yako ya anwani, na programu hasidi zinaweza kushiriki data ya anwani bila ya kujua kwako."</string>
<string name="permlab_writeContacts" msgid="5107492086416793544">"rekebisha anwani zako"</string>
- <string name="permdesc_writeContacts" product="tablet" msgid="897243932521953602">"Inaruhusu programu kurekebisha data kuhusu anwani zako zilizohifadhiwa kwenye kompyuta yako ndogo, ikijumulisha kasi ya kupiga simu, kutuma barua pepe, au kuwasiliana kwa njia nyingine na wawasiliani maalum. Idhini hii inaruhusu programu kufuta data ya anwani."</string>
- <string name="permdesc_writeContacts" product="default" msgid="589869224625163558">"Inaruhusu programu kurekebisha data kuhusu anwani zako zilizohifadhiwa kwenye kompyuta yako ndogo, ikijumulisha kasi ya kupiga simu, kutuma barua pepe, au kuwasiliana kwa njia nyingine na wawasiliani maalum. Idhini hii inaruhusu programu kufuta data ya anwani."</string>
+ <string name="permdesc_writeContacts" product="tablet" msgid="897243932521953602">"Inaruhusu programu kurekebisha data kuhusu anwani zako zilizohifadhiwa kwenye kompyuta kibao yako, ikijumuisha ni mara ngapi umepiga simu, kutuma barua pepe, au kuwasiliana kwa njia nyingine na wawasiliani maalum. Idhini hii inaruhusu programu kufuta data ya anwani."</string>
+ <string name="permdesc_writeContacts" product="default" msgid="589869224625163558">"Inaruhusu programu kurekebisha data kuhusu anwani zako zilizohifadhiwa kwenye simu yako, ikijumuisha ni mara ngapi umepiga simu, kutuma barua pepe, au kuwasiliana kwa njia nyingine na wawasiliani maalum. Idhini hii inaruhusu programu kufuta data ya anwani."</string>
<string name="permlab_readCallLog" msgid="3478133184624102739">"soma rajisi ya simu"</string>
- <string name="permdesc_readCallLog" product="tablet" msgid="3700645184870760285">"Inaruhusu programu kusoma rajisi ya simu ya kompyuta yako ndogo, ikijumulisha data kuhusu simu zinazoingia na zinazotoka. Idhini hii inaruhusu programu kuhifadhi data ya rajisi ya simu yako, na programu hasidi zinaweza kushiriki data ya rajisi ya simu bila ya kujua kwako."</string>
- <string name="permdesc_readCallLog" product="default" msgid="5777725796813217244">"Inaruhusu programu kusoma rajisi ya simu ya simu yako, ikijumulisha data kuhusu simu zinazoingia na zinazotoka. Idhini hii inaruhusu programu kuhifadhi data ya rajisi ya simu yako, na programu hasidi zinaweza kushiriki data ya rajisi ya simu bila ya kujua kwako."</string>
+ <string name="permdesc_readCallLog" product="tablet" msgid="3700645184870760285">"Inaruhusu programu kusoma rajisi ya simu ya kompyuta kibao yako, ikijumuisha data kuhusu simu zinazoingia na zinazotoka. Idhini hii inaruhusu programu kuhifadhi data ya rajisi ya simu yako, na programu hasidi zinaweza kushiriki data ya rajisi ya simu bila ya kujua kwako."</string>
+ <string name="permdesc_readCallLog" product="default" msgid="5777725796813217244">"Inaruhusu programu kusoma rajisi ya simu ya simu yako, ikijumuisha data kuhusu simu zinazoingia na zinazotoka. Idhini hii inaruhusu programu kuhifadhi data ya rajisi ya simu yako, na programu hasidi zinaweza kushiriki data ya rajisi ya simu bila ya kujua kwako."</string>
<string name="permlab_writeCallLog" msgid="8552045664743499354">"andika rajisi ya simu"</string>
<string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"Huruhusu programu kurekebisha rajisi ya kompyuta kibao yako, ikiwa ni pamoja na simu zinazoingia na kutoka. Huenda programu hasidi zikatumia hii ili kufuta au kurekebisha rajisi ya simu yako."</string>
<string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"Huruhusu programu kurekebisha rajisi ya simu yako, ikiwa ni pamoja na simu zinazoingia na kutoka. Huenda programu hasidi zikatumia hii ili kufuta au kurekebisha rajisi ya simu yako."</string>
@@ -361,24 +361,24 @@
<string name="permlab_writeProfile" msgid="907793628777397643">"rekebisha kadi yako mwenyewe ya mawasiliano"</string>
<string name="permdesc_writeProfile" product="default" msgid="5552084294598465899">"Inaruhusu programu kubadilisha au kuongeza taarifa ya maelezo mafupi ya kibinafsi yaliyohifadhiwa kwenye kifaa chako, kama vile jina lako na taarifa ya anwani. Hii inamaanisha kuwa programu inaweza kukutambua na inaweza kutuma taarifa ya maelezo yako mafupi kwa wengine."</string>
<string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"soma mipasho yako wa kijamii"</string>
- <string name="permdesc_readSocialStream" product="default" msgid="4255706027172050872">"Inaruhusu programu kufikia na kupatanisha sasisho za kijamii kutoka kwa marafiki zako. Kuwa makini wakati unashiriki taarifa -- hii inaruhusu programu kusoma mawasiliano kati yako na marafiki zako kwenye mitandao ya jamii, bila kujali usiri. Kumbuka: idhini hii haiwezi kutekelezwa kwenye mitandao ya jamii yote."</string>
+ <string name="permdesc_readSocialStream" product="default" msgid="4255706027172050872">"Inaruhusu programu kufikia na kupatanisha sasisho za kijamii kutoka kwa marafiki zako. Kuwa makini wakati unashiriki taarifa -- hii inaruhusu programu kusoma mawasiliano kati yako na marafiki zako kwenye mitandao ya jamii, bila kujali usiri. Kumbuka: idhini hii haiwezi kutekelezwa kwenye mitandao yote ya jamii."</string>
<string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"andika kwa mipasho yako wa kijamii"</string>
- <string name="permdesc_writeSocialStream" product="default" msgid="3086557552204114849">"Inaruhusu programu kuonyesha sasisho za kijamii kutoka kwa marafiki zako. Kuwa makini wakati unashiriki taarifa -- hii inaruhusu programu kutoa ujumbe unaoweza kuonekana kuwa unatoka kwa rafiki. Kumbuka: idhini hii huenda usitekelezwe kwenye mitandao yate ya kijamii."</string>
+ <string name="permdesc_writeSocialStream" product="default" msgid="3086557552204114849">"Inaruhusu programu kuonyesha sasisho za kijamii kutoka kwa marafiki zako. Kuwa makini wakati unashiriki taarifa -- hii inaruhusu programu kutoa ujumbe unaoweza kuonekana kuwa unatoka kwa rafiki. Kumbuka: idhini hii huenda usitekelezwe kwenye mitandao yote ya kijamii."</string>
<string name="permlab_readCalendar" msgid="5972727560257612398">"soma matukio ya kalenda pamoja na maelezo ya siri"</string>
- <string name="permdesc_readCalendar" product="tablet" msgid="4216462049057658723">"Inaruhusu programu kusoma matukio yote ya kalenda yaliohifadhiwa kwenye kompyuta yako ndogo, yakijumulisha yale ya marafiki au wafanyakazi wenza. Hii inaweza kuruhusu programu kushiriki au kuhifadhi data yako ya kaelnda, bila kujali usiri au unyeti."</string>
- <string name="permdesc_readCalendar" product="default" msgid="7434548682470851583">"Inaruhusu programu kusoma matukio yote ya kalenda yaliyohifadhiwa kwenye simu yako, pamoja na yale ya marafiki au wafanyakazi wenza. Hii inaweza kuruhusu programu kushiriki au kuhifashi data yako ya kalenda, bila kujali usiri au umuhimu."</string>
+ <string name="permdesc_readCalendar" product="tablet" msgid="4216462049057658723">"Inaruhusu programu kusoma matukio yote ya kalenda yaliohifadhiwa kwenye kompyuta kibao yako, yakijumuisha yale ya marafiki au wafanyakazi wenza. Hii inaweza kuruhusu programu kushiriki au kuhifadhi data yako ya kaelnda, bila kujali usiri au unyeti."</string>
+ <string name="permdesc_readCalendar" product="default" msgid="7434548682470851583">"Inaruhusu programu kusoma matukio yote ya kalenda yaliyohifadhiwa kwenye simu yako, pamoja na yale ya marafiki au wafanyakazi wenza. Hii inaweza kuruhusu programu kushiriki au kuhifadhi data yako ya kalenda, bila kujali usiri au umuhimu."</string>
<string name="permlab_writeCalendar" msgid="8438874755193825647">"ongeza au rekebisha matukio ya kalenda na utume barua pepe kwa wageni bila ufahamu wa mmiliki"</string>
- <string name="permdesc_writeCalendar" product="tablet" msgid="6679035520113668528">"Inaruhusu programu kuongeza, kuondoa matukio ambayo unaweza kurekebisha kwenye kompyuta yako ndogo, yakijumulisha yale ya marafiki na wafanyakazi wenza. Hii inaweza kuruhusu programu kutuma ujumbe yanaonekana kuwa yanatoka kwa wamiliki wa kalenda, au kurekebisha matukio bila ya kujua kwa mmiliki."</string>
- <string name="permdesc_writeCalendar" product="default" msgid="2324469496327249376">"Inaruhusu programu kuongeza, kuondoa matukio ambayo unaweza kurekebisha kwenye kompyuta yako ndogo, yakijumulisha yale ya marafiki na wafanyakazi wenza. Hii inaweza kuruhusu programu kutuma ujumbe yanaonekana kuwa yanatoka kwa wamiliki wa kalenda, au kurekebisha matukio bila ya kujua kwa mmiliki."</string>
+ <string name="permdesc_writeCalendar" product="tablet" msgid="6679035520113668528">"Inaruhusu programu kuongeza, kuondoa, kubadilisha matukio ambayo unaweza kurekebisha kwenye kompyuta kibao yako, yakijumulisha yale ya marafiki na wafanyakazi wenza. Hii inaweza kuruhusu programu kutuma ujumbe unaonekana kuwa unatoka kwa mmiliki wa kalenda, au kurekebisha matukio bila mmiliki kujua."</string>
+ <string name="permdesc_writeCalendar" product="default" msgid="2324469496327249376">"Inaruhusu programu kuongeza, kuondoa, kubadilisha matukio ambayo unaweza kurekebisha kwenye simu yako, yakijumulisha yale ya marafiki na wafanyakazi wenza. Hii inaweza kuruhusu programu kutuma ujumbe unaonekana kuwa unatoka kwa mmiliki wa kalenda, au kurekebisha matukio bila mmiliki kujia."</string>
<string name="permlab_accessMockLocation" msgid="8688334974036823330">"vyanzo vya jaribio la mahali kwa lengo la majaribio"</string>
- <string name="permdesc_accessMockLocation" msgid="5808711039482051824">"Unda vyanzo vya majaribio ya eneo vya kujaribu au sakinisha mtoaji huduma mpya wa eneo. Hii inaruhusu programu kufuta eneo na/au hali inayorudishwa na vyanzo vingine vya eneo kama vile GPS au watoaji huduma wa eneo."</string>
+ <string name="permdesc_accessMockLocation" msgid="5808711039482051824">"Unda vyanzo vya majaribio ya eneo vya kujaribia au usakinishe mtoaji huduma mpya wa eneo. Hii inaruhusu programu kufuta eneo na/au hali inayorudishwa na vyanzo vingine vya eneo kama vile GPS au watoaji huduma wa eneo."</string>
<string name="permlab_accessLocationExtraCommands" msgid="2836308076720553837">"fikia amri za ziada za mtoa huduma ya mahali"</string>
<string name="permdesc_accessLocationExtraCommands" msgid="5945166642335800763">"Huruhusu programu kufikia amri za ziada za mtoaji huduma wa eneo. Hii inaweza kuruhusu programu kuhitilafiana na uendeshaji wa GPS au vyanzo vingine vya eneo."</string>
<string name="permlab_installLocationProvider" msgid="6578101199825193873">"kibali ili kusakinisha mtoa huduma ya mahali"</string>
- <string name="permdesc_installLocationProvider" msgid="9066146120470591509">"Unda vyanzo vya eneo la majaribio vya kujaribu au kusakinisha mtoaji huduma mpya wa eneo. Hii inaruhusu programu kufuta eneo na/auhali zilizorudishwa na vyanzo vingine vya eneo kama vile GPS au watoaji huduma wa eneo."</string>
+ <string name="permdesc_installLocationProvider" msgid="9066146120470591509">"Unda vyanzo vya eneo la majaribio vya kujaribu au kusakinisha mtoaji huduma mpya wa eneo. Hii inaruhusu programu kufuta eneo na/au hali zilizorudishwa na vyanzo vingine vya eneo kama vile GPS au watoaji huduma wa eneo."</string>
<string name="permlab_accessFineLocation" msgid="5885550969882561436">"eneo halisi la (GPS)"</string>
- <string name="permdesc_accessFineLocation" product="tablet" msgid="8960597421469894181">"Fikia vyanzo vya eneo sahihi kama vile Mfumo wa Global Positioning kwenye kompyuta ndogo. Wakati huduma za eneo zinapatikana na kuwashwa, kibali hiki kinaruhusu programu kuthibitisha eneo lako sahihi."</string>
- <string name="permdesc_accessFineLocation" product="default" msgid="239268765496141815">"Fikia vyanzo vya eneo sahihi kama vile Mfumo wa Global Positioning kwenye simu. Wakati huduma za eneo zinapatikana na kuwashwa, kibali hiki kinaruhusu programu kuthibitisha eneo lako sahihi."</string>
+ <string name="permdesc_accessFineLocation" product="tablet" msgid="8960597421469894181">"Fikia vyanzo vya eneo sahihi kama vile Mfumo wa Global Positioning kwenye kompyuta ndogo. Wakati huduma za eneo zinapatikana na kuwashwa, kibali hiki kinaruhusu programu kuthibitisha eneo lako kamili."</string>
+ <string name="permdesc_accessFineLocation" product="default" msgid="239268765496141815">"Fikia vyanzo vya eneo sahihi kama vile Mfumo wa Global Positioning kwenye simu. Wakati huduma za eneo zinapatikana na zimewashwa, kibali hiki kinaruhusu programu kuthibitisha eneo lako kamili."</string>
<string name="permlab_accessCoarseLocation" msgid="7422827215441638984">"eneo karibu (linalotegemea mtandao)"</string>
<string name="permdesc_accessCoarseLocation" msgid="5383798877137640762">"Fikia kadirio la eneo lako kutoka kwa watoaji huduma wa eneo kwa kutumia vyanzo vya mtandao kama vile mnara wa seli na Wi-Fi. Wakati huduma hizi za eneo zinapatikana na kuwashwa, kibali hiki kinaruhusu programu kuthibitisha kadirio la eneo lako."</string>
<string name="permlab_accessSurfaceFlinger" msgid="2363969641792388947">"fikia SurfaceFlinger"</string>
@@ -388,7 +388,7 @@
<string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"badilisha mipangilio yako ya sauti"</string>
<string name="permdesc_modifyAudioSettings" msgid="3522565366806248517">"Inaruhusu programu kurekebisha mipangilio ya sauti kila mahali kama vile sauti na ni kipaza sauti kipi ambacho kinatumika kwa kutoa."</string>
<string name="permlab_recordAudio" msgid="3876049771427466323">"rekodi sauti"</string>
- <string name="permdesc_recordAudio" msgid="4906839301087980680">"Inaruhusu programu kurekodi sauti kwa kipokea sauti. Idhini hii inaruhusu programu kurekodi sauti wakati wowote bila ya uthibitisho wako."</string>
+ <string name="permdesc_recordAudio" msgid="4906839301087980680">"Inaruhusu programu kurekodi sauti kwa kinasa sauti. Idhini hii inaruhusu programu kurekodi sauti wakati wowote bila ya uthibitisho wako."</string>
<string name="permlab_camera" msgid="3616391919559751192">"chukua picha na video"</string>
<string name="permdesc_camera" msgid="8497216524735535009">"Inaruhusu programu kupiga picha na video kwa kamera. Kibali hiki kinaruhusu programu kutumia kamera kwa wakati wowote bila uthibitisho wako."</string>
<string name="permlab_brick" product="tablet" msgid="2961292205764488304">"lemaza kompyuta ndogo kabisa"</string>
@@ -426,7 +426,7 @@
<string name="permlab_hardware_test" msgid="4148290860400659146">"jaribu maunzi"</string>
<string name="permdesc_hardware_test" msgid="6597964191208016605">"Inaruhusu programu kudhibiti vifaa mbalimbali kwa lengo la kujaribia maunzi."</string>
<string name="permlab_callPhone" msgid="3925836347681847954">"piga simu moja kwa moja kwa nambari za simu"</string>
- <string name="permdesc_callPhone" msgid="3740797576113760827">"Inaruhusu programu kupiga nambari za simu bila ya wewe kuingilia kati. Hii inaweza sababisha gharama zisizotarajiwa au simu. Kumbuka kuwa hii hairuhusu programu kupiga nambari za dharura. Programu hasidi zinaweza kukugharimu pesa kwa kupiga simu bila uthibitisho wako."</string>
+ <string name="permdesc_callPhone" msgid="3740797576113760827">"Inaruhusu programu kupiga nambari za simu bila ya wewe kuingilia kati. Hii inaweza kusababisha gharama zisizotarajiwa au simu. Kumbuka kuwa hii hairuhusu programu kupiga nambari za dharura. Programu hasidi zinaweza kukugharimu pesa kwa kupiga simu bila uthibitisho wako."</string>
<string name="permlab_callPrivileged" msgid="4198349211108497879">"piga simu moja kwa moja kwa nambari zozote za simu"</string>
<string name="permdesc_callPrivileged" msgid="1689024901509996810">"Inaruhusu programu kupiga namba yoyote ya simu, ikiwa ni pamoja na namba za dharura, bila wewe kuingilia kati.Programu hasidi zinaweza piga simu zisizo za lazima na haramu kwa huduma za dharura."</string>
<string name="permlab_performCdmaProvisioning" product="tablet" msgid="4842576994144604821">"anzisha usanidi wa kompyuta ndogo ya CDMA moja kwa moja"</string>
@@ -441,7 +441,7 @@
<string name="permlab_modifyPhoneState" msgid="8423923777659292228">"badiliisha hali ya simu"</string>
<string name="permdesc_modifyPhoneState" msgid="1029877529007686732">"Inaruhusu programu kudhibiti vipengee vya kifaa. Programu iliyo na ruhusa hii inaweza badilisha mtandao, kuzima na kuwasha redio ya simu bila hata kukujulisha."</string>
<string name="permlab_readPhoneState" msgid="9178228524507610486">"soma hali ya simu na kitambulisho"</string>
- <string name="permdesc_readPhoneState" msgid="1639212771826125528">"Inaruhusu programu kufikia vipengele vya simu vya kifaa. Idhini hii inaruhusu programu tambulisho wa nambari ya simu na kifaa, kama simu ni amilifu, na nambari ya kidhibiti mbali kuunganishwa kwa simu."</string>
+ <string name="permdesc_readPhoneState" msgid="1639212771826125528">"Inaruhusu programu kufikia vipengele vya simu vya kifaa. Idhini hii inaruhusu programu kutambua nambari ya simu na kifaa, kama simu ni amilifu, na nambari ya mbali iliyounganishwa kwa simu."</string>
<string name="permlab_wakeLock" product="tablet" msgid="1531731435011495015">"zuia kompyuta ndogo dhidi ya kulala"</string>
<string name="permlab_wakeLock" product="default" msgid="573480187941496130">"zuia simu dhidi ya kulala"</string>
<string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"Inaruhusu programu kuzuia kompyuta kibao kwenda kulala."</string>
@@ -468,8 +468,8 @@
<string name="permlab_accountManagerService" msgid="4829262349691386986">"tenda kama Huduma ya Meneja wa Akaunti"</string>
<string name="permdesc_accountManagerService" msgid="1948455552333615954">"Huruhusu programu kupiga simu kwa Wathibitishaji Akaunti."</string>
<string name="permlab_getAccounts" msgid="1086795467760122114">"pata akaunti kwenye kifaa"</string>
- <string name="permdesc_getAccounts" product="tablet" msgid="2741496534769660027">"Inaruhusu programu kupata orodha ya akaunti zinazojulikana kwa kompyuta ndogo. Hii inaweza kujumlisha akaunti zozote zilizoundwa na programu ambazo umesakinisha."</string>
- <string name="permdesc_getAccounts" product="default" msgid="3448316822451807382">"Inaruhusu programu kupata orodha ya akaunti zinazojulikana kwa simu. Hii inaweza kujumlisha akaunti zozote zilizoundwa na programu ambazo umesakinisha."</string>
+ <string name="permdesc_getAccounts" product="tablet" msgid="2741496534769660027">"Inaruhusu programu kupata orodha ya akaunti zinazojulikana kwa kompyuta kibao. Hii inaweza kujumuisha akaunti zozote zilizoundwa na programu ambazo umesakinisha."</string>
+ <string name="permdesc_getAccounts" product="default" msgid="3448316822451807382">"Inaruhusu programu kupata orodha ya akaunti zinazojulikana kwa simu. Hii inaweza kujumuisha akaunti zozote zilizoundwa na programu ambazo umesakinisha."</string>
<string name="permlab_authenticateAccounts" msgid="5265908481172736933">"unda akaunti na weka manenosiri"</string>
<string name="permdesc_authenticateAccounts" msgid="5472124296908977260">"Inaruhusu programu kutumia uwezo wa uthibitishaji akaunti wa KidhibitiAkaunti, pamoja na kuunda akaunti na kupata na kuweka nywila zao."</string>
<string name="permlab_manageAccounts" msgid="4983126304757177305">"ongeza au uondoe akaunti"</string>
@@ -491,31 +491,31 @@
<string name="permlab_accessWifiState" msgid="5202012949247040011">"ona miunganisho ya Wi-Fi"</string>
<string name="permdesc_accessWifiState" msgid="5002798077387803726">"Inaruhusu programu kuona taarifa kuhusu mtandao wa Wi-Fi, kama vile ikiwa Wi-Fi imewezeshwa mna jina la vifaa vya Wi-Fi vilivyounganishwa."</string>
<string name="permlab_changeWifiState" msgid="6550641188749128035">"unganisha na utenganishe kutoka kwa Wi-Fi"</string>
- <string name="permdesc_changeWifiState" msgid="7137950297386127533">"Inaruhusu programu kuunganisha kwenye au kuachanisha kutoka pointi za ufikivu wa Wi-Fi na kufanya mabadiliko kwenye usanidi wa kifaa cha mitandao ya Wi-Fi."</string>
+ <string name="permdesc_changeWifiState" msgid="7137950297386127533">"Inaruhusu programu kuunganisha kwenye au kukata kutoka pointi za ufikivu wa Wi-Fi na kufanya mabadiliko kwenye usanidi wa kifaa cha mitandao ya Wi-Fi."</string>
<string name="permlab_changeWifiMulticastState" msgid="1368253871483254784">"ruhusu upokeaji wa Wi-Fi Multicast"</string>
- <string name="permdesc_changeWifiMulticastState" product="tablet" msgid="7969774021256336548">"Inaruhusu programu kupokea pakiti zilizotumwa katika vifaa vyote kwenye mtandao wa Wi-Fi kwa kutumia anwani za upeperushaji anuwai, sio tu kompyuta yako ndogo. Inatumia nguvu zaidi kuliko modi ya upeperushaji usiyo anuwai."</string>
- <string name="permdesc_changeWifiMulticastState" product="default" msgid="6851949706025349926">"Inaruhusu programu kupokea pakiti zilizotumwa katika vifaa vyote kwenye mtandao wa Wi-Fi kwa kutumia anwani za upeperushaji anuwai, sio tu simu yako. Inatumia nguvu zaidi kuliko modi ya upeperushaji usiyo anuwai."</string>
+ <string name="permdesc_changeWifiMulticastState" product="tablet" msgid="7969774021256336548">"Inaruhusu programu kupokea pakiti zilizotumwa katika vifaa vyote kwenye mtandao wa Wi-Fi kwa kutumia anwani za upeperushaji anuwai, sio tu kompyuta yako kibao. Inatumia nguvu zaidi kuliko mfumo wa upeperushaji usio anuwai."</string>
+ <string name="permdesc_changeWifiMulticastState" product="default" msgid="6851949706025349926">"Inaruhusu programu kupokea pakiti zilizotumwa katika vifaa vyote kwenye mtandao wa Wi-Fi kwa kutumia anwani za upeperushaji anuwai, sio tu simu yako. Inatumia nguvu zaidi kuliko mfumo wa upeperushaji usio anuwai."</string>
<string name="permlab_bluetoothAdmin" msgid="6006967373935926659">"fikia mipangilio ya Bluetooth"</string>
<string name="permdesc_bluetoothAdmin" product="tablet" msgid="6921177471748882137">"Inaruhusu programu kusanidi kompyuta kibao ya karibu ya Bluetooth na kutambua na kuoanisha na vifaa vya kudhibiti."</string>
<string name="permdesc_bluetoothAdmin" product="default" msgid="8931682159331542137">"Inaruhusu programu kusanidi simu ya karibu ya Bluetooth, na kutambua na kuoanisha na vifaa vya mbali."</string>
<string name="permlab_accessWimaxState" msgid="7436749103151096452">"Ona miunganisho ya WiMAX"</string>
<string name="permdesc_accessWimaxState" msgid="6360102877261978887">"Inaruhusu programu kuthibitisha ikiwa WiMAX imewezeshwa na taarifa kuhusu mitandao yoyote ya WiMAX ambayo imeunganishwa."</string>
<string name="permlab_changeWimaxState" msgid="2405042267131496579">"Badilisha hali ya WiMAX"</string>
- <string name="permdesc_changeWimaxState" product="tablet" msgid="3156456504084201805">"Inaruhusu programu kuunganisha kompyuta ndogo kwenye na kuachanisha kompyuta ndogo kutoka mitandao ya WiMAX."</string>
- <string name="permdesc_changeWimaxState" product="default" msgid="697025043004923798">"Inaruhusu programu kuunganisha simu kwenye na kuachanisha simu kutoka mitandao ya WiMAX."</string>
+ <string name="permdesc_changeWimaxState" product="tablet" msgid="3156456504084201805">"Inaruhusu programu kuunganisha kompyuta kibao, na kukata kompyuta kibao kutoka mitandao ya WiMAX."</string>
+ <string name="permdesc_changeWimaxState" product="default" msgid="697025043004923798">"Inaruhusu programu kuunganisha simu kwenye, na kukata simu kutoka mitandao ya WiMAX."</string>
<string name="permlab_bluetooth" msgid="6127769336339276828">"oanisha na vifaa vya Bluetooth"</string>
- <string name="permdesc_bluetooth" product="tablet" msgid="3480722181852438628">"Inaruhusu programu kuona usanidi wa Bluetooth kwenye kompyuta ndogo, na kuunda na kukubali miunganisho kwa vifaa vilivyooanishwa."</string>
+ <string name="permdesc_bluetooth" product="tablet" msgid="3480722181852438628">"Inaruhusu programu kuona usanidi wa Bluetooth kwenye kompyuta kibao, na kuunda na kukubali miunganisho kwa vifaa vilivyooanishwa."</string>
<string name="permdesc_bluetooth" product="default" msgid="3207106324452312739">"Inaruhusu programu kuona usanidi wa Bluetooth kwenye simu, na kuunda na kukubali miunganisho kwa vifaa vilivyooanishwa."</string>
<string name="permlab_nfc" msgid="4423351274757876953">"dhibiti Mawasiliano Karibu na Uga"</string>
<string name="permdesc_nfc" msgid="7120611819401789907">"Inaruhusu programu kuwasiliana na lebo, kadi na wasomaji wa Near Field Communication (NFC)."</string>
<string name="permlab_disableKeyguard" msgid="3598496301486439258">"lemaza kufuli la skrini yako"</string>
- <string name="permdesc_disableKeyguard" msgid="6034203065077122992">"Inaruhusu programu kulemaza ufunguo wa vitufe na usalama mwingine husiani wa nenosiri. Kwa mfano, simu inalemaza ufunguo wa viitufe inapopokea simu inayoingia, kisha inawezesha upya ufunguo wa vitufe wakati simu inapokamilika."</string>
+ <string name="permdesc_disableKeyguard" msgid="6034203065077122992">"Inaruhusu programu kulemaza ufunguo wa vitufe na usalama mwingine ambata wa nenosiri. Kwa mfano, simu inalemaza ufunguo wa viitufe inapopokea simu inayoingia, kisha inawezesha upya ufunguo wa vitufe wakati simu inapokamilika."</string>
<string name="permlab_readSyncSettings" msgid="6201810008230503052">"soma mipangilio ya usawazishaji"</string>
<string name="permdesc_readSyncSettings" msgid="2706745674569678644">"Inaruhusu programu kusoma mipangilio ya upatanishi wa akaunti. Kwa mfano, huku kunaweza kuamua kama programu ya Watu imepatanishwa na akaunti."</string>
<string name="permlab_writeSyncSettings" msgid="5408694875793945314">"washa na zima ulandanishi"</string>
- <string name="permdesc_writeSyncSettings" msgid="8956262591306369868">"Inaruhusu programu kurekebisha mipangalio ya upatanishi wa akaunti. Kwa mfano, hii inaweza kuwesha programu ya upatanishi wa Watu na akaunti."</string>
+ <string name="permdesc_writeSyncSettings" msgid="8956262591306369868">"Inaruhusu programu kurekebisha mipangalio ya upatanishi wa akaunti. Kwa mfano, hii inaweza kuwezesha programu ya upatanishi wa Watu na akaunti."</string>
<string name="permlab_readSyncStats" msgid="7396577451360202448">"soma takwimu za usawazishaji"</string>
- <string name="permdesc_readSyncStats" msgid="1510143761757606156">"Inaruhusu programu kusoma takwimu za upatanishi za akaunti, zikijumulisha historia ya matukio ya upatanishi na kiasi kipi cha data kimepatanishwa."</string>
+ <string name="permdesc_readSyncStats" msgid="1510143761757606156">"Inaruhusu programu kusoma takwimu za upatanishi za akaunti, ikiwa ni pamoja na historia ya matukio ya upatanishi na kiasi cha data kimepatanishwa."</string>
<string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"soma milisho ya kujiunga"</string>
<string name="permdesc_subscribedFeedsRead" msgid="5557058907906144505">"Inaruhusu programu kupata maelezo kuhusu mlisho iliyolandanishwa kwa sasa."</string>
<string name="permlab_subscribedFeedsWrite" msgid="9015246325408209296">"andika milisho ya kujiunga"</string>
@@ -524,8 +524,8 @@
<string name="permdesc_readDictionary" msgid="659614600338904243">"Inaruhusu programu kusoma maneno, majina na misemo yote ambayo mtumiaji alihifadhi katika kamusi ya mtumiaji."</string>
<string name="permlab_writeDictionary" msgid="2296383164914812772">"andika kwa kamusi iliyobainishwa na mtumiaji"</string>
<string name="permdesc_writeDictionary" msgid="8185385716255065291">"Inaruhusu programu kuandika maneno mapya katika kamusi ya mtumiaji."</string>
- <string name="permlab_sdcardRead" product="nosdcard" msgid="8235341515605559677">"jaribu ufikiaji wa hifadhi iliyolindwa"</string>
- <string name="permlab_sdcardRead" product="default" msgid="8235341515605559677">"jaribu ufikiaji wa hifadhi iliyolindwa"</string>
+ <string name="permlab_sdcardRead" product="nosdcard" msgid="8235341515605559677">"jaribu mfikio kwa hifadhi iliyolindwa"</string>
+ <string name="permlab_sdcardRead" product="default" msgid="8235341515605559677">"jaribu mfikio kwa hifadhi iliyolindwa"</string>
<string name="permdesc_sdcardRead" product="nosdcard" msgid="5791957130190763289">"Inaruhusu programu kujaribu idhini ya hifadhi ya USB itakayokuwa kwenye vifaa vya baadaye."</string>
<string name="permdesc_sdcardRead" product="default" msgid="5914402684685848828">"Inaruhusu programu kujaribu idhini ya kadi ya SD itakayokuwa kwenye vifaa vya baadaye."</string>
<string name="permlab_sdcardWrite" product="nosdcard" msgid="8485979062254666748">"rekebisha au ufute maudhui ya hifadhi yako ya USB"</string>
@@ -784,9 +784,9 @@
<string name="autofill_area" msgid="3547409050889952423">"Eneo"</string>
<string name="autofill_emirate" msgid="2893880978835698818">"Emirate"</string>
<string name="permlab_readHistoryBookmarks" msgid="3775265775405106983">"soma alamisho na historia ya Wavuti wako"</string>
- <string name="permdesc_readHistoryBookmarks" msgid="8462378226600439658">"Inaruhusu programu kusoma historia ya URL zote ambazo zimetembelewa na Kivinjari, na alamisho zote za Kivinjari. Kumbuka: idhini hii haiwezi kutekelezwa wavinjari wengine au programu zingine zenye uwezo wa kuvinjari."</string>
+ <string name="permdesc_readHistoryBookmarks" msgid="8462378226600439658">"Inaruhusu programu kusoma historia ya URL zote ambazo zimetembelewa na Kivinjari, na alamisho zote za Kivinjari. Kumbuka: idhini hii haiwezi kutekelezwa vivinjari vya vingine au programu zingine zenye uwezo wa kuvinjari."</string>
<string name="permlab_writeHistoryBookmarks" msgid="3714785165273314490">"andika alamisho na historia ya wavuti"</string>
- <string name="permdesc_writeHistoryBookmarks" product="tablet" msgid="6825527469145760922">"Inaruhusu programu kurekebisha historia ya Kivinjari au alamisho zilizohifadhiwa kwenye kompyuta yako ndogo. Hii inaruhusu programu kufuta au kurekebisha data ya Kivinjari. Kumbuka: huenda idhini hii isitekelezwe na kivinjari kingine au programu nyingine zenye uwezo wa kuvinjari wavuti."</string>
+ <string name="permdesc_writeHistoryBookmarks" product="tablet" msgid="6825527469145760922">"Inaruhusu programu kurekebisha historia ya Kivinjari au alamisho zilizohifadhiwa kwenye kompyuta kibao yako. Hii inaruhusu programu kufuta au kurekebisha data ya Kivinjari. Kumbuka: huenda idhini hii isitekelezwe na kivinjari kingine au programu nyingine zenye uwezo wa kuvinjari wavuti."</string>
<string name="permdesc_writeHistoryBookmarks" product="default" msgid="8497389531014185509">"Inaruhusu programu kurekebisha historia ya Kivinjari au vialamisho vilivyohifadhiwa kwenye simu yako. Hii huenda ikaruhusu programu kufuta au kurekebisha data ya Kivinjari. Kumbuka: huenda idhini hii isitekelezwe na vivinjari vingine au programu nyingine zenye uwezo wa kuvinjari wavuti."</string>
<string name="permlab_setAlarm" msgid="1379294556362091814">"weka kengele"</string>
<string name="permdesc_setAlarm" msgid="316392039157473848">"Inaruhusu programu kuweka kengele katika programu iliyosakinishwa ya kengele. Programu zingine za kengele zinawezakosa kutekeleza kipengee hiki."</string>
@@ -821,9 +821,9 @@
<string name="searchview_description_clear" msgid="1330281990951833033">"Futa swali"</string>
<string name="searchview_description_submit" msgid="2688450133297983542">"Wasilisha hoja"</string>
<string name="searchview_description_voice" msgid="2453203695674994440">"Utafutaji wa sauti"</string>
- <string name="enable_explore_by_touch_warning_title" msgid="7460694070309730149">"Wezesha Kuchunguza kwa Kugusa?"</string>
- <string name="enable_explore_by_touch_warning_message" product="tablet" msgid="8655887539089910577">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> inataka kuwezesha Kuchunguza kwa Kugusa. Wakati Kuchunguza kwa Kugusa kumewezeshwa, unaweza kusikia au kuona maelezo ya ni nini kilichochini ya kidole chako au kufanya ishara za kuingiliana na kumpyuta ndogo."</string>
- <string name="enable_explore_by_touch_warning_message" product="default" msgid="2708199672852373195">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> inataka kuwezesha Kuchunguza kwa Kugusa. Wakati Kuchunguza kwa Kugusa kumewezeshwa, unaweza kusikia au kuona maelezo ya ni nini kilichochini ya kidole chako au kufanya ishara za kuingiliana na simu."</string>
+ <string name="enable_explore_by_touch_warning_title" msgid="7460694070309730149">"Unataka kuwezesha Kuchunguza kwa Kugusa?"</string>
+ <string name="enable_explore_by_touch_warning_message" product="tablet" msgid="8655887539089910577">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> inataka kuwezesha Kuchunguza kwa Kugusa. Wakati Kuchunguza kwa Kugusa kumewezeshwa, unaweza kusikia au kuona maelezo ya kilicho chini ya kidole chako au kutumia ishara ili kuingiliana na kompyuta kibao."</string>
+ <string name="enable_explore_by_touch_warning_message" product="default" msgid="2708199672852373195">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> inataka kuwezesha Kuchunguza kwa Kugusa. Wakati Kuchunguza kwa Kugusa kumewezeshwa, unaweza kusikia au kuona maelezo ya kilicho chini ya kidole chako au kutumia ishara ili kuingiliana na simu."</string>
<string name="oneMonthDurationPast" msgid="7396384508953779925">"Mwezi 1 uliopita"</string>
<string name="beforeOneMonthDurationPast" msgid="909134546836499826">"Kabla ya mwezi 1 uliopita"</string>
<plurals name="num_seconds_ago">
@@ -1095,7 +1095,7 @@
<string name="use_physical_keyboard" msgid="6203112478095117625">"Kibodi halisi"</string>
<string name="hardware" msgid="7517821086888990278">"Maunzi"</string>
<string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"Teua mpangilio wa kibodi"</string>
- <string name="select_keyboard_layout_notification_message" msgid="4465907700449257063">"Gusa kuchagua mpangilio wa kibodi."</string>
+ <string name="select_keyboard_layout_notification_message" msgid="4465907700449257063">"Gusa ili kuchagua mpangilio wa kibodi."</string>
<string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="candidates_style" msgid="4333913089637062257"><u>"wagombeaji"</u></string>
@@ -1291,14 +1291,13 @@
<string name="SetupCallDefault" msgid="5834948469253758575">"Kubali simu?"</string>
<string name="activity_resolver_use_always" msgid="8017770747801494933">"Kila mara"</string>
<string name="activity_resolver_use_once" msgid="2404644797149173758">"Mara moja tu"</string>
- <string name="default_audio_route_name" product="tablet" msgid="6890731863195399186">"Vipaza sauti vya kompyuta ndogo"</string>
+ <string name="default_audio_route_name" product="tablet" msgid="6890731863195399186">"Vipaza sauti vya kompyuta kibao"</string>
<string name="default_audio_route_name" product="default" msgid="4551396562363128432">"Kipaza sauti cha simu"</string>
- <string name="default_audio_route_name_headphones" msgid="8119971843803439110">"Vipokea sauti"</string>
- <string name="default_audio_route_name_dock_speakers" msgid="6240602982276591864">"Vipasa sauti vya gati"</string>
+ <string name="default_audio_route_name_headphones" msgid="8119971843803439110">"Vipokeasauti"</string>
+ <string name="default_audio_route_name_dock_speakers" msgid="6240602982276591864">"Vipasa sauti vya kituo"</string>
<string name="default_audio_route_name_hdmi" msgid="7986404173839007682">"Sauti ya HDMI"</string>
<string name="default_audio_route_category_name" msgid="3722811174003886946">"Mfumo"</string>
- <!-- no translation found for bluetooth_a2dp_audio_route_name (8575624030406771015) -->
- <skip />
+ <string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"Sauti ya Bluetooth"</string>
<!-- no translation found for media_route_chooser_grouping_done (7966438307723317169) -->
<skip />
</resources>
diff --git a/core/res/res/values-sw600dp-land/arrays.xml b/core/res/res/values-sw600dp-land/arrays.xml
index 2b5fd99..5550216 100644
--- a/core/res/res/values-sw600dp-land/arrays.xml
+++ b/core/res/res/values-sw600dp-land/arrays.xml
@@ -57,7 +57,7 @@
<array name="lockscreen_targets_with_camera">
<item>@drawable/ic_lockscreen_unlock</item>
- <item>@drawable/ic_lockscreen_search</item>
+ <item>@drawable/ic_action_assist_generic</item>
<item>@drawable/ic_lockscreen_camera</item>
<item>@null</item>
</array>
diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml
index 6585595..b3b0745 100644
--- a/core/res/res/values-tl/strings.xml
+++ b/core/res/res/values-tl/strings.xml
@@ -934,10 +934,8 @@
<string name="deleteText" msgid="7070985395199629156">"tanggalin"</string>
<string name="inputMethod" msgid="1653630062304567879">"Pamamaraan ng pag-input"</string>
<string name="editTextMenuTitle" msgid="4909135564941815494">"Pagkilos ng teksto"</string>
- <!-- no translation found for low_internal_storage_view_title (5576272496365684834) -->
- <skip />
- <!-- no translation found for low_internal_storage_view_text (6640505817617414371) -->
- <skip />
+ <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Nauubusan na ang puwang ng storage"</string>
+ <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Maaaring hindi gumana nang tama ang ilang paggana ng system"</string>
<string name="ok" msgid="5970060430562524910">"OK"</string>
<string name="cancel" msgid="6442560571259935130">"Kanselahin"</string>
<string name="yes" msgid="5362982303337969312">"OK"</string>
@@ -1299,6 +1297,5 @@
<string name="default_audio_route_category_name" msgid="3722811174003886946">"System"</string>
<!-- no translation found for bluetooth_a2dp_audio_route_name (8575624030406771015) -->
<skip />
- <!-- no translation found for media_route_chooser_grouping_done (7966438307723317169) -->
- <skip />
+ <string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Tapos na"</string>
</resources>
diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml
index 43164ed..02e10f8 100644
--- a/core/res/res/values-tr/strings.xml
+++ b/core/res/res/values-tr/strings.xml
@@ -185,7 +185,7 @@
<string name="permgrouplab_developmentTools" msgid="3446164584710596513">"Geliştirme araçları"</string>
<string name="permgroupdesc_developmentTools" msgid="7058828032358142018">"Yalnızca uygulama geliştiriciler için gerekli özellikler."</string>
<string name="permgrouplab_storage" msgid="1971118770546336966">"Depolama"</string>
- <string name="permgroupdesc_storage" product="nosdcard" msgid="7442318502446874999">"Payl depolama birimine erişin."</string>
+ <string name="permgroupdesc_storage" product="nosdcard" msgid="7442318502446874999">"USB belleğe erişin."</string>
<string name="permgroupdesc_storage" product="default" msgid="9203302214915355774">"SD karta erişin."</string>
<string name="permlab_statusBar" msgid="7417192629601890791">"durum çubuğunu devre dışı bırak veya değiştir"</string>
<string name="permdesc_statusBar" msgid="8434669549504290975">"Uygulamaya, durum çubuğunu devre dışı bırakma ve sistem simgelerini ekleyip kaldırma izni verir."</string>
@@ -399,10 +399,10 @@
<string name="permlab_reboot" product="default" msgid="2898560872462638242">"telefonu yeniden başlamaya zorla"</string>
<string name="permdesc_reboot" product="tablet" msgid="8172056180063700741">"Uygulamaya, tableti yeniden açılmaya zorlama izni verir."</string>
<string name="permdesc_reboot" product="default" msgid="5326008124289989969">"Uygulamaya, telefonu yeniden başlatmaya zorlama izni verir."</string>
- <string name="permlab_mount_unmount_filesystems" product="nosdcard" msgid="2927361537942591841">"USB deplm dosya sistemine eriş"</string>
+ <string name="permlab_mount_unmount_filesystems" product="nosdcard" msgid="2927361537942591841">"USB bellek dosya sistemine eriş"</string>
<string name="permlab_mount_unmount_filesystems" product="default" msgid="4402305049890953810">"SD Kartın dosya sistemine eriş"</string>
<string name="permdesc_mount_unmount_filesystems" msgid="1829290701658992347">"Uygulamaya, çıkarılabilir depolama için dosya sistemlerini ekleme veya bağlantısını kesme izni verir."</string>
- <string name="permlab_mount_format_filesystems" product="nosdcard" msgid="6227819582624904972">"USB depolamayı sil"</string>
+ <string name="permlab_mount_format_filesystems" product="nosdcard" msgid="6227819582624904972">"USB belleği sil"</string>
<string name="permlab_mount_format_filesystems" product="default" msgid="262582698639274056">"SD Kartı sil"</string>
<string name="permdesc_mount_format_filesystems" msgid="8784268246779198627">"Uygulamaya, çıkarılabilir depolama birimini biçimlendirme izni verir."</string>
<string name="permlab_asec_access" msgid="3411338632002193846">"dahili depolama birimi hakkında bilgi al"</string>
@@ -526,11 +526,11 @@
<string name="permdesc_writeDictionary" msgid="8185385716255065291">"Uygulamaya, kullanıcı sözlüğüne yeni kelimeler yazma izni verir."</string>
<string name="permlab_sdcardRead" product="nosdcard" msgid="8235341515605559677">"korumalı depolama birimine erişimi test et"</string>
<string name="permlab_sdcardRead" product="default" msgid="8235341515605559677">"korumalı depolama birimine erişimi test et"</string>
- <string name="permdesc_sdcardRead" product="nosdcard" msgid="5791957130190763289">"Uygulamaya gelecekteki cihazlarda kullanılabilecek USB depolama birimine ilişkin bir izni test etme izni verir."</string>
+ <string name="permdesc_sdcardRead" product="nosdcard" msgid="5791957130190763289">"Uygulamaya gelecekteki cihazlarda kullanılabilecek USB belleğe ilişkin bir izni test etme izni verir."</string>
<string name="permdesc_sdcardRead" product="default" msgid="5914402684685848828">"Uygulamaya gelecekteki cihazlarda kullanılabilecek SD karta ilişkin bir izni test etme olanağı verir."</string>
- <string name="permlab_sdcardWrite" product="nosdcard" msgid="8485979062254666748">"USB depolamamın içeriğini değiştir veya sil"</string>
+ <string name="permlab_sdcardWrite" product="nosdcard" msgid="8485979062254666748">"USB belleğimin içeriğini değiştir veya sil"</string>
<string name="permlab_sdcardWrite" product="default" msgid="8805693630050458763">"SD kartın içeriğini değiştir veya sil"</string>
- <string name="permdesc_sdcardWrite" product="nosdcard" msgid="6175406299445710888">"Uygulamaya USB depolama birimine yazma izni verir."</string>
+ <string name="permdesc_sdcardWrite" product="nosdcard" msgid="6175406299445710888">"Uygulamaya USB belleğe yazma izni verir."</string>
<string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"Uygulamaya, SD karta yazma izni verir."</string>
<string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"dahili medya depolama birimi içeriğini değiştir/sil"</string>
<string name="permdesc_mediaStorageWrite" product="default" msgid="8189160597698529185">"Uygulamaya, dahili medya depolama içeriğini değiştirme izni verir."</string>
@@ -934,10 +934,8 @@
<string name="deleteText" msgid="7070985395199629156">"sil"</string>
<string name="inputMethod" msgid="1653630062304567879">"Giriş yöntemi"</string>
<string name="editTextMenuTitle" msgid="4909135564941815494">"Metin eylemleri"</string>
- <!-- no translation found for low_internal_storage_view_title (5576272496365684834) -->
- <skip />
- <!-- no translation found for low_internal_storage_view_text (6640505817617414371) -->
- <skip />
+ <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Depolama alanı bitiyor"</string>
+ <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Bazı sistem işlevleri çalışmayabilir"</string>
<string name="ok" msgid="5970060430562524910">"Tamam"</string>
<string name="cancel" msgid="6442560571259935130">"İptal"</string>
<string name="yes" msgid="5362982303337969312">"Tamam"</string>
@@ -1058,24 +1056,24 @@
<string name="perms_show_all" msgid="2671791163933091180"><b>"Tümünü göster"</b></string>
<string name="perms_new_perm_prefix" msgid="8257740710754301407"><font size="12" fgcolor="#ff900000">"YENİ: "</font></string>
<string name="perms_description_app" msgid="5139836143293299417">"Sağlayan: <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
- <string name="usb_storage_activity_title" msgid="4465055157209648641">"USB yığın depolama"</string>
+ <string name="usb_storage_activity_title" msgid="4465055157209648641">"USB yığın belleği"</string>
<string name="usb_storage_title" msgid="5901459041398751495">"USB bağlandı"</string>
- <string name="usb_storage_message" product="nosdcard" msgid="3308538094316477839">"Cihazınızı USB ile bilgisayarınıza bağladınız. Bilgisayarınız ile Android\'inizin USB depolama birimi arasında dosya kopyalamak istiyorsanız aşağıdaki düğmeye dokunun."</string>
+ <string name="usb_storage_message" product="nosdcard" msgid="3308538094316477839">"Cihazınızı USB ile bilgisayarınıza bağladınız. Bilgisayarınız ile Android\'inizin USB belleği arasında dosya kopyalamak istiyorsanız aşağıdaki düğmeye dokunun."</string>
<string name="usb_storage_message" product="default" msgid="805351000446037811">"Cihazınızı USB ile bilgisayarınıza bağladınız. Bilgisayarınız ile Android\'inizin SD kartı arasında dosya kopyalamak istiyorsanız aşağıdaki düğmeye dokunun."</string>
- <string name="usb_storage_button_mount" msgid="1052259930369508235">"USB depolama birimini aç"</string>
- <string name="usb_storage_error_message" product="nosdcard" msgid="3017045217365540658">"USB depolama biriminizi USB yığın depolama amaçlı kullanmayla ilgili bir sorun var."</string>
- <string name="usb_storage_error_message" product="default" msgid="2876018512716970313">"SD kartınızı USB yığın depolama birimi olarak kullanmada sorun var."</string>
+ <string name="usb_storage_button_mount" msgid="1052259930369508235">"USB belleği aç"</string>
+ <string name="usb_storage_error_message" product="nosdcard" msgid="3017045217365540658">"USB belleğinizi USB yığın belleği amaçlı kullanmayla ilgili bir sorun var."</string>
+ <string name="usb_storage_error_message" product="default" msgid="2876018512716970313">"SD kartınızı USB yığın belleği olarak kullanmada sorun var."</string>
<string name="usb_storage_notification_title" msgid="8175892554757216525">"USB bağlandı"</string>
<string name="usb_storage_notification_message" msgid="939822783828183763">"Bilgisayarınıza/bilgisayarınızdan dosya kopyalamak için dokunun."</string>
- <string name="usb_storage_stop_notification_title" msgid="2336058396663516017">"USB belleğini kapat"</string>
- <string name="usb_storage_stop_notification_message" msgid="1656852098555623822">"USB depolama birimini kapatmak için dokunun."</string>
- <string name="usb_storage_stop_title" msgid="660129851708775853">"USB depolama birimi kullanılıyor"</string>
- <string name="usb_storage_stop_message" product="nosdcard" msgid="4264025280777219521">"USB depolama birimini kapatmadan önce Android\'inizin USB depolama biriminin bilgisayarınızla olan bağlantısını kesin (\"çıkarın\")."</string>
- <string name="usb_storage_stop_message" product="default" msgid="8043969782460613114">"USB depolama birimini kapatmadan önce Android\'inizin SD kartının bilgisayarınızla olan bağlantısını kesin (\"çıkarın\")."</string>
- <string name="usb_storage_stop_button_mount" msgid="7060218034900696029">"USB depolama birimini kapat"</string>
- <string name="usb_storage_stop_error_message" msgid="1970374898263063836">"USB depolama birimini kapatırken bir sorun oluştu. USB birimini kaldırdığınızdan emin olun ve daha sonra tekrar deneyin."</string>
- <string name="dlg_confirm_kill_storage_users_title" msgid="963039033470478697">"USB depolama birimini aç"</string>
- <string name="dlg_confirm_kill_storage_users_text" msgid="5100428757107469454">"USB depolama birimini açarsanız, kullanmakta olduğunuz bazı uygulamalar durur ve USB depolama birimi kapatılıncaya kadar kullanılamayabilir."</string>
+ <string name="usb_storage_stop_notification_title" msgid="2336058396663516017">"USB belleği kapat"</string>
+ <string name="usb_storage_stop_notification_message" msgid="1656852098555623822">"USB belleği kapatmak için dokunun."</string>
+ <string name="usb_storage_stop_title" msgid="660129851708775853">"USB bellek kullanılıyor"</string>
+ <string name="usb_storage_stop_message" product="nosdcard" msgid="4264025280777219521">"USB belleği kapatmadan önce Android\'inizin USB belleğin bilgisayarınızla olan bağlantısını kesin (\"çıkarın\")."</string>
+ <string name="usb_storage_stop_message" product="default" msgid="8043969782460613114">"USB belleği kapatmadan önce Android\'inizin SD kartının bilgisayarınızla olan bağlantısını kesin (\"çıkarın\")."</string>
+ <string name="usb_storage_stop_button_mount" msgid="7060218034900696029">"USB belleği kapat"</string>
+ <string name="usb_storage_stop_error_message" msgid="1970374898263063836">"USB belleği kapatırken bir sorun oluştu. USB birimini kaldırdığınızdan emin olun ve daha sonra tekrar deneyin."</string>
+ <string name="dlg_confirm_kill_storage_users_title" msgid="963039033470478697">"USB belleği aç"</string>
+ <string name="dlg_confirm_kill_storage_users_text" msgid="5100428757107469454">"USB belleği açarsanız, kullanmakta olduğunuz bazı uygulamalar durur ve USB bellek kapatılıncaya kadar kullanılamayabilir."</string>
<string name="dlg_error_title" msgid="7323658469626514207">"USB işlemi başarısız oldu"</string>
<string name="dlg_ok" msgid="7376953167039865701">"Tamam"</string>
<string name="usb_mtp_notification_title" msgid="3699913097391550394">"Medya cihazı olarak bağlandı"</string>
@@ -1083,9 +1081,9 @@
<string name="usb_cd_installer_notification_title" msgid="6774712827892090754">"Yükleyici olarak bağlandı"</string>
<string name="usb_accessory_notification_title" msgid="7848236974087653666">"USB aksesuarına bağlandı"</string>
<string name="usb_notification_message" msgid="2290859399983720271">"Diğer USB seçenekleri için dokunun."</string>
- <string name="extmedia_format_title" product="nosdcard" msgid="9020092196061007262">"USB dp br biçimlendirilsin mi?"</string>
+ <string name="extmedia_format_title" product="nosdcard" msgid="9020092196061007262">"USB bellek biçimlendirilsin mi?"</string>
<string name="extmedia_format_title" product="default" msgid="3648415921526526069">"SD kart biçimlendirilsin mi?"</string>
- <string name="extmedia_format_message" product="nosdcard" msgid="3934016853425761078">"USB depolama biriminizdeki tüm dosyalar silinecek. Bu işlem geri alınamaz!"</string>
+ <string name="extmedia_format_message" product="nosdcard" msgid="3934016853425761078">"USB belleğinizdeki tüm dosyalar silinecek. Bu işlem geri alınamaz!"</string>
<string name="extmedia_format_message" product="default" msgid="14131895027543830">"Kartınızdaki tüm veriler kaybolacak."</string>
<string name="extmedia_format_button_format" msgid="4131064560127478695">"Biçimlendir"</string>
<string name="adb_active_notification_title" msgid="6729044778949189918">"USB hata ayıklaması bağlandı"</string>
@@ -1099,28 +1097,28 @@
<string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="candidates_style" msgid="4333913089637062257"><u>"adaylar"</u></string>
- <string name="ext_media_checking_notification_title" product="nosdcard" msgid="3449816005351468560">"USB depolm birimi hazırlanıyor"</string>
+ <string name="ext_media_checking_notification_title" product="nosdcard" msgid="3449816005351468560">"USB bellek hazırlanıyor"</string>
<string name="ext_media_checking_notification_title" product="default" msgid="5457603418970994050">"SD kart hazırlanıyor"</string>
<string name="ext_media_checking_notification_message" msgid="8287319882926737053">"Hata kontrolü yapılıyor"</string>
- <string name="ext_media_nofs_notification_title" product="nosdcard" msgid="7788040745686229307">"Boş USB depolama birimi"</string>
+ <string name="ext_media_nofs_notification_title" product="nosdcard" msgid="7788040745686229307">"Boş USB bellek"</string>
<string name="ext_media_nofs_notification_title" product="default" msgid="780477838241212997">"Boş SD kart"</string>
- <string name="ext_media_nofs_notification_message" product="nosdcard" msgid="7840121067427269500">"USB depolama birimi boş veya desteklenmeyen bir dosya sistemine sahip."</string>
+ <string name="ext_media_nofs_notification_message" product="nosdcard" msgid="7840121067427269500">"USB bellek boş veya desteklenmeyen bir dosya sistemine sahip."</string>
<string name="ext_media_nofs_notification_message" product="default" msgid="8641065641786923604">"SD kart boş veya desteklenmeyen dosya sistemi içeriyor."</string>
- <string name="ext_media_unmountable_notification_title" product="nosdcard" msgid="2090046769532713563">"USB depolm birimi zarar görmüş"</string>
+ <string name="ext_media_unmountable_notification_title" product="nosdcard" msgid="2090046769532713563">"USB bellek zarar görmüş"</string>
<string name="ext_media_unmountable_notification_title" product="default" msgid="6410723906019100189">"Hasarlı SD kart"</string>
- <string name="ext_media_unmountable_notification_message" product="nosdcard" msgid="1795917578395333280">"USB depolama birimi bozuk. Yeniden biçimlendirmeyi deneyin."</string>
+ <string name="ext_media_unmountable_notification_message" product="nosdcard" msgid="1795917578395333280">"USB bellek bozuk. Yeniden biçimlendirmeyi deneyin."</string>
<string name="ext_media_unmountable_notification_message" product="default" msgid="1753898567525568253">"SD kart bozuk. Yeniden biçimlendirmeyi deneyin."</string>
- <string name="ext_media_badremoval_notification_title" product="nosdcard" msgid="1661683031330951073">"USB dep br bklnmd şekl çıkarld"</string>
+ <string name="ext_media_badremoval_notification_title" product="nosdcard" msgid="1661683031330951073">"USB bellek bklnmd şekl çıkarld"</string>
<string name="ext_media_badremoval_notification_title" product="default" msgid="6872152882604407837">"SD kart beklenmedik biçimde çıkarıldı"</string>
- <string name="ext_media_badremoval_notification_message" product="nosdcard" msgid="4329848819865594241">"Veri kaybı olmaması için çıkarmadan önce USB depolama biriminin bağlantısını kesin."</string>
+ <string name="ext_media_badremoval_notification_message" product="nosdcard" msgid="4329848819865594241">"Veri kaybı olmaması için çıkarmadan önce USB belleğin bağlantısını kesin."</string>
<string name="ext_media_badremoval_notification_message" product="default" msgid="7260183293747448241">"Veri kaybından kaçınmak için SD kartı çıkarmadan önce bağlantısını kesin."</string>
- <string name="ext_media_safe_unmount_notification_title" product="nosdcard" msgid="3967973893270360230">"USB depl birm güvenle çıkrlblr"</string>
+ <string name="ext_media_safe_unmount_notification_title" product="nosdcard" msgid="3967973893270360230">"USB bellek güvenle çıkarılablr"</string>
<string name="ext_media_safe_unmount_notification_title" product="default" msgid="6729801130790616200">"SD kart güvenle çıkarılabilir"</string>
- <string name="ext_media_safe_unmount_notification_message" product="nosdcard" msgid="6142195361606493530">"USB depolama birimini güvenli bir şekilde çıkarabilirsiniz."</string>
+ <string name="ext_media_safe_unmount_notification_message" product="nosdcard" msgid="6142195361606493530">"USB belleği güvenli bir şekilde çıkarabilirsiniz."</string>
<string name="ext_media_safe_unmount_notification_message" product="default" msgid="568841278138377604">"SD kartı güvenle kaldırabilirsiniz."</string>
- <string name="ext_media_nomedia_notification_title" product="nosdcard" msgid="4486377230140227651">"USB depolama birimi çıkarıldı"</string>
+ <string name="ext_media_nomedia_notification_title" product="nosdcard" msgid="4486377230140227651">"USB bellek çıkarıldı"</string>
<string name="ext_media_nomedia_notification_title" product="default" msgid="8902518030404381318">"SD kart çıkarılmış"</string>
- <string name="ext_media_nomedia_notification_message" product="nosdcard" msgid="6921126162580574143">"USB depolama birimi çıkarıldı. Yeni medyayı takın."</string>
+ <string name="ext_media_nomedia_notification_message" product="nosdcard" msgid="6921126162580574143">"USB bellek çıkarıldı. Yeni medyayı takın."</string>
<string name="ext_media_nomedia_notification_message" product="default" msgid="3870120652983659641">"SD kart çıkarıldı. Yeni bir SD kart takın."</string>
<string name="activity_list_empty" msgid="1675388330786841066">"Eşleşen hiçbir etkinlik bulunamadı."</string>
<string name="permlab_pkgUsageStats" msgid="8787352074326748892">"bileşen kullanım istatistiklerini güncelle"</string>
@@ -1178,17 +1176,17 @@
<item quantity="other" msgid="4641872797067609177">"<xliff:g id="INDEX">%d</xliff:g> / <xliff:g id="TOTAL">%d</xliff:g>"</item>
</plurals>
<string name="action_mode_done" msgid="7217581640461922289">"Bitti"</string>
- <string name="progress_unmounting" product="nosdcard" msgid="3923810448507612746">"USB depolama biriminin bağlantısı kesiliyor…"</string>
+ <string name="progress_unmounting" product="nosdcard" msgid="3923810448507612746">"USB belleğin bağlantısı kesiliyor…"</string>
<string name="progress_unmounting" product="default" msgid="1327894998409537190">"SD kartın bağlantısı kesiliyor…"</string>
- <string name="progress_erasing" product="nosdcard" msgid="4521573321524340058">"USB depolama birimi siliniyor…"</string>
+ <string name="progress_erasing" product="nosdcard" msgid="4521573321524340058">"USB bellek siliniyor…"</string>
<string name="progress_erasing" product="default" msgid="6596988875507043042">"SD kart siliniyor…"</string>
- <string name="format_error" product="nosdcard" msgid="6299769563624776948">"USB depolama birimi silinemedi."</string>
+ <string name="format_error" product="nosdcard" msgid="6299769563624776948">"USB bellek silinemedi."</string>
<string name="format_error" product="default" msgid="7315248696644510935">"SD kart silinemedi."</string>
<string name="media_bad_removal" msgid="7960864061016603281">"SD kart, bağlantısı kesilmeden çıkarıldı."</string>
- <string name="media_checking" product="nosdcard" msgid="418188720009569693">"USB depolama birimi şu anda denetleniyor."</string>
+ <string name="media_checking" product="nosdcard" msgid="418188720009569693">"USB bellek şu anda denetleniyor."</string>
<string name="media_checking" product="default" msgid="7334762503904827481">"SD kart şu anda denetleniyor."</string>
<string name="media_removed" msgid="7001526905057952097">"SD kart çıkarıldı."</string>
- <string name="media_shared" product="nosdcard" msgid="5830814349250834225">"USB depolama birimi, şu anda bir bilgisayar tarafından kullanılıyor."</string>
+ <string name="media_shared" product="nosdcard" msgid="5830814349250834225">"USB bellek şu anda bir bilgisayar tarafından kullanılıyor."</string>
<string name="media_shared" product="default" msgid="5706130568133540435">"SD kart şu anda bir bilgisayar tarafından kullanılıyor."</string>
<string name="media_unknown_state" msgid="729192782197290385">"Harici medyanın durumu bilinmiyor."</string>
<string name="share" msgid="1778686618230011964">"Paylaş"</string>
@@ -1251,7 +1249,7 @@
<string name="action_menu_overflow_description" msgid="2295659037509008453">"Diğer seçenekler"</string>
<string name="storage_internal" msgid="4891916833657929263">"Dahili depolama birimi"</string>
<string name="storage_sd_card" msgid="3282948861378286745">"SD kart"</string>
- <string name="storage_usb" msgid="3017954059538517278">"USB depolama birimi"</string>
+ <string name="storage_usb" msgid="3017954059538517278">"USB bellek"</string>
<string name="extract_edit_menu_button" msgid="8940478730496610137">"Düzenle"</string>
<string name="data_usage_warning_title" msgid="1955638862122232342">"Veri kullanım uyarısı"</string>
<string name="data_usage_warning_body" msgid="2814673551471969954">"Kullanımı ve ayarları görmek için dokunun."</string>
@@ -1299,6 +1297,5 @@
<string name="default_audio_route_category_name" msgid="3722811174003886946">"Sistem"</string>
<!-- no translation found for bluetooth_a2dp_audio_route_name (8575624030406771015) -->
<skip />
- <!-- no translation found for media_route_chooser_grouping_done (7966438307723317169) -->
- <skip />
+ <string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Tamamlandı"</string>
</resources>
diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml
index 89e549c..8742590 100644
--- a/core/res/res/values-uk/strings.xml
+++ b/core/res/res/values-uk/strings.xml
@@ -1295,7 +1295,6 @@
<string name="default_audio_route_name_dock_speakers" msgid="6240602982276591864">"Динаміки док-станції"</string>
<string name="default_audio_route_name_hdmi" msgid="7986404173839007682">"Аудіовихід HDMI"</string>
<string name="default_audio_route_category_name" msgid="3722811174003886946">"Система"</string>
- <!-- no translation found for bluetooth_a2dp_audio_route_name (8575624030406771015) -->
- <skip />
+ <string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"Аудіо Bluetooth"</string>
<string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Готово"</string>
</resources>
diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml
index 60da566..1f10e3b 100644
--- a/core/res/res/values-vi/strings.xml
+++ b/core/res/res/values-vi/strings.xml
@@ -810,7 +810,7 @@
<string name="save_password_never" msgid="8274330296785855105">"Chưa bao giờ"</string>
<string name="open_permission_deny" msgid="7374036708316629800">"Bạn không được phép mở trang này."</string>
<string name="text_copied" msgid="4985729524670131385">"Đã sao chép văn bản vào khay nhớ tạm thời."</string>
- <string name="more_item_label" msgid="4650918923083320495">"Khác"</string>
+ <string name="more_item_label" msgid="4650918923083320495">"Thêm"</string>
<string name="prepend_shortcut_label" msgid="2572214461676015642">"Trình đơn+"</string>
<string name="menu_space_shortcut_label" msgid="2410328639272162537">"dấu cách"</string>
<string name="menu_enter_shortcut_label" msgid="2743362785111309668">"nhập"</string>
diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml
index 3ebbb1b..639bc03 100644
--- a/core/res/res/values-zh-rCN/strings.xml
+++ b/core/res/res/values-zh-rCN/strings.xml
@@ -934,10 +934,8 @@
<string name="deleteText" msgid="7070985395199629156">"删除"</string>
<string name="inputMethod" msgid="1653630062304567879">"输入法"</string>
<string name="editTextMenuTitle" msgid="4909135564941815494">"文字操作"</string>
- <!-- no translation found for low_internal_storage_view_title (5576272496365684834) -->
- <skip />
- <!-- no translation found for low_internal_storage_view_text (6640505817617414371) -->
- <skip />
+ <string name="low_internal_storage_view_title" msgid="5576272496365684834">"存储空间不足"</string>
+ <string name="low_internal_storage_view_text" msgid="6640505817617414371">"某些系统功能可能无法正常使用"</string>
<string name="ok" msgid="5970060430562524910">"确定"</string>
<string name="cancel" msgid="6442560571259935130">"取消"</string>
<string name="yes" msgid="5362982303337969312">"确定"</string>
@@ -1299,6 +1297,5 @@
<string name="default_audio_route_category_name" msgid="3722811174003886946">"系统"</string>
<!-- no translation found for bluetooth_a2dp_audio_route_name (8575624030406771015) -->
<skip />
- <!-- no translation found for media_route_chooser_grouping_done (7966438307723317169) -->
- <skip />
+ <string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"完成"</string>
</resources>
diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml
index 465816d..b43e2c5 100644
--- a/core/res/res/values-zh-rTW/strings.xml
+++ b/core/res/res/values-zh-rTW/strings.xml
@@ -934,10 +934,8 @@
<string name="deleteText" msgid="7070985395199629156">"刪除"</string>
<string name="inputMethod" msgid="1653630062304567879">"輸入法"</string>
<string name="editTextMenuTitle" msgid="4909135564941815494">"文字動作"</string>
- <!-- no translation found for low_internal_storage_view_title (5576272496365684834) -->
- <skip />
- <!-- no translation found for low_internal_storage_view_text (6640505817617414371) -->
- <skip />
+ <string name="low_internal_storage_view_title" msgid="5576272496365684834">"儲存空間即將用盡"</string>
+ <string name="low_internal_storage_view_text" msgid="6640505817617414371">"部分系統功能可能無法運作"</string>
<string name="ok" msgid="5970060430562524910">"確定"</string>
<string name="cancel" msgid="6442560571259935130">"取消"</string>
<string name="yes" msgid="5362982303337969312">"確定"</string>
@@ -1299,6 +1297,5 @@
<string name="default_audio_route_category_name" msgid="3722811174003886946">"系統"</string>
<!-- no translation found for bluetooth_a2dp_audio_route_name (8575624030406771015) -->
<skip />
- <!-- no translation found for media_route_chooser_grouping_done (7966438307723317169) -->
- <skip />
+ <string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"完成"</string>
</resources>
diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml
index e702c1d..c0c798d 100644
--- a/core/res/res/values-zu/strings.xml
+++ b/core/res/res/values-zu/strings.xml
@@ -934,10 +934,8 @@
<string name="deleteText" msgid="7070985395199629156">"susa"</string>
<string name="inputMethod" msgid="1653630062304567879">"Indlela yokufakwayo"</string>
<string name="editTextMenuTitle" msgid="4909135564941815494">"Izenzo zombhalo"</string>
- <!-- no translation found for low_internal_storage_view_title (5576272496365684834) -->
- <skip />
- <!-- no translation found for low_internal_storage_view_text (6640505817617414371) -->
- <skip />
+ <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Isikhala sokulondoloza siyaphela"</string>
+ <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Eminye imisebenzi yohlelo ingahle ingasebenzi"</string>
<string name="ok" msgid="5970060430562524910">"KULUNGILE"</string>
<string name="cancel" msgid="6442560571259935130">"Khansela"</string>
<string name="yes" msgid="5362982303337969312">"KULUNGILE"</string>
@@ -1291,14 +1289,12 @@
<string name="SetupCallDefault" msgid="5834948469253758575">"Amukela ucingo?"</string>
<string name="activity_resolver_use_always" msgid="8017770747801494933">"Njalo"</string>
<string name="activity_resolver_use_once" msgid="2404644797149173758">"Kanye nje"</string>
- <string name="default_audio_route_name" product="tablet" msgid="6890731863195399186">"Izipika zethebhulethi"</string>
- <string name="default_audio_route_name" product="default" msgid="4551396562363128432">"Isipika sefoni"</string>
+ <string name="default_audio_route_name" product="tablet" msgid="6890731863195399186">"Izipikha zethebhulethi"</string>
+ <string name="default_audio_route_name" product="default" msgid="4551396562363128432">"Isipikha sefoni"</string>
<string name="default_audio_route_name_headphones" msgid="8119971843803439110">"Ama-headphone"</string>
- <string name="default_audio_route_name_dock_speakers" msgid="6240602982276591864">"Izipika ze-Dock"</string>
+ <string name="default_audio_route_name_dock_speakers" msgid="6240602982276591864">"Izipikha ze-Dock"</string>
<string name="default_audio_route_name_hdmi" msgid="7986404173839007682">"Umsindo we-HDMI"</string>
<string name="default_audio_route_category_name" msgid="3722811174003886946">"Isistimu"</string>
- <!-- no translation found for bluetooth_a2dp_audio_route_name (8575624030406771015) -->
- <skip />
- <!-- no translation found for media_route_chooser_grouping_done (7966438307723317169) -->
- <skip />
+ <string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"Umsindo we-Bluetooth"</string>
+ <string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Qedile"</string>
</resources>
diff --git a/core/res/res/values/arrays.xml b/core/res/res/values/arrays.xml
index aeb6b4f..b425ad7 100644
--- a/core/res/res/values/arrays.xml
+++ b/core/res/res/values/arrays.xml
@@ -353,7 +353,7 @@
<!-- Resources for GlowPadView in LockScreen -->
<array name="lockscreen_targets_when_silent">
<item>@drawable/ic_lockscreen_unlock</item>
- <item>@drawable/ic_lockscreen_search</item>
+ <item>@drawable/ic_action_assist_generic</item>
<item>@drawable/ic_lockscreen_soundon</item>
<item>@null</item>
</array>
@@ -374,7 +374,7 @@
<array name="lockscreen_targets_when_soundon">
<item>@drawable/ic_lockscreen_unlock</item>
- <item>@drawable/ic_lockscreen_search</item>
+ <item>@drawable/ic_action_assist_generic</item>
<item>@drawable/ic_lockscreen_silent</item>
<item>@null</item>
</array>
@@ -388,7 +388,7 @@
<array name="lockscreen_targets_with_camera">
<item>@drawable/ic_lockscreen_unlock</item>
- <item>@drawable/ic_lockscreen_search</item>
+ <item>@drawable/ic_action_assist_generic</item>
<item>@drawable/ic_lockscreen_camera</item>
<item>@null</item>
</array>
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index 910fbb9..69d8ef1 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -1026,7 +1026,7 @@
<java-symbol type="drawable" name="ic_lockscreen_camera" />
<java-symbol type="drawable" name="ic_lockscreen_silent" />
<java-symbol type="drawable" name="ic_lockscreen_unlock" />
- <java-symbol type="drawable" name="ic_lockscreen_search" />
+ <java-symbol type="drawable" name="ic_action_assist_generic" />
<java-symbol type="drawable" name="notification_bg" />
<java-symbol type="drawable" name="notification_bg_low" />
<java-symbol type="drawable" name="notification_template_icon_bg" />
@@ -1177,6 +1177,9 @@
<java-symbol type="attr" name="externalRouteEnabledDrawable" />
<java-symbol type="id" name="extended_settings" />
<java-symbol type="id" name="check" />
+ <java-symbol type="id" name="volume_slider" />
+ <java-symbol type="id" name="volume_icon" />
+ <java-symbol type="drawable" name="ic_media_route_on_holo_dark" />
<java-symbol type="layout" name="media_route_chooser_layout" />
<java-symbol type="layout" name="media_route_list_item_top_header" />
<java-symbol type="layout" name="media_route_list_item_section_header" />
diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java
index 3d5a5fa..7b1113b 100644
--- a/media/java/android/media/AudioManager.java
+++ b/media/java/android/media/AudioManager.java
@@ -1274,42 +1274,25 @@
}
/**
- * Allow or disallow use of Bluetooth A2DP for media.
- * <p>The default behavior of the system is to use A2DP for media playback whenever an A2DP sink
- * is connected. Applications can use this method to override this behavior.
- * Note that the request will not persist after a wired headset or an A2DP sink is connected or
- * disconnected:
- * - Connection of an A2DP sink automatically enables use of A2DP.
- * - Connection of a wired headset automatically disables use of A2DP.
- * - Disconnection of a wired headset automatically enables use of A2DP if an A2DP sink is
- * connected.
- * <p>Requires Permission:
- * {@link android.Manifest.permission#MODIFY_AUDIO_SETTINGS}.
- * @param on set <var>true</var> to allow use of A2DP for media (default).
- * <var>false</var> to disallow use of A2DP for media.
+ * @param on set <var>true</var> to route A2DP audio to/from Bluetooth
+ * headset; <var>false</var> disable A2DP audio
* @deprecated Do not use.
*/
@Deprecated public void setBluetoothA2dpOn(boolean on){
- IAudioService service = getService();
- try {
- service.setBluetoothA2dpOn(on);
- } catch (RemoteException e) {
- Log.e(TAG, "Dead object in setBluetoothA2dpOn", e);
- }
}
/**
- * Checks whether use of A2DP sinks is enabled for media.
+ * Checks whether A2DP audio routing to the Bluetooth headset is on or off.
*
- * @return true if use of A2DP is enabled for media, false otherwise.
+ * @return true if A2DP audio is being routed to/from Bluetooth headset;
+ * false if otherwise
*/
public boolean isBluetoothA2dpOn() {
- IAudioService service = getService();
- try {
- return service.isBluetoothA2dpOn();
- } catch (RemoteException e) {
- Log.e(TAG, "Dead object in isBluetoothA2dpOn", e);
+ if (AudioSystem.getDeviceConnectionState(DEVICE_OUT_BLUETOOTH_A2DP,"")
+ == AudioSystem.DEVICE_STATE_UNAVAILABLE) {
return false;
+ } else {
+ return true;
}
}
diff --git a/media/java/android/media/AudioRoutesInfo.aidl b/media/java/android/media/AudioRoutesInfo.aidl
new file mode 100644
index 0000000..d665851
--- /dev/null
+++ b/media/java/android/media/AudioRoutesInfo.aidl
@@ -0,0 +1,18 @@
+/* Copyright 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.media;
+
+parcelable AudioRoutesInfo;
diff --git a/media/java/android/media/AudioRoutesInfo.java b/media/java/android/media/AudioRoutesInfo.java
new file mode 100644
index 0000000..df9fc06
--- /dev/null
+++ b/media/java/android/media/AudioRoutesInfo.java
@@ -0,0 +1,71 @@
+/*
+ * 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.media;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.text.TextUtils;
+
+/**
+ * Information available from AudioService about the current routes.
+ * @hide
+ */
+public class AudioRoutesInfo implements Parcelable {
+ static final int MAIN_SPEAKER = 0;
+ static final int MAIN_HEADSET = 1<<0;
+ static final int MAIN_HEADPHONES = 1<<1;
+ static final int MAIN_DOCK_SPEAKERS = 1<<2;
+ static final int MAIN_HDMI = 1<<3;
+
+ CharSequence mBluetoothName;
+ int mMainType = MAIN_SPEAKER;
+
+ public AudioRoutesInfo() {
+ }
+
+ public AudioRoutesInfo(AudioRoutesInfo o) {
+ mBluetoothName = o.mBluetoothName;
+ mMainType = o.mMainType;
+ }
+
+ AudioRoutesInfo(Parcel src) {
+ mBluetoothName = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(src);
+ mMainType = src.readInt();
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ TextUtils.writeToParcel(mBluetoothName, dest, flags);
+ dest.writeInt(mMainType);
+ }
+
+ public static final Parcelable.Creator<AudioRoutesInfo> CREATOR
+ = new Parcelable.Creator<AudioRoutesInfo>() {
+ public AudioRoutesInfo createFromParcel(Parcel in) {
+ return new AudioRoutesInfo(in);
+ }
+
+ public AudioRoutesInfo[] newArray(int size) {
+ return new AudioRoutesInfo[size];
+ }
+ };
+}
diff --git a/media/java/android/media/AudioService.java b/media/java/android/media/AudioService.java
index a69912d..27dc6e3 100644
--- a/media/java/android/media/AudioService.java
+++ b/media/java/android/media/AudioService.java
@@ -53,6 +53,7 @@
import android.os.Looper;
import android.os.Message;
import android.os.PowerManager;
+import android.os.RemoteCallbackList;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.SystemProperties;
@@ -62,6 +63,7 @@
import android.speech.RecognizerIntent;
import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager;
+import android.text.TextUtils;
import android.util.Log;
import android.view.KeyEvent;
import android.view.VolumePanel;
@@ -135,10 +137,11 @@
private static final int MSG_RCDISPLAY_UPDATE = 13;
private static final int MSG_SET_ALL_VOLUMES = 14;
private static final int MSG_PERSIST_MASTER_VOLUME_MUTE = 15;
+ private static final int MSG_REPORT_NEW_ROUTES = 16;
// messages handled under wakelock, can only be queued, i.e. sent with queueMsgUnderWakeLock(),
// and not with sendMsg(..., ..., SENDMSG_QUEUE, ...)
- private static final int MSG_SET_WIRED_DEVICE_CONNECTION_STATE = 16;
- private static final int MSG_SET_A2DP_CONNECTION_STATE = 17;
+ private static final int MSG_SET_WIRED_DEVICE_CONNECTION_STATE = 17;
+ private static final int MSG_SET_A2DP_CONNECTION_STATE = 18;
// flags for MSG_PERSIST_VOLUME indicating if current and/or last audible volume should be
@@ -397,6 +400,11 @@
private boolean mBluetoothA2dpEnabled;
private final Object mBluetoothA2dpEnabledLock = new Object();
+ // Monitoring of audio routes. Protected by mCurAudioRoutes.
+ final AudioRoutesInfo mCurAudioRoutes = new AudioRoutesInfo();
+ final RemoteCallbackList<IAudioRoutesObserver> mRoutesObservers
+ = new RemoteCallbackList<IAudioRoutesObserver>();
+
///////////////////////////////////////////////////////////////////////////
// Construction
///////////////////////////////////////////////////////////////////////////
@@ -1652,9 +1660,6 @@
/** @see AudioManager#setBluetoothA2dpOn() */
public void setBluetoothA2dpOn(boolean on) {
- if (!checkAudioSettingsPermission("setBluetoothA2dpOn()")) {
- return;
- }
setBluetoothA2dpOnInt(on);
}
@@ -3011,6 +3016,26 @@
onSetA2dpConnectionState((BluetoothDevice)msg.obj, msg.arg1);
mMediaEventWakeLock.release();
break;
+
+ case MSG_REPORT_NEW_ROUTES: {
+ int N = mRoutesObservers.beginBroadcast();
+ if (N > 0) {
+ AudioRoutesInfo routes;
+ synchronized (mCurAudioRoutes) {
+ routes = new AudioRoutesInfo(mCurAudioRoutes);
+ }
+ while (N > 0) {
+ N--;
+ IAudioRoutesObserver obs = mRoutesObservers.getBroadcastItem(N);
+ try {
+ obs.dispatchAudioRoutesChanged(routes);
+ } catch (RemoteException e) {
+ }
+ }
+ }
+ mRoutesObservers.finishBroadcast();
+ break;
+ }
}
}
}
@@ -3127,6 +3152,13 @@
} else {
makeA2dpDeviceUnavailableNow(address);
}
+ synchronized (mCurAudioRoutes) {
+ if (mCurAudioRoutes.mBluetoothName != null) {
+ mCurAudioRoutes.mBluetoothName = null;
+ sendMsg(mAudioHandler, MSG_REPORT_NEW_ROUTES,
+ SENDMSG_NOOP, 0, 0, null, 0);
+ }
+ }
} else if (!isConnected && state == BluetoothProfile.STATE_CONNECTED) {
if (btDevice.isBluetoothDock()) {
// this could be a reconnection after a transient disconnection
@@ -3141,6 +3173,14 @@
}
}
makeA2dpDeviceAvailable(address);
+ synchronized (mCurAudioRoutes) {
+ String name = btDevice.getAliasName();
+ if (!TextUtils.equals(mCurAudioRoutes.mBluetoothName, name)) {
+ mCurAudioRoutes.mBluetoothName = name;
+ sendMsg(mAudioHandler, MSG_REPORT_NEW_ROUTES,
+ SENDMSG_NOOP, 0, 0, null, 0);
+ }
+ }
}
}
}
@@ -3204,20 +3244,43 @@
intent.putExtra("name", name);
intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
+ int connType = 0;
+
if (device == AudioSystem.DEVICE_OUT_WIRED_HEADSET) {
+ connType = AudioRoutesInfo.MAIN_HEADSET;
intent.setAction(Intent.ACTION_HEADSET_PLUG);
intent.putExtra("microphone", 1);
} else if (device == AudioSystem.DEVICE_OUT_WIRED_HEADPHONE) {
+ connType = AudioRoutesInfo.MAIN_HEADPHONES;
intent.setAction(Intent.ACTION_HEADSET_PLUG);
intent.putExtra("microphone", 0);
} else if (device == AudioSystem.DEVICE_OUT_ANLG_DOCK_HEADSET) {
+ connType = AudioRoutesInfo.MAIN_DOCK_SPEAKERS;
intent.setAction(Intent.ACTION_ANALOG_AUDIO_DOCK_PLUG);
} else if (device == AudioSystem.DEVICE_OUT_DGTL_DOCK_HEADSET) {
+ connType = AudioRoutesInfo.MAIN_DOCK_SPEAKERS;
intent.setAction(Intent.ACTION_DIGITAL_AUDIO_DOCK_PLUG);
} else if (device == AudioSystem.DEVICE_OUT_AUX_DIGITAL) {
+ connType = AudioRoutesInfo.MAIN_HDMI;
intent.setAction(Intent.ACTION_HDMI_AUDIO_PLUG);
}
+ synchronized (mCurAudioRoutes) {
+ if (connType != 0) {
+ int newConn = mCurAudioRoutes.mMainType;
+ if (state != 0) {
+ newConn |= connType;
+ } else {
+ newConn &= ~connType;
+ }
+ if (newConn != mCurAudioRoutes.mMainType) {
+ mCurAudioRoutes.mMainType = newConn;
+ sendMsg(mAudioHandler, MSG_REPORT_NEW_ROUTES,
+ SENDMSG_NOOP, 0, 0, null, 0);
+ }
+ }
+ }
+
ActivityManagerNative.broadcastStickyIntent(intent, null);
}
@@ -4796,6 +4859,15 @@
}
@Override
+ public AudioRoutesInfo startWatchingRoutes(IAudioRoutesObserver observer) {
+ synchronized (mCurAudioRoutes) {
+ AudioRoutesInfo routes = new AudioRoutesInfo(mCurAudioRoutes);
+ mRoutesObservers.register(observer);
+ return routes;
+ }
+ }
+
+ @Override
protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DUMP, TAG);
@@ -4803,5 +4875,8 @@
dumpFocusStack(pw);
dumpRCStack(pw);
dumpStreamStates(pw);
+ pw.println("\nAudio routes:");
+ pw.print(" mMainType=0x"); pw.println(Integer.toHexString(mCurAudioRoutes.mMainType));
+ pw.print(" mBluetoothName="); pw.println(mCurAudioRoutes.mBluetoothName);
}
}
diff --git a/media/java/android/media/IAudioRoutesObserver.aidl b/media/java/android/media/IAudioRoutesObserver.aidl
new file mode 100644
index 0000000..c269b83
--- /dev/null
+++ b/media/java/android/media/IAudioRoutesObserver.aidl
@@ -0,0 +1,27 @@
+/*
+ * 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.media;
+
+import android.media.AudioRoutesInfo;
+
+/**
+ * AIDL for the AudioService to report changes in available audio routes.
+ * @hide
+ */
+oneway interface IAudioRoutesObserver {
+ void dispatchAudioRoutesChanged(in AudioRoutesInfo newRoutes);
+}
diff --git a/media/java/android/media/IAudioService.aidl b/media/java/android/media/IAudioService.aidl
index 70fc623..fc5b8f1 100644
--- a/media/java/android/media/IAudioService.aidl
+++ b/media/java/android/media/IAudioService.aidl
@@ -19,7 +19,9 @@
import android.app.PendingIntent;
import android.bluetooth.BluetoothDevice;
import android.content.ComponentName;
+import android.media.AudioRoutesInfo;
import android.media.IAudioFocusDispatcher;
+import android.media.IAudioRoutesObserver;
import android.media.IRemoteControlClient;
import android.media.IRemoteControlDisplay;
import android.media.IRingtonePlayer;
@@ -137,4 +139,6 @@
void setWiredDeviceConnectionState(int device, int state, String name);
int setBluetoothA2dpDeviceConnectionState(in BluetoothDevice device, int state);
+
+ AudioRoutesInfo startWatchingRoutes(in IAudioRoutesObserver observer);
}
diff --git a/media/java/android/media/MediaRouter.java b/media/java/android/media/MediaRouter.java
index 9e70b7f..a9e6e3d 100644
--- a/media/java/android/media/MediaRouter.java
+++ b/media/java/android/media/MediaRouter.java
@@ -16,19 +16,20 @@
package android.media;
-import android.bluetooth.BluetoothA2dp;
-import android.content.BroadcastReceiver;
import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
import android.content.res.Resources;
import android.graphics.drawable.Drawable;
import android.os.Handler;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.text.TextUtils;
import android.util.Log;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
+import java.util.concurrent.CopyOnWriteArrayList;
/**
* MediaRouter allows applications to control the routing of media channels
@@ -46,46 +47,104 @@
static class Static {
final Resources mResources;
- final AudioManager mAudioManager;
+ final IAudioService mAudioService;
final Handler mHandler;
- final ArrayList<CallbackInfo> mCallbacks = new ArrayList<CallbackInfo>();
+ final CopyOnWriteArrayList<CallbackInfo> mCallbacks =
+ new CopyOnWriteArrayList<CallbackInfo>();
final ArrayList<RouteInfo> mRoutes = new ArrayList<RouteInfo>();
final ArrayList<RouteCategory> mCategories = new ArrayList<RouteCategory>();
final RouteCategory mSystemCategory;
- final HeadphoneChangedBroadcastReceiver mHeadphoneChangedReceiver;
+
+ final AudioRoutesInfo mCurRoutesInfo = new AudioRoutesInfo();
RouteInfo mDefaultAudio;
RouteInfo mBluetoothA2dpRoute;
RouteInfo mSelectedRoute;
+ final IAudioRoutesObserver.Stub mRoutesObserver = new IAudioRoutesObserver.Stub() {
+ public void dispatchAudioRoutesChanged(final AudioRoutesInfo newRoutes) {
+ mHandler.post(new Runnable() {
+ @Override public void run() {
+ updateRoutes(newRoutes);
+ }
+ });
+ }
+ };
+
Static(Context appContext) {
mResources = Resources.getSystem();
mHandler = new Handler(appContext.getMainLooper());
- mAudioManager = (AudioManager)appContext.getSystemService(Context.AUDIO_SERVICE);
+ IBinder b = ServiceManager.getService(Context.AUDIO_SERVICE);
+ mAudioService = IAudioService.Stub.asInterface(b);
- // XXX this doesn't deal with locale changes!
- mSystemCategory = new RouteCategory(mResources.getText(
- com.android.internal.R.string.default_audio_route_category_name),
+ mSystemCategory = new RouteCategory(
+ com.android.internal.R.string.default_audio_route_category_name,
ROUTE_TYPE_LIVE_AUDIO, false);
-
- final IntentFilter speakerFilter = new IntentFilter(Intent.ACTION_HEADSET_PLUG);
- speakerFilter.addAction(Intent.ACTION_ANALOG_AUDIO_DOCK_PLUG);
- speakerFilter.addAction(Intent.ACTION_DIGITAL_AUDIO_DOCK_PLUG);
- speakerFilter.addAction(Intent.ACTION_HDMI_AUDIO_PLUG);
- mHeadphoneChangedReceiver = new HeadphoneChangedBroadcastReceiver();
- appContext.registerReceiver(mHeadphoneChangedReceiver, speakerFilter);
}
// Called after sStatic is initialized
- void initDefaultRoutes() {
+ void startMonitoringRoutes() {
mDefaultAudio = new RouteInfo(mSystemCategory);
mDefaultAudio.mNameResId = com.android.internal.R.string.default_audio_route_name;
mDefaultAudio.mSupportedTypes = ROUTE_TYPE_LIVE_AUDIO;
addRoute(mDefaultAudio);
+
+ AudioRoutesInfo newRoutes = null;
+ try {
+ newRoutes = mAudioService.startWatchingRoutes(mRoutesObserver);
+ } catch (RemoteException e) {
+ }
+ if (newRoutes != null) {
+ updateRoutes(newRoutes);
+ }
+ }
+
+ void updateRoutes(AudioRoutesInfo newRoutes) {
+ if (newRoutes.mMainType != mCurRoutesInfo.mMainType) {
+ mCurRoutesInfo.mMainType = newRoutes.mMainType;
+ int name;
+ if ((newRoutes.mMainType&AudioRoutesInfo.MAIN_HEADPHONES) != 0
+ || (newRoutes.mMainType&AudioRoutesInfo.MAIN_HEADSET) != 0) {
+ name = com.android.internal.R.string.default_audio_route_name_headphones;
+ } else if ((newRoutes.mMainType&AudioRoutesInfo.MAIN_DOCK_SPEAKERS) != 0) {
+ name = com.android.internal.R.string.default_audio_route_name_dock_speakers;
+ } else if ((newRoutes.mMainType&AudioRoutesInfo.MAIN_HDMI) != 0) {
+ name = com.android.internal.R.string.default_audio_route_name_hdmi;
+ } else {
+ name = com.android.internal.R.string.default_audio_route_name;
+ }
+ sStatic.mDefaultAudio.mNameResId = name;
+ dispatchRouteChanged(sStatic.mDefaultAudio);
+ }
+ if (!TextUtils.equals(newRoutes.mBluetoothName, mCurRoutesInfo.mBluetoothName)) {
+ mCurRoutesInfo.mBluetoothName = newRoutes.mBluetoothName;
+ if (mCurRoutesInfo.mBluetoothName != null) {
+ if (sStatic.mBluetoothA2dpRoute == null) {
+ final RouteInfo info = new RouteInfo(sStatic.mSystemCategory);
+ info.mName = mCurRoutesInfo.mBluetoothName;
+ info.mSupportedTypes = ROUTE_TYPE_LIVE_AUDIO;
+ sStatic.mBluetoothA2dpRoute = info;
+ addRoute(sStatic.mBluetoothA2dpRoute);
+ try {
+ if (mAudioService.isBluetoothA2dpOn()) {
+ selectRouteStatic(ROUTE_TYPE_LIVE_AUDIO, mBluetoothA2dpRoute);
+ }
+ } catch (RemoteException e) {
+ Log.e(TAG, "Error selecting Bluetooth A2DP route", e);
+ }
+ } else {
+ sStatic.mBluetoothA2dpRoute.mName = mCurRoutesInfo.mBluetoothName;
+ dispatchRouteChanged(sStatic.mBluetoothA2dpRoute);
+ }
+ } else if (sStatic.mBluetoothA2dpRoute != null) {
+ removeRoute(sStatic.mBluetoothA2dpRoute);
+ sStatic.mBluetoothA2dpRoute = null;
+ }
+ }
}
}
@@ -132,7 +191,7 @@
synchronized (Static.class) {
if (sStatic == null) {
sStatic = new Static(context.getApplicationContext());
- sStatic.initDefaultRoutes();
+ sStatic.startMonitoringRoutes();
}
}
}
@@ -145,6 +204,13 @@
}
/**
+ * @hide for use by framework routing UI
+ */
+ public RouteCategory getSystemAudioCategory() {
+ return sStatic.mSystemCategory;
+ }
+
+ /**
* Return the currently selected route for the given types
*
* @param type route types
@@ -154,19 +220,6 @@
return sStatic.mSelectedRoute;
}
- static void onHeadphonesPlugged(boolean headphonesPresent, String headphonesName) {
- if (headphonesPresent) {
- sStatic.mDefaultAudio.mName = headphonesName;
- sStatic.mDefaultAudio.mNameResId = 0;
- } else {
- sStatic.mDefaultAudio.mName = null;
- sStatic.mDefaultAudio.mNameResId =
- com.android.internal.R.string.default_audio_route_name;
- }
-
- dispatchRouteChanged(sStatic.mDefaultAudio);
- }
-
/**
* Add a callback to listen to events about specific kinds of media routes.
* If the specified callback is already registered, its registration will be updated for any
@@ -229,6 +282,17 @@
Log.w(TAG, "selectRoute ignored; cannot select route with supported types " +
typesToString(route.getSupportedTypes()) + " into route types " +
typesToString(types));
+ return;
+ }
+
+ final RouteInfo btRoute = sStatic.mBluetoothA2dpRoute;
+ if (btRoute != null && (types & ROUTE_TYPE_LIVE_AUDIO) != 0 &&
+ (route == btRoute || route == sStatic.mDefaultAudio)) {
+ try {
+ sStatic.mAudioService.setBluetoothA2dpOn(route == btRoute);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Error changing Bluetooth A2DP state", e);
+ }
}
if (sStatic.mSelectedRoute != null) {
@@ -459,9 +523,7 @@
}
static void dispatchRouteSelected(int type, RouteInfo info) {
- final int count = sStatic.mCallbacks.size();
- for (int i = 0; i < count; i++) {
- final CallbackInfo cbi = sStatic.mCallbacks.get(i);
+ for (CallbackInfo cbi : sStatic.mCallbacks) {
if ((cbi.type & type) != 0) {
cbi.cb.onRouteSelected(cbi.router, type, info);
}
@@ -469,9 +531,7 @@
}
static void dispatchRouteUnselected(int type, RouteInfo info) {
- final int count = sStatic.mCallbacks.size();
- for (int i = 0; i < count; i++) {
- final CallbackInfo cbi = sStatic.mCallbacks.get(i);
+ for (CallbackInfo cbi : sStatic.mCallbacks) {
if ((cbi.type & type) != 0) {
cbi.cb.onRouteUnselected(cbi.router, type, info);
}
@@ -479,9 +539,7 @@
}
static void dispatchRouteChanged(RouteInfo info) {
- final int count = sStatic.mCallbacks.size();
- for (int i = 0; i < count; i++) {
- final CallbackInfo cbi = sStatic.mCallbacks.get(i);
+ for (CallbackInfo cbi : sStatic.mCallbacks) {
if ((cbi.type & info.mSupportedTypes) != 0) {
cbi.cb.onRouteChanged(cbi.router, info);
}
@@ -489,9 +547,7 @@
}
static void dispatchRouteAdded(RouteInfo info) {
- final int count = sStatic.mCallbacks.size();
- for (int i = 0; i < count; i++) {
- final CallbackInfo cbi = sStatic.mCallbacks.get(i);
+ for (CallbackInfo cbi : sStatic.mCallbacks) {
if ((cbi.type & info.mSupportedTypes) != 0) {
cbi.cb.onRouteAdded(cbi.router, info);
}
@@ -499,9 +555,7 @@
}
static void dispatchRouteRemoved(RouteInfo info) {
- final int count = sStatic.mCallbacks.size();
- for (int i = 0; i < count; i++) {
- final CallbackInfo cbi = sStatic.mCallbacks.get(i);
+ for (CallbackInfo cbi : sStatic.mCallbacks) {
if ((cbi.type & info.mSupportedTypes) != 0) {
cbi.cb.onRouteRemoved(cbi.router, info);
}
@@ -509,9 +563,7 @@
}
static void dispatchRouteGrouped(RouteInfo info, RouteGroup group, int index) {
- final int count = sStatic.mCallbacks.size();
- for (int i = 0; i < count; i++) {
- final CallbackInfo cbi = sStatic.mCallbacks.get(i);
+ for (CallbackInfo cbi : sStatic.mCallbacks) {
if ((cbi.type & group.mSupportedTypes) != 0) {
cbi.cb.onRouteGrouped(cbi.router, info, group, index);
}
@@ -519,27 +571,13 @@
}
static void dispatchRouteUngrouped(RouteInfo info, RouteGroup group) {
- final int count = sStatic.mCallbacks.size();
- for (int i = 0; i < count; i++) {
- final CallbackInfo cbi = sStatic.mCallbacks.get(i);
+ for (CallbackInfo cbi : sStatic.mCallbacks) {
if ((cbi.type & group.mSupportedTypes) != 0) {
cbi.cb.onRouteUngrouped(cbi.router, info, group);
}
}
}
- static void onA2dpDeviceConnected() {
- final RouteInfo info = new RouteInfo(sStatic.mSystemCategory);
- info.mNameResId = com.android.internal.R.string.bluetooth_a2dp_audio_route_name;
- sStatic.mBluetoothA2dpRoute = info;
- addRoute(sStatic.mBluetoothA2dpRoute);
- }
-
- static void onA2dpDeviceDisconnected() {
- removeRoute(sStatic.mBluetoothA2dpRoute);
- sStatic.mBluetoothA2dpRoute = null;
- }
-
/**
* Information about a media route.
*/
@@ -636,6 +674,7 @@
*/
public void setTag(Object tag) {
mTag = tag;
+ routeUpdated();
}
/**
@@ -649,7 +688,6 @@
void setStatusInt(CharSequence status) {
if (!status.equals(mStatus)) {
mStatus = status;
- routeUpdated();
if (mGroup != null) {
mGroup.memberStatusChanged(this, status);
}
@@ -726,6 +764,16 @@
}
/**
+ * Retrieve the RemoteControlClient associated with this route, if one has been set.
+ *
+ * @return the RemoteControlClient associated with this route
+ * @see #setRemoteControlClient(RemoteControlClient)
+ */
+ public RemoteControlClient getRemoteControlClient() {
+ return mRcc;
+ }
+
+ /**
* Set an icon that will be used to represent this route.
* The system may use this icon in picker UIs or similar.
*
@@ -1158,44 +1206,4 @@
}
}
-
- class BtChangedBroadcastReceiver extends BroadcastReceiver {
- @Override
- public void onReceive(Context context, Intent intent) {
- final String action = intent.getAction();
- if (BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED.equals(action)) {
- final int state = intent.getIntExtra(BluetoothA2dp.EXTRA_STATE, -1);
- if (state == BluetoothA2dp.STATE_CONNECTED) {
- onA2dpDeviceConnected();
- } else if (state == BluetoothA2dp.STATE_DISCONNECTING ||
- state == BluetoothA2dp.STATE_DISCONNECTED) {
- onA2dpDeviceDisconnected();
- }
- }
- }
- }
-
- static class HeadphoneChangedBroadcastReceiver extends BroadcastReceiver {
- @Override
- public void onReceive(Context context, Intent intent) {
- final String action = intent.getAction();
- if (Intent.ACTION_HEADSET_PLUG.equals(action)) {
- final boolean plugged = intent.getIntExtra("state", 0) != 0;
- final String name = sStatic.mResources.getString(
- com.android.internal.R.string.default_audio_route_name_headphones);
- onHeadphonesPlugged(plugged, name);
- } else if (Intent.ACTION_ANALOG_AUDIO_DOCK_PLUG.equals(action) ||
- Intent.ACTION_DIGITAL_AUDIO_DOCK_PLUG.equals(action)) {
- final boolean plugged = intent.getIntExtra("state", 0) != 0;
- final String name = sStatic.mResources.getString(
- com.android.internal.R.string.default_audio_route_name_dock_speakers);
- onHeadphonesPlugged(plugged, name);
- } else if (Intent.ACTION_HDMI_AUDIO_PLUG.equals(action)) {
- final boolean plugged = intent.getIntExtra("state", 0) != 0;
- final String name = sStatic.mResources.getString(
- com.android.internal.R.string.default_audio_route_name_hdmi);
- onHeadphonesPlugged(plugged, name);
- }
- }
- }
}
diff --git a/packages/SystemUI/res/drawable/navbar_search_outerring.xml b/packages/SystemUI/res/drawable/navbar_search_outerring.xml
index 0dd081d..8a8785f 100644
--- a/packages/SystemUI/res/drawable/navbar_search_outerring.xml
+++ b/packages/SystemUI/res/drawable/navbar_search_outerring.xml
@@ -19,5 +19,5 @@
<size android:height="@dimen/navbar_search_outerring_diameter"
android:width="@dimen/navbar_search_outerring_diameter" />
<solid android:color="#00000000" />
- <stroke android:color="#40ffffff" android:width="2dp" />
-</shape>
\ No newline at end of file
+ <stroke android:color="#00000000" android:width="2dp" />
+</shape>
diff --git a/packages/SystemUI/res/layout-land/status_bar_search_panel.xml b/packages/SystemUI/res/layout-land/status_bar_search_panel.xml
index c8a120d4..f91e5d6 100644
--- a/packages/SystemUI/res/layout-land/status_bar_search_panel.xml
+++ b/packages/SystemUI/res/layout-land/status_bar_search_panel.xml
@@ -54,7 +54,7 @@
prvandroid:outerRadius="@dimen/navbar_search_outerring_radius"
prvandroid:innerRadius="@*android:dimen/glowpadview_inner_radius"
prvandroid:snapMargin="@dimen/navbar_search_snap_margin"
- prvandroid:feedbackCount="0"
+ prvandroid:feedbackCount="1"
prvandroid:vibrationDuration="@integer/config_vibration_duration"
prvandroid:alwaysTrackFinger="true"
prvandroid:glowRadius="@*android:dimen/glowpadview_glow_radius"
diff --git a/packages/SystemUI/res/layout-port/status_bar_search_panel.xml b/packages/SystemUI/res/layout-port/status_bar_search_panel.xml
index 1e4bb57..2556aca 100644
--- a/packages/SystemUI/res/layout-port/status_bar_search_panel.xml
+++ b/packages/SystemUI/res/layout-port/status_bar_search_panel.xml
@@ -54,7 +54,7 @@
prvandroid:outerRadius="@dimen/navbar_search_outerring_radius"
prvandroid:innerRadius="@*android:dimen/glowpadview_inner_radius"
prvandroid:snapMargin="@dimen/navbar_search_snap_margin"
- prvandroid:feedbackCount="0"
+ prvandroid:feedbackCount="1"
prvandroid:vibrationDuration="@integer/config_vibration_duration"
prvandroid:alwaysTrackFinger="true"
prvandroid:glowRadius="@*android:dimen/glowpadview_glow_radius"
diff --git a/packages/SystemUI/res/layout-sw600dp/status_bar_search_panel.xml b/packages/SystemUI/res/layout-sw600dp/status_bar_search_panel.xml
index 3b6c52e..459fac9 100644
--- a/packages/SystemUI/res/layout-sw600dp/status_bar_search_panel.xml
+++ b/packages/SystemUI/res/layout-sw600dp/status_bar_search_panel.xml
@@ -40,7 +40,7 @@
prvandroid:outerRadius="@dimen/navbar_search_outerring_radius"
prvandroid:innerRadius="@*android:dimen/glowpadview_inner_radius"
prvandroid:snapMargin="@dimen/navbar_search_snap_margin"
- prvandroid:feedbackCount="0"
+ prvandroid:feedbackCount="1"
prvandroid:vibrationDuration="@integer/config_vibration_duration"
prvandroid:alwaysTrackFinger="true"
prvandroid:glowRadius="@*android:dimen/glowpadview_glow_radius"
diff --git a/packages/SystemUI/res/layout-sw720dp/status_bar_search_panel.xml b/packages/SystemUI/res/layout-sw720dp/status_bar_search_panel.xml
index 8c2360e..d2e26db 100644
--- a/packages/SystemUI/res/layout-sw720dp/status_bar_search_panel.xml
+++ b/packages/SystemUI/res/layout-sw720dp/status_bar_search_panel.xml
@@ -41,7 +41,7 @@
prvandroid:outerRadius="@dimen/navbar_search_outerring_radius"
prvandroid:innerRadius="@*android:dimen/glowpadview_inner_radius"
prvandroid:snapMargin="@dimen/navbar_search_snap_margin"
- prvandroid:feedbackCount="0"
+ prvandroid:feedbackCount="1"
prvandroid:vibrationDuration="@integer/config_vibration_duration"
prvandroid:alwaysTrackFinger="true"
prvandroid:glowRadius="@*android:dimen/glowpadview_glow_radius"
diff --git a/packages/SystemUI/res/values-land/arrays.xml b/packages/SystemUI/res/values-land/arrays.xml
index 53f374d..74a6c81 100644
--- a/packages/SystemUI/res/values-land/arrays.xml
+++ b/packages/SystemUI/res/values-land/arrays.xml
@@ -22,7 +22,7 @@
<array name="navbar_search_targets">
<item>@null</item>
<item>@null</item>
- <item>@*android:drawable/ic_lockscreen_search</item>
+ <item>@*android:drawable/ic_action_assist_generic</item>
<item>@null</item>
</array>
diff --git a/packages/SystemUI/res/values-port/arrays.xml b/packages/SystemUI/res/values-port/arrays.xml
index f8b1620..cd6aaf6 100644
--- a/packages/SystemUI/res/values-port/arrays.xml
+++ b/packages/SystemUI/res/values-port/arrays.xml
@@ -21,7 +21,7 @@
<array name="navbar_search_targets">
<item>@null</item>
- <item>@*android:drawable/ic_lockscreen_search</item>
+ <item>@*android:drawable/ic_action_assist_generic</item>
<item>@null</item>
<item>@null</item>
</array>
diff --git a/packages/SystemUI/res/values-sw600dp/arrays.xml b/packages/SystemUI/res/values-sw600dp/arrays.xml
index 8b5b17d..f3a1771 100644
--- a/packages/SystemUI/res/values-sw600dp/arrays.xml
+++ b/packages/SystemUI/res/values-sw600dp/arrays.xml
@@ -21,7 +21,7 @@
<array name="navbar_search_targets">
<item>@null</item>
- <item>@*android:drawable/ic_lockscreen_search</item>
+ <item>@*android:drawable/ic_action_assist_generic</item>
<item>@null</item>
<item>@null</item>
</array>
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index 6a96c6b..6c40461 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -68,7 +68,7 @@
<dimen name="status_bar_icon_drawing_size">18dip</dimen>
<!-- opacity at which Notification icons will be drawn in the status bar -->
- <item type="dimen" name="status_bar_icon_drawing_alpha">55%</item>
+ <item type="dimen" name="status_bar_icon_drawing_alpha">65%</item>
<!-- gap on either side of status bar notification icons -->
<dimen name="status_bar_icon_padding">0dp</dimen>
diff --git a/packages/SystemUI/src/com/android/systemui/ExpandHelper.java b/packages/SystemUI/src/com/android/systemui/ExpandHelper.java
index 48efbc7..5dd15c3 100644
--- a/packages/SystemUI/src/com/android/systemui/ExpandHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/ExpandHelper.java
@@ -22,15 +22,13 @@
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.content.Context;
-import android.util.Log;
+import android.util.Slog;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.ScaleGestureDetector;
import android.view.View;
import android.view.ViewGroup;
import android.view.View.OnClickListener;
-import android.widget.ScrollView;
-import android.widget.FrameLayout;
public class ExpandHelper implements Gefingerpoken, OnClickListener {
public interface Callback {
@@ -41,7 +39,7 @@
}
private static final String TAG = "ExpandHelper";
- protected static final boolean DEBUG = true;
+ protected static final boolean DEBUG = false;
private static final long EXPAND_DURATION = 250;
private static final long GLOW_DURATION = 150;
@@ -95,7 +93,7 @@
mView = v;
}
public void setHeight(float h) {
- if (DEBUG) Log.v(TAG, "SetHeight: setting to " + h);
+ if (DEBUG) Slog.v(TAG, "SetHeight: setting to " + h);
ViewGroup.LayoutParams lp = mView.getLayoutParams();
lp.height = (int)h;
mView.setLayoutParams(lp);
@@ -110,7 +108,7 @@
}
public int getNaturalHeight(int maximum) {
ViewGroup.LayoutParams lp = mView.getLayoutParams();
- if (DEBUG) Log.v(TAG, "Inspecting a child of type: " + mView.getClass().getName());
+ if (DEBUG) Slog.v(TAG, "Inspecting a child of type: " + mView.getClass().getName());
int oldHeight = lp.height;
lp.height = ViewGroup.LayoutParams.WRAP_CONTENT;
mView.setLayoutParams(lp);
@@ -176,7 +174,7 @@
new ScaleGestureDetector.SimpleOnScaleGestureListener() {
@Override
public boolean onScaleBegin(ScaleGestureDetector detector) {
- if (DEBUG) Log.v(TAG, "onscalebegin()");
+ if (DEBUG) Slog.v(TAG, "onscalebegin()");
float x = detector.getFocusX();
float y = detector.getFocusY();
@@ -194,7 +192,7 @@
// your fingers have to be somewhat close to the bounds of the view in question
mInitialTouchFocusY = detector.getFocusY();
mInitialTouchSpan = Math.abs(detector.getCurrentSpan());
- if (DEBUG) Log.d(TAG, "got mInitialTouchSpan: (" + mInitialTouchSpan + ")");
+ if (DEBUG) Slog.d(TAG, "got mInitialTouchSpan: (" + mInitialTouchSpan + ")");
mStretching = initScale(v);
return mStretching;
@@ -202,7 +200,7 @@
@Override
public boolean onScale(ScaleGestureDetector detector) {
- if (DEBUG) Log.v(TAG, "onscale() on " + mCurrView);
+ if (DEBUG) Slog.v(TAG, "onscale() on " + mCurrView);
// are we scaling or dragging?
float span = Math.abs(detector.getCurrentSpan()) - mInitialTouchSpan;
@@ -212,28 +210,28 @@
drag *= mGravity == Gravity.BOTTOM ? -1f : 1f;
float pull = Math.abs(drag) + Math.abs(span) + 1f;
float hand = drag * Math.abs(drag) / pull + span * Math.abs(span) / pull;
- if (DEBUG) Log.d(TAG, "current span handle is: " + hand);
+ if (DEBUG) Slog.d(TAG, "current span handle is: " + hand);
hand = hand + mOldHeight;
float target = hand;
- if (DEBUG) Log.d(TAG, "target is: " + target);
+ if (DEBUG) Slog.d(TAG, "target is: " + target);
hand = hand < mSmallSize ? mSmallSize : (hand > mLargeSize ? mLargeSize : hand);
hand = hand > mNaturalHeight ? mNaturalHeight : hand;
- if (DEBUG) Log.d(TAG, "scale continues: hand =" + hand);
+ if (DEBUG) Slog.d(TAG, "scale continues: hand =" + hand);
mScaler.setHeight(hand);
// glow if overscale
float stretch = (float) Math.abs((target - hand) / mMaximumStretch);
float strength = 1f / (1f + (float) Math.pow(Math.E, -1 * ((8f * stretch) - 5f)));
- if (DEBUG) Log.d(TAG, "stretch: " + stretch + " strength: " + strength);
+ if (DEBUG) Slog.d(TAG, "stretch: " + stretch + " strength: " + strength);
setGlow(GLOW_BASE + strength * (1f - GLOW_BASE));
return true;
}
@Override
public void onScaleEnd(ScaleGestureDetector detector) {
- if (DEBUG) Log.v(TAG, "onscaleend()");
+ if (DEBUG) Slog.v(TAG, "onscaleend()");
// I guess we're alone now
- if (DEBUG) Log.d(TAG, "scale end");
+ if (DEBUG) Slog.d(TAG, "scale end");
finishScale(false);
}
});
@@ -279,7 +277,7 @@
}
public boolean onInterceptTouchEvent(MotionEvent ev) {
- if (DEBUG) Log.d(TAG, "interceptTouch: act=" + (ev.getAction()) +
+ if (DEBUG) Slog.d(TAG, "interceptTouch: act=" + (ev.getAction()) +
" stretching=" + mStretching);
mDetector.onTouchEvent(ev);
return mStretching;
@@ -287,15 +285,15 @@
public boolean onTouchEvent(MotionEvent ev) {
final int action = ev.getAction();
- if (DEBUG) Log.d(TAG, "touch: act=" + (action) + " stretching=" + mStretching);
+ if (DEBUG) Slog.d(TAG, "touch: act=" + (action) + " stretching=" + mStretching);
if (mStretching) {
- if (DEBUG) Log.d(TAG, "detector ontouch");
+ if (DEBUG) Slog.d(TAG, "detector ontouch");
mDetector.onTouchEvent(ev);
}
switch (action) {
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
- if (DEBUG) Log.d(TAG, "cancel");
+ if (DEBUG) Slog.d(TAG, "cancel");
mStretching = false;
clearView();
break;
@@ -304,20 +302,20 @@
}
private boolean initScale(View v) {
if (v != null) {
- if (DEBUG) Log.d(TAG, "scale begins on view: " + v);
+ if (DEBUG) Slog.d(TAG, "scale begins on view: " + v);
mStretching = true;
setView(v);
setGlow(GLOW_BASE);
mScaler.setView(v);
mOldHeight = mScaler.getHeight();
if (mCallback.canChildBeExpanded(v)) {
- if (DEBUG) Log.d(TAG, "working on an expandable child");
+ if (DEBUG) Slog.d(TAG, "working on an expandable child");
mNaturalHeight = mScaler.getNaturalHeight(mLargeSize);
} else {
- if (DEBUG) Log.d(TAG, "working on a non-expandable child");
+ if (DEBUG) Slog.d(TAG, "working on a non-expandable child");
mNaturalHeight = mOldHeight;
}
- if (DEBUG) Log.d(TAG, "got mOldHeight: " + mOldHeight +
+ if (DEBUG) Slog.d(TAG, "got mOldHeight: " + mOldHeight +
" mNaturalHeight: " + mNaturalHeight);
v.getParent().requestDisallowInterceptTouchEvent(true);
}
@@ -342,7 +340,7 @@
mStretching = false;
setGlow(0f);
mCallback.setUserExpandedChild(mCurrView, h == mNaturalHeight);
- if (DEBUG) Log.d(TAG, "scale was finished on view: " + mCurrView);
+ if (DEBUG) Slog.d(TAG, "scale was finished on view: " + mCurrView);
clearView();
}
@@ -362,7 +360,7 @@
String debugLog = "Looking for glows: " +
(mCurrViewTopGlow != null ? "found top " : "didn't find top") +
(mCurrViewBottomGlow != null ? "found bottom " : "didn't find bottom");
- Log.v(TAG, debugLog);
+ Slog.v(TAG, debugLog);
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/SearchPanelView.java b/packages/SystemUI/src/com/android/systemui/SearchPanelView.java
index c082c97..acab41e 100644
--- a/packages/SystemUI/src/com/android/systemui/SearchPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/SearchPanelView.java
@@ -118,7 +118,7 @@
public void onTrigger(View v, final int target) {
final int resId = mGlowPadView.getResourceIdForTarget(target);
switch (resId) {
- case com.android.internal.R.drawable.ic_lockscreen_search:
+ case com.android.internal.R.drawable.ic_action_assist_generic:
mWaitingForLaunch = true;
startAssistActivity();
vibrate();
@@ -155,7 +155,7 @@
if (component != null) {
if (!mGlowPadView.replaceTargetDrawablesIfPresent(component,
ASSIST_ICON_METADATA_NAME,
- com.android.internal.R.drawable.ic_lockscreen_search)) {
+ com.android.internal.R.drawable.ic_action_assist_generic)) {
Slog.w(TAG, "Couldn't grab icon from component " + component);
}
} else {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java
index bb0ce16..82d6a99 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java
@@ -46,7 +46,7 @@
private static final String TAG = "StatusBar.KeyButtonView";
final float GLOW_MAX_SCALE_FACTOR = 1.8f;
- final float BUTTON_QUIESCENT_ALPHA = 0.6f;
+ final float BUTTON_QUIESCENT_ALPHA = 0.70f;
long mDownTime;
int mCode;
diff --git a/policy/src/com/android/internal/policy/impl/KeyguardUpdateMonitor.java b/policy/src/com/android/internal/policy/impl/KeyguardUpdateMonitor.java
index 87ec16b..dfe9134 100644
--- a/policy/src/com/android/internal/policy/impl/KeyguardUpdateMonitor.java
+++ b/policy/src/com/android/internal/policy/impl/KeyguardUpdateMonitor.java
@@ -105,6 +105,8 @@
protected static final int MSG_DPM_STATE_CHANGED = 309;
protected static final int MSG_USER_CHANGED = 310;
+ protected static final boolean DEBUG_SIM_STATES = DEBUG || false;
+
/**
* When we receive a
* {@link com.android.internal.telephony.TelephonyIntents#ACTION_SIM_STATE_CHANGED} broadcast,
@@ -292,6 +294,10 @@
MSG_BATTERY_UPDATE, new BatteryStatus(status, level, plugged, health));
mHandler.sendMessage(msg);
} else if (TelephonyIntents.ACTION_SIM_STATE_CHANGED.equals(action)) {
+ if (DEBUG_SIM_STATES) {
+ Log.v(TAG, "action " + action + " state" +
+ intent.getStringExtra(IccCard.INTENT_KEY_ICC_STATE));
+ }
mHandler.sendMessage(mHandler.obtainMessage(
MSG_SIM_STATE_CHANGE, SimArgs.fromIntent(intent)));
} else if (AudioManager.RINGER_MODE_CHANGED_ACTION.equals(action)) {
@@ -407,6 +413,7 @@
}
if (state != IccCard.State.UNKNOWN && state != mSimState) {
+ if (DEBUG_SIM_STATES) Log.v(TAG, "dispatching state: " + state);
mSimState = state;
for (int i = 0; i < mSimStateCallbacks.size(); i++) {
mSimStateCallbacks.get(i).onSimStateChanged(state);
diff --git a/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java b/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java
index 518d8e9..35e7820 100644
--- a/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java
+++ b/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java
@@ -202,8 +202,21 @@
private Runnable mRecreateRunnable = new Runnable() {
public void run() {
- updateScreen(mMode, true);
+ Mode mode = mMode;
+ // If we were previously in a locked state but now it's Unknown, it means the phone
+ // was previously locked because of SIM state and has since been resolved. This
+ // bit of code checks this condition and dismisses keyguard.
+ boolean dismissAfterCreation = false;
+ if (mode == Mode.UnlockScreen && getUnlockMode() == UnlockMode.Unknown) {
+ if (DEBUG) Log.v(TAG, "Switch to Mode.LockScreen because SIM unlocked");
+ mode = Mode.LockScreen;
+ dismissAfterCreation = true;
+ }
+ updateScreen(mode, true);
restoreWidgetState();
+ if (dismissAfterCreation) {
+ mKeyguardScreenCallback.keyguardDone(false);
+ }
}
};
@@ -307,6 +320,7 @@
}
public void recreateMe(Configuration config) {
+ if (DEBUG) Log.v(TAG, "recreateMe()");
removeCallbacks(mRecreateRunnable);
post(mRecreateRunnable);
}
@@ -524,6 +538,7 @@
public void reset() {
mIsVerifyUnlockOnly = false;
mForgotPattern = false;
+ if (DEBUG) Log.v(TAG, "reset()");
post(mRecreateRunnable);
}
@@ -673,6 +688,7 @@
if (DEBUG_CONFIGURATION) Log.v(TAG, "**** re-creating lock screen since config changed");
saveWidgetState();
removeCallbacks(mRecreateRunnable);
+ if (DEBUG) Log.v(TAG, "recreating lockscreen because config changed");
post(mRecreateRunnable);
}
diff --git a/policy/src/com/android/internal/policy/impl/LockScreen.java b/policy/src/com/android/internal/policy/impl/LockScreen.java
index 4af66ce..33dda09 100644
--- a/policy/src/com/android/internal/policy/impl/LockScreen.java
+++ b/policy/src/com/android/internal/policy/impl/LockScreen.java
@@ -301,10 +301,17 @@
if (searchManager != null) {
ComponentName component = searchManager.getGlobalSearchActivity();
if (component != null) {
- if (!mGlowPadView.replaceTargetDrawablesIfPresent(component,
- ASSIST_ICON_METADATA_NAME,
- com.android.internal.R.drawable.ic_lockscreen_search)) {
- Slog.w(TAG, "Couldn't grab icon from package " + component);
+ // XXX Hack. We need to substitute the icon here but haven't formalized
+ // the public API. The "_google" metadata will be going away, so
+ // DON'T USE IT!
+ boolean replaced = mGlowPadView.replaceTargetDrawablesIfPresent(component,
+ ASSIST_ICON_METADATA_NAME + "_google",
+ com.android.internal.R.drawable.ic_action_assist_generic);
+
+ if (!replaced && !mGlowPadView.replaceTargetDrawablesIfPresent(component,
+ ASSIST_ICON_METADATA_NAME,
+ com.android.internal.R.drawable.ic_action_assist_generic)) {
+ Slog.w(TAG, "Couldn't grab icon from package " + component);
}
} else {
Slog.w(TAG, "No search icon specified in package " + component);
@@ -315,7 +322,7 @@
}
setEnabled(com.android.internal.R.drawable.ic_lockscreen_camera, !mCameraDisabled);
- setEnabled(com.android.internal.R.drawable.ic_lockscreen_search, !mSearchDisabled);
+ setEnabled(com.android.internal.R.drawable.ic_action_assist_generic, !mSearchDisabled);
}
public void onGrabbed(View v, int handle) {
@@ -329,7 +336,7 @@
public void onTrigger(View v, int target) {
final int resId = mGlowPadView.getResourceIdForTarget(target);
switch (resId) {
- case com.android.internal.R.drawable.ic_lockscreen_search:
+ case com.android.internal.R.drawable.ic_action_assist_generic:
Intent assistIntent = getAssistIntent();
if (assistIntent != null) {
launchActivity(assistIntent);
@@ -535,7 +542,7 @@
: false;
boolean searchTargetPresent = (mUnlockWidgetMethods instanceof GlowPadViewMethods)
? ((GlowPadViewMethods) mUnlockWidgetMethods)
- .isTargetPresent(com.android.internal.R.drawable.ic_lockscreen_search)
+ .isTargetPresent(com.android.internal.R.drawable.ic_action_assist_generic)
: false;
if (disabledByAdmin) {
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
index 0911f1f..35f71ec 100755
--- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
@@ -143,7 +143,6 @@
import android.view.animation.AnimationUtils;
import java.io.File;
-import java.io.FileDescriptor;
import java.io.FileReader;
import java.io.IOException;
import java.io.PrintWriter;
@@ -4371,7 +4370,7 @@
mLastInputMethodTargetWindow = target;
}
- public void dump(String prefix, FileDescriptor fd, PrintWriter pw, String[] args) {
+ public void dump(String prefix, PrintWriter pw, String[] args) {
pw.print(prefix); pw.print("mSafeMode="); pw.print(mSafeMode);
pw.print(" mSystemReady="); pw.print(mSystemReady);
pw.print(" mSystemBooted="); pw.println(mSystemBooted);
diff --git a/services/input/InputDispatcher.cpp b/services/input/InputDispatcher.cpp
index 7e1a80c..e63da05 100644
--- a/services/input/InputDispatcher.cpp
+++ b/services/input/InputDispatcher.cpp
@@ -53,6 +53,7 @@
#include <unistd.h>
#include <errno.h>
#include <limits.h>
+#include <time.h>
#define INDENT " "
#define INDENT2 " "
@@ -1073,7 +1074,7 @@
injectionResult, timeSpentWaitingForApplication);
#if DEBUG_FOCUS
ALOGD("findFocusedWindow finished: injectionResult=%d, "
- "timeSpendWaitingForApplication=%0.1fms",
+ "timeSpentWaitingForApplication=%0.1fms",
injectionResult, timeSpentWaitingForApplication / 1000000.0);
#endif
return injectionResult;
@@ -3100,7 +3101,7 @@
for (EventEntry* entry = mInboundQueue.head; entry; entry = entry->next) {
dump.append(INDENT2);
entry->appendDescription(dump);
- dump.appendFormat(", age=%01.1fms\n",
+ dump.appendFormat(", age=%0.1fms\n",
(currentTime - entry->eventTime) * 0.000001f);
}
} else {
@@ -3124,7 +3125,7 @@
entry = entry->next) {
dump.append(INDENT4);
entry->eventEntry->appendDescription(dump);
- dump.appendFormat(", targetFlags=0x%08x, resolvedAction=%d, age=%01.1fms\n",
+ dump.appendFormat(", targetFlags=0x%08x, resolvedAction=%d, age=%0.1fms\n",
entry->targetFlags, entry->resolvedAction,
(currentTime - entry->eventEntry->eventTime) * 0.000001f);
}
@@ -3140,7 +3141,7 @@
dump.append(INDENT4);
entry->eventEntry->appendDescription(dump);
dump.appendFormat(", targetFlags=0x%08x, resolvedAction=%d, "
- "age=%01.1fms, wait=%01.1fms\n",
+ "age=%0.1fms, wait=%0.1fms\n",
entry->targetFlags, entry->resolvedAction,
(currentTime - entry->eventEntry->eventTime) * 0.000001f,
(currentTime - entry->deliveryTime) * 0.000001f);
@@ -3154,11 +3155,17 @@
}
if (isAppSwitchPendingLocked()) {
- dump.appendFormat(INDENT "AppSwitch: pending, due in %01.1fms\n",
+ dump.appendFormat(INDENT "AppSwitch: pending, due in %0.1fms\n",
(mAppSwitchDueTime - now()) / 1000000.0);
} else {
dump.append(INDENT "AppSwitch: not pending\n");
}
+
+ dump.append(INDENT "Configuration:\n");
+ dump.appendFormat(INDENT2 "KeyRepeatDelay: %0.1fms\n",
+ mConfig.keyRepeatDelay * 0.000001f);
+ dump.appendFormat(INDENT2 "KeyRepeatTimeout: %0.1fms\n",
+ mConfig.keyRepeatTimeout * 0.000001f);
}
status_t InputDispatcher::registerInputChannel(const sp<InputChannel>& inputChannel,
@@ -3285,11 +3292,28 @@
nsecs_t currentTime, const sp<InputApplicationHandle>& applicationHandle,
const sp<InputWindowHandle>& windowHandle,
nsecs_t eventTime, nsecs_t waitStartTime, const char* reason) {
+ float dispatchLatency = (currentTime - eventTime) * 0.000001f;
+ float waitDuration = (currentTime - waitStartTime) * 0.000001f;
ALOGI("Application is not responding: %s. "
- "It has been %01.1fms since event, %01.1fms since wait started. Reason: %s",
+ "It has been %0.1fms since event, %0.1fms since wait started. Reason: %s",
getApplicationWindowLabelLocked(applicationHandle, windowHandle).string(),
- (currentTime - eventTime) / 1000000.0,
- (currentTime - waitStartTime) / 1000000.0, reason);
+ dispatchLatency, waitDuration, reason);
+
+ // Capture a record of the InputDispatcher state at the time of the ANR.
+ time_t t = time(NULL);
+ struct tm tm;
+ localtime_r(&t, &tm);
+ char timestr[64];
+ strftime(timestr, sizeof(timestr), "%F %T", &tm);
+ mLastANRState.clear();
+ mLastANRState.append(INDENT "ANR:\n");
+ mLastANRState.appendFormat(INDENT2 "Time: %s\n", timestr);
+ mLastANRState.appendFormat(INDENT2 "Window: %s\n",
+ getApplicationWindowLabelLocked(applicationHandle, windowHandle).string());
+ mLastANRState.appendFormat(INDENT2 "DispatchLatency: %0.1fms\n", dispatchLatency);
+ mLastANRState.appendFormat(INDENT2 "WaitDuration: %0.1fms\n", waitDuration);
+ mLastANRState.appendFormat(INDENT2 "Reason: %s\n", reason);
+ dumpDispatchStateLocked(mLastANRState);
CommandEntry* commandEntry = postCommandLocked(
& InputDispatcher::doNotifyANRLockedInterruptible);
@@ -3371,7 +3395,7 @@
nsecs_t eventDuration = finishTime - dispatchEntry->deliveryTime;
if (eventDuration > SLOW_EVENT_PROCESSING_WARNING_TIMEOUT) {
String8 msg;
- msg.appendFormat("Window '%s' spent %01.1fms processing the last input event: ",
+ msg.appendFormat("Window '%s' spent %0.1fms processing the last input event: ",
connection->getWindowName(), eventDuration * 0.000001f);
dispatchEntry->eventEntry->appendDescription(msg);
ALOGI("%s", msg.string());
@@ -3634,9 +3658,10 @@
dump.append("Input Dispatcher State:\n");
dumpDispatchStateLocked(dump);
- dump.append(INDENT "Configuration:\n");
- dump.appendFormat(INDENT2 "KeyRepeatDelay: %0.1fms\n", mConfig.keyRepeatDelay * 0.000001f);
- dump.appendFormat(INDENT2 "KeyRepeatTimeout: %0.1fms\n", mConfig.keyRepeatTimeout * 0.000001f);
+ if (!mLastANRState.isEmpty()) {
+ dump.append("\nInput Dispatcher State at time of last ANR:\n");
+ dump.append(mLastANRState);
+ }
}
void InputDispatcher::monitor() {
diff --git a/services/input/InputDispatcher.h b/services/input/InputDispatcher.h
index c5b8cd7..d0824fc 100644
--- a/services/input/InputDispatcher.h
+++ b/services/input/InputDispatcher.h
@@ -948,6 +948,9 @@
// Focused application.
sp<InputApplicationHandle> mFocusedApplicationHandle;
+ // Dispatcher state at time of last ANR.
+ String8 mLastANRState;
+
// Dispatch inbound events.
bool dispatchConfigurationChangedLocked(
nsecs_t currentTime, ConfigurationChangedEntry* entry);
diff --git a/services/java/com/android/server/BatteryService.java b/services/java/com/android/server/BatteryService.java
index ab9ae69..0a6f23c 100644
--- a/services/java/com/android/server/BatteryService.java
+++ b/services/java/com/android/server/BatteryService.java
@@ -68,7 +68,7 @@
* a degree Centigrade</p>
* <p>"technology" - String, the type of battery installed, e.g. "Li-ion"</p>
*/
-class BatteryService extends Binder {
+public class BatteryService extends Binder {
private static final String TAG = BatteryService.class.getSimpleName();
private static final boolean LOCAL_LOGV = false;
@@ -148,12 +148,12 @@
update();
}
- final boolean isPowered() {
+ public final boolean isPowered() {
// assume we are powered if battery state is unknown so the "stay on while plugged in" option will work.
return (mAcOnline || mUsbOnline || mBatteryStatus == BatteryManager.BATTERY_STATUS_UNKNOWN);
}
- final boolean isPowered(int plugTypeSet) {
+ public final boolean isPowered(int plugTypeSet) {
// assume we are powered if battery state is unknown so
// the "stay on while plugged in" option will work.
if (mBatteryStatus == BatteryManager.BATTERY_STATUS_UNKNOWN) {
@@ -172,7 +172,7 @@
return (plugTypeSet & plugTypeBit) != 0;
}
- final int getPlugType() {
+ public final int getPlugType() {
return mPlugType;
}
@@ -195,7 +195,7 @@
};
// returns battery level as a percentage
- final int getBatteryLevel() {
+ public final int getBatteryLevel() {
return mBatteryLevel;
}
diff --git a/services/java/com/android/server/DevicePolicyManagerService.java b/services/java/com/android/server/DevicePolicyManagerService.java
index 7699de2..4ea3d90 100644
--- a/services/java/com/android/server/DevicePolicyManagerService.java
+++ b/services/java/com/android/server/DevicePolicyManagerService.java
@@ -112,6 +112,8 @@
int mPasswordOwner = -1;
Handler mHandler = new Handler();
+ long mLastMaximumTimeToLock = -1;
+
final HashMap<ComponentName, ActiveAdmin> mAdminMap
= new HashMap<ComponentName, ActiveAdmin>();
final ArrayList<ActiveAdmin> mAdminList
@@ -595,7 +597,7 @@
new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
- synchronized (this) {
+ synchronized (DevicePolicyManagerService.this) {
boolean doProxyCleanup = admin.info.usesPolicy(
DeviceAdminInfo.USES_POLICY_SETS_GLOBAL_PROXY);
mAdminList.remove(admin);
@@ -603,9 +605,10 @@
validatePasswordOwnerLocked();
syncDeviceCapabilitiesLocked();
if (doProxyCleanup) {
- resetGlobalProxy();
+ resetGlobalProxyLocked();
}
saveSettingsLocked();
+ updateMaximumTimeToLockLocked();
}
}
});
@@ -826,16 +829,7 @@
validatePasswordOwnerLocked();
syncDeviceCapabilitiesLocked();
-
- long timeMs = getMaximumTimeToLock(null);
- if (timeMs <= 0) {
- timeMs = Integer.MAX_VALUE;
- }
- try {
- getIPowerManager().setMaximumScreenOffTimeount((int)timeMs);
- } catch (RemoteException e) {
- Slog.w(TAG, "Failure talking with power manager", e);
- }
+ updateMaximumTimeToLockLocked();
}
static void validateQualityConstant(int quality) {
@@ -1606,28 +1600,41 @@
DeviceAdminInfo.USES_POLICY_FORCE_LOCK);
if (ap.maximumTimeToUnlock != timeMs) {
ap.maximumTimeToUnlock = timeMs;
-
- long ident = Binder.clearCallingIdentity();
- try {
- saveSettingsLocked();
-
- timeMs = getMaximumTimeToLock(null);
- if (timeMs <= 0) {
- timeMs = Integer.MAX_VALUE;
- }
-
- try {
- getIPowerManager().setMaximumScreenOffTimeount((int)timeMs);
- } catch (RemoteException e) {
- Slog.w(TAG, "Failure talking with power manager", e);
- }
- } finally {
- Binder.restoreCallingIdentity(ident);
- }
+ saveSettingsLocked();
+ updateMaximumTimeToLockLocked();
}
}
}
+ void updateMaximumTimeToLockLocked() {
+ long timeMs = getMaximumTimeToLock(null);
+ if (mLastMaximumTimeToLock == timeMs) {
+ return;
+ }
+
+ long ident = Binder.clearCallingIdentity();
+ try {
+ if (timeMs <= 0) {
+ timeMs = Integer.MAX_VALUE;
+ } else {
+ // Make sure KEEP_SCREEN_ON is disabled, since that
+ // would allow bypassing of the maximum time to lock.
+ Settings.System.putInt(mContext.getContentResolver(),
+ Settings.System.STAY_ON_WHILE_PLUGGED_IN, 0);
+ }
+
+ mLastMaximumTimeToLock = timeMs;
+
+ try {
+ getIPowerManager().setMaximumScreenOffTimeount((int)timeMs);
+ } catch (RemoteException e) {
+ Slog.w(TAG, "Failure talking with power manager", e);
+ }
+ } finally {
+ Binder.restoreCallingIdentity(ident);
+ }
+ }
+
public long getMaximumTimeToLock(ComponentName who) {
synchronized (this) {
long time = 0;
@@ -1869,7 +1876,7 @@
// Reset the global proxy accordingly
// Do this using system permissions, as apps cannot write to secure settings
long origId = Binder.clearCallingIdentity();
- resetGlobalProxy();
+ resetGlobalProxyLocked();
Binder.restoreCallingIdentity(origId);
return null;
}
@@ -1893,20 +1900,20 @@
return null;
}
- private void resetGlobalProxy() {
+ private void resetGlobalProxyLocked() {
final int N = mAdminList.size();
for (int i = 0; i < N; i++) {
ActiveAdmin ap = mAdminList.get(i);
if (ap.specifiesGlobalProxy) {
- saveGlobalProxy(ap.globalProxySpec, ap.globalProxyExclusionList);
+ saveGlobalProxyLocked(ap.globalProxySpec, ap.globalProxyExclusionList);
return;
}
}
// No device admins defining global proxies - reset global proxy settings to none
- saveGlobalProxy(null, null);
+ saveGlobalProxyLocked(null, null);
}
- private void saveGlobalProxy(String proxySpec, String exclusionList) {
+ private void saveGlobalProxyLocked(String proxySpec, String exclusionList) {
if (exclusionList == null) {
exclusionList = "";
}
diff --git a/services/java/com/android/server/DockObserver.java b/services/java/com/android/server/DockObserver.java
index 64789d3..72c0767 100644
--- a/services/java/com/android/server/DockObserver.java
+++ b/services/java/com/android/server/DockObserver.java
@@ -16,6 +16,8 @@
package com.android.server;
+import com.android.server.power.PowerManagerService;
+
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.content.ContentResolver;
diff --git a/services/java/com/android/server/LightsService.java b/services/java/com/android/server/LightsService.java
index 1e95f3e..89bfcac 100644
--- a/services/java/com/android/server/LightsService.java
+++ b/services/java/com/android/server/LightsService.java
@@ -31,29 +31,29 @@
private static final String TAG = "LightsService";
private static final boolean DEBUG = false;
- static final int LIGHT_ID_BACKLIGHT = 0;
- static final int LIGHT_ID_KEYBOARD = 1;
- static final int LIGHT_ID_BUTTONS = 2;
- static final int LIGHT_ID_BATTERY = 3;
- static final int LIGHT_ID_NOTIFICATIONS = 4;
- static final int LIGHT_ID_ATTENTION = 5;
- static final int LIGHT_ID_BLUETOOTH = 6;
- static final int LIGHT_ID_WIFI = 7;
- static final int LIGHT_ID_COUNT = 8;
+ public static final int LIGHT_ID_BACKLIGHT = 0;
+ public static final int LIGHT_ID_KEYBOARD = 1;
+ public static final int LIGHT_ID_BUTTONS = 2;
+ public static final int LIGHT_ID_BATTERY = 3;
+ public static final int LIGHT_ID_NOTIFICATIONS = 4;
+ public static final int LIGHT_ID_ATTENTION = 5;
+ public static final int LIGHT_ID_BLUETOOTH = 6;
+ public static final int LIGHT_ID_WIFI = 7;
+ public static final int LIGHT_ID_COUNT = 8;
- static final int LIGHT_FLASH_NONE = 0;
- static final int LIGHT_FLASH_TIMED = 1;
- static final int LIGHT_FLASH_HARDWARE = 2;
+ public static final int LIGHT_FLASH_NONE = 0;
+ public static final int LIGHT_FLASH_TIMED = 1;
+ public static final int LIGHT_FLASH_HARDWARE = 2;
/**
* Light brightness is managed by a user setting.
*/
- static final int BRIGHTNESS_MODE_USER = 0;
+ public static final int BRIGHTNESS_MODE_USER = 0;
/**
* Light brightness is managed by a light sensor.
*/
- static final int BRIGHTNESS_MODE_SENSOR = 1;
+ public static final int BRIGHTNESS_MODE_SENSOR = 1;
private final Light mLights[] = new Light[LIGHT_ID_COUNT];
diff --git a/services/java/com/android/server/ShutdownActivity.java b/services/java/com/android/server/ShutdownActivity.java
index d85abe6..a4341b7 100644
--- a/services/java/com/android/server/ShutdownActivity.java
+++ b/services/java/com/android/server/ShutdownActivity.java
@@ -17,13 +17,12 @@
package com.android.server;
import android.app.Activity;
-import android.content.BroadcastReceiver;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.util.Slog;
-import com.android.server.pm.ShutdownThread;
+import com.android.server.power.ShutdownThread;
public class ShutdownActivity extends Activity {
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index 7e733c6..ed7b6e3 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -55,7 +55,8 @@
import com.android.server.net.NetworkPolicyManagerService;
import com.android.server.net.NetworkStatsService;
import com.android.server.pm.PackageManagerService;
-import com.android.server.pm.ShutdownThread;
+import com.android.server.power.PowerManagerService;
+import com.android.server.power.ShutdownThread;
import com.android.server.usb.UsbService;
import com.android.server.wm.WindowManagerService;
diff --git a/services/java/com/android/server/Watchdog.java b/services/java/com/android/server/Watchdog.java
index c239382..c5b4a07 100644
--- a/services/java/com/android/server/Watchdog.java
+++ b/services/java/com/android/server/Watchdog.java
@@ -17,6 +17,7 @@
package com.android.server;
import com.android.server.am.ActivityManagerService;
+import com.android.server.power.PowerManagerService;
import android.app.AlarmManager;
import android.app.PendingIntent;
diff --git a/services/java/com/android/server/am/ActivityRecord.java b/services/java/com/android/server/am/ActivityRecord.java
index 26c5c3d..17957d2 100644
--- a/services/java/com/android/server/am/ActivityRecord.java
+++ b/services/java/com/android/server/am/ActivityRecord.java
@@ -164,6 +164,9 @@
if (pendingResults != null) {
pw.print(prefix); pw.print("pendingResults="); pw.println(pendingResults);
}
+ if (pendingOptions != null) {
+ pw.print(prefix); pw.print("pendingOptions="); pw.println(pendingOptions);
+ }
if (uriPermissions != null) {
if (uriPermissions.readUriPermissions != null) {
pw.print(prefix); pw.print("readUriPermissions=");
@@ -202,7 +205,7 @@
if (lastVisibleTime != 0 || waitingVisible || nowVisible) {
pw.print(prefix); pw.print("waitingVisible="); pw.print(waitingVisible);
pw.print(" nowVisible="); pw.print(nowVisible);
- pw.print("lastVisibleTime=");
+ pw.print(" lastVisibleTime=");
TimeUtils.formatDuration(lastVisibleTime, pw); pw.println("");
}
if (configDestroy || configChangeFlags != 0) {
@@ -453,6 +456,7 @@
if (task != null && !finishing) {
task.numActivities--;
}
+ clearOptionsLocked();
}
}
@@ -466,6 +470,9 @@
if (task != null && inHistory) {
task.numActivities--;
}
+ if (stopped) {
+ clearOptionsLocked();
+ }
}
}
diff --git a/services/java/com/android/server/am/ActivityStack.java b/services/java/com/android/server/am/ActivityStack.java
index 1eef2cf..e2d6d98 100755
--- a/services/java/com/android/server/am/ActivityStack.java
+++ b/services/java/com/android/server/am/ActivityStack.java
@@ -1055,7 +1055,9 @@
mHandler.removeMessages(STOP_TIMEOUT_MSG, r);
r.stopped = true;
r.state = ActivityState.STOPPED;
- if (!r.finishing) {
+ if (r.finishing) {
+ r.clearOptionsLocked();
+ } else {
if (r.configDestroy) {
destroyActivityLocked(r, true, false, "stop-config");
resumeTopActivityLocked(null);
diff --git a/services/java/com/android/server/pm/PackageManagerService.java b/services/java/com/android/server/pm/PackageManagerService.java
index 7898342..2609664 100644
--- a/services/java/com/android/server/pm/PackageManagerService.java
+++ b/services/java/com/android/server/pm/PackageManagerService.java
@@ -30,6 +30,7 @@
import com.android.internal.app.ResolverActivity;
import com.android.internal.content.NativeLibraryHelper;
import com.android.internal.content.PackageHelper;
+import com.android.internal.util.FastXmlSerializer;
import com.android.internal.util.XmlUtils;
import com.android.server.DeviceStorageMonitorService;
import com.android.server.EventLogTags;
@@ -37,6 +38,7 @@
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
+import org.xmlpull.v1.XmlSerializer;
import android.app.ActivityManagerNative;
import android.app.IActivityManager;
@@ -110,6 +112,7 @@
import android.view.Display;
import android.view.WindowManager;
+import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileDescriptor;
import java.io.FileInputStream;
@@ -8407,6 +8410,10 @@
public static final int DUMP_VERIFIERS = 1 << 8;
+ public static final int DUMP_PREFERRED = 1 << 9;
+
+ public static final int DUMP_PREFERRED_XML = 1 << 10;
+
public static final int OPTION_SHOW_FILTERS = 1 << 0;
private int mTypes;
@@ -8418,7 +8425,7 @@
private SharedUserSetting mSharedUser;
public boolean isDumping(int type) {
- if (mTypes == 0) {
+ if (mTypes == 0 && type != DUMP_PREFERRED_XML) {
return true;
}
@@ -8495,6 +8502,8 @@
pw.println(" f[ibraries]: list device features");
pw.println(" r[esolvers]: dump intent resolvers");
pw.println(" perm[issions]: dump permissions");
+ pw.println(" pref[erred]: print preferred package settings");
+ pw.println(" preferred-xml: print preferred package settings as xml");
pw.println(" prov[iders]: dump content providers");
pw.println(" p[ackages]: dump installed packages");
pw.println(" s[hared-users]: dump shared user IDs");
@@ -8524,6 +8533,10 @@
dumpState.setDump(DumpState.DUMP_RESOLVERS);
} else if ("perm".equals(cmd) || "permissions".equals(cmd)) {
dumpState.setDump(DumpState.DUMP_PERMISSIONS);
+ } else if ("pref".equals(cmd) || "preferred".equals(cmd)) {
+ dumpState.setDump(DumpState.DUMP_PREFERRED);
+ } else if ("preferred-xml".equals(cmd)) {
+ dumpState.setDump(DumpState.DUMP_PREFERRED_XML);
} else if ("p".equals(cmd) || "packages".equals(cmd)) {
dumpState.setDump(DumpState.DUMP_PACKAGES);
} else if ("s".equals(cmd) || "shared-users".equals(cmd)) {
@@ -8592,6 +8605,9 @@
dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS))) {
dumpState.setTitlePrinted(true);
}
+ }
+
+ if (dumpState.isDumping(DumpState.DUMP_PREFERRED)) {
if (mSettings.mPreferredActivities.dump(pw,
dumpState.getTitlePrinted() ? "\nPreferred Activities:"
: "Preferred Activities:", " ",
@@ -8599,7 +8615,29 @@
dumpState.setTitlePrinted(true);
}
}
-
+
+ if (dumpState.isDumping(DumpState.DUMP_PREFERRED_XML)) {
+ pw.flush();
+ FileOutputStream fout = new FileOutputStream(fd);
+ BufferedOutputStream str = new BufferedOutputStream(fout);
+ XmlSerializer serializer = new FastXmlSerializer();
+ try {
+ serializer.setOutput(str, "utf-8");
+ serializer.startDocument(null, true);
+ serializer.setFeature(
+ "http://xmlpull.org/v1/doc/features.html#indent-output", true);
+ mSettings.writePreferredActivitiesLPr(serializer);
+ serializer.endDocument();
+ serializer.flush();
+ } catch (IllegalArgumentException e) {
+ pw.println("Failed writing: " + e);
+ } catch (IllegalStateException e) {
+ pw.println("Failed writing: " + e);
+ } catch (IOException e) {
+ pw.println("Failed writing: " + e);
+ }
+ }
+
if (dumpState.isDumping(DumpState.DUMP_PERMISSIONS)) {
mSettings.dumpPermissionsLPr(pw, packageName, dumpState);
}
diff --git a/services/java/com/android/server/pm/Settings.java b/services/java/com/android/server/pm/Settings.java
index 8b901b7..b26e853 100644
--- a/services/java/com/android/server/pm/Settings.java
+++ b/services/java/com/android/server/pm/Settings.java
@@ -1174,13 +1174,7 @@
writeDisabledSysPackageLPr(serializer, pkg);
}
- serializer.startTag(null, "preferred-activities");
- for (final PreferredActivity pa : mPreferredActivities.filterSet()) {
- serializer.startTag(null, TAG_ITEM);
- pa.writeToXml(serializer);
- serializer.endTag(null, TAG_ITEM);
- }
- serializer.endTag(null, "preferred-activities");
+ writePreferredActivitiesLPr(serializer);
for (final SharedUserSetting usr : mSharedUsers.values()) {
serializer.startTag(null, "shared-user");
@@ -1306,6 +1300,17 @@
//Debug.stopMethodTracing();
}
+ void writePreferredActivitiesLPr(XmlSerializer serializer)
+ throws IllegalArgumentException, IllegalStateException, IOException {
+ serializer.startTag(null, "preferred-activities");
+ for (final PreferredActivity pa : mPreferredActivities.filterSet()) {
+ serializer.startTag(null, TAG_ITEM);
+ pa.writeToXml(serializer);
+ serializer.endTag(null, TAG_ITEM);
+ }
+ serializer.endTag(null, "preferred-activities");
+ }
+
void writeDisabledSysPackageLPr(XmlSerializer serializer, final PackageSetting pkg)
throws java.io.IOException {
serializer.startTag(null, "updated-package");
@@ -1477,6 +1482,7 @@
mReadMessages.append("No settings file found\n");
PackageManagerService.reportSettingsProblem(Log.INFO,
"No settings file; creating initial state");
+ readDefaultPreferredAppsLPw();
return false;
}
str = new FileInputStream(mSettingsFilename);
@@ -1641,6 +1647,65 @@
return true;
}
+ private void readDefaultPreferredAppsLPw() {
+ // Read preferred apps from .../etc/preferred-apps directory.
+ File preferredDir = new File(Environment.getRootDirectory(), "etc/preferred-apps");
+ if (!preferredDir.exists() || !preferredDir.isDirectory()) {
+ return;
+ }
+ if (!preferredDir.canRead()) {
+ Slog.w(TAG, "Directory " + preferredDir + " cannot be read");
+ return;
+ }
+
+ // Iterate over the files in the directory and scan .xml files
+ for (File f : preferredDir.listFiles()) {
+ if (!f.getPath().endsWith(".xml")) {
+ Slog.i(TAG, "Non-xml file " + f + " in " + preferredDir + " directory, ignoring");
+ continue;
+ }
+ if (!f.canRead()) {
+ Slog.w(TAG, "Preferred apps file " + f + " cannot be read");
+ continue;
+ }
+
+ FileInputStream str = null;
+ try {
+ str = new FileInputStream(f);
+ XmlPullParser parser = Xml.newPullParser();
+ parser.setInput(str, null);
+
+ int type;
+ while ((type = parser.next()) != XmlPullParser.START_TAG
+ && type != XmlPullParser.END_DOCUMENT) {
+ ;
+ }
+
+ if (type != XmlPullParser.START_TAG) {
+ Slog.w(TAG, "Preferred apps file " + f + " does not have start tag");
+ continue;
+ }
+ if (!"preferred-activities".equals(parser.getName())) {
+ Slog.w(TAG, "Preferred apps file " + f
+ + " does not start with 'preferred-activities'");
+ continue;
+ }
+ readPreferredActivitiesLPw(parser);
+ } catch (XmlPullParserException e) {
+ Slog.w(TAG, "Error reading apps file " + f, e);
+ } catch (IOException e) {
+ Slog.w(TAG, "Error reading apps file " + f, e);
+ } finally {
+ if (str != null) {
+ try {
+ str.close();
+ } catch (IOException e) {
+ }
+ }
+ }
+ }
+ }
+
private int readInt(XmlPullParser parser, String ns, String name, int defValue) {
String v = parser.getAttributeValue(ns, name);
try {
diff --git a/services/java/com/android/server/PowerManagerService.java b/services/java/com/android/server/power/PowerManagerService.java
similarity index 98%
rename from services/java/com/android/server/PowerManagerService.java
rename to services/java/com/android/server/power/PowerManagerService.java
index 2e3121d..de2edff 100644
--- a/services/java/com/android/server/PowerManagerService.java
+++ b/services/java/com/android/server/power/PowerManagerService.java
@@ -14,11 +14,16 @@
* limitations under the License.
*/
-package com.android.server;
+package com.android.server.power;
import com.android.internal.app.IBatteryStats;
+import com.android.server.BatteryService;
+import com.android.server.EventLogTags;
+import com.android.server.LightsService;
+import com.android.server.LightsService.Light;
+import com.android.server.Watchdog;
+import com.android.server.Watchdog.Monitor;
import com.android.server.am.BatteryStatsService;
-import com.android.server.pm.ShutdownThread;
import android.app.ActivityManagerNative;
import android.app.IActivityManager;
@@ -477,6 +482,11 @@
}
}
+ int getStayOnConditionsLocked() {
+ return mMaximumScreenOffTimeout <= 0 || mMaximumScreenOffTimeout == Integer.MAX_VALUE
+ ? mStayOnConditions : 0;
+ }
+
private class SettingsObserver implements Observer {
private int getInt(String name, int defValue) {
ContentValues values = mSettings.getValues(name);
@@ -527,7 +537,7 @@
}
}
- PowerManagerService() {
+ public PowerManagerService() {
// Hack to get our uid... should have a func for this.
long token = Binder.clearCallingIdentity();
MY_UID = Process.myUid();
@@ -545,7 +555,7 @@
private ContentQueryMap mSettings;
- void init(Context context, LightsService lights, IActivityManager activity,
+ public void init(Context context, LightsService lights, IActivityManager activity,
BatteryService battery) {
mLightsService = lights;
mContext = context;
@@ -702,7 +712,7 @@
/**
* Low-level function turn the device off immediately, without trying
* to be clean. Most people should use
- * {@link com.android.server.pm.internal.app.ShutdownThread} for a clean shutdown.
+ * {@link com.android.server.power.internal.app.ShutdownThread} for a clean shutdown.
*/
public static void lowLevelShutdown() {
nativeShutdown();
@@ -760,7 +770,8 @@
}
private void updateWakeLockLocked() {
- if (mStayOnConditions != 0 && mBatteryService.isPowered(mStayOnConditions)) {
+ final int stayOnConditions = getStayOnConditionsLocked();
+ if (stayOnConditions != 0 && mBatteryService.isPowered(stayOnConditions)) {
// keep the device on if we're plugged in and mStayOnWhilePluggedIn is set.
mStayOnWhilePluggedInScreenDimLock.acquire();
mStayOnWhilePluggedInPartialLock.acquire();
@@ -2099,7 +2110,8 @@
// was dim
steps = (int)(ANIM_STEPS*ratio);
}
- if (mStayOnConditions != 0 && mBatteryService.isPowered(mStayOnConditions)) {
+ final int stayOnConditions = getStayOnConditionsLocked();
+ if (stayOnConditions != 0 && mBatteryService.isPowered(stayOnConditions)) {
// If the "stay on while plugged in" option is
// turned on, then the screen will often not
// automatically turn off while plugged in. To
@@ -2110,6 +2122,10 @@
brightness = mScreenBrightnessDim;
}
}
+ if (mWaitingForFirstLightSensor && (newState & SCREEN_ON_BIT) != 0) {
+ steps = IMMEDIATE_ANIM_STEPS;
+ }
+
long identity = Binder.clearCallingIdentity();
try {
mBatteryStats.noteScreenBrightness(brightness);
@@ -3045,7 +3061,7 @@
return mPolicy;
}
- void systemReady() {
+ public void systemReady() {
mSensorManager = new SystemSensorManager(mHandlerThread.getLooper());
mProximitySensor = mSensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY);
// don't bother with the light sensor if auto brightness is handled in hardware
@@ -3352,6 +3368,7 @@
}
SensorEventListener mLightListener = new SensorEventListener() {
+ @Override
public void onSensorChanged(SensorEvent event) {
if (mDebugLightSensor) {
Slog.d(TAG, "onSensorChanged: light value: " + event.values[0]);
@@ -3362,12 +3379,16 @@
return;
}
handleLightSensorValue((int)event.values[0], mWaitingForFirstLightSensor);
- if (mWaitingForFirstLightSensor) {
+ if (mWaitingForFirstLightSensor && !mPreparingForScreenOn) {
+ if (mDebugLightAnimation) {
+ Slog.d(TAG, "onSensorChanged: Clearing mWaitingForFirstLightSensor.");
+ }
mWaitingForFirstLightSensor = false;
}
}
}
+ @Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
// ignore
}
diff --git a/services/java/com/android/server/pm/ShutdownThread.java b/services/java/com/android/server/power/ShutdownThread.java
similarity index 99%
rename from services/java/com/android/server/pm/ShutdownThread.java
rename to services/java/com/android/server/power/ShutdownThread.java
index 3675d41..5f2f428 100644
--- a/services/java/com/android/server/pm/ShutdownThread.java
+++ b/services/java/com/android/server/power/ShutdownThread.java
@@ -15,7 +15,7 @@
*/
-package com.android.server.pm;
+package com.android.server.power;
import android.app.ActivityManagerNative;
import android.app.AlertDialog;
@@ -43,7 +43,6 @@
import android.os.storage.IMountShutdownObserver;
import com.android.internal.telephony.ITelephony;
-import com.android.server.PowerManagerService;
import android.util.Log;
import android.view.WindowManager;
diff --git a/services/java/com/android/server/wm/InputMonitor.java b/services/java/com/android/server/wm/InputMonitor.java
index c4bb519..285d230 100644
--- a/services/java/com/android/server/wm/InputMonitor.java
+++ b/services/java/com/android/server/wm/InputMonitor.java
@@ -87,24 +87,29 @@
public long notifyANR(InputApplicationHandle inputApplicationHandle,
InputWindowHandle inputWindowHandle) {
AppWindowToken appWindowToken = null;
- if (inputWindowHandle != null) {
- synchronized (mService.mWindowMap) {
- WindowState windowState = (WindowState) inputWindowHandle.windowState;
+ synchronized (mService.mWindowMap) {
+ WindowState windowState = null;
+ if (inputWindowHandle != null) {
+ windowState = (WindowState) inputWindowHandle.windowState;
if (windowState != null) {
- Slog.i(WindowManagerService.TAG, "Input event dispatching timed out sending to "
- + windowState.mAttrs.getTitle());
appWindowToken = windowState.mAppToken;
}
}
- }
-
- if (appWindowToken == null && inputApplicationHandle != null) {
- appWindowToken = (AppWindowToken)inputApplicationHandle.appWindowToken;
- if (appWindowToken != null) {
- Slog.i(WindowManagerService.TAG,
- "Input event dispatching timed out sending to application "
- + appWindowToken.stringName);
+ if (appWindowToken == null && inputApplicationHandle != null) {
+ appWindowToken = (AppWindowToken)inputApplicationHandle.appWindowToken;
}
+
+ if (windowState != null) {
+ Slog.i(WindowManagerService.TAG, "Input event dispatching timed out "
+ + "sending to " + windowState.mAttrs.getTitle());
+ } else if (appWindowToken != null) {
+ Slog.i(WindowManagerService.TAG, "Input event dispatching timed out "
+ + "sending to application " + appWindowToken.stringName);
+ } else {
+ Slog.i(WindowManagerService.TAG, "Input event dispatching timed out.");
+ }
+
+ mService.saveANRStateLocked(appWindowToken, windowState);
}
if (appWindowToken != null && appWindowToken.appToken != null) {
diff --git a/services/java/com/android/server/wm/WindowAnimator.java b/services/java/com/android/server/wm/WindowAnimator.java
index 758b6e7..e65d5d2 100644
--- a/services/java/com/android/server/wm/WindowAnimator.java
+++ b/services/java/com/android/server/wm/WindowAnimator.java
@@ -38,10 +38,18 @@
ArrayList<WindowStateAnimator> mWinAnimators = new ArrayList<WindowStateAnimator>();
boolean mAnimating;
- boolean mTokenMayBeDrawn;
- boolean mForceHiding;
- WindowState mWindowAnimationBackground;
- int mWindowAnimationBackgroundColor;
+
+ /** Variables only intended to be valid within each pass through animate(). Does not contain
+ * persistent state. */
+ private class InnerLoopParams {
+ boolean mTokenMayBeDrawn;
+ boolean mForceHiding;
+ WindowState mDetachedWallpaper = null;
+ WindowState mWindowAnimationBackground;
+ int mWindowAnimationBackgroundColor;
+ }
+ InnerLoopParams mInner = new InnerLoopParams();
+
int mAdjResult;
int mPendingLayoutChanges;
@@ -65,9 +73,9 @@
// Window currently running an animation that has requested it be detached
// from the wallpaper. This means we need to ensure the wallpaper is
// visible behind it in case it animates in a way that would allow it to be
- // seen.
+ // seen. If multiple windows satisfy this, use the lowest window.
WindowState mWindowDetachedWallpaper = null;
- WindowState mDetachedWallpaper = null;
+
DimSurface mWindowAnimationBackgroundSurface = null;
int mBulkUpdateParams = 0;
@@ -103,19 +111,20 @@
}
private void testWallpaperAndBackgroundLocked() {
- if (mWindowDetachedWallpaper != mDetachedWallpaper) {
+ final WindowState detachedWallpaper = mInner.mDetachedWallpaper;
+ if (mWindowDetachedWallpaper != detachedWallpaper) {
if (WindowManagerService.DEBUG_WALLPAPER) Slog.v(TAG,
"Detached wallpaper changed from " + mWindowDetachedWallpaper
- + " to " + mDetachedWallpaper);
- mWindowDetachedWallpaper = mDetachedWallpaper;
+ + " to " + detachedWallpaper);
+ mWindowDetachedWallpaper = detachedWallpaper;
mBulkUpdateParams |= SET_WALLPAPER_MAY_CHANGE;
}
- if (mWindowAnimationBackgroundColor != 0) {
+ if (mInner.mWindowAnimationBackgroundColor != 0) {
// If the window that wants black is the current wallpaper
// target, then the black goes *below* the wallpaper so we
// don't cause the wallpaper to suddenly disappear.
- WindowState target = mWindowAnimationBackground;
+ WindowState target = mInner.mWindowAnimationBackground;
if (mService.mWallpaperTarget == target
|| mService.mLowerWallpaperTarget == target
|| mService.mUpperWallpaperTarget == target) {
@@ -135,7 +144,7 @@
final int dh = mDh;
mWindowAnimationBackgroundSurface.show(dw, dh,
target.mWinAnimator.mAnimLayer - WindowManagerService.LAYER_OFFSET_DIM,
- mWindowAnimationBackgroundColor);
+ mInner.mWindowAnimationBackgroundColor);
} else if (mWindowAnimationBackgroundSurface != null) {
mWindowAnimationBackgroundSurface.hide();
}
@@ -199,9 +208,9 @@
ArrayList<WindowStateAnimator> unForceHiding = null;
boolean wallpaperInUnForceHiding = false;
- for (int i = mService.mWindows.size() - 1; i >= 0; i--) {
- WindowState win = mService.mWindows.get(i);
- WindowStateAnimator winAnimator = win.mWinAnimator;
+ for (int i = mWinAnimators.size() - 1; i >= 0; i--) {
+ WindowStateAnimator winAnimator = mWinAnimators.get(i);
+ WindowState win = winAnimator.mWin;
final int flags = winAnimator.mAttrFlags;
if (winAnimator.mSurface != null) {
@@ -220,15 +229,15 @@
if (winAnimator.mAnimation != null) {
if ((flags & FLAG_SHOW_WALLPAPER) != 0
&& winAnimator.mAnimation.getDetachWallpaper()) {
- mDetachedWallpaper = win;
+ mInner.mDetachedWallpaper = win;
}
final int backgroundColor = winAnimator.mAnimation.getBackgroundColor();
if (backgroundColor != 0) {
- if (mWindowAnimationBackground == null
- || (winAnimator.mAnimLayer <
- mWindowAnimationBackground.mWinAnimator.mAnimLayer)) {
- mWindowAnimationBackground = win;
- mWindowAnimationBackgroundColor = backgroundColor;
+ final WindowState background = mInner.mWindowAnimationBackground;
+ if (background == null || (winAnimator.mAnimLayer <
+ background.mWinAnimator.mAnimLayer)) {
+ mInner.mWindowAnimationBackground = win;
+ mInner.mWindowAnimationBackgroundColor = backgroundColor;
}
}
}
@@ -244,15 +253,15 @@
&& appAnimator.animating) {
if ((flags & FLAG_SHOW_WALLPAPER) != 0
&& appAnimator.animation.getDetachWallpaper()) {
- mDetachedWallpaper = win;
+ mInner.mDetachedWallpaper = win;
}
final int backgroundColor = appAnimator.animation.getBackgroundColor();
if (backgroundColor != 0) {
- if (mWindowAnimationBackground == null
- || (winAnimator.mAnimLayer <
- mWindowAnimationBackground.mWinAnimator.mAnimLayer)) {
- mWindowAnimationBackground = win;
- mWindowAnimationBackgroundColor = backgroundColor;
+ final WindowState background = mInner.mWindowAnimationBackground;
+ if (background == null || (winAnimator.mAnimLayer <
+ background.mWinAnimator.mAnimLayer)) {
+ mInner.mWindowAnimationBackground = win;
+ mInner.mWindowAnimationBackgroundColor = backgroundColor;
}
}
}
@@ -280,10 +289,10 @@
mService.mFocusMayChange = true;
}
if (win.isReadyForDisplay() && !winAnimator.isAnimating()) {
- mForceHiding = true;
+ mInner.mForceHiding = true;
}
if (WindowManagerService.DEBUG_VISIBILITY) Slog.v(TAG,
- "Force hide " + mForceHiding
+ "Force hide " + mInner.mForceHiding
+ " hasSurface=" + win.mHasSurface
+ " policyVis=" + win.mPolicyVisibility
+ " destroying=" + win.mDestroying
@@ -293,7 +302,7 @@
+ " anim=" + win.mWinAnimator.mAnimation);
} else if (mPolicy.canBeForceHidden(win, win.mAttrs)) {
final boolean changed;
- if (mForceHiding && !winAnimator.isAnimating()) {
+ if (mInner.mForceHiding && !winAnimator.isAnimating()) {
changed = win.hideLw(false, false);
if (WindowManagerService.DEBUG_VISIBILITY && changed) Slog.v(TAG,
"Now policy hidden: " + win);
@@ -308,7 +317,7 @@
unForceHiding = new ArrayList<WindowStateAnimator>();
}
unForceHiding.add(winAnimator);
- if ((win.mAttrs.flags&WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER) != 0) {
+ if ((flags & FLAG_SHOW_WALLPAPER) != 0) {
wallpaperInUnForceHiding = true;
}
}
@@ -320,7 +329,7 @@
}
}
}
- if (changed && (flags & WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER) != 0) {
+ if (changed && (flags & FLAG_SHOW_WALLPAPER) != 0) {
mBulkUpdateParams |= SET_WALLPAPER_MAY_CHANGE;
mPendingLayoutChanges |= WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
if (WindowManagerService.DEBUG_LAYOUT_REPEATS) {
@@ -364,7 +373,7 @@
"tokenMayBeDrawn: " + atoken
+ " freezingScreen=" + atoken.mAppAnimator.freezingScreen
+ " mAppFreezing=" + win.mAppFreezing);
- mTokenMayBeDrawn = true;
+ mInner.mTokenMayBeDrawn = true;
}
}
} else if (win.isDrawnLw()) {
@@ -454,18 +463,18 @@
}
private void performAnimationsLocked() {
- mTokenMayBeDrawn = false;
- mForceHiding = false;
- mDetachedWallpaper = null;
- mWindowAnimationBackground = null;
- mWindowAnimationBackgroundColor = 0;
+ mInner.mTokenMayBeDrawn = false;
+ mInner.mForceHiding = false;
+ mInner.mDetachedWallpaper = null;
+ mInner.mWindowAnimationBackground = null;
+ mInner.mWindowAnimationBackgroundColor = 0;
updateWindowsAndWallpaperLocked();
if ((mPendingLayoutChanges & WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER) != 0) {
mPendingActions |= WALLPAPER_ACTION_PENDING;
}
- if (mTokenMayBeDrawn) {
+ if (mInner.mTokenMayBeDrawn) {
testTokenMayBeDrawnLocked();
}
}
@@ -526,7 +535,15 @@
Surface.closeTransaction();
}
- mService.bulkSetParameters(mBulkUpdateParams, mPendingLayoutChanges);
+ if (mBulkUpdateParams != 0 || mPendingLayoutChanges != 0) {
+ final WindowManagerService.AnimatorToLayoutParams animToLayout = mService.mAnimToLayout;
+ synchronized (animToLayout) {
+ animToLayout.mBulkUpdateParams = mBulkUpdateParams;
+ animToLayout.mPendingLayoutChanges = mPendingLayoutChanges;
+ animToLayout.mWindowDetachedWallpaper = mWindowDetachedWallpaper;
+ mService.setAnimatorParameters();
+ }
+ }
if (mAnimating) {
mService.scheduleAnimationLocked();
diff --git a/services/java/com/android/server/wm/WindowManagerService.java b/services/java/com/android/server/wm/WindowManagerService.java
index 6c8d969..d73dc45 100755
--- a/services/java/com/android/server/wm/WindowManagerService.java
+++ b/services/java/com/android/server/wm/WindowManagerService.java
@@ -42,12 +42,12 @@
import com.android.internal.view.WindowManagerPolicyThread;
import com.android.server.AttributeCache;
import com.android.server.EventLogTags;
-import com.android.server.PowerManagerService;
import com.android.server.Watchdog;
import com.android.server.am.BatteryStatsService;
import com.android.server.input.InputFilter;
import com.android.server.input.InputManagerService;
-import com.android.server.pm.ShutdownThread;
+import com.android.server.power.PowerManagerService;
+import com.android.server.power.ShutdownThread;
import android.Manifest;
import android.app.ActivityManagerNative;
@@ -143,7 +143,9 @@
import java.io.PrintWriter;
import java.io.StringWriter;
import java.net.Socket;
+import java.text.DateFormat;
import java.util.ArrayList;
+import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
@@ -458,6 +460,8 @@
boolean mForceDisplayEnabled = false;
boolean mShowingBootMessages = false;
+ String mLastANRState;
+
// This protects the following display size properties, so that
// getDisplaySize() doesn't need to acquire the global lock. This is
// needed because the window manager sometimes needs to use ActivityThread
@@ -507,9 +511,9 @@
// State while inside of layoutAndPlaceSurfacesLocked().
boolean mFocusMayChange;
-
+
Configuration mCurConfiguration = new Configuration();
-
+
// This is held as long as we have the screen frozen, to give us time to
// perform a rotation animation when turning off shows the lock screen which
// changes the orientation.
@@ -636,7 +640,17 @@
private float mButtonBrightness = -1;
private boolean mUpdateRotation = false;
}
- LayoutFields mInnerFields = new LayoutFields();
+ final LayoutFields mInnerFields = new LayoutFields();
+
+ static class AnimatorToLayoutParams {
+ int mBulkUpdateParams;
+ int mPendingLayoutChanges;
+ WindowState mWindowDetachedWallpaper;
+ }
+ final AnimatorToLayoutParams mAnimToLayout = new AnimatorToLayoutParams();
+
+ /** The lowest wallpaper target with a detached wallpaper animation on it. */
+ WindowState mWindowDetachedWallpaper = null;
/** Only do a maximum of 6 repeated layouts. After that quit */
private int mLayoutRepeatCount;
@@ -667,7 +681,7 @@
}
final AnimationRunnable mAnimationRunnable = new AnimationRunnable();
boolean mAnimationScheduled;
-
+
final WindowAnimator mAnimator;
final class DragInputEventReceiver extends InputEventReceiver {
@@ -1572,9 +1586,9 @@
Slog.v(TAG, "List with no IM target:");
logWindowList(" ");
}
- if (DN > 0) moveInputMethodDialogsLocked(-1);;
+ if (DN > 0) moveInputMethodDialogsLocked(-1);
} else {
- moveInputMethodDialogsLocked(-1);;
+ moveInputMethodDialogsLocked(-1);
}
}
@@ -1636,7 +1650,7 @@
continue;
}
topCurW = null;
- if (w != mAnimator.mWindowDetachedWallpaper && w.mAppToken != null) {
+ if (w != mWindowDetachedWallpaper && w.mAppToken != null) {
// If this window's app token is hidden and not animating,
// it is of no interest to us.
if (w.mAppToken.hidden && w.mAppToken.mAppAnimator.animation == null) {
@@ -1662,7 +1676,7 @@
continue;
}
break;
- } else if (w == mAnimator.mWindowDetachedWallpaper) {
+ } else if (w == mWindowDetachedWallpaper) {
windowDetachedI = i;
}
}
@@ -3104,12 +3118,11 @@
a.setDetachWallpaper(true);
a.setDuration(duration);
return a;
- } else {
- // For normal animations, the exiting element just holds in place.
- Animation a = new AlphaAnimation(1, 1);
- a.setDuration(duration);
- return a;
}
+ // For normal animations, the exiting element just holds in place.
+ Animation a = new AlphaAnimation(1, 1);
+ a.setDuration(duration);
+ return a;
}
/**
@@ -6822,7 +6835,7 @@
public static final int REPORT_HARD_KEYBOARD_STATUS_CHANGE = 22;
public static final int BOOT_TIMEOUT = 23;
public static final int WAITING_FOR_DRAWN_TIMEOUT = 24;
- public static final int BULK_UPDATE_PARAMETERS = 25;
+ public static final int UPDATE_ANIM_PARAMETERS = 25;
public static final int SHOW_STRICT_MODE_VIOLATION = 26;
public static final int DO_ANIMATION_CALLBACK = 27;
@@ -7249,44 +7262,49 @@
break;
}
- case BULK_UPDATE_PARAMETERS: {
+ case UPDATE_ANIM_PARAMETERS: {
// Used to send multiple changes from the animation side to the layout side.
synchronized (mWindowMap) {
- boolean doRequest = false;
- // TODO(cmautner): As the number of bits grows, use masks of bit groups to
- // eliminate unnecessary tests.
- if ((msg.arg1 & LayoutFields.SET_UPDATE_ROTATION) != 0) {
- mInnerFields.mUpdateRotation = true;
- doRequest = true;
- }
- if ((msg.arg1 & LayoutFields.SET_WALLPAPER_MAY_CHANGE) != 0) {
- mInnerFields.mWallpaperMayChange = true;
- doRequest = true;
- }
- if ((msg.arg1 & LayoutFields.SET_FORCE_HIDING_CHANGED) != 0) {
- mInnerFields.mWallpaperForceHidingChanged = true;
- doRequest = true;
- }
- if ((msg.arg1 & LayoutFields.CLEAR_ORIENTATION_CHANGE_COMPLETE) != 0) {
- mInnerFields.mOrientationChangeComplete = false;
- } else {
- mInnerFields.mOrientationChangeComplete = true;
- if (mWindowsFreezingScreen) {
+ synchronized (mAnimToLayout) {
+ boolean doRequest = false;
+ final int bulkUpdateParams = mAnimToLayout.mBulkUpdateParams;
+ // TODO(cmautner): As the number of bits grows, use masks of bit groups to
+ // eliminate unnecessary tests.
+ if ((bulkUpdateParams & LayoutFields.SET_UPDATE_ROTATION) != 0) {
+ mInnerFields.mUpdateRotation = true;
doRequest = true;
}
- }
- if ((msg.arg1 & LayoutFields.SET_TURN_ON_SCREEN) != 0) {
- mTurnOnScreen = true;
- }
+ if ((bulkUpdateParams & LayoutFields.SET_WALLPAPER_MAY_CHANGE) != 0) {
+ mInnerFields.mWallpaperMayChange = true;
+ doRequest = true;
+ }
+ if ((bulkUpdateParams & LayoutFields.SET_FORCE_HIDING_CHANGED) != 0) {
+ mInnerFields.mWallpaperForceHidingChanged = true;
+ doRequest = true;
+ }
+ if ((bulkUpdateParams & LayoutFields.CLEAR_ORIENTATION_CHANGE_COMPLETE) != 0) {
+ mInnerFields.mOrientationChangeComplete = false;
+ } else {
+ mInnerFields.mOrientationChangeComplete = true;
+ if (mWindowsFreezingScreen) {
+ doRequest = true;
+ }
+ }
+ if ((bulkUpdateParams & LayoutFields.SET_TURN_ON_SCREEN) != 0) {
+ mTurnOnScreen = true;
+ }
- mPendingLayoutChanges |= msg.arg2;
- if (mPendingLayoutChanges != 0) {
- doRequest = true;
- }
+ mPendingLayoutChanges |= mAnimToLayout.mPendingLayoutChanges;
+ if (mPendingLayoutChanges != 0) {
+ doRequest = true;
+ }
- if (doRequest) {
- mH.sendEmptyMessage(CLEAR_PENDING_ACTIONS);
- performLayoutAndPlaceSurfacesLocked();
+ mWindowDetachedWallpaper = mAnimToLayout.mWindowDetachedWallpaper;
+
+ if (doRequest) {
+ mH.sendEmptyMessage(CLEAR_PENDING_ACTIONS);
+ performLayoutAndPlaceSurfacesLocked();
+ }
}
}
break;
@@ -9429,12 +9447,12 @@
mPolicy.lockNow();
}
- void dumpPolicyLocked(FileDescriptor fd, PrintWriter pw, String[] args, boolean dumpAll) {
+ void dumpPolicyLocked(PrintWriter pw, String[] args, boolean dumpAll) {
pw.println("WINDOW MANAGER POLICY STATE (dumpsys window policy)");
- mPolicy.dump(" ", fd, pw, args);
+ mPolicy.dump(" ", pw, args);
}
- void dumpTokensLocked(FileDescriptor fd, PrintWriter pw, boolean dumpAll) {
+ void dumpTokensLocked(PrintWriter pw, boolean dumpAll) {
pw.println("WINDOW MANAGER TOKENS (dumpsys window tokens)");
if (mTokenMap.size() > 0) {
pw.println(" All tokens:");
@@ -9542,7 +9560,7 @@
}
}
- void dumpSessionsLocked(FileDescriptor fd, PrintWriter pw, boolean dumpAll) {
+ void dumpSessionsLocked(PrintWriter pw, boolean dumpAll) {
pw.println("WINDOW MANAGER SESSIONS (dumpsys window sessions)");
if (mSessions.size() > 0) {
Iterator<Session> it = mSessions.iterator();
@@ -9554,9 +9572,14 @@
}
}
- void dumpWindowsLocked(FileDescriptor fd, PrintWriter pw, boolean dumpAll,
+ void dumpWindowsLocked(PrintWriter pw, boolean dumpAll,
ArrayList<WindowState> windows) {
pw.println("WINDOW MANAGER WINDOWS (dumpsys window windows)");
+ dumpWindowsNoHeaderLocked(pw, dumpAll, windows);
+ }
+
+ void dumpWindowsNoHeaderLocked(PrintWriter pw, boolean dumpAll,
+ ArrayList<WindowState> windows) {
for (int i=mWindows.size()-1; i>=0; i--) {
WindowState w = mWindows.get(i);
if (windows == null || windows.contains(w)) {
@@ -9793,7 +9816,7 @@
}
}
- boolean dumpWindows(FileDescriptor fd, PrintWriter pw, String name, String[] args,
+ boolean dumpWindows(PrintWriter pw, String name, String[] args,
int opti, boolean dumpAll) {
ArrayList<WindowState> windows = new ArrayList<WindowState>();
if ("visible".equals(name)) {
@@ -9832,11 +9855,44 @@
}
synchronized(mWindowMap) {
- dumpWindowsLocked(fd, pw, dumpAll, windows);
+ dumpWindowsLocked(pw, dumpAll, windows);
}
return true;
}
+ void dumpLastANRLocked(PrintWriter pw) {
+ pw.println("WINDOW MANAGER LAST ANR (dumpsys window lastanr)");
+ if (mLastANRState == null) {
+ pw.println(" <no ANR has occurred since boot>");
+ } else {
+ pw.println(mLastANRState);
+ }
+ }
+
+ /**
+ * Saves information about the state of the window manager at
+ * the time an ANR occurred before anything else in the system changes
+ * in response.
+ *
+ * @param appWindowToken The application that ANR'd, may be null.
+ * @param windowState The window that ANR'd, may be null.
+ */
+ public void saveANRStateLocked(AppWindowToken appWindowToken, WindowState windowState) {
+ StringWriter sw = new StringWriter();
+ PrintWriter pw = new PrintWriter(sw);
+ pw.println(" ANR time: " + DateFormat.getInstance().format(new Date()));
+ if (appWindowToken != null) {
+ pw.println(" Application at fault: " + appWindowToken.stringName);
+ }
+ if (windowState != null) {
+ pw.println(" Window at fault: " + windowState.mAttrs.getTitle());
+ }
+ pw.println();
+ dumpWindowsNoHeaderLocked(pw, true, null);
+ pw.close();
+ mLastANRState = sw.toString();
+ }
+
@Override
public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
if (mContext.checkCallingOrSelfPermission("android.permission.DUMP")
@@ -9862,6 +9918,7 @@
pw.println("Window manager dump options:");
pw.println(" [-a] [-h] [cmd] ...");
pw.println(" cmd may be one of:");
+ pw.println(" l[astanr]: last ANR information");
pw.println(" p[policy]: policy state");
pw.println(" s[essions]: active sessions");
pw.println(" t[okens]: token list");
@@ -9882,34 +9939,39 @@
if (opti < args.length) {
String cmd = args[opti];
opti++;
- if ("policy".equals(cmd) || "p".equals(cmd)) {
+ if ("lastanr".equals(cmd) || "l".equals(cmd)) {
synchronized(mWindowMap) {
- dumpPolicyLocked(fd, pw, args, true);
+ dumpLastANRLocked(pw);
+ }
+ return;
+ } else if ("policy".equals(cmd) || "p".equals(cmd)) {
+ synchronized(mWindowMap) {
+ dumpPolicyLocked(pw, args, true);
}
return;
} else if ("sessions".equals(cmd) || "s".equals(cmd)) {
synchronized(mWindowMap) {
- dumpSessionsLocked(fd, pw, true);
+ dumpSessionsLocked(pw, true);
}
return;
} else if ("tokens".equals(cmd) || "t".equals(cmd)) {
synchronized(mWindowMap) {
- dumpTokensLocked(fd, pw, true);
+ dumpTokensLocked(pw, true);
}
return;
} else if ("windows".equals(cmd) || "w".equals(cmd)) {
synchronized(mWindowMap) {
- dumpWindowsLocked(fd, pw, true, null);
+ dumpWindowsLocked(pw, true, null);
}
return;
} else if ("all".equals(cmd) || "a".equals(cmd)) {
synchronized(mWindowMap) {
- dumpWindowsLocked(fd, pw, true, null);
+ dumpWindowsLocked(pw, true, null);
}
return;
} else {
// Dumping a single name?
- if (!dumpWindows(fd, pw, cmd, args, opti, dumpAll)) {
+ if (!dumpWindows(pw, cmd, args, opti, dumpAll)) {
pw.println("Bad window command, or no windows match: " + cmd);
pw.println("Use -h for help.");
}
@@ -9921,22 +9983,27 @@
if (dumpAll) {
pw.println("-------------------------------------------------------------------------------");
}
- dumpPolicyLocked(fd, pw, args, dumpAll);
+ dumpPolicyLocked(pw, args, dumpAll);
pw.println();
if (dumpAll) {
pw.println("-------------------------------------------------------------------------------");
}
- dumpSessionsLocked(fd, pw, dumpAll);
+ dumpSessionsLocked(pw, dumpAll);
pw.println();
if (dumpAll) {
pw.println("-------------------------------------------------------------------------------");
}
- dumpTokensLocked(fd, pw, dumpAll);
+ dumpTokensLocked(pw, dumpAll);
pw.println();
if (dumpAll) {
pw.println("-------------------------------------------------------------------------------");
}
- dumpWindowsLocked(fd, pw, dumpAll, null);
+ dumpWindowsLocked(pw, dumpAll, null);
+ pw.println();
+ if (dumpAll) {
+ pw.println("-------------------------------------------------------------------------------");
+ }
+ dumpLastANRLocked(pw);
}
}
@@ -9957,8 +10024,7 @@
}
}
- void bulkSetParameters(final int bulkUpdateParams, int pendingLayoutChanges) {
- mH.sendMessage(mH.obtainMessage(H.BULK_UPDATE_PARAMETERS, bulkUpdateParams,
- pendingLayoutChanges));
+ void setAnimatorParameters() {
+ mH.sendMessage(mH.obtainMessage(H.UPDATE_ANIM_PARAMETERS));
}
}
diff --git a/services/jni/Android.mk b/services/jni/Android.mk
index e0a14af..d097a93 100644
--- a/services/jni/Android.mk
+++ b/services/jni/Android.mk
@@ -8,7 +8,7 @@
com_android_server_input_InputManagerService.cpp \
com_android_server_input_InputWindowHandle.cpp \
com_android_server_LightsService.cpp \
- com_android_server_PowerManagerService.cpp \
+ com_android_server_power_PowerManagerService.cpp \
com_android_server_SerialService.cpp \
com_android_server_SystemServer.cpp \
com_android_server_UsbDeviceManager.cpp \
diff --git a/services/jni/com_android_server_input_InputManagerService.cpp b/services/jni/com_android_server_input_InputManagerService.cpp
index 0e1ce51..57e1c28 100644
--- a/services/jni/com_android_server_input_InputManagerService.cpp
+++ b/services/jni/com_android_server_input_InputManagerService.cpp
@@ -49,7 +49,7 @@
#include <ScopedLocalRef.h>
#include <ScopedUtfChars.h>
-#include "com_android_server_PowerManagerService.h"
+#include "com_android_server_power_PowerManagerService.h"
#include "com_android_server_input_InputApplicationHandle.h"
#include "com_android_server_input_InputWindowHandle.h"
diff --git a/services/jni/com_android_server_PowerManagerService.cpp b/services/jni/com_android_server_power_PowerManagerService.cpp
similarity index 98%
rename from services/jni/com_android_server_PowerManagerService.cpp
rename to services/jni/com_android_server_power_PowerManagerService.cpp
index 2b8715c..2690b68 100644
--- a/services/jni/com_android_server_PowerManagerService.cpp
+++ b/services/jni/com_android_server_power_PowerManagerService.cpp
@@ -35,7 +35,7 @@
#include <private/gui/ComposerService.h>
-#include "com_android_server_PowerManagerService.h"
+#include "com_android_server_power_PowerManagerService.h"
namespace android {
@@ -246,14 +246,14 @@
LOG_FATAL_IF(! var, "Unable to find field " fieldName);
int register_android_server_PowerManagerService(JNIEnv* env) {
- int res = jniRegisterNativeMethods(env, "com/android/server/PowerManagerService",
+ int res = jniRegisterNativeMethods(env, "com/android/server/power/PowerManagerService",
gPowerManagerServiceMethods, NELEM(gPowerManagerServiceMethods));
LOG_FATAL_IF(res < 0, "Unable to register native methods.");
// Callbacks
jclass clazz;
- FIND_CLASS(clazz, "com/android/server/PowerManagerService");
+ FIND_CLASS(clazz, "com/android/server/power/PowerManagerService");
GET_METHOD_ID(gPowerManagerServiceClassInfo.goToSleep, clazz,
"goToSleep", "(J)V");
diff --git a/services/jni/com_android_server_PowerManagerService.h b/services/jni/com_android_server_power_PowerManagerService.h
similarity index 100%
rename from services/jni/com_android_server_PowerManagerService.h
rename to services/jni/com_android_server_power_PowerManagerService.h